7.8 KiB
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)
- Lines 238-239: Conflict resolution loop (when creating files with duplicate names)
- Lines 377, 408, 590, 710, 836: Folder-not-file errors (5 occurrences across different methods)
- Line 647: Include compressed data flag in Excalidraw read
- Line 771: Add frontmatter to file that has no existing frontmatter
Vault-Tools Uncovered Lines (14 lines)
- Line 76: Invalid path validation error
- Line 200: Folder assignment (possibly unreachable)
- Line 267: Skip root folder in iteration
- Line 272: Glob filtering skip
- Line 325: Alias as string (non-array) normalization
- Line 374: Folder mtime extraction error catch
- Lines 452-456, 524-528: Defensive "path doesn't exist" returns
- Lines 596-597: Glob filtering in search
- Lines 608, 620: MaxResults early termination
- Line 650: Snippet end-of-line adjustment
- 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:
- Add test: "creates file with incremented counter when conflicts exist"
- Mock PathUtils.fileExists to return true for "file.md" and "file 2.md"
- Verify creates "file 3.md"
- 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:
-
Add test for read_note: "returns error when path is a folder"
- Mock PathUtils.folderExists to return true
- Verify error message uses ErrorMessages.notAFile()
-
Add test for rename_file: "returns error when path is a folder"
-
Add test for update_note: "returns error when path is a folder"
-
Add test for delete_note: "returns error when path is a folder"
-
Add test for update_sections: "returns error when path is a folder"
-
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:
-
Add test for read_excalidraw: "includes compressed data when flag is true"
- Call with includeCompressed=true
- Verify result.compressedData is included
-
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
-
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:
-
Add test for list(): "returns error for invalid vault path"
- Mock PathUtils.isValidVaultPath to return false
- Verify error message
-
Add test for list(): "filters items using glob excludes"
- Mock GlobUtils.shouldInclude to return false for some items
- Verify filtered items not in results
-
Add test for search(): "applies glob filtering to search results"
- Provide includes/excludes patterns
- Verify filtered files not searched
-
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:
-
Add test for list(): "skips root folder in iteration"
- Mock folder structure with root folder (path='', isRoot()=true)
- Verify root not in results
-
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
-
Add test for getFolderMetadata(): "handles folder without mtime stat"
- Mock folder without stat or with invalid stat
- Verify doesn't crash, uses default mtime
-
Add test for search(): "stops searching when maxResults=1 reached"
- Multiple files with matches
- Verify only 1 result returned
-
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)
-
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:
-
Analyze if lines 200, 452-456, 524-528 are truly unreachable
- If unreachable: Document why (defensive code)
- If reachable: Add tests to trigger them
-
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
-
For defensive returns (452-456, 524-528):
- Attempt to trigger "path doesn't exist" cases
- If impossible: Document as unreachable defensive code
-
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:
- Run
npm run test:coverage - Check coverage report:
- note-tools.ts: 100% or documented gaps
- vault-tools.ts: 100% or documented gaps
- If any gaps remain:
- Identify what's uncovered
- Add tests or document as unreachable
- Final coverage verification
Expected outcome: Both tools at 100% coverage
Task 8: Run Full Test Suite and Build
Objective: Verify no regressions
Steps:
- Run
npm test- all tests must pass - Run
npm run build- must succeed - Verify total test count increased
- Document final metrics
Expected outcome: All tests passing, build successful
Task 9: Create Summary and Merge
Objective: Document and integrate work
Steps:
- Update IMPLEMENTATION_SUMMARY.md with:
- Coverage improvements (before/after)
- Test counts
- Any unreachable code documented
- Use finishing-a-development-branch skill
- Merge to master
Expected outcome: Work merged, documentation updated
Success Criteria
- note-tools.ts at 100% statement coverage
- vault-tools.ts at 100% statement coverage
- All tests passing
- Build succeeds
- Any unreachable code documented
- 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