264 lines
7.8 KiB
Markdown
264 lines
7.8 KiB
Markdown
# 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**
|