luff 0.2.1

Print files with formatting
Documentation
//! Integration tests for configuration precedence (CLI > Env > Config File > Defaults)
//!
//! Requires the `cli` feature (for `Args`, `Config::from_args`, etc.).
#![cfg(feature = "cli")]

use clap::Parser;
use luff::{cli::Args, config::Config, format::OutputFormat};
use serial_test::serial;
use tempfile::TempDir;

#[test]
#[serial]
fn test_config_file_respected_when_no_cli_override() {
    let temp = TempDir::new().unwrap();

    let config_content = r#"
include_dotfiles: true
format: tree
max_files: 50000
ignore_extensions:
  - "custom"
  - "cache"
"#;
    let config_path = temp.path().join("luff.yaml");
    std::fs::write(&config_path, config_content).unwrap();

    std::env::set_current_dir(temp.path()).unwrap();
    let args = Args::parse_from(["luff", "--config", config_path.to_str().unwrap()]);
    let config = Config::from_args(&args).unwrap();

    assert!(config.include_dotfiles());
    assert_eq!(config.output_format(), OutputFormat::Tree);
    assert_eq!(config.max_files(), 50000);
    assert!(config.patterns().should_ignore_extension("custom"));
}

#[test]
#[serial]
fn test_cli_override_takes_precedence_over_config_file() {
    let temp = TempDir::new().unwrap();

    // Config file sets tree format and dotfiles
    let config_content = r#"
format: tree
max_clipboard_mb: 200
include_dotfiles: true
"#;
    let config_path = temp.path().join("luff.yaml");
    std::fs::write(&config_path, config_content).unwrap();

    std::env::set_current_dir(temp.path()).unwrap();

    // CLI overrides format and max_clipboard_mb
    let args = Args::parse_from([
        "luff",
        "--config",
        config_path.to_str().unwrap(),
        "--format",
        "markdown",
        "--max-clipboard-mb",
        "50",
    ]);
    let config = Config::from_args(&args).unwrap();

    // CLI values should override config file
    assert_eq!(config.output_format(), OutputFormat::Markdown);
    assert_eq!(config.max_clipboard_bytes(), 50 * 1024 * 1024);
    // Config file value for boolean should be used (not in CLI)
    assert!(config.include_dotfiles());
}

#[test]
#[serial]
fn test_env_var_override_precedence() {
    let temp = TempDir::new().unwrap();

    // Set environment variable (should override config file but not CLI)
    // SAFETY: marked with `#[serial]` to prevent concurrent execution
    unsafe {
        std::env::set_var("LUFF_MAX_CLIPBOARD_MB", "75");
    }

    let config_content = r#"
max_clipboard_mb: 200
"#;
    let config_path = temp.path().join("luff.yaml");
    std::fs::write(&config_path, config_content).unwrap();

    std::env::set_current_dir(temp.path()).unwrap();

    let args = Args::parse_from(["luff", "--config", config_path.to_str().unwrap()]);
    let config = Config::from_args(&args).unwrap();

    // Env var should override config file (75MB = 78643200 bytes)
    assert_eq!(config.max_clipboard_bytes(), 75 * 1024 * 1024);

    // SAFETY: Test is marked with `#[serial]` to prevent concurrent execution.
    unsafe {
        std::env::remove_var("LUFF_MAX_CLIPBOARD_MB");
    }
}