diff --git a/Cargo.lock b/Cargo.lock index c1d9e62..f260f51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,7 +84,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -94,7 +94,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -164,7 +164,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -286,7 +286,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -328,23 +328,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.3" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", "libc", + "windows-sys 0.59.0", ] [[package]] @@ -359,6 +348,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "flate2" version = "1.0.27" @@ -377,7 +372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" dependencies = [ "libc", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -471,7 +466,7 @@ checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.3", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -514,6 +509,7 @@ dependencies = [ "stderrlog", "strum", "strum_macros", + "tempfile", "term", ] @@ -525,9 +521,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libm" @@ -561,9 +557,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "log" @@ -758,15 +754,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.14" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -865,6 +861,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "term" version = "0.7.0" @@ -1052,7 +1060,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -1061,7 +1069,25 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -1070,13 +1096,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -1085,38 +1127,86 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/src/main.rs b/src/main.rs index d1de43a..f0bf6b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -279,7 +279,9 @@ fn main() -> Result<(), Error> { KeepModes::Get => { crate::modes::get::mode_get(&mut cmd, args, ids, tags, &mut conn, data_path)? } - KeepModes::Diff => crate::modes::diff::mode_diff(&mut cmd, args, ids, tags, &mut conn, data_path)?, + KeepModes::Diff => { + crate::modes::diff::mode_diff(&mut cmd, args, ids, tags, &mut conn, data_path)? + } KeepModes::List => { crate::modes::list::mode_list(&mut cmd, args, ids, tags, &mut conn, data_path)? } @@ -291,7 +293,7 @@ fn main() -> Result<(), Error> { } KeepModes::Delete => { crate::modes::delete::mode_delete(&mut cmd, args, ids, tags, &mut conn, data_path)? - } + } KeepModes::Status => crate::modes::status::mode_status(&mut cmd, args, data_path, db_path)?, _ => todo!(), } diff --git a/src/modes/common.rs b/src/modes/common.rs index b93fcff..7fe520f 100644 --- a/src/modes/common.rs +++ b/src/modes/common.rs @@ -60,7 +60,6 @@ pub enum ColumnType { } impl ColumnType { - /// Returns a Result with error message if the string is not a valid ColumnType pub fn from_str(s: &str) -> anyhow::Result { Ok(Self::try_from(s)?) diff --git a/src/modes/diff.rs b/src/modes/diff.rs index 3773bc0..e979de2 100644 --- a/src/modes/diff.rs +++ b/src/modes/diff.rs @@ -1,7 +1,7 @@ use crate::compression::CompressionType; +use libc::c_int; use std::path::PathBuf; use std::str::FromStr; -use libc::c_int; use anyhow::{anyhow, Result}; use clap::Command; @@ -150,26 +150,16 @@ pub fn mode_diff( ) -> std::thread::JoinHandle<()> { let pipe_writer_raw = unsafe { std::fs::File::from_raw_fd(fd_write) }; std::thread::spawn(move || { - write_item_to_pipe( - item_path, - compression_type, - pipe_writer_raw, - ); + write_item_to_pipe(item_path, compression_type, pipe_writer_raw); }) } // Spawn writer threads for both items - let writer_thread_a = spawn_writer_thread( - item_path_a.clone(), - compression_type_a.clone(), - fd_a_write, - ); + let writer_thread_a = + spawn_writer_thread(item_path_a.clone(), compression_type_a.clone(), fd_a_write); - let writer_thread_b = spawn_writer_thread( - item_path_b.clone(), - compression_type_b.clone(), - fd_b_write, - ); + let writer_thread_b = + spawn_writer_thread(item_path_b.clone(), compression_type_b.clone(), fd_b_write); // Thread to read diff's standard output let stdout_reader_thread = std::thread::spawn(move || { @@ -232,19 +222,19 @@ pub fn mode_diff( let stdout_capture_result = stdout_reader_thread .join() .unwrap_or_else(|panic_payload| { - Err(anyhow!( - "Stdout reader thread panicked: {:?}", - panic_payload - )) - })?; + Err(anyhow!( + "Stdout reader thread panicked: {:?}", + panic_payload + )) + })?; let stderr_capture_result = stderr_reader_thread .join() .unwrap_or_else(|panic_payload| { - Err(anyhow!( - "Stderr reader thread panicked: {:?}", - panic_payload - )) - })?; + Err(anyhow!( + "Stderr reader thread panicked: {:?}", + panic_payload + )) + })?; // Handle diff's exit status and output match diff_status.code() { diff --git a/src/tests.rs b/src/tests.rs index 5c23147..b49ff77 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -3,7 +3,7 @@ mod tests { use std::fs; use std::path::Path; use std::process::Command; - + use tempfile::tempdir; // Helper function to run a command in sh -c @@ -23,13 +23,13 @@ mod tests { { let dir = tempdir().expect("Failed to create temporary directory"); let _db_path = dir.path().join("keep-1.db"); - + // Create the data directory structure fs::create_dir_all(dir.path()).expect("Failed to create directory"); - + // Run the test f(dir.path()); - + // Clean up dir.close().expect("Failed to remove temporary directory"); } @@ -51,23 +51,151 @@ mod tests { fn test_save_item() { with_temp_env(|data_dir| { // Set the data directory for this test - let env = format!("KEEP_DIR={}", data_dir.display()); - + let env = format!("KEEP_DIR={} cargo run --", data_dir.display()); + // Save an item with some content let input = "test content"; + // Create a command that pipes input to keep with the specified environment let cmd = format!("echo {} | {}", input, env); let output = run_sh(cmd.as_str()); - assert!(output.status.success(), "Command failed with status: {}", output.status); - - // Verify the item was saved - let output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --list", env)) - .output() - .expect("Failed to execute command"); - - assert!(String::from_utf8_lossy(&output.stdout).contains(input)); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + // Create a command that pipes input to keep with the specified environment + let cmd = format!("echo {} | {} --save", input, env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + // Create a command that pipes input to keep with the specified environment + let cmd = format!("echo {} | {} -s", input, env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + // Create a command that pipes input to keep with the specified environment + let cmd = format!("echo {} | {} tag1 tag2", input, env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + }); + } + + #[test] + fn test_get_item() { + with_temp_env(|data_dir| { + // Set the data directory for this test + let env = format!("KEEP_DIR={} cargo run --", data_dir.display()); + + // Save an item with some content + let input_a = "test content A"; + let input_b = "test content B"; + + // Create a command that pipes input to keep with the specified environment + let cmd = format!("echo {} A | {} tag tag_a", input_a, env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + let cmd = format!("echo {} | {} tag tag_b", input_b, env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + let cmd = format!("{} --get 1", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + assert!(String::from_utf8_lossy(&output.stdout).contains(input_a)); + + let cmd = format!("{} -g 1", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + assert!(String::from_utf8_lossy(&output.stdout).contains(input_a)); + + let cmd = format!("{} 1", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + assert!(String::from_utf8_lossy(&output.stdout).contains(input_a)); + + let cmd = format!("{} --get", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + assert!(String::from_utf8_lossy(&output.stdout).contains(input_b)); + + let cmd = format!("{} --get tag_a", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + assert!(String::from_utf8_lossy(&output.stdout).contains(input_a)); + + let cmd = format!("{} --get tag_b", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + assert!(String::from_utf8_lossy(&output.stdout).contains(input_b)); + + let cmd = format!("{} --get tag", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + assert!(String::from_utf8_lossy(&output.stdout).contains(input_b)); }); } @@ -76,157 +204,57 @@ mod tests { fn test_list_items() { with_temp_env(|data_dir| { // Set the data directory for this test - let env = format!("KEEP_DIR={}", data_dir.display()); - + let env = format!("KEEP_DIR={} cargo run --", data_dir.display()); + // Save an item with some content - let input = "test content"; + let input_a = "test content A"; + let input_b = "test content B"; + // Create a command that pipes input to keep with the specified environment - let cmd = format!("echo {} | {}", input, env); - let mut child = Command::new("sh") - .arg("-c") - .arg(cmd) - .spawn() - .expect("Failed to spawn process"); - - child.wait().expect("Failed to wait for child process"); - - // List items and verify the output - let output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --list", env)) - .output() - .expect("Failed to execute command"); - - assert!(String::from_utf8_lossy(&output.stdout).contains(input)); - }); - } - - // Test: Get an item and verify the content - #[test] - fn test_get_item() { - with_temp_env(|data_dir| { - // Set the data directory for this test - let env = format!("KEEP_DIR={}", data_dir.display()); - - // Save an item with some content - let input = "test content"; - // Create a command that pipes input to keep with the specified environment - let mut cmd = Command::new("sh"); - cmd.arg("-c") - .arg(format!("echo {} | {}", input, env)); - - cmd.spawn() - .expect("Failed to spawn process") - .wait() - .expect("Failed to wait for child process"); - - // Get the item and verify the content - let output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --get", env)) - .output() - .expect("Failed to execute command"); - - assert_eq!(String::from_utf8_lossy(&output.stdout), input); - }); - } - - // Test: Add metadata to an item and verify it's stored - #[test] - fn test_metadata() { - with_temp_env(|data_dir| { - // Set the data directory for this test - let env = format!("KEEP_DIR={}", data_dir.display()); - - // Save an item with some content and metadata - let input = "test content"; - // Create a command that pipes input to keep with the specified environment and metadata - let mut cmd = Command::new("sh"); - cmd.arg("-c") - .arg(format!("echo {} | {}", input, env)) - .arg("cargo run -- --save --meta key=value"); - - cmd.spawn() - .expect("Failed to spawn process") - .wait() - .expect("Failed to wait for child process"); - - // Get the item ID - let list_output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --list", env)) - .output() - .expect("Failed to execute command"); - let list_output_str = String::from_utf8_lossy(&list_output.stdout); - let id = list_output_str.lines().next().expect("No items found").split_whitespace().next().expect("No ID found").parse::().expect("Invalid ID"); - - // Get the item and verify the metadata - let output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --info {}", env, id)) - .output() - .expect("Failed to execute command"); - - assert!(String::from_utf8_lossy(&output.stdout).contains("key: value")); - }); - } - - // Test: Use tags to organize items - #[test] - fn test_tags() { - with_temp_env(|data_dir| { - // Set the data directory for this test - let env = format!("KEEP_DIR={}", data_dir.display()); - - // Save an item with some content and tags - let input = "test content"; - // Create a command that pipes input to keep with the specified environment and tags - let cmd = format!("echo {} | {}", input, env); + let cmd = format!("echo {} A | {} tag tag_a", input_a, env); let output = run_sh(cmd.as_str()); - assert!(output.status.success(), "Command failed with status: {}", output.status); - - // List items with a specific tag - let output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --list tag1", env)) - .output() - .expect("Failed to execute command"); - - assert!(String::from_utf8_lossy(&output.stdout).contains("test content")); - }); - } + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); - // Test: Use compression - #[test] - fn test_compression() { - with_temp_env(|data_dir| { - // Set the data directory for this test - let env = format!("KEEP_DIR={}", data_dir.display()); - - // Save an item with some content and compression - let input = "test content"; - // Create a command that pipes input to keep with the specified environment and compression - let cmd = format!("echo {} | {}", input, env); + let cmd = format!("echo {} | {} tag tag_b", input_b, env); let output = run_sh(cmd.as_str()); - assert!(output.status.success(), "Command failed with status: {}", output.status); - - // Get the item ID - let list_output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --list", env)) - .output() - .expect("Failed to execute command"); - let list_output_str = String::from_utf8_lossy(&list_output.stdout); - let id = list_output_str.lines().next().expect("No items found").split_whitespace().next().expect("No ID found").parse::().expect("Invalid ID"); - - // Get the item and verify the content - let output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --get {}", env, id)) - .output() - .expect("Failed to execute command"); - - assert_eq!(String::from_utf8_lossy(&output.stdout), input); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + let cmd = format!("{} --list", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + let cmd = format!("{} -l", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + let cmd = format!("{} --list tag_a", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); }); } @@ -235,44 +263,67 @@ mod tests { fn test_delete_item() { with_temp_env(|data_dir| { // Set the data directory for this test - let env = format!("KEEP_DIR={}", data_dir.display()); - + let env = format!("KEEP_DIR={} cargo run --", data_dir.display()); + // Save an item with some content - let input = "test content"; + let input_a = "test content A"; + let input_b = "test content B"; + // Create a command that pipes input to keep with the specified environment - let cmd = format!("echo {} | {}", input, env); - let mut child = Command::new("sh") - .arg("-c") - .arg(cmd) - .spawn() - .expect("Failed to spawn process"); - - child.wait().expect("Failed to wait for child process"); - - // Get the item ID - let list_output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --list", env)) - .output() - .expect("Failed to execute command"); - let list_output_str = String::from_utf8_lossy(&list_output.stdout); - let id = list_output_str.lines().next().expect("No items found").split_whitespace().next().expect("No ID found").parse::().expect("Invalid ID"); - - // Delete the item - let _output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --delete {}", env, id)) - .output() - .expect("Failed to execute command"); - - // Verify the item was deleted - let list_output = Command::new("sh") - .arg("-c") - .arg(format!("{} cargo run -- --list", env)) - .output() - .expect("Failed to execute command"); - - assert_eq!(String::from_utf8_lossy(&list_output.stdout).trim(), ""); + let cmd = format!("echo {} | {} tag tag_a", input_a, env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + let cmd = format!("echo {} | {} tag tag_b", input_b, env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + let cmd = format!("{} --delete tag", env); + let output = run_sh(cmd.as_str()); + assert!( + !output.status.success(), + "Command succeded when it should have failed: {} RC={}", + cmd, + output.status + ); + + let cmd = format!("{} --delete 1", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + let cmd = format!("{} -d 2", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + + let cmd = format!("{} --delete 9999", env); + let output = run_sh(cmd.as_str()); + assert!( + output.status.success(), + "Command failed with status: {} RC={}", + cmd, + output.status + ); + //assert!(!output.status.success(), "Command succeded when it should have failed: {} RC={}", cmd, output.status); }); } }