test(aura-cli): RED for --help/-h success-path affordance

`aura --help` and `aura -h` are a newcomer's reflex first command, but
today they hit the unknown-subcommand error path: exit 2, empty stdout,
one-line `aura: usage: aura run` on stderr. For a C22 "newcomer sees a
populated trace" milestone the conventional help affordance returning
the error path is a first-contact friction.

This compile-clean RED pins the desired success-path contract: `--help`
and `-h` print non-empty usage to stdout and exit 0, and the usage names
the `run` subcommand. A negative-preservation assertion keeps an unknown
subcommand (`frobnicate`) on the exit-2 error path so the fix cannot
regress bad-args handling. Asserts structural facts only (exit code,
non-empty stdout, mentions `run`), not exact help prose.

refs #20
This commit is contained in:
2026-06-05 00:03:10 +02:00
parent ac4a8c68cf
commit 07ba20a991
+32
View File
@@ -34,3 +34,35 @@ fn no_args_prints_usage_and_exits_two() {
let stderr = String::from_utf8(out.stderr).expect("utf-8 stderr");
assert!(stderr.contains("usage"), "stderr was: {stderr:?}");
}
/// Property: `--help`/`-h` is the success-path help affordance, not the error
/// path. A newcomer's reflex first command (C22 first-contact ergonomics, #20)
/// prints the usage to stdout and exits 0; the conventional `-h` alias behaves
/// identically. An *unknown* subcommand keeps the error path (exit 2) so the
/// help fix does not regress bad-args handling.
#[test]
fn help_flag_prints_usage_to_stdout_and_exits_zero() {
for flag in ["--help", "-h"] {
let out = Command::new(BIN).arg(flag).output().expect("spawn aura --help");
assert_eq!(out.status.code(), Some(0), "`aura {flag}` exit: {:?}", out.status);
let stdout = String::from_utf8(out.stdout).expect("utf-8 stdout");
assert!(
!stdout.trim().is_empty(),
"`aura {flag}` should print help to stdout, got: {stdout:?}"
);
// The usage names the only subcommand a newcomer can run.
assert!(
stdout.contains("run"),
"`aura {flag}` help should mention the `run` subcommand, got: {stdout:?}"
);
}
// Negative-preservation: an unknown subcommand is still the error path.
let out = Command::new(BIN).arg("frobnicate").output().expect("spawn aura frobnicate");
assert_eq!(
out.status.code(),
Some(2),
"unknown subcommand must stay exit 2: {:?}",
out.status
);
}