33// For the full copyright and license information, please view the LICENSE
44// file that was distributed with this source code.
55// spell-checker:ignore (words) READMECAREFULLY birthtime doesntexist oneline somebackup lrwx somefile somegroup somehiddenbackup somehiddenfile tabsize aaaaaaaa bbbb cccc dddddddd ncccc neee naaaaa nbcdef nfffff dired subdired tmpfs mdir COLORTERM mexe bcdef mfoo timefile
6- // spell-checker:ignore (words) fakeroot setcap drwxr bcdlps
6+ // spell-checker:ignore (words) fakeroot setcap drwxr bcdlps mdangling mentry
77#![ allow(
88 clippy:: similar_names,
99 clippy:: too_many_lines,
@@ -1446,31 +1446,213 @@ fn test_ls_long_dangling_symlink_color() {
14461446
14471447 at. mkdir ( "dir1" ) ;
14481448 at. symlink_dir ( "foo" , "dir1/dangling_symlink" ) ;
1449+ let ls_colors = "ln=target:or=40:mi=34" ;
14491450 let result = ts
14501451 . ucmd ( )
1452+ . env ( "LS_COLORS" , ls_colors)
14511453 . arg ( "-l" )
14521454 . arg ( "--color=always" )
14531455 . arg ( "dir1/dangling_symlink" )
14541456 . succeeds ( ) ;
14551457
14561458 let stdout = result. stdout_str ( ) ;
1457- // stdout contains output like in the below sequence. We match for the color i.e. 01;36
1458- // \x1b[0m\x1b[01;36mdir1/dangling_symlink\x1b[0m -> \x1b[01;36mfoo\x1b[0m
1459- let color_regex = Regex :: new ( r"(\d\d;)\d\dm" ) . unwrap ( ) ;
1460- // colors_vec[0] contains the symlink color and style and colors_vec[1] contains the color and style of the file the
1461- // symlink points to.
1462- let colors_vec: Vec < _ > = color_regex
1463- . find_iter ( stdout)
1464- . map ( |color| color. as_str ( ) )
1465- . collect ( ) ;
1459+ // Ensure dangling link name uses `or=` and target uses `mi=`.
1460+ let name_regex =
1461+ Regex :: new ( r"(?:\x1b\[[0-9;]*m)*\x1b\[([0-9;]*)mdir1/dangling_symlink\x1b\[0m" ) . unwrap ( ) ;
1462+ let target_path = regex:: escape ( & at. plus_as_string ( "foo" ) ) ;
1463+ let target_pattern = format ! ( r"(?:\x1b\[[0-9;]*m)*\x1b\[([0-9;]*)m{target_path}\x1b\[0m" ) ;
1464+ let target_regex = Regex :: new ( & target_pattern) . unwrap ( ) ;
1465+
1466+ let name_caps = name_regex
1467+ . captures ( stdout)
1468+ . expect ( "failed to capture dangling symlink name color" ) ;
1469+ let target_caps = target_regex
1470+ . captures ( stdout)
1471+ . expect ( "failed to capture dangling target color" ) ;
1472+
1473+ let name_color = name_caps. get ( 1 ) . unwrap ( ) . as_str ( ) ;
1474+ let target_color = target_caps. get ( 1 ) . unwrap ( ) . as_str ( ) ;
1475+
1476+ assert_eq ! ( name_color, "40" ) ;
1477+ assert_eq ! ( target_color, "34" ) ;
1478+ }
1479+
1480+ #[ test]
1481+ /// Mirrors GNU `tests/ls/ls-misc.pl::sl-dangle3`.
1482+ fn test_ls_dangling_symlink_or_and_missing_colors ( ) {
1483+ let ts = TestScenario :: new ( util_name ! ( ) ) ;
1484+ let at = & ts. fixtures ;
1485+ at. symlink_file ( "nowhere" , "dangling" ) ;
1486+
1487+ let stdout = ts
1488+ . ucmd ( )
1489+ . env ( "LS_COLORS" , "ln=target:or=40:mi=34" )
1490+ . arg ( "-o" )
1491+ . arg ( "--time-style=+:TIME:" )
1492+ . arg ( "--color=always" )
1493+ . arg ( "dangling" )
1494+ . succeeds ( )
1495+ . stdout_str ( )
1496+ . to_string ( ) ;
14661497
1467- assert_eq ! ( colors_vec[ 0 ] , colors_vec[ 1 ] ) ;
1468- // constructs the string of file path with the color code
1469- let symlink_color_name = colors_vec[ 0 ] . to_owned ( ) + "dir1/dangling_symlink\x1b " ;
1470- let target_color_name = colors_vec[ 1 ] . to_owned ( ) + at. plus_as_string ( "foo\x1b " ) . as_str ( ) ;
1498+ let color_regex = Regex :: new (
1499+ r"\x1b\[0m\x1b\[(?P<link>[0-9;]*)mdangling\x1b\[0m -> \x1b\[(?P<target>[0-9;]*)m" ,
1500+ )
1501+ . unwrap ( ) ;
1502+ let captures = color_regex
1503+ . captures ( & stdout)
1504+ . expect ( "failed to capture dangling colors" ) ;
14711505
1472- assert ! ( stdout. contains( & symlink_color_name) ) ;
1473- assert ! ( stdout. contains( & target_color_name) ) ;
1506+ assert_eq ! ( captures. name( "link" ) . unwrap( ) . as_str( ) , "40" ) ;
1507+ assert_eq ! ( captures. name( "target" ) . unwrap( ) . as_str( ) , "34" ) ;
1508+ }
1509+
1510+ #[ test]
1511+ /// Mirrors GNU `tests/ls/ls-misc.pl::sl-dangle4`.
1512+ fn test_ls_dangling_symlink_ln_or_priority ( ) {
1513+ let ts = TestScenario :: new ( util_name ! ( ) ) ;
1514+ let at = & ts. fixtures ;
1515+ at. symlink_file ( "nowhere" , "dangling" ) ;
1516+
1517+ let stdout = ts
1518+ . ucmd ( )
1519+ . env ( "LS_COLORS" , "ln=34:mi=35:or=36" )
1520+ . arg ( "-o" )
1521+ . arg ( "--time-style=+:TIME:" )
1522+ . arg ( "--color=always" )
1523+ . arg ( "dangling" )
1524+ . succeeds ( )
1525+ . stdout_str ( )
1526+ . to_string ( ) ;
1527+
1528+ let color_regex = Regex :: new (
1529+ r"\x1b\[0m\x1b\[(?P<link>[0-9;]*)mdangling\x1b\[0m -> \x1b\[(?P<target>[0-9;]*)m" ,
1530+ )
1531+ . unwrap ( ) ;
1532+ let captures = color_regex
1533+ . captures ( & stdout)
1534+ . expect ( "failed to capture dangling colors" ) ;
1535+ assert_eq ! ( captures. name( "link" ) . unwrap( ) . as_str( ) , "36" ) ;
1536+ assert_eq ! ( captures. name( "target" ) . unwrap( ) . as_str( ) , "35" ) ;
1537+ }
1538+
1539+ #[ test]
1540+ /// Mirrors GNU `tests/ls/ls-misc.pl::sl-dangle5`.
1541+ fn test_ls_dangling_symlink_ln_and_missing_colors ( ) {
1542+ let ts = TestScenario :: new ( util_name ! ( ) ) ;
1543+ let at = & ts. fixtures ;
1544+ at. symlink_file ( "nowhere" , "dangling" ) ;
1545+
1546+ let stdout = ts
1547+ . ucmd ( )
1548+ . env ( "LS_COLORS" , "ln=34:mi=35" )
1549+ . arg ( "-o" )
1550+ . arg ( "--time-style=+:TIME:" )
1551+ . arg ( "--color=always" )
1552+ . arg ( "dangling" )
1553+ . succeeds ( )
1554+ . stdout_str ( )
1555+ . to_string ( ) ;
1556+
1557+ let color_regex = Regex :: new (
1558+ r"\x1b\[0m\x1b\[(?P<link>[0-9;]*)mdangling\x1b\[0m -> \x1b\[(?P<target>[0-9;]*)m" ,
1559+ )
1560+ . unwrap ( ) ;
1561+ let captures = color_regex
1562+ . captures ( & stdout)
1563+ . expect ( "failed to capture dangling colors" ) ;
1564+ assert_eq ! ( captures. name( "link" ) . unwrap( ) . as_str( ) , "34" ) ;
1565+ assert_eq ! ( captures. name( "target" ) . unwrap( ) . as_str( ) , "35" ) ;
1566+ }
1567+
1568+ #[ test]
1569+ /// Mirrors GNU `tests/ls/ls-misc.pl::sl-dangle7`.
1570+ fn test_ls_dangling_symlink_blank_or_still_emits_reset ( ) {
1571+ let ts = TestScenario :: new ( util_name ! ( ) ) ;
1572+ let at = & ts. fixtures ;
1573+ at. symlink_file ( "nowhere" , "dangling" ) ;
1574+
1575+ let stdout = ts
1576+ . ucmd ( )
1577+ . env ( "LS_COLORS" , "ln=target:or=:ex=:" )
1578+ . arg ( "--color=always" )
1579+ . arg ( "dangling" )
1580+ . succeeds ( )
1581+ . stdout_str ( )
1582+ . to_string ( ) ;
1583+
1584+ assert ! (
1585+ stdout. contains( "\u{1b} [0m\u{1b} [mdangling\u{1b} [0m" ) ,
1586+ "unexpected output: {stdout:?}"
1587+ ) ;
1588+ }
1589+
1590+ #[ test]
1591+ /// Mirrors GNU `tests/ls/ls-misc.pl::sl-dangle9`.
1592+ fn test_ls_dangling_symlink_blank_or_in_directory_listing ( ) {
1593+ let ts = TestScenario :: new ( util_name ! ( ) ) ;
1594+ let at = & ts. fixtures ;
1595+ at. mkdir ( "dir" ) ;
1596+ at. symlink_file ( "nowhere" , "dir/entry" ) ;
1597+
1598+ let stdout = ts
1599+ . ucmd ( )
1600+ . env ( "LS_COLORS" , "ln=target:or=:ex=:" )
1601+ . arg ( "--color=always" )
1602+ . arg ( "dir" )
1603+ . succeeds ( )
1604+ . stdout_str ( )
1605+ . to_string ( ) ;
1606+
1607+ assert ! (
1608+ stdout. contains( "\u{1b} [0m\u{1b} [mentry\u{1b} [0m" ) ,
1609+ "unexpected output: {stdout:?}"
1610+ ) ;
1611+ }
1612+
1613+ #[ test]
1614+ /// Mirrors GNU `tests/ls/ls-misc.pl::sl-dangle8`.
1615+ fn test_ls_dangling_symlink_uses_ln_when_or_blank ( ) {
1616+ let ts = TestScenario :: new ( util_name ! ( ) ) ;
1617+ let at = & ts. fixtures ;
1618+ at. symlink_file ( "nowhere" , "dangling" ) ;
1619+
1620+ let stdout = ts
1621+ . ucmd ( )
1622+ . env ( "LS_COLORS" , "ln=1;36:or=:" )
1623+ . arg ( "--color=always" )
1624+ . arg ( "dangling" )
1625+ . succeeds ( )
1626+ . stdout_str ( )
1627+ . to_string ( ) ;
1628+
1629+ assert ! (
1630+ stdout. contains( "\u{1b} [0m\u{1b} [1;36mdangling\u{1b} [0m" ) ,
1631+ "unexpected output: {stdout:?}"
1632+ ) ;
1633+ }
1634+
1635+ #[ test]
1636+ /// Mirrors GNU `tests/ls/ls-misc.pl::sl-dangle6`.
1637+ fn test_ls_directory_dangling_symlink_uses_ln_when_or_blank ( ) {
1638+ let ts = TestScenario :: new ( util_name ! ( ) ) ;
1639+ let at = & ts. fixtures ;
1640+ at. mkdir ( "dir" ) ;
1641+ at. symlink_file ( "nowhere" , "dir/entry" ) ;
1642+
1643+ let stdout = ts
1644+ . ucmd ( )
1645+ . env ( "LS_COLORS" , "ln=1;36:or=:" )
1646+ . arg ( "--color=always" )
1647+ . arg ( "dir" )
1648+ . succeeds ( )
1649+ . stdout_str ( )
1650+ . to_string ( ) ;
1651+
1652+ assert ! (
1653+ stdout. contains( "\u{1b} [0m\u{1b} [1;36mentry\u{1b} [0m" ) ,
1654+ "unexpected output: {stdout:?}"
1655+ ) ;
14741656}
14751657
14761658#[ test]
@@ -5862,8 +6044,7 @@ fn test_ls_color_norm() {
58626044 . stdout_contains ( expected) ;
58636045
58646046 // uncolored ordinary files that do _not_ inherit from NORMAL.
5865- let expected =
5866- "\x1b [0m\x1b [07mnorm \x1b [0mno_color\x1b [0m\n \x1b [07mnorm \x1b [0m\x1b [01;32mexe\x1b [0m\n " ; // spell-checker:disable-line
6047+ let expected = "\x1b [0m\x1b [07mnorm \x1b [0m\x1b [mno_color\x1b [0m\n \x1b [07mnorm \x1b [0m\x1b [01;32mexe\x1b [0m\n " ; // spell-checker:disable-line
58676048 scene
58686049 . ucmd ( )
58696050 . env ( "LS_COLORS" , format ! ( "{colors}:fi=" ) )
@@ -5876,8 +6057,7 @@ fn test_ls_color_norm() {
58766057 . stdout_str_apply ( strip)
58776058 . stdout_contains ( expected) ;
58786059
5879- let expected =
5880- "\x1b [0m\x1b [07mnorm \x1b [0mno_color\x1b [0m\n \x1b [07mnorm \x1b [0m\x1b [01;32mexe\x1b [0m\n " ; // spell-checker:disable-line
6060+ let expected = "\x1b [0m\x1b [07mnorm \x1b [0m\x1b [00mno_color\x1b [0m\n \x1b [07mnorm \x1b [0m\x1b [01;32mexe\x1b [0m\n " ; // spell-checker:disable-line
58816061 scene
58826062 . ucmd ( )
58836063 . env ( "LS_COLORS" , format ! ( "{colors}:fi=0" ) )
@@ -6498,7 +6678,7 @@ fn test_f_overrides_sort_flags() {
64986678
64996679 // Create files with different sizes for predictable sort order
65006680 at. write ( "small.txt" , "a" ) ; // 1 byte
6501- at. write ( "medium.txt" , "bb" ) ; // 2 bytes
6681+ at. write ( "medium.txt" , "bb" ) ; // 2 bytes
65026682 at. write ( "large.txt" , "ccc" ) ; // 3 bytes
65036683
65046684 // Get baseline outputs (include -a to match -f behavior which shows all files)
0 commit comments