#![allow(clippy::ignore_without_reason)] #![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_check_valid_file_exits_zero() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "valid.ruchy", "let x = 1 + 1\n");
ruchy_cmd().arg("check").arg(&file).assert().success(); }
#[test]
fn cli_check_invalid_syntax_exits_nonzero() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "invalid.ruchy", "let x = \n");
ruchy_cmd().arg("check").arg(&file).assert().failure(); }
#[test]
fn cli_check_missing_file_exits_nonzero() {
ruchy_cmd()
.arg("check")
.arg("nonexistent_file_12345.ruchy")
.assert()
.failure(); }
#[test]
fn cli_check_valid_file_writes_stdout() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "valid.ruchy", "let x = 42\n");
ruchy_cmd()
.arg("check")
.arg(&file)
.assert()
.success()
.stdout(predicate::str::contains("✓").or(predicate::str::contains("valid")));
}
#[test]
fn cli_check_invalid_syntax_writes_stderr() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "invalid.ruchy", "fun f( { }\n");
ruchy_cmd()
.arg("check")
.arg(&file)
.assert()
.failure()
.stderr(predicate::str::is_empty().not()); }
#[test]
fn cli_check_missing_file_writes_stderr() {
ruchy_cmd()
.arg("check")
.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_check_error_includes_filename() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "bad_syntax.ruchy", "let x = \n");
ruchy_cmd()
.arg("check")
.arg(&file)
.assert()
.failure()
.stderr(predicate::str::contains("bad_syntax.ruchy"));
}
#[test]
fn cli_check_error_includes_line_number() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "error_line.ruchy", "let x = 1\nlet y = \n");
let output = ruchy_cmd().arg("check").arg(&file).assert().failure();
let stderr = String::from_utf8_lossy(&output.get_output().stderr);
assert!(
stderr.contains("line 2") || stderr.contains(":2:") || stderr.contains(" 2"),
"Error should include line number, got: {stderr}"
);
}
#[test]
fn cli_check_multiple_files_checks_all() {
let temp = TempDir::new().unwrap();
let file1 = create_temp_file(&temp, "valid1.ruchy", "let x = 1\n");
let file2 = create_temp_file(&temp, "valid2.ruchy", "let y = 2\n");
ruchy_cmd()
.arg("check")
.arg(&file1)
.arg(&file2)
.assert()
.success();
}
#[test]
fn cli_check_empty_file_is_error() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "empty.ruchy", "");
ruchy_cmd()
.arg("check")
.arg(&file)
.assert()
.failure() .stderr(predicate::str::contains("Empty program"));
}
#[test]
fn cli_check_whitespace_only_is_error() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "whitespace.ruchy", " \n \n \n");
ruchy_cmd()
.arg("check")
.arg(&file)
.assert()
.failure() .stderr(predicate::str::contains("Empty program"));
}
#[test]
fn cli_check_comment_only_is_error() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "comments.ruchy", "// This is a comment\n");
ruchy_cmd()
.arg("check")
.arg(&file)
.assert()
.failure() .stderr(predicate::str::contains("Empty program"));
}