mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-25 10:08:33 +02:00
test(wm): colocate tests with src files, add socket msg test
This commit is contained in:
3
.github/workflows/windows.yaml
vendored
3
.github/workflows/windows.yaml
vendored
@@ -55,7 +55,8 @@ jobs:
|
|||||||
key: ${{ matrix.platform.target }}
|
key: ${{ matrix.platform.target }}
|
||||||
- run: cargo +nightly fmt --check
|
- run: cargo +nightly fmt --check
|
||||||
- run: cargo clippy
|
- run: cargo clippy
|
||||||
- run: cargo test --package komorebi --test compat
|
# sockets don't work properly on the windows runner
|
||||||
|
- run: cargo test -- --skip window_manager --skip process_command
|
||||||
- uses: houseabsolute/actions-rust-cross@v1
|
- uses: houseabsolute/actions-rust-cross@v1
|
||||||
with:
|
with:
|
||||||
command: "build"
|
command: "build"
|
||||||
|
|||||||
@@ -2069,3 +2069,74 @@ pub fn read_commands_tcp(
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::monitor;
|
||||||
|
use crate::window_manager::WindowManager;
|
||||||
|
use crate::Rect;
|
||||||
|
use crate::SocketMessage;
|
||||||
|
use crate::WindowManagerEvent;
|
||||||
|
use crate::DATA_DIR;
|
||||||
|
use crossbeam_channel::bounded;
|
||||||
|
use crossbeam_channel::Receiver;
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::time::Duration;
|
||||||
|
use uds_windows::UnixStream;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
fn send_socket_message(socket: &str, message: SocketMessage) {
|
||||||
|
let socket = DATA_DIR.join(socket);
|
||||||
|
let mut stream = UnixStream::connect(socket).unwrap();
|
||||||
|
stream
|
||||||
|
.set_write_timeout(Some(Duration::from_secs(1)))
|
||||||
|
.unwrap();
|
||||||
|
stream
|
||||||
|
.write_all(serde_json::to_string(&message).unwrap().as_bytes())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_receive_socket_message() {
|
||||||
|
let (_sender, receiver): (Sender<WindowManagerEvent>, Receiver<WindowManagerEvent>) =
|
||||||
|
bounded(1);
|
||||||
|
let socket_name = format!("komorebi-test-{}.sock", Uuid::new_v4());
|
||||||
|
let socket_path = DATA_DIR.join(&socket_name);
|
||||||
|
let mut wm = WindowManager::new(receiver, Some(socket_path.clone())).unwrap();
|
||||||
|
let m = monitor::new(
|
||||||
|
0,
|
||||||
|
Rect::default(),
|
||||||
|
Rect::default(),
|
||||||
|
"TestMonitor".to_string(),
|
||||||
|
"TestDevice".to_string(),
|
||||||
|
"TestDeviceID".to_string(),
|
||||||
|
Some("TestMonitorID".to_string()),
|
||||||
|
);
|
||||||
|
|
||||||
|
wm.monitors_mut().push_back(m);
|
||||||
|
|
||||||
|
// send a message
|
||||||
|
send_socket_message(&socket_name, SocketMessage::FocusWorkspaceNumber(5));
|
||||||
|
|
||||||
|
let (stream, _) = wm.command_listener.accept().unwrap();
|
||||||
|
let reader = BufReader::new(stream.try_clone().unwrap());
|
||||||
|
let next = reader.lines().next();
|
||||||
|
|
||||||
|
// read and deserialize the message
|
||||||
|
let message_string = next.unwrap().unwrap();
|
||||||
|
let message = SocketMessage::from_str(&message_string).unwrap();
|
||||||
|
assert!(matches!(message, SocketMessage::FocusWorkspaceNumber(5)));
|
||||||
|
|
||||||
|
// process the message
|
||||||
|
wm.process_command(message, stream).unwrap();
|
||||||
|
|
||||||
|
// check the updated window manager state
|
||||||
|
assert_eq!(wm.focused_workspace_idx().unwrap(), 5);
|
||||||
|
|
||||||
|
std::fs::remove_file(socket_path).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1721,3 +1721,36 @@ fn populate_rules(
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::StaticConfig;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn backwards_compat() {
|
||||||
|
let root = vec!["0.1.17", "0.1.18", "0.1.19"];
|
||||||
|
let docs = vec![
|
||||||
|
"0.1.20", "0.1.21", "0.1.22", "0.1.23", "0.1.24", "0.1.25", "0.1.26", "0.1.27",
|
||||||
|
"0.1.28", "0.1.29", "0.1.30", "0.1.31", "0.1.32", "0.1.33", "0.1.34",
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut versions = vec![];
|
||||||
|
|
||||||
|
let client = reqwest::blocking::Client::new();
|
||||||
|
|
||||||
|
for version in root {
|
||||||
|
let request = client.get(format!("https://raw.githubusercontent.com/LGUG2Z/komorebi/refs/tags/v{version}/komorebi.example.json")).header("User-Agent", "komorebi-backwards-compat-test").build().unwrap();
|
||||||
|
versions.push((version, client.execute(request).unwrap().text().unwrap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for version in docs {
|
||||||
|
let request = client.get(format!("https://raw.githubusercontent.com/LGUG2Z/komorebi/refs/tags/v{version}/docs/komorebi.example.json")).header("User-Agent", "komorebi-backwards-compat-test").build().unwrap();
|
||||||
|
versions.push((version, client.execute(request).unwrap().text().unwrap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (version, config) in versions {
|
||||||
|
println!("{version}");
|
||||||
|
StaticConfig::read_raw(&config).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3660,3 +3660,81 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::monitor;
|
||||||
|
use crate::window_manager::WindowManager;
|
||||||
|
use crate::Rect;
|
||||||
|
use crate::WindowManagerEvent;
|
||||||
|
use crate::DATA_DIR;
|
||||||
|
use crossbeam_channel::bounded;
|
||||||
|
use crossbeam_channel::Receiver;
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_window_manager() {
|
||||||
|
let (_sender, receiver): (Sender<WindowManagerEvent>, Receiver<WindowManagerEvent>) =
|
||||||
|
bounded(1);
|
||||||
|
let socket_name = format!("komorebi-test-{}.sock", Uuid::new_v4());
|
||||||
|
let socket = Some(DATA_DIR.join(socket_name));
|
||||||
|
let wm = WindowManager::new(receiver, socket.clone());
|
||||||
|
assert!(wm.is_ok());
|
||||||
|
|
||||||
|
if let Some(ref socket_path) = socket {
|
||||||
|
let _ = std::fs::remove_file(socket_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_focus_workspace() {
|
||||||
|
let (_sender, receiver): (Sender<WindowManagerEvent>, Receiver<WindowManagerEvent>) =
|
||||||
|
bounded(1);
|
||||||
|
let socket_name = format!("komorebi-test-{}.sock", Uuid::new_v4());
|
||||||
|
let socket_path = DATA_DIR.join(&socket_name);
|
||||||
|
let mut wm = WindowManager::new(receiver, Some(socket_path.clone())).unwrap();
|
||||||
|
let m = monitor::new(
|
||||||
|
0,
|
||||||
|
Rect::default(),
|
||||||
|
Rect::default(),
|
||||||
|
"TestMonitor".to_string(),
|
||||||
|
"TestDevice".to_string(),
|
||||||
|
"TestDeviceID".to_string(),
|
||||||
|
Some("TestMonitorID".to_string()),
|
||||||
|
);
|
||||||
|
|
||||||
|
// a new monitor should have a single workspace
|
||||||
|
assert_eq!(m.workspaces().len(), 1);
|
||||||
|
|
||||||
|
// the next index on the monitor should be the not-yet-created second workspace
|
||||||
|
let new_workspace_index = m.new_workspace_idx();
|
||||||
|
assert_eq!(new_workspace_index, 1);
|
||||||
|
|
||||||
|
// add the monitor to the window manager
|
||||||
|
wm.monitors_mut().push_back(m);
|
||||||
|
|
||||||
|
{
|
||||||
|
// focusing a workspace which doesn't yet exist should create it
|
||||||
|
let monitor = wm.focused_monitor_mut().unwrap();
|
||||||
|
monitor.focus_workspace(new_workspace_index).unwrap();
|
||||||
|
assert_eq!(monitor.workspaces().len(), 2);
|
||||||
|
}
|
||||||
|
assert_eq!(wm.focused_workspace_idx().unwrap(), 1);
|
||||||
|
|
||||||
|
{
|
||||||
|
// focusing a workspace many indices ahead should create all workspaces
|
||||||
|
// required along the way
|
||||||
|
let monitor = wm.focused_monitor_mut().unwrap();
|
||||||
|
monitor.focus_workspace(new_workspace_index + 2).unwrap();
|
||||||
|
assert_eq!(monitor.workspaces().len(), 4);
|
||||||
|
}
|
||||||
|
assert_eq!(wm.focused_workspace_idx().unwrap(), 3);
|
||||||
|
|
||||||
|
// we should be able to successfully focus an existing workspace too
|
||||||
|
wm.focus_workspace(0).unwrap();
|
||||||
|
assert_eq!(wm.focused_workspace_idx().unwrap(), 0);
|
||||||
|
|
||||||
|
std::fs::remove_file(socket_path).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
use komorebi::StaticConfig;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn backwards_compat() {
|
|
||||||
let root = vec!["0.1.17", "0.1.18", "0.1.19"];
|
|
||||||
let docs = vec![
|
|
||||||
"0.1.20", "0.1.21", "0.1.22", "0.1.23", "0.1.24", "0.1.25", "0.1.26", "0.1.27", "0.1.28",
|
|
||||||
"0.1.29", "0.1.30", "0.1.31", "0.1.32", "0.1.33",
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut versions = vec![];
|
|
||||||
|
|
||||||
let client = reqwest::blocking::Client::new();
|
|
||||||
|
|
||||||
for version in root {
|
|
||||||
let request = client.get(format!("https://raw.githubusercontent.com/LGUG2Z/komorebi/refs/tags/v{version}/komorebi.example.json")).header("User-Agent", "komorebi-backwards-compat-test").build().unwrap();
|
|
||||||
versions.push((version, client.execute(request).unwrap().text().unwrap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for version in docs {
|
|
||||||
let request = client.get(format!("https://raw.githubusercontent.com/LGUG2Z/komorebi/refs/tags/v{version}/docs/komorebi.example.json")).header("User-Agent", "komorebi-backwards-compat-test").build().unwrap();
|
|
||||||
versions.push((version, client.execute(request).unwrap().text().unwrap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (version, config) in versions {
|
|
||||||
println!("{version}");
|
|
||||||
StaticConfig::read_raw(&config).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
#[cfg(test)]
|
|
||||||
mod window_manager_tests {
|
|
||||||
use color_eyre::eyre::anyhow;
|
|
||||||
use crossbeam_channel::bounded;
|
|
||||||
use crossbeam_channel::Receiver;
|
|
||||||
use crossbeam_channel::Sender;
|
|
||||||
use komorebi::monitor;
|
|
||||||
use komorebi::window_manager::WindowManager;
|
|
||||||
use komorebi::Rect;
|
|
||||||
use komorebi::WindowManagerEvent;
|
|
||||||
use komorebi::DATA_DIR;
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_create_window_manager() {
|
|
||||||
let (_sender, receiver): (Sender<WindowManagerEvent>, Receiver<WindowManagerEvent>) =
|
|
||||||
bounded(1);
|
|
||||||
let socket_name = format!("komorebi-test-{}.sock", Uuid::new_v4());
|
|
||||||
let socket = Some(DATA_DIR.join(socket_name));
|
|
||||||
let wm = WindowManager::new(receiver, socket.clone());
|
|
||||||
assert!(wm.is_ok());
|
|
||||||
|
|
||||||
if let Some(ref socket_path) = socket {
|
|
||||||
let _ = std::fs::remove_file(socket_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_focus_workspace() {
|
|
||||||
let (_sender, receiver): (Sender<WindowManagerEvent>, Receiver<WindowManagerEvent>) =
|
|
||||||
bounded(1);
|
|
||||||
let socket_name = format!("komorebi-test-{}.sock", Uuid::new_v4());
|
|
||||||
let socket = Some(DATA_DIR.join(socket_name));
|
|
||||||
let mut wm = WindowManager::new(receiver, socket.clone()).unwrap();
|
|
||||||
let m = monitor::new(
|
|
||||||
0,
|
|
||||||
Rect::default(),
|
|
||||||
Rect::default(),
|
|
||||||
"TestMonitor".to_string(),
|
|
||||||
"TestDevice".to_string(),
|
|
||||||
"TestDeviceID".to_string(),
|
|
||||||
Some("TestMonitorID".to_string()),
|
|
||||||
);
|
|
||||||
|
|
||||||
wm.monitors.elements_mut().push_back(m);
|
|
||||||
|
|
||||||
let workspace_idx = {
|
|
||||||
let monitor = wm
|
|
||||||
.focused_monitor_mut()
|
|
||||||
.ok_or_else(|| anyhow!("there is no workspace"))
|
|
||||||
.unwrap();
|
|
||||||
monitor.new_workspace_idx()
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
|
||||||
let monitor = wm
|
|
||||||
.focused_monitor_mut()
|
|
||||||
.ok_or_else(|| anyhow!("there is no workspace"))
|
|
||||||
.unwrap();
|
|
||||||
monitor
|
|
||||||
.focus_workspace(workspace_idx)
|
|
||||||
.expect("failed to focus workspace");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let monitor = wm
|
|
||||||
.focused_monitor_mut()
|
|
||||||
.ok_or_else(|| anyhow!("there is no workspace"))
|
|
||||||
.unwrap();
|
|
||||||
monitor
|
|
||||||
.focus_workspace(workspace_idx + 1)
|
|
||||||
.expect("failed to focus workspace");
|
|
||||||
assert_eq!(monitor.workspaces().len(), 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(wm.focused_workspace_idx().unwrap(), 2);
|
|
||||||
|
|
||||||
wm.focus_workspace(0).ok();
|
|
||||||
|
|
||||||
assert_eq!(wm.focused_workspace_idx().unwrap(), 0);
|
|
||||||
|
|
||||||
if let Some(ref socket_path) = socket {
|
|
||||||
let _ = std::fs::remove_file(socket_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user