diskr-cli 1.0.0

Save your disk space, without fear of deleting the wrong thing.
Documentation
mod common;
use common::TempDir;
use std::fs;

#[test]
fn scan_counts_files_and_size() {
    let dir = TempDir::new("scan");
    fs::write(dir.path().join("a.txt"), b"hello world").unwrap();
    fs::create_dir_all(dir.path().join("sub")).unwrap();
    fs::write(dir.path().join("sub/b.txt"), b"1234567890").unwrap();

    let opts = diskr::scanner::walker::WalkOptions { show_progress: false, ..Default::default() };
    let result = diskr::scanner::walker::scan_path(dir.path(), &opts).unwrap();

    assert_eq!(result.file_count, 2);
    assert!(result.dir_count >= 1);
    assert!(result.total_size > 0);
    assert!(!result.root.children.is_empty());
    assert_eq!(result.root.path, dir.path().canonicalize().unwrap());
}

#[test]
fn root_children_are_not_swallowed_by_the_merge_step() {
    let dir = TempDir::new("root_merge");
    fs::write(dir.path().join("top.txt"), vec![0u8; 5000]).unwrap();
    fs::create_dir_all(dir.path().join("nested")).unwrap();
    fs::write(dir.path().join("nested/inner.txt"), vec![0u8; 5000]).unwrap();

    let opts = diskr::scanner::walker::WalkOptions { show_progress: false, ..Default::default() };
    let result = diskr::scanner::walker::scan_path(dir.path(), &opts).unwrap();

    assert_eq!(result.root.children.len(), 2);
    assert_eq!(result.root.apparent_size, 10000);
    assert!(result.root.size > 0);
    assert!(result.root.children.iter().any(|c| c.path.ends_with("top.txt")));
    assert!(result.root.children.iter().any(|c| c.path.ends_with("nested")));
}

#[test]
fn protected_paths_are_never_removable() {
    assert!(diskr::cleaner::safe::is_protected(std::path::Path::new("/")));
    assert!(diskr::cleaner::safe::is_protected(std::path::Path::new("/etc")));
    assert!(diskr::cleaner::safe::is_protected(std::path::Path::new("/usr")));
}

#[test]
fn ordinary_paths_are_not_protected() {
    let dir = TempDir::new("not_protected");
    assert!(!diskr::cleaner::safe::is_protected(dir.path()));
}

#[test]
fn clean_plan_excludes_protected_paths() {
    let candidates = vec![
        (std::path::PathBuf::from("/etc"), 100u64),
        (std::env::temp_dir(), 200u64),
    ];
    let plan = diskr::cleaner::safe::build_plan(candidates);
    assert_eq!(plan.blocked.len(), 1);
    assert_eq!(plan.remove.len(), 1);
    assert_eq!(plan.total_size, 200);
}