chore: core unit tests for shared + main modules#54
Merged
Conversation
- add fixture-based suite for computeAll: overview, daily seeding, trend gaps (the W19 regression), vocab carry-forward, streaks, mode pct sum, bucketBy granularities, streakWindowDays, word frequency stopword filter, filler summary roll-up, heatmap cell - mirror tsconfig path aliases (@shared, @Renderer) in vitest config so source files keep using the alias under test
- filterByRange: open window passthrough, from/to bounds, invalid datetime tolerance - tokenise: stopword filter, length floor, empty input - normalisePhrases: case-insensitive dedupe, non-string rejection, first-seen ordering - buildFillers: word-boundary matching, substring rejection, multi-word + whitespace tolerance, breakdown invariants
- valid recording → parsed Recording with derived metrics - malformed JSON folders counted as errors - folders without meta.json counted as skipped - non-directory root entries ignored - zero-duration → 0 wpm (not Infinity) - non-existent root path returns empty without throwing - output sorted newest-first by datetime - configured filler list flows through to fillerBreakdown
- mock electron.app.getPath via vi.hoisted so each test runs against a fresh tmpdir - getConfig: defaults, fillerWords injection, empty-array preservation, additive migration, malformed-JSON fallback - setConfig round-trips through disk - resetConfig wipes back to defaults - isPathValid: requires a child with meta.json - resolveRecordingsPath: promotes a SuperWhisper parent to its recordings/ subdirectory - isPathInsideHome: home / outside / null
- export pickBucketBy + datasetSpanDays so they're directly testable without rendering the hook (which is glue around computeAll + zustand selectors that's already covered upstream) - pickBucketBy: day for <=29d, week for 30-90d, month beyond - datasetSpanDays: empty, single recording, multi-recording span, invalid datetime tolerance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a focused test pass over the calculation, parsing, and disk-read surfaces. 78 tests, sub-second runtime, no new dependencies.
aggregates.test.ts— overview, daily seeding, trend gaps (the W19 regression that the bug-fix PR addressed), vocab carry-forward, streaks, mode percentages, bucket granularities, word-frequency stopword filter, filler roll-up, heatmaprange.test.ts—filterByRangebounds + invalid-datetime tolerancetext-metrics.test.ts—tokenise,normalisePhrases,buildFillers(word-boundary, multi-word, ordering)scanner.test.ts— tmpdir fixtures covering valid / malformed / no-meta / non-directory entries, zero-duration → 0 wpm, missing root path, sort order, filler threadingconfig.test.ts— electron mocked viavi.hoisted; defaults, fillerWords migration paths,setConfiground-trip,resetConfig,isPathValid,resolveRecordingsPathparent-promotion,isPathInsideHomeuseFilteredAggregates.test.ts— exportspickBucketBy+datasetSpanDaysso they're testable without React; the hook itself is glueSkipped (with reasoning in the plan): IPC handlers (thin glue), protocol/watcher/updater (Electron-bound), Zustand stores, components, Playwright.
vitest.config.tsgains the@shared/@rendereraliases so source files keep using them under test.Test plan
pnpm typecheck/pnpm lint/pnpm format:check/pnpm testall green locally