From a909ba0e38c8a9057781b6d4909830deb816908f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 12:30:50 +0000 Subject: [PATCH 1/3] Initial plan From ae2a54157b74918ccb01b1ba183ca8486096e51e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 12:43:44 +0000 Subject: [PATCH 2/3] test: Add comprehensive tests for walker-discoveredfile (closes #52) Co-authored-by: jade-codes <9397730+jade-codes@users.noreply.github.com> --- .../src/scanner/tests/tests_walker.rs | 233 ++++++++++++++++++ 1 file changed, 233 insertions(+) diff --git a/crates/mother-core/src/scanner/tests/tests_walker.rs b/crates/mother-core/src/scanner/tests/tests_walker.rs index 65392f5..95509a9 100644 --- a/crates/mother-core/src/scanner/tests/tests_walker.rs +++ b/crates/mother-core/src/scanner/tests/tests_walker.rs @@ -91,3 +91,236 @@ fn test_scanner_root_with_path_buf() { assert_eq!(scanner.root(), path_buf.as_path()); } + +#[test] +fn test_compute_hash_basic() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let file_path = temp_dir.path().join("test.rs"); + let content = "fn main() { println!(\"Hello, world!\"); }"; + fs::write(&file_path, content).expect("Failed to write file"); + + let discovered_file = crate::scanner::DiscoveredFile { + path: file_path, + language: Language::Rust, + }; + + let hash = discovered_file + .compute_hash() + .expect("Failed to compute hash"); + + // SHA-256 hash should be 64 characters (hex representation) + assert_eq!(hash.len(), 64); + assert!(hash.chars().all(|c| c.is_ascii_hexdigit())); +} + +#[test] +fn test_compute_hash_same_content_produces_same_hash() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let file1_path = temp_dir.path().join("file1.rs"); + let file2_path = temp_dir.path().join("file2.rs"); + let content = "fn test() { println!(\"Same content\"); }"; + + fs::write(&file1_path, content).expect("Failed to write file1"); + fs::write(&file2_path, content).expect("Failed to write file2"); + + let file1 = crate::scanner::DiscoveredFile { + path: file1_path, + language: Language::Rust, + }; + let file2 = crate::scanner::DiscoveredFile { + path: file2_path, + language: Language::Rust, + }; + + let hash1 = file1.compute_hash().expect("Failed to compute hash1"); + let hash2 = file2.compute_hash().expect("Failed to compute hash2"); + + assert_eq!(hash1, hash2); +} + +#[test] +fn test_compute_hash_different_content_produces_different_hash() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let file1_path = temp_dir.path().join("file1.rs"); + let file2_path = temp_dir.path().join("file2.rs"); + + fs::write(&file1_path, "fn main() { println!(\"Hello\"); }").expect("Failed to write file1"); + fs::write(&file2_path, "fn main() { println!(\"World\"); }").expect("Failed to write file2"); + + let file1 = crate::scanner::DiscoveredFile { + path: file1_path, + language: Language::Rust, + }; + let file2 = crate::scanner::DiscoveredFile { + path: file2_path, + language: Language::Rust, + }; + + let hash1 = file1.compute_hash().expect("Failed to compute hash1"); + let hash2 = file2.compute_hash().expect("Failed to compute hash2"); + + assert_ne!(hash1, hash2); +} + +#[test] +fn test_compute_hash_empty_file() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let file_path = temp_dir.path().join("empty.rs"); + fs::write(&file_path, "").expect("Failed to write empty file"); + + let discovered_file = crate::scanner::DiscoveredFile { + path: file_path, + language: Language::Rust, + }; + + let hash = discovered_file + .compute_hash() + .expect("Failed to compute hash"); + + // SHA-256 hash of empty string is known + assert_eq!( + hash, + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ); +} + +#[test] +fn test_compute_hash_nonexistent_file_returns_error() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let nonexistent_path = temp_dir.path().join("nonexistent.rs"); + + let discovered_file = crate::scanner::DiscoveredFile { + path: nonexistent_path, + language: Language::Rust, + }; + + let result = discovered_file.compute_hash(); + + assert!(result.is_err()); + assert_eq!( + result + .expect_err("Expected error for nonexistent file") + .kind(), + std::io::ErrorKind::NotFound + ); +} + +#[test] +fn test_compute_hash_large_file() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let file_path = temp_dir.path().join("large.rs"); + // Create a large file content (10KB) + let large_content = "a".repeat(10_000); + fs::write(&file_path, &large_content).expect("Failed to write large file"); + + let discovered_file = crate::scanner::DiscoveredFile { + path: file_path, + language: Language::Rust, + }; + + let hash = discovered_file + .compute_hash() + .expect("Failed to compute hash"); + + // Should still produce a valid 64-character hex hash + assert_eq!(hash.len(), 64); + assert!(hash.chars().all(|c| c.is_ascii_hexdigit())); +} + +#[test] +fn test_compute_hash_binary_content() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let file_path = temp_dir.path().join("binary.rs"); + // Write binary content (including null bytes and non-ASCII) + let binary_content: Vec = vec![0, 1, 2, 255, 127, 128]; + fs::write(&file_path, &binary_content).expect("Failed to write binary file"); + + let discovered_file = crate::scanner::DiscoveredFile { + path: file_path, + language: Language::Rust, + }; + + let hash = discovered_file + .compute_hash() + .expect("Failed to compute hash"); + + // Should handle binary content correctly + assert_eq!(hash.len(), 64); + assert!(hash.chars().all(|c| c.is_ascii_hexdigit())); +} + +#[test] +fn test_compute_hash_with_special_characters() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let file_path = temp_dir.path().join("special.rs"); + let content = "fn main() {\n let emoji = \"🦀\";\n println!(\"Rust {}\", emoji);\n}"; + fs::write(&file_path, content).expect("Failed to write file"); + + let discovered_file = crate::scanner::DiscoveredFile { + path: file_path, + language: Language::Rust, + }; + + let hash = discovered_file + .compute_hash() + .expect("Failed to compute hash"); + + // Should handle Unicode correctly + assert_eq!(hash.len(), 64); + assert!(hash.chars().all(|c| c.is_ascii_hexdigit())); +} + +#[test] +fn test_compute_hash_with_different_line_endings() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let file1_path = temp_dir.path().join("unix.rs"); + let file2_path = temp_dir.path().join("windows.rs"); + + // Unix line endings (LF) + fs::write(&file1_path, "line1\nline2\nline3").expect("Failed to write unix file"); + // Windows line endings (CRLF) + fs::write(&file2_path, "line1\r\nline2\r\nline3").expect("Failed to write windows file"); + + let file1 = crate::scanner::DiscoveredFile { + path: file1_path, + language: Language::Rust, + }; + let file2 = crate::scanner::DiscoveredFile { + path: file2_path, + language: Language::Rust, + }; + + let hash1 = file1.compute_hash().expect("Failed to compute hash1"); + let hash2 = file2.compute_hash().expect("Failed to compute hash2"); + + // Different line endings should produce different hashes + assert_ne!(hash1, hash2); +} + +#[test] +fn test_compute_hash_deterministic() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let file_path = temp_dir.path().join("deterministic.rs"); + let content = "fn test() { return 42; }"; + fs::write(&file_path, content).expect("Failed to write file"); + + let discovered_file = crate::scanner::DiscoveredFile { + path: file_path, + language: Language::Rust, + }; + + // Compute hash multiple times + let hash1 = discovered_file + .compute_hash() + .expect("Failed to compute hash1"); + let hash2 = discovered_file + .compute_hash() + .expect("Failed to compute hash2"); + let hash3 = discovered_file + .compute_hash() + .expect("Failed to compute hash3"); + + // All hashes should be identical + assert_eq!(hash1, hash2); + assert_eq!(hash2, hash3); +} From e349eebfd44217299c1b96fa8cd79132fbe67198 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 12:48:36 +0000 Subject: [PATCH 3/3] Address code review feedback - improve test comments and variable names Co-authored-by: jade-codes <9397730+jade-codes@users.noreply.github.com> --- crates/mother-core/src/scanner/tests/tests_walker.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/mother-core/src/scanner/tests/tests_walker.rs b/crates/mother-core/src/scanner/tests/tests_walker.rs index 95509a9..4e325d7 100644 --- a/crates/mother-core/src/scanner/tests/tests_walker.rs +++ b/crates/mother-core/src/scanner/tests/tests_walker.rs @@ -209,7 +209,7 @@ fn test_compute_hash_nonexistent_file_returns_error() { fn test_compute_hash_large_file() { let temp_dir = TempDir::new().expect("Failed to create temp dir"); let file_path = temp_dir.path().join("large.rs"); - // Create a large file content (10KB) + // Create a large file content (10,000 bytes) let large_content = "a".repeat(10_000); fs::write(&file_path, &large_content).expect("Failed to write large file"); @@ -231,9 +231,9 @@ fn test_compute_hash_large_file() { fn test_compute_hash_binary_content() { let temp_dir = TempDir::new().expect("Failed to create temp dir"); let file_path = temp_dir.path().join("binary.rs"); - // Write binary content (including null bytes and non-ASCII) - let binary_content: Vec = vec![0, 1, 2, 255, 127, 128]; - fs::write(&file_path, &binary_content).expect("Failed to write binary file"); + // Write binary test data (including null bytes and non-ASCII) + let test_binary_data: Vec = vec![0, 1, 2, 255, 127, 128]; + fs::write(&file_path, &test_binary_data).expect("Failed to write binary file"); let discovered_file = crate::scanner::DiscoveredFile { path: file_path,