1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! CLI contract snapshots driven by `trycmd`.
//!
//! Each case file under `tests/cmd/` is a frozen sample of the qli
//! binary's user-visible contract: argv, exit code, stdout, stderr.
//! These guard against accidental regressions to the help text,
//! suggestion behaviour, error messages, and exit codes — the
//! clig.dev compliance bar set in Phase 1.
//!
//! ## Scope (Phase 1L Push B)
//!
//! Six cases, deliberately narrow to keep the snapshots maintainable
//! across clap upgrades:
//! - `version.toml` — `qli --version`
//! - `completions-zsh.toml` — first line + redaction of zsh script body
//! - `unknown-no-tip.toml` — `qli foo` (no close subcommand → no tip)
//! - `unknown-with-tip.toml` — `qli porod hello` (typo of `prod` → tip)
//! - `missing-env.toml` — `qli prod hello` without `QLI_ENV` → export hint
//!
//! ## Refresh
//!
//! ```text
//! TRYCMD=overwrite cargo test -p qli --test cli
//! ```
//!
//! After overwriting, eyeball the diff before committing — clap
//! upgrades occasionally reflow help text in ways that look right but
//! drop a contract detail.
//!
//! ## Hermeticity
//!
//! Cases that touch dispatch (e.g. `missing-env`) need `XDG_*` and
//! `HOME` to point at non-host paths so the test never reads or writes
//! the developer's `~/.config/qli`. We set them to a pinned tempdir per
//! test invocation via `TestCases::env`. The embedded extension layer
//! (the `prod` group used by `missing-env`) ships inside the binary via
//! `include_dir!` and does not depend on host XDG state.
use Mutex;
// trycmd's runner mutates process env (XDG_*, HOME) inside `.run()`. The
// other integration tests in this crate (assert_cmd-based) gate with
// `#[serial_test::serial]`; this test serializes against them via the
// same `serial_test::serial` macro. The `Mutex` guarding `TRYCMD_LOCK`
// is belt-and-suspenders for any future trycmd parallelism.
static TRYCMD_LOCK: = new;