CodeVetter · Repo Unpack · Testing signals
anthropics/claude-code
Automated tests exist only for the four mods and only under the Claude Code plugin test host, not Jest, Vitest, or pytest. CI typechecks always and runs tests only when the installed CLI advertises claude plugin test. Plugins, Bun issue scripts, Python hooks, and workflows have no unit tests in this repo. Diff has broad pure-function coverage; telemetry and sec-default cover their registers; agents-md has a single register suite.
- The test framework is claude-code/testing: imports are describe, expect, mock, test, and tier from 'claude-code/testing'. A file calls tier('builtin') or tier('prepend'), then describe. Tests receive the engine's $ and an on registrar. mock.env, mock.clock (advance/settle), and mock.store answer nouns from memory. An unanswered call throws, naming the event.
- Test files live only under mods/*/tests. Counts: agents-md 1, telemetry 2 (register.test.ts, gate.test.ts), sec-default 2 (register.test.ts, policy/create-policy-memo.test.ts), diff 27 including register, git, views, pane-state, pane-toggle, classify, ask, backend, todos, and turns. Shared helpers are one-export files under tests/fixtures/. No test_*.py or *_test.py files exist.
- Telemetry register tests assert a real batch: two $.telemetry.log rows stay unsent until clock.advance(BATCH_WINDOW_MS), then one POST to the ingest URL with auth the-handle and headers Content-Type plus x-service-name claude-code, event_name tengu_plugin_again, and debug line 'telemetry: sent 2 row(s)'. A second test fills BATCH_ROWS and expects one post before the window, after clock.settle().
- sec-default register tests seat the mod at tier prepend and stub settings.read. Under an MCP allowlist, a user plugin named mine does not register a tool while prepend suite and builtin bundled do. With no allowlist, mine registers. A denying user plugin does not block an org registration. A settings.read deny ('managed settings unreadable') yields no registrations.
- Diff unit tests cover pure pieces beside the register: fetch-diff, parse-numstat, parse-file-diff, repository-of, kind-walk-of, datings-of, is-safe-ref-name, head-key-of, is-noise-file, pane-toggle-of, header-totals-of, turn-diffs-of, todo-progress-of, fitted-ask-text-of, backend-of, pane-view, detail-view, code-blocks-of, truncate-start. They do not start a real git process; the host is mocked.
- CI for mods is only .github/workflows/mod-tests.yml. The test step is allowed to no-op when the published CLI has no plugin test subcommand, so a green check does not prove behavioural tests ran. No other workflow runs tsc or plugin tests.
- plugins/security-guidance (security_reminder_hook.py is 2192 lines, llm.py is 1697) has no tests in-repo. hookify's RuleEngine and config_loader have no tests. scripts/sweep.ts, auto-close-duplicates.ts, lifecycle-comment.ts, and backfill-duplicate-comments.ts have no tests. Workflow shell in log-issue-events.yml is untested.
- Local commands documented for mods are tsc -p mods/tsconfig.json and claude plugin test mods/<dir> (example: claude plugin test mods/diff). Running a mod from source is claude --plugin-dir mods/diff, which for sec-default cannot perform next.to because that move is refused outside a managed tier.
- Plugin-dev documents hook and command testing as skills (plugins/plugin-dev/skills/hook-development/scripts/test-hook.sh and validate-hook-schema.sh, command-development references/testing-strategies.md) but those are authoring guides, not a CI job for this repo's plugins.
- examples/hooks/bash_command_validator_example.py is a sample PreToolUse Bash hook that rewrites guidance for grep and find, not a test and not wired into any plugin hooks.json in this repo.