From 10135dccef1d3c0844963831acadf1127dbdfb17 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Mon, 15 Mar 2021 13:46:21 +0100 Subject: [PATCH] ls: fix unused import and improve coverage --- src/uu/ls/src/ls.rs | 10 +-- tests/by-util/test_ls.rs | 127 +++++++++++++++++++++++++++++++++++---- 2 files changed, 120 insertions(+), 17 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 24adaa649..5c4cdaa80 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -27,7 +27,9 @@ use std::os::unix::fs::MetadataExt; #[cfg(windows)] use std::os::windows::fs::MetadataExt; use std::path::{Path, PathBuf}; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; +#[cfg(unix)] +use std::time::Duration; +use std::time::{SystemTime, UNIX_EPOCH}; use term_grid::{Cell, Direction, Filling, Grid, GridOptions}; use time::{strftime, Timespec}; @@ -165,7 +167,7 @@ impl Config { "single-column" => Format::OneLine, "columns" => Format::Columns, // below should never happen as clap already restricts the values. - _ => panic!("Invalid field for --format"), + _ => unreachable!("Invalid field for --format"), } } else if options.is_present(options::format::LONG) { Format::Long @@ -192,7 +194,7 @@ impl Config { "time" => Sort::Time, "size" => Sort::Size, // below should never happen as clap already restricts the values. - _ => panic!("Invalid field for --sort"), + _ => unreachable!("Invalid field for --sort"), } } else if options.is_present(options::sort::TIME) { Sort::Time @@ -209,7 +211,7 @@ impl Config { "ctime" | "status" => Time::Change, "access" | "atime" | "use" => Time::Access, // below should never happen as clap already restricts the values. - _ => panic!("Invalid field for --time"), + _ => unreachable!("Invalid field for --time"), } } else if options.is_present(options::time::ACCESS) { Time::Access diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 422db8df9..e8ef18966 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -57,6 +57,36 @@ fn test_ls_a() { assert!(!result.stdout.contains("..")); } +#[test] +fn test_ls_columns() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + at.touch(&at.plus_as_string("test-columns-1")); + at.touch(&at.plus_as_string("test-columns-2")); + + // Columns is the default + let result = scene.ucmd().run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(result.success); + + #[cfg(not(windows))] + assert_eq!(result.stdout, "test-columns-1\ntest-columns-2\n"); + #[cfg(windows)] + assert_eq!(result.stdout, "test-columns-1 test-columns-2\n"); + + for option in &["-C", "--format=columns"] { + let result = scene.ucmd().arg(option).run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(result.success); + #[cfg(not(windows))] + assert_eq!(result.stdout, "test-columns-1\ntest-columns-2\n"); + #[cfg(windows)] + assert_eq!(result.stdout, "test-columns-1 test-columns-2\n"); + } +} + #[test] fn test_ls_long() { #[cfg(not(windows))] @@ -71,16 +101,20 @@ fn test_ls_long() { } } - let (at, mut ucmd) = at_and_ucmd!(); + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; at.touch(&at.plus_as_string("test-long")); - let result = ucmd.arg("-l").arg("test-long").succeeds(); - println!("stderr = {:?}", result.stderr); - println!("stdout = {:?}", result.stdout); - #[cfg(not(windows))] - assert!(result.stdout.contains("-rw-rw-r--")); - #[cfg(windows)] - assert!(result.stdout.contains("---------- 1 somebody somegroup")); + for arg in &["-l", "--long", "--format=long", "--format=verbose"] { + let result = scene.ucmd().arg(arg).arg("test-long").succeeds(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + #[cfg(not(windows))] + assert!(result.stdout.contains("-rw-rw-r--")); + + #[cfg(windows)] + assert!(result.stdout.contains("---------- 1 somebody somegroup")); + } #[cfg(not(windows))] { @@ -90,6 +124,24 @@ fn test_ls_long() { } } +#[test] +fn test_ls_oneline() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + at.touch(&at.plus_as_string("test-oneline-1")); + at.touch(&at.plus_as_string("test-oneline-2")); + + // Bit of a weird situation: in the tests oneline and columns have the same output, + // except on Windows. + for option in &["-1", "--format=single-column"] { + let result = scene.ucmd().arg(option).run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(result.success); + assert_eq!(result.stdout, "test-oneline-1\ntest-oneline-2\n"); + } +} + #[test] fn test_ls_deref() { let scene = TestScenario::new(util_name!()); @@ -166,27 +218,54 @@ fn test_ls_order_size() { } #[test] -fn test_ls_order_creation() { +fn test_ls_long_ctime() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + at.touch("test-long-ctime-1"); + let result = scene.ucmd().arg("-lc").succeeds(); + + // Should show the time on Unix, but question marks on windows. + #[cfg(unix)] + assert!(result.stdout.contains(":")); + #[cfg(not(unix))] + assert!(result.stdout.contains("???")); +} + +#[test] +fn test_ls_order_time() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.touch("test-1"); at.append("test-1", "1"); - sleep(Duration::from_millis(500)); + sleep(Duration::from_millis(100)); at.touch("test-2"); at.append("test-2", "22"); - sleep(Duration::from_millis(500)); + sleep(Duration::from_millis(100)); at.touch("test-3"); at.append("test-3", "333"); - sleep(Duration::from_millis(500)); + sleep(Duration::from_millis(100)); at.touch("test-4"); at.append("test-4", "4444"); + sleep(Duration::from_millis(100)); + + // Read test-3, only changing access time + at.read("test-3"); + + // Set permissions of test-2, only changing ctime + std::fs::set_permissions( + at.plus_as_string("test-2"), + at.metadata("test-2").permissions(), + ) + .unwrap(); let result = scene.ucmd().arg("-al").run(); println!("stderr = {:?}", result.stderr); println!("stdout = {:?}", result.stdout); assert!(result.success); + // ctime was changed at write, so the order is 4 3 2 1 let result = scene.ucmd().arg("-t").run(); println!("stderr = {:?}", result.stderr); println!("stdout = {:?}", result.stdout); @@ -196,7 +275,7 @@ fn test_ls_order_creation() { #[cfg(windows)] assert_eq!(result.stdout, "test-4 test-3 test-2 test-1\n"); - let result = scene.ucmd().arg("-t").arg("-r").run(); + let result = scene.ucmd().arg("-tr").run(); println!("stderr = {:?}", result.stderr); println!("stdout = {:?}", result.stdout); assert!(result.success); @@ -204,6 +283,28 @@ fn test_ls_order_creation() { assert_eq!(result.stdout, "test-1\ntest-2\ntest-3\ntest-4\n"); #[cfg(windows)] assert_eq!(result.stdout, "test-1 test-2 test-3 test-4\n"); + + // 3 was accessed last in the read + // So the order should be 2 3 4 1 + let result = scene.ucmd().arg("-tu").run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(result.success); + #[cfg(not(windows))] + assert_eq!(result.stdout, "test-3\ntest-4\ntest-2\ntest-1\n"); + #[cfg(windows)] + assert_eq!(result.stdout, "test-3 test-4 test-2 test-1\n"); + + // test-2 had the last ctime change when the permissions were set + // So the order should be 2 4 3 1 + #[cfg(unix)] + { + let result = scene.ucmd().arg("-tc").run(); + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(result.success); + assert_eq!(result.stdout, "test-2\ntest-4\ntest-3\ntest-1\n"); + } } #[test]