use std::fs;
use std::path::PathBuf;
use std::process::Command;
use tempfile::tempdir;
fn rustedscithe_bin() -> PathBuf {
std::env::var_os("CARGO_BIN_EXE_RustedSciThe")
.or_else(|| std::env::var_os("CARGO_BIN_EXE_rustedscithe"))
.map(PathBuf::from)
.expect("RustedSciThe binary should be available to integration tests")
}
fn run_cli(args: &[&str]) -> std::process::Output {
Command::new(rustedscithe_bin())
.args(args)
.output()
.expect("CLI process should start")
}
fn read_fixture(name: &str) -> String {
fs::read_to_string(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures").join(name))
.expect("fixture should be readable")
}
fn write_temp_task_doc(contents: &str, stem: &str) -> PathBuf {
let dir = tempdir().expect("tempdir should be created");
let dir_path = dir.keep();
let path = dir_path.join(format!("{stem}.txt"));
fs::write(&path, contents).expect("task document should be writable");
path
}
#[test]
fn help_mentions_current_top_level_commands() {
let output = run_cli(&["--help"]);
assert!(output.status.success(), "help command should succeed");
let stdout = String::from_utf8_lossy(&output.stdout);
assert_eq!(stdout, read_fixture("task_shell_help.txt"));
}
#[test]
fn showcase_mentions_parser_ready_template_and_guide_entrypoints() {
let output = run_cli(&["showcase"]);
assert!(output.status.success(), "showcase command should succeed");
let stdout = String::from_utf8_lossy(&output.stdout);
assert_eq!(stdout, read_fixture("task_shell_showcase.txt"));
}
#[test]
fn check_mode_renders_substituted_preview_without_running_solver() {
let task_doc = r#"
task
solver: IVP
method: RK45
equations
arg: t
y: -y
initial_conditions
t0: 0.0
t_end: 1.0
y0: 1.0
solver_options
step_size: 1e-3
"#;
let path = write_temp_task_doc(task_doc, "ivp_check_contract");
let output = run_cli(&["check", path.to_string_lossy().as_ref()]);
assert!(output.status.success(), "check mode should succeed");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("[Task check] IVP"));
assert!(stdout.contains("fully substituted equations"));
assert!(stdout.contains("solver=IVP, method=RK45"));
assert!(stdout.contains("idx | unknown | rhs"));
assert!(stdout.contains("0 | y | -1 * y"));
}
#[test]
fn ffi_dependency_report_lists_expected_tools() {
let output = run_cli(&["check-ffi-dependencies"]);
assert!(output.status.success(), "ffi dependency probe should succeed");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("RustedSciThe external dependency report"));
assert!(stdout.contains("platform:"));
assert!(stdout.contains("probe strategy: PATH-based process checks"));
assert!(stdout.contains("rustc"));
assert!(stdout.contains("cargo"));
assert!(stdout.contains("tcc"));
assert!(stdout.contains("gcc"));
assert!(stdout.contains("zig"));
assert!(stdout.contains("gnuplot"));
assert!(stdout.contains("pandoc"));
assert!(stdout.contains("arrayfire"));
}