docs: add implementation plans for coverage work

This commit is contained in:
2025-10-20 11:12:16 -04:00
parent a7745b46e1
commit e3ab2f18f5
2 changed files with 470 additions and 0 deletions

View File

@@ -0,0 +1,263 @@
# Implementation Plan: 100% Tool Coverage
**Date:** 2025-01-20
**Goal:** Achieve 100% test coverage on note-tools.ts and vault-tools.ts
**Approach:** Add targeted test cases to existing test files
## Overview
This plan addresses the remaining coverage gaps in the tool modules to achieve 100% statement coverage as part of pre-release validation.
## Current Coverage Status
- **note-tools.ts:** 96.01% → Target: 100% (9 uncovered lines)
- **vault-tools.ts:** 94.22% → Target: 100% (14 uncovered lines)
## Gap Analysis
### Note-Tools Uncovered Lines (9 lines)
1. **Lines 238-239:** Conflict resolution loop (when creating files with duplicate names)
2. **Lines 377, 408, 590, 710, 836:** Folder-not-file errors (5 occurrences across different methods)
3. **Line 647:** Include compressed data flag in Excalidraw read
4. **Line 771:** Add frontmatter to file that has no existing frontmatter
### Vault-Tools Uncovered Lines (14 lines)
1. **Line 76:** Invalid path validation error
2. **Line 200:** Folder assignment (possibly unreachable)
3. **Line 267:** Skip root folder in iteration
4. **Line 272:** Glob filtering skip
5. **Line 325:** Alias as string (non-array) normalization
6. **Line 374:** Folder mtime extraction error catch
7. **Lines 452-456, 524-528:** Defensive "path doesn't exist" returns
8. **Lines 596-597:** Glob filtering in search
9. **Lines 608, 620:** MaxResults early termination
10. **Line 650:** Snippet end-of-line adjustment
11. **Line 777:** Search error catch block
## Implementation Tasks
### Task 1: Add Note-Tools Conflict Resolution Tests
**Objective:** Cover lines 238-239 (conflict resolution loop)
**Steps:**
1. Add test: "creates file with incremented counter when conflicts exist"
2. Mock PathUtils.fileExists to return true for "file.md" and "file 2.md"
3. Verify creates "file 3.md"
4. Run coverage to confirm lines 238-239 covered
**Files to modify:**
- `tests/note-tools.test.ts`
**Expected outcome:** Lines 238-239 covered
---
### Task 2: Add Note-Tools Folder-Not-File Error Tests
**Objective:** Cover lines 377, 408, 590, 710, 836 (folder instead of file errors)
**Steps:**
1. Add test for read_note: "returns error when path is a folder"
- Mock PathUtils.folderExists to return true
- Verify error message uses ErrorMessages.notAFile()
2. Add test for rename_file: "returns error when path is a folder"
3. Add test for update_note: "returns error when path is a folder"
4. Add test for delete_note: "returns error when path is a folder"
5. Add test for update_sections: "returns error when path is a folder"
6. Run coverage to confirm all 5 lines covered
**Files to modify:**
- `tests/note-tools.test.ts`
**Expected outcome:** Lines 377, 408, 590, 710, 836 covered
---
### Task 3: Add Note-Tools Excalidraw and Frontmatter Tests
**Objective:** Cover lines 647, 771
**Steps:**
1. Add test for read_excalidraw: "includes compressed data when flag is true"
- Call with includeCompressed=true
- Verify result.compressedData is included
2. Add test for update_frontmatter: "adds frontmatter to file without existing frontmatter"
- Mock file content without frontmatter
- Update frontmatter
- Verify frontmatter added at beginning with newline separator
3. Run coverage to confirm lines 647, 771 covered
**Files to modify:**
- `tests/note-tools.test.ts`
**Expected outcome:** Lines 647, 771 covered, note-tools.ts at 100%
---
### Task 4: Add Vault-Tools Invalid Path and Glob Tests
**Objective:** Cover lines 76, 272, 596-597
**Steps:**
1. Add test for list(): "returns error for invalid vault path"
- Mock PathUtils.isValidVaultPath to return false
- Verify error message
2. Add test for list(): "filters items using glob excludes"
- Mock GlobUtils.shouldInclude to return false for some items
- Verify filtered items not in results
3. Add test for search(): "applies glob filtering to search results"
- Provide includes/excludes patterns
- Verify filtered files not searched
4. Run coverage to confirm lines 76, 272, 596-597 covered
**Files to modify:**
- `tests/vault-tools.test.ts`
**Expected outcome:** Lines 76, 272, 596-597 covered
---
### Task 5: Add Vault-Tools Edge Case Tests
**Objective:** Cover lines 267, 325, 374, 608, 620, 650
**Steps:**
1. Add test for list(): "skips root folder in iteration"
- Mock folder structure with root folder (path='', isRoot()=true)
- Verify root not in results
2. Add test for list(): "normalizes aliases from string to array"
- Mock cache.frontmatter.aliases as string instead of array
- Verify result has aliases as array
3. Add test for getFolderMetadata(): "handles folder without mtime stat"
- Mock folder without stat or with invalid stat
- Verify doesn't crash, uses default mtime
4. Add test for search(): "stops searching when maxResults=1 reached"
- Multiple files with matches
- Verify only 1 result returned
5. Add test for search(): "adjusts snippet for long lines at end"
- Mock line longer than snippetLength ending with match
- Verify snippet adjustment logic (line 650)
6. Run coverage to confirm lines 267, 325, 374, 608, 620, 650 covered
**Files to modify:**
- `tests/vault-tools.test.ts`
**Expected outcome:** Lines 267, 325, 374, 608, 620, 650 covered
---
### Task 6: Add Vault-Tools Defensive Code Coverage
**Objective:** Cover lines 200, 452-456, 524-528, 777
**Steps:**
1. Analyze if lines 200, 452-456, 524-528 are truly unreachable
- If unreachable: Document why (defensive code)
- If reachable: Add tests to trigger them
2. Add test for search(): "handles file read errors gracefully"
- Mock vault.read to throw error
- Verify error caught, logged to console, search continues
- Covers line 777
3. For defensive returns (452-456, 524-528):
- Attempt to trigger "path doesn't exist" cases
- If impossible: Document as unreachable defensive code
4. Run coverage to verify maximum possible coverage
**Files to modify:**
- `tests/vault-tools.test.ts`
- Possibly: add comments in source code marking defensive code
**Expected outcome:** Lines covered or documented as unreachable
---
### Task 7: Verify 100% Coverage
**Objective:** Confirm 100% coverage achieved
**Steps:**
1. Run `npm run test:coverage`
2. Check coverage report:
- note-tools.ts: 100% or documented gaps
- vault-tools.ts: 100% or documented gaps
3. If any gaps remain:
- Identify what's uncovered
- Add tests or document as unreachable
4. Final coverage verification
**Expected outcome:** Both tools at 100% coverage
---
### Task 8: Run Full Test Suite and Build
**Objective:** Verify no regressions
**Steps:**
1. Run `npm test` - all tests must pass
2. Run `npm run build` - must succeed
3. Verify total test count increased
4. Document final metrics
**Expected outcome:** All tests passing, build successful
---
### Task 9: Create Summary and Merge
**Objective:** Document and integrate work
**Steps:**
1. Update IMPLEMENTATION_SUMMARY.md with:
- Coverage improvements (before/after)
- Test counts
- Any unreachable code documented
2. Use finishing-a-development-branch skill
3. Merge to master
**Expected outcome:** Work merged, documentation updated
## Success Criteria
- [x] note-tools.ts at 100% statement coverage
- [x] vault-tools.ts at 100% statement coverage
- [x] All tests passing
- [x] Build succeeds
- [x] Any unreachable code documented
- [x] Work merged to master
## Risk Mitigation
**If some lines are truly unreachable:**
- Document with inline comments explaining why
- Accept 99.x% if justified
- Focus on getting all reachable code to 100%
**If tests become too complex:**
- Consider minor refactoring for testability
- Use subagent review to validate approach
- Ensure tests remain maintainable
## Estimated Effort
- Note-tools tests: ~1 hour (7 new test cases)
- Vault-tools tests: ~1.5 hours (10-12 new test cases)
- Verification and cleanup: ~0.5 hours
- **Total: ~3 hours**

