From 94032aa4d92f8d1737a1ea91910c9553680b9a00 Mon Sep 17 00:00:00 2001 From: brianp Date: Sun, 9 Nov 2025 17:55:46 +0100 Subject: [PATCH 1/5] test: fix doc test --- common/src/tmux/pane.rs | 4 ++-- common/src/tmux/target.rs | 15 ++++++++++++--- common/src/tmux/window.rs | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/common/src/tmux/pane.rs b/common/src/tmux/pane.rs index ceb74cf..c0b73bf 100644 --- a/common/src/tmux/pane.rs +++ b/common/src/tmux/pane.rs @@ -40,12 +40,12 @@ impl<'de> Deserialize<'de> for Pane { /// # Examples (YAML) /// /// As a string: - /// ``` + /// ```yaml /// "htop" /// ``` /// /// As a map: - /// ``` + /// ```yaml /// active: true /// command: ls /// path: /tmp diff --git a/common/src/tmux/target.rs b/common/src/tmux/target.rs index e1d69f4..ff40987 100644 --- a/common/src/tmux/target.rs +++ b/common/src/tmux/target.rs @@ -13,16 +13,25 @@ use serde::Deserialize; /// /// # Examples /// Creating targets for different granularities: -/// ``` +/// ```rust +/// use common::tmux::Target; +/// /// let session = Target::new("mysession", None, None); // "mysession" /// let window = Target::new("mysession", Some(2), None); // "mysession:2" /// let pane = Target::new("mysession", Some(2), Some(1)); // "mysession:2.1" /// ``` /// /// You can also extend a session-only target to include window or pane: -/// ``` +/// ```rust +/// use common::tmux::Target; +/// /// let t = Target::new("s", None, None); -/// let t = t.extend(1)?; // Now session "s", window 1 +/// let t = t.extend(1).unwrap(); // Now session "s", window 1 +/// assert_eq!(t.combined, "s:1"); +/// +/// let t = t.extend(2).unwrap(); // Now session "s", window 1, pane 2 +/// assert_eq!(t.combined, "s:1.2"); +/// /// ``` #[derive(Debug, Deserialize, Clone)] pub struct Target { diff --git a/common/src/tmux/window.rs b/common/src/tmux/window.rs index 5f9e74d..31af049 100644 --- a/common/src/tmux/window.rs +++ b/common/src/tmux/window.rs @@ -67,7 +67,7 @@ impl<'de> Deserialize<'de> for Window { /// - An object with fields `layout`, `panes`, `active`, `path`, and/or `command` /// /// Examples of supported YAML representations: - /// ``` + /// ```yaml /// # As a string: /// windows: [vim] /// From b001209fc6568ee0a21a31085d1d24d5907e35d6 Mon Sep 17 00:00:00 2001 From: brianp Date: Sun, 9 Nov 2025 18:30:32 +0100 Subject: [PATCH 2/5] test: ensure doctests are run --- .github/workflows/test.yml | 3 +++ new/src/lib.rs | 4 ++-- snapshot/src/lib.rs | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d768d1..cf66aa0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,6 +26,9 @@ jobs: - name: unit tests run: cargo test --all --lib + - name: doc tests + run: cargo test --all --doc + integration-tests: strategy: matrix: diff --git a/new/src/lib.rs b/new/src/lib.rs index 92b066f..988a282 100644 --- a/new/src/lib.rs +++ b/new/src/lib.rs @@ -22,13 +22,13 @@ static DEFAULT_TEMPLATE: &str = include_str!("template.yml"); /// /// You can run the command: /// -/// ``` +/// ```console /// $ ./muxednew projectName /// ``` /// /// or specify the directory target of the file: /// -/// ``` +/// ```console /// $ ./muxednew -p ~/.some_other_dir/ projectName /// ``` pub fn new(args: Args) -> Result<(), NewError> { diff --git a/snapshot/src/lib.rs b/snapshot/src/lib.rs index 4086906..11f908d 100644 --- a/snapshot/src/lib.rs +++ b/snapshot/src/lib.rs @@ -23,13 +23,13 @@ use new::write_template as write_config; /// /// You can run the command: /// -/// ``` +/// ```console /// $ ./muxedsnapshot -n my_new_project -t existing_sesion /// ``` /// /// or /// -/// ``` +/// ```console /// $ ./muxed snapshot -n jasper -t 1 /// ``` pub fn snapshot(args: Args) -> Result<(), SnapshotError> { From 76690cca5cba85bf4f9089fe4e4b18813ba7ddcf Mon Sep 17 00:00:00 2001 From: brianp Date: Sun, 9 Nov 2025 22:58:22 +0100 Subject: [PATCH 3/5] test: correct the usage of temp dirs --- Cargo.lock | 18 ++++-------------- common/Cargo.toml | 5 ++--- common/src/project_paths.rs | 13 +++++++------ common/src/rand_names.rs | 9 ++++++++- load/Cargo.toml | 2 +- load/src/project.rs | 16 +++++++++------- load/tests/load.rs | 23 ++++++++++++++++++----- new/src/lib.rs | 12 +++++++----- snapshot/src/lib.rs | 25 +++++++++++++++---------- 9 files changed, 71 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f56ce74..93341b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,7 +67,6 @@ dependencies = [ "rand", "serde", "serde-saphyr", - "serde_test", ] [[package]] @@ -313,9 +312,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -478,15 +477,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "serde_test" -version = "1.0.177" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f901ee573cab6b3060453d2d5f0bae4e6d628c23c0a962ff9b5f1d7c8d4f1ed" -dependencies = [ - "serde", -] - [[package]] name = "serde_yaml" version = "0.9.34+deprecated" @@ -525,9 +515,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.108" +version = "2.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +checksum = "2f17c7e013e88258aa9543dcbe81aca68a667a9ac37cd69c9fbc07858bfe0e2f" dependencies = [ "proc-macro2", "quote", diff --git a/common/Cargo.toml b/common/Cargo.toml index 2a965f2..80bbff4 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -7,9 +7,8 @@ edition = "2024" [dependencies] dirs = "6.0.0" -rand = "0.9.1" +rand = "0.9.2" serde = { version = "1.0.103", features = ["derive"] } serde-saphyr = "0.0.6" -[dev-dependencies] -serde_test = "1.0.177" +[dev-dependencies] \ No newline at end of file diff --git a/common/src/project_paths.rs b/common/src/project_paths.rs index 06be443..3f037d8 100644 --- a/common/src/project_paths.rs +++ b/common/src/project_paths.rs @@ -121,19 +121,20 @@ pub fn homedir() -> Option { /// Return the temp dir as the users home dir during testing. #[cfg(any(test, doctest))] pub fn homedir() -> Option { - Some(PathBuf::from("/tmp")) + Some(std::env::temp_dir()) } #[cfg(test)] mod test { use super::*; + use std::env::temp_dir; #[test] fn expects_tmp_as_default_homedir() { let args: Args = Default::default(); let project_paths = ProjectPaths::try_from(&args).unwrap(); - assert_eq!(project_paths.home_directory, PathBuf::from("/tmp")) + assert_eq!(project_paths.home_directory, temp_dir()) } #[test] @@ -143,7 +144,7 @@ mod test { assert_eq!( project_paths.project_directory, - PathBuf::from("/tmp/.muxed") + temp_dir().join(".muxed") ) } @@ -154,7 +155,7 @@ mod test { assert_eq!( project_paths.template_file, - PathBuf::from("/tmp/.muxed/.template.yml") + temp_dir().join(".muxed/.template.yml") ) } @@ -179,7 +180,7 @@ mod test { assert_eq!( project_paths.project_file, - PathBuf::from("/tmp/.muxed/projectname.yml") + temp_dir().join(".muxed/projectname.yml") ) } @@ -193,7 +194,7 @@ mod test { assert_eq!( project_paths.template_file, - PathBuf::from("/tmp/.muxed/custom_template.yml") + temp_dir().join(".muxed/custom_template.yml") ) } } diff --git a/common/src/rand_names.rs b/common/src/rand_names.rs index 125c4c0..ba49d52 100644 --- a/common/src/rand_names.rs +++ b/common/src/rand_names.rs @@ -1,9 +1,11 @@ +use std::env::temp_dir; use crate::project_paths::CONFIG_EXTENSION; use rand::random; use std::path::PathBuf; pub fn project_path_name() -> String { - format!("/tmp/.muxed-test-{}/", random::()) + let tmp = std::env::temp_dir().join(format!(".muxed-test-{}", random::())); + tmp.to_str().unwrap().to_string() } pub fn template_path_name() -> String { @@ -37,3 +39,8 @@ pub fn project_file_with_dir(dir: &str) -> PathBuf { let project_file = PathBuf::from(project_file_name()).with_extension(CONFIG_EXTENSION); PathBuf::from(dir).join(project_file) } + +pub fn project_file_in_tmp_dir() -> PathBuf { + let project_file = PathBuf::from(project_file_name()).with_extension(CONFIG_EXTENSION); + temp_dir().join(project_file) +} diff --git a/load/Cargo.toml b/load/Cargo.toml index 72fd02d..cfa3615 100644 --- a/load/Cargo.toml +++ b/load/Cargo.toml @@ -13,6 +13,6 @@ yaml-rust = { version = "0.4.5", default-features = false } serde-saphyr = "0.0.6" [dev-dependencies] -rand = "0.9.1" +rand = "0.9.2" snapshot = { path = "../snapshot" } retry_test = { path = "../retry_test" } diff --git a/load/src/project.rs b/load/src/project.rs index a76249c..95329cf 100644 --- a/load/src/project.rs +++ b/load/src/project.rs @@ -64,12 +64,13 @@ impl Project { /// use load::error::LoadError; /// use std::path::PathBuf; /// use yaml_rust::{Yaml, YamlLoader}; +/// use std::env::temp_dir; /// /// let paths = ProjectPaths::new( -/// PathBuf::from("/tmp"), -/// PathBuf::from("/tmp/.muxed"), -/// PathBuf::from("/tmp/.muxed/projectname.yml"), -/// PathBuf::from("/tmp/.muxed/.template.yml") +/// temp_dir(), +/// temp_dir().join(".muxed"), +/// temp_dir().join(".muxed/projectname.yml"), +/// temp_dir().join(".muxed/.template.yml") /// ); /// /// let yaml: Result = read("compiler", paths); @@ -137,13 +138,14 @@ pub fn open(project_name: &str) -> Commands { #[cfg(test)] mod test { + use std::env::temp_dir; use super::*; use common::rand_names; use std::fs; #[test] fn missing_file_returns_err() { - let project_paths = ProjectPaths::from_strs("/tmp", ".muxed", "", ""); + let project_paths = ProjectPaths::from_strs(temp_dir().to_str().unwrap(), ".muxed", "", ""); let result = read(&String::from("not_a_file"), project_paths); assert!(result.is_err()) } @@ -151,7 +153,7 @@ mod test { #[test] fn poorly_formatted_file_returns_err() { let name = rand_names::project_file_name(); - let project_paths = ProjectPaths::from_strs("/tmp", ".muxed", &name, ""); + let project_paths = ProjectPaths::from_strs(temp_dir().to_str().unwrap(), ".muxed", &name, ""); let _ = fs::create_dir(&project_paths.project_directory); let mut buffer = File::create(&project_paths.project_file).unwrap(); @@ -167,7 +169,7 @@ mod test { #[test] fn good_file_returns_ok() { let name = rand_names::project_file_name(); - let project_paths = ProjectPaths::from_strs("/tmp", ".muxed", &name, ""); + let project_paths = ProjectPaths::from_strs(temp_dir().to_str().unwrap(), ".muxed", &name, ""); let _ = fs::create_dir(&project_paths.project_directory); let mut buffer = File::create(&project_paths.project_file).unwrap(); diff --git a/load/tests/load.rs b/load/tests/load.rs index 1b91c17..84e55c0 100644 --- a/load/tests/load.rs +++ b/load/tests/load.rs @@ -15,6 +15,7 @@ mod helpers; #[cfg(test)] mod test { mod load { + use std::env::temp_dir; use crate::helpers::test_with_contents; use common::project_paths::homedir; use common::rand_names; @@ -253,7 +254,7 @@ windows: ['ssh', 'git'] #[test] fn expect_pre_to_create_file() { - let file = rand_names::project_file_with_dir("/tmp"); + let file = rand_names::project_file_in_tmp_dir(); let contents = format!( "--- pre: touch {} @@ -269,8 +270,8 @@ windows: ['ssh', 'git'] #[test] fn expect_pre_to_create_two_files() { - let file1 = rand_names::project_file_with_dir("/tmp"); - let file2 = rand_names::project_file_with_dir("/tmp"); + let file1 = rand_names::project_file_in_tmp_dir(); + let file2 = rand_names::project_file_in_tmp_dir(); let contents = format!( "--- pre: @@ -291,7 +292,7 @@ windows: ['ssh', 'git'] #[test] fn expect_pre_window_to_be_called_for_each_window() { - let file = rand_names::project_file_with_dir("/tmp"); + let file = rand_names::project_file_in_tmp_dir(); let contents = format!( "--- pre_window: \"echo 'pre_window' >> {}\" @@ -309,7 +310,7 @@ windows: ['ssh', 'git'] #[test] fn expect_pre_window_to_be_called_twice_for_each_window() { - let file = rand_names::project_file_with_dir("/tmp"); + let file = rand_names::project_file_in_tmp_dir(); let contents = format!( "--- pre_window: @@ -354,5 +355,17 @@ windows: ['ssh', 'git'] // let session = test_with_contents(contents); // assert_eq!(session.pane_active, "ssh.0") // } + + + #[test] + fn expect_attach_to_session_with_space_in_name() { + let contents = "--- +name: name with spaces +windows: ['ls'] +".to_string(); + let session = test_with_contents(contents.as_bytes()); + assert_eq!(session.name, "name with spaces"); + } } + } diff --git a/new/src/lib.rs b/new/src/lib.rs index 988a282..c47ab9a 100644 --- a/new/src/lib.rs +++ b/new/src/lib.rs @@ -114,6 +114,7 @@ where #[cfg(test)] mod test { + use std::env::temp_dir; use super::*; use common::rand_names; use std::fs; @@ -171,7 +172,8 @@ mod test { #[test] fn expect_ok_result_when_path_exists() { - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); + let result = write_template(&"test template".to_string(), &path, false); let _ = fs::remove_file(path); assert!(result.is_ok()); @@ -186,7 +188,7 @@ mod test { #[test] fn expect_new_file_to_exist() { - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); let _ = write_template(&"test template".to_string(), &path, false); let result = &path.exists(); let _ = fs::remove_file(&path); @@ -203,7 +205,7 @@ mod test { #[test] fn expect_no_truncation_or_overwrite() { // Write a file with content - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); let mut buffer = File::create(&path).unwrap(); let _ = buffer.write(b"original content"); let _ = buffer.sync_all(); @@ -220,7 +222,7 @@ mod test { #[test] fn expect_truncation_or_overwrite() { // Write a file with content - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); let mut buffer = File::create(&path).unwrap(); let _ = buffer.write(b"original content"); let _ = buffer.sync_all(); @@ -236,7 +238,7 @@ mod test { #[test] fn expect_err_when_file_exists() { - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); let mut buffer = File::create(&path).unwrap(); let _ = buffer.write(b"original content"); let _ = buffer.sync_all(); diff --git a/snapshot/src/lib.rs b/snapshot/src/lib.rs index 11f908d..0105807 100644 --- a/snapshot/src/lib.rs +++ b/snapshot/src/lib.rs @@ -51,6 +51,7 @@ pub fn snapshot(args: Args) -> Result<(), SnapshotError> { #[cfg(test)] mod test { + use std::env::temp_dir; use super::write_config; use common::rand_names; use std::fs; @@ -59,7 +60,7 @@ mod test { #[test] fn expect_ok_result() { - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); let result = write_config("test template", &path, false); let _ = fs::remove_file(path); assert!(result.is_ok()); @@ -67,14 +68,14 @@ mod test { #[test] fn expect_err_result() { - let path = rand_names::project_file_with_dir("/tmp/non_existent/"); + let path = rand_names::project_file_with_dir("/non_existent/"); let result = write_config("test template", &path, false); assert!(result.is_err()); } #[test] fn expect_file_to_exist() { - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); let _ = write_config("test template", &path, false); let result = &path.exists(); let _ = fs::remove_file(&path); @@ -83,7 +84,7 @@ mod test { #[test] fn expect_file_not_to_exist() { - let path = rand_names::project_file_with_dir("/tmp/non_existent/"); + let path = rand_names::project_file_with_dir("/non_existent/"); let _ = write_config("test template", &path, false); assert!(!path.exists()); } @@ -91,7 +92,7 @@ mod test { #[test] fn expect_no_truncation_or_overwrite() { // Write a file with content - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); let mut buffer = File::create(&path).unwrap(); let _ = buffer.write(b"original content"); let _ = buffer.sync_all(); @@ -110,7 +111,11 @@ mod test { #[test] fn expect_err_when_file_exists() { - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_path(); + if let Some(parent) = path.parent() { + fs::create_dir_all(parent).unwrap(); + } + println!("{:?}", path); let mut buffer = File::create(&path).unwrap(); let _ = buffer.write(b"original content"); let _ = buffer.sync_all(); @@ -122,7 +127,7 @@ mod test { #[test] fn expect_ok_when_file_exists_using_force() { - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); let mut buffer = File::create(&path).unwrap(); let _ = buffer.write(b"original content"); let _ = buffer.sync_all(); @@ -135,7 +140,7 @@ mod test { #[test] fn expect_truncation_or_overwrite_using_force() { // Write a file with content - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); let mut buffer = File::create(&path).unwrap(); let _ = buffer.write(b"original content"); let _ = buffer.sync_all(); @@ -154,14 +159,14 @@ mod test { #[test] fn expect_file_not_to_exist_using_force_with_bad_dir() { - let path = rand_names::project_file_with_dir("/tmp/non_existent_path/"); + let path = rand_names::project_file_with_dir("/non_existent_path/"); let _ = write_config("test template", &path, true); assert!(!path.exists()); } #[test] fn expect_ok_result_using_force_when_file_doesnt_exist() { - let path = rand_names::project_file_with_dir("/tmp"); + let path = rand_names::project_file_in_tmp_dir(); let result = write_config("test template", &path, true); let _ = fs::remove_file(path); assert!(result.is_ok()); From 2070a6751b28e1b846802a44c3153ec68c063bcd Mon Sep 17 00:00:00 2001 From: brianp Date: Mon, 10 Nov 2025 01:29:33 +0100 Subject: [PATCH 4/5] test: test path related inheritance --- Cargo.lock | 4 +- common/Cargo.toml | 2 +- common/src/project_paths.rs | 5 +-- common/src/rand_names.rs | 2 +- common/src/tmux/session.rs | 3 ++ load/Cargo.toml | 2 +- load/src/interpreter/enrichment.rs | 65 +++++++++++++++++++++++++++- load/src/interpreter/to_command.rs | 3 +- load/src/project.rs | 8 ++-- load/tests/helpers/mod.rs | 8 ++-- load/tests/load.rs | 68 +++++++++++++++--------------- new/src/lib.rs | 2 +- snapshot/src/lib.rs | 2 +- 13 files changed, 121 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93341b2..e20471e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -430,9 +430,9 @@ dependencies = [ [[package]] name = "serde-saphyr" -version = "0.0.6" +version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f637bb99547414f8c08b7d4fe3e56b248fa9db36860e190988501ac1b3741eee" +checksum = "fd76af9505b2498740576f95f60b3b4e2c469b5b677a8d2dd1d2da18b58193de" dependencies = [ "base64", "nohash-hasher", diff --git a/common/Cargo.toml b/common/Cargo.toml index 80bbff4..c53820c 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -9,6 +9,6 @@ edition = "2024" dirs = "6.0.0" rand = "0.9.2" serde = { version = "1.0.103", features = ["derive"] } -serde-saphyr = "0.0.6" +serde-saphyr = "0.0.7" [dev-dependencies] \ No newline at end of file diff --git a/common/src/project_paths.rs b/common/src/project_paths.rs index 3f037d8..f53ccb0 100644 --- a/common/src/project_paths.rs +++ b/common/src/project_paths.rs @@ -142,10 +142,7 @@ mod test { let args: Args = Default::default(); let project_paths = ProjectPaths::try_from(&args).unwrap(); - assert_eq!( - project_paths.project_directory, - temp_dir().join(".muxed") - ) + assert_eq!(project_paths.project_directory, temp_dir().join(".muxed")) } #[test] diff --git a/common/src/rand_names.rs b/common/src/rand_names.rs index ba49d52..cdea053 100644 --- a/common/src/rand_names.rs +++ b/common/src/rand_names.rs @@ -1,6 +1,6 @@ -use std::env::temp_dir; use crate::project_paths::CONFIG_EXTENSION; use rand::random; +use std::env::temp_dir; use std::path::PathBuf; pub fn project_path_name() -> String { diff --git a/common/src/tmux/session.rs b/common/src/tmux/session.rs index 1e33d7e..e92dff2 100644 --- a/common/src/tmux/session.rs +++ b/common/src/tmux/session.rs @@ -134,6 +134,7 @@ pub enum NodeMut<'a> { window_index: usize, pane_index: usize, pane: &'a mut Pane, + window_path: Option, }, } @@ -167,6 +168,7 @@ impl<'a> Iterator for SessionIterMut<'a> { // currently iterating panes if let Some(pane_idx) = self.pane_index { + let window_path = session.windows[self.window_index].path.clone(); let num_panes = session.windows[self.window_index].panes.len(); if pane_idx < num_panes { @@ -176,6 +178,7 @@ impl<'a> Iterator for SessionIterMut<'a> { window_index: self.window_index, pane_index: pane_idx, pane, + window_path, }); } else { // finished panes for this window diff --git a/load/Cargo.toml b/load/Cargo.toml index cfa3615..471f72d 100644 --- a/load/Cargo.toml +++ b/load/Cargo.toml @@ -10,7 +10,7 @@ common = { path = "../common" } dirs = "6.0.0" libc = "0.2.66" yaml-rust = { version = "0.4.5", default-features = false } -serde-saphyr = "0.0.6" +serde-saphyr = "0.0.7" [dev-dependencies] rand = "0.9.2" diff --git a/load/src/interpreter/enrichment.rs b/load/src/interpreter/enrichment.rs index a4e0e04..e590a6d 100644 --- a/load/src/interpreter/enrichment.rs +++ b/load/src/interpreter/enrichment.rs @@ -45,6 +45,7 @@ pub fn enrich(session: &mut Session, project_name: String, daemonize: bool, conf match node { NodeMut::Pane { window_index, + window_path, pane_index, pane, } => { @@ -53,7 +54,10 @@ pub fn enrich(session: &mut Session, project_name: String, daemonize: bool, conf pane.path = match pane.path.as_ref() { Some(path) => expand_path(path), - None => root.clone(), + None => match window_path.as_ref() { + Some(path) => expand_path(path), + None => root.clone(), + }, }; pane.target = Some(Target::new( @@ -299,6 +303,65 @@ mod test { assert_eq!(sess.root, orig.root); } + #[test] + fn pane_path_inherits_from_window_if_none() { + // Session with root, one window, two panes + // Only window.path is set + let window_path = PathBuf::from("/tmp/from-window"); + let mut sess = Session { + name: None, + windows: vec![Window { + name: "w".to_string(), + panes: vec![ + Pane { + path: None, + ..Default::default() + }, // will inherit from window + Pane { + path: None, + ..Default::default() + }, // will inherit from window + ], + path: Some(window_path.clone()), + ..Default::default() + }], + root: Some(PathBuf::from("/tmp/not-used")), + ..Default::default() + }; + + enrich(&mut sess, "proj".into(), false, Config::default()); + + for pane in sess.windows[0].panes.iter() { + assert_eq!(pane.path, Some(window_path.clone())); + } + } + + #[test] + fn pane_path_inherits_from_root_if_pane_and_window_none() { + // Session with root, but window.path and pane.path are None + let root_path = PathBuf::from("/tmp/fallback-root"); + let mut sess = Session { + name: None, + windows: vec![Window { + name: "w".to_string(), + panes: vec![ + Pane { + path: None, + ..Default::default() + }, // will inherit from root + ], + path: None, + ..Default::default() + }], + root: Some(root_path.clone()), + ..Default::default() + }; + + enrich(&mut sess, "demo".into(), false, Config::default()); + + assert_eq!(sess.windows[0].panes[0].path, Some(root_path)); + } + #[cfg(test)] mod expand_path_tests { use super::*; diff --git a/load/src/interpreter/to_command.rs b/load/src/interpreter/to_command.rs index d77312e..b4d58ae 100644 --- a/load/src/interpreter/to_command.rs +++ b/load/src/interpreter/to_command.rs @@ -144,7 +144,8 @@ impl ToCommand for common::tmux::Window { if ctx.first { commands.push( - crate::command::Session::new(session_name, &self.name, self.path.clone()).into(), + crate::command::Session::new(session_name, &self.name, ctx.session.root.clone()) + .into(), ); } else { commands.push(Window::new(&self.name, target.clone(), self.path.clone()).into()); diff --git a/load/src/project.rs b/load/src/project.rs index 95329cf..1bc29a5 100644 --- a/load/src/project.rs +++ b/load/src/project.rs @@ -138,9 +138,9 @@ pub fn open(project_name: &str) -> Commands { #[cfg(test)] mod test { - use std::env::temp_dir; use super::*; use common::rand_names; + use std::env::temp_dir; use std::fs; #[test] @@ -153,7 +153,8 @@ mod test { #[test] fn poorly_formatted_file_returns_err() { let name = rand_names::project_file_name(); - let project_paths = ProjectPaths::from_strs(temp_dir().to_str().unwrap(), ".muxed", &name, ""); + let project_paths = + ProjectPaths::from_strs(temp_dir().to_str().unwrap(), ".muxed", &name, ""); let _ = fs::create_dir(&project_paths.project_directory); let mut buffer = File::create(&project_paths.project_file).unwrap(); @@ -169,7 +170,8 @@ mod test { #[test] fn good_file_returns_ok() { let name = rand_names::project_file_name(); - let project_paths = ProjectPaths::from_strs(temp_dir().to_str().unwrap(), ".muxed", &name, ""); + let project_paths = + ProjectPaths::from_strs(temp_dir().to_str().unwrap(), ".muxed", &name, ""); let _ = fs::create_dir(&project_paths.project_directory); let mut buffer = File::create(&project_paths.project_file).unwrap(); diff --git a/load/tests/helpers/mod.rs b/load/tests/helpers/mod.rs index 0f57967..1681f59 100644 --- a/load/tests/helpers/mod.rs +++ b/load/tests/helpers/mod.rs @@ -2,6 +2,7 @@ use common::args::Args; use common::rand_names; +use common::tmux::Session; use rand::random; use snapshot::tmux; use std::fs; @@ -11,13 +12,12 @@ use std::path::{Path, PathBuf}; use std::str; use std::thread::sleep; use std::time::Duration; -use yaml_rust::YamlLoader; fn project_name(contents: &[u8]) -> String { let string_content = str::from_utf8(contents).unwrap(); - let yaml = YamlLoader::load_from_str(string_content).unwrap(); + let session: Session = serde_saphyr::from_str(string_content).unwrap(); - match yaml[0]["name"].as_str() { + match session.name { Some(x) => x.to_string(), None => rand_names::project_file_name(), } @@ -68,7 +68,7 @@ fn open_muxed(project: &str, project_root: &Path) -> Result<(), String> { let args = Args { arg_project: project.to_string(), flag_p: Some(format!("{}", project_root.display())), - flag_debug: false, + flag_debug: true, ..Default::default() }; diff --git a/load/tests/load.rs b/load/tests/load.rs index 84e55c0..be2ebe6 100644 --- a/load/tests/load.rs +++ b/load/tests/load.rs @@ -15,12 +15,13 @@ mod helpers; #[cfg(test)] mod test { mod load { - use std::env::temp_dir; use crate::helpers::test_with_contents; use common::project_paths::homedir; use common::rand_names; + use common::tmux::Session; use dirs::home_dir; use retry_test::retry_test; + use std::env::temp_dir; use std::fs; use std::fs::File; use std::io::prelude::*; @@ -208,35 +209,37 @@ windows: assert_eq!(homedir().unwrap(), pane.path); } - // #[test] - // #[retry_test(3, 10)] - // fn first_window_path_shouldnt_be_default_path() { - // let contents = b"--- - //root: ~/ - //windows: - // - editor: - // panes: - // - ls - // path: /tmp/ - // - other: pwd - //"; - // let session = test_with_contents(contents); - // let window = session.find_window("editor").unwrap(); - // let pane = &window.panes[0]; - // - // assert_eq!( - // PathBuf::from("/tmp/"), - // pane.path - // ); - // - // let window = session.find_window("other").unwrap(); - // let pane = &window.panes[0]; - // - // assert_eq!( - // home_dir().unwrap(), - // pane.path - // ); - // } + #[test] + #[retry_test(3, 10)] + fn first_window_path_shouldnt_be_default_path() { + let file = rand_names::project_file_in_tmp_dir(); + let window_path = file.parent().unwrap(); + let contents = format!( + "--- +root: ~/ +windows: + - editor: + panes: + - ls + path: {} + - other: pwd +", + window_path.display() + ); + let session = test_with_contents(contents.as_bytes()); + let window = session.find_window("editor").unwrap(); + let pane = &window.panes[0]; + + assert_eq!( + temp_dir().canonicalize().unwrap(), + pane.path.canonicalize().unwrap() + ); + + let window = session.find_window("other").unwrap(); + let pane = &window.panes[0]; + + assert_eq!(home_dir().unwrap(), pane.path); + } // TODO: should ssh or git be a command or window name? #[test] @@ -356,16 +359,15 @@ windows: ['ssh', 'git'] // assert_eq!(session.pane_active, "ssh.0") // } - #[test] fn expect_attach_to_session_with_space_in_name() { let contents = "--- name: name with spaces windows: ['ls'] -".to_string(); +" + .to_string(); let session = test_with_contents(contents.as_bytes()); assert_eq!(session.name, "name with spaces"); } } - } diff --git a/new/src/lib.rs b/new/src/lib.rs index c47ab9a..6521991 100644 --- a/new/src/lib.rs +++ b/new/src/lib.rs @@ -114,9 +114,9 @@ where #[cfg(test)] mod test { - use std::env::temp_dir; use super::*; use common::rand_names; + use std::env::temp_dir; use std::fs; use std::fs::File; use std::path::Path; diff --git a/snapshot/src/lib.rs b/snapshot/src/lib.rs index 0105807..4a893b2 100644 --- a/snapshot/src/lib.rs +++ b/snapshot/src/lib.rs @@ -51,9 +51,9 @@ pub fn snapshot(args: Args) -> Result<(), SnapshotError> { #[cfg(test)] mod test { - use std::env::temp_dir; use super::write_config; use common::rand_names; + use std::env::temp_dir; use std::fs; use std::fs::File; use std::io::{Read, Write}; From 62e6595f7c51070e3170a1215af97ff0b2005c7c Mon Sep 17 00:00:00 2001 From: brianp Date: Mon, 10 Nov 2025 01:35:05 +0100 Subject: [PATCH 5/5] test: uncomment previously broken test --- load/tests/load.rs | 47 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/load/tests/load.rs b/load/tests/load.rs index be2ebe6..2e049ed 100644 --- a/load/tests/load.rs +++ b/load/tests/load.rs @@ -18,7 +18,6 @@ mod test { use crate::helpers::test_with_contents; use common::project_paths::homedir; use common::rand_names; - use common::tmux::Session; use dirs::home_dir; use retry_test::retry_test; use std::env::temp_dir; @@ -167,30 +166,28 @@ windows: assert_eq!(pane.path, home_dir().unwrap()); } - // #[test] - // #[retry_test(3, 10)] - // fn expect_window_path_to_take_priority() { - // let dir = PathBuf::from("/tmp/special/"); - // if !dir.exists() { - // println!("{:?}", fs::create_dir(&dir)) - // }; - // let contents = b"--- - //root: ~/ - //windows: - // - editor: - // panes: - // - ls - // path: /tmp/special/ - //"; - // let session = test_with_contents(contents); - // let window = session.find_window("editor").unwrap(); - // let pane = &window.panes[0]; - // - // assert_eq!( - // PathBuf::from("/tmp/special/"), - // pane.path - // ); - // } + #[test] + #[retry_test(3, 10)] + fn expect_window_path_to_take_priority() { + let file = rand_names::project_file_in_tmp_dir(); + let window_path = file.parent().unwrap(); + let contents = format!( + "--- +root: ~/ +windows: + - editor: + panes: + - ls + path: {} +", + window_path.display() + ); + let session = test_with_contents(contents.as_bytes()); + let window = session.find_window("editor").unwrap(); + let pane = &window.panes[0]; + + assert_eq!(window_path.canonicalize().unwrap(), pane.path); + } #[test] #[retry_test(3, 10)]