use fabro_test::{fabro_snapshot, test_context}; use serde_json::Value; use super::support::fixture; #[test] fn help() { let context = test_context!(); let mut cmd = context.command(); cmd.args(["preflight", "--help"]); fabro_snapshot!(context.filters(), cmd, @" success: true exit_code: 0 ----- stdout ----- Validate run configuration without executing Usage: fabro preflight [OPTIONS] Arguments: Path to a .fabro workflow file or .toml task config Options: --json Output as JSON [env: FABRO_JSON=] --server Fabro server target: http(s) URL or absolute Unix socket path [env: FABRO_SERVER=] --debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=] --goal Override the workflow goal (available as {{ goal }} in prompts) --goal-file Read the workflow goal from a file --no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true] --model Override default LLM model --quiet Suppress non-essential output [env: FABRO_QUIET=] --provider Override default LLM provider -v, --verbose Enable verbose output --sandbox Sandbox for agent tools [possible values: local, docker, daytona] -h, --help Print help ----- stderr ----- "); } #[test] fn preflight_invalid_workflow_fails_with_validation_output() { let context = test_context!(); let workflow = fixture("invalid.fabro"); let mut cmd = context.command(); cmd.args(["preflight", workflow.to_str().unwrap()]); fabro_snapshot!(context.filters(), cmd, @" success: false exit_code: 1 ----- stdout ----- ----- stderr ----- Workflow: Invalid (2 nodes, 1 edges) Graph: [FIXTURES]/invalid.fabro error: Pipeline must have exactly one start node (shape=Mdiamond or id start/Start) (start_node) error [node: exit]: Exit node 'exit' has 1 outgoing edge(s) but must have none (exit_no_outgoing) × Validation failed "); } #[test] fn preflight_invalid_workflow_json_emits_diagnostics() { let context = test_context!(); let workflow = fixture("invalid.fabro"); let output = context .command() .args(["--json", "preflight", workflow.to_str().unwrap()]) .output() .expect("command should run"); assert!(!output.status.success()); let value: Value = serde_json::from_slice(&output.stdout).expect("preflight --json should parse"); assert_eq!(value["workflow"]["name"], "Invalid"); assert!( value["workflow"]["diagnostics"] .as_array() .is_some_and(|diagnostics| !diagnostics.is_empty()) ); assert_eq!(value["checks"]["title"], "Run Preflight"); let stderr = String::from_utf8(output.stderr).unwrap(); assert!(stderr.contains("Validation failed")); }