mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-10-26 16:55:08 +00:00
A Client plugin loaded after the page starts fetches its bootstrap once. The Host now registers that route before starting the Worker and answers once the Worker is ready, so enabling Developer Tools on a running page opens the bottom DevTools without a reload. A failed start answers 503. When the platform cannot run the Worker (ERR_FEATURE_UNAVAILABLE_ON_PLATFORM), the Host warns once and stays active with only the 503 bootstrap route; serve-static and open load after the Worker starts. Every other startup failure still fails the fiber.
407 lines
22 KiB
TypeScript
407 lines
22 KiB
TypeScript
import { spawnSync } from 'node:child_process'
|
|
import { fileURLToPath } from 'node:url'
|
|
import tsconfigPaths from 'vite-tsconfig-paths'
|
|
import { resolvePwshPath } from './packages/shell/pwsh-local/src/resolve.ts'
|
|
import { defineConfig } from 'vitest/config'
|
|
import { standardDecoratorPlugin, vitestExecArgv } from './vitest.shared.ts'
|
|
import { COVERAGE_EXEMPT_ENV, coverageExemptHeavySuites } from './scripts/coverage-exempt.ts'
|
|
import { COVERAGE_PARTITION_MODE_ENV, COVERAGE_TEST_TIMEOUT_ENV, coverageTestTimeoutOptions } from './scripts/coverage-partitions.ts'
|
|
import { LOCAL_TEST_PARALLELISM_CAP, defaultParallelism } from './scripts/parallelism.ts'
|
|
|
|
// Prints exact `path:line:col` records for every uncovered statement, branch
|
|
// path, and function when a file misses the per-file 100% gate — the built-in
|
|
// threshold ERRORs name only the file. Absolute path because istanbul-reports
|
|
// require()s custom reporters (which is also why the reporter is CJS).
|
|
const uncoveredLocationsReporter = fileURLToPath(new URL('./scripts/coverage-uncovered-locations.cjs', import.meta.url))
|
|
|
|
// Resolution facade shared by every plugin instance below: tsconfig.base.json
|
|
// has no include, which vite-tsconfig-paths treats as match-all, so its paths
|
|
// map applies to every test file. paths must win over package exports so built
|
|
// lib/ never loads a second module-singleton copy.
|
|
const pathsPlugin = (): ReturnType<typeof tsconfigPaths> => tsconfigPaths({ projects: ['./tsconfig.base.json'] })
|
|
|
|
const windowsUnsupportedPackages = process.platform === 'win32'
|
|
? [
|
|
// Bash-requiring suites (a real POSIX shell is unavailable on Windows).
|
|
// The pwsh-requiring suites (pwsh-local, tool-pwsh) deliberately stay
|
|
// INCLUDED: PowerShell ships with Windows, so they run natively here.
|
|
// This explicit list (not a 'packages/shell/*' glob) keeps
|
|
// packages/shell/shell — the Service Definition package — running on Windows.
|
|
'packages/shell/bash-local',
|
|
'packages/shell/bash-sandbox',
|
|
'packages/shell/tool-bash',
|
|
'packages/experimental/hook-protocol',
|
|
'packages/experimental/hooks-claude-code',
|
|
'packages/experimental/hooks-codex',
|
|
'packages/terminal/terminal-bash',
|
|
'packages/experimental/ptc-runtime-python',
|
|
'packages/sandbox/sandbox-local',
|
|
// OpenSSH multiplexing and Unix-socket helper streams require POSIX endpoints.
|
|
'packages/ssh/*',
|
|
]
|
|
: []
|
|
|
|
const windowsUnsupportedTests = process.platform === 'win32'
|
|
? [
|
|
...windowsUnsupportedPackages.map(path => `${path}/tests/**/*.spec.ts`),
|
|
'packages/subprocess/subprocess/tests/**/*.spec.ts',
|
|
'packages/subprocess/subprocess-local/tests/local.spec.ts',
|
|
'packages/subprocess/subprocess-local/tests/process-inspector.spec.ts',
|
|
'packages/subprocess/subprocess-local/tests/spawn.spec.ts',
|
|
'packages/subprocess/subprocess-local/tests/terminal.spec.ts',
|
|
// Oracle-diff suites: they compare the worker's POSIX path/url faces
|
|
// against the host Node's own answers, which are win32 semantics on
|
|
// Windows. The worker always speaks POSIX; the Linux lanes hold the diff.
|
|
'packages/experimental/webworker-runtime/tests/node/path-diff.spec.ts',
|
|
'packages/experimental/webworker-runtime/tests/node/shim-diff.spec.ts',
|
|
// The subprocess ladder over the worker's child_process face: its kill
|
|
// rung reaches the in-worker process table through `process.kill`,
|
|
// which the ladder's win32 branch replaces with taskkill-by-real-pid —
|
|
// undeliverable to a table pid. The worker host always reports 'linux',
|
|
// so the Linux lanes hold the ladder.
|
|
'packages/experimental/webworker-runtime/tests/node/child-process.spec.ts',
|
|
]
|
|
: []
|
|
|
|
// These suites compare against or assemble the Worker's fixed Linux platform.
|
|
// Host-native Windows and macOS behavior is not their oracle.
|
|
const nonLinuxWebWorkerTests = process.platform === 'linux'
|
|
? []
|
|
: [
|
|
'packages/experimental/webworker-runtime/tests/node/fs-watch-stream.spec.ts',
|
|
'packages/experimental/webworker-runtime/tests/node/sandbox-stack.spec.ts',
|
|
]
|
|
|
|
const platformUnsupportedTests = [...windowsUnsupportedTests, ...nonLinuxWebWorkerTests]
|
|
|
|
const windowsUnsupportedCoveragePackages = process.platform === 'win32'
|
|
? [...windowsUnsupportedPackages, 'packages/subprocess/*']
|
|
: []
|
|
|
|
// Windows-only packages: their sources execute exclusively on win32 (koffi
|
|
// loads Win32 libraries), so the Linux coverage lane can never cover them.
|
|
// The Windows dev/CI lane exercises them through the probe/runner suites; the
|
|
// per-file 100% gate must not fail on their Linux-uncovered paths.
|
|
const windowsOnlyCoverageExclusions = process.platform !== 'win32'
|
|
? [
|
|
'packages/sandbox/sandbox-windows-acl/src/**/*.ts',
|
|
// The koffi-backed Win32 table (Toolhelp32/GetProcessTimes/taskkill)
|
|
// executes only on win32; its decision logic is unit-pinned on every
|
|
// host through the injected-internals suites.
|
|
'packages/subprocess/subprocess-local/src/windows-inspector.ts',
|
|
]
|
|
: []
|
|
|
|
// The confinement runner entry executes exclusively as a spawned child
|
|
// process (the sandbox seam's argv-prefix wrapper): its module-level main()
|
|
// would run the confinement in-process if imported, and vitest's v8 coverage
|
|
// never measures child processes. Its behavior is pinned end-to-end by
|
|
// tests/runner.spec.ts, which spawns the real entry through tsx.
|
|
const windowsRunnerCoverageExclusions = process.platform === 'win32'
|
|
? [
|
|
'packages/sandbox/sandbox-windows-acl/src/runner.ts',
|
|
// The session write lock's POSIX face (fs-ext flock plus inode
|
|
// verification) executes only off-Windows: the Linux lanes hold its
|
|
// per-file 100%, while the Windows branch is unit-pinned by
|
|
// win32.spec's injected bindings and exercised natively by every
|
|
// Windows suite through the real backend.
|
|
'packages/session/session-persistence-jsonl/src/lease.ts',
|
|
// The macOS provider transport uses Unix sockets; POSIX lanes cover its real socket lifecycle.
|
|
'packages/experimental/cua-macos/src/shared-native.ts',
|
|
]
|
|
: []
|
|
|
|
// pwsh-local's run/start/lifecycle suites self-skip without a real pwsh
|
|
// (executor.spec.ts hasPwsh), leaving this file
|
|
// far below per-file 100% on pwsh-less hosts; the exemption keeps those hosts
|
|
// green while CI runners ship pwsh and still enforce the full bar. The probe
|
|
// runs the suites' own resolution (the dependency-free resolve.ts module),
|
|
// so the exemption is active exactly when the suites skip — a mismatched
|
|
// narrower probe could exempt the file on hosts whose suites actually run.
|
|
const pwshCoverageExclusions = spawnSync(resolvePwshPath(), ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', '$true'], { encoding: 'utf8' }).status === 0
|
|
? []
|
|
: [
|
|
'packages/shell/pwsh-local/src/index.ts',
|
|
'packages/shell/pwsh-sandbox/src/**/*.ts',
|
|
]
|
|
|
|
const testIncludes = [
|
|
'packages/*/*/tests/**/*.spec.{ts,tsx}',
|
|
'apps/*/tests/**/*.spec.{ts,tsx}',
|
|
'scripts/**/*.spec.ts',
|
|
'website/tests/**/*.spec.ts',
|
|
]
|
|
|
|
// The instrumented coverage gate sets this env; the exempt heavy suites then
|
|
// run beside it uninstrumented (membership contract in scripts/coverage-exempt.ts).
|
|
// A set-but-not-'1' value is a misconfiguration, not a silent no-op.
|
|
const coverageExemptRaw = process.env[COVERAGE_EXEMPT_ENV]
|
|
if (coverageExemptRaw !== undefined && coverageExemptRaw !== '' && coverageExemptRaw !== '1') {
|
|
throw new Error(`vitest config: ${COVERAGE_EXEMPT_ENV} must be '1' or unset, got ${JSON.stringify(coverageExemptRaw)}.`)
|
|
}
|
|
const coverageExemptExcludes = coverageExemptRaw === '1'
|
|
? coverageExemptHeavySuites.map(suite => suite.exclude)
|
|
: []
|
|
|
|
const coveragePartitionRaw = process.env[COVERAGE_PARTITION_MODE_ENV]
|
|
if (coveragePartitionRaw !== undefined && coveragePartitionRaw !== '' && coveragePartitionRaw !== '1') {
|
|
throw new Error(`vitest config: ${COVERAGE_PARTITION_MODE_ENV} must be '1' or unset, got ${JSON.stringify(coveragePartitionRaw)}.`)
|
|
}
|
|
const coveragePartitionMode = coveragePartitionRaw === '1'
|
|
|
|
// Lanes on shared hosts raise the per-test, hook, and expect.poll defaults
|
|
// together through DSH_COVERAGE_TEST_TIMEOUT_MS; it lands in each inline
|
|
// project below because CLI flags do not reach them (coverageTestTimeoutOptions
|
|
// owns the rule and its reach).
|
|
const laneTestBudget = coverageTestTimeoutOptions(process.env[COVERAGE_TEST_TIMEOUT_ENV])
|
|
// Outside CI, forks follow the local worker budget; CI keeps Vitest's own default for its runner.
|
|
const localWorkerBudget = process.env.CI === 'true' ? {} : { maxWorkers: defaultParallelism(process.env, undefined, LOCAL_TEST_PARALLELISM_CAP) }
|
|
|
|
// These suites exercise process-global state, process APIs, or timing-sensitive process I/O
|
|
// that worker threads cannot isolate reliably under aggregate gate contention.
|
|
// Keep the narrow exception in forks while the rest of the inventory avoids per-file processes.
|
|
const processBoundTests = [
|
|
'packages/session/session-persistence-jsonl/tests/jsonl.spec.ts',
|
|
'packages/subagent/subagent-acp/tests/subagent-acp.spec.ts',
|
|
'packages/subprocess/subprocess-local/tests/process-exit.spec.ts',
|
|
'packages/subprocess/subprocess-local/tests/spawn.spec.ts',
|
|
'packages/context/time-context/tests/time-context.spec.ts',
|
|
'packages/llm/llm-pi-ai/tests/adapter.spec.ts',
|
|
'packages/boot/app-boot/tests/app-boot.spec.ts',
|
|
'packages/workflow/workflow-ptc/tests/workflow-ptc.spec.ts',
|
|
]
|
|
|
|
// Claude Code's test-kit module names, served by the mods bridge's test support so the example mods' tests import them unchanged.
|
|
const claudeCodeTestingAliases = {
|
|
'claude-code/testing': fileURLToPath(new URL('./packages/experimental/claude-code-mods/tests/support/claude-code-testing.ts', import.meta.url)),
|
|
'claude-code': fileURLToPath(new URL('./packages/experimental/claude-code-mods/tests/support/claude-code.ts', import.meta.url)),
|
|
}
|
|
|
|
export default defineConfig({
|
|
plugins: [pathsPlugin(), standardDecoratorPlugin()],
|
|
resolve: { alias: claudeCodeTestingAliases },
|
|
test: {
|
|
...localWorkerBudget,
|
|
setupFiles: ['./scripts/test-proxy-environment.ts', './scripts/test-dom-environment.ts'],
|
|
// .tsx: client component specs (jsdom via per-file @vitest-environment pragma).
|
|
include: testIncludes,
|
|
exclude: platformUnsupportedTests,
|
|
// One coverage invocation aggregates both projects. Every suite forks for
|
|
// Node stability; process-bound suites stay separate for inventory control.
|
|
projects: [
|
|
{
|
|
plugins: [pathsPlugin(), standardDecoratorPlugin()],
|
|
resolve: { alias: claudeCodeTestingAliases },
|
|
test: {
|
|
name: 'thread-safe',
|
|
execArgv: vitestExecArgv,
|
|
// Node 24 has aborted in its CJS lexer (v8::ToLocalChecked Empty
|
|
// MaybeLocal in cjs_lexer::Parse) from worker threads on macOS,
|
|
// Linux, and Windows. Forked workers avoid that shared thread path.
|
|
pool: 'forks',
|
|
...laneTestBudget,
|
|
setupFiles: ['./scripts/test-proxy-environment.ts', './scripts/test-dom-environment.ts'],
|
|
include: testIncludes,
|
|
exclude: [
|
|
...platformUnsupportedTests,
|
|
...processBoundTests,
|
|
...coverageExemptExcludes,
|
|
],
|
|
},
|
|
},
|
|
{
|
|
plugins: [pathsPlugin(), standardDecoratorPlugin()],
|
|
resolve: { alias: claudeCodeTestingAliases },
|
|
test: {
|
|
name: 'process-bound',
|
|
execArgv: vitestExecArgv,
|
|
pool: 'forks',
|
|
...laneTestBudget,
|
|
setupFiles: ['./scripts/test-proxy-environment.ts', './scripts/test-dom-environment.ts'],
|
|
include: processBoundTests,
|
|
exclude: [
|
|
...platformUnsupportedTests,
|
|
...coverageExemptExcludes,
|
|
],
|
|
},
|
|
},
|
|
],
|
|
coverage: {
|
|
provider: 'v8',
|
|
// Coverage measures OUR runtime source. Types-only files carry no
|
|
// executable code; vendor/ and application/config fixtures are out of scope.
|
|
// .tsx: client components are gated like everything else (jsdom lane).
|
|
include: ['packages/*/*/src/**/*.{ts,tsx}'],
|
|
// Types-only files have no runtime coverage. Importing self-executing bins/workers would boot
|
|
// them inside the unit process, so real subprocess/Worker tests cover their thin entry glue.
|
|
exclude: [
|
|
'packages/*/*/src/types.ts',
|
|
'packages/*/*/src/bin.ts',
|
|
'packages/*/*/src/worker.ts',
|
|
// The built Node entry invokes the independently covered process bootstrap through fd 7.
|
|
'packages/ptc-runtime/ptc-runtime-node/src/process-entry.ts',
|
|
'packages/ptc-runtime/ptc-runtime-node/src/persistent-process-entry.ts',
|
|
// Dynamic Host/Client composition is covered by its focused lifecycle
|
|
// tests and assembled application checks rather than per-file coverage.
|
|
'packages/self-modification/*/src/**/*.{ts,tsx}',
|
|
// A killed executable lint-contract test can leave a non-product source probe behind.
|
|
'packages/*/*/src/oxlint-contract-*.ts',
|
|
// Client/web UI files whose remaining branches need a browser-grade
|
|
// harness the jsdom lane doesn't cover yet. TODO(gui): cover and
|
|
// remove as the client test lane matures.
|
|
'packages/client/ui-trajectory/src/*',
|
|
// Electron guest integration retains its unit specs; per-file coverage
|
|
// is deferred until a native Electron harness covers guest behavior.
|
|
'packages/client/ui-sidebar-browser/src/client/electron/**',
|
|
// Trajectory's compact Markdown projection retains deferred branch coverage.
|
|
'packages/client/ui-primitives/src/markdown/plain-text.ts',
|
|
'packages/client/ui-user-questions/src/client/QuestionComposer.tsx',
|
|
'packages/client/ui-primitives/src/Menu.tsx',
|
|
'packages/client/ui-primitives/src/RiskConfirmation.tsx',
|
|
'packages/client/ui-workspace/src/client/WorkspaceBrowser.tsx',
|
|
'packages/client/ui-workspace/src/client/WorkspacePicker.tsx',
|
|
'packages/client/ui-workspace/src/client/rows/WorkspaceBrowser.tsx',
|
|
'packages/client/ui-renderer/src/client/*',
|
|
// Session object internals retain the runtime GUI debt exemption; the
|
|
// assistant-stream reconciler, Controller entry, transport, Agent scope,
|
|
// and adapters stay gated.
|
|
'packages/api/session-controller/src/client/sessions/!(assistant-stream).ts',
|
|
'packages/api/session-controller/src/client/ordered-baseline.ts',
|
|
'packages/api/session-controller/src/client/time-zone.ts',
|
|
// Keep the browser conversation tree under its existing GUI debt
|
|
// exemption while gating the newly stateful Host half and vocabulary.
|
|
'packages/client/ui-conversation/src/client/*',
|
|
// Chat presentation and assembly retain the same GUI debt exemption;
|
|
// package wiring and the new approval-detail adapter remain gated.
|
|
'packages/client/ui-chat/src/client/chat/!(ApprovalCommand).{ts,tsx}',
|
|
'packages/client/ui-chat/src/client/conversation-nodes/*',
|
|
'packages/client/ui-chat/src/client/details/*',
|
|
'packages/client/ui-chat/src/client/model/*',
|
|
'packages/client/ui-chat/src/client/contract/snapshot.ts',
|
|
'packages/client/ui-chat/src/client/historical-images.ts',
|
|
'packages/client/ui-primitives/src/DisclosureRow.tsx',
|
|
'packages/client/ui-tool/src/*',
|
|
'packages/client/ui-slots/src/*',
|
|
'packages/client/ui-layout/src/*',
|
|
'packages/client/web/src/*',
|
|
'packages/host/webserver/src/*',
|
|
// The browser-worker runtime and its image packer: the executing
|
|
// composition is a real dedicated Worker driven by the web browser lane
|
|
// (apps/web/tests/preview-boot.e2e.ts), which unit-process V8 coverage
|
|
// cannot observe. Unit specs cover the algorithmic cores; the assembled
|
|
// evidence is that boot. TODO(webworker): revisit when a browser-grade
|
|
// coverage lane exists.
|
|
'packages/experimental/webworker-runtime/src/**',
|
|
'packages/experimental/webworker-packer/src/*',
|
|
// Inspector execution adapters run in a Node Worker, the Host native
|
|
// inspector session, or a browser realm, outside attributable parent
|
|
// Vitest coverage.
|
|
'packages/experimental/inspector/src/client/**',
|
|
'packages/experimental/inspector/src/host/bridge/**',
|
|
'packages/experimental/inspector/src/host/cdp/**',
|
|
'packages/experimental/inspector/src/worker/bridge/**',
|
|
'packages/experimental/inspector/src/worker/cdp/**',
|
|
'packages/experimental/inspector/src/worker/realms/**',
|
|
'packages/experimental/inspector/src/worker/{entry,server}.ts',
|
|
// Keep already-complete Inspector modules under the per-file gate and
|
|
// enumerate the remaining direct-test debt instead of exempting src/**.
|
|
// TODO(inspector): close these branch gaps and remove the entries.
|
|
'packages/experimental/inspector/src/shared/bridge/{control-codec,rpc}.ts',
|
|
'packages/experimental/inspector/src/shared/bridge/messages/observation.ts',
|
|
'packages/experimental/inspector/src/shared/bridge/messages/query/codec.ts',
|
|
'packages/experimental/inspector/src/shared/bridge/messages/runtime/{command-codec,console-frames,frames,value-codec}.ts',
|
|
'packages/experimental/inspector/src/shared/bridge/messages/sources/{codec,frames}.ts',
|
|
'packages/experimental/inspector/src/worker/inspection/{cordis-store,query-router,realm-store}.ts',
|
|
// Web config-tree boot round: the new host-side web-transport halves
|
|
// whose remaining branches need real-composition/process harnesses.
|
|
// TODO(gui): cover and remove with the client test lane above.
|
|
'packages/client/modules/src/index.ts',
|
|
'packages/client/modules/src/client/index.ts',
|
|
'packages/client/modules/src/client/manifest.ts',
|
|
'packages/client/hmr/src/index.ts',
|
|
'packages/client/connection/src/index.ts',
|
|
'packages/client/connection/src/http-bridge.ts',
|
|
// This assembly imports generated Host-for-Client code that exists
|
|
// only in lib; the post-build built-bin smoke executes both entries.
|
|
'packages/api/remotes/src/index.ts',
|
|
'packages/api/remotes/src/client/index.ts',
|
|
// The Team browser entry binds its source-covered mount lifecycle to
|
|
// the generated Team Remote contribution, which likewise exists only in lib.
|
|
'packages/experimental/client-ui-agent-team/src/client/index.ts',
|
|
// The speech entry also imports generated Remote definitions; voice-input.e2e.ts
|
|
// exercises the built entry, while source tests cover mountVoiceInput.
|
|
'packages/experimental/client-ui-voice-input/src/client/index.ts',
|
|
// The mods band entry imports the bridge's generated Remote contribution, which exists only in lib;
|
|
// the Web snapshot exercises the built entry, while source tests cover mountModsBand.
|
|
'packages/experimental/client-ui-claude-code-mods/src/client/index.ts',
|
|
// The access entry imports its generated Remote contribution, which exists only in lib;
|
|
// the Web snapshot exercises the built entry, while source tests cover mountAccess.
|
|
'packages/api/remote-access/src/client/index.ts',
|
|
// Slash/command/input round: per-file gaps deferred with the same
|
|
// client-lane debt. TODO(gui): cover and remove with the lane above.
|
|
'packages/client/ui-commands/src/index.ts',
|
|
'packages/client/ui-skill/src/index.ts',
|
|
'packages/client/ui-input-trigger/src/index.ts',
|
|
'packages/client/ui-subagent/src/index.ts',
|
|
'packages/client/ui-commands/src/client/popup.ts',
|
|
'packages/client/ui-commands/src/client/directory.ts',
|
|
'packages/client/ui-commands/src/client/service.ts',
|
|
'packages/client/ui-commands/src/client/PopupSelectView.tsx',
|
|
'packages/client/ui-model-selection/src/index.ts',
|
|
'packages/client/ui-permission-presets/src/index.ts',
|
|
'packages/client/ui-model-selection/src/client/ModelSelect.tsx',
|
|
'packages/client/ui-model-selection/src/client/directory.ts',
|
|
'packages/client/ui-model-selection/src/client/index.ts',
|
|
'packages/client/ui-model-selection/src/client/service.ts',
|
|
'packages/client/ui-input-trigger/src/client/controller.ts',
|
|
'packages/client/ui-input-trigger/src/client/service.ts',
|
|
'packages/client/ui-input-trigger/src/core/menu.ts',
|
|
'packages/client/ui-input-trigger/src/core/detect.ts',
|
|
'packages/client/ui-sidebar/src/client/index.ts',
|
|
'packages/client/ui-skill/src/client/index.ts',
|
|
'packages/client/ui-workspace/src/client/index.ts',
|
|
'packages/test-support/client-runtime/src/translate.ts',
|
|
'packages/client/ui-primitives/src/JsonTree.tsx',
|
|
'packages/client/ui-settings-models/src/client/DeepSeekOnboardingDialog.tsx',
|
|
'packages/client/ui-settings-models/src/client/welcome-store.ts',
|
|
'packages/extensions/*/src/**/*.ts',
|
|
'packages/extensions/*/src/**/*.tsx',
|
|
// Typert correctness is checked by its uninstrumented suites,
|
|
// including compiler fixtures and byte-for-byte catalog reproduction.
|
|
'packages/typert/*/src/**/*.{ts,tsx}',
|
|
// Experimental webworker-runtime is outside the coverage requirement
|
|
// by decision: its correctness signal is its uninstrumented suite and
|
|
// the packer's end-to-end image spec.
|
|
'packages/experimental/webworker-runtime/src/**/*.ts',
|
|
// Projection/command round: executor lifecycle branches and the
|
|
// registry's drive tails need the same maturing lanes. TODO(gui):
|
|
// cover and remove with the client test lane above.
|
|
'packages/interaction/commands/src/index.ts',
|
|
'packages/session/session-projection/src/index.ts',
|
|
...windowsUnsupportedCoveragePackages.map(path => `${path}/src/**/*.ts`),
|
|
...windowsOnlyCoverageExclusions,
|
|
...windowsRunnerCoverageExclusions,
|
|
...pwshCoverageExclusions,
|
|
],
|
|
// 100% or it doesn't merge (docs/testing.md: excessive tests are welcome).
|
|
// Per-file so a well-covered big file can't subsidize a bare one.
|
|
// Every v8 ignore comment must carry a reason — see the testing policy
|
|
// (docs/testing.md).
|
|
thresholds: coveragePartitionMode
|
|
? undefined
|
|
: {
|
|
perFile: true,
|
|
statements: 100,
|
|
branches: 100,
|
|
functions: 100,
|
|
lines: 100,
|
|
},
|
|
reporter: coveragePartitionMode
|
|
? []
|
|
: process.env.CI
|
|
? ['text', uncoveredLocationsReporter]
|
|
: ['text', 'html', uncoveredLocationsReporter],
|
|
},
|
|
},
|
|
})
|