@testing-library/svelte 5.0.1 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -7
- package/package.json +20 -4
- package/src/__tests__/_vitest-setup.js +0 -1
- package/src/vite.js +75 -0
- package/types/types.test-d.ts +65 -0
- package/types/vite.d.ts +12 -0
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<p>Simple and complete Svelte testing utilities that encourage good testing practices.</p>
|
|
14
14
|
|
|
15
15
|
[**Read The Docs**](https://testing-library.com/docs/svelte-testing-library/intro) |
|
|
16
|
-
[Edit the docs](https://github.com/
|
|
16
|
+
[Edit the docs](https://github.com/testing-library/testing-library-docs)
|
|
17
17
|
|
|
18
18
|
<!-- prettier-ignore-start -->
|
|
19
19
|
[![Build Status][build-badge]][build]
|
|
@@ -80,19 +80,42 @@ This library has `peerDependencies` listings for `svelte >= 3`.
|
|
|
80
80
|
You may also be interested in installing `@testing-library/jest-dom` so you can use
|
|
81
81
|
[the custom jest matchers](https://github.com/testing-library/jest-dom).
|
|
82
82
|
|
|
83
|
+
## Setup
|
|
84
|
+
|
|
85
|
+
We recommend using `@testing-library/svelte` with [Vitest][] as your test runner. To get started, add the `svelteTesting` plugin to your Vite or Vitest config.
|
|
86
|
+
|
|
87
|
+
```diff
|
|
88
|
+
// vite.config.js
|
|
89
|
+
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
|
90
|
+
+ import { svelteTesting } from '@testing-library/svelte/vite'
|
|
91
|
+
|
|
92
|
+
export default defineConfig({
|
|
93
|
+
plugins: [
|
|
94
|
+
svelte(),
|
|
95
|
+
+ svelteTesting(),
|
|
96
|
+
]
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
See the [setup docs][] for more detailed setup instructions, including for other test runners like Jest.
|
|
101
|
+
|
|
102
|
+
[vitest]: https://vitest.dev/
|
|
103
|
+
[setup docs]: https://testing-library.com/docs/svelte-testing-library/setup
|
|
104
|
+
|
|
83
105
|
### Svelte 5 support
|
|
84
106
|
|
|
85
107
|
If you are riding the bleeding edge of Svelte 5, you'll need to either
|
|
86
|
-
import from `@testing-library/svelte/svelte5` instead of `@testing-library/svelte`, or
|
|
108
|
+
import from `@testing-library/svelte/svelte5` instead of `@testing-library/svelte`, or add an alias to your `vite.config.js`:
|
|
87
109
|
|
|
88
|
-
```
|
|
89
|
-
export default defineConfig(
|
|
110
|
+
```js
|
|
111
|
+
export default defineConfig({
|
|
112
|
+
plugins: [svelte(), svelteTesting()],
|
|
90
113
|
test: {
|
|
91
114
|
alias: {
|
|
92
|
-
'@testing-library/svelte': '@testing-library/svelte/svelte5'
|
|
93
|
-
}
|
|
115
|
+
'@testing-library/svelte': '@testing-library/svelte/svelte5',
|
|
116
|
+
},
|
|
94
117
|
},
|
|
95
|
-
})
|
|
118
|
+
})
|
|
96
119
|
```
|
|
97
120
|
|
|
98
121
|
## Docs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testing-library/svelte",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Simple and complete Svelte testing utilities that encourage good testing practices.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
},
|
|
15
15
|
"./vitest": {
|
|
16
16
|
"default": "./src/vitest.js"
|
|
17
|
+
},
|
|
18
|
+
"./vite": {
|
|
19
|
+
"types": "./types/vite.d.ts",
|
|
20
|
+
"default": "./src/vite.js"
|
|
17
21
|
}
|
|
18
22
|
},
|
|
19
23
|
"type": "module",
|
|
@@ -43,8 +47,10 @@
|
|
|
43
47
|
"e2e"
|
|
44
48
|
],
|
|
45
49
|
"files": [
|
|
46
|
-
"src
|
|
47
|
-
"types
|
|
50
|
+
"src",
|
|
51
|
+
"types",
|
|
52
|
+
"!*.test-d.ts",
|
|
53
|
+
"!__tests__"
|
|
48
54
|
],
|
|
49
55
|
"scripts": {
|
|
50
56
|
"toc": "doctoc README.md",
|
|
@@ -68,7 +74,17 @@
|
|
|
68
74
|
"contributors:generate": "all-contributors generate"
|
|
69
75
|
},
|
|
70
76
|
"peerDependencies": {
|
|
71
|
-
"svelte": "^3 || ^4 || ^5"
|
|
77
|
+
"svelte": "^3 || ^4 || ^5",
|
|
78
|
+
"vite": "*",
|
|
79
|
+
"vitest": "*"
|
|
80
|
+
},
|
|
81
|
+
"peerDependenciesMeta": {
|
|
82
|
+
"vite": {
|
|
83
|
+
"optional": true
|
|
84
|
+
},
|
|
85
|
+
"vitest": {
|
|
86
|
+
"optional": true
|
|
87
|
+
}
|
|
72
88
|
},
|
|
73
89
|
"dependencies": {
|
|
74
90
|
"@testing-library/dom": "^9.3.1"
|
package/src/vite.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { dirname, join } from 'node:path'
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Vite plugin to configure @testing-library/svelte.
|
|
6
|
+
*
|
|
7
|
+
* Ensures Svelte is imported correctly in tests
|
|
8
|
+
* and that the DOM is cleaned up after each test.
|
|
9
|
+
*
|
|
10
|
+
* @param {{resolveBrowser?: boolean, autoCleanup?: boolean}} options
|
|
11
|
+
* @returns {import('vite').Plugin}
|
|
12
|
+
*/
|
|
13
|
+
export const svelteTesting = ({
|
|
14
|
+
resolveBrowser = true,
|
|
15
|
+
autoCleanup = true,
|
|
16
|
+
} = {}) => ({
|
|
17
|
+
name: 'vite-plugin-svelte-testing-library',
|
|
18
|
+
config: (config) => {
|
|
19
|
+
if (!process.env.VITEST) {
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (resolveBrowser) {
|
|
24
|
+
addBrowserCondition(config)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (autoCleanup) {
|
|
28
|
+
addAutoCleanup(config)
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Add `browser` to `resolve.conditions` before `node`.
|
|
35
|
+
*
|
|
36
|
+
* This ensures that Svelte's browser code is used in tests,
|
|
37
|
+
* rather than its SSR code.
|
|
38
|
+
*
|
|
39
|
+
* @param {import('vitest/config').UserConfig} config
|
|
40
|
+
*/
|
|
41
|
+
const addBrowserCondition = (config) => {
|
|
42
|
+
const resolve = config.resolve ?? {}
|
|
43
|
+
const conditions = resolve.conditions ?? []
|
|
44
|
+
const nodeConditionIndex = conditions.indexOf('node')
|
|
45
|
+
const browserConditionIndex = conditions.indexOf('browser')
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
nodeConditionIndex >= 0 &&
|
|
49
|
+
(nodeConditionIndex < browserConditionIndex || browserConditionIndex < 0)
|
|
50
|
+
) {
|
|
51
|
+
conditions.splice(nodeConditionIndex, 0, 'browser')
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
resolve.conditions = conditions
|
|
55
|
+
config.resolve = resolve
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Add auto-cleanup file to Vitest's setup files.
|
|
60
|
+
*
|
|
61
|
+
* @param {import('vitest/config').UserConfig} config
|
|
62
|
+
*/
|
|
63
|
+
const addAutoCleanup = (config) => {
|
|
64
|
+
const test = config.test ?? {}
|
|
65
|
+
let setupFiles = test.setupFiles ?? []
|
|
66
|
+
|
|
67
|
+
if (typeof setupFiles === 'string') {
|
|
68
|
+
setupFiles = [setupFiles]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
setupFiles.push(join(dirname(fileURLToPath(import.meta.url)), './vitest.js'))
|
|
72
|
+
|
|
73
|
+
test.setupFiles = setupFiles
|
|
74
|
+
config.test = test
|
|
75
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { expectTypeOf } from 'expect-type'
|
|
2
|
+
import type { ComponentProps, SvelteComponent } from 'svelte'
|
|
3
|
+
import { describe, test } from 'vitest'
|
|
4
|
+
|
|
5
|
+
import Simple from '../src/__tests__/fixtures/Simple.svelte'
|
|
6
|
+
import * as subject from './index.js'
|
|
7
|
+
|
|
8
|
+
describe('types', () => {
|
|
9
|
+
test('render is a function that accepts a Svelte component', () => {
|
|
10
|
+
subject.render(Simple, { name: 'Alice', count: 42 })
|
|
11
|
+
subject.render(Simple, { props: { name: 'Alice', count: 42 } })
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
test('rerender is a function that accepts partial props', async () => {
|
|
15
|
+
const { rerender } = subject.render(Simple, { name: 'Alice', count: 42 })
|
|
16
|
+
|
|
17
|
+
await rerender({ name: 'Bob' })
|
|
18
|
+
await rerender({ count: 0 })
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test('invalid prop types are rejected', () => {
|
|
22
|
+
// @ts-expect-error: name should be a string
|
|
23
|
+
subject.render(Simple, { name: 42 })
|
|
24
|
+
|
|
25
|
+
// @ts-expect-error: name should be a string
|
|
26
|
+
subject.render(Simple, { props: { name: 42 } })
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('render result has container and component', () => {
|
|
30
|
+
const result = subject.render(Simple, { name: 'Alice', count: 42 })
|
|
31
|
+
|
|
32
|
+
expectTypeOf(result).toMatchTypeOf<{
|
|
33
|
+
container: HTMLElement
|
|
34
|
+
component: SvelteComponent<{ name: string }>
|
|
35
|
+
debug: (el?: HTMLElement) => void
|
|
36
|
+
rerender: (props: Partial<ComponentProps<Simple>>) => Promise<void>
|
|
37
|
+
unmount: () => void
|
|
38
|
+
}>()
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('render result has default queries', () => {
|
|
42
|
+
const result = subject.render(Simple, { name: 'Alice', count: 42 })
|
|
43
|
+
|
|
44
|
+
expectTypeOf(result.getByRole).parameters.toMatchTypeOf<
|
|
45
|
+
[role: subject.ByRoleMatcher, options?: subject.ByRoleOptions]
|
|
46
|
+
>()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('render result can have custom queries', () => {
|
|
50
|
+
const [getByVibes] = subject.buildQueries(
|
|
51
|
+
(_container: HTMLElement, vibes: string) => {
|
|
52
|
+
throw new Error(`unimplemented ${vibes}`)
|
|
53
|
+
},
|
|
54
|
+
() => '',
|
|
55
|
+
() => ''
|
|
56
|
+
)
|
|
57
|
+
const result = subject.render(
|
|
58
|
+
Simple,
|
|
59
|
+
{ name: 'Alice', count: 42 },
|
|
60
|
+
{ queries: { getByVibes } }
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
expectTypeOf(result.getByVibes).parameters.toMatchTypeOf<[vibes: string]>()
|
|
64
|
+
})
|
|
65
|
+
})
|
package/types/vite.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Plugin } from 'vite'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Vite plugin to configure @testing-library/svelte.
|
|
5
|
+
*
|
|
6
|
+
* Ensures Svelte is imported correctly in tests
|
|
7
|
+
* and that the DOM is cleaned up after each test.
|
|
8
|
+
*/
|
|
9
|
+
export function svelteTesting(options?: {
|
|
10
|
+
resolveBrowser?: boolean
|
|
11
|
+
autoCleanup?: boolean
|
|
12
|
+
}): Plugin
|