|
1 | | -# Spec: Close user-journey test coverage gaps before 1.1.0 (#190) |
| 1 | +# Spec: Integration tests for all user stories — 1.1.0 (#190) |
2 | 2 |
|
3 | 3 | ## Goal |
4 | 4 |
|
5 | | -Add regression and journey tests for the five highest-risk flows identified in the 1.1.0 coverage audit, and fix three test-infrastructure flakiness items. |
| 5 | +Add integration tests covering every user-facing command and flow in the extension so that each user story has an observable, automated pass/fail signal. |
6 | 6 |
|
7 | 7 | ## Why now |
8 | 8 |
|
9 | | -1.1.0 milestone. Milestone bugs (#51, #144, #167, #170) are fixed; none has a test that would catch a recurrence. Release without coverage leaves those fixes unverifiable. |
| 9 | +1.1.0 milestone. Code coverage gaps mean regressions in closed bugs (#51, #144, #167, #170) are silent, and untested commands have no safety net for future changes. Release without integration-level coverage for all user stories is a quality gap. |
10 | 10 |
|
11 | 11 | ## In scope |
12 | 12 |
|
13 | | -### Tests to add |
| 13 | +### User stories → test suites |
14 | 14 |
|
15 | | -1. **Mark-task-complete code action (E2E)** |
16 | | - - Files: `src/provider/codeactions/for-open-tasks.ts`, `for-completed-tasks.ts` |
17 | | - - Scenario: seed entry with `- [ ] foo`, invoke `ForOpenTasksCodeAction`, assert line becomes `- [x] foo` with completed timestamp. |
18 | | - - Currently: zero direct tests on either file. |
| 15 | +Each suite invokes the command or feature end-to-end against a tmp workspace; assertions are on file system state, document content, or VS Code messages. |
19 | 16 |
|
20 | | -2. **Weekly entry creation full write path (#167 regression)** |
21 | | - - Files: `src/actions/writer.ts` (`createWeeklyForWeek`), `src/ext/conf.ts` (weekly template resolution) |
22 | | - - Scenario: call weekly creation with tmp base, assert file exists at `${base}/${year}/wNN.md` and body matches resolved `weekly` template. |
23 | | - - Currently: `phase1-regression.test.ts:10` only resolves the template object, does not write. |
| 17 | +| User story | Command / entry point | Test file (new or extend) | |
| 18 | +|---|---|---| |
| 19 | +| Open today's entry | `journal.today` | `commands-today.test.ts` | |
| 20 | +| Open yesterday / tomorrow | `journal.yesterday`, `journal.tomorrow` | `commands-prev-next-shortcuts.test.ts` | |
| 21 | +| Open entry by day expression | `journal.day` (smart input: date, weekday, offset) | `commands-day.test.ts` | |
| 22 | +| Open entry by date picker | `journal.open` (QuickPick flow) | `commands-open.test.ts` | |
| 23 | +| Open previous / next entry | `journal.openPrevious`, `journal.openNext` | extend `commands-prev-next.test.ts` | |
| 24 | +| Open previous / next in non-default scope | `journal.openPrevious`, `journal.openNext` + scopes config | extend `commands-prev-next.test.ts` | |
| 25 | +| Create / open a note | `journal.note` | `commands-note.test.ts` | |
| 26 | +| Insert memo into today's entry | `journal.memo` (`memo: text`) | `commands-inject.test.ts` | |
| 27 | +| Insert task into today's entry | `journal.task` (`task: text`) | `commands-inject.test.ts` | |
| 28 | +| Create weekly entry | `journal.day` with week expression OR weekly write path | `commands-weekly.test.ts` | |
| 29 | +| Mark open task done (code action) | `ForOpenTasksCodeAction` | `codeaction-tasks.test.ts` | |
| 30 | +| Mark completed task open (code action) | `ForCompletedTasksCodeAction` | `codeaction-tasks.test.ts` | |
| 31 | +| Print current time | `journal.printTime` | `commands-print.test.ts` | |
| 32 | +| Print duration between selected times | `journal.printDuration` | `commands-print.test.ts` | |
| 33 | +| Print sum of selected numbers | `journal.printSum` | `commands-print.test.ts` | |
24 | 34 |
|
25 | | -3. **`Inject.injectInput` E2E — memo / task / file link** |
26 | | - - File: `src/actions/inject.ts` |
27 | | - - Scenarios: seed today's entry, run `journal.memo` with `memo: lorem ipsum`, assert file gains the line at correct anchor. Parallel cases for `task:` and file link. |
28 | | - - Currently: no targeted inject suite. |
| 35 | +### Test-infrastructure fixes (prerequisite) |
29 | 36 |
|
30 | | -4. **Prev/next under non-default scope (#144 regression)** |
31 | | - - File: `src/actions/navigation.ts` |
32 | | - - Scenarios: |
33 | | - - Seed `${base}/scopes/work/2025/03/{05,08}.md`, anchor on `08.md` in `work` scope, assert `OpenPreviousEntryCommand` opens `05.md` and does not cross into default scope. |
34 | | - - Calendar mode backward through a non-existent day. |
35 | | - - Currently: navigation tests use only default scope. |
36 | | - |
37 | | -5. **`journal.today` command-layer E2E under remote-style URI (#51 closure)** |
38 | | - - File: `src/provider/commands/show-entry-for-date.ts` |
39 | | - - Scenario: `vscode.commands.executeCommand('journal.today')` against tmp base with no existing entry, assert no error and entry file exists afterwards. |
40 | | - - Currently: `issue-51-remote-create.test.ts` stops at `Reader.loadEntryForDay`. |
41 | | - |
42 | | -### Test-infrastructure fixes |
| 37 | +These must land first to avoid poisoning new suites: |
43 | 38 |
|
44 | 39 | - **`read-templates.test.ts`**: mutates `journal.scopes` without teardown → add `afterEach` restore. |
45 | | -- **`phase1-regression.test.ts:74`**: today-offset brittle near midnight UTC → use fixed clock or assert sign only. |
46 | | -- **`week-input.test.ts`**: `next week` uses `moment().week()`, fails on year-rollover week 52→1 → injected clock or relative offset assertion. |
47 | | -- **`notes-sync.test.ts`**: 8×500ms poll with no diagnostic dump on failure → log captured state on timeout. |
| 40 | +- **`phase1-regression.test.ts:74`**: today-offset assertion brittle near midnight UTC → assert sign only, not exact ISO value. |
| 41 | +- **`week-input.test.ts`**: `next week` uses `moment().week()`, fails on year-rollover week 52→1 → assert relative offset. |
| 42 | +- **`notes-sync.test.ts`**: 8×500ms poll dumps no diagnostics on CI timeout → log captured state on failure. |
48 | 43 |
|
49 | 44 | ## Out of scope |
50 | 45 |
|
51 | | -Zero-coverage modules not needed for 1.1.0: |
52 | | -- `codelens/migrate-tasks.ts`, `shift-task.ts` |
53 | | -- `features/scan-entries.ts`, `show-pick-list.ts` |
54 | | -- `features/sync-note-links.ts` (only indirect), `load-note.ts` (indirect) |
55 | | -- `src/ext/conf.ts` template/scope path resolution |
| 46 | +- `journal.weeklySync` — sync-note-links is exercised indirectly via `notes-sync.test.ts`; full integration deferred. |
| 47 | +- `journal.open` workspace picker — requires interactive QuickPick; can only be tested via monkey-patch; defer unless trivial. |
| 48 | +- `codelens/migrate-tasks.ts`, `shift-task.ts` — CodeLens providers; no activation path from command layer; defer. |
| 49 | +- `scan-entries.ts`, `show-pick-list.ts` — internal feature, not a direct user story; `scan-entries-cache.test.ts` already covers caching. |
56 | 50 |
|
57 | 51 | ## Acceptance criteria |
58 | 52 |
|
59 | | -- All five test groups added and green in `npm test`. |
60 | | -- Each closed 1.1.0 bug (#170, #167, #51, #144) has ≥1 regression test that would catch a recurrence. |
61 | | -- Four infra flakiness items addressed. |
62 | | -- No new ESLint or TypeScript errors introduced. |
| 53 | +- Every in-scope user story has ≥1 integration test with observable file-system or document assertion. |
| 54 | +- All tests green in `npm test` on Linux CI. |
| 55 | +- Four infra flakiness items addressed before new tests land. |
| 56 | +- No new ESLint or TypeScript errors. |
| 57 | +- `TestLogger.errors` asserted empty on every happy-path test. |
63 | 58 |
|
64 | 59 | ## Entities / contracts |
65 | 60 |
|
66 | | -- `ForOpenTasksCodeAction` / `ForCompletedTasksCodeAction` in `src/provider/codeactions/` |
67 | | -- `Writer.createWeeklyForWeek(input, ctrl)` in `src/actions/writer.ts` |
68 | | -- `Inject.injectInput(input, document, ctrl)` in `src/actions/inject.ts` |
69 | | -- `OpenPreviousEntryCommand` / `OpenNextEntryCommand` in `src/provider/commands/` |
70 | | -- Test helpers: `command-test-helpers.ts`, `TestLogger` (`src/test/test-logger.ts`) |
71 | | -- Pattern for config: `config.update('base', tmpBase, ConfigurationTarget.Workspace)` + fresh `Ctrl` |
| 61 | +**Commands (instantiate directly, do not `registerCommand`):** |
| 62 | +- `ShowEntryForTodayCommand`, `ShowEntryForYesterdayCommand`, `ShowEntryForTomorrowCommand` → `src/provider/commands/show-entry-for-today.ts` etc. |
| 63 | +- `ShowEntryForDateCommand` (smart input) → `src/provider/commands/show-entry-for-date.ts` |
| 64 | +- `ShowNoteCommand` → `src/provider/commands/show-note.ts` |
| 65 | +- `OpenNextEntryCommand`, `OpenPreviousEntryCommand` → `src/provider/commands/open-next-entry.ts`, `open-previous-entry.ts` |
| 66 | +- `PrintCurrentTimeCommand`, `PrintDurationCommand`, `PrintSumCommand` → `src/provider/commands/print-*.ts` |
72 | 67 |
|
73 | | -## Constraints |
| 68 | +**Code actions:** |
| 69 | +- `ForOpenTasksCodeAction`, `ForCompletedTasksCodeAction` → `src/provider/codeactions/` |
74 | 70 |
|
75 | | -- Tests run inside real VS Code Extension Host — no mocking of `vscode.workspace.fs`. |
76 | | -- Do not register commands in tests — instantiate command classes directly. |
77 | | -- Must pass on Linux (CI uses `xvfb-run`). |
| 71 | +**Domain actions under test:** |
| 72 | +- `Writer.createEntryForDay`, `Writer.createWeeklyForWeek`, `Writer.createNote` → `src/actions/writer.ts` |
| 73 | +- `Inject.injectInput` → `src/actions/inject.ts` |
| 74 | +- `Navigation.openPreviousEntry`, `Navigation.openNextEntry` → `src/actions/navigation.ts` |
78 | 75 |
|
79 | | -## Open questions |
| 76 | +**Test infrastructure:** |
| 77 | +- Config pattern: `config.update('base', tmpBase, ConfigurationTarget.Workspace)` + fresh `new Ctrl(...)` |
| 78 | +- Seeding: write fixture files via `vscode.workspace.fs.writeFile` before command invocation |
| 79 | +- Spy pattern: `(vscode.window as any).showInformationMessage = wrapper`; restore in `afterEach` |
| 80 | +- Error assertion: `assert.strictEqual(logger.errors.length, 0)` |
80 | 81 |
|
81 | | -None after reviewing issue body. |
| 82 | +## Constraints |
| 83 | + |
| 84 | +- Tests run inside real VS Code Extension Host — no mocking of `vscode.workspace.fs`. |
| 85 | +- Instantiate command classes directly: `new ShowEntryForTodayCommand(ctrl)`. |
| 86 | +- Must pass on Linux (`xvfb-run npm test`). |
| 87 | +- No `moment()` in new test code — use `Date` or fixed timestamps. |
82 | 88 |
|
83 | 89 | ## Related issues |
84 | 90 |
|
85 | | -- Blocks: milestone 1.1.0 release |
86 | | -- Regression coverage for: #51, #144, #167, #170 |
| 91 | +- Regression coverage closes: #51, #144, #167, #170 |
| 92 | +- Blocks: 1.1.0 milestone release |
0 commit comments