# Stub Implementation Detection Guide ## Overview Stub detection automatically identifies incomplete, placeholder, or mock implementations in the codebase. This prevents accidental deployment of unfinished code and helps teams track what still needs to be completed. ## What is a Stub? A stub is a function or component that: - Throws "not implemented" errors - Returns placeholder values (null, empty objects, mock data) - Contains TODO/FIXME comments indicating incomplete work - Only logs to console without doing real work - Has minimal/empty implementation - Contains placeholder text in UI ## Detection Methods ### 1. Pattern-Based Detection Scans code for specific patterns that indicate stubs: #### Error Throwing ```typescript // ❌ Detected as stub export function processData(data) { throw new Error('not implemented') } ``` #### Console Logging Only ```typescript // ❌ Detected as stub export function validateEmail(email) { console.log('validating:', email) // Nothing else } ``` #### Null/Undefined Returns ```typescript // ❌ Detected as stub export function fetchData() { return null } ``` #### Placeholder Text ```typescript // ❌ Detected as stub function Dashboard() { return
TODO: Build dashboard
} ``` #### Mock Data with Markers ```typescript // ❌ Detected as stub export function getUsers() { return [ // stub data { id: 1, name: 'John' } ] } ``` ### 2. Completeness Analysis Analyzes implementation quality: - **Logical Lines**: Actual code (excluding returns and comments) - **Return Lines**: How many return statements - **JSX Lines**: For components, how much actual UI - **Completeness Score**: 0-100% based on implementation density **Scoring**: - **0%**: Throws not implemented error - **0-30%**: Critical (only logging, returning null, no real logic) - **30-60%**: Medium (minimal implementation, mostly mock data) - **60-80%**: Low (mostly complete, some placeholders) - **80-100%**: Good (real implementation) ### 3. Code Indicators Detects special markers: | Indicator | Severity | Meaning | |-----------|----------|---------| | `throw new Error('not implemented')` | Critical | Explicitly unimplemented | | `// TODO:` or `// FIXME:` | Medium | Known issue, incomplete | | `console.log()` only | High | Debug logging, not real code | | `// mock`, `// stub` | Medium | Explicitly marked placeholder | | `return null` | Low | Empty return value | | `<> ` | High | Empty component fragment | ## Workflow Integration ### Automatic Detection The `detect-stubs.yml` workflow runs: - On every PR (to flag new stubs) - On every push to main/master - Weekly scheduled (Monday midnight) ### PR Comments Posts a summary comment showing: - Total stubs found - Severity breakdown - Critical issues with file/line/function - Recommendations for fixes Example: ``` ## 🔍 Stub Implementation Detection Report ### Summary - Pattern-Based Stubs: 5 - Low Completeness Items: 3 - Average Completeness: 72% ### Severity Breakdown - 🔴 Critical: 2 - 🟠 Medium: 2 - 🟡 Low: 1 ### 🔴 Critical Issues Found | File | Line | Function | Type | |------|------|----------|------| | src/api/users.ts | 42 | fetchUsers | throws-not-implemented | | src/components/Dashboard.tsx | 15 | Dashboard | empty-fragment | ``` ## Local Usage ### Run Detection Locally ```bash # Pattern-based stub detection npx tsx scripts/detect-stub-implementations.ts # Completeness analysis npx tsx scripts/analyze-implementation-completeness.ts # Generate detailed report npx tsx scripts/generate-stub-report.ts # All three npm run detect-stubs ``` ### Output Formats All scripts output JSON for programmatic access: #### Pattern Detection Output ```json { "totalStubsFound": 5, "bySeverity": { "high": 2, "medium": 2, "low": 1 }, "byType": { "not-implemented": 2, "todo-comment": 1, "console-log-only": 1, "returns-empty-value": 1 }, "criticalIssues": [ { "file": "src/api/users.ts", "line": 42, "function": "fetchUsers", "type": "not-implemented" } ] } ``` #### Completeness Analysis Output ```json { "totalAnalyzed": 45, "bySeverity": { "critical": 2, "high": 5, "medium": 8, "low": 12 }, "flagTypes": { "has-todo-comments": 5, "throws-not-implemented": 2, "only-console-log": 1 }, "averageCompleteness": 72.4, "criticalStubs": [ { "file": "src/api/users.ts", "line": 42, "name": "fetchUsers", "type": "function", "flags": ["throws-not-implemented"], "summary": "Potential stub: throws-not-implemented" } ] } ``` ## Common Stub Patterns & Fixes ### Pattern 1: Not Implemented Error **Problem**: Function explicitly throws unimplemented error **Severity**: 🔴 Critical **Fix**: Implement the function ```typescript // ❌ Before export async function fetchUserData(id: string) { throw new Error('not implemented') } // ✅ After export async function fetchUserData(id: string): Promise { const response = await fetch(`/api/users/${id}`) if (!response.ok) throw new Error(`Failed to fetch user ${id}`) return response.json() } ``` ### Pattern 2: Console Logging Only **Problem**: Function only logs without doing real work **Severity**: 🟠 High **Fix**: Replace logging with actual implementation ```typescript // ❌ Before export function calculateTotal(items: Item[]): number { console.log('calculating total for:', items) // nothing else } // ✅ After export function calculateTotal(items: Item[]): number { return items.reduce((sum, item) => sum + item.price, 0) } ``` ### Pattern 3: Return Null/Undefined **Problem**: Function returns null or undefined **Severity**: 🟡 Medium **Fix**: Return actual data or use types to force implementation ```typescript // ❌ Before export function getConfig() { return null // TODO: load config } // ✅ After export function getConfig(): Config { return configLoader.load() } ``` ### Pattern 4: Placeholder Component **Problem**: Component renders placeholder text instead of UI **Severity**: 🟠 High **Fix**: Implement the component properly ```typescript // ❌ Before export function Dashboard() { return
TODO: Build dashboard
} // ✅ After export function Dashboard() { return (
) } ``` ### Pattern 5: Mock Data **Problem**: Function returns hardcoded mock data **Severity**: 🟠 Medium **Fix**: Replace with real data source ```typescript // ❌ Before export function getUsers(): User[] { return [ // mock data { id: 1, name: 'John', email: 'john@example.com' }, { id: 2, name: 'Jane', email: 'jane@example.com' } ] } // ✅ After export async function getUsers(): Promise { const data = await Database.query('SELECT * FROM users') return data.map(row => new User(row)) } ``` ### Pattern 6: TODO Comments **Problem**: Code has TODO/FIXME comments indicating incomplete work **Severity**: 🟡 Medium/Low **Fix**: Create GitHub issue and remove TODO from code ```typescript // ❌ Before export function validateEmail(email: string): boolean { // TODO: Add real email validation return true } // ✅ After (create issue #123 first) export function validateEmail(email: string): boolean { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ return emailRegex.test(email) } ``` ### Pattern 7: Empty Component **Problem**: Component has minimal or empty JSX **Severity**: 🟠 High **Fix**: Implement the component's UI ```typescript // ❌ Before export function UserList() { return
} // ✅ After export function UserList() { const users = useQuery('users') return (
{users.map(user => ( ))}
) } ``` ## Best Practices ### 1. Never Leave Stubs in Main Branch ```bash # Before merging, ensure no stubs in changed files git diff HEAD~1 -- 'src/**/*.ts' | grep -i 'todo\|not implemented' ``` ### 2. Use Types to Force Implementation ```typescript // ❌ Function can return anything function getValue() { // oops, forgot to implement } // ✅ Type forces implementation function getValue(): string { // TypeScript error: missing return // MUST implement } ``` ### 3. Create Issues Instead of TODOs ```typescript // ❌ Don't do this function processData(data) { // TODO: add caching (#TBD) return compute(data) } // ✅ Do this // Implemented cache per issue #456 const cache = new LRUCache() function processData(data) { return cache.getOrCompute(data, () => compute(data)) } ``` ### 4. Test Stubs Explicitly ```typescript // Make stubs fail tests explicitly describe('getUsers', () => { it('should fetch users from API', async () => { // This WILL fail if implementation is missing const users = await getUsers() expect(users).toBeDefined() expect(users.length).toBeGreaterThan(0) expect(users[0].name).toBeDefined() }) }) ``` ### 5. Use Linting to Prevent Stubs Add ESLint rules to `.eslintrc.json`: ```json { "rules": { "no-console": ["error", { "allow": ["warn", "error"] }], "no-throw-literal": "error", "no-empty-function": ["error", { "allow": ["arrowFunctions"] }] } } ``` ## Interpreting the Report ### Severity Levels - **🔴 Critical** (Completeness: 0%) - Blocks production - Must fix immediately - Examples: `throw new Error('not implemented')` - **🟠 High** (Completeness: 10-30%) - Should fix before merge - Likely causes bugs - Examples: Console logging only, empty components - **🟡 Medium** (Completeness: 40-70%) - Should fix soon - Partial implementation - Examples: Mock data, basic structure - **🟢 Low** (Completeness: 80-99%) - Nice to fix - Mostly complete - Examples: Minor TODOs, edge cases ### Metrics Explained | Metric | Meaning | |--------|---------| | Logical Lines | Lines that do actual work (not returns/comments) | | Return Lines | Number of return statements | | JSX Lines | For components, lines rendering UI | | Completeness | Estimated % of implementation done | | Flags | Detected stub indicators | ## Artifacts The workflow uploads three artifacts: 1. **stub-patterns.json** - Raw pattern detection data 2. **implementation-analysis.json** - Completeness scoring 3. **stub-report.md** - Formatted markdown report 4. **changed-stubs.txt** - Stubs in changed files (PRs only) Available for 30 days after workflow run. ## CI/CD Integration ### Failing Builds The workflow runs with `continue-on-error: true`, so stubs don't block merging. However, you can: 1. Enable stricter linting to fail on TODOs 2. Require test coverage (which fails with stubs) 3. Use branch protection rules to require review of detected stubs ### GitHub Checks - Posts check run with stub detection results - Shows in PR checks section - Includes summary of critical issues ## Troubleshooting ### "No stubs found" but code looks incomplete - Patterns may not match your specific style - Check individual function with completeness analyzer - Consider adding custom patterns to detection script ### Too many false positives - Edit `STUB_PATTERNS` in `detect-stub-implementations.ts` - Adjust completeness thresholds in `analyze-implementation-completeness.ts` - Add file/function exclusions ### Stubs not showing in PR comment - Check workflow permissions (needs `pull-requests: write`) - Verify GitHub API isn't rate limited - Check workflow logs for errors ## Extension Points ### Add Custom Patterns Edit `scripts/detect-stub-implementations.ts`: ```typescript const STUB_PATTERNS = [ // ... existing patterns { name: 'Your custom pattern', pattern: /your regex here/, type: 'custom-stub', severity: 'high', description: 'Your description' } ] ``` ### Add Custom Analysis Create new script in `scripts/`: ```bash npx tsx scripts/my-custom-analysis.ts > my-report.json ``` Then add to workflow in `.github/workflows/detect-stubs.yml`. ## References - [Workflow Definition](.github/workflows/detect-stubs.yml) - [Detection Script](scripts/detect-stub-implementations.ts) - [Completeness Analyzer](scripts/analyze-implementation-completeness.ts) - [Report Generator](scripts/generate-stub-report.ts) --- **Last updated**: December 25, 2025