This commit is contained in:
617
crates/kreuzberg-cli/tests/config_discovery_test.rs
Normal file
617
crates/kreuzberg-cli/tests/config_discovery_test.rs
Normal file
@@ -0,0 +1,617 @@
|
||||
//! Integration tests for CLI config file discovery.
|
||||
//!
|
||||
//! These tests verify that the CLI correctly discovers and loads configuration files
|
||||
//! in various formats (.toml, .yaml, .json) with case-insensitive extension
|
||||
//! matching, explicit --config flag support, and proper error handling.
|
||||
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use tempfile::tempdir;
|
||||
|
||||
/// Get the path to the kreuzberg binary.
|
||||
fn get_binary_path() -> String {
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
format!("{}/../../target/debug/kreuzberg", manifest_dir)
|
||||
}
|
||||
|
||||
/// Build the binary before running tests.
|
||||
fn build_binary() {
|
||||
let status = Command::new("cargo")
|
||||
.args(["build", "--bin", "kreuzberg"])
|
||||
.status()
|
||||
.expect("Failed to build kreuzberg binary");
|
||||
|
||||
assert!(status.success(), "Failed to build kreuzberg binary");
|
||||
}
|
||||
|
||||
/// Get the test_documents directory path.
|
||||
fn get_test_documents_dir() -> PathBuf {
|
||||
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
manifest_dir.parent().unwrap().parent().unwrap().join("test_documents")
|
||||
}
|
||||
|
||||
/// Get a test file path relative to test_documents/.
|
||||
fn get_test_file(relative_path: &str) -> String {
|
||||
get_test_documents_dir()
|
||||
.join(relative_path)
|
||||
.to_string_lossy()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_discover_kreuzberg_toml_in_current_directory() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join(".kreuzberg.toml");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"
|
||||
use_cache = false
|
||||
enable_quality_processing = false
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.current_dir(dir.path())
|
||||
.args(["extract", test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_discover_kreuzberg_yaml_in_current_directory() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join(".kreuzberg.yaml");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"
|
||||
use_cache: false
|
||||
enable_quality_processing: false
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.current_dir(dir.path())
|
||||
.args(["extract", test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_discover_kreuzberg_yml_in_current_directory() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join(".kreuzberg.yaml");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"
|
||||
use_cache: false
|
||||
enable_quality_processing: false
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.current_dir(dir.path())
|
||||
.args(["extract", test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_discover_kreuzberg_json_in_current_directory() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join(".kreuzberg.json");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"{
|
||||
"use_cache": false,
|
||||
"enable_quality_processing": false
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.current_dir(dir.path())
|
||||
.args(["extract", test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_case_insensitive_toml_extension() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("custom.TOML");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"
|
||||
use_cache = false
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.current_dir(dir.path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_case_insensitive_yaml_extension() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("custom.Yaml");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"
|
||||
use_cache: false
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.current_dir(dir.path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_case_insensitive_yml_extension() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("custom.YML");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"
|
||||
use_cache: false
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.current_dir(dir.path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_case_insensitive_json_extension() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("custom.JSON");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"{
|
||||
"use_cache": false
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.current_dir(dir.path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_explicit_config_path_toml() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("custom_config.toml");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"
|
||||
use_cache = false
|
||||
enable_quality_processing = false
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_explicit_config_path_yaml() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("custom_config.yaml");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"
|
||||
use_cache: false
|
||||
enable_quality_processing: false
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_explicit_config_path_json() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("custom_config.json");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"{
|
||||
"use_cache": false,
|
||||
"enable_quality_processing": false
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_config_extension() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("config.txt");
|
||||
|
||||
fs::write(&config_path, "invalid content").unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(!output.status.success());
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
assert!(
|
||||
stderr.contains(".toml") || stderr.contains(".yaml") || stderr.contains(".json"),
|
||||
"Error message should mention supported extensions: {}",
|
||||
stderr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_malformed_toml_config() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("bad_config.toml");
|
||||
|
||||
fs::write(&config_path, "use_cache = [[[[[").unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(!output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_malformed_yaml_config() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("bad_config.yaml");
|
||||
|
||||
fs::write(&config_path, "use_cache: [[[[[").unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(!output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_malformed_json_config() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("bad_config.json");
|
||||
|
||||
fs::write(&config_path, r#"{"use_cache": [[[[[}"#).unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(!output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nonexistent_config_file() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("nonexistent.toml");
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(!output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_config_when_no_file_found() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.current_dir(dir.path())
|
||||
.args(["extract", test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"Command failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_config_values() {
|
||||
build_binary();
|
||||
|
||||
let dir = tempdir().unwrap();
|
||||
let config_path = dir.path().join("invalid.toml");
|
||||
|
||||
fs::write(
|
||||
&config_path,
|
||||
r#"
|
||||
use_cache = "not_a_bool"
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let test_file = get_test_file("text/simple.txt");
|
||||
if !PathBuf::from(&test_file).exists() {
|
||||
tracing::debug!("Skipping test: {} not found", test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
let config_arg = config_path.to_string_lossy().into_owned();
|
||||
|
||||
let output = Command::new(get_binary_path())
|
||||
.args(["extract", "--config", config_arg.as_str(), test_file.as_str()])
|
||||
.output()
|
||||
.expect("Failed to execute kreuzberg");
|
||||
|
||||
assert!(!output.status.success());
|
||||
}
|
||||
Reference in New Issue
Block a user