#![allow(clippy::all)]
use cqlite_cli::cli_types::{Cli, OutputMode};
use cqlite_cli::config::Config;
use serial_test::serial;
use std::env;
use std::fs;
use std::path::PathBuf;
use tempfile::TempDir;
fn create_temp_config(content: &str) -> (TempDir, PathBuf) {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("test_config.toml");
fs::write(&config_path, content).unwrap();
(temp_dir, config_path)
}
fn create_cli_with_flags(
config_path: Option<PathBuf>,
schema: Option<PathBuf>,
data_dir: Option<PathBuf>,
execute: Option<String>,
file: Option<PathBuf>,
out: Option<OutputMode>,
limit: Option<usize>,
page_size: Option<usize>,
no_color: bool,
) -> Cli {
Cli {
database: None,
config: config_path,
verbose: 0,
quiet: false,
format: cqlite_cli::cli::OutputFormat::Table,
auto_detect: false,
cassandra_version: None,
schema,
dataset: None,
data_dir,
execute,
file,
out,
output: None,
overwrite: false,
limit,
page_size,
no_color,
enable_select_fallback: false,
writable: false,
write_dir: None,
mutation: Vec::new(),
mutations_file: None,
flush: false,
command: None,
}
}
#[test]
#[serial]
fn test_defaults_when_no_config() {
let cli = create_cli_with_flags(None, None, None, None, None, None, None, None, false);
let config = Config::load(None, &cli).unwrap();
assert_eq!(config.schema_paths, Vec::<PathBuf>::new());
assert_eq!(config.data_directory, None);
assert_eq!(config.execution_query, None);
assert_eq!(config.execution_file, None);
assert_eq!(config.output_mode, None);
assert_eq!(config.query_limit, None);
assert_eq!(config.repl.page_size, 50); assert_eq!(config.no_color, false);
}
#[test]
#[serial]
fn test_config_file_overrides_defaults() {
let config_content = r#"
data_directory = "/test/data"
query_limit = 100
[repl]
enable_history = true
enable_completion = true
enable_colors = true
show_timing = false
page_size = 25
enable_paging = true
max_history_size = 1000
prompt = "cqlite> "
prompt_continuation = " -> "
[output]
colors = false
timestamp_format = "%Y-%m-%d %H:%M:%S"
"#;
let (_temp_dir, config_path) = create_temp_config(config_content);
let cli = create_cli_with_flags(
Some(config_path.clone()),
None,
None,
None,
None,
None,
None,
None,
false,
);
let config = Config::load(Some(config_path), &cli).unwrap();
assert_eq!(config.data_directory, Some(PathBuf::from("/test/data")));
assert_eq!(config.query_limit, Some(100));
assert_eq!(config.repl.page_size, 25);
assert_eq!(config.output.colors, false);
}
#[test]
#[serial]
fn test_env_vars_override_config_file() {
let config_content = r#"
data_directory = "/config/data"
query_limit = 100
[repl]
enable_history = true
enable_completion = true
enable_colors = true
show_timing = false
page_size = 25
enable_paging = true
max_history_size = 1000
prompt = "cqlite> "
prompt_continuation = " -> "
"#;
let (_temp_dir, config_path) = create_temp_config(config_content);
env::set_var("CQLITE_DATA_DIR", "/env/data");
env::set_var("CQLITE_LIMIT", "200");
env::set_var("CQLITE_PAGE_SIZE", "75");
let cli = create_cli_with_flags(
Some(config_path.clone()),
None,
None,
None,
None,
None,
None,
None,
false,
);
let config = Config::load(Some(config_path), &cli).unwrap();
assert_eq!(config.data_directory, Some(PathBuf::from("/env/data")));
assert_eq!(config.query_limit, Some(200));
assert_eq!(config.repl.page_size, 75);
env::remove_var("CQLITE_DATA_DIR");
env::remove_var("CQLITE_LIMIT");
env::remove_var("CQLITE_PAGE_SIZE");
}
#[test]
#[serial]
fn test_flags_override_env_vars() {
let config_content = r#"
data_directory = "/config/data"
query_limit = 100
"#;
let (_temp_dir, config_path) = create_temp_config(config_content);
env::set_var("CQLITE_DATA_DIR", "/env/data");
env::set_var("CQLITE_LIMIT", "200");
env::set_var("CQLITE_PAGE_SIZE", "75");
env::set_var("CQLITE_NO_COLOR", "true");
let cli = create_cli_with_flags(
Some(config_path.clone()),
Some(PathBuf::from("/flag/schema.cql")),
Some(PathBuf::from("/flag/data")),
Some("SELECT * FROM test".to_string()),
None,
Some(OutputMode::Json),
Some(50),
Some(100),
true,
);
let config = Config::load(Some(config_path), &cli).unwrap();
assert_eq!(config.data_directory, Some(PathBuf::from("/flag/data")));
assert_eq!(config.schema_paths, vec![PathBuf::from("/flag/schema.cql")]);
assert_eq!(
config.execution_query,
Some("SELECT * FROM test".to_string())
);
assert_eq!(config.output_mode, Some("json".to_string()));
assert_eq!(config.query_limit, Some(50));
assert_eq!(config.repl.page_size, 100);
assert_eq!(config.no_color, true);
assert_eq!(config.output.colors, false);
env::remove_var("CQLITE_DATA_DIR");
env::remove_var("CQLITE_LIMIT");
env::remove_var("CQLITE_PAGE_SIZE");
env::remove_var("CQLITE_NO_COLOR");
}
#[test]
#[serial]
fn test_schema_env_var_comma_separated() {
env::set_var(
"CQLITE_SCHEMA",
"/path/one.cql,/path/two.json, /path/three.cql",
);
let cli = create_cli_with_flags(None, None, None, None, None, None, None, None, false);
let config = Config::load(None, &cli).unwrap();
assert_eq!(
config.schema_paths,
vec![
PathBuf::from("/path/one.cql"),
PathBuf::from("/path/two.json"),
PathBuf::from("/path/three.cql"),
]
);
env::remove_var("CQLITE_SCHEMA");
}
#[test]
#[serial]
fn test_no_color_env_var_parsing() {
env::set_var("CQLITE_NO_COLOR", "true");
let cli = create_cli_with_flags(None, None, None, None, None, None, None, None, false);
let config = Config::load(None, &cli).unwrap();
assert_eq!(config.no_color, true);
assert_eq!(config.output.colors, false);
env::set_var("CQLITE_NO_COLOR", "1");
let config = Config::load(None, &cli).unwrap();
assert_eq!(config.no_color, true);
env::set_var("CQLITE_NO_COLOR", "yes");
let config = Config::load(None, &cli).unwrap();
assert_eq!(config.no_color, true);
env::set_var("CQLITE_NO_COLOR", "false");
let config = Config::load(None, &cli).unwrap();
assert_eq!(config.no_color, false);
env::remove_var("CQLITE_NO_COLOR");
}
#[test]
#[serial]
fn test_complete_precedence_chain() {
let config_content = r#"
data_directory = "/config/data"
query_limit = 100
output_mode = "table"
[repl]
enable_history = true
enable_completion = true
enable_colors = true
show_timing = false
page_size = 25
enable_paging = true
max_history_size = 1000
prompt = "cqlite> "
prompt_continuation = " -> "
"#;
let (_temp_dir, config_path) = create_temp_config(config_content);
env::set_var("CQLITE_DATA_DIR", "/env/data");
env::set_var("CQLITE_LIMIT", "200");
let cli = create_cli_with_flags(
Some(config_path.clone()),
None, Some(PathBuf::from("/flag/data")), None,
None,
None, None, Some(150), false,
);
let config = Config::load(Some(config_path), &cli).unwrap();
assert_eq!(config.data_directory, Some(PathBuf::from("/flag/data")));
assert_eq!(config.query_limit, Some(200));
assert_eq!(config.repl.page_size, 150);
assert_eq!(config.output_mode, Some("table".to_string()));
env::remove_var("CQLITE_DATA_DIR");
env::remove_var("CQLITE_LIMIT");
}