From devflow-enforcer
Analyze test coverage in depth. Identifies uncovered lines, branches, and functions with detailed reporting.
npx claudepluginhub xarlord/devflow-enforcer --plugin devflow-enforcerThis skill uses the workspace's default tool permissions.
This skill performs deep coverage analysis:
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
This skill performs deep coverage analysis:
Ensure comprehensive test coverage. Use this skill:
1. DETECT test framework
2. RUN tests with coverage
3. PARSE coverage data
4. ANALYZE coverage patterns
5. IDENTIFY gaps
6. GENERATE detailed report
| Parameter | Type | Description | Required |
|---|---|---|---|
| threshold | number | Minimum coverage % | No |
| type | string | line, branch, function, all | No |
| diff | boolean | Compare with base branch | No |
| Language | Tool | Output |
|---|---|---|
| JavaScript | Jest, Vitest | lcov, json |
| Python | coverage.py | xml, html |
| Java | JaCoCo | xml, html |
| Go | go test -cover | text, html |
| .NET | coverlet | json, opencover |
// jest.config.js
module.exports = {
collectCoverage: true,
coverageDirectory: 'coverage',
coverageReporters: ['text', 'lcov', 'html', 'json-summary'],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
collectCoverageFrom: [
'src/**/*.{ts,tsx}',
'!src/**/*.spec.{ts,tsx}',
'!src/**/*.d.ts',
],
};
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html', 'lcov'],
exclude: ['**/*.spec.ts', '**/*.test.ts'],
thresholds: {
lines: 80,
functions: 80,
branches: 80,
statements: 80,
},
},
},
});
# .coveragerc
[run]
source = src
branch = True
omit = tests/*
[report]
exclude_lines =
pragma: no cover
if TYPE_CHECKING:
raise NotImplementedError
fail_under = 80
[html]
directory = htmlcov
# Coverage Analysis Report
**Date:** [timestamp]
**Framework:** Jest with v8 coverage
## Coverage Summary
| Type | Coverage | Target | Status |
|------|----------|--------|--------|
| **Lines** | **85%** | 80% | ✅ Pass |
| **Branches** | **78%** | 80% | ❌ Fail |
| **Functions** | **92%** | 80% | ✅ Pass |
| **Statements** | **86%** | 80% | ✅ Pass |
## Coverage by Directory
| Directory | Lines | Branches | Functions |
|-----------|-------|----------|-----------|
| src/services | 92% | 85% | 95% |
| src/components | 88% | 75% | 90% |
| src/utils | 72% | 65% | 80% |
| src/api | 95% | 90% | 100% |
## Files Below Threshold
### 1. src/utils/validators.ts
| Type | Coverage | Missing |
|------|----------|---------|
| Lines | 65% | 14 lines |
| Branches | 55% | 9 branches |
| Functions | 70% | 3 functions |
**Uncovered Lines:** 23-28, 45-52, 78-82
```typescript
// Line 23-28: Not covered
export function validateEmail(email: string): boolean {
if (!email) return false; // ❌ Not covered
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email); // ❌ Not covered
}
Suggested Tests:
describe('validateEmail', () => {
it('should return false for empty email', () => {
expect(validateEmail('')).toBe(false);
});
it('should return true for valid email', () => {
expect(validateEmail('test@example.com')).toBe(true);
});
});
| Type | Coverage | Missing |
|---|---|---|
| Lines | 70% | 8 lines |
| Branches | 60% | 4 branches |
Uncovered: Loading state, disabled variant
| File | Branch | Coverage |
|---|---|---|
| validators.ts | if (!email) | ❌ False path |
| validators.ts | if (!phone) | ❌ Both paths |
| Button.tsx | if (loading) | ❌ True path |
| Button.tsx | if (disabled) | ❌ True path |
| Date | Lines | Branches | Change |
|---|---|---|---|
| 2026-02-15 | 82% | 75% | - |
| 2026-02-16 | 84% | 77% | +2% |
| 2026-02-17 | 85% | 78% | +1% |
## Example Usage
### Example 1: Full Coverage Analysis
USER: /coverage-analysis
SKILL OUTPUT:
| Type | Coverage | Target |
|---|---|---|
| Lines | 85% | 80% ✅ |
| Branches | 78% | 80% ❌ |
| Functions | 92% | 80% ✅ |
| Statements | 86% | 80% ✅ |
Add 8 tests to reach 80% branch coverage:
### Example 2: Coverage Diff
USER: /coverage-analysis --diff main
SKILL OUTPUT:
Base: main Current: feature/new-auth
| Type | Base | Current | Change |
|---|---|---|---|
| Lines | 82% | 85% | +3% ✅ |
| Branches | 75% | 78% | +3% ✅ |
| Functions | 90% | 92% | +2% ✅ |
| File | New Lines | Covered | Coverage |
|---|---|---|---|
| auth.service.ts | 45 | 40 | 89% |
| login.component.ts | 32 | 28 | 88% |
⚠️ Coverage decreased in:
Missing tests for new error handling code.
### Example 3: Threshold Enforcement
USER: /coverage-analysis --threshold 90
SKILL OUTPUT:
Threshold: 90%
| Type | Coverage | Status |
|---|---|---|
| Lines | 85% | ❌ Fail |
| Branches | 78% | ❌ Fail |
| Functions | 92% | ✅ Pass |
| Statements | 86% | ❌ Fail |
❌ Build Failed: Coverage below threshold
Need 5% more line coverage (10 lines):
## Running Coverage
### Jest
```bash
jest --coverage
vitest run --coverage
pytest --cov=src --cov-report=html
go test -coverprofile=coverage.out
go tool cover -html=coverage.out
# .github/workflows/coverage.yml
name: Coverage
on: [push, pull_request]
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npm test -- --coverage
- uses: codecov/codecov-action@v3
with:
files: ./coverage/lcov.info
This skill integrates with:
mutation-testing: Combined quality metricstest-generation: Generate missing tests