use super::*; use crate::display::DisplayData; use display::format_string; use std::fs::File; use std::io::Write; use std::panic; use std::path::PathBuf; use std::process::Command; use tempfile::Builder; use tempfile::TempDir; // fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable #[cfg_attr(target_os = "windows", ignore)] #[test] pub fn test_main() { assert_cli::Assert::main_binary() .with_args(&["src/test_dir"]) .stdout() .is(main_output(true).as_str()) .unwrap(); } // fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable #[cfg_attr(target_os = "windows", ignore)] #[test] pub fn test_main_long_paths() { assert_cli::Assert::main_binary() .with_args(&["-p", "src/test_dir"]) .stdout() .is(main_output(false).as_str()) .unwrap(); } // fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable #[cfg_attr(target_os = "windows", ignore)] #[test] pub fn test_main_multi_arg() { assert_cli::Assert::main_binary() .with_args(&["src/test_dir/many/", "src/test_dir/", "src/test_dir"]) .stdout() .is(main_output(true).as_str()) .unwrap(); } #[cfg(target_os = "macos")] fn main_output(short_paths: bool) -> String { let d = DisplayData { short_paths, is_reversed: false, colors_on: true, }; format!( "{} {} {} {}", format_string("src/test_dir", true, &d, " 4.0K", "─┬"), format_string("src/test_dir/many", true, &d, " 4.0K", " └─┬",), format_string("src/test_dir/many/hello_file", true, &d, " 4.0K", " ├──",), format_string("src/test_dir/many/a_file", false, &d, " 0B", " └──",), ) } #[cfg(target_os = "linux")] fn main_output(short_paths: bool) -> String { let d = DisplayData { short_paths, is_reversed: false, colors_on: true, }; format!( "{} {} {} {}", format_string("src/test_dir", true, &d, " 12K", "─┬"), format_string("src/test_dir/many", true, &d, " 8.0K", " └─┬",), format_string("src/test_dir/many/hello_file", true, &d, " 4.0K", " ├──",), format_string("src/test_dir/many/a_file", false, &d, " 0B", " └──",), ) } #[cfg(target_os = "windows")] fn main_output(short_paths: bool) -> String { let d = DisplayData { short_paths, is_reversed: false, colors_on: true, }; format!( "{} {} {} {}", format_string("src/test_dir", true, &d, " 6B", "─┬"), format_string("src/test_dir\\many", true, &d, " 6B", " └─┬",), format_string( "src/test_dir\\many\\hello_file", true, &d, " 6B", " ├──", ), format_string("src/test_dir\\many\\a_file", false, &d, " 0B", " └──",), ) } // fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable #[cfg_attr(target_os = "windows", ignore)] #[test] pub fn test_no_color_flag() { assert_cli::Assert::main_binary() .with_args(&["-c", "src/test_dir/"]) .stdout() .is(no_color_flag_output().as_str()) .unwrap(); } #[cfg(target_os = "macos")] fn no_color_flag_output() -> String { " 4.0K ─┬ test_dir 4.0K └─┬ many 4.0K ├── hello_file 0B └── a_file " .to_string() } #[cfg(target_os = "linux")] fn no_color_flag_output() -> String { " 12K ─┬ test_dir 8.0K └─┬ many 4.0K ├── hello_file 0B └── a_file " .to_string() } #[cfg(target_os = "windows")] fn no_color_flag_output() -> String { " 6B ─┬ test_dir 6B └─┬ many 6B ├── hello_file 0B └── a_file " .to_string() } // fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable #[cfg_attr(target_os = "windows", ignore)] #[test] pub fn test_apparent_size() { let d = DisplayData { short_paths: true, is_reversed: false, colors_on: true, }; let r = format!( "{}", format_string("src/test_dir/many/hello_file", true, &d, " 6B", " ├──",), ); assert_cli::Assert::main_binary() .with_args(&["-s", "src/test_dir"]) .stdout() .contains(r.as_str()) .unwrap(); } #[test] pub fn test_reverse_flag() { // variable names the same length make the output easier to read let a = " ┌── a_file"; let b = " ├── hello_file"; let c = " ┌─┴ many"; let d = " ─┴ test_dir"; assert_cli::Assert::main_binary() .with_args(&["-r", "src/test_dir"]) .stdout() .contains(a) .stdout() .contains(b) .stdout() .contains(c) .stdout() .contains(d) .unwrap(); } #[test] pub fn test_d_flag_works() { // We should see the top level directory but not the sub dirs / files: assert_cli::Assert::main_binary() .with_args(&["-d", "1", "-s", "src/test_dir"]) .stdout() .doesnt_contain("hello_file") .unwrap(); } fn build_temp_file(dir: &TempDir) -> PathBuf { let file_path = dir.path().join("notes.txt"); let mut file = File::create(&file_path).unwrap(); writeln!(file, "I am a temp file").unwrap(); file_path } // fix! [rivy; 2020-01-22] possible on "windows"?; `ln` is not usually an available command; creation of symbolic links requires special enhanced permissions // ... ref: @@ #[cfg_attr(target_os = "windows", ignore)] #[test] pub fn test_soft_sym_link() { let dir = Builder::new().tempdir().unwrap(); let file = build_temp_file(&dir); let dir_s = dir.path().to_str().unwrap(); let file_path_s = file.to_str().unwrap(); let link_name = dir.path().join("the_link"); let link_name_s = link_name.to_str().unwrap(); let c = Command::new("ln") .arg("-s") .arg(file_path_s) .arg(link_name_s) .output(); assert!(c.is_ok()); let a = format!(" ─┬ {}", dir_s); let b = format!(" ├── {}", file_path_s); let c = format!(" └── {}", link_name_s); assert_cli::Assert::main_binary() .with_args(&["-p", &dir_s]) .stdout() .contains(a.as_str()) .stdout() .contains(b.as_str()) .stdout() .contains(c.as_str()) .unwrap(); } // Hard links are ignored as the inode is the same as the file // fix! [rivy; 2020-01-22] may fail on "usual" windows hosts as `ln` is not usually an available command #[test] pub fn test_hard_sym_link() { let dir = Builder::new().tempdir().unwrap(); let file = build_temp_file(&dir); let dir_s = dir.path().to_str().unwrap(); let file_path_s = file.to_str().unwrap(); let link_name = dir.path().join("the_link"); let link_name_s = link_name.to_str().unwrap(); let c = Command::new("ln") .arg(file_path_s) .arg(link_name_s) .output(); assert!(c.is_ok()); let a = format!(" ─┬ {}", dir_s); let b = format!(" └── {}", link_name_s); let b2 = format!(" └── {}", file_path_s); // Because this is a hard link the file and hard link look identical. Therefore // we cannot guarantee which version will appear first. let result = panic::catch_unwind(|| { assert_cli::Assert::main_binary() .with_args(&["-p", dir_s]) .stdout() .contains(a.as_str()) .stdout() .contains(b.as_str()) .unwrap(); }); if result.is_err() { assert_cli::Assert::main_binary() .with_args(&["-p", dir_s]) .stdout() .contains(a.as_str()) .stdout() .contains(b2.as_str()) .unwrap(); } } // Check we don't recurse down an infinite symlink tree // fix! [rivy; 2020-01-22] possible on "windows"?; `ln` is not usually an available command; creation of symbolic links requires special enhanced permissions // ... ref: @@ #[cfg_attr(target_os = "windows", ignore)] #[test] pub fn test_recursive_sym_link() { let dir = Builder::new().tempdir().unwrap(); let dir_s = dir.path().to_str().unwrap(); let link_name = dir.path().join("the_link"); let link_name_s = link_name.to_str().unwrap(); let c = Command::new("ln") .arg("-s") .arg(dir_s) .arg(link_name_s) .output(); assert!(c.is_ok()); let a = format!(" ─┬ {}", dir_s); let b = format!(" └── {}", link_name_s); assert_cli::Assert::main_binary() .with_args(&["-p", dir_s]) .stdout() .contains(a.as_str()) .stdout() .contains(b.as_str()) .unwrap(); } // Check against directories and files whos names are substrings of each other // fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable #[cfg_attr(target_os = "windows", ignore)] #[test] pub fn test_substring_of_names() { assert_cli::Assert::main_binary() .with_args(&["-c", "src/test_dir2"]) .stdout() .is(no_substring_of_names_output().as_str()) .unwrap(); } #[cfg(target_os = "linux")] fn no_substring_of_names_output() -> String { " 24K ─┬ test_dir2 8.0K ├─┬ dir 4.0K │ └── hello 8.0K ├─┬ dir_substring 4.0K │ └── hello 4.0K └── dir_name_clash " .into() } #[cfg(target_os = "macos")] fn no_substring_of_names_output() -> String { " 12K ─┬ test_dir2 4.0K ├─┬ dir 4.0K │ └── hello 4.0K ├── dir_name_clash 4.0K └─┬ dir_substring 4.0K └── hello " .into() } #[cfg(target_os = "windows")] fn no_substring_of_names_output() -> String { " 16B ─┬ test_dir2 6B ├─┬ dir_substring 6B │ └── hello 5B ├─┬ dir 5B │ └── hello 5B └── dir_name_clash " .into() } // Check against directories and files whos names are substrings of each other #[test] pub fn test_ignore_dir() { assert_cli::Assert::main_binary() .with_args(&["-c", "-X", "dir_substring", "src/test_dir2"]) .stdout() .is(ignore_dir_output().as_str()) .unwrap(); } #[cfg(target_os = "linux")] fn ignore_dir_output() -> String { " 16K ─┬ test_dir2 8.0K ├─┬ dir 4.0K │ └── hello 4.0K └── dir_name_clash " .into() } #[cfg(target_os = "macos")] fn ignore_dir_output() -> String { " 8.0K ─┬ test_dir2 4.0K ├─┬ dir 4.0K │ └── hello 4.0K └── dir_name_clash " .into() } #[cfg(target_os = "windows")] fn ignore_dir_output() -> String { " 10B ─┬ test_dir2 5B ├─┬ dir 5B │ └── hello 5B └── dir_name_clash " .into() }