Phase 09: CI Pipeline Hardening - 4 plan(s) in 3 wave(s) - Wave 1: Infrastructure setup (09-01) - Wave 2: Tests in parallel (09-02, 09-03) - Wave 3: CI integration (09-04) - Ready for execution Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7.6 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 09-ci-pipeline | 02 | execute | 2 |
|
|
true |
|
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.
<execution_context> @/home/tho/.claude/get-shit-done/workflows/execute-plan.md @/home/tho/.claude/get-shit-done/templates/summary.md </execution_context>
@.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.
Pattern for all component tests:
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.
- Set initial thresholds using autoUpdate to establish baseline:
thresholds: {
autoUpdate: true, // Will update thresholds based on current coverage
}
-
Run
npm run test:coverageonce to establish baseline thresholds -
Review the auto-updated thresholds in vite.config.ts
-
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%:
thresholds: {
global: {
statements: [current - 10],
branches: [current - 10],
functions: [current - 10],
lines: [current - 10],
},
}
- 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.
<success_criteria>
- 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 </success_criteria>