diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 49cabba..0000000 --- a/.babelrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "presets": [["@babel/preset-env", { "targets": { "node": "8" } }]], - "plugins": [ - ["@babel/plugin-transform-modules-commonjs", { "allowTopLevelThis": true }] - ] -} diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 51% rename from .eslintrc.js rename to .eslintrc.cjs index 4ef4d17..97b6929 100644 --- a/.eslintrc.js +++ b/.eslintrc.cjs @@ -3,29 +3,19 @@ module.exports = { env: { browser: true, es6: true, - jest: true + 'vitest-globals/env': true }, - parser: 'babel-eslint', - extends: [ - 'standard' - ], - plugins: [ - 'svelte3', - 'simple-import-sort' - ], + extends: ['standard', 'plugin:vitest-globals/recommended'], + plugins: ['svelte', 'simple-import-sort'], rules: { 'max-len': ['warn', { code: 100 }], 'simple-import-sort/imports': 'error', - 'no-multiple-empty-lines': ['error', { max: 2, maxBOF: 2, maxEOF: 0 }] + 'no-multiple-empty-lines': ['error', { max: 2, maxBOF: 2, maxEOF: 0 }], }, overrides: [ - { - files: ['**/*.svelte'], - processor: 'svelte3/svelte3' - } ], parserOptions: { - ecmaVersion: 2019, - sourceType: 'module' - } + ecmaVersion: 2022, + sourceType: 'module', + }, } diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 752e5ee..5204198 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,18 +6,19 @@ on: pull_request: branches: [main] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: main: # ignore all-contributors PRs if: ${{ !contains(github.head_ref, 'all-contributors') }} strategy: matrix: - node: [10, 12, 14, 16] + node: [16, 18, 20] runs-on: ubuntu-latest steps: - - name: 🛑 Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.9.1 - - name: ⬇️ Checkout repo uses: actions/checkout@v3 @@ -40,14 +41,10 @@ jobs: release: needs: main runs-on: ubuntu-latest - if: - ${{ github.repository == 'testing-library/svelte-testing-library' && + if: ${{ github.repository == 'testing-library/svelte-testing-library' && contains('refs/heads/main,refs/heads/beta,refs/heads/next,refs/heads/alpha', github.ref) && github.event_name == 'push' }} steps: - - name: 🛑 Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.9.1 - - name: ⬇️ Checkout repo uses: actions/checkout@v3 @@ -61,9 +58,6 @@ jobs: with: useLockFile: false - - name: 🏗 Run build script - run: npm run build - - name: 🚀 Release uses: cycjimmy/semantic-release-action@v2 with: diff --git a/README.md b/README.md index b0633dd..0808979 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,7 @@ /> -

Simple and complete Svelte testing utilities that encourage good testing -practices.

+

Simple and complete Svelte testing utilities that encourage good testing practices.

