refactor(dirname): implement pure string manipulation per POSIX (#8936)

This commit is contained in:
Cả thế giới là Rust
2026-01-17 17:36:28 +01:00
committed by GitHub
parent 571e13999a
commit b3ad96f8a0
3 changed files with 151 additions and 58 deletions
+65 -5
View File
@@ -9,6 +9,11 @@ fn test_invalid_arg() {
new_ucmd!().arg("--definitely-invalid").fails_with_code(1);
}
#[test]
fn test_missing_operand() {
new_ucmd!().fails_with_code(1);
}
#[test]
fn test_path_with_trailing_slashes() {
new_ucmd!()
@@ -71,15 +76,11 @@ fn test_dirname_non_utf8_paths() {
use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt;
// Create a test file with non-UTF-8 bytes in the name
let non_utf8_bytes = b"test_\xFF\xFE/file.txt";
let non_utf8_name = OsStr::from_bytes(non_utf8_bytes);
// Test that dirname handles non-UTF-8 paths without crashing
let result = new_ucmd!().arg(non_utf8_name).succeeds();
// Just verify it didn't crash and produced some output
// The exact output format may vary due to lossy conversion
let output = result.stdout_str_lossy();
assert!(!output.is_empty());
assert!(output.contains("test_"));
@@ -156,7 +157,7 @@ fn test_trailing_dot_edge_cases() {
new_ucmd!()
.arg("/home/dos//.")
.succeeds()
.stdout_is("/home/dos/\n");
.stdout_is("/home/dos\n");
// Path with . in middle (should use normal logic)
new_ucmd!()
@@ -216,3 +217,62 @@ fn test_existing_behavior_preserved() {
.succeeds()
.stdout_is("/home/dos\n");
}
#[test]
fn test_multiple_paths_comprehensive() {
// Comprehensive test for multiple paths in single invocation
new_ucmd!()
.args(&[
"/home/dos/.",
"/var/log",
".",
"/tmp/.",
"",
"/",
"relative/path",
])
.succeeds()
.stdout_is("/home/dos\n/var\n.\n/tmp\n.\n/\nrelative\n");
}
#[test]
fn test_all_dot_slash_variations() {
// Tests for all the cases mentioned in issue #8910 comment
// https://github.com/uutils/coreutils/issues/8910#issuecomment-3408735720
new_ucmd!().arg("foo//.").succeeds().stdout_is("foo\n");
new_ucmd!().arg("foo///.").succeeds().stdout_is("foo\n");
new_ucmd!().arg("foo/./").succeeds().stdout_is("foo\n");
new_ucmd!()
.arg("foo/bar/./")
.succeeds()
.stdout_is("foo/bar\n");
new_ucmd!().arg("foo/./bar").succeeds().stdout_is("foo/.\n");
}
#[test]
fn test_dot_slash_component_preservation() {
// Ensure that /. components in the middle are preserved
// These should NOT be normalized away
new_ucmd!().arg("a/./b").succeeds().stdout_is("a/.\n");
new_ucmd!()
.arg("a/./b/./c")
.succeeds()
.stdout_is("a/./b/.\n");
new_ucmd!()
.arg("foo/./bar/baz")
.succeeds()
.stdout_is("foo/./bar\n");
new_ucmd!()
.arg("/path/./to/file")
.succeeds()
.stdout_is("/path/./to\n");
}