Test Coverage Protocol — STRICT MODE
Goal
FORCE coverage of all changed code (functions, methods, lines) at ≥80% (file-wide) with a primary mandate for 100% coverage of the specific logic introduced or modified. Ensure both npm run test:coverage and npm run lint:full are green. Run from root directory only. No shortcuts. No exceptions.
Invariant
npm run test:coverage && npm run lint:full
Both must pass. If either fails, fix and re-run. Do not stop until both are green.
Workflow
Phase 1: Identify Changed Files & Logic
-
Get all changed files (staged + unstaged):
git diff --name-only git diff --name-only --stagedUnion both lists. Filter to testable files:
*.ts,*.tsxunderfrontend/app,frontend/locales,frontend/utils, etc. (exclude config, mocks,*.test.*,*.spec.*). -
Identify specific line changes:
- Use
git diff -U0to see exactly which lines were modified.
- Use
-
Record the list of changed files and the logic blocks (functions/branches) affected. These are the primary coverage targets.
Phase 2: Baseline Coverage Measurement
-
Run initial coverage from root:
npm run test:coverageIf it fails (tests red), fix valid test failures first.
-
Record BASELINE coverage for each changed file:
- Identify the coverage % (Lines/Statements).
- Crucially: Check if the CHANGED lines are uncovered (check "Uncovered Line #s" in Jest output).
- Example log:
utils/dateFormatter.ts: 50% (Baseline) - Lines 45-50 (NEW) are UNCOVERED.
Phase 3: Add Regression Tests for Changes
-
Prioritize covering the DIFF:
- Even if the file has 90% coverage, if your changes are in the 10% uncovered part, you MUST add tests.
- Focus on newly added branches, edge cases, and bug fixes.
-
Write tests that:
- Specifically target the modified lines and logic.
- Assert the fix for the bug or the correctness of the new feature.
- Use mock data that reflects the specific scenarios handled in the diff.
-
Re-run coverage:
npm run test:coverageVerify:
- Changed file is ≥80% overall.
- All modified/new lines are covered.
Phase 4: Lint Until Green
-
Run full lint from root:
npm run lint:fullThis runs:
lint→compile→lint:unused. -
Fix all lint/compile/unused errors:
- Do not leave any error unfixed.
- Re-run
npm run lint:fulluntil it passes.
Phase 5: Final Validation & Report
-
Run the full invariant from root:
npm run test:coverage && npm run lint:fullBoth must pass.
-
Generate Final Report:
- You MUST provide a comparison showing that the changes are specifically covered.
- Format:
| File | Baseline % | Final % | Changes Covered? | Status | |------|------------|---------|------------------|--------| | utils/api.ts | 45% | 85% | Yes (Lines 120-145) | ✅ | | components/Calc.tsx | 100% | 100% | Yes (Regression added) | ✅ |
Validation Checklist
- Changed files AND changed line ranges identified.
-
npm run test:coveragepasses. - Every single modified line is exercised by a test.
- File-wide coverage ≥80%.
-
npm run lint:fullpasses. - Final run:
npm run test:coverage && npm run lint:full— both green.
Output Expectations
- Provide the exact command used:
npm run test:coverage && npm run lint:full. - Explicitly state which changed line ranges or newly added functions are now covered.
- Provide before/after coverage comparison.
- Confirm both test:coverage and lint:full are green.
Exclusions
- Files explicitly excluded in
jest.config.ts. - If no changed files are testable (e.g. only config changes), run the invariant anyway and report.
