mod cli_testing_tools;
use cli_testing_tools::*;
use predicates::prelude::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn cli_oracle_bootstrap_dry_run() {
let result = decy_cmd().arg("oracle").arg("bootstrap").arg("--dry-run").assert();
let _ = result;
}
#[test]
fn cli_oracle_bootstrap_no_dry_run() {
let result = decy_cmd().arg("oracle").arg("bootstrap").assert();
let _ = result;
}
#[test]
fn cli_oracle_stats_json_format() {
let result = decy_cmd().arg("oracle").arg("stats").arg("--format").arg("json").assert();
let _ = result;
}
#[test]
fn cli_oracle_stats_markdown_format() {
let result = decy_cmd().arg("oracle").arg("stats").arg("--format").arg("markdown").assert();
let _ = result;
}
#[test]
fn cli_oracle_stats_prometheus_format() {
let result = decy_cmd().arg("oracle").arg("stats").arg("--format").arg("prometheus").assert();
let _ = result;
}
#[test]
fn cli_oracle_stats_default_format() {
let result = decy_cmd().arg("oracle").arg("stats").arg("--format").arg("default").assert();
let _ = result;
}
#[test]
fn cli_oracle_stats_unknown_format() {
let result = decy_cmd().arg("oracle").arg("stats").arg("--format").arg("yaml").assert();
let _ = result;
}
#[test]
fn cli_oracle_retire_dry_run() {
let result = decy_cmd().arg("oracle").arg("retire").arg("--dry-run").assert();
let _ = result;
}
#[test]
fn cli_oracle_retire_no_dry_run() {
let result = decy_cmd().arg("oracle").arg("retire").assert();
let _ = result;
}
#[test]
fn cli_oracle_retire_with_archive_path() {
let temp = TempDir::new().unwrap();
let archive = temp.path().join("archive.apr");
let result =
decy_cmd().arg("oracle").arg("retire").arg("--archive-path").arg(&archive).assert();
let _ = result;
}
#[test]
fn cli_oracle_retire_dry_run_with_archive() {
let temp = TempDir::new().unwrap();
let archive = temp.path().join("archive.apr");
let result = decy_cmd()
.arg("oracle")
.arg("retire")
.arg("--dry-run")
.arg("--archive-path")
.arg(&archive)
.assert();
let _ = result;
}
#[test]
fn cli_oracle_query_valid_error_code() {
let result = decy_cmd().arg("oracle").arg("query").arg("--error").arg("E0308").assert();
let _ = result;
}
#[test]
fn cli_oracle_query_invalid_error_code_short() {
let result = decy_cmd().arg("oracle").arg("query").arg("--error").arg("E01").assert();
let _ = result;
}
#[test]
fn cli_oracle_query_invalid_error_code_no_e() {
let result = decy_cmd().arg("oracle").arg("query").arg("--error").arg("X0308").assert();
let _ = result;
}
#[test]
fn cli_oracle_query_with_context() {
let result = decy_cmd()
.arg("oracle")
.arg("query")
.arg("--error")
.arg("E0382")
.arg("--context")
.arg("borrow of moved value")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_query_json_format() {
let result = decy_cmd()
.arg("oracle")
.arg("query")
.arg("--error")
.arg("E0308")
.arg("--format")
.arg("json")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_query_text_format() {
let result = decy_cmd()
.arg("oracle")
.arg("query")
.arg("--error")
.arg("E0308")
.arg("--format")
.arg("text")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_query_unknown_error_code() {
let result = decy_cmd().arg("oracle").arg("query").arg("--error").arg("E9999").assert();
let _ = result;
}
#[test]
fn cli_oracle_query_with_context_json() {
let result = decy_cmd()
.arg("oracle")
.arg("query")
.arg("--error")
.arg("E0382")
.arg("--context")
.arg("pointer ownership")
.arg("--format")
.arg("json")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_seed_missing_file() {
let result = decy_cmd()
.arg("oracle")
.arg("seed")
.arg("--from")
.arg("/tmp/nonexistent_patterns_file.apr")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_seed_existing_file() {
let temp = TempDir::new().unwrap();
let patterns_file = create_temp_file(&temp, "patterns.apr", "{}");
let result = decy_cmd().arg("oracle").arg("seed").arg("--from").arg(&patterns_file).assert();
let _ = result;
}
#[test]
fn cli_oracle_validate_nonexistent_corpus() {
let result =
decy_cmd().arg("oracle").arg("validate").arg("/tmp/nonexistent_corpus_dir_98765").assert();
let _ = result;
}
#[test]
fn cli_oracle_validate_empty_corpus() {
let temp = TempDir::new().unwrap();
let result = decy_cmd().arg("oracle").arg("validate").arg(temp.path()).assert();
let _ = result;
}
#[test]
fn cli_oracle_validate_corpus_with_files() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "hello.c", "int main() { return 0; }");
create_temp_file(&temp, "add.c", "int add(int a, int b) { return a + b; }");
let result = decy_cmd().arg("oracle").arg("validate").arg(temp.path()).assert();
let _ = result;
}
#[test]
fn cli_oracle_export_jsonl() {
let temp = TempDir::new().unwrap();
let output = temp.path().join("export.jsonl");
let result =
decy_cmd().arg("oracle").arg("export").arg(&output).arg("--format").arg("jsonl").assert();
let _ = result;
}
#[test]
fn cli_oracle_export_chatml() {
let temp = TempDir::new().unwrap();
let output = temp.path().join("export.jsonl");
let result =
decy_cmd().arg("oracle").arg("export").arg(&output).arg("--format").arg("chatml").assert();
let _ = result;
}
#[test]
fn cli_oracle_export_alpaca() {
let temp = TempDir::new().unwrap();
let output = temp.path().join("export.jsonl");
let result =
decy_cmd().arg("oracle").arg("export").arg(&output).arg("--format").arg("alpaca").assert();
let _ = result;
}
#[test]
fn cli_oracle_export_parquet() {
let temp = TempDir::new().unwrap();
let output = temp.path().join("export.parquet");
let result =
decy_cmd().arg("oracle").arg("export").arg(&output).arg("--format").arg("parquet").assert();
let _ = result;
}
#[test]
fn cli_oracle_export_unknown_format() {
let temp = TempDir::new().unwrap();
let output = temp.path().join("export.txt");
let result =
decy_cmd().arg("oracle").arg("export").arg(&output).arg("--format").arg("xml").assert();
let _ = result;
}
#[test]
fn cli_oracle_export_with_card() {
let temp = TempDir::new().unwrap();
let output = temp.path().join("export.jsonl");
let result = decy_cmd()
.arg("oracle")
.arg("export")
.arg(&output)
.arg("--format")
.arg("jsonl")
.arg("--with-card")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_train_nonexistent_corpus() {
let result = decy_cmd()
.arg("oracle")
.arg("train")
.arg("--corpus")
.arg("/tmp/nonexistent_corpus_train_dir")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_train_empty_corpus() {
let temp = TempDir::new().unwrap();
let result = decy_cmd().arg("oracle").arg("train").arg("--corpus").arg(temp.path()).assert();
let _ = result;
}
#[test]
fn cli_oracle_train_valid_corpus_dry_run() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "simple.c", "int main() { return 0; }");
let result = decy_cmd()
.arg("oracle")
.arg("train")
.arg("--corpus")
.arg(temp.path())
.arg("--dry-run")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_train_tier_p1() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "main.c", "int main() { return 0; }");
let result = decy_cmd()
.arg("oracle")
.arg("train")
.arg("--corpus")
.arg(temp.path())
.arg("--tier")
.arg("P1")
.arg("--dry-run")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_train_tier_p2() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "main.c", "int main() { return 0; }");
let result = decy_cmd()
.arg("oracle")
.arg("train")
.arg("--corpus")
.arg(temp.path())
.arg("--tier")
.arg("P2")
.arg("--dry-run")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_train_invalid_tier() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "main.c", "int main() { return 0; }");
let result = decy_cmd()
.arg("oracle")
.arg("train")
.arg("--corpus")
.arg(temp.path())
.arg("--tier")
.arg("P3")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_generate_traces_nonexistent_corpus() {
let temp = TempDir::new().unwrap();
let output = temp.path().join("traces.jsonl");
let result = decy_cmd()
.arg("oracle")
.arg("generate-traces")
.arg("--corpus")
.arg("/tmp/nonexistent_traces_corpus_dir")
.arg("--output")
.arg(&output)
.assert();
let _ = result;
}
#[test]
fn cli_oracle_generate_traces_empty_corpus() {
let temp = TempDir::new().unwrap();
let output = temp.path().join("traces.jsonl");
let result = decy_cmd()
.arg("oracle")
.arg("generate-traces")
.arg("--corpus")
.arg(temp.path())
.arg("--output")
.arg(&output)
.assert();
let _ = result;
}
#[test]
fn cli_oracle_generate_traces_dry_run() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "hello.c", "int main() { return 0; }");
let output = temp.path().join("traces.jsonl");
let result = decy_cmd()
.arg("oracle")
.arg("generate-traces")
.arg("--corpus")
.arg(temp.path())
.arg("--output")
.arg(&output)
.arg("--dry-run")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_generate_traces_tier_p1() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "hello.c", "int main() { return 0; }");
let output = temp.path().join("traces.jsonl");
let result = decy_cmd()
.arg("oracle")
.arg("generate-traces")
.arg("--corpus")
.arg(temp.path())
.arg("--output")
.arg(&output)
.arg("--tier")
.arg("P1")
.arg("--dry-run")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_generate_traces_tier_p2() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "hello.c", "int main() { return 0; }");
let output = temp.path().join("traces.jsonl");
let result = decy_cmd()
.arg("oracle")
.arg("generate-traces")
.arg("--corpus")
.arg(temp.path())
.arg("--output")
.arg(&output)
.arg("--tier")
.arg("P2")
.arg("--dry-run")
.assert();
let _ = result;
}
#[test]
fn cli_oracle_generate_traces_invalid_tier() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "hello.c", "int main() { return 0; }");
let output = temp.path().join("traces.jsonl");
let result = decy_cmd()
.arg("oracle")
.arg("generate-traces")
.arg("--corpus")
.arg(temp.path())
.arg("--output")
.arg(&output)
.arg("--tier")
.arg("INVALID")
.assert();
let _ = result;
}
#[test]
fn cli_transpile_with_oracle_flag() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "oracle_test.c", VALID_C_CODE);
let result = decy_cmd().arg("transpile").arg(&input).arg("--oracle").assert();
let _ = result;
}
#[test]
fn cli_transpile_with_oracle_and_threshold() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "oracle_thresh.c", VALID_C_CODE);
let result = decy_cmd()
.arg("transpile")
.arg(&input)
.arg("--oracle")
.arg("--oracle-threshold")
.arg("0.9")
.assert();
let _ = result;
}
#[test]
fn cli_transpile_with_oracle_auto_fix() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "oracle_fix.c", VALID_C_CODE);
let result = decy_cmd().arg("transpile").arg(&input).arg("--oracle").arg("--auto-fix").assert();
let _ = result;
}
#[test]
fn cli_transpile_with_oracle_capture() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "oracle_capture.c", VALID_C_CODE);
let result = decy_cmd().arg("transpile").arg(&input).arg("--oracle").arg("--capture").assert();
let _ = result;
}
#[test]
fn cli_transpile_with_oracle_report_json() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "oracle_rpt.c", VALID_C_CODE);
let result = decy_cmd()
.arg("transpile")
.arg(&input)
.arg("--oracle")
.arg("--oracle-report")
.arg("json")
.assert();
let _ = result;
}
#[test]
fn cli_transpile_with_oracle_report_markdown() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "oracle_rpt_md.c", VALID_C_CODE);
let result = decy_cmd()
.arg("transpile")
.arg(&input)
.arg("--oracle")
.arg("--oracle-report")
.arg("markdown")
.assert();
let _ = result;
}
#[test]
fn cli_transpile_with_oracle_report_prometheus() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "oracle_rpt_prom.c", VALID_C_CODE);
let result = decy_cmd()
.arg("transpile")
.arg(&input)
.arg("--oracle")
.arg("--oracle-report")
.arg("prometheus")
.assert();
let _ = result;
}
#[test]
fn cli_transpile_with_oracle_report_unknown() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "oracle_rpt_unk.c", VALID_C_CODE);
let result = decy_cmd()
.arg("transpile")
.arg(&input)
.arg("--oracle")
.arg("--oracle-report")
.arg("unknown_format")
.assert();
let _ = result;
}
#[test]
fn cli_transpile_with_oracle_import_patterns() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "oracle_import.c", VALID_C_CODE);
let patterns = create_temp_file(&temp, "patterns.apr", "{}");
let result = decy_cmd()
.arg("transpile")
.arg(&input)
.arg("--oracle")
.arg("--import-patterns")
.arg(&patterns)
.assert();
let _ = result;
}
#[test]
fn cli_transpile_with_all_oracle_flags() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "oracle_all.c", VALID_C_CODE);
let patterns = create_temp_file(&temp, "all_patterns.apr", "{}");
let result = decy_cmd()
.arg("transpile")
.arg(&input)
.arg("--oracle")
.arg("--oracle-threshold")
.arg("0.5")
.arg("--auto-fix")
.arg("--capture")
.arg("--import-patterns")
.arg(&patterns)
.arg("--oracle-report")
.arg("json")
.assert();
let _ = result;
}
#[test]
fn cli_transpile_project_with_oracle() {
let temp = TempDir::new().unwrap();
let output_dir = temp.path().join("output");
create_temp_file(&temp, "test.c", "int main() { return 0; }");
let result = decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--oracle")
.assert();
let _ = result;
}
#[test]
fn cli_transpile_project_with_oracle_all_flags() {
let temp = TempDir::new().unwrap();
let output_dir = temp.path().join("output");
let patterns = create_temp_file(&temp, "patterns.apr", "{}");
create_temp_file(&temp, "test.c", "int main() { return 0; }");
let result = decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--oracle")
.arg("--auto-fix")
.arg("--capture")
.arg("--import-patterns")
.arg(&patterns)
.arg("--oracle-report")
.arg("json")
.assert();
let _ = result;
}
#[test]
fn cli_audit_verbose_with_raw_pointer_deref() {
let temp = TempDir::new().unwrap();
let rust_code = r#"
fn raw_stuff() {
unsafe {
let raw: *mut i32 = 0x1234 as *mut i32;
*raw = 42;
}
}
fn main() {
raw_stuff();
}
"#;
let input = create_temp_file(&temp, "raw_deref.rs", rust_code);
decy_cmd()
.arg("audit")
.arg(&input)
.arg("--verbose")
.assert()
.success()
.stdout(predicate::str::contains("Unsafe Code Audit Report"));
}
#[test]
fn cli_audit_summary_without_verbose() {
let temp = TempDir::new().unwrap();
let rust_code = r#"
fn a() {
unsafe { let _ = 1; }
}
fn b() {
unsafe { let _ = 2; }
}
fn c() {
unsafe { let _ = 3; }
}
fn main() {
a(); b(); c();
}
"#;
let input = create_temp_file(&temp, "summary_unsafe.rs", rust_code);
decy_cmd()
.arg("audit")
.arg(&input)
.assert()
.success()
.stdout(predicate::str::contains("Summary by Confidence"))
.stdout(predicate::str::contains("HIGH"))
.stdout(predicate::str::contains("MEDIUM").or(predicate::str::contains("LOW")))
.stdout(predicate::str::contains("--verbose"));
}
#[test]
fn cli_audit_high_density_unsafe() {
let temp = TempDir::new().unwrap();
let rust_code = r#"
unsafe fn f1() { let _ = 1; }
unsafe fn f2() { let _ = 2; }
unsafe fn f3() { let _ = 3; }
unsafe fn f4() { let _ = 4; }
unsafe fn f5() { let _ = 5; }
fn main() {
unsafe {
f1(); f2(); f3(); f4(); f5();
}
}
"#;
let input = create_temp_file(&temp, "high_density.rs", rust_code);
decy_cmd()
.arg("audit")
.arg(&input)
.assert()
.success()
.stdout(predicate::str::contains("Unsafe Code Audit Report"))
.stdout(predicate::str::contains("Unsafe Density"));
}
#[test]
fn cli_cache_stats_after_transpile() {
let temp = TempDir::new().unwrap();
let output_dir = temp.path().join("output");
create_temp_file(&temp, "cached.c", "int main() { return 0; }");
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.assert()
.success();
let result = decy_cmd().arg("cache-stats").arg(temp.path()).assert();
let _ = result;
}
#[test]
fn cli_transpile_project_dry_run_quiet() {
let temp = TempDir::new().unwrap();
let output_dir = temp.path().join("output");
create_temp_file(&temp, "quiet_dry.c", "int main() { return 0; }");
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--dry-run")
.arg("--quiet")
.assert()
.success();
}
#[test]
fn cli_transpile_project_no_cache_with_stats() {
let temp = TempDir::new().unwrap();
let output_dir = temp.path().join("output");
create_temp_file(&temp, "nocache_stats.c", "int main() { return 0; }");
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--no-cache")
.arg("--stats")
.assert()
.success()
.stdout(predicate::str::contains("Statistics"));
}
#[test]
fn cli_transpile_output_to_bad_path() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "good.c", VALID_C_CODE);
decy_cmd()
.arg("transpile")
.arg(&input)
.arg("-o")
.arg("/proc/nonexistent/impossible/output.rs")
.assert()
.failure()
.stderr(predicate::str::contains("Failed to write output file"));
}
#[test]
fn cli_transpile_with_if_else() {
let temp = TempDir::new().unwrap();
let c_code = r#"
int abs_val(int x) {
if (x < 0) {
return -x;
} else {
return x;
}
}
int main() {
return abs_val(-5);
}
"#;
let input = create_temp_file(&temp, "ifelse.c", c_code);
decy_cmd()
.arg("transpile")
.arg(&input)
.assert()
.success()
.stdout(predicate::str::contains("fn abs_val"));
}
#[test]
fn cli_transpile_with_while_loop() {
let temp = TempDir::new().unwrap();
let c_code = r#"
int count_down(int n) {
int count = 0;
while (n > 0) {
count++;
n--;
}
return count;
}
int main() {
return count_down(10);
}
"#;
let input = create_temp_file(&temp, "while.c", c_code);
decy_cmd()
.arg("transpile")
.arg(&input)
.assert()
.success()
.stdout(predicate::str::contains("fn count_down"));
}
#[test]
fn cli_transpile_void_return_function() {
let temp = TempDir::new().unwrap();
let c_code = r#"
void do_nothing() {
}
int main() {
do_nothing();
return 0;
}
"#;
let input = create_temp_file(&temp, "void_ret.c", c_code);
decy_cmd()
.arg("transpile")
.arg(&input)
.assert()
.success()
.stdout(predicate::str::contains("fn do_nothing"));
}
#[test]
fn cli_transpile_trace_with_output_file() {
let temp = TempDir::new().unwrap();
let input = create_temp_file(&temp, "trace_out.c", VALID_C_CODE);
let output = temp.path().join("trace_out.rs");
decy_cmd()
.arg("transpile")
.arg(&input)
.arg("--trace")
.arg("-o")
.arg(&output)
.assert()
.success()
.stderr(predicate::str::is_empty().not());
assert!(output.exists());
}
#[test]
fn cli_transpile_project_cache_reuse() {
let temp = TempDir::new().unwrap();
let output_dir = temp.path().join("output");
create_temp_file(&temp, "cache_test.c", "int main() { return 0; }");
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.assert()
.success();
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--verbose")
.assert()
.success();
}
#[test]
fn cli_transpile_project_subdirectories() {
let temp = TempDir::new().unwrap();
let output_dir = temp.path().join("output");
let sub_dir = temp.path().join("src");
fs::create_dir_all(&sub_dir).unwrap();
create_temp_file(&temp, "main.c", "int main() { return 0; }");
let sub_file = sub_dir.join("helper.c");
fs::write(&sub_file, "int helper() { return 1; }").unwrap();
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--verbose")
.arg("--stats")
.assert()
.success()
.stdout(predicate::str::contains("Found 2 C files"));
}
#[test]
fn cli_check_project_with_subdirectories() {
let temp = TempDir::new().unwrap();
let sub = temp.path().join("subdir");
fs::create_dir_all(&sub).unwrap();
create_temp_file(&temp, "main.c", "int main() { return 0; }");
fs::write(sub.join("util.c"), "int util() { return 1; }").unwrap();
decy_cmd()
.arg("check-project")
.arg(temp.path())
.assert()
.success()
.stdout(predicate::str::contains("Found 2 C files"))
.stdout(predicate::str::contains("Project is ready"));
}
#[test]
fn cli_no_subcommand_shows_all_usage() {
decy_cmd()
.assert()
.success()
.stdout(predicate::str::contains("transpile-project"))
.stdout(predicate::str::contains("check-project"))
.stdout(predicate::str::contains("cache-stats"))
.stdout(predicate::str::contains("audit"));
}
#[test]
fn cli_transpile_library_code_stdout_note() {
let temp = TempDir::new().unwrap();
let c_code = "float average(float a, float b) { return (a + b) / 2.0; }";
let input = create_temp_file(&temp, "lib_avg.c", c_code);
decy_cmd()
.arg("transpile")
.arg(&input)
.assert()
.success()
.stderr(predicate::str::contains("No main function found"))
.stderr(predicate::str::contains("rustc --crate-type=lib"));
}
#[test]
fn cli_transpile_library_code_file_note() {
let temp = TempDir::new().unwrap();
let c_code = "double square(double x) { return x * x; }";
let input = create_temp_file(&temp, "lib_sq.c", c_code);
let output = temp.path().join("lib_sq.rs");
decy_cmd()
.arg("transpile")
.arg(&input)
.arg("-o")
.arg(&output)
.assert()
.success()
.stderr(predicate::str::contains("No main function found"))
.stderr(predicate::str::contains("rustc --crate-type=lib"));
}
#[test]
fn cli_transpile_verify_valid_code_succeeds() {
let temp = TempDir::new().unwrap();
let c_code = "int main() { return 0; }";
let input = create_temp_file(&temp, "verify_ok.c", c_code);
decy_cmd()
.arg("transpile")
.arg(&input)
.arg("--verify")
.assert()
.success()
.stderr(predicate::str::contains("Compilation verified"));
}
#[test]
fn cli_transpile_verify_with_output_file() {
let temp = TempDir::new().unwrap();
let c_code = "int add(int a, int b) { return a + b; }\nint main() { return add(1, 2); }";
let input = create_temp_file(&temp, "verify_out.c", c_code);
let output = temp.path().join("verify_out.rs");
decy_cmd()
.arg("transpile")
.arg(&input)
.arg("-o")
.arg(&output)
.arg("--verify")
.assert()
.success()
.stderr(predicate::str::contains("Compilation verified"))
.stderr(predicate::str::contains("Transpiled"));
}
#[test]
fn cli_transpile_verify_stdout_mode() {
let temp = TempDir::new().unwrap();
let c_code = "int main() { int x = 42; return x; }";
let input = create_temp_file(&temp, "verify_stdout.c", c_code);
let assert = decy_cmd().arg("transpile").arg(&input).arg("--verify").assert().success();
let output = assert.get_output();
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(stdout.contains("fn main"), "Expected Rust code on stdout");
assert!(stderr.contains("Compilation verified"), "Expected verification message on stderr");
}
#[test]
fn cli_transpile_project_dry_run_mode() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "a.c", "int f() { return 1; }");
create_temp_file(&temp, "b.c", "int g() { return 2; }");
let output_dir = temp.path().join("out");
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--dry-run")
.assert()
.success()
.stdout(predicate::str::contains("DRY RUN"))
.stdout(predicate::str::contains("Dry run complete"));
}
#[test]
fn cli_transpile_project_verbose_output() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "hello.c", "int main() { return 0; }");
let output_dir = temp.path().join("verbose_out");
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--verbose")
.assert()
.success()
.stdout(predicate::str::contains("Transpiled"));
}
#[test]
fn cli_transpile_project_quiet_mode() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "quiet.c", "int main() { return 0; }");
let output_dir = temp.path().join("quiet_out");
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--quiet")
.assert()
.success();
}
#[test]
fn cli_transpile_project_stats_flag() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "stats.c", "int main() { return 0; }");
let output_dir = temp.path().join("stats_out");
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--stats")
.assert()
.success()
.stdout(predicate::str::contains("Statistics"))
.stdout(predicate::str::contains("Files found"))
.stdout(predicate::str::contains("Files transpiled"));
}
#[test]
fn cli_transpile_project_no_cache_flag() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "nocache.c", "int main() { return 0; }");
let output_dir = temp.path().join("nocache_out");
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.arg("--no-cache")
.assert()
.success();
}
#[test]
fn cli_transpile_project_nonexistent_dir() {
let temp = TempDir::new().unwrap();
let output_dir = temp.path().join("out");
decy_cmd()
.arg("transpile-project")
.arg("/nonexistent/dir/does/not/exist")
.arg("-o")
.arg(&output_dir)
.assert()
.failure()
.stderr(predicate::str::contains("not found"));
}
#[test]
fn cli_transpile_project_empty_dir() {
let temp = TempDir::new().unwrap();
let output_dir = temp.path().join("empty_out");
decy_cmd()
.arg("transpile-project")
.arg(temp.path())
.arg("-o")
.arg(&output_dir)
.assert()
.success()
.stdout(predicate::str::contains("No C files found"));
}
#[test]
fn cli_check_project_with_files() {
let temp = TempDir::new().unwrap();
create_temp_file(&temp, "main.c", "int main() { return 0; }");
create_temp_file(&temp, "util.c", "int helper() { return 1; }");
decy_cmd()
.arg("check-project")
.arg(temp.path())
.assert()
.success()
.stdout(predicate::str::contains("Found 2 C files"))
.stdout(predicate::str::contains("No circular dependencies"))
.stdout(predicate::str::contains("Build order"))
.stdout(predicate::str::contains("ready for transpilation"));
}
#[test]
fn cli_check_project_empty_dir() {
let temp = TempDir::new().unwrap();
decy_cmd()
.arg("check-project")
.arg(temp.path())
.assert()
.success()
.stdout(predicate::str::contains("No C files found"));
}
#[test]
fn cli_check_project_nonexistent_dir() {
decy_cmd()
.arg("check-project")
.arg("/nonexistent/dir/does/not/exist")
.assert()
.failure()
.stderr(predicate::str::contains("not found"));
}
#[test]
fn cli_cache_stats_no_cache_exists() {
let temp = TempDir::new().unwrap();
decy_cmd()
.arg("cache-stats")
.arg(temp.path())
.assert()
.success()
.stdout(predicate::str::contains("No cache found"));
}
#[test]
fn cli_cache_stats_nonexistent_dir() {
decy_cmd()
.arg("cache-stats")
.arg("/nonexistent/dir/does/not/exist")
.assert()
.failure()
.stderr(predicate::str::contains("not found"));
}