test(coverage): drive mcp to >=95% line + branch coverage#24
Merged
Conversation
mastermanas805
pushed a commit
that referenced
this pull request
May 22, 2026
The test script uses --test-coverage-exclude (added in Node 22.5.0). On the existing Node 20 runners it errored `bad option: --test-coverage-exclude`, hard-failing the build + coverage jobs. Bump both workflows to Node 22 and drop the `|| true` mask on the coverage job now that the run is real (CLAUDE.md rule 12: no test-masking). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds 1 test file with 25 unit tests covering src/client.ts edge branches:
- fetch network-error path (ApiError(0))
- non-JSON 2xx + non-2xx response body coercion
- empty-2xx safe sentinel (redeploy + multipart)
- requireAuth gating without INSTANODE_TOKEN
- createDeploy client-side validation (oversized tarball, allowed_ips
without private=true, private without allowed_ips)
- ApiError envelope field bubbling (agent_action, upgrade_url, claim_url)
- dashboardURL / apiBaseURL env-var-fresh reads
- createVector dimensions hint passthrough
- getApiToken default + supplied name handling
Coverage (measured on the test-compiled copy at dist-test/src/client.js,
since the test compile tree is what the unit tests import — node's coverage
reporter does not cross-link the two compile outputs):
client.js: 93.71% lines / 76.77% branches / 68.97% funcs
The production-built dist/client.js (exercised separately by the
integration suite) remains at 90.47% lines / 62.96% branches — these
unit tests increase the *logical* coverage to ~94% but the dist/ count
will need test/integration.test.ts to import the unit-level paths to
reflect in the canonical report.
Test count: 62 → 87 (all passing).
Remaining gap: src/index.ts is at 92.29% lines — uncovered lines are
mostly tool-handler error-formatting branches that fire only on rare
API error envelopes (PAT-creating-PAT 403, anonymous-recycle 429, etc.)
and are caught structurally by the existing mock-api integration tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds tests for every src/* surface: the InstantClient HTTP client (error
envelope branches, requestMultipart edges, empty-2xx sentinel), the
index.ts tool handlers (every create_*/lifecycle handler's success +
catch + optional-field branch), and the pure-helper exports
(formatError's every cascade arm, formatLimits typed-limit branches,
appendUpgradeBlock's 4 truth combinations).
To unit-test the tool handlers and helpers directly, src/index.ts now:
- exports `formatError`, `formatLimits`, `appendUpgradeBlock`, `textResult`
(was module-private; integration tests still exercise them via the
spawned subprocess, unchanged)
- exports the `server` instance so unit tests can pluck registered tool
callbacks out of its `_registeredTools` map and call them in-process
- guards the top-level `await server.connect(transport)` behind
INSTANODE_MCP_NO_LISTEN — the production binary path and the
integration tests' `node dist/index.js` invocation never set this var,
so prod behavior is unchanged
- wraps the package.json version read in a try/catch with a "dev"
fallback (mirrors client.ts's User-Agent resolver) so unit tests
importing from a non-canonical build path don't crash before any
test code runs
Coverage on src/ (via dist-test/src/, where `npm test` measures
--experimental-test-coverage):
Before: client 93.71% / 76.77%, index 92.29% / 30.77%
After: client 100.00% / 95.04%, index 99.70% / 95.00%
(index uncovered lines 995-997 = the production
`await server.connect()` path, unreachable in unit tests)
All files: 99.81% lines / 95.03% branches
Test count: 87 -> 248 passing (161 new unit-level tests across three
new/extended files):
- test/client-unit.test.ts (extended; was 25 tests, now 73)
- test/index-unit.test.ts (new; 35 tests for the pure helpers)
- test/tools-unit.test.ts (new; 79 tests for every tool handler,
including error-injection paths via stubbed globalThis.fetch)
Integration suite (87 tests) unchanged and still passing — the
new unit-level coverage is additive.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The test script uses --test-coverage-exclude (added in Node 22.5.0). On the existing Node 20 runners it errored `bad option: --test-coverage-exclude`, hard-failing the build + coverage jobs. Bump both workflows to Node 22 and drop the `|| true` mask on the coverage job now that the run is real (CLAUDE.md rule 12: no test-masking). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
801b9cb to
63f2718
Compare
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Drives
src/to >=95% line + branch coverage via 161 new unit-level tests across three new/extended files.Coverage (via
dist-test/src/, measured bynode --test --experimental-test-coverage)src/client.tssrc/index.tssrc/name_schema.tsThe 3 uncovered lines on
src/index.ts(995-997) are the productionawait server.connect(transport)path — unreachable from unit tests by design (guarded byINSTANODE_MCP_NO_LISTEN).What the tests cover
request<T>andrequestMultipartINSTANODE_TOKENString(err)branch; mock returns noname→ arg fallback;result.dimensionsprecedence chain; multipart non-OK with empty body vs{}body vs JSON error envelope vs HTML bodySource refactor (minimal, all backward-compatible)
src/index.ts:formatError,formatLimits,appendUpgradeBlock,textResult(were module-private; integration tests still exercise them via the spawned subprocess, unchanged)serverinstance so unit tests can drive registered tool callbacks in-process via_registeredToolsawait server.connect(transport)behindINSTANODE_MCP_NO_LISTEN— production binary + integration tests never set this var, so prod behavior is unchangedpackage.jsonversion read in a try/catch with a"dev"fallback (mirrorsclient.ts's User-Agent resolver) so unit tests importing from a non-canonical build path don't crash before any test code runsTest counts
Files
test/client-unit.test.ts— extended from 25 to 73 teststest/index-unit.test.ts— new, 35 tests (pure helper coverage)test/tools-unit.test.ts— new, 79 tests (every tool handler)src/index.ts— refactor for testability (export helpers + server, guard connect)package.json—testscript now includes--experimental-test-coverage+ the two new filesTest plan
npm testpasses with all 248 tests greensrc/>=95% on both lines + branchesnode dist/index.js) behavior unchanged (only the unit-test path setsINSTANODE_MCP_NO_LISTEN)🤖 Generated with Claude Code
CI fix (2026-05-22)
The
build+coveragejobs were failing because thetestscript uses--test-coverage-exclude(Node 22.5.0+) while both workflows pinnednode-version: 20(erroredbad option: --test-coverage-exclude). Bumped both to Node 22 and dropped the|| truemask on the coverage job per CLAUDE.md rule 12 (no test-masking).