Test and Debug
Run Tests
clice has four types of tests: unit tests, integration tests, smoke tests, and snap tests.
All test dependencies (node/npm for the integration suite and tools, python for scripts/) are managed by pixi — no separate installation needed.
Unit Tests
pixi run unit-test # default RelWithDebInfo
pixi run unit-test Debug # debug buildEquivalent to:
./build/RelWithDebInfo/bin/unit_tests \
--test-dir="./tests/data" \
--verboseIntegration Tests
End-to-end tests that start a real clice serve instance and communicate via LSP protocol.
pixi run integration-test # default RelWithDebInfo
pixi run integration-test Debug # debug buildThe suite is TypeScript on vitest (tests/), speaking LSP through the official vscode-languageserver-protocol stack. Equivalent to:
cd tests
npm run check # typecheck (tsc strict) + lint (ESLint)
CLICE_EXECUTABLE=../build/RelWithDebInfo/bin/clice npm testUseful variants:
npx vitest run --config integration/vitest.config.ts integration/server/memory_ownership.test.ts # one fileSmoke Tests
Replay recorded LSP sessions to catch regressions in protocol handling.
pixi run smoke-test # default RelWithDebInfo
pixi run smoke-test Debug # debug buildEquivalent to:
node tools/replay.ts tests/smoke/*.jsonl \
--clice=./build/RelWithDebInfo/bin/cliceSnap Tests
Feature snapshot corpora under tests/snap/<feature>/, with sources and snapshots side by side. The snap suite (tests/snap/snap.test.ts, domain logic in tools/snap/) pins every fixture from the paths its verify: mode asks for: inspect (one clice inspect process per fixture, no server involved) and server (replayed through a real server). The integration suite plays no part in snapshots.
pixi run snap-test # default RelWithDebInfo
pixi run snap-test Debug # debug buildEquivalent to:
cd tests
CLICE_EXECUTABLE=../build/RelWithDebInfo/bin/clice npm run snapA fixture is a single .cpp at the corpus root, or a subdirectory entered through its main.cpp — one multi-file unit whose sibling sources (module interfaces, headers, extra sources) belong to the fixture. Corpus-wide compile flags live in the corpus's corpus.json manifest; a fixture appends its own with - flags: [...]. Each server-path run materializes the fixture into a throwaway workspace (sources arrive on disk with §-annotations already stripped), so fixtures never share state and background indexing — off by default, enabled per fixture with - indexing: true — sees the same bytes the compiler does. A fixture that deliberately does not compile cleanly declares - diagnostics: expected; unexpected diagnostics fail the fixture, and so does a clean compile under that declaration.
By default a fixture is verify: both with snap: shared: the inspect and server results must render byte-identically and are pinned by one <name>.snap.yml. A fixture whose two paths legitimately differ declares - snap: separate in its /// doc header (with a // snap: comment explaining why) and each path pins its own <name>.inspect.snap.yml / <name>.server.snap.yml. A known-wrong divergence is declared as - snap: skip: the fixture runs nowhere and keeps no snapshot until the two paths agree. A feature that exists on only one path (include and import completion answered by the server; index dumps with no LSP request shape) declares - verify: server or - verify: inspect and that side owns the plain <name>.snap.yml.
UPDATE_SNAPSHOTS=1 updates everything in one run: inspect tests run first and own shared snapshot bodies; the server side can only update its own variants. A shared snapshot mismatch on the server side is a real divergence between the server pipeline and the direct feature call — investigate it instead of regenerating over it.
Run All Tests
pixi run test # runs unit + integration + smoke + snap
pixi run test Debug # all tests with debug buildEditor E2E Tests
Smoke tests that run real editors (headless Neovim and VSCode) against a locally built clice binary, covering startup, first diagnostics, hover, definition and completion on two fixtures (including a C++20 modules project). CI runs them in the test-editor job on Linux with the latest stable editor releases, on purpose unpinned: the job exists to catch breakage caused by new editor versions.
$ pixi run build # build/RelWithDebInfo/bin/clice
$ pixi run -e editor editor-test # nvim + vscode, both fixturesPrerequisites outside the pixi env:
nvim(stable) onPATHfornvim-e2e.- A system
cmake/ninja/clangforeditor-prepareto configure the CMake-based module fixture (same assumption the integration tests make). - A display (or
xvfb-run) plus the usual Electron system libraries forvscode-e2e.
Debug
If you want to attach a debugger to clice, start it in socket mode independently, then connect a client.
./build/Debug/bin/clice serve --mode socket --port 50051After the server starts, you can connect a client in two ways:
Connect via VS Code
Configure the clice extension to connect to your running instance:
Install the clice extension.
Configure
.vscode/settings.json:jsonc{ "clice.executable": "/path/to/your/clice/executable", "clice.mode": "socket", "clice.port": 50051, // Optional: disable clangd if also installed "clangd.path": "", }Reload Window (
Developer: Reload Window) for settings to take effect.
Debug the VS Code extension
The extension lives in-tree at editors/vscode/:
Install dependencies:
shellnpm install # at the repo root; the extension is an npm workspace memberOpen the repository root in VS Code (the launch configurations are in
.vscode/launch.jsonat the root).Create
.vscode/settings.jsonwith the tcp config above.Press
F5and selectVSCode Extension (pipe)orVSCode Extension (socket)to launch an Extension Development Host window.