#![cfg(feature = "device-test")]
use crate::common::xremap_controller::{InputDeviceFilter, XremapController};
use crate::common::{
assert_err, assert_events, assert_str_contains, fetch_events, get_random_device_name, get_raw_device_pair,
get_virtual_device, key_press, key_release, wait_for_device,
};
use anyhow::Result;
use evdev::uinput::VirtualDevice;
use evdev::{Device, KeyCode as Key};
use indoc::indoc;
use std::time::Duration;
use xremap::device::select_input_devices;
mod common;
#[test]
pub fn test_no_input_device_match() {
let device_filter = vec!["match_nothing".into()];
assert_err(
"Failed to prepare input devices: No device was selected!",
select_input_devices(&device_filter, &vec![], false, false, "own_device"),
);
}
#[test]
pub fn test_device_without_keys_is_not_selected_automatically() -> Result<()> {
let name = get_random_device_name();
let _device = VirtualDevice::builder()?.name(&name).build()?;
let _ = wait_for_device(&name)?;
let devices = select_input_devices(&[], &vec![], false, false, "own_device")?;
assert_eq!(
0,
devices
.iter()
.filter(|(_, device)| device.device_name() == name)
.count()
);
Ok(())
}
#[test]
pub fn test_device_filter_overwrites_keyboard_and_mouse_check() -> Result<()> {
let name = get_random_device_name();
let _device = VirtualDevice::builder()?.name(&name).build()?;
let _ = wait_for_device(&name)?;
let names: Vec<String> = select_input_devices(&[name.clone()], &vec![], false, false, "own_device")?
.iter()
.map(|(_, device)| device.device_name().to_string())
.collect();
assert_eq!(vec![name], names);
Ok(())
}
#[test]
pub fn test_device_that_does_not_exist() -> Result<()> {
let ctrl = XremapController::builder()
.allow_stdio_errors(true)
.not_open_for_fetch()
.input_device(InputDeviceFilter::CustomFilter {
filter: "/dev/input/event99".into(),
})
.build()?;
let output = ctrl.wait_for_output()?;
assert_str_contains("Failed to prepare input devices", &output.stderr);
Ok(())
}
#[test]
pub fn test_device_that_is_already_grabbed() -> Result<()> {
let (mut input, output) = get_raw_device_pair()?;
let mut ctrl = XremapController::builder()
.allow_stdio_errors(true)
.not_open_for_fetch()
.input_device(InputDeviceFilter::CustomFilter {
filter: output.path.to_string_lossy().into(),
})
.build()?;
std::thread::sleep(Duration::from_millis(1000));
input.ungrab()?;
let output = ctrl.kill_for_output()?;
assert_str_contains("Failed to prepare input devices", &output.stderr);
assert_str_contains("Device or resource busy", &output.stderr);
assert_str_contains("Another program might have grabbed the device", &output.stderr);
Ok(())
}
#[test]
pub fn test_last_device_removed_in_non_watch_mode() -> Result<()> {
let mut ctrl = XremapController::builder().allow_stdio_errors(true).build()?;
ctrl.close_input_device()?;
let output = ctrl.wait_for_output()?;
assert_str_contains("Last device was removed, and not watching for new devices", &output.stderr);
Ok(())
}
#[test]
pub fn test_wait_for_all_up_keys_up() -> Result<()> {
let name = get_random_device_name();
let mut device = get_virtual_device(&name)?;
let mut input = Device::open(&device.path)?;
device.device.emit(&[key_press(Key::BTN_TRIGGER_HAPPY1)])?;
let ctrl = XremapController::builder()
.not_open_for_fetch()
.input_device(InputDeviceFilter::CustomFilter { filter: name.clone() })
.build()?;
std::thread::sleep(Duration::from_millis(100));
device.device.emit(&[key_release(Key::BTN_TRIGGER_HAPPY1)])?;
std::thread::sleep(Duration::from_millis(200));
let events: Vec<_> = fetch_events(&mut input)?.collect();
assert_events(
events,
indoc! {"
btn_trigger_happy1:1
btn_trigger_happy1:0
"},
);
ctrl.kill()
}
#[test]
pub fn test_wait_for_all_up_keys_up_fails() -> Result<()> {
let name = get_random_device_name();
let mut device = get_virtual_device(&name)?;
device.device.emit(&[key_press(Key::BTN_TRIGGER_HAPPY1)])?;
let ctrl = XremapController::builder()
.allow_stdio_errors(true)
.not_open_for_fetch()
.input_device(InputDeviceFilter::CustomFilter { filter: name.clone() })
.build()?;
std::thread::sleep(Duration::from_millis(500));
let output = ctrl.wait_for_output()?;
assert_str_contains("Failed to prepare input devices", &output.stderr);
assert_str_contains("Timed out waiting for keys to be released", &output.stderr);
Ok(())
}