[**Read The Docs**](https://testing-library.com/docs/svelte-testing-library/intro) | [Edit the docs](https://github.com/alexkrolick/testing-library-docs) diff --git a/dont-clean-up-after-each.js b/dont-clean-up-after-each.js deleted file mode 100644 index 3facae5..0000000 --- a/dont-clean-up-after-each.js +++ /dev/null @@ -1 +0,0 @@ -process.env.STL_SKIP_AUTO_CLEANUP = true diff --git a/package.json b/package.json index 64837b7..62be775 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "@testing-library/svelte", "version": "0.0.0-semantically-released", "description": "Simple and complete Svelte testing utilities that encourage good testing practices.", - "main": "dist/index.js", + "exports": "src/index.js", + "type": "module", "types": "types/index.d.ts", "license": "MIT", "homepage": "https://github.com/testing-library/svelte-testing-library#readme", @@ -29,57 +30,50 @@ "e2e" ], "files": [ - "dist", - "dont-cleanup-after-each.js", - "pure.js", + "src/", "types/index.d.ts" ], "scripts": { "toc": "doctoc README.md", "lint": "eslint src --fix", - "clean": "rimraf dist", - "build": "npm run clean && babel src --out-dir dist --ignore '**/__tests__/**'", - "test": "jest src", + "test": "vitest run src", "test:watch": "npm run test -- --watch", "test:update": "npm run test -- --updateSnapshot --coverage", "setup": "npm install && npm run validate", - "validate": "npm run clean && npm-run-all lint test build", + "validate": "npm-run-all lint test", "contributors:add": "all-contributors add", "contributors:generate": "all-contributors generate" }, "peerDependencies": { - "svelte": "3.x" + "svelte": "^3 || ^4" }, "dependencies": { "@testing-library/dom": "^8.1.0" }, "devDependencies": { - "@babel/cli": "^7.6.2", - "@babel/core": "^7.6.2", - "@babel/plugin-transform-modules-commonjs": "^7.6.0", - "@babel/preset-env": "^7.6.2", "@commitlint/cli": "^13.1.0", "@commitlint/config-conventional": "^13.1.0", - "@testing-library/jest-dom": "^5.0.2", - "@types/jest": "^27.0.0", + "@sveltejs/vite-plugin-svelte": "^2.4.1", + "@testing-library/jest-dom": "^5.16.5", + "@vitest/coverage-c8": "^0.32.0", "all-contributors-cli": "^6.9.0", - "babel-eslint": "^10.0.3", - "babel-jest": "^27.0.6", "doctoc": "^2.0.0", - "eslint": "^7.2.0", - "eslint-config-standard": "^16.0.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-node": "^11.0.0", - "eslint-plugin-promise": "^5.1.0", - "eslint-plugin-simple-import-sort": "^7.0.0", - "eslint-plugin-svelte3": "^3.0.0", + "eslint": "^8.42.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^16.0.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-simple-import-sort": "^10.0.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-svelte": "^2.30.0", + "eslint-plugin-vitest-globals": "^1.3.1", "husky": "^7.0.1", - "jest": "^27.0.0", + "jsdom": "^22.1.0", "lint-staged": "^11.1.1", "npm-run-all": "^4.1.5", "prettier": "^2.0.1", - "svelte": "^3.0.0", - "svelte-jester": "^2.1.4" + "svelte": "^3.59.1", + "vite": "^4.3.9", + "vitest": "^0.32.0" }, "husky": { "hooks": { @@ -107,26 +101,5 @@ "extends": [ "@commitlint/config-conventional" ] - }, - "jest": { - "testPathIgnorePatterns": [ - "src/__tests__/fixtures" - ], - "collectCoverageFrom": [ - "src/*.js" - ], - "setupFilesAfterEnv": [ - "@testing-library/jest-dom/extend-expect" - ], - "testEnvironment": "jsdom", - "transform": { - "^.+\\.js$": "babel-jest", - "^.+\\.svelte$": "svelte-jester", - "^.+\\.html$": "svelte-jester" - }, - "moduleFileExtensions": [ - "js", - "svelte" - ] } } diff --git a/pure.js b/pure.js deleted file mode 100644 index 7466726..0000000 --- a/pure.js +++ /dev/null @@ -1,2 +0,0 @@ -// Makes it so people can import from '@testing-library/svelte/pure' -module.exports = require('./dist/pure') diff --git a/src/__tests__/__snapshots__/auto-cleanup-skip.test.js.snap b/src/__tests__/__snapshots__/auto-cleanup-skip.test.js.snap index 8daef3b..2631c86 100644 --- a/src/__tests__/__snapshots__/auto-cleanup-skip.test.js.snap +++ b/src/__tests__/__snapshots__/auto-cleanup-skip.test.js.snap @@ -1,3 +1,3 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`auto-cleanup-skip second 1`] = `"

Hello world!

we have undefined
"`; +exports[`auto-cleanup-skip > second 1`] = `""`; diff --git a/src/__tests__/__snapshots__/render.test.js.snap b/src/__tests__/__snapshots__/render.test.js.snap index f89402e..a31cf2e 100644 --- a/src/__tests__/__snapshots__/render.test.js.snap +++ b/src/__tests__/__snapshots__/render.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`render should accept svelte component options 1`] = ` +exports[`render > should accept svelte component options 1`] = `

Button +
diff --git a/src/__tests__/act.test.js b/src/__tests__/act.test.js index 6ab7796..6eafc0d 100644 --- a/src/__tests__/act.test.js +++ b/src/__tests__/act.test.js @@ -1,5 +1,7 @@ +import { beforeEach, describe, expect, test } from 'vitest' + import { act, fireEvent, render as stlRender } from '..' -import Comp from './fixtures/Comp' +import Comp from './fixtures/Comp.svelte' describe('act', () => { let props @@ -36,9 +38,10 @@ describe('act', () => { }) test('accepts async functions', async () => { - const sleep = (ms) => new Promise(resolve => { - setTimeout(() => resolve(), ms) - }) + const sleep = (ms) => + new Promise((resolve) => { + setTimeout(() => resolve(), ms) + }) const { getByText } = render() const button = getByText('Button') diff --git a/src/__tests__/auto-cleanup-skip.test.js b/src/__tests__/auto-cleanup-skip.test.js index df54d43..265f55b 100644 --- a/src/__tests__/auto-cleanup-skip.test.js +++ b/src/__tests__/auto-cleanup-skip.test.js @@ -1,11 +1,13 @@ -import Comp from './fixtures/Comp' +import { beforeAll, describe, expect, test } from 'vitest' + +import Comp from './fixtures/Comp.svelte' describe('auto-cleanup-skip', () => { let render - beforeAll(() => { + beforeAll(async () => { process.env.STL_SKIP_AUTO_CLEANUP = 'true' - const stl = require('..') + const stl = await import('..') render = stl.render }) diff --git a/src/__tests__/auto-cleanup.test.js b/src/__tests__/auto-cleanup.test.js index 92104cd..349ee39 100644 --- a/src/__tests__/auto-cleanup.test.js +++ b/src/__tests__/auto-cleanup.test.js @@ -1,5 +1,7 @@ +import { describe, expect, test } from 'vitest' + import { render } from '..' -import Comp from './fixtures/Comp' +import Comp from './fixtures/Comp.svelte' describe('auto-cleanup', () => { // This just verifies that by importing STL in an diff --git a/src/__tests__/debug.test.js b/src/__tests__/debug.test.js index ca646bc..1072a0f 100644 --- a/src/__tests__/debug.test.js +++ b/src/__tests__/debug.test.js @@ -1,11 +1,12 @@ import { prettyDOM } from '@testing-library/dom' +import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' import { render } from '..' -import Comp from './fixtures/Comp' +import Comp from './fixtures/Comp.svelte' describe('debug', () => { beforeEach(() => { - jest.spyOn(console, 'log').mockImplementation(() => {}) + vi.spyOn(console, 'log').mockImplementation(() => { }) }) afterEach(() => { diff --git a/src/__tests__/events.test.js b/src/__tests__/events.test.js index 60d21c4..fccf990 100644 --- a/src/__tests__/events.test.js +++ b/src/__tests__/events.test.js @@ -1,5 +1,7 @@ +import { describe, expect, test } from 'vitest' + import { fireEvent, render } from '..' -import Comp from './fixtures/Comp' +import Comp from './fixtures/Comp.svelte' describe('events', () => { test('state changes are flushed after firing an event', async () => { diff --git a/src/__tests__/fixtures/Comp.svelte b/src/__tests__/fixtures/Comp.svelte index 523d2d3..ec04c05 100644 --- a/src/__tests__/fixtures/Comp.svelte +++ b/src/__tests__/fixtures/Comp.svelte @@ -1,3 +1,5 @@ + + - -

Hello {name}!

we have {contextName}
+ + diff --git a/src/__tests__/fixtures/Comp.html b/src/__tests__/fixtures/Comp2.svelte similarity index 59% rename from src/__tests__/fixtures/Comp.html rename to src/__tests__/fixtures/Comp2.svelte index d6dc7f4..104e81a 100644 --- a/src/__tests__/fixtures/Comp.html +++ b/src/__tests__/fixtures/Comp2.svelte @@ -1,10 +1,10 @@ diff --git a/src/__tests__/multi-base.test.js b/src/__tests__/multi-base.test.js index a928fe4..39f28d1 100644 --- a/src/__tests__/multi-base.test.js +++ b/src/__tests__/multi-base.test.js @@ -1,28 +1,38 @@ +import { describe, expect, test } from 'vitest' + import { render } from '..' -import Comp from './fixtures/Comp' +import Comp from './fixtures/Comp.svelte' describe('multi-base', () => { const treeA = document.createElement('div') const treeB = document.createElement('div') test('container isolates trees from one another', () => { - const { getByText: getByTextInA } = render(Comp, { - target: treeA, - props: { - name: 'Tree A' + const { getByText: getByTextInA } = render( + Comp, + { + target: treeA, + props: { + name: 'Tree A' + } + }, + { + container: treeA } - }, { - container: treeA - }) + ) - const { getByText: getByTextInB } = render(Comp, { - target: treeB, - props: { - name: 'Tree B' + const { getByText: getByTextInB } = render( + Comp, + { + target: treeB, + props: { + name: 'Tree B' + } + }, + { + container: treeB } - }, { - container: treeB - }) + ) expect(() => getByTextInA('Hello Tree A!')).not.toThrow() expect(() => getByTextInB('Hello Tree A!')).toThrow() diff --git a/src/__tests__/render.test.js b/src/__tests__/render.test.js index 3fc6d2f..6beb984 100644 --- a/src/__tests__/render.test.js +++ b/src/__tests__/render.test.js @@ -1,6 +1,8 @@ +import { beforeEach, describe, expect, test } from 'vitest' + import { act, render as stlRender } from '..' -import Comp from './fixtures/Comp' -import CompDefault from './fixtures/Comp.html' +import Comp from './fixtures/Comp.svelte' +import CompDefault from './fixtures/Comp2.svelte' describe('render', () => { let props @@ -9,13 +11,13 @@ describe('render', () => { return stlRender(Comp, { target: document.body, props, - ...additional, + ...additional }) } beforeEach(() => { props = { - name: 'World', + name: 'World' } }) @@ -66,7 +68,7 @@ describe('render', () => { target, anchor: div, props: { name: 'World' }, - context: new Map([['name', 'context']]), + context: new Map([['name', 'context']]) }) expect(container).toMatchSnapshot() }) @@ -92,9 +94,9 @@ describe('render', () => { test("accept the 'context' option", () => { const { getByText } = stlRender(Comp, { props: { - name: 'Universe', + name: 'Universe' }, - context: new Map([['name', 'context']]), + context: new Map([['name', 'context']]) }) expect(getByText('we have context')).toBeInTheDocument() diff --git a/src/__tests__/rerender.test.js b/src/__tests__/rerender.test.js index 2e1b423..e3eddb2 100644 --- a/src/__tests__/rerender.test.js +++ b/src/__tests__/rerender.test.js @@ -1,5 +1,10 @@ +/** + * @jest-environment jsdom + */ +import { describe, expect, test } from 'vitest' + import { render } from '..' -import Comp from './fixtures/Comp' +import Comp from './fixtures/Comp.svelte' describe('rerender', () => { test('mounts new component successfully', () => { @@ -15,7 +20,9 @@ describe('rerender', () => { const { rerender, component } = render(Comp, { props: { name: '' } }) - component.$$.on_destroy.push(() => { isDestroyed = true }) + component.$$.on_destroy.push(() => { + isDestroyed = true + }) rerender({ props: { name: '' } }) expect(isDestroyed).toBeTruthy() }) diff --git a/src/__tests__/unmount.test.js b/src/__tests__/unmount.test.js index af41044..86a29dd 100644 --- a/src/__tests__/unmount.test.js +++ b/src/__tests__/unmount.test.js @@ -1,9 +1,11 @@ +import { describe, expect, test, vi } from 'vitest' + import { act, fireEvent, render } from '..' -import Stopwatch from './fixtures/Stopwatch' +import Stopwatch from './fixtures/Stopwatch.svelte' describe('unmount', () => { test('unmounts component successfully', async () => { - console.warn = jest.fn() + console.warn = vi.fn() const { unmount, getByText, container } = render(Stopwatch) @@ -21,7 +23,7 @@ describe('unmount', () => { }) test('destroying component directly and calling unmount does not log warning', async () => { - console.warn = jest.fn() + console.warn = vi.fn() const { unmount, component } = render(Stopwatch) diff --git a/src/pure.js b/src/pure.js index f9f1474..04d3cb0 100644 --- a/src/pure.js +++ b/src/pure.js @@ -1,7 +1,7 @@ import { fireEvent as dtlFireEvent, getQueriesForElement, - prettyDOM, + prettyDOM } from '@testing-library/dom' import { tick } from 'svelte' @@ -14,7 +14,7 @@ const svelteComponentOptions = [ 'props', 'hydrate', 'intro', - 'context', + 'context' ] const render = ( @@ -56,7 +56,7 @@ const render = ( let component = new ComponentConstructor({ target, - ...checkProps(options), + ...checkProps(options) }) containerCache.add({ container, target, component }) @@ -76,7 +76,7 @@ const render = ( // eslint-disable-next-line no-new component = new ComponentConstructor({ target, - ...checkProps(options), + ...checkProps(options) }) containerCache.add({ container, target, component }) @@ -89,7 +89,7 @@ const render = ( unmount: () => { if (componentCache.has(component)) component.$destroy() }, - ...getQueriesForElement(container, queries), + ...getQueriesForElement(container, queries) } } diff --git a/src/test-setup.js b/src/test-setup.js new file mode 100644 index 0000000..fb76eb6 --- /dev/null +++ b/src/test-setup.js @@ -0,0 +1,11 @@ +import * as matchers from '@testing-library/jest-dom/dist/matchers' +import { afterEach, expect } from 'vitest' + +import { act, cleanup } from './pure' + +expect.extend(matchers) + +afterEach(async () => { + await act() + cleanup() +}) diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 0000000..61eb947 --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,7 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..65a1618 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,11 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()], + test: { + environment: 'jsdom', + setupFiles: ['./src/test-setup.js'], + }, +})