query-forge 0.5.0

Run SQL queries on XLSX/XML/CSV/JSON/JSONL/Markdown/HTML/Parquet inputs and export results as text, CSV, JSONL, Markdown, XML, HTML, XLSX, or Parquet
Documentation
use clap::Parser;

use super::{Cli, Commands, 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 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());
}