---
phase: 09-ci-pipeline
plan: 02
type: execute
wave: 2
depends_on: ["09-01"]
files_modified:
- src/lib/utils/highlightText.test.ts
- src/lib/utils/parseHashtags.test.ts
- src/lib/components/SearchBar.svelte.test.ts
- src/lib/components/TagInput.svelte.test.ts
- src/lib/components/CompletedToggle.svelte.test.ts
- vite.config.ts
autonomous: true
must_haves:
truths:
- "All utility functions have passing tests"
- "Component tests run in real browser via Vitest browser mode"
- "Coverage threshold is enforced (starts with autoUpdate baseline)"
artifacts:
- path: "src/lib/utils/highlightText.test.ts"
provides: "Tests for text highlighting utility"
min_lines: 20
- path: "src/lib/utils/parseHashtags.test.ts"
provides: "Tests for hashtag parsing utility"
min_lines: 20
- path: "src/lib/components/SearchBar.svelte.test.ts"
provides: "Browser-mode test for SearchBar component"
min_lines: 25
- path: "src/lib/components/TagInput.svelte.test.ts"
provides: "Browser-mode test for TagInput component"
min_lines: 25
- path: "src/lib/components/CompletedToggle.svelte.test.ts"
provides: "Browser-mode test for toggle component"
min_lines: 20
key_links:
- from: "src/lib/components/SearchBar.svelte.test.ts"
to: "vitest-browser-svelte"
via: "render import"
pattern: "import.*render.*from.*vitest-browser-svelte"
---
Write unit tests for utility functions and initial component tests to establish testing patterns.
Purpose: Create comprehensive tests for pure utility functions (easy wins for coverage) and establish the component testing pattern using Vitest browser mode. This proves both test project configurations work.
Output: All utility functions tested, 3 component tests demonstrating the browser-mode pattern, coverage baseline established.
@/home/tho/.claude/get-shit-done/workflows/execute-plan.md
@/home/tho/.claude/get-shit-done/templates/summary.md
@.planning/PROJECT.md
@.planning/phases/09-ci-pipeline/09-RESEARCH.md
@.planning/phases/09-ci-pipeline/09-01-SUMMARY.md
@src/lib/utils/highlightText.ts
@src/lib/utils/parseHashtags.ts
@src/lib/components/SearchBar.svelte
@src/lib/components/TagInput.svelte
@src/lib/components/CompletedToggle.svelte
@vitest-setup-client.ts
Task 1: Write unit tests for remaining utility functions
src/lib/utils/highlightText.test.ts, src/lib/utils/parseHashtags.test.ts
Read each utility file to understand its behavior, then write comprehensive tests:
**highlightText.test.ts:**
- Import function and test utilities from vitest
- Test: Returns original text when no search term
- Test: Highlights single match with mark tag
- Test: Highlights multiple matches
- Test: Case-insensitive matching
- Test: Handles special regex characters in search term
- Test: Returns empty string for empty input
**parseHashtags.test.ts:**
- Import function and test utilities from vitest
- Test: Extracts single hashtag from text
- Test: Extracts multiple hashtags
- Test: Returns empty array when no hashtags
- Test: Handles hashtags at start/middle/end of text
- Test: Ignores invalid hashtag patterns (e.g., # alone, #123)
- Test: Removes duplicates if function does that
Each test file should have describe block with descriptive test names.
Use `it.each` for data-driven tests where appropriate.
Run `npm run test:unit -- --reporter=verbose` - all utility tests pass
Run `npm run test:coverage` - shows improved coverage for src/lib/utils/
All 3 utility functions (filterEntries, highlightText, parseHashtags) have comprehensive test coverage.
Task 2: Write browser-mode component tests for 3 simpler components
src/lib/components/SearchBar.svelte.test.ts, src/lib/components/TagInput.svelte.test.ts, src/lib/components/CompletedToggle.svelte.test.ts
Create .svelte.test.ts files (note: .svelte.test.ts NOT .test.ts for browser mode) for three simpler components.
**Pattern for all component tests:**
```typescript
import { render } from 'vitest-browser-svelte';
import { page } from '@vitest/browser/context';
import { describe, expect, it } from 'vitest';
import ComponentName from './ComponentName.svelte';
```
**SearchBar.svelte.test.ts:**
- Read SearchBar.svelte to understand props and behavior
- Test: Renders input element
- Test: Calls onSearch callback when user types (if applicable)
- Test: Shows clear button when text entered (if applicable)
- Test: Placeholder text is visible
**TagInput.svelte.test.ts:**
- Read TagInput.svelte to understand props and behavior
- Test: Renders tag input element
- Test: Can add a tag (simulate user typing and pressing enter/adding)
- Test: Displays existing tags if passed as prop
**CompletedToggle.svelte.test.ts:**
- Read CompletedToggle.svelte to understand props
- Test: Renders toggle in unchecked state by default
- Test: Toggle state changes on click
- Test: Calls callback when toggled (if applicable)
Use `page.getByRole()`, `page.getByText()`, `page.getByPlaceholder()` for element selection.
Use `await button.click()` for interactions.
Use `flushSync()` from 'svelte' after external state changes if needed.
Use `await expect.element(locator).toBeInTheDocument()` for assertions.
Run `npm run test:unit` - component tests run in browser mode (you'll see Chromium launch)
All 3 component tests pass
Browser-mode component testing pattern established with 3 working tests.
Task 3: Configure coverage thresholds with baseline
vite.config.ts
Update vite.config.ts coverage configuration:
1. Set initial thresholds using autoUpdate to establish baseline:
```typescript
thresholds: {
autoUpdate: true, // Will update thresholds based on current coverage
}
```
2. Run `npm run test:coverage` once to establish baseline thresholds
3. Review the auto-updated thresholds in vite.config.ts
4. If coverage is already above 30%, manually set thresholds to a reasonable starting point (e.g., 50% of current coverage) with a path toward 80%:
```typescript
thresholds: {
global: {
statements: [current - 10],
branches: [current - 10],
functions: [current - 10],
lines: [current - 10],
},
}
```
5. Add comment noting the target is 80% coverage (CI-01 decision)
Note: Full 80% coverage will be achieved incrementally. This plan establishes the enforcement mechanism.
Run `npm run test:coverage` - shows coverage percentages
Coverage thresholds are set in vite.config.ts
Future test runs will fail if coverage drops below threshold
Coverage thresholds configured. Enforcement mechanism in place for incremental coverage improvement.
1. `npm run test:unit` runs all tests (utility + component)
2. Component tests run in Chromium browser (browser mode working)
3. `npm run test:coverage` shows coverage for utilities and tested components
4. Coverage thresholds are configured in vite.config.ts
5. All tests pass
- All 3 utility functions have comprehensive tests
- 3 component tests demonstrate browser-mode testing pattern
- Coverage thresholds configured (starting point toward 80% goal)
- Both Vitest projects (client browser, server node) verified working