summaryrefslogtreecommitdiffstats
path: root/tests/tests_symlinks.rs
blob: 620d5c971a454da22546c5e2c74bb9c33338cf98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use assert_cmd::Command;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use std::str;

use tempfile::Builder;
use tempfile::TempDir;

// File sizes differ on both platform and on the format of the disk.
// Windows: `ln` is not usually an available command; creation of symbolic links requires special enhanced permissions

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
}

fn link_it(link_path: PathBuf, file_path_s: &str, is_soft: bool) -> String {
    let link_name_s = link_path.to_str().unwrap();
    let mut c = Command::new("ln");
    if is_soft {
        c.arg("-s");
    }
    c.arg(file_path_s);
    c.arg(link_name_s);
    assert!(c.output().is_ok());
    return link_name_s.into();
}

#[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_it(link_name, file_path_s, true);

    let c = format!(" ├── {}", link_name_s);
    let b = format!(" ┌── {}", file_path_s);
    let a = format!("─┴ {}", dir_s);

    let mut cmd = Command::cargo_bin("dust").unwrap();
    // Mac test runners create long filenames in tmp directories
    let output = cmd
        .args(["-p", "-c", "-s", "-w 999", dir_s])
        .unwrap()
        .stdout;

    let output = str::from_utf8(&output).unwrap();

    assert!(output.contains(a.as_str()));
    assert!(output.contains(b.as_str()));
    assert!(output.contains(c.as_str()));
}

#[cfg_attr(target_os = "windows", ignore)]
#[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");
    link_it(link_name, file_path_s, false);

    let file_output = format!(" ┌── {}", file_path_s);
    let dirs_output = format!("─┴ {}", dir_s);

    let mut cmd = Command::cargo_bin("dust").unwrap();
    // Mac test runners create long filenames in tmp directories
    let output = cmd.args(["-p", "-c", "-w 999", dir_s]).unwrap().stdout;

    // The link should not appear in the output because multiple inodes are now ordered
    // then filtered.
    let output = str::from_utf8(&output).unwrap();
    assert!(output.contains(dirs_output.as_str()));
    assert!(output.contains(file_output.as_str()));
}

#[cfg_attr(target_os = "windows", ignore)]
#[test]
pub fn test_hard_sym_link_no_dup_multi_arg() {
    let dir = Builder::new().tempdir().unwrap();
    let dir_link = Builder::new().tempdir().unwrap();
    let file = build_temp_file(&dir);
    let dir_s = dir.path().to_str().unwrap();
    let dir_link_s = dir_link.path().to_str().unwrap();
    let file_path_s = file.to_str().unwrap();

    let link_name = dir_link.path().join("the_link");
    let link_name_s = link_it(link_name, file_path_s, false);

    let mut cmd = Command::cargo_bin("dust").unwrap();

    // Mac test runners create long filenames in tmp directories
    let output = cmd
        .args(["-p", "-c", "-w 999", "-b", dir_link_s, dir_s])
        .unwrap()
        .stdout;

    // The link or the file should appeart but not both
    let output = str::from_utf8(&output).unwrap();
    println!("cmd:\n{:?}", cmd);
    println!("output:\n{:?}", output);
    let has_file_only = output.contains(file_path_s) && !output.contains(&link_name_s);
    let has_link_only = !output.contains(file_path_s) && output.contains(&link_name_s);
    assert!(has_file_only || has_link_only)
}

#[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_it(link_name, dir_s, true);

    let a = format!("─┬ {}", dir_s);
    let b = format!(" └── {}", link_name_s);

    let mut cmd = Command::cargo_bin("dust").unwrap();
    let output = cmd
        .arg("-p")
        .arg("-c")
        .arg("-r")
        .arg("-s")
        .arg("-w 999")
        .arg(dir_s)
        .unwrap()
        .stdout;
    let output = str::from_utf8(&output).unwrap();

    assert!(output.contains(a.as_str()));
    assert!(output.contains(b.as_str()));
}