[v0.1/CLI Args Review] Snapshot the visible help and pin the valid/invalid argv matrix #185

Closed
opened 2026-09-07 16:10:23 +09:00 by natsukium · 1 comment
Owner

現状

#55 の完了条件に「全 visible command の help snapshot と valid/invalid argv matrix がテストされる」があるが、子 issue がなく追跡されていない。現行の crates/felis-cli/src/tests.rs は個別 assertion の散在 (the_launch_verbs_help_says_where_the_globals_gothe_retired_json_flag_is_an_unknown_argumentfelis_ssh_is_not_a_verb 等) であり、以下を固定していない。

  • 全 visible command の --help 全文。grammar 変更 (文言・語彙・配置) が意図せず help を変えても検出されない。
  • valid/invalid argv matrix。既に凍結した文法 (spawn-- <CMD>... 要求 — #53、--trace-perf 除去 — #54、send --rawrequires = "text"frontend の opaque pass-through 例外) が将来のリファクタで崩れても検出されない。

publish freeze 後に help/completion/man は生成物として固定される (#29)。その直前に、grammar の現在形をテストで錨止めする。

提案

  • 全 visible command (+ felis-client / felis-daemon serve の公開面) の long help を snapshot するテストを追加する。全文 golden か、語彙・配置の要点を押さえた assertion 群かは実装時に選ぶ。全文 golden を選ぶなら #184 (CLI 有限語彙の公開) の着地後に生成する。
  • valid/invalid argv matrix テストを追加する。最低限:
    • sessions spawn htop / spawn --json が usage error (exit 2) — #53 の回帰防止
    • spawn --format json -- htop --format json で前者のみ felis が消費 — #53
    • --trace-perf が unknown argument — #54
    • point verb + --format jsonl / stream verb + --format json が exit 2
    • felis ssh … が解決しない、frontend 以外の opaque pass-through がない
    • send --raw 単独 (payload なし) が usage error
  • 既存の散在 assertion は matrix へ統合するか、重複として残すかを決める (削除は必須としない)。

Principle check

いずれも capability を増やさない test-only の変更。principles 1–4 はすべて Pass (ないし非該当)。

Acceptance criteria

  • 全 visible command の help が snapshot / assertion で固定され、意図しない文言変更が just check で落ちる。
  • 上記 matrix の全行がテストされ、#53/#54 で凍結した文法の回帰が検出される。
  • #29 の golden (help/completion/man/schema) と重複する場合は役割分担がコメントで明示される (本件: parser 層の回帰防止、#29: 公開生成物の freeze)。

対象

  • crates/felis-cli/src/tests.rs (新規テスト)
  • crates/felis-client/src/tests.rscrates/felis-daemon の CLI test (公開面のみ)
  • 必要なら docs/reference/cli.md の grammar 記述との突合せ

Parent review: #55. Release tracker: #12.

## 現状 #55 の完了条件に「全 visible command の help snapshot と valid/invalid argv matrix がテストされる」があるが、子 issue がなく追跡されていない。現行の `crates/felis-cli/src/tests.rs` は個別 assertion の散在 (`the_launch_verbs_help_says_where_the_globals_go`、`the_retired_json_flag_is_an_unknown_argument`、`felis_ssh_is_not_a_verb` 等) であり、以下を固定していない。 - 全 visible command の `--help` 全文。grammar 変更 (文言・語彙・配置) が意図せず help を変えても検出されない。 - valid/invalid argv matrix。既に凍結した文法 (`spawn` の `-- <CMD>...` 要求 — #53、`--trace-perf` 除去 — #54、`send --raw` の `requires = "text"`、`frontend` の opaque pass-through 例外) が将来のリファクタで崩れても検出されない。 publish freeze 後に help/completion/man は生成物として固定される (#29)。その直前に、grammar の現在形をテストで錨止めする。 ## 提案 - 全 visible command (+ `felis-client` / `felis-daemon serve` の公開面) の long help を snapshot するテストを追加する。全文 golden か、語彙・配置の要点を押さえた assertion 群かは実装時に選ぶ。全文 golden を選ぶなら #184 (CLI 有限語彙の公開) の着地後に生成する。 - valid/invalid argv matrix テストを追加する。最低限: - `sessions spawn htop` / `spawn --json` が usage error (exit `2`) — #53 の回帰防止 - `spawn --format json -- htop --format json` で前者のみ felis が消費 — #53 - `--trace-perf` が unknown argument — #54 - point verb + `--format jsonl` / stream verb + `--format json` が exit `2` - `felis ssh …` が解決しない、`frontend` 以外の opaque pass-through がない - `send --raw` 単独 (payload なし) が usage error - 既存の散在 assertion は matrix へ統合するか、重複として残すかを決める (削除は必須としない)。 ## Principle check いずれも capability を増やさない test-only の変更。principles 1–4 はすべて Pass (ないし非該当)。 ## Acceptance criteria - [ ] 全 visible command の help が snapshot / assertion で固定され、意図しない文言変更が `just check` で落ちる。 - [ ] 上記 matrix の全行がテストされ、#53/#54 で凍結した文法の回帰が検出される。 - [ ] #29 の golden (help/completion/man/schema) と重複する場合は役割分担がコメントで明示される (本件: parser 層の回帰防止、#29: 公開生成物の freeze)。 ## 対象 - `crates/felis-cli/src/tests.rs` (新規テスト) - `crates/felis-client/src/tests.rs`、`crates/felis-daemon` の CLI test (公開面のみ) - 必要なら `docs/reference/cli.md` の grammar 記述との突合せ Parent review: #55. Release tracker: #12.
Author
Owner

Triage plan (2026-09-07)

Re-scoped. The help-snapshot half of this issue is delivered by #187 (an insta snapshot of Cli::command().render_long_help() for the root and every visible subcommand). What remains here is the valid/invalid argv matrix.

Approach

One test module in crates/felis-cli/src/tests.rs (parser layer, no daemon) that drives Cli::try_parse_from over a table of argv rows and asserts the outcome class: parses, or a clap error whose kind and exit code (2) are pinned. Rows, at minimum:

  • sessions spawn htop and sessions spawn --json → usage error (#53: bare program without -- is refused)
  • sessions spawn --format json -- htop --format json → only the first --format is felis's; the rest is the command (#53)
  • --trace-perf anywhere → unknown argument (#54)
  • a Point verb with --format jsonl and a Stream verb with --format json → invalid value, exit 2 (after #187 the error lists the possible values)
  • felis ssh … → no such verb; no opaque pass-through outside frontend
  • sessions send --raw with no payload → usage error (requires = "text")

Existing scattered assertions that a row now covers may stay or be folded into the table; deleting them is not required. Where #29's goldens already freeze a generated surface (help/completion/man/schema), a one-line comment at the top of the module states the split: this module pins the parser layer, #29's goldens freeze the published artifacts.

Tests

The table itself. Each row is one acceptance item; a row that passes with the guarded change reverted (e.g. -- requirement removed) does not belong.

Cascade

None expected: test-only. docs/reference/cli.md is consulted for the grammar the rows assert, not edited, unless a row exposes a doc falsehood.

Dependencies

After #187 merges (the invalid-value rows assert the ValueEnum error shape).

## Triage plan (2026-09-07) **Re-scoped.** The help-snapshot half of this issue is delivered by #187 (an insta snapshot of `Cli::command().render_long_help()` for the root and every visible subcommand). What remains here is the valid/invalid argv matrix. ## Approach One test module in `crates/felis-cli/src/tests.rs` (parser layer, no daemon) that drives `Cli::try_parse_from` over a table of argv rows and asserts the outcome class: parses, or a clap error whose `kind` and exit code (`2`) are pinned. Rows, at minimum: - `sessions spawn htop` and `sessions spawn --json` → usage error (#53: bare program without `--` is refused) - `sessions spawn --format json -- htop --format json` → only the first `--format` is felis's; the rest is the command (#53) - `--trace-perf` anywhere → unknown argument (#54) - a Point verb with `--format jsonl` and a Stream verb with `--format json` → invalid value, exit 2 (after #187 the error lists the possible values) - `felis ssh …` → no such verb; no opaque pass-through outside `frontend` - `sessions send --raw` with no payload → usage error (`requires = "text"`) Existing scattered assertions that a row now covers may stay or be folded into the table; deleting them is not required. Where #29's goldens already freeze a generated surface (help/completion/man/schema), a one-line comment at the top of the module states the split: this module pins the parser layer, #29's goldens freeze the published artifacts. ## Tests The table itself. Each row is one acceptance item; a row that passes with the guarded change reverted (e.g. `--` requirement removed) does not belong. ## Cascade None expected: test-only. `docs/reference/cli.md` is consulted for the grammar the rows assert, not edited, unless a row exposes a doc falsehood. ## Dependencies After #187 merges (the invalid-value rows assert the ValueEnum error shape).
Sign in to join this conversation.
No description provided.