#![allow(missing_docs)]
use assert_cmd::Command;
use predicates::prelude::*;
use std::fs;
use tempfile::TempDir;
fn ruchy_cmd() -> Command {
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
}
fn create_temp_file(dir: &TempDir, name: &str, content: &str) -> std::path::PathBuf {
let path = dir.path().join(name);
fs::write(&path, content).expect("Failed to write temp file");
path
}
#[test]
fn cli_coverage_valid_program_exits_zero() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "test.ruchy", "println(\"coverage test\")\n");
ruchy_cmd().arg("coverage").arg(&file).assert().success(); }
#[test]
fn cli_coverage_syntax_error_exits_nonzero() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "invalid.ruchy", "let x = \n");
ruchy_cmd().arg("coverage").arg(&file).assert().failure(); }
#[test]
fn cli_coverage_missing_file_exits_nonzero() {
ruchy_cmd()
.arg("coverage")
.arg("nonexistent_xyz.ruchy")
.assert()
.failure(); }
#[test]
fn cli_coverage_below_threshold_exits_nonzero() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(
&temp,
"partial.ruchy",
r#"
fun test_function(x) {
if x > 0 {
println("positive")
} else {
println("negative")
}
}
test_function(5)
"#,
);
ruchy_cmd()
.arg("coverage")
.arg(&file)
.arg("--threshold")
.arg("100.0")
.assert()
.failure(); }
#[test]
fn cli_coverage_text_format_output() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "simple.ruchy", "let x = 42\nprintln(x)\n");
ruchy_cmd()
.arg("coverage")
.arg(&file)
.arg("--format")
.arg("text")
.assert()
.success()
.stdout(
predicate::str::contains("Coverage")
.or(predicate::str::contains("Lines"))
.or(predicate::str::contains("%")),
);
}
#[test]
fn cli_coverage_json_format_output() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "json_test.ruchy", "println(\"json\")\n");
let output = ruchy_cmd()
.arg("coverage")
.arg(&file)
.arg("--format")
.arg("json")
.assert()
.success();
let stdout = String::from_utf8_lossy(&output.get_output().stdout);
assert!(
stdout.contains('{') && stdout.contains('}'),
"Should output JSON format"
);
}
#[test]
fn cli_coverage_html_format_output() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "html_test.ruchy", "println(\"html\")\n");
ruchy_cmd()
.arg("coverage")
.arg(&file)
.arg("--format")
.arg("html")
.assert()
.success()
.stdout(
predicate::str::contains("<")
.or(predicate::str::contains("html"))
.or(predicate::str::contains("Coverage")),
);
}
#[test]
fn cli_coverage_syntax_error_writes_stderr() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "bad_syntax.ruchy", "fun f( { }\n");
ruchy_cmd()
.arg("coverage")
.arg(&file)
.assert()
.failure()
.stderr(predicate::str::is_empty().not()); }
#[test]
fn cli_coverage_missing_file_writes_stderr() {
ruchy_cmd()
.arg("coverage")
.arg("missing.ruchy")
.assert()
.failure()
.stderr(
predicate::str::contains("not found")
.or(predicate::str::contains("No such file"))
.or(predicate::str::contains("does not exist")),
);
}
#[test]
fn cli_coverage_meets_threshold_succeeds() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "full.ruchy", "println(\"full coverage\")\n");
ruchy_cmd()
.arg("coverage")
.arg(&file)
.arg("--threshold")
.arg("0.0")
.assert()
.success();
}
#[test]
fn cli_coverage_threshold_message() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "threshold_test.ruchy", "println(\"test\")\n");
let output = ruchy_cmd()
.arg("coverage")
.arg(&file)
.arg("--threshold")
.arg("50.0")
.assert();
let stdout = String::from_utf8_lossy(&output.get_output().stdout);
let stderr = String::from_utf8_lossy(&output.get_output().stderr);
let combined = format!("{stdout}{stderr}");
assert!(
combined.contains("threshold") || combined.contains("50"),
"Threshold information should be displayed"
);
}
#[test]
fn cli_coverage_empty_file_succeeds() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "empty.ruchy", "");
ruchy_cmd()
.arg("coverage")
.arg(&file)
.assert()
.success()
.stdout(predicate::str::contains("100"));
}
#[test]
fn cli_coverage_comment_only_succeeds() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "comments.ruchy", "// Just a comment\n");
ruchy_cmd()
.arg("coverage")
.arg(&file)
.assert()
.success()
.stdout(predicate::str::contains("100"));
}
#[test]
fn cli_coverage_complex_program() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(
&temp,
"complex.ruchy",
r"
fun factorial(n) {
if n <= 1 {
1
} else {
n * factorial(n - 1)
}
}
fun fibonacci(n) {
if n <= 1 {
n
} else {
fibonacci(n - 1) + fibonacci(n - 2)
}
}
println(factorial(5))
println(fibonacci(8))
",
);
ruchy_cmd()
.arg("coverage")
.arg(&file)
.assert()
.success()
.stdout(predicate::str::contains("Coverage").or(predicate::str::contains("%")));
}
#[test]
fn cli_coverage_with_verbose_flag() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "verbose.ruchy", "println(\"verbose test\")\n");
ruchy_cmd()
.arg("coverage")
.arg(&file)
.arg("--verbose")
.assert()
.success();
}