provenant-cli 0.0.8

Provenant is a high-performance Rust scanner for licenses, packages, and source provenance.
Documentation
use super::*;
use std::fs;
use std::path::PathBuf;

#[test]
fn is_included_path_requires_include_match_before_excludes() {
    assert!(is_included_path(
        "user/src/test/sample.doc",
        &["*.doc".to_string()],
        &[]
    ));
    assert!(!is_included_path(
        "user/src/test/sample.txt",
        &["*.doc".to_string()],
        &[]
    ));
}

#[test]
fn is_included_path_applies_exclude_after_include() {
    assert!(!is_included_path(
        "src/dist/build/mylib.so",
        &["/src/*".to_string()],
        &["/src/*.so".to_string()]
    ));
    assert!(is_included_path(
        "some/src/this/that",
        &["src".to_string()],
        &["src/*.so".to_string()]
    ));
}

#[test]
fn apply_user_path_filters_to_collected_filters_files_without_pruning_directories() {
    let scan_root = PathBuf::from("/scan");
    let placeholder_metadata = fs::metadata(std::env::temp_dir()).expect("temp dir metadata");
    let mut collected = crate::scanner::CollectedPaths {
        files: vec![
            (
                scan_root.join("src/test/sample.doc"),
                placeholder_metadata.clone(),
            ),
            (
                scan_root.join("src/test/sample.txt"),
                placeholder_metadata.clone(),
            ),
        ],
        directories: vec![
            (scan_root.clone(), placeholder_metadata.clone()),
            (scan_root.join("src"), placeholder_metadata.clone()),
            (scan_root.join("src/test"), placeholder_metadata.clone()),
            (scan_root.join("other"), placeholder_metadata.clone()),
        ],
        excluded_count: 0,
        total_file_bytes: 0,
        collection_errors: Vec::new(),
    };

    let removed = apply_user_path_filters_to_collected(
        &mut collected,
        &scan_root,
        &["*.doc".to_string()],
        &[],
    );

    assert_eq!(removed, 2);
    assert_eq!(collected.files.len(), 1);
    let kept_dirs: Vec<_> = collected
        .directories
        .iter()
        .map(|(path, _)| normalize_scan_relative_path(path, &scan_root))
        .collect();
    assert_eq!(
        kept_dirs,
        vec!["".to_string(), "src".to_string(), "src/test".to_string()]
    );
    assert_eq!(
        normalize_scan_relative_path(&collected.files[0].0, &scan_root),
        "src/test/sample.doc"
    );
}

#[test]
fn is_included_path_treats_directory_include_patterns_recursively() {
    assert!(is_included_path(
        "src/foo/bar/baz.txt",
        &["src/foo".to_string()],
        &[]
    ));
    assert!(!is_included_path(
        "src/other/bar.txt",
        &["src/foo".to_string()],
        &[]
    ));
}

#[test]
fn resolve_native_scan_inputs_builds_common_prefix_and_synthetic_includes() {
    let (scan_root, includes) =
        resolve_native_scan_inputs(&["src/foo".to_string(), "src/bar/baz".to_string()])
            .expect("multiple relative inputs should resolve");

    assert_eq!(scan_root, "src");
    assert_eq!(includes, vec!["src/foo", "src/bar/baz"]);
}

#[test]
fn resolve_native_scan_inputs_uses_component_aware_prefix_for_siblings() {
    let temp_dir = tempfile::tempdir().expect("tempdir");
    let parent = temp_dir.path().join("src");
    fs::create_dir_all(parent.join("bar")).expect("create bar dir");
    fs::create_dir_all(parent.join("baz")).expect("create baz dir");

    let old_cwd = std::env::current_dir().expect("current dir");
    std::env::set_current_dir(temp_dir.path()).expect("set cwd");

    let result = resolve_native_scan_inputs(&["src/bar".to_string(), "src/baz".to_string()]);

    std::env::set_current_dir(old_cwd).expect("restore cwd");

    let (scan_root, includes) = result.expect("sibling inputs should resolve");
    assert_eq!(scan_root, "src");
    assert_eq!(includes, vec!["src/bar", "src/baz"]);
}