#![cfg(test)]
use clap::Parser;
use context_creator::cli::Config;
use context_creator::core::walker::WalkOptions;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_cli_ignore_patterns_override_config() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("test-config.toml");
let config_content = r#"
ignore = ["config_*.rs", "config_target/**"]
"#;
fs::write(&config_path, config_content).unwrap();
let mut config = Config::parse_from([
"context-creator",
"--config",
config_path.to_str().unwrap(),
"--ignore",
"cli_*.rs",
"--ignore",
"cli_target/**",
]);
config.load_from_file().unwrap();
let ignore_patterns = config.get_ignore_patterns();
assert_eq!(ignore_patterns, vec!["cli_*.rs", "cli_target/**"]);
let walk_options = WalkOptions::from_config(&config).unwrap();
assert_eq!(
walk_options.ignore_patterns,
vec!["cli_*.rs", "cli_target/**"]
);
}
#[test]
fn test_cli_include_patterns_override_config() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("test-config.toml");
let config_content = r#"
include = ["config_*.rs", "config_src/**"]
"#;
fs::write(&config_path, config_content).unwrap();
let mut config = Config::parse_from([
"context-creator",
"--config",
config_path.to_str().unwrap(),
"--include",
"cli_*.rs",
"--include",
"cli_src/**",
]);
config.load_from_file().unwrap();
let include_patterns = config.get_include_patterns();
assert_eq!(include_patterns, vec!["cli_*.rs", "cli_src/**"]);
let walk_options = WalkOptions::from_config(&config).unwrap();
assert_eq!(
walk_options.include_patterns,
vec!["cli_*.rs", "cli_src/**"]
);
}
#[test]
fn test_config_patterns_used_when_no_cli_patterns() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("test-config.toml");
let config_content = r#"
ignore = ["config_*.rs", "config_target/**"]
include = ["config_src/**/*.rs"]
"#;
fs::write(&config_path, config_content).unwrap();
let mut config =
Config::parse_from(["context-creator", "--config", config_path.to_str().unwrap()]);
config.load_from_file().unwrap();
let ignore_patterns = config.get_ignore_patterns();
let include_patterns = config.get_include_patterns();
assert_eq!(ignore_patterns, vec!["config_*.rs", "config_target/**"]);
assert_eq!(include_patterns, vec!["config_src/**/*.rs"]);
}
#[test]
fn test_empty_cli_patterns_dont_override_config() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("test-config.toml");
let config_content = r#"
ignore = ["config_*.rs", "config_target/**"]
"#;
fs::write(&config_path, config_content).unwrap();
let mut config = Config::parse_from([
"context-creator",
"--config",
config_path.to_str().unwrap(),
"--ignore",
"",
"--ignore",
" ",
]);
config.load_from_file().unwrap();
let ignore_patterns = config.get_ignore_patterns();
assert_eq!(ignore_patterns, vec!["", " "]);
let walk_options = WalkOptions::from_config(&config).unwrap();
assert_eq!(walk_options.ignore_patterns, Vec::<String>::new());
}
#[test]
fn test_mixed_cli_and_config_precedence() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("test-config.toml");
let config_content = r#"
ignore = ["config_*.rs", "config_target/**"]
include = ["config_src/**/*.rs"]
"#;
fs::write(&config_path, config_content).unwrap();
let mut config = Config::parse_from([
"context-creator",
"--config",
config_path.to_str().unwrap(),
"--ignore",
"cli_*.rs",
]);
config.load_from_file().unwrap();
let ignore_patterns = config.get_ignore_patterns();
assert_eq!(ignore_patterns, vec!["cli_*.rs"]);
let include_patterns = config.get_include_patterns();
assert_eq!(include_patterns, vec!["config_src/**/*.rs"]);
}
#[test]
fn test_cli_patterns_with_default_config() {
let config = Config::parse_from([
"context-creator",
"--ignore",
"cli_*.rs",
"--ignore",
"cli_target/**",
"--include",
"cli_src/**/*.rs",
]);
let ignore_patterns = config.get_ignore_patterns();
let include_patterns = config.get_include_patterns();
assert_eq!(ignore_patterns, vec!["cli_*.rs", "cli_target/**"]);
assert_eq!(include_patterns, vec!["cli_src/**/*.rs"]);
let walk_options = WalkOptions::from_config(&config).unwrap();
assert_eq!(
walk_options.ignore_patterns,
vec!["cli_*.rs", "cli_target/**"]
);
assert_eq!(walk_options.include_patterns, vec!["cli_src/**/*.rs"]);
}
#[test]
fn test_cli_pattern_validation_scenarios() {
let config = Config::parse_from([
"context-creator",
"--prompt",
"Analyze code",
"--ignore",
"../../../etc/passwd",
"--ignore",
"valid_*.rs",
]);
assert!(config.validate().is_ok());
let walk_options_result = WalkOptions::from_config(&config);
assert!(walk_options_result.is_ok());
let walk_options = walk_options_result.unwrap();
assert_eq!(
walk_options.ignore_patterns,
vec!["../../../etc/passwd", "valid_*.rs"]
);
}
#[test]
fn test_cli_patterns_with_prompt_precedence() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("test-config.toml");
let config_content = r#"
ignore = ["config_*.rs"]
include = ["config_src/**/*.rs"]
"#;
fs::write(&config_path, config_content).unwrap();
let mut config = Config::parse_from([
"context-creator",
"--config",
config_path.to_str().unwrap(),
"--prompt",
"Analyze security",
"--include",
"cli_src/**/*.rs",
"--ignore",
"cli_*.rs",
]);
config.load_from_file().unwrap();
assert_eq!(config.get_prompt(), Some("Analyze security".to_string()));
assert_eq!(config.get_include_patterns(), vec!["cli_src/**/*.rs"]);
assert_eq!(config.get_ignore_patterns(), vec!["cli_*.rs"]);
let walk_options = WalkOptions::from_config(&config).unwrap();
assert_eq!(walk_options.include_patterns, vec!["cli_src/**/*.rs"]);
assert_eq!(walk_options.ignore_patterns, vec!["cli_*.rs"]);
}
#[test]
fn test_config_patterns_with_repo_precedence() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("test-config.toml");
let config_content = r#"
ignore = ["config_*.rs"]
"#;
fs::write(&config_path, config_content).unwrap();
let mut config = Config::parse_from([
"context-creator",
"--config",
config_path.to_str().unwrap(),
"--remote",
"https://github.com/owner/repo",
"--ignore",
"cli_*.rs",
]);
config.load_from_file().unwrap();
assert_eq!(
config.remote,
Some("https://github.com/owner/repo".to_string())
);
assert_eq!(config.get_ignore_patterns(), vec!["cli_*.rs"]);
}
#[test]
fn test_multiple_cli_invocations_precedence() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("test-config.toml");
let config_content = r#"
ignore = ["config1_*.rs", "config2_*.rs"]
include = ["config_src/**/*.rs"]
"#;
fs::write(&config_path, config_content).unwrap();
let mut config = Config::parse_from([
"context-creator",
"--config",
config_path.to_str().unwrap(),
"--ignore",
"cli1_*.rs",
"--ignore",
"cli2_*.rs",
"--ignore",
"cli3_*.rs",
"--include",
"cli_src/**/*.rs",
]);
config.load_from_file().unwrap();
assert_eq!(
config.get_ignore_patterns(),
vec!["cli1_*.rs", "cli2_*.rs", "cli3_*.rs"]
);
assert_eq!(config.get_include_patterns(), vec!["cli_src/**/*.rs"]);
}
#[test]
fn test_config_loading_doesnt_interfere_with_cli() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("test-config.toml");
let config_content = r#"
[token_limits]
gemini = 500000
"#;
fs::write(&config_path, config_content).unwrap();
let mut config = Config::parse_from([
"context-creator",
"--config",
config_path.to_str().unwrap(),
"--ignore",
"cli_*.rs",
"--include",
"cli_src/**/*.rs",
]);
config.load_from_file().unwrap();
assert_eq!(config.get_ignore_patterns(), vec!["cli_*.rs"]);
assert_eq!(config.get_include_patterns(), vec!["cli_src/**/*.rs"]);
}