View File

@@ -0,0 +1,207 @@
# Implementation Plan: 100% Utils Coverage
**Date:** 2025-01-20
**Goal:** Achieve 100% test coverage on all utils modules
**Approach:** Remove dead code + Add targeted test cases
## Overview
This plan addresses the remaining coverage gaps in the utils modules to achieve 100% statement coverage as part of pre-release validation. Unlike the tools coverage work, this combines dead code removal with targeted testing.
## Current Coverage Status
- **error-messages.ts:** 82.6% → Target: 100% (lines 182-198 uncovered)
- **version-utils.ts:** 88.88% → Target: 100% (line 52 uncovered)
- **path-utils.ts:** 98.18% → Target: 100% (line 70 uncovered)
- **frontmatter-utils.ts:** 96.55% → Target: 100% (lines 253-255, 310 uncovered)
## Gap Analysis
### Dead Code (To Remove)
1. **error-messages.ts (lines 182-198)**:
- `permissionDenied()` - Never called anywhere in codebase
- `formatError()` - Never called anywhere in codebase
2. **version-utils.ts (line 52)**:
- `createVersionedResponse()` - Never called (only documented in CHANGELOG)
### Untested Code (To Test)
1. **path-utils.ts (line 70)**:
- Windows absolute path validation: `/^[A-Za-z]:/` regex check
2. **frontmatter-utils.ts (lines 253-255)**:
- Excalidraw parsing fallback: code fence without language specifier
3. **frontmatter-utils.ts (line 310)**:
- Excalidraw decompression error handler
## Implementation Tasks
### Task 1: Remove Dead Code from error-messages.ts
**Objective:** Delete unused methods to improve coverage
**Steps:**
1. Delete `permissionDenied()` method (lines 178-189)
2. Delete `formatError()` method (lines 191-204)
3. Run tests to verify no broken imports
4. Run coverage to confirm improved percentage
**Files to modify:**
- `src/utils/error-messages.ts`
**Expected outcome:** error-messages.ts at 100% coverage
---
### Task 2: Remove Dead Code from version-utils.ts
**Objective:** Delete unused method to improve coverage
**Steps:**
1. Delete `createVersionedResponse()` method (lines 48-57)
2. Run tests to verify no broken imports
3. Run coverage to confirm improved percentage
**Files to modify:**
- `src/utils/version-utils.ts`
**Expected outcome:** version-utils.ts at 100% coverage
---
### Task 3: Clean Up CHANGELOG.md
**Objective:** Remove references to deleted code
**Steps:**
1. Remove `createVersionedResponse()` reference from line 282
2. Keep surrounding context intact
3. Verify file still well-formed
**Files to modify:**
- `CHANGELOG.md`
**Expected outcome:** CHANGELOG accurate to current codebase
---
### Task 4: Add path-utils Windows Absolute Path Tests
**Objective:** Cover line 70 (Windows path validation)
**Steps:**
1. Add test: "rejects Windows absolute paths (C: drive)"
- Test `isValidVaultPath('C:\\Users\\file.md')` returns false
2. Add test: "rejects Windows absolute paths (D: drive)"
- Test `isValidVaultPath('D:\\Documents\\note.md')` returns false
3. Run coverage to confirm line 70 covered
**Files to modify:**
- `tests/path-utils.test.ts`
**Expected outcome:** path-utils.ts at 100% coverage
---
### Task 5: Add frontmatter-utils Code Fence Fallback Test
**Objective:** Cover lines 253-255 (code fence without language specifier)
**Steps:**
1. Create Excalidraw note with ` ``` ` fence (no language)
2. Add test: "parses Excalidraw with code fence lacking language specifier"
3. Call `parseExcalidrawMetadata()` on content
4. Verify JSON parsed correctly
5. Run coverage to confirm lines 253-255 covered
**Files to modify:**
- `tests/frontmatter-utils.test.ts`
**Expected outcome:** Lines 253-255 covered
---
### Task 6: Add frontmatter-utils Decompression Failure Test
**Objective:** Cover line 310 (decompression error handler)
**Steps:**
1. Create Excalidraw note with invalid compressed data
2. Add test: "handles decompression failure gracefully"
3. Mock or create scenario where decompression throws error
4. Verify graceful fallback with `hasCompressedData: true`
5. Run coverage to confirm line 310 covered
**Files to modify:**
- `tests/frontmatter-utils.test.ts`
**Expected outcome:** frontmatter-utils.ts at 100% coverage
---
### Task 7: Verify 100% Coverage
**Objective:** Confirm 100% coverage achieved on all utils
**Steps:**
1. Run `npm run test:coverage`
2. Check coverage report:
- error-messages.ts: 100%
- version-utils.ts: 100%
- path-utils.ts: 100%
- frontmatter-utils.ts: 100%
3. If any gaps remain:
- Identify what's uncovered
- Add tests or document as unreachable
4. Final coverage verification
**Expected outcome:** All 4 utils at 100% coverage
---
### Task 8: Create Summary and Merge
**Objective:** Document and integrate work
**Steps:**
1. Create `UTILS_COVERAGE_SUMMARY.md` with:
- Coverage improvements (before/after)
- Test counts
- Dead code removed
2. Use finishing-a-development-branch skill
3. Merge to master
**Expected outcome:** Work merged, documentation updated
## Success Criteria
- [ ] error-messages.ts at 100% statement coverage
- [ ] version-utils.ts at 100% statement coverage
- [ ] path-utils.ts at 100% statement coverage
- [ ] frontmatter-utils.ts at 100% statement coverage
- [ ] All tests passing (505+)
- [ ] Build succeeds
- [ ] Dead code removed cleanly
- [ ] Work merged to master
## Risk Mitigation
**If dead code is actually used:**
- Full test suite will catch broken imports immediately
- TypeScript compilation will fail if methods are referenced
- Git revert available if needed
**If edge case tests are too complex:**
- Document specific difficulty encountered
- Consider if code is truly reachable
- Mark with istanbul ignore if unreachable
## Estimated Effort
- Dead code removal: ~15 minutes (3 simple deletions)
- Test additions: ~20 minutes (3 test cases)
- Verification and cleanup: ~10 minutes
- **Total: ~45 minutes**