From 0edc93e1c31eb770fec7a37438159acac555a491 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 23 Feb 2026 10:58:54 -0500 Subject: [PATCH] Add CLI tests for validate and dry-run on all test workflows Co-Authored-By: Claude Opus 4.6 --- Cargo.lock | 2 + crates/attractor/Cargo.toml | 2 + crates/attractor/tests/cli.rs | 104 ++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 crates/attractor/tests/cli.rs diff --git a/Cargo.lock b/Cargo.lock index eff007e60..86b6d59be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,6 +165,7 @@ version = "0.1.0" dependencies = [ "agent", "anyhow", + "assert_cmd", "async-trait", "axum", "chrono", @@ -174,6 +175,7 @@ dependencies = [ "http-body-util", "llm", "nom", + "predicates", "rand", "serde", "serde_json", diff --git a/crates/attractor/Cargo.toml b/crates/attractor/Cargo.toml index b98e07d09..e06162c50 100644 --- a/crates/attractor/Cargo.toml +++ b/crates/attractor/Cargo.toml @@ -48,6 +48,8 @@ tower = "0.5" tokio-stream = { workspace = true, features = ["sync"] } http-body-util = "0.1" dotenvy.workspace = true +assert_cmd = "2" +predicates = "3" [lints] workspace = true diff --git a/crates/attractor/tests/cli.rs b/crates/attractor/tests/cli.rs new file mode 100644 index 000000000..25ad28610 --- /dev/null +++ b/crates/attractor/tests/cli.rs @@ -0,0 +1,104 @@ +use assert_cmd::Command; +use predicates::prelude::*; + +#[allow(deprecated)] +fn attractor() -> Command { + Command::cargo_bin("attractor").unwrap() +} + +// -- validate ---------------------------------------------------------------- + +#[test] +fn validate_simple() { + attractor() + .args(["validate", "../../test/simple.dot"]) + .assert() + .success() + .stdout(predicate::str::contains("Validation: OK")); +} + +#[test] +fn validate_branching() { + attractor() + .args(["validate", "../../test/branching.dot"]) + .assert() + .success() + .stdout(predicate::str::contains("Validation: OK")); +} + +#[test] +fn validate_conditions() { + attractor() + .args(["validate", "../../test/conditions.dot"]) + .assert() + .success() + .stdout(predicate::str::contains("Validation: OK")); +} + +#[test] +fn validate_parallel() { + attractor() + .args(["validate", "../../test/parallel.dot"]) + .assert() + .success() + .stdout(predicate::str::contains("Validation: OK")); +} + +#[test] +fn validate_styled() { + attractor() + .args(["validate", "../../test/styled.dot"]) + .assert() + .success() + .stdout(predicate::str::contains("Validation: OK")); +} + +#[test] +fn validate_invalid() { + attractor() + .args(["validate", "../../test/invalid.dot"]) + .assert() + .failure(); +} + +// -- run --dry-run ----------------------------------------------------------- + +#[test] +fn dry_run_simple() { + attractor() + .args(["run", "--dry-run", "--auto-approve", "../../test/simple.dot"]) + .assert() + .success(); +} + +#[test] +fn dry_run_branching() { + attractor() + .args(["run", "--dry-run", "--auto-approve", "../../test/branching.dot"]) + .assert() + .success(); +} + +#[test] +fn dry_run_conditions() { + attractor() + .args(["run", "--dry-run", "--auto-approve", "../../test/conditions.dot"]) + .assert() + .success(); +} + +#[test] +fn dry_run_parallel() { + attractor() + .args(["run", "--dry-run", "--auto-approve", "../../test/parallel.dot"]) + .assert() + .success(); +} + +#[test] +fn dry_run_styled() { + attractor() + .args(["run", "--dry-run", "--auto-approve", "../../test/styled.dot"]) + .assert() + .success(); +}