Skip to content

Commit ac97ed8

Browse files
josealekhineclaude
andcommitted
test: add subcommand execution verification
Add integration test that verifies each subcommand executes properly and doesn't silently fall through to root help text. Tests check that: - status, agent, drift, load, hook all produce expected output - None of them contain "Available Commands:" (root help indicator) This catches bugs where subcommands fail to register or wire up properly. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 2298ed6 commit ac97ed8

2 files changed

Lines changed: 38 additions & 1 deletion

File tree

.context/TASKS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
- [x] Set unit test coverage target (70% for internal/cli, internal/context)
5353
- [x] Add coverage reporting to `make test`
5454
- [x] Add smoke test to CI/Makefile: build binary, run basic commands
55-
- [ ] Verify built binary executes subcommands (not silently falling through to root help)
55+
- [x] Verify built binary executes subcommands (not silently falling through to root help)
5656

5757
### Phase 8: Task Archival & Snapshots `#priority:medium` `#area:cli`
5858
- [ ] Implement `ctx tasks archive` — move completed tasks to timestamped archive file

internal/cli/cli_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,4 +459,41 @@ func TestBinaryIntegration(t *testing.T) {
459459
t.Fatalf("ctx drift failed: %v\n%s", err, output)
460460
}
461461
})
462+
463+
// Subtest: verify all subcommands execute (not falling through to root help)
464+
t.Run("subcommands execute without falling through to root help", func(t *testing.T) {
465+
// Commands that should produce output without "Available Commands:"
466+
// (which would indicate they fell through to root help)
467+
subcommands := []struct {
468+
args []string
469+
checkFor string // expected output marker
470+
}{
471+
{[]string{"status"}, "Context"},
472+
{[]string{"agent"}, "Context Packet"},
473+
{[]string{"drift"}, "Drift"},
474+
{[]string{"load"}, ""}, // load outputs context, varies by content
475+
{[]string{"hook", "cursor"}, "Cursor"}, // hook outputs integration instructions
476+
}
477+
478+
for _, tc := range subcommands {
479+
t.Run(strings.Join(tc.args, "_"), func(t *testing.T) {
480+
cmd := exec.Command(binaryPath, tc.args...)
481+
cmd.Dir = testDir
482+
output, err := cmd.CombinedOutput()
483+
if err != nil {
484+
t.Fatalf("ctx %s failed: %v\n%s", strings.Join(tc.args, " "), err, output)
485+
}
486+
487+
outputStr := string(output)
488+
// Critical check: should NOT contain root help indicators
489+
if strings.Contains(outputStr, "Available Commands:") {
490+
t.Errorf("ctx %s fell through to root help:\n%s", strings.Join(tc.args, " "), outputStr)
491+
}
492+
// If we have an expected marker, check for it
493+
if tc.checkFor != "" && !strings.Contains(outputStr, tc.checkFor) {
494+
t.Errorf("ctx %s missing expected output %q:\n%s", strings.Join(tc.args, " "), tc.checkFor, outputStr)
495+
}
496+
})
497+
}
498+
})
462499
}

0 commit comments

Comments
 (0)