This directory contains comprehensive tests for the Worklog project using Vitest.
# Run all tests once
npm test
# Run tests in watch mode (auto-rerun on file changes)
npm run test:watch
# Run tests with coverage report
npm run test:coverage
# Run TUI tests only (CI/headless)
npm run test:tui
# Generate per-test timings
```bash
# You can generate a JSON report of per-test timings which helps
# identify slow tests to refactor or move to integration-only runs.
# Run the timings collector (writes test-timings.json at repo root)
npm run test:timings
# Open test-timings.json for the slowest tests and candidates to move
cat test-timings.json | jq '.rows | sort_by(-.durationMs) | .[0:20]'Tests are spread across two top-level directories:
tests/— the main test directory (this folder)test/— additional tests (migrations, TUI integration, doctor checks, etc.)
database.test.ts— WorklogDatabase CRUD, queries, comments, parent-child relationshipsjsonl.test.ts— JSONL import/export, backward compatibility, round-trip integritysync.test.ts— Work item merging, field-level conflict resolution, tag/comment mergingsync-worktree.test.ts— Git worktree sync scenariosconfig.test.ts— Configuration loading, defaults, validation, prefix managementvalidator.test.ts— Work item field validation rulesfts-search.test.ts— Full-text search across titles, descriptions, comments, tagssort-operations.test.ts— Sort index operations and rebalancinggrouping.test.ts— Work item grouping logicfile-lock.test.ts— File locking and concurrent accesslockless-reads.test.ts— Lock-free read path correctnessnormalize-sqlite-bindings.test.ts— SQLite binding normalizationplugin-loader.test.ts/plugin-integration.test.ts— Plugin discovery and loadinggithub-*.test.ts— GitHub sync, push state, pre-filter, comments, deleted items, self-link, output
issue-management.test.ts— End-to-end create/update/delete/show workflowsissue-status.test.ts— Status transitionsstatus.test.ts—wl statuscommand outputteam.test.ts— Team/sync CLI commandscreate-description-file.test.ts—--description-fileflaginit.test.ts—wl initworkflowfresh-install.test.ts— Clean install scenarioupdate-batch.test.ts— Batch update operationsupdate-do-not-delegate.test.ts— Do-not-delegate flag handlingreviewed.test.ts—wl reviewedtogglemisc.test.ts— Miscellaneous CLI edge caseshelpers-tree-rendering.test.ts— Tree display formattingaction-opts-normalization.test.ts— Option normalizationinproc-harness.test.ts/debug-inproc.test.ts— In-process test harnessinitialization-check.test.ts— Pre-init guardunlock.test.ts— Lock file removalgit-mock-roundtrip.test.ts— Git mock for sync testsgithub-*.test.ts— GitHub push/filter CLI tests
tui-state.test.ts/state.test.ts— TUI state managementcontroller.test.ts— TUI controller logiclayout.test.ts— Layout renderingfilter.test.ts— Item filteringmove-mode.test.ts— Move/reparent modeautocomplete.test.ts/autocomplete-widget.test.ts— Autocompleteopencode-*.test.ts— OpenCode integration, SSE, prompt, sessions, layoutpersistence*.test.ts— TUI persistencefocus-cycling-integration.test.ts— Focus cyclingwidget-create-destroy*.test.ts— Widget lifecyclestatus-stage-validation.test.ts— Status/stage rule enforcement in TUItui-update-dialog.test.ts— Update dialogtui-mouse-guard.test.ts— Mouse event handlingshutdown-flow.test.ts/event-cleanup.test.ts— Cleanup on exitnext-dialog-wrap.test.ts— Next dialog wrappingtoggle-do-not-delegate.test.ts— Do-not-delegate toggle in TUI
migrations.test.ts— Database migration testsdoctor-dependency-check.test.ts/doctor-status-stage.test.ts—wl doctorcheckscomment-update.test.ts— Comment update operationsvalidator.test.ts— Additional validation teststui-integration.test.ts/tui-opencode-integration.test.ts— TUI integrationtui-opencode-sse-handler.test.ts— OpenCode SSE handlertui-chords.test.ts— Keyboard chord handlingtui-style.test.ts— TUI styling
Current test coverage: 894 tests passing, 0 skipped across 82 test files.
The test-utils.ts file provides shared utilities for tests:
createTempDir()- Creates a temporary directory for test isolationcleanupTempDir(dir)- Cleans up temporary directories after testscreateTempJsonlPath(dir)- Generates a temp path for JSONL filescreateTempDbPath(dir)- Generates a temp path for database fileswait(ms)- Async delay utility
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { createTempDir, cleanupTempDir } from './test-utils.js';
describe('MyFeature', () => {
let tempDir: string;
beforeEach(() => {
tempDir = createTempDir();
// Setup code
});
afterEach(() => {
cleanupTempDir(tempDir);
});
it('should do something', () => {
// Test code
expect(result).toBe(expected);
});
});- Isolate tests - Each test should be independent and use temp directories
- Clean up - Always clean up temp files and directories in
afterEach - Descriptive names - Test names should clearly describe what is being tested
- Arrange-Act-Assert - Structure tests with clear setup, execution, and verification phases
- Test edge cases - Include tests for error conditions and boundary cases
Tests run automatically on:
- Pull requests
- Pushes to main branch
- Manual workflow dispatch
None at this time. All 894 tests pass with 0 skipped.
- Add API endpoint integration tests
- Increase code coverage measurement
- Add mutation testing
Some tests in this repository are intentionally long-running (load or simulation tests) and are gated so they do not run in CI by default. The gating mechanism is implemented in tests/test-utils.ts:
- Wrapper helpers:
describeLong(name, fn)anditLong(name, fn)– these skip the suite/test unless the environment variableWL_RUN_LONG_TESTSis set totrue. - Naming convention: long tests often use the
.long.test.tsfilename suffix (for discoverability), but the gate is enforced by the helper functions above.
How to run long or gated tests locally:
-
Run all tests but skip long tests (default CI behaviour):
npm test
-
Run the full test-suite including long tests:
WL_RUN_LONG_TESTS=true npm test
-
Run only the long tests (by filename pattern):
WL_RUN_LONG_TESTS=true npx vitest run "tests/**/*.long.test.ts"
-
Run a single long test file:
WL_RUN_LONG_TESTS=true npx vitest run tests/github-sync-load.long.test.ts
Running subsets of tests
-
Run unit tests only (tests under
tests/):npx vitest run tests
-
Run integration tests only (tests under
test/):npx vitest run test
-
Run TUI/headless tests (CI helper):
npm run test:tui
Guidance for authors
- Mark legitimately long simulations with the
describeLong/itLonghelpers fromtests/test-utils.ts. This ensures CI remains fast and reliable while still allowing engineers to run exhaustive load simulations locally when needed. - Keep long tests deterministic: use injectable clocks, network stubs, and spies rather than real external services.
- Prefer splitting long integration/load tests into separate files (or
.long.test.tssuffix) so they are easy to find and run.
Example
import { describeLong, itLong } from './test-utils.ts';
describeLong('github-sync long load simulations (gated)', () => {
itLong('schedules many calls through throttler under simulated load', async () => {
// ...long-running simulation here
});
});