mirror of
https://github.com/ultraworkers/claw-code.git
synced 2026-05-30 03:35:20 +08:00
test(#742): add git-fixture test for diff changed_file_count dedup; fixes unreachable branch in #740 coverage
This commit is contained in:
parent
6e78c1fc8b
commit
2036f0bd4c
@ -7649,3 +7649,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed)
|
||||
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.
|
||||
|
||||
741. **`claw config list`, `claw config show`, `claw config bogus` --output-format json returned `hint: null` — the unsupported_config_section error envelope had no `hint` field populated, so callers reading `.hint` get null with no actionable guidance** — dogfooded 2026-05-26 on `5d072d21`. The `render_config_json` unsupported-section branch returned a JSON object with `error` (contains the section list) but no `hint` field. Notably `config list` and `config show` are natural verb patterns that users type expecting a list/show subcommand, but claw config uses `claw config` (no args) for list and `claw config <section>` for show — the error gave no indication of this. Fix: add `hint` field to unsupported_config_section error; verbs (`list`, `show`, `help`, `info`) get a hint explaining the correct idiom (`claw config` / `claw config <section>`); other unknown sections get a "not a config section" hint listing valid values. Source: Jobdori dogfood on `5d072d21`, 2026-05-26.
|
||||
|
||||
742. **ROADMAP #740 test coverage gap: the new `changed_file_count` branch for git repos was unreachable — the fixture is a plain `unique_temp_dir` (no `git init`), so the test always exercises the `no_git_repo` path and never proves the numeric contract or deduplication behavior** — confirmed by gaebal-gajae on `5d072d21`, fixed on `6e78c1fc`. Fix: add `diff_json_changed_file_count_deduplication_733` test that (a) `git init`s a temp repo, (b) commits a file, (c) asserts `result:"clean"` + `changed_file_count:0`, (d) stages an edit + makes an unstaged edit to the same file, (e) asserts `result:"changes"` + `changed_file_count:1` — proving the BTreeSet deduplication actually works. Source: gaebal-gajae dogfood on `5d072d21`, 2026-05-26.
|
||||
|
||||
@ -1376,6 +1376,86 @@ fn diff_json_has_status_and_result_field_702() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn diff_json_changed_file_count_deduplication_733() {
|
||||
// #733/#742: changed_file_count must be numeric in a git repo, be 0 for clean,
|
||||
// and deduplicate staged+unstaged edits to the same file (1 file changed = count 1).
|
||||
use std::process::Command;
|
||||
let root = unique_temp_dir("diff-changed-dedup");
|
||||
fs::create_dir_all(&root).expect("temp dir");
|
||||
|
||||
// git init + identity config + initial commit
|
||||
Command::new("git")
|
||||
.args(["init"])
|
||||
.current_dir(&root)
|
||||
.output()
|
||||
.expect("git init");
|
||||
Command::new("git")
|
||||
.args(["config", "user.email", "test@claw.test"])
|
||||
.current_dir(&root)
|
||||
.output()
|
||||
.expect("git config email");
|
||||
Command::new("git")
|
||||
.args(["config", "user.name", "Test"])
|
||||
.current_dir(&root)
|
||||
.output()
|
||||
.expect("git config name");
|
||||
fs::write(root.join("tracked.txt"), b"v1").expect("write tracked");
|
||||
Command::new("git")
|
||||
.args(["add", "tracked.txt"])
|
||||
.current_dir(&root)
|
||||
.output()
|
||||
.expect("git add");
|
||||
Command::new("git")
|
||||
.args(["commit", "-m", "init"])
|
||||
.current_dir(&root)
|
||||
.output()
|
||||
.expect("git commit");
|
||||
|
||||
// Clean state: changed_file_count must be 0
|
||||
let bin = env!("CARGO_BIN_EXE_claw");
|
||||
let clean = Command::new(bin)
|
||||
.current_dir(&root)
|
||||
.args(["--output-format", "json", "diff"])
|
||||
.output()
|
||||
.expect("claw diff clean");
|
||||
let clean_json: serde_json::Value =
|
||||
serde_json::from_slice(&clean.stdout).expect("diff clean stdout must be valid JSON");
|
||||
assert_eq!(clean_json["result"], "clean", "fresh repo must be clean");
|
||||
assert_eq!(
|
||||
clean_json["changed_file_count"].as_u64(),
|
||||
Some(0),
|
||||
"clean repo must have changed_file_count:0 (#733)"
|
||||
);
|
||||
|
||||
// Make a staged edit AND an unstaged edit to the same file
|
||||
fs::write(root.join("tracked.txt"), b"v2").expect("staged write");
|
||||
Command::new("git")
|
||||
.args(["add", "tracked.txt"])
|
||||
.current_dir(&root)
|
||||
.output()
|
||||
.expect("git add staged");
|
||||
fs::write(root.join("tracked.txt"), b"v3").expect("unstaged write");
|
||||
|
||||
// Dirty state: same file appears in staged+unstaged — must deduplicate to count 1
|
||||
let dirty = Command::new(bin)
|
||||
.current_dir(&root)
|
||||
.args(["--output-format", "json", "diff"])
|
||||
.output()
|
||||
.expect("claw diff dirty");
|
||||
let dirty_json: serde_json::Value =
|
||||
serde_json::from_slice(&dirty.stdout).expect("diff dirty stdout must be valid JSON");
|
||||
assert_eq!(
|
||||
dirty_json["result"], "changes",
|
||||
"dirty repo must have result:changes (#733)"
|
||||
);
|
||||
assert_eq!(
|
||||
dirty_json["changed_file_count"].as_u64(),
|
||||
Some(1),
|
||||
"staged+unstaged edits to same file must deduplicate to changed_file_count:1 (#733)"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn export_json_has_kind_702() {
|
||||
// #458/#702: `claw export --output-format json` must emit kind:export.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user