use clap::Parser;
use super::{Cli, Commands, DiffOutputFormat, DiffShow, HeaderCase, JsonMode, MetadataFormat, XmlMode};
#[test]
fn parses_configurable_type_inference_flags() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql",
"SELECT * FROM table",
"--all-text",
"--decimal-comma",
"--date-format",
"%d/%m/%Y",
"--null-values",
"NULL,N/A",
"--true-values",
"YES,Y",
"--false-values",
"NO,N",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(cmd.all_text);
assert!(cmd.decimal_comma);
assert_eq!(cmd.date_format.as_deref(), Some("%d/%m/%Y"));
assert_eq!(cmd.null_values, vec!["NULL", "N/A"]);
assert_eq!(cmd.true_values, vec!["YES", "Y"]);
assert_eq!(cmd.false_values, vec!["NO", "N"]);
}
#[test]
fn parses_input_normalization_flags() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql",
"SELECT * FROM table",
"--trim",
"--skip-empty-rows",
"--normalize-headers",
"--header-case",
"snake",
"--dedupe-headers",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(cmd.trim);
assert!(cmd.skip_empty_rows);
assert!(cmd.normalize_headers);
assert!(matches!(cmd.header_case, Some(HeaderCase::Snake)));
assert!(cmd.dedupe_headers);
}
#[test]
fn parses_header_case_camel() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql",
"SELECT * FROM table",
"--normalize-headers",
"--header-case",
"camel",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(matches!(cmd.header_case, Some(HeaderCase::Camel)));
}
#[test]
fn parses_header_case_pascal() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql",
"SELECT * FROM table",
"--normalize-headers",
"--header-case",
"pascal",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(matches!(cmd.header_case, Some(HeaderCase::Pascal)));
}
#[test]
fn parses_header_case_screaming_snake() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql",
"SELECT * FROM table",
"--normalize-headers",
"--header-case",
"screaming-snake",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(matches!(cmd.header_case, Some(HeaderCase::ScreamingSnake)));
}
#[test]
fn rejects_infer_types_and_all_text_together() {
let parsed = Cli::try_parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql",
"SELECT * FROM table",
"--infer-types",
"--all-text",
]);
assert!(parsed.is_err());
}
#[test]
fn parses_sql_file_flag() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql-file",
"query.sql",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert_eq!(cmd.sql_file.as_deref(), Some(std::path::Path::new("query.sql")));
}
#[test]
fn parses_json_mode_flag() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.json",
"--sql",
"SELECT * FROM table",
"--json-mode",
"flatten",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(matches!(cmd.json_mode, Some(JsonMode::Flatten)));
}
#[test]
fn parses_xml_mode_flag() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.xml",
"--sql",
"SELECT * FROM table",
"--xml-mode",
"attributes",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(matches!(cmd.xml_mode, Some(XmlMode::Attributes)));
}
#[test]
fn json_mode_defaults_to_none_when_not_specified() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.json",
"--sql",
"SELECT * FROM table",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(cmd.json_mode.is_none());
assert!(cmd.xml_mode.is_none());
}
#[test]
fn parses_meta_flag() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql",
"SELECT * FROM table",
"--meta",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(cmd.meta);
assert!(cmd.meta_format.is_none());
}
#[test]
fn parses_meta_with_json_format() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql",
"SELECT * FROM table",
"--meta",
"--meta-format",
"json",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(cmd.meta);
assert!(matches!(cmd.meta_format, Some(MetadataFormat::Json)));
}
#[test]
fn parses_meta_with_text_format() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql",
"SELECT * FROM table",
"--meta",
"--meta-format",
"text",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(cmd.meta);
assert!(matches!(cmd.meta_format, Some(MetadataFormat::Text)));
}
#[test]
fn meta_flag_is_false_when_not_specified() {
let cli = Cli::parse_from([
"qf",
"query",
"--input",
"data.csv",
"--sql",
"SELECT * FROM table",
]);
let Commands::Query(cmd) = cli.command else {
panic!("expected query command");
};
assert!(!cmd.meta);
assert!(cmd.meta_format.is_none());
}
#[test]
fn parses_diff_command_with_keys_and_show_filter() {
let cli = Cli::parse_from([
"qf",
"diff",
"--key",
"id,tenant",
"--show",
"added,changed",
"--ignore-columns",
"updated_at",
"before.csv",
"after.csv",
]);
let Commands::Diff(cmd) = cli.command else {
panic!("expected diff command");
};
assert_eq!(cmd.left, "before.csv");
assert_eq!(cmd.right, "after.csv");
assert_eq!(cmd.key, vec!["id", "tenant"]);
assert_eq!(cmd.ignore_columns, vec!["updated_at"]);
assert_eq!(cmd.show.len(), 2);
assert!(matches!(cmd.show[0], DiffShow::Added));
assert!(matches!(cmd.show[1], DiffShow::Changed));
}
#[test]
fn parses_diff_schema_only_side_by_side_format() {
let cli = Cli::parse_from([
"qf",
"diff",
"--schema-only",
"--side-by-side",
"--format",
"markdown",
"left.json",
"right.json",
]);
let Commands::Diff(cmd) = cli.command else {
panic!("expected diff command");
};
assert!(cmd.schema_only);
assert!(cmd.side_by_side);
assert!(matches!(cmd.format, Some(DiffOutputFormat::Markdown)));
}