From 1e3835fff52389e25d7e55cbcefb35b51cf0176f Mon Sep 17 00:00:00 2001 From: Yunfei He Date: Wed, 15 Jul 2026 16:10:56 +0800 Subject: [PATCH] test: cover Windows invalid drive paths --- .agents/docs/testing-strategy.md | 1 + tests/invalid_encoding.rs | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/.agents/docs/testing-strategy.md b/.agents/docs/testing-strategy.md index 6f60c02..a505543 100644 --- a/.agents/docs/testing-strategy.md +++ b/.agents/docs/testing-strategy.md @@ -36,6 +36,7 @@ The matrix is interaction-aware. A platform root kind must be crossed with encod - An independent public `relative_with` model resolves its own root and component structures without calling SugarPath or `std::path::components`, then checks 40,368 Unix and 161,472 Windows combinations across clean and dirty native spellings. Its dirty absolute cwd contains `..`; Unix comparison is exact, while Windows roots and components compare with ASCII case ignored. - On macOS and Linux, all 224,676 pairs from the bounded short absolute spelling set plus the multibyte set are checked through the production `relative_str` dispatch and the suffix-validation helper against the slow component oracle. - Absolute paths with native-invalid normal components prove that equal raw encoding cancels and distinct encoding with the same lossy rendering does not, through `relative`, `try_relative`, and `relative_with` on Unix and Windows. Unix explicit-cwd rows also prove that relative resolution preserves native-invalid cwd components for borrowed and owned context arguments. +- Windows drive-relative rows apply the same exact comparison before shared-context cancellation and preserve invalid-wide components while resolving against explicit borrowed and owned cwd arguments. - Unavailable Unix cwd coverage pins exact successful output and `Cow` variants for cwd-independent fallible calls, preserves the ambient error and panic checks for dependent `Path`, `str`, and `String` calls, and proves that a valid explicit cwd still succeeds. - Known-UTF-8 `str` and `String` receivers prove exact clean-trailing and dirty normalization contracts, receiver-only borrowing, explicit and ambient relative context forwarding, and cached-cwd behavior on Unix and Windows. Unix deleted-cwd rows also prove cwd-independent success and strict cwd-dependent panics for string receivers. diff --git a/tests/invalid_encoding.rs b/tests/invalid_encoding.rs index 34b3676..be79e3a 100644 --- a/tests/invalid_encoding.rs +++ b/tests/invalid_encoding.rs @@ -339,6 +339,32 @@ mod windows { assert_wide(&distinct_target.relative(&distinct_base), &expected); } + #[test] + fn drive_relative_common_prefix_compares_invalid_encoding_exactly() { + let same_base = invalid_path(r"C:..\segment-", r"\chunks"); + let same_target = invalid_path(r"c:..\segment-", r"\assets"); + let same_expected = r"..\assets".encode_utf16().collect::>(); + assert_wide(&same_target.relative(&same_base), &same_expected); + assert_wide( + &same_target + .try_relative(&same_base) + .expect("matching drive-relative contexts do not need cwd"), + &same_expected, + ); + assert_wide(&same_target.relative_with(&same_base, "not/absolute"), &same_expected); + + let base = invalid_path(r"C:..\segment-", r"\chunks"); + let target = invalid_path_with_unit(r"c:..\segment-", DISTINCT_HIGH_SURROGATE, r"\assets"); + let expected = wide_with_invalid_unit(r"..\..\segment-", DISTINCT_HIGH_SURROGATE, r"\assets"); + + assert_wide(&target.relative(&base), &expected); + assert_wide( + &target.try_relative(&base).expect("matching drive-relative contexts do not need cwd"), + &expected, + ); + assert_wide(&target.relative_with(&base, "not/absolute"), &expected); + } + #[test] fn absolute_relative_common_prefix_compares_invalid_encoding_exactly() { let same_base = invalid_path(r"C:\workspace\segment-", r"\chunks"); @@ -407,4 +433,18 @@ mod windows { expected.extend(r"\file".encode_utf16()); assert_wide(&absolute, &expected); } + + #[test] + fn drive_relative_absolutize_with_preserves_invalid_wide_encoding() { + let input = invalid_path(r"C:pkg\invalid-", r"\.\file"); + let expected = wide_with_invalid(r"C:\workspace\pkg\invalid-", r"\file"); + + let borrowed_cwd = input.absolutize_with(Path::new(r"C:\workspace")); + assert_wide(&borrowed_cwd, &expected); + assert!(matches!(borrowed_cwd, Cow::Owned(_))); + + let owned_cwd = input.absolutize_with(PathBuf::from(r"C:\workspace")); + assert_wide(&owned_cwd, &expected); + assert!(matches!(owned_cwd, Cow::Owned(_))); + } }