ecformat 0.1.1

command line tool to keep files correct in respect of your EditorConfig
Documentation
// SPDX-FileCopyrightText: Contributors to ecformat project <https://codeberg.org/BaumiCoder/ecformat>
//
// SPDX-License-Identifier: BlueOak-1.0.0

//! Tests for the function [`get_target_files`]

use std::path::PathBuf;
use std::slice;

use crate::cli::IgnoreArgs;

use super::super::get_target_files;

#[test]
fn test_get_target_files_defaults() {
    let repo = get_repo();
    let args = IgnoreArgs {
        hidden: true,
        git_settings: true,
        ignore_file: None,
    };
    let files =
        get_target_files(slice::from_ref(&repo), &args).expect("Repository have to be accessible");
    let mut gitignore = false;
    for f in files {
        let f = f.expect("file in the iterator should not be an error");

        assert!(
            !f.starts_with("./.git"),
            "A file of the .git directory is considered: {}",
            f.display()
        );
        assert!(
            !f.starts_with("./target"),
            "target directory (part of .gitignore) is considered: {}",
            f.display()
        );
        if f.file_name().unwrap() == ".gitignore" {
            gitignore = true;
        }
    }
    assert!(gitignore, ".gitignore (a hidden file) not in target files");
}

/// Test with the boolean options different from in the default.
#[test]
fn test_get_target_files_bool_options() {
    let repo = get_repo();
    let args = IgnoreArgs {
        hidden: false,
        git_settings: false,
        ignore_file: None,
    };
    let files =
        get_target_files(slice::from_ref(&repo), &args).expect("Repository have to be accessible");
    let mut target_dir = false;
    for f in files {
        let f = f.expect("file in the iterator should not be an error");
        assert!(
            !f.starts_with("./.git"),
            "files in .git directory (a hidden directory) in target files: {}",
            f.display()
        );
        if f.starts_with("./target") {
            target_dir = true;
        }
        assert_ne!(
            f.file_name().unwrap(),
            ".gitignore",
            ".gitignore (a hidden file) in target files"
        );
    }
    assert!(
        target_dir,
        "target directory is not considered (only ignored by gitignore)"
    );
}

/// Test with an explicit ignore file name.
#[test]
fn test_get_target_files_ignore_file() {
    let repo = get_repo();
    let args = IgnoreArgs {
        hidden: true,
        git_settings: false,
        ignore_file: Some(PathBuf::from(".gitignore")),
    };
    let files =
        get_target_files(slice::from_ref(&repo), &args).expect("Repository have to be accessible");
    let mut git_dir = false;
    let mut gitignore = false;
    for f in files {
        let f = f.expect("file in the iterator should not be an error");
        if f.starts_with("./.git") {
            git_dir = true;
        }
        assert!(
            !f.starts_with("./target"),
            "target directory (part of .gitignore) is considered: {}",
            f.display()
        );
        if f.file_name().unwrap() == ".gitignore" {
            gitignore = true;
        }
    }
    assert!(
        git_dir,
        ".git directory is not considered (not in .gitignore and no git settings)"
    );
    assert!(gitignore, ".gitignore (a hidden file) not in target files");
}

/// Test multiple target files and folders
#[test]
fn test_get_target_files_multiple_targets() {
    let repo = get_repo();
    let explicit_license = repo.join("LICENSES").join("BlueOak-1.0.0.txt");
    let explicit_file = repo.join("README.md");
    let targets = vec![
        explicit_license.clone(),
        repo.join("src"),
        explicit_file.clone(),
        repo.join("LICENSES"),
    ];
    let args = IgnoreArgs {
        hidden: true,
        git_settings: true,
        ignore_file: None,
    };
    let files = get_target_files(&targets, &args).expect("Repository have to be accessible");

    let mut explicit_license_count = 0;
    let mut explicit_file_count = 0;
    let other_license = repo.join("LICENSES").join("CC0-1.0.txt");
    let mut other_license_count = 0;
    let other_file = repo.join("src").join("lib.rs");
    let mut other_file_count = 0;
    for f in files {
        let f = f.expect("file in the iterator should not be an error");

        match &f {
            f if f == &explicit_license => explicit_license_count += 1,
            f if f == &explicit_file => explicit_file_count += 1,
            f if f == &other_license => other_license_count += 1,
            f if f == &other_file => other_file_count += 1,
            _ => (),
        }
    }
    assert_eq!(
        explicit_license_count, 1,
        "Additionally explicitly given file is not returned exactly ones"
    );
    assert_eq!(
        explicit_file_count, 1,
        "Explicitly given file is not returned exactly ones"
    );
    assert_eq!(
        other_license_count, 1,
        "Implicit given file from folder with explicit given file is not returned exactly ones"
    );
    assert_eq!(
        other_file_count, 1,
        "Implicit given file is not returned exactly ones"
    );
}

fn get_repo() -> PathBuf {
    PathBuf::from("./")
}