blob: 1ef84eda66b687f5b112d602db9fa4df1d46b4b1 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![cfg(test)]
use {
crate::utils::Position,
crate::{
consumer_controls_binding, input_device, input_handler, keyboard_binding, mouse_binding,
touch_binding,
},
assert_matches::assert_matches,
fidl_fuchsia_input_report as fidl_input_report, fidl_fuchsia_ui_input as fidl_ui_input,
fidl_fuchsia_ui_input3 as fidl_ui_input3, fidl_fuchsia_ui_pointerinjector as pointerinjector,
fuchsia_zircon as zx,
futures::FutureExt as _,
maplit::hashmap,
std::collections::HashMap,
std::collections::HashSet,
};
/// Returns the current time as an i64 for InputReports and zx::Time for InputEvents.
pub fn event_times() -> (i64, zx::Time) {
let event_time = zx::Time::get_monotonic();
(event_time.into_nanos(), event_time)
}
/// Creates a [`fidl_input_report::InputReport`] with a keyboard report.
///
/// # Parameters
/// -`pressed_keys`: The input3 keys that will be added to the returned input report.
/// -`event_time`: The time in nanoseconds when the event was first recorded.
pub fn create_keyboard_input_report(
pressed_keys: Vec<fidl_fuchsia_input::Key>,
event_time: i64,
) -> fidl_input_report::InputReport {
fidl_input_report::InputReport {
event_time: Some(event_time),
keyboard: Some(fidl_input_report::KeyboardInputReport {
pressed_keys3: Some(pressed_keys),
..fidl_input_report::KeyboardInputReport::EMPTY
}),
mouse: None,
touch: None,
sensor: None,
consumer_control: None,
trace_id: None,
..fidl_input_report::InputReport::EMPTY
}
}
/// Creates a new [input_device::InputEvent] from the provided components.
pub fn create_input_event(
keyboard_event: keyboard_binding::KeyboardEvent,
device_descriptor: &input_device::InputDeviceDescriptor,
event_time: zx::Time,
handled: input_device::Handled,
) -> input_device::InputEvent {
input_device::InputEvent {
device_event: input_device::InputDeviceEvent::Keyboard(keyboard_event),
device_descriptor: device_descriptor.clone(),
event_time,
handled,
trace_id: None,
}
}
/// Creates a [`keyboard_binding::KeyboardEvent`] with the provided keys, meaning, and handled state.
///
/// # Parameters
/// - `key`: The input3 key which changed state.
/// - `event_type`: The input3 key event type (e.g. pressed, released).
/// - `modifiers`: The input3 modifiers that are to be included as pressed.
/// - `event_time`: The timestamp in nanoseconds when the event was recorded.
/// - `device_descriptor`: The device descriptor to add to the event.
/// - `handled`: Whether the event has been consumed by an upstream handler.
pub fn create_keyboard_event_with_handled(
key: fidl_fuchsia_input::Key,
event_type: fidl_fuchsia_ui_input3::KeyEventType,
modifiers: Option<fidl_ui_input3::Modifiers>,
event_time: zx::Time,
device_descriptor: &input_device::InputDeviceDescriptor,
keymap: Option<String>,
key_meaning: Option<fidl_fuchsia_ui_input3::KeyMeaning>,
handled: input_device::Handled,
) -> input_device::InputEvent {
let keyboard_event = keyboard_binding::KeyboardEvent::new(key, event_type)
.into_with_modifiers(modifiers)
.into_with_keymap(keymap)
.into_with_key_meaning(key_meaning);
create_input_event(keyboard_event, device_descriptor, event_time, handled)
}
/// Creates a [`keyboard_binding::KeyboardEvent`] with the provided keys and meaning.
/// a repeat sequence.
///
/// # Parameters
/// - `key`: The input3 key which changed state.
/// - `event_type`: The input3 key event type (e.g. pressed, released).
/// - `modifiers`: The input3 modifiers that are to be included as pressed.
/// - `event_time`: The timestamp in nanoseconds when the event was recorded.
/// - `device_descriptor`: The device descriptor to add to the event.
/// - `repeat_sequence`: The sequence of this key event in the autorepeat process.
pub fn create_keyboard_event_with_key_meaning_and_repeat_sequence(
key: fidl_fuchsia_input::Key,
event_type: fidl_fuchsia_ui_input3::KeyEventType,
modifiers: Option<fidl_ui_input3::Modifiers>,
event_time: zx::Time,
device_descriptor: &input_device::InputDeviceDescriptor,
keymap: Option<String>,
key_meaning: Option<fidl_fuchsia_ui_input3::KeyMeaning>,
repeat_sequence: u32,
) -> input_device::InputEvent {
let device_event = keyboard_binding::KeyboardEvent::new(key, event_type)
.into_with_modifiers(modifiers)
.into_with_key_meaning(key_meaning)
.into_with_keymap(keymap)
.into_with_repeat_sequence(repeat_sequence);
create_input_event(device_event, device_descriptor, event_time, input_device::Handled::No)
}
/// Creates a [`keyboard_binding::KeyboardEvent`] with the provided keys and meaning.
///
/// # Parameters
/// - `key`: The input3 key which changed state.
/// - `event_type`: The input3 key event type (e.g. pressed, released).
/// - `modifiers`: The input3 modifiers that are to be included as pressed.
/// - `event_time`: The timestamp in nanoseconds when the event was recorded.
/// - `device_descriptor`: The device descriptor to add to the event.
pub fn create_keyboard_event_with_key_meaning(
key: fidl_fuchsia_input::Key,
event_type: fidl_fuchsia_ui_input3::KeyEventType,
modifiers: Option<fidl_ui_input3::Modifiers>,
event_time: zx::Time,
device_descriptor: &input_device::InputDeviceDescriptor,
keymap: Option<String>,
key_meaning: Option<fidl_fuchsia_ui_input3::KeyMeaning>,
) -> input_device::InputEvent {
create_keyboard_event_with_key_meaning_and_repeat_sequence(
key,
event_type,
modifiers,
event_time,
device_descriptor,
keymap,
key_meaning,
0,
)
}
/// Creates a [`keyboard_binding::KeyboardEvent`] with the provided keys.
///
/// # Parameters
/// - `key`: The input3 key which changed state.
/// - `event_type`: The input3 key event type (e.g. pressed, released).
/// - `modifiers`: The input3 modifiers that are to be included as pressed.
/// - `event_time`: The timestamp in nanoseconds when the event was recorded.
/// - `device_descriptor`: The device descriptor to add to the event.
pub fn create_keyboard_event(
key: fidl_fuchsia_input::Key,
event_type: fidl_fuchsia_ui_input3::KeyEventType,
modifiers: Option<fidl_ui_input3::Modifiers>,
event_time: zx::Time,
device_descriptor: &input_device::InputDeviceDescriptor,
keymap: Option<String>,
) -> input_device::InputEvent {
create_keyboard_event_with_key_meaning(
key,
event_type,
modifiers,
event_time,
device_descriptor,
keymap,
None,
)
}
/// Creates a fake input event with the given event time. Please do not
/// read into other event fields.
pub fn create_fake_input_event(event_time: zx::Time) -> input_device::InputEvent {
input_device::InputEvent {
event_time,
device_event: input_device::InputDeviceEvent::Fake,
device_descriptor: input_device::InputDeviceDescriptor::Fake,
handled: input_device::Handled::No,
trace_id: None,
}
}
/// Creates a fake handled input event with the given event time. Please do not
/// read into other event fields.
pub fn create_fake_handled_input_event(event_time: zx::Time) -> input_device::InputEvent {
input_device::InputEvent {
event_time,
device_event: input_device::InputDeviceEvent::Fake,
device_descriptor: input_device::InputDeviceDescriptor::Fake,
handled: input_device::Handled::Yes,
trace_id: None,
}
}
/// Creates an [`input_device::InputDeviceDescriptor`] for a consumer controls device.
pub fn consumer_controls_device_descriptor() -> input_device::InputDeviceDescriptor {
input_device::InputDeviceDescriptor::ConsumerControls(
consumer_controls_binding::ConsumerControlsDeviceDescriptor {
buttons: vec![
fidl_input_report::ConsumerControlButton::CameraDisable,
fidl_input_report::ConsumerControlButton::FactoryReset,
fidl_input_report::ConsumerControlButton::MicMute,
fidl_input_report::ConsumerControlButton::Pause,
fidl_input_report::ConsumerControlButton::VolumeDown,
fidl_input_report::ConsumerControlButton::VolumeUp,
],
},
)
}
/// Creates a [`fidl_input_report::InputReport`] with a consumer control report.
///
/// # Parameters
/// - `buttons`: The buttons in the consumer control report.
/// - `event_time`: The time of event.
pub fn create_consumer_control_input_report(
buttons: Vec<fidl_input_report::ConsumerControlButton>,
event_time: i64,
) -> fidl_input_report::InputReport {
fidl_input_report::InputReport {
event_time: Some(event_time),
keyboard: None,
mouse: None,
touch: None,
sensor: None,
consumer_control: Some(fidl_input_report::ConsumerControlInputReport {
pressed_buttons: Some(buttons),
..fidl_input_report::ConsumerControlInputReport::EMPTY
}),
trace_id: None,
..fidl_input_report::InputReport::EMPTY
}
}
/// Creates a [`consumer_controls_binding::ConsumerControlsEvent`] with the provided parameters.
///
/// # Parameters
/// - `pressed_buttons`: The buttons to report in the event.
/// - `event_time`: The time of event.
/// - `device_descriptor`: The device descriptor to add to the event.
/// - `handled`: Whether the event has been consumed.
pub fn create_consumer_controls_event_with_handled(
pressed_buttons: Vec<fidl_input_report::ConsumerControlButton>,
event_time: zx::Time,
device_descriptor: &input_device::InputDeviceDescriptor,
handled: input_device::Handled,
) -> input_device::InputEvent {
input_device::InputEvent {
device_event: input_device::InputDeviceEvent::ConsumerControls(
consumer_controls_binding::ConsumerControlsEvent::new(pressed_buttons),
),
device_descriptor: device_descriptor.clone(),
event_time,
handled,
trace_id: None,
}
}
/// Creates a [`consumer_controls_binding::ConsumerControlsEvent`] with the provided parameters.
///
/// # Parameters
/// - `pressed_buttons`: The buttons to report in the event.
/// - `event_time`: The time of event.
/// - `device_descriptor`: The device descriptor to add to the event.
pub fn create_consumer_controls_event(
pressed_buttons: Vec<fidl_input_report::ConsumerControlButton>,
event_time: zx::Time,
device_descriptor: &input_device::InputDeviceDescriptor,
) -> input_device::InputEvent {
create_consumer_controls_event_with_handled(
pressed_buttons,
event_time,
device_descriptor,
input_device::Handled::No,
)
}
/// Creates a [`fidl_input_report::InputReport`] with a mouse report.
///
/// # Parameters
/// - `location`: The movement or position of the mouse report, in input device coordinates.
/// [`MouseLocation::Relative`] represents movement, and
/// [`MouseLocation::Absolute`] represents position.
/// - `wheel_delta_v`: The wheel delta in vertical.
/// - `wheel_delta_h`: The wheel delta in horizontal.
/// - `buttons`: The buttons to report as pressed in the mouse report.
/// - `event_time`: The time of event.
pub fn create_mouse_input_report(
location: mouse_binding::MouseLocation,
scroll_v: Option<i64>,
scroll_h: Option<i64>,
buttons: Vec<u8>,
event_time: i64,
) -> fidl_input_report::InputReport {
fidl_input_report::InputReport {
event_time: Some(event_time),
keyboard: None,
mouse: Some(fidl_input_report::MouseInputReport {
movement_x: match location {
mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
counts: Position { x, .. },
millimeters: Position { .. },
}) => Some(x as i64),
_ => None,
},
movement_y: match location {
mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
counts: Position { y, .. },
millimeters: Position { .. },
}) => Some(y as i64),
_ => None,
},
position_x: match location {
mouse_binding::MouseLocation::Absolute(Position { x, .. }) => Some(x as i64),
_ => None,
},
position_y: match location {
mouse_binding::MouseLocation::Absolute(Position { y, .. }) => Some(y as i64),
_ => None,
},
scroll_v: scroll_v,
scroll_h: scroll_h,
pressed_buttons: Some(buttons),
..fidl_input_report::MouseInputReport::EMPTY
}),
touch: None,
sensor: None,
consumer_control: None,
trace_id: None,
..fidl_input_report::InputReport::EMPTY
}
}
/// Creates a [`mouse_binding::MouseEvent`] with the provided parameters.
///
/// # Parameters
/// - `location`: The mouse location to report in the event.
/// - `wheel_delta_v`: The wheel delta in vertical.
/// - `wheel_delta_h`: The wheel delta in horizontal.
/// - `phase`: The phase of the buttons in the event.
/// - `buttons`: The buttons to report in the event.
/// - `event_time`: The time of event.
/// - `device_descriptor`: The device descriptor to add to the event.
pub fn create_mouse_event_with_handled(
location: mouse_binding::MouseLocation,
wheel_delta_v: Option<i64>,
wheel_delta_h: Option<i64>,
phase: mouse_binding::MousePhase,
affected_buttons: HashSet<mouse_binding::MouseButton>,
pressed_buttons: HashSet<mouse_binding::MouseButton>,
event_time: zx::Time,
device_descriptor: &input_device::InputDeviceDescriptor,
handled: input_device::Handled,
) -> input_device::InputEvent {
input_device::InputEvent {
device_event: input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent::new(
location,
wheel_delta_v,
wheel_delta_h,
phase,
affected_buttons,
pressed_buttons,
)),
device_descriptor: device_descriptor.clone(),
event_time,
handled,
trace_id: None,
}
}
/// Creates a [`mouse_binding::MouseEvent`] with the provided parameters.
///
/// # Parameters
/// - `location`: The mouse location to report in the event.
/// - `phase`: The phase of the buttons in the event.
/// - `buttons`: The buttons to report in the event.
/// - `event_time`: The time of event.
/// - `device_descriptor`: The device descriptor to add to the event.
pub fn create_mouse_event(
location: mouse_binding::MouseLocation,
wheel_delta_v: Option<i64>,
wheel_delta_h: Option<i64>,
phase: mouse_binding::MousePhase,
affected_buttons: HashSet<mouse_binding::MouseButton>,
pressed_buttons: HashSet<mouse_binding::MouseButton>,
event_time: zx::Time,
device_descriptor: &input_device::InputDeviceDescriptor,
) -> input_device::InputEvent {
create_mouse_event_with_handled(
location,
wheel_delta_v,
wheel_delta_h,
phase,
affected_buttons,
pressed_buttons,
event_time,
device_descriptor,
input_device::Handled::No,
)
}
/// Creates a [`pointerinjector::Event`] representing a mouse event.
///
/// # Parameters
/// - `phase`: The phase of the touch contact.
/// - `contact`: The touch contact to create the event for.
/// - `position`: The position of the contact in the viewport space.
/// - `relative_motion`: The relative motion fopr the event.
/// - `wheel_delta_v`: The wheel delta in vertical.
/// - `wheel_delta_h`: The wheel delta in horizontal.
/// - `event_time`: The time in nanoseconds when the event was first recorded.
pub fn create_mouse_pointer_sample_event(
phase: pointerinjector::EventPhase,
buttons: Vec<mouse_binding::MouseButton>,
position: crate::utils::Position,
relative_motion: Option<[f32; 2]>,
wheel_delta_v: Option<i64>,
wheel_delta_h: Option<i64>,
event_time: zx::Time,
) -> pointerinjector::Event {
let pointer_sample = pointerinjector::PointerSample {
pointer_id: Some(0),
phase: Some(phase),
position_in_viewport: Some([position.x, position.y]),
scroll_v: wheel_delta_v,
scroll_h: wheel_delta_h,
pressed_buttons: Some(buttons),
relative_motion,
..pointerinjector::PointerSample::EMPTY
};
let data = pointerinjector::Data::PointerSample(pointer_sample);
pointerinjector::Event {
timestamp: Some(event_time.into_nanos()),
data: Some(data),
..pointerinjector::Event::EMPTY
}
}
/// Creates a [`fidl_input_report::InputReport`] with a touch report.
///
/// # Parameters
/// - `contacts`: The contacts in the touch report.
/// - `event_time`: The time of event.
pub fn create_touch_input_report(
contacts: Vec<fidl_input_report::ContactInputReport>,
event_time: i64,
) -> fidl_input_report::InputReport {
fidl_input_report::InputReport {
event_time: Some(event_time),
keyboard: None,
mouse: None,
touch: Some(fidl_input_report::TouchInputReport {
contacts: Some(contacts),
pressed_buttons: None,
..fidl_input_report::TouchInputReport::EMPTY
}),
sensor: None,
consumer_control: None,
trace_id: None,
..fidl_input_report::InputReport::EMPTY
}
}
pub fn create_touch_contact(id: u32, position: Position) -> touch_binding::TouchContact {
touch_binding::TouchContact { id, position, pressure: None, contact_size: None }
}
/// Creates a [`touch_binding::TouchEvent`] with the provided parameters.
///
/// # Parameters
/// - `contacts`: The contacts in the touch report.
/// - `event_time`: The time of event.
/// - `device_descriptor`: The device descriptor to add to the event.
/// - `handled`: Whether the event has been consumed.
pub fn create_touch_event_with_handled(
mut contacts: HashMap<fidl_ui_input::PointerEventPhase, Vec<touch_binding::TouchContact>>,
event_time: zx::Time,
device_descriptor: &input_device::InputDeviceDescriptor,
handled: input_device::Handled,
) -> input_device::InputEvent {
contacts.entry(fidl_ui_input::PointerEventPhase::Add).or_insert(vec![]);
contacts.entry(fidl_ui_input::PointerEventPhase::Down).or_insert(vec![]);
contacts.entry(fidl_ui_input::PointerEventPhase::Move).or_insert(vec![]);
contacts.entry(fidl_ui_input::PointerEventPhase::Up).or_insert(vec![]);
contacts.entry(fidl_ui_input::PointerEventPhase::Remove).or_insert(vec![]);
let injector_contacts = hashmap! {
pointerinjector::EventPhase::Add =>
contacts.get(&fidl_ui_input::PointerEventPhase::Add).unwrap().clone(),
pointerinjector::EventPhase::Change =>
contacts.get(&fidl_ui_input::PointerEventPhase::Move).unwrap().clone(),
pointerinjector::EventPhase::Remove =>
contacts.get(&fidl_ui_input::PointerEventPhase::Remove).unwrap().clone(),
};
input_device::InputEvent {
device_event: input_device::InputDeviceEvent::Touch(touch_binding::TouchEvent {
contacts,
injector_contacts,
}),
device_descriptor: device_descriptor.clone(),
event_time,
handled: handled,
trace_id: None,
}
}
/// Creates a [`touch_binding::TouchEvent`] with the provided parameters.
///
/// # Parameters
/// - `contacts`: The contacts in the touch report.
/// - `event_time`: The time of event.
/// - `device_descriptor`: The device descriptor to add to the event.
pub fn create_touch_event(
contacts: HashMap<fidl_ui_input::PointerEventPhase, Vec<touch_binding::TouchContact>>,
event_time: zx::Time,
device_descriptor: &input_device::InputDeviceDescriptor,
) -> input_device::InputEvent {
create_touch_event_with_handled(
contacts,
event_time,
device_descriptor,
input_device::Handled::No,
)
}
/// Creates a [`fidl_ui_scenic::Command`] representing the given touch contact.
///
/// # Parameters
/// - `phase`: The phase of the touch contact.
/// - `contact`: The touch contact to create the event for.
/// - `position`: The position of the contact in the viewport space.
/// - `event_time`: The time in nanoseconds when the event was first recorded.
pub fn create_touch_pointer_sample_event(
phase: pointerinjector::EventPhase,
contact: &touch_binding::TouchContact,
position: crate::utils::Position,
event_time: zx::Time,
) -> pointerinjector::Event {
let pointer_sample = pointerinjector::PointerSample {
pointer_id: Some(contact.id),
phase: Some(phase),
position_in_viewport: Some([position.x, position.y]),
scroll_v: None,
scroll_h: None,
pressed_buttons: None,
..pointerinjector::PointerSample::EMPTY
};
let data = pointerinjector::Data::PointerSample(pointer_sample);
pointerinjector::Event {
timestamp: Some(event_time.into_nanos()),
data: Some(data),
trace_flow_id: Some(fuchsia_trace::generate_nonce()),
..pointerinjector::Event::EMPTY
}
}
/// Asserts that the given sequence of input reports generates the provided input events
/// when the reports are processed by the given device type.
#[macro_export]
macro_rules! assert_input_report_sequence_generates_events {
(
// The input reports to process.
input_reports: $input_reports:expr,
// The events which are expected.
expected_events: $expected_events:expr,
// The descriptor for the device that is sent to the input processor.
device_descriptor: $device_descriptor:expr,
// The type of device generating the events.
device_type: $DeviceType:ty,
) => {
let mut previous_report: Option<fidl_fuchsia_input_report::InputReport> = None;
let (event_sender, mut event_receiver) = futures::channel::mpsc::channel(std::cmp::max(
$input_reports.len(),
$expected_events.len(),
));
// Send all the reports prior to verifying the received events.
for report in $input_reports {
previous_report = <$DeviceType>::process_reports(
report,
previous_report,
&$device_descriptor,
&mut event_sender.clone(),
);
}
for expected_event in $expected_events {
let input_event = event_receiver.next().await;
match input_event {
Some(mut received_event) => {
// The trace_id field is set to a nonce value by process_reports(), so a naive
// comparison to an expected event will not match. Here, we set it to None to
// allow comparing against an expected event, but we ensure trace_id is set
// properly with another test.
received_event.trace_id = None;
pretty_assertions::assert_eq!(expected_event, received_event)
}
_ => assert!(false),
};
}
};
}
/// Asserts that the given sequence of input events generates the provided Scenic commands when the
/// events are processed by the given input handler.
#[macro_export]
macro_rules! assert_input_event_sequence_generates_scenic_events {
(
// The input handler that will handle input events.
input_handler: $input_handler:expr,
// The InputEvents to handle.
input_events: $input_events:expr,
// The commands the Scenic session should receive.
expected_commands: $expected_commands:expr,
// The Scenic session request stream.
scenic_session_request_stream: $scenic_session_request_stream:expr,
// A function to validate the Scenic commands.
assert_command: $assert_command:expr,
) => {
for input_event in $input_events {
assert_matches!(
$input_handler.clone().handle_input_event(input_event).await.as_slice(),
[input_device::InputEvent { handled: input_device::Handled::Yes, .. }]
);
}
let mut expected_command_iter = $expected_commands.into_iter().peekable();
while let Some(request) = $scenic_session_request_stream.next().await {
match request {
Ok(fidl_ui_scenic::SessionRequest::Enqueue { cmds, control_handle: _ }) => {
let mut command_iter = cmds.into_iter().peekable();
while let Some(command) = command_iter.next() {
let expected_command = expected_command_iter.next().unwrap();
$assert_command(command, expected_command);
// All the expected events have been received, so make sure no more events
// are present before returning.
if expected_command_iter.peek().is_none() {
assert!(command_iter.peek().is_none());
return;
}
}
}
_ => {
assert!(false);
}
}
}
};
}
/// Asserts that the given sequence of input events generates the provided media buttons events when
/// the input events are processed by the given input handler.
#[macro_export]
macro_rules! assert_input_event_sequence_generates_media_buttons_events {
(
// The input handler that will handle input events.
input_handler: $input_handler:expr,
// The InputEvents to handle.
input_events: $input_events:expr,
// The events the listeners should receive.
expected_events: $expected_events:expr,
// The media buttons listener request stream(s).
media_buttons_listener_request_stream: $media_buttons_listener_request_stream:expr,
) => {
fasync::Task::local(async move {
for input_event in $input_events {
assert_matches!(
$input_handler.clone().handle_input_event(input_event).await.as_slice(),
[input_device::InputEvent { handled: input_device::Handled::Yes, .. }]
);
}
})
.detach();
for mut stream in $media_buttons_listener_request_stream {
let mut expected_command_iter = $expected_events.clone().into_iter().peekable();
while let Some(request) = stream.next().await {
match request {
Ok(fidl_ui_policy::MediaButtonsListenerRequest::OnEvent {
event,
responder,
}) => {
let expected_command = expected_command_iter.next().unwrap();
pretty_assertions::assert_eq!(event, expected_command);
let _ = responder.send();
// All the expected events have been received, so make sure no more
// events are present before continuing to the next stream.
if expected_command_iter.peek().is_none() {
break;
}
}
_ => assert!(false),
}
}
}
};
}
/// Asserts that the given sequence of input events are ignored by the provided handler and request stream.
pub async fn assert_handler_ignores_input_event_sequence(
// The handler processing events.
input_handler: std::rc::Rc<dyn input_handler::InputHandler>,
// The InputEvents to handle.
input_events: Vec<input_device::InputEvent>,
// The listener request stream.
mut request_stream: impl futures::StreamExt + std::marker::Unpin,
) {
for input_event in input_events {
assert_matches!(
input_handler.clone().handle_input_event(input_event).await.as_slice(),
[input_device::InputEvent { handled: input_device::Handled::Yes, .. }]
);
}
// The request stream should not receive any events.
assert!(request_stream.next().now_or_never().is_none());
}