use assert_cmd::Command;
use predicates::prelude::*;
use std::fs;
use tempfile::TempDir;
fn axonml_cmd() -> Command {
Command::cargo_bin("axonml").unwrap()
}
#[test]
fn test_cli_help() {
axonml_cmd()
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("Usage:"))
.stdout(predicate::str::contains("Commands:"))
.stdout(predicate::str::contains("train").or(predicate::str::contains("Train")));
}
#[test]
fn test_cli_version() {
axonml_cmd()
.arg("--version")
.assert()
.success()
.stdout(predicate::str::contains("axonml"));
}
#[test]
fn test_new_project_creates_structure() {
let temp_dir = TempDir::new().unwrap();
let project_name = "test_ml_project";
axonml_cmd()
.arg("new")
.arg(project_name)
.arg("--path")
.arg(temp_dir.path())
.arg("--no-git")
.assert()
.success()
.stdout(predicate::str::contains("Created project"));
let project_path = temp_dir.path().join(project_name);
assert!(project_path.exists(), "Project directory should exist");
assert!(
project_path.join("axonml.toml").exists(),
"Config file should exist"
);
assert!(
project_path.join("src").exists(),
"src directory should exist"
);
assert!(
project_path.join("data").exists(),
"data directory should exist"
);
}
#[test]
fn test_new_project_with_template() {
let temp_dir = TempDir::new().unwrap();
axonml_cmd()
.arg("new")
.arg("cnn_project")
.arg("--path")
.arg(temp_dir.path())
.arg("--template")
.arg("cnn")
.arg("--no-git")
.assert()
.success();
let project_path = temp_dir.path().join("cnn_project");
assert!(project_path.exists());
}
#[test]
fn test_init_in_existing_directory() {
let temp_dir = TempDir::new().unwrap();
axonml_cmd()
.current_dir(temp_dir.path())
.arg("init")
.arg("--no-git")
.assert()
.success()
.stdout(predicate::str::contains("Initialized Axonml project"));
assert!(temp_dir.path().join("axonml.toml").exists());
}
#[test]
fn test_gpu_list() {
axonml_cmd().arg("gpu").arg("list").assert().success();
}
#[test]
fn test_gpu_info() {
axonml_cmd().arg("gpu").arg("info").assert().success();
}
#[test]
fn test_gpu_status() {
axonml_cmd().arg("gpu").arg("status").assert().success();
}
#[test]
fn test_hub_list() {
axonml_cmd()
.arg("hub")
.arg("list")
.assert()
.success()
.stdout(
predicate::str::contains("resnet")
.or(predicate::str::contains("ResNet"))
.or(predicate::str::contains("Model")),
);
}
#[test]
fn test_hub_info() {
axonml_cmd()
.arg("hub")
.arg("info")
.arg("resnet18")
.assert()
.success()
.stdout(predicate::str::contains("ResNet"));
}
#[test]
fn test_hub_cached() {
axonml_cmd().arg("hub").arg("cached").assert().success();
}
#[test]
fn test_dataset_list() {
axonml_cmd()
.arg("dataset")
.arg("list")
.assert()
.success()
.stdout(
predicate::str::contains("mnist")
.or(predicate::str::contains("MNIST"))
.or(predicate::str::contains("Dataset")),
);
}
#[test]
fn test_dataset_info() {
axonml_cmd()
.arg("dataset")
.arg("info")
.arg("mnist")
.assert()
.success()
.stdout(predicate::str::contains("MNIST"));
}
#[test]
fn test_dataset_sources() {
axonml_cmd()
.arg("dataset")
.arg("sources")
.assert()
.success()
.stdout(predicate::str::contains("builtin"));
}
#[test]
fn test_bench_hardware() {
axonml_cmd()
.arg("bench")
.arg("hardware")
.arg("--iterations")
.arg("2")
.assert()
.success()
.stdout(predicate::str::contains("Hardware Benchmark"));
}
#[test]
fn test_quant_list() {
axonml_cmd()
.arg("quant")
.arg("list")
.assert()
.success()
.stdout(predicate::str::contains("Q4_0"))
.stdout(predicate::str::contains("Q8_0"))
.stdout(predicate::str::contains("F16"));
}
#[test]
fn test_scaffold_templates() {
axonml_cmd()
.arg("scaffold")
.arg("templates")
.assert()
.success()
.stdout(predicate::str::contains("training"))
.stdout(predicate::str::contains("Template"));
}
#[test]
fn test_scaffold_generate() {
let temp_dir = TempDir::new().unwrap();
let result = axonml_cmd()
.arg("scaffold")
.arg("generate")
.arg("my_training_project")
.arg("--output")
.arg(temp_dir.path())
.arg("--template")
.arg("minimal")
.assert();
let _ = result; }
#[test]
fn test_load_status() {
axonml_cmd().arg("load").arg("status").assert().success();
}
#[test]
fn test_load_clear() {
axonml_cmd().arg("load").arg("clear").assert().success();
}
#[test]
fn test_analyze_model_without_loaded() {
let result = axonml_cmd().arg("analyze").arg("model").assert();
let _ = result;
}
#[test]
fn test_inspect_nonexistent_model() {
axonml_cmd()
.arg("inspect")
.arg("/nonexistent/model.axonml")
.assert()
.failure(); }
#[test]
fn test_zip_create_and_list() {
let temp_dir = TempDir::new().unwrap();
let bundle_path = temp_dir.path().join("test_bundle.axonmlbundle");
let model_path = temp_dir.path().join("model.bin");
fs::write(&model_path, b"dummy model data").unwrap();
axonml_cmd()
.arg("zip")
.arg("create")
.arg("--output")
.arg(&bundle_path)
.arg("--model")
.arg(&model_path)
.assert()
.success();
if bundle_path.exists() {
axonml_cmd()
.arg("zip")
.arg("list")
.arg(&bundle_path)
.assert()
.success();
}
}
#[test]
fn test_kaggle_status() {
axonml_cmd().arg("kaggle").arg("status").assert().success(); }
#[test]
fn test_kaggle_list() {
axonml_cmd().arg("kaggle").arg("list").assert().success();
}
#[test]
fn test_data_list() {
let temp_dir = TempDir::new().unwrap();
axonml_cmd()
.arg("data")
.arg("list")
.arg("--path")
.arg(temp_dir.path())
.assert()
.success();
}
#[test]
fn test_data_validate_nonexistent() {
axonml_cmd()
.arg("data")
.arg("validate")
.arg("/nonexistent/data")
.assert()
.failure(); }
#[test]
fn test_verbose_flag() {
axonml_cmd()
.arg("--verbose")
.arg("hub")
.arg("list")
.assert()
.success();
}
#[test]
fn test_quiet_flag() {
axonml_cmd()
.arg("--quiet")
.arg("hub")
.arg("list")
.assert()
.success();
}
#[test]
fn test_train_help() {
axonml_cmd()
.arg("train")
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("epochs"))
.stdout(predicate::str::contains("batch-size"))
.stdout(predicate::str::contains("learning rate").or(predicate::str::contains("lr")));
}
#[test]
fn test_eval_help() {
axonml_cmd()
.arg("eval")
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("model"))
.stdout(predicate::str::contains("metrics"));
}
#[test]
fn test_convert_help() {
axonml_cmd()
.arg("convert")
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("INPUT").or(predicate::str::contains("input")))
.stdout(predicate::str::contains("OUTPUT").or(predicate::str::contains("output")));
}
#[test]
fn test_export_help() {
axonml_cmd()
.arg("export")
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("format"))
.stdout(predicate::str::contains("onnx").or(predicate::str::contains("ONNX")));
}
#[test]
fn test_invalid_command() {
axonml_cmd().arg("nonexistent_command").assert().failure();
}
#[test]
fn test_missing_required_args() {
axonml_cmd()
.arg("eval")
.assert()
.failure()
.stderr(predicate::str::contains("required"));
}
#[test]
fn test_full_project_workflow() {
let temp_dir = TempDir::new().unwrap();
let project_name = "e2e_test_project";
axonml_cmd()
.arg("new")
.arg(project_name)
.arg("--path")
.arg(temp_dir.path())
.arg("--no-git")
.assert()
.success();
let project_path = temp_dir.path().join(project_name);
assert!(project_path.join("axonml.toml").exists());
assert!(project_path.join("src").exists());
axonml_cmd()
.current_dir(&project_path)
.arg("load")
.arg("status")
.assert()
.success();
axonml_cmd()
.current_dir(&project_path)
.arg("dataset")
.arg("list")
.assert()
.success();
axonml_cmd()
.current_dir(&project_path)
.arg("hub")
.arg("list")
.assert()
.success();
println!("✓ Full project workflow completed successfully");
}
#[test]
fn test_multiple_help_commands() {
for cmd in &["new", "train", "eval", "hub", "dataset", "gpu"] {
axonml_cmd().arg(cmd).arg("--help").assert().success();
}
}