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
2 changes: 2 additions & 0 deletions .agents/docs/testing-strategy.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The matrix is interaction-aware. A platform root kind must be crossed with encod
- 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.
- A Windows drive-relative path containing an embedded NUL deterministically fails in `std::path::absolute` before WinAPI dispatch. Native tests require `try_absolutize` and both target/base roles of `try_relative` to preserve the exact error kind and raw OS error, while their strict counterparts panic; CI requires this contract to register in both default and cached-cwd configurations.
- Unavailable Unix cwd coverage pins exact successful output and `Cow` variants for cwd-independent fallible calls, compares dependent fallible calls with the direct `current_dir` error, preserves strict panic checks for `Path`, `str`, and `String` calls, and proves that a valid explicit cwd still succeeds.
- A Unix child process successfully reads cwd before removing that directory, then requires default mode to expose the subsequent ambient error while `cached_current_dir` continues producing exact owned results from the successful process-lifetime snapshot.
- 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 Expand Up @@ -76,4 +77,5 @@ Any change to a public contract, platform branch, native-encoding comparison, cl
- [Known-UTF-8 string receiver ownership](../../tests/string_receiver_contracts.rs)
- [Native-invalid ambient cwd preservation](../../tests/non_utf8_ambient_cwd.rs)
- [Native-invalid exact comparison](../../tests/invalid_encoding.rs)
- [Windows drive-relative error propagation](../../tests/windows_drive_relative_errors.rs)
- [Production dispatch and short-path oracle](../../src/impl_sugar_path.rs)
1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ jobs:
utf8_string_receivers_borrow_only_from_the_receiver
windows_path_equality_does_not_define_normalized_spelling
windows_prefix_like_normal_components_remain_exactly_idempotent
windows_drive_relative_resolution_propagates_native_errors
current_directory_is_cached_only_when_requested
pure_relative_calls_initialize_and_observe_cwd_policy
requested_cached_current_dir_configuration_is_active
Expand Down
57 changes: 57 additions & 0 deletions tests/windows_drive_relative_errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#![cfg(target_family = "windows")]

use std::{io, path::Path};

use sugar_path::SugarPath;

fn assert_same_error(actual: &io::Error, expected: &io::Error, context: &str) {
assert_eq!(actual.kind(), expected.kind(), "{context} error kind");
assert_eq!(actual.raw_os_error(), expected.raw_os_error(), "{context} raw OS error");
}

#[test]
fn windows_drive_relative_resolution_propagates_native_errors() {
let invalid = "C:bad\0path";
let expected = std::path::absolute(invalid).expect_err("an embedded NUL is invalid for WinAPI");
assert_eq!(expected.kind(), io::ErrorKind::InvalidInput);

assert_same_error(
&Path::new(invalid).try_absolutize().expect_err("drive-relative Path should fail"),
&expected,
"Path try_absolutize",
);
assert_same_error(
&invalid.try_absolutize().expect_err("drive-relative str should fail"),
&expected,
"str try_absolutize",
);
let owned = invalid.to_owned();
assert_same_error(
&owned.try_absolutize().expect_err("drive-relative String should fail"),
&expected,
"String try_absolutize",
);
assert!(std::panic::catch_unwind(|| Path::new(invalid).absolutize()).is_err());

let absolute_base = Path::new(r"C:\base");
assert_same_error(
&Path::new(invalid).try_relative(absolute_base).expect_err("drive-relative target should fail"),
&expected,
"try_relative target",
);
assert!(
std::panic::catch_unwind(|| Path::new(invalid).relative(absolute_base)).is_err(),
"strict relative should panic for an invalid drive-relative target",
);

let absolute_target = Path::new(r"C:\target");
assert_same_error(
&absolute_target.try_relative(invalid).expect_err("drive-relative base should fail"),
&expected,
"try_relative base",
);
assert!(
std::panic::catch_unwind(|| absolute_target.relative(invalid)).is_err(),
"strict relative should panic for an invalid drive-relative base",
);
}