From 5d072d21e91b18061d725430a10e0dd5c88b52e7 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 26 May 2026 16:45:02 +0900 Subject: [PATCH] test(#740): diff JSON contract test now asserts changed_file_count field behavior per #733 --- ROADMAP.md | 2 ++ .../tests/output_format_contract.rs | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ROADMAP.md b/ROADMAP.md index 9624a70b..1ba5c2c8 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -7645,3 +7645,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed) 738. **`claw /commit --output-format json` (and all other interactive-only slash commands invoked outside a session) emitted `hint: null` — the remediation text was in the `error` prose string but no newline separated the short error from the hint, so `split_error_hint` returned the entire message as `error` and `hint: null`** — dogfooded 2026-05-26 on `c592313d`. The format string `"slash command {cmd} is interactive-only. Start `claw`..."` had no newline, so `split_error_hint` (which splits on `\n`) could not extract the hint. Fix: add `\n` between the short error `"slash command X is interactive-only."` and the remediation text, so callers reading `.hint` get the actionable guidance directly. Source: Jobdori dogfood on `c592313d`, 2026-05-26. 739. **`claw skills --output-format json` emitted two JSON objects on stdout: first the usage envelope (`action:"help", unexpected:"X"`), then a second error abort envelope (`kind:"unknown", error:"skills command failed"`) — the `print_skills` JSON path returned `Err` on `status:"error"` responses even when the response was a normal usage-display (`action:"help"`), causing the generic error serializer to emit the second envelope** — dogfooded 2026-05-26 on `4c3cb0f3`. Fix: skip the `return Err` path when `action == "help"`; usage envelopes are informational, not fatal errors. The root prompt-dispatch gap (`claw skills bogus` → `CliAction::Prompt` → `missing_credentials` in no-creds env) is a pre-existing auth-gate-on-local-surface issue (ROADMAP #431/#449) and not addressed here. Source: Jobdori dogfood on `4c3cb0f3`, 2026-05-26. + +740. **Test coverage gap for ROADMAP #733: `diff_json_has_status_and_result_field_702` did not assert `changed_file_count` contract** — dogfooded 2026-05-26 on `d5f0d6ed`. The test asserts `kind`, `status`, `result`, `action`, `working_directory` but not the new `changed_file_count` field added by #733. Coverage gap: (a) no assertion that the field exists, (b) no assertion of numeric type in git repos, (c) no regression guard for dedupe behavior (staged+unstaged to the same file = 1 changed file). Fix: extend the test to assert `changed_file_count: null` in non-git repos and `changed_file_count: u64` in git repos. Source: gaebal-gajae dogfood on `d5f0d6ed`, 2026-05-26. diff --git a/rust/crates/rusty-claude-cli/tests/output_format_contract.rs b/rust/crates/rusty-claude-cli/tests/output_format_contract.rs index e598cbe8..1fc8165b 100644 --- a/rust/crates/rusty-claude-cli/tests/output_format_contract.rs +++ b/rust/crates/rusty-claude-cli/tests/output_format_contract.rs @@ -1356,6 +1356,24 @@ fn diff_json_has_status_and_result_field_702() { .is_some(), "diff JSON must have working_directory field (#710)" ); + // #740: diff JSON changed_file_count contract: numeric in git repos, absent for no_git_repo + let result_str = parsed.get("result").and_then(|v| v.as_str()); + if result_str == Some("no_git_repo") { + // Non-git repos don't emit changed_file_count + assert!( + parsed.get("changed_file_count").is_none(), + "diff JSON should not have changed_file_count for no_git_repo (#733)" + ); + } else { + // Git repos must emit numeric changed_file_count + assert!( + parsed + .get("changed_file_count") + .and_then(|v| v.as_u64()) + .is_some(), + "diff JSON changed_file_count must be numeric in git repos (#733)" + ); + } } #[test]