Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .agents/docs/testing-strategy.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
40 changes: 40 additions & 0 deletions tests/invalid_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Vec<_>>();
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");
Expand Down Expand Up @@ -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(_)));
}
}