docs(09): create phase plan
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>
This commit is contained in:
211
.planning/phases/09-ci-pipeline/09-02-PLAN.md
Normal file
211
.planning/phases/09-ci-pipeline/09-02-PLAN.md
Normal file
@@ -0,0 +1,211 @@
|
||||
---
|
||||
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"
|
||||
---
|
||||
|
||||
<objective>
|
||||
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.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/home/tho/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@/home/tho/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<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
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Write unit tests for remaining utility functions</name>
|
||||
<files>src/lib/utils/highlightText.test.ts, src/lib/utils/parseHashtags.test.ts</files>
|
||||
<action>
|
||||
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.
|
||||
</action>
|
||||
<verify>
|
||||
Run `npm run test:unit -- --reporter=verbose` - all utility tests pass
|
||||
Run `npm run test:coverage` - shows improved coverage for src/lib/utils/
|
||||
</verify>
|
||||
<done>All 3 utility functions (filterEntries, highlightText, parseHashtags) have comprehensive test coverage.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Write browser-mode component tests for 3 simpler components</name>
|
||||
<files>src/lib/components/SearchBar.svelte.test.ts, src/lib/components/TagInput.svelte.test.ts, src/lib/components/CompletedToggle.svelte.test.ts</files>
|
||||
<action>
|
||||
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.
|
||||
</action>
|
||||
<verify>
|
||||
Run `npm run test:unit` - component tests run in browser mode (you'll see Chromium launch)
|
||||
All 3 component tests pass
|
||||
</verify>
|
||||
<done>Browser-mode component testing pattern established with 3 working tests.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Configure coverage thresholds with baseline</name>
|
||||
<files>vite.config.ts</files>
|
||||
<action>
|
||||
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.
|
||||
</action>
|
||||
<verify>
|
||||
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
|
||||
</verify>
|
||||
<done>Coverage thresholds configured. Enforcement mechanism in place for incremental coverage improvement.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
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
|
||||
</verification>
|
||||
|
||||
<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>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/09-ci-pipeline/09-02-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user