From 020a56d849bcc862190d50b1357ab380e3fcb9d0 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Fri, 2 Oct 2026 21:57:35 +0200 Subject: [PATCH 1/2] chore: bump `sv` and `sv-utils` devdep and peer --- .github/workflows/ci.yml | 35 ++++++++++++- CONTRIBUTING.md | 4 ++ README.md | 9 ++++ package.json | 7 +-- pnpm-lock.yaml | 46 ++++++++++++----- tests/compatibility.test.mjs | 95 ++++++++++++++++++++++++++++++++++++ 6 files changed, 181 insertions(+), 15 deletions(-) create mode 100644 tests/compatibility.test.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90422d8..a3764b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,10 +49,43 @@ jobs: path: dist if-no-files-found: error + compatibility: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sv: ['0.13.1', '0.17.1', '1.0.0', '1.0.1'] + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + + - name: Set up pnpm + uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 + with: + version: 11.27.1 + + - name: Set up Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e + with: + node-version: 24 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build published entry point + run: pnpm build + + - name: Install CLI version under test + run: pnpm add --save-dev sv@${{ matrix.sv }} + + - name: Test published entry point + run: pnpm test:compatibility + release: runs-on: ubuntu-latest if: github.event_name == 'push' && github.ref == 'refs/heads/main' - needs: build + needs: [build, compatibility] permissions: contents: read id-token: write diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b128728..90e555d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,6 +15,10 @@ pnpm demo-add ## run the tests pnpm test + +## test the published entry point against the installed sv version +pnpm build +pnpm test:compatibility ``` ## Key things to note diff --git a/README.md b/README.md index b494895..a86af66 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,15 @@ Or integrate MSW add-in into an existing project with this one: npx sv add @msw/sveltekit ``` +## CLI compatibility + +Supports `sv` versions `>=0.13.1 <2.0.0`. The published add-on is tested against +`0.13.1`, `0.17.1`, `1.0.0`, and `1.0.1`. Its `sv-utils` dependency is bundled. + +Older `sv` versions may show a major-version compatibility warning even though +they are supported: the CLI checks a single major version rather than the full +peer dependency range. Use `npx sv@latest add @msw/sveltekit` to avoid that warning. + ## What you get - `msw` added as a dev dependency. diff --git a/package.json b/package.json index 73563a7..6de9b76 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "format": "prettier --write .", "format:check": "prettier --check .", "test": "vitest run", + "test:compatibility": "node --test tests/compatibility.test.mjs", "release": "release publish" }, "exports": { @@ -40,16 +41,16 @@ }, "homepage": "https://github.com/mswjs/sveltekit", "peerDependencies": { - "sv": "^0.13.0" + "sv": "^1.0.0 || >=0.13.1 <1.0.0" }, "devDependencies": { "@ossjs/release": "^0.11.2", "@playwright/test": "^1.63.0", - "@sveltejs/sv-utils": "^0.3.3", + "@sveltejs/sv-utils": "^1.0.0", "@types/node": "^26.6.3", "oxlint": "^1.85.0", "prettier": "^3.9.9", - "sv": "^0.17.1", + "sv": "^1.0.1", "tsdown": "^0.23.0", "vitest": "^5.0.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 714bf96..0b992ea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: ^1.63.0 version: 1.63.0 '@sveltejs/sv-utils': - specifier: ^0.3.3 - version: 0.3.3 + specifier: ^1.0.0 + version: 1.0.0 '@types/node': specifier: ^26.6.3 version: 26.6.3 @@ -27,8 +27,8 @@ importers: specifier: ^3.9.9 version: 3.9.9 sv: - specifier: ^0.17.1 - version: 0.17.1 + specifier: ^1.0.1 + version: 1.0.1 tsdown: specifier: ^0.23.0 version: 0.23.0(publint@0.3.24) @@ -308,8 +308,8 @@ packages: resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} engines: {node: '>=18'} - '@sveltejs/sv-utils@0.3.3': - resolution: {integrity: sha512-K6Voe+/4Ry6o3QTFdG4cNkdgW9kvbkJuRyyIyUbSVkuJUVz4jCdvYNuDCBNYC1mpxBFi7nuulpOeuqRjldZXRA==} + '@sveltejs/sv-utils@1.0.0': + resolution: {integrity: sha512-nK6hcTMF9Iffu3zHS6+1bE7yDROFPvraKGvzjUy7aBQkzoccKse6WSWhpMvPLMP2tOC9+el4+HI+RhfA1OPFpQ==} '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} @@ -359,133 +359,157 @@ packages: resolution: {integrity: sha512-Oc2KInVkPfUjEB4PeV6X0NvIoyYTzDe/WmqFrTwBqKs6YKnz4A7XwWQvJTb7M0rLz9a6WgpUUiiS5QKaCi4O/g==} cpu: [arm64] os: [android] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-darwin-arm64@0.10.2': resolution: {integrity: sha512-3H7eNPIHJndUJXZ4QUGBPq1zC6RGcUZfm7bymJes+/N7wTVWUn1bxZ9JcozYHpkWQNm9f23G8YWbaHD9aYH72A==} cpu: [arm64] os: [darwin] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-darwin-x64@0.10.2': resolution: {integrity: sha512-AJOUpR2s3LF9AWiiub/Uyc/UoXNTWcq8hK3cVI6fUSXtwh34dG21J6hRuNlO6JVJFTo4o3ScVvZOrh/YFfUEAA==} cpu: [x64] os: [darwin] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-freebsd-x64@0.10.2': resolution: {integrity: sha512-ms7DcZu87u5CiK/wMwvpKAvAmtaqKjCQIXNweMLypG6qbuiaOMQf1jpbB5+j46xBcgCovo8TQMcv0bCQLKIL9w==} cpu: [x64] os: [freebsd] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-linux-arm-gnu@0.10.2': resolution: {integrity: sha512-xJDpYAsKV5+eaiBhTYl05fvT6sst4PsCeuIFMRu9b0/WCSrNQPfCDtAQ5/MS6xNpsdujdZEPR+gmfWk3ZG5i3A==} cpu: [arm] os: [linux] libc: [glibc] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-linux-arm-musl@0.10.2': resolution: {integrity: sha512-qfTkgd7AEx61l4K9VtXWCGTxc/fmXJ4ZheDz3i+/AAJUtg4sa0bPrc0VBxPggB/rayR8Z3+JfrBItuyanBJJ9Q==} cpu: [arm] os: [linux] libc: [musl] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': resolution: {integrity: sha512-4e6Mifm/4UdjtU3D8mATIrvgP+xEiH8xtQOjd0zpd72XKWT7ug3sdyhq2utkkZFP6BvYp7SgZrI+aR4VeIOHdw==} cpu: [arm64] os: [linux] libc: [glibc] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-linux-arm64-musl@0.10.2': resolution: {integrity: sha512-RdsJrUfDYFVV3JOmWFUWwSu31fa1APn12xDeIKxgl/YWxrabwtxsDBNjF2561c7tmcbiewdCUvngqRs8AyGVLA==} cpu: [arm64] os: [linux] libc: [musl] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-linux-x64-gnu@0.10.2': resolution: {integrity: sha512-mVzWimEPPreaPyXIUvxsHoJzvO7ckZ5j0LgQFHz04zQIRwt9A9T2hA7K5/jYjJKkMxWG/U2VjhGNwVhtyU+uqg==} cpu: [x64] os: [linux] libc: [glibc] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-linux-x64-musl@0.10.2': resolution: {integrity: sha512-Y77fyISurmr2mvO1yeq3u+x/WJbACgPR4w+lzEVx30ViCxZzIGrZPRN1yEdZ9xUNPNsIO5thBHIdRNG+UGUG+Q==} cpu: [x64] os: [linux] libc: [musl] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-win32-arm64@0.10.2': resolution: {integrity: sha512-1+tGLyG0u5YYy0lev4ck7/0sd8xJ9SZde0dLut7qLDPZV5WVTV8x6OxNXUne/PGuHZyO1vK+txPQzzHOyXHGSw==} cpu: [arm64] os: [win32] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-codegen/binding-win32-x64@0.10.2': resolution: {integrity: sha512-8a2SExRohRbwC0MY4VpOF0/RSckrJ2ASZqAor5/RYSJJaeadR93n10gZzcKT6pY9ukiSOIZCRKVRD2tH73T0qA==} cpu: [x64] os: [win32] + deprecated: yuku-codegen is pure JavaScript since 0.14 '@yuku-parser/binding-android-arm64@0.10.2': resolution: {integrity: sha512-2VPBU9fRGRAQ2xPAvghnec3oou5Nrxm2Bezhf+13UMspAxQSkF/32r+ySKXSwIPA5/RivumDJDxAxc301Sgicw==} cpu: [arm64] os: [android] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-darwin-arm64@0.10.2': resolution: {integrity: sha512-LD+PMZE51tCYTOss5HBkm3/AE39MvcMDBfWJx7A4yDcjfNbAQDnHZKtzSOuqrswx+TQHY0ws5xn6+fWOwtmfBA==} cpu: [arm64] os: [darwin] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-darwin-x64@0.10.2': resolution: {integrity: sha512-mmZ8cND+AoIIMRERyMinlg5ApHxP23B9jH2B5wT7T+dliPa9rubLxneB/SUjFwyUjGaFnB5G7t4YvpfbO5zbkQ==} cpu: [x64] os: [darwin] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-freebsd-x64@0.10.2': resolution: {integrity: sha512-gVIjaaIddbRfAhHlC8N809wQWml7mxfSVnzaLtzGXObTeFTPAg/YVnQXt1UOhPM1ah5eG/8Y0RUlNpB4GVe7eQ==} cpu: [x64] os: [freebsd] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-linux-arm-gnu@0.10.2': resolution: {integrity: sha512-q/XPPQQAPdlw05aPj30ygBhekmQryGOwxVraBgApjKK8yY1kNQgqq6XCYLF1WHSee+lhxclrTO7W0/bt7dR1GA==} cpu: [arm] os: [linux] libc: [glibc] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-linux-arm-musl@0.10.2': resolution: {integrity: sha512-A+Cb0I1hFF4wilTQpWs79k1aNnj4B2tkrHx3zsuUNF9BtVY2zPZ4yeQEM/zjXrS/qJlNMZVK9NrWJjwdpnTrfg==} cpu: [arm] os: [linux] libc: [musl] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-linux-arm64-gnu@0.10.2': resolution: {integrity: sha512-aGNSzqIqqphFwAdIFwVvKIyXD1Iy3CxrEJVIZAT87Ecyi4vCmmDD2v2l9h+Gd3/wSy3JZlOI792LJbKAjyy9rQ==} cpu: [arm64] os: [linux] libc: [glibc] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-linux-arm64-musl@0.10.2': resolution: {integrity: sha512-Ddl1sF0rtuCXyHGSOV6dcmdx+ETv1iD+IVFqQuOjzkJZWclxJxdBWX6ZJMRtTiGqGUTbqLEKiTXxpR/Bvqk+2A==} cpu: [arm64] os: [linux] libc: [musl] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-linux-x64-gnu@0.10.2': resolution: {integrity: sha512-/nlcpR6IF5U+0m5L9wvAIXeQa2DT+BXuvqKDsTcOTlcc0B4dHNyqE5hTXsS4hAyimpy2ZK8A1zMNF5hTrjg2cg==} cpu: [x64] os: [linux] libc: [glibc] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-linux-x64-musl@0.10.2': resolution: {integrity: sha512-GX80dxTQD/M/OryyuxJcFzFENzry3cDFPvCFTyWogNWQH3fSHfMrNfpwpl1YzMos1eV9NygK5GSDG7VArQlb4w==} cpu: [x64] os: [linux] libc: [musl] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-win32-arm64@0.10.2': resolution: {integrity: sha512-agePQBV4VHewiGU0ACSjscZ/hJd283f9JfAF19Gf1rI5+wy5tTgx4GS36i0b3xim15AQ4RCpDRosEvhLZ4zAOw==} cpu: [arm64] os: [win32] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-parser/binding-win32-x64@0.10.2': resolution: {integrity: sha512-s8//CMpgL5+y1lvDCdyh1rwGI5+ytDJywFJRe1vnhI7n0j+caxshNucurikYLLVeQ2SYFex6aPrzgQxkabBQRA==} cpu: [x64] os: [win32] + deprecated: yuku-parser runs on yuku-core since 0.14 '@yuku-toolchain/types@0.10.2': resolution: {integrity: sha512-sSeo4SSSToiS+sSD+bwn/s94EEcaLJ7tG5LCp8gFYC1G5VzxzX7fqB6m9RU1yMD8KTpu6zdU/I1NlQf8hVBJ9Q==} @@ -1043,8 +1067,8 @@ packages: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} - sv@0.17.1: - resolution: {integrity: sha512-h8kB4mIpxiZKPd8CxxpMjBjGXGYlI5KKAwIFccXxWYJEUO9dVomvVSZGnbWQV1+dN+KJ2kzvsVjpJ+aTrYQ0xg==} + sv@1.0.1: + resolution: {integrity: sha512-w0Us7C+4JsTLVW42NjMnyFBIeEEjwSEv2URDThUtv53jHYe1k7eaqXrP23JoeGcCxfEL86TVCWfuI8pqJjnbRQ==} hasBin: true thread-stream@0.15.2: @@ -1415,7 +1439,7 @@ snapshots: '@simple-libs/stream-utils@1.2.0': {} - '@sveltejs/sv-utils@0.3.3': {} + '@sveltejs/sv-utils@1.0.0': {} '@types/chai@5.2.3': dependencies: @@ -2024,9 +2048,9 @@ snapshots: dependencies: has-flag: 3.0.0 - sv@0.17.1: + sv@1.0.1: dependencies: - '@sveltejs/sv-utils': 0.3.3 + '@sveltejs/sv-utils': 1.0.0 thread-stream@0.15.2: dependencies: diff --git a/tests/compatibility.test.mjs b/tests/compatibility.test.mjs new file mode 100644 index 0000000..de59087 --- /dev/null +++ b/tests/compatibility.test.mjs @@ -0,0 +1,95 @@ +import assert from 'node:assert/strict' +import fs from 'node:fs' +import path from 'node:path' +import { test } from 'node:test' +import { fileURLToPath } from 'node:url' +import { add } from 'sv' +// Exercise the published entry point, including the bundled sv-utils. +import addon from '@msw/sveltekit' + +const testDirectory = fileURLToPath( + new URL('../.test-output/', import.meta.url), +) +fs.mkdirSync(testDirectory, { recursive: true }) +process.env.MSW_VERSION = '3.0.0' + +for (const extension of ['js', 'ts']) { + for (const environments of [['browser'], ['node'], ['browser', 'node']]) { + test(`published add-on: ${extension}, ${environments.join('+')}`, async (t) => { + const cwd = fs.mkdtempSync(path.join(testDirectory, 'compatibility-')) + t.after(() => fs.rmSync(cwd, { recursive: true, force: true })) + + fs.mkdirSync(path.join(cwd, 'src'), { recursive: true }) + fs.writeFileSync( + path.join(cwd, 'package.json'), + JSON.stringify({ + name: 'compatibility-fixture', + type: 'module', + devDependencies: { '@sveltejs/kit': '^2.62.0', svelte: '^5.0.0' }, + }), + ) + fs.writeFileSync( + path.join(cwd, extension === 'ts' ? 'tsconfig.json' : 'jsconfig.json'), + '{}', + ) + fs.writeFileSync( + path.join(cwd, 'svelte.config.js'), + 'export default {};\n', + ) + fs.writeFileSync( + path.join(cwd, `vite.config.${extension}`), + "import { sveltekit } from '@sveltejs/kit/vite';\nexport default { plugins: [sveltekit()] };\n", + ) + + const options = { + cwd, + addons: { [addon.id]: addon }, + options: { [addon.id]: { environments } }, + packageManager: 'pnpm', + } + await add(options) + + const read = (file) => fs.readFileSync(path.join(cwd, file), 'utf8') + const files = [ + 'package.json', + `vite.config.${extension}`, + 'src/app.d.ts', + `src/mocks/handlers.${extension}`, + ] + assert.equal( + JSON.parse(read('package.json')).devDependencies.msw, + '3.0.0', + ) + assert.match(read(`vite.config.${extension}`), /msw\(\)/) + assert.match(read(`vite.config.${extension}`), /from ['"]msw\/vite['"]/) + assert.match(read('src/app.d.ts'), /types="msw\/vite\/client"/) + assert.match(read(`src/mocks/handlers.${extension}`), /http\.get\(/) + + for (const [environment, target] of [ + ['browser', 'client'], + ['node', 'server'], + ]) { + const file = `src/hooks.${target}.${extension}` + assert.equal( + fs.existsSync(path.join(cwd, file)), + environments.includes(environment), + ) + if (!environments.includes(environment)) continue + + files.push(file) + assert.match(read(file), /export const init = async/) + assert.match(read(file), /if \(import\.meta\.env\.DEV\)/) + assert.match(read(file), /await import\(['"]virtual:msw['"]\)/) + assert.match(read(file), /await network\.enable\(\)/) + } + + const before = files.map(read) + await add(options) + assert.deepEqual( + files.map(read), + before, + 'Reapplying the add-on must be idempotent', + ) + }) + } +} From 3f60069df071ac7f382e0bb737c5f2e401957434 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Mon, 5 Oct 2026 09:58:35 +0200 Subject: [PATCH 2/2] fix: use proper test setup --- package.json | 2 +- ...ibility.test.mjs => compatibility.test.js} | 51 ++++++++++--------- vitest.compatibility.config.js | 12 +++++ vitest.config.js | 2 +- 4 files changed, 42 insertions(+), 25 deletions(-) rename tests/{compatibility.test.mjs => compatibility.test.js} (63%) create mode 100644 vitest.compatibility.config.js diff --git a/package.json b/package.json index 6de9b76..55ee7f2 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "format": "prettier --write .", "format:check": "prettier --check .", "test": "vitest run", - "test:compatibility": "node --test tests/compatibility.test.mjs", + "test:compatibility": "vitest run --config vitest.compatibility.config.js", "release": "release publish" }, "exports": { diff --git a/tests/compatibility.test.mjs b/tests/compatibility.test.js similarity index 63% rename from tests/compatibility.test.mjs rename to tests/compatibility.test.js index de59087..1d7da43 100644 --- a/tests/compatibility.test.mjs +++ b/tests/compatibility.test.js @@ -1,7 +1,6 @@ -import assert from 'node:assert/strict' import fs from 'node:fs' import path from 'node:path' -import { test } from 'node:test' +import { expect, test } from 'vitest' import { fileURLToPath } from 'node:url' import { add } from 'sv' // Exercise the published entry point, including the bundled sv-utils. @@ -11,13 +10,16 @@ const testDirectory = fileURLToPath( new URL('../.test-output/', import.meta.url), ) fs.mkdirSync(testDirectory, { recursive: true }) -process.env.MSW_VERSION = '3.0.0' for (const extension of ['js', 'ts']) { - for (const environments of [['browser'], ['node'], ['browser', 'node']]) { + for (const environments of [ + [/** @type {const} */ ('browser')], + [/** @type {const} */ ('node')], + [/** @type {const} */ ('browser'), /** @type {const} */ ('node')], + ]) { test(`published add-on: ${extension}, ${environments.join('+')}`, async (t) => { const cwd = fs.mkdtempSync(path.join(testDirectory, 'compatibility-')) - t.after(() => fs.rmSync(cwd, { recursive: true, force: true })) + t.onTestFinished(() => fs.rmSync(cwd, { recursive: true, force: true })) fs.mkdirSync(path.join(cwd, 'src'), { recursive: true }) fs.writeFileSync( @@ -41,6 +43,9 @@ for (const extension of ['js', 'ts']) { "import { sveltekit } from '@sveltejs/kit/vite';\nexport default { plugins: [sveltekit()] };\n", ) + /** + * @type {Parameters[0]} + */ const options = { cwd, addons: { [addon.id]: addon }, @@ -49,6 +54,9 @@ for (const extension of ['js', 'ts']) { } await add(options) + /** + * @param {string} file + */ const read = (file) => fs.readFileSync(path.join(cwd, file), 'utf8') const files = [ 'package.json', @@ -56,40 +64,37 @@ for (const extension of ['js', 'ts']) { 'src/app.d.ts', `src/mocks/handlers.${extension}`, ] - assert.equal( - JSON.parse(read('package.json')).devDependencies.msw, - '3.0.0', + expect(JSON.parse(read('package.json')).devDependencies.msw).toBe( + process.env.MSW_VERSION, ) - assert.match(read(`vite.config.${extension}`), /msw\(\)/) - assert.match(read(`vite.config.${extension}`), /from ['"]msw\/vite['"]/) - assert.match(read('src/app.d.ts'), /types="msw\/vite\/client"/) - assert.match(read(`src/mocks/handlers.${extension}`), /http\.get\(/) + expect(read(`vite.config.${extension}`)).toMatch(/msw\(\)/) + expect(read(`vite.config.${extension}`)).toMatch(/from ['"]msw\/vite['"]/) + expect(read('src/app.d.ts')).toMatch(/types="msw\/vite\/client"/) + expect(read(`src/mocks/handlers.${extension}`)).toMatch(/http\.get\(/) - for (const [environment, target] of [ + for (const [environment, target] of /** @type {const} */ ([ ['browser', 'client'], ['node', 'server'], - ]) { + ])) { const file = `src/hooks.${target}.${extension}` - assert.equal( - fs.existsSync(path.join(cwd, file)), + expect(fs.existsSync(path.join(cwd, file))).toBe( environments.includes(environment), ) if (!environments.includes(environment)) continue files.push(file) - assert.match(read(file), /export const init = async/) - assert.match(read(file), /if \(import\.meta\.env\.DEV\)/) - assert.match(read(file), /await import\(['"]virtual:msw['"]\)/) - assert.match(read(file), /await network\.enable\(\)/) + expect(read(file)).toMatch(/export const init = async/) + expect(read(file)).toMatch(/if \(import\.meta\.env\.DEV\)/) + expect(read(file)).toMatch(/await import\(['"]virtual:msw['"]\)/) + expect(read(file)).toMatch(/await network\.enable\(\)/) } const before = files.map(read) await add(options) - assert.deepEqual( + expect( files.map(read), - before, 'Reapplying the add-on must be idempotent', - ) + ).toEqual(before) }) } } diff --git a/vitest.compatibility.config.js b/vitest.compatibility.config.js new file mode 100644 index 0000000..24dc534 --- /dev/null +++ b/vitest.compatibility.config.js @@ -0,0 +1,12 @@ +import { defineConfig } from 'vitest/config' +import config from './vitest.config.js' + +export default defineConfig({ + test: { + ...config.test, + include: ['tests/compatibility.test.js'], + exclude: [], + // Older CLI versions don't provide the current sv/testing setup API. + globalSetup: [], + }, +}) diff --git a/vitest.config.js b/vitest.config.js index 3f81d66..8b62c38 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -8,7 +8,7 @@ export default defineConfig({ MSW_VERSION: '3.0.0', }, include: ['tests/**/*.test.{js,ts}'], - exclude: ['tests/setup/*'], + exclude: ['tests/setup/*', 'tests/compatibility.test.js'], testTimeout: ONE_MINUTE * 3, hookTimeout: ONE_MINUTE * 3, globalSetup: ['tests/setup/global.js'],