blob: 3be5df160c560a82ece0d7279acb6dfb924a8585 [file] [log] [blame]
// Copyright 2021 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 anyhow::{Context as _, Result};
use fidl_fuchsia_input as input;
use fidl_fuchsia_ui_input as ui_input;
use fidl_fuchsia_ui_input3 as ui_input3;
use fuchsia_async as fasync;
use fuchsia_component::client::connect_to_protocol;
use fuchsia_zircon as zx;
use futures::TryStreamExt;
use keymaps::usages::Usages;
use test_helpers::{bind_editor, get_state_update, simulate_keypress};
/// Connects to a service that provides key injection.
fn connect_to_key_event_service() -> Result<ui_input3::KeyEventInjectorProxy> {
connect_to_protocol::<ui_input3::KeyEventInjectorMarker>()
.context("Failed to connect to fuchsia.ui.input3.KeyEventInjector")
}
fn connect_to_ime_service() -> Result<ui_input::ImeServiceProxy> {
connect_to_protocol::<ui_input::ImeServiceMarker>()
.context("Failed to connect to fuchsia.ui.input.ImeService")
}
const DELAY: zx::Duration = zx::Duration::from_seconds(5);
// TODO(https://fxbug.dev/42154779) This is horrible, but inevitable. Until the linked
// bug is fixed. It can't work in 100% of the cases, and it can't work 100%
// reliably regardless of the value of DELAY.
async fn wait_for_editor_binding() {
fasync::Timer::new(fasync::Time::after(DELAY)).await;
}
#[fasync::run_singlethreaded(test)]
async fn test_input_updates_ime_state() -> Result<()> {
let ime_service = connect_to_ime_service()?;
let key_event_service = connect_to_key_event_service()?;
let (_ime, mut editor_stream) = bind_editor(&ime_service)?;
wait_for_editor_binding().await;
simulate_keypress(&key_event_service, input::Key::A).await?;
// get first message with keypress event but no state update
let (state, event) = get_state_update(&mut editor_stream).await?;
let event = event.expect("expected event to be set");
assert_eq!(event.phase, ui_input::KeyboardEventPhase::Pressed);
assert_eq!(event.code_point, 97);
assert_eq!(state.text, "");
// get second message with state update
let (state, event) = get_state_update(&mut editor_stream).await?;
assert!(event.is_none());
assert_eq!(state.text, "a");
assert_eq!(state.selection.base, 1);
assert_eq!(state.selection.extent, 1);
// get third message with keyrelease event but no state update
let (state, event) = get_state_update(&mut editor_stream).await?;
let event = event.expect("expected event to be set");
assert_eq!(event.phase, ui_input::KeyboardEventPhase::Released);
assert_eq!(event.code_point, 97);
assert_eq!(state.text, "a");
// press left arrow
simulate_keypress(&key_event_service, input::Key::Left).await?;
// get first message with keypress event but no state update
let (state, event) = get_state_update(&mut editor_stream).await?;
let event = event.expect("expected event to be set");
assert_eq!(event.phase, ui_input::KeyboardEventPhase::Pressed);
assert_eq!(event.code_point, 0);
assert_eq!(event.hid_usage, Usages::HidUsageKeyLeft as u32);
assert_eq!(state.text, "a");
// get second message with state update
let (state, event) = get_state_update(&mut editor_stream).await?;
assert!(event.is_none());
assert_eq!(state.text, "a");
assert_eq!(state.selection.base, 0);
assert_eq!(state.selection.extent, 0);
// get first message with keyrelease event but no state update
let (state, event) = get_state_update(&mut editor_stream).await?;
let event = event.expect("expected event to be set");
assert_eq!(event.phase, ui_input::KeyboardEventPhase::Released);
assert_eq!(event.code_point, 0);
assert_eq!(event.hid_usage, Usages::HidUsageKeyLeft as u32);
assert_eq!(state.text, "a");
Ok(())
}
#[fasync::run_singlethreaded(test)]
async fn test_input_triggers_action() -> Result<()> {
let ime_service = connect_to_ime_service()?;
let key_event_service = connect_to_key_event_service()?;
let (_ime, mut editor_stream) = bind_editor(&ime_service)?;
wait_for_editor_binding().await;
// send key events
simulate_keypress(&key_event_service, input::Key::Enter).await?;
// get first message with keypress event
let (_state, event) = get_state_update(&mut editor_stream).await?;
let event = event.expect("expected event to be set");
assert_eq!(event.phase, ui_input::KeyboardEventPhase::Pressed);
assert_eq!(event.code_point, 0);
assert_eq!(event.hid_usage, Usages::HidUsageKeyEnter as u32);
// get second message with onaction event
let msg = editor_stream
.try_next()
.await
.expect("expected working event stream")
.expect("ime should have sent message");
if let ui_input::InputMethodEditorClientRequest::OnAction { action, .. } = msg {
assert_eq!(action, ui_input::InputMethodAction::Done);
} else {
panic!("request should be OnAction");
};
Ok(())
}