import { coverageConfigDefaults, defineConfig } from 'vitest/config'; export default defineConfig({ test: { // A .jsx suite renders components, which only a file the JSX transform // reads can do. The account and browser apps are the only ones with any. include: [ 'packages/*/test/**/*.test.js', 'packages/*/test/**/*.test.jsx', 'test/**/*.test.js', ], testTimeout: 30000, hookTimeout: 60000, coverage: { provider: 'v8', reporter: ['text', 'html'], include: ['packages/*/src/**/*.js'], // The e2e suite runs these files, but in a runtime this process cannot // instrument. It starts `wrangler dev`, `deno` and the readonly CLI as // subprocesses. blobs-s3 needs a real S3. If they stay in the report, they // show 0% however many tests cover them. // // PLATFORM=node is the exception. That server runs in this process, so // `PLATFORM=node vitest run --coverage` does record its e2e coverage. exclude: [ ...coverageConfigDefaults.exclude, 'packages/deno/src/**', 'packages/blobs-deno/src/**', 'packages/cloudflare/src/index.js', 'packages/readonly/src/cli.js', 'packages/git-ci/src/cli.js', 'packages/git-host/src/cli.js', 'packages/blobs-s3/src/index.js', // Browser code, exercised in the browser rather than by this suite. 'packages/start/src/**', 'packages/git-ui/src/**', 'packages/spaces-ui/src/**', ], // Vitest gives no report at all after a test fails, unless this is true. reportOnFailure: true, // These are floors, one per area, not one global number. A global number // mixes two different groups of files. The unit suite covers some modules // directly. For other handlers, only the e2e suite gives coverage, and // `npm run ci` does not run it. The unit suite covers every file named // below, so these floors hold without the e2e suite. thresholds: { 'packages/core/src/proxy.js': { statements: 98, branches: 95, functions: 100, }, 'packages/core/src/session.js': { statements: 96, branches: 84, functions: 100, }, 'packages/core/src/http.js': { statements: 92, branches: 88, functions: 100, }, 'packages/core/src/passkey.js': { statements: 100, branches: 80, functions: 100, }, 'packages/core/src/{crypto,auth,plc,repo,scope,verify,webauthn,backup}.js': { statements: 90, branches: 78, functions: 95, }, // A glob key adds together every file it matches. Then the total can pass // the floor while one module is far below it. Each module gets its own // entry. The two spaces entries below are separate for the same reason. 'packages/core/src/handlers/account.js': { statements: 88, branches: 74, functions: 96, }, 'packages/core/src/handlers/migration.js': { statements: 96, branches: 83, functions: 84, }, 'packages/core/src/handlers/account-backup.js': { statements: 97, branches: 90, functions: 100, }, 'packages/core/src/handlers/xrpc-sync.js': { statements: 95, branches: 79, functions: 100, }, // Branches sit under the measured 100% because the v8 provider counts // them differently between releases. Statements and functions do not // move that way. 'packages/core/src/handlers/xrpc-repo.js': { statements: 88, branches: 79, functions: 100, }, 'packages/core/src/handlers/oauth.js': { statements: 83, branches: 73, functions: 100, }, 'packages/core/src/handlers/xrpc-server.js': { statements: 97, branches: 92, functions: 94, }, 'packages/core/src/handlers/xrpc-identity.js': { statements: 95, branches: 82, functions: 100, }, 'packages/core/src/handlers/{server-meta,xrpc-blob,xrpc-preferences}.js': { statements: 100, branches: 95, functions: 100, }, 'packages/core/src/kem.js': { statements: 100, branches: 100, functions: 100, }, 'packages/core/src/sha256.js': { statements: 100, branches: 95, functions: 100, }, 'packages/core/src/handlers/xrpc-firehose.js': { statements: 100, branches: 86, functions: 100, }, 'packages/drive/src/{browser,extension,lexicon,writer}.js': { statements: 90, branches: 72, functions: 90, }, // The account routes carry error paths and the change-feed walk // the unit suite reaches only in part. 'packages/drive/src/account.js': { statements: 82, branches: 65, functions: 100, }, 'packages/oci/src/*.js': { statements: 82, branches: 70, functions: 92, }, 'packages/npm/src/*.js': { statements: 82, branches: 70, functions: 92, }, 'packages/spaces/src/*.js': { statements: 90, branches: 80, functions: 95, }, 'packages/spaces/src/handlers/*.js': { statements: 80, branches: 70, functions: 95, }, 'packages/lexicon-resolver/src/**/*.js': { statements: 84, branches: 70, functions: 90, }, 'packages/git/src/methods.js': { statements: 90, branches: 80, // The discovery-cap notice sink logs on an answer larger than a // unit test builds, so one arrow here is uncovered by design. functions: 96, }, 'packages/git/src/api-lexicon.js': { statements: 95, branches: 90, functions: 95, }, // The hosting operations carry the runner and space paths the unit // suite reaches only in part. 'packages/git/src/hosting.js': { statements: 78, branches: 70, functions: 85, }, // checkout.js has no entry: it drives the git binary against a live // PDS, which only the e2e suite can provide. 'packages/git-ci/src/{daemon,refs,request,spec,state,workflow}.js': { statements: 100, branches: 78, functions: 100, }, 'packages/git-ci/src/{executor,firehose,publish,runner}.js': { statements: 90, branches: 65, functions: 88, }, 'packages/git/src/merge3.js': { statements: 95, branches: 88, functions: 100, }, 'packages/git/src/{merge,merge-commit,pack-write}.js': { statements: 90, branches: 78, functions: 100, }, 'packages/git/src/discovery.js': { statements: 95, branches: 90, functions: 100, }, 'packages/git/src/upstream.js': { statements: 100, branches: 90, functions: 100, }, 'packages/git/src/pull-requests.js': { statements: 95, branches: 85, functions: 100, }, 'packages/git/src/issues.js': { statements: 95, branches: 78, functions: 100, }, 'packages/git/src/pull-request-reader.js': { statements: 85, branches: 70, functions: 85, }, 'packages/git/src/issue-reader.js': { statements: 93, branches: 74, functions: 90, }, 'packages/appview/src/discovery.js': { statements: 100, branches: 100, functions: 100, }, 'packages/appview/src/store.js': { statements: 95, branches: 92, functions: 98, }, 'packages/appview/src/watch.js': { statements: 84, branches: 66, functions: 78, }, 'packages/appview/src/jetstream.js': { statements: 88, branches: 70, functions: 82, }, // The backfill walk needs a live relay and PDS to finish its pages, // so the unit suite holds only the partial-answer paths. 'packages/appview/src/backfill.js': { statements: 78, branches: 62, functions: 88, }, 'packages/git-host/src/host.js': { statements: 57, branches: 48, functions: 35, }, 'packages/git-host/src/remote.js': { statements: 82, branches: 62, functions: 90, }, 'packages/git-host/src/server.js': { statements: 74, branches: 50, functions: 78, }, // The login flow needs a live authorization server to run to the // token exchange; the unit suite holds the metadata and redirect. 'packages/git-host/src/auth.js': { statements: 36, branches: 18, functions: 40, }, }, }, }, });