Files
wordcraft/apps/wordcraft-cli/tests/help.rs
1c2f0fe65e --help and -h print the usage for the app and every CLI command (#968) (#977)
* --help and -h print the usage for the app and every CLI command (#968)

wordcraft --help / -h printed nothing useful: the app tried to open a
file named --help and started. wordcraft-cli <command> --help failed with
"unknown option --help" for every command, and -h was taken as a file
name or ignored.

The app now prints its options and returns before the window opens.
The CLI checks for --help / -h after any known command before options
are validated or files and folders opened, and prints the shared usage.
Tests run both binaries for each command and flag; the app's test runs
without a display, so a regression fails instead of opening a window.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* #968: test bare --help and -h on wordcraft-cli

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-14 15:08:15 -04:00

48 lines
1.9 KiB
Rust

//! `--help` or `-h` after any subcommand prints the usage and exits 0, before options are checked
//! or files and folders opened (#968).
use std::process::{Command, Output};
const SUBCOMMANDS: [&str; 10] = ["convert", "info", "text", "inspect", "render", "run", "commands", "parity", "mcp", "zotero"];
fn cli(args: &[&str]) -> Output {
// `output()` gives the child no stdin, so `mcp` can't wait for a client.
Command::new(env!("CARGO_BIN_EXE_wordcraft-cli")).args(args).output().unwrap()
}
fn assert_prints_usage(args: &[&str]) {
let out = cli(args);
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(out.status.success(), "{args:?}: status {:?}, stderr: {stderr}", out.status);
assert!(String::from_utf8_lossy(&out.stdout).starts_with("wordcraft-cli — "), "{args:?}: stdout: {}", String::from_utf8_lossy(&out.stdout));
assert!(stderr.is_empty(), "{args:?}: stderr: {stderr}");
}
#[test]
fn every_subcommand_prints_usage_for_help_and_h() {
assert_prints_usage(&["--help"]);
assert_prints_usage(&["-h"]);
for sub in SUBCOMMANDS {
for flag in ["--help", "-h"] {
assert_prints_usage(&[sub, flag]);
}
}
}
#[test]
fn help_comes_before_opening_files_and_folders() {
assert_prints_usage(&["info", "missing.docx", "--help"]);
assert_prints_usage(&["convert", "missing.docx", "out.pdf", "-h"]);
assert_prints_usage(&["mcp", "--automation-read-root", "/definitely/not/a/folder", "--help"]);
}
#[test]
fn misspelled_options_and_unknown_commands_still_fail() {
let out = cli(&["info", "--hepl"]);
assert!(!out.status.success());
assert!(String::from_utf8_lossy(&out.stderr).contains("info: unknown option --hepl"));
let out = cli(&["frobnicate", "--help"]);
assert!(!out.status.success());
assert!(String::from_utf8_lossy(&out.stderr).contains("unknown command `frobnicate`"));
}