@testing-library/svelte 4.1.0 → 4.2.1

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 CHANGED
@@ -38,7 +38,6 @@
38
38
  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
39
39
  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
40
40
 
41
-
42
41
  - [The Problem](#the-problem)
43
42
  - [This Solution](#this-solution)
44
43
  - [Installation](#installation)
@@ -81,6 +80,21 @@ This library has `peerDependencies` listings for `svelte >= 3`.
81
80
  You may also be interested in installing `@testing-library/jest-dom` so you can use
82
81
  [the custom jest matchers](https://github.com/testing-library/jest-dom).
83
82
 
83
+ ### Svelte 5 support
84
+
85
+ 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 have your `vite.config.js` contains the following alias:
87
+
88
+ ```
89
+ export default defineConfig(({ }) => ({
90
+ test: {
91
+ alias: {
92
+ '@testing-library/svelte': '@testing-library/svelte/svelte5'
93
+ }
94
+ },
95
+ }))
96
+ ```
97
+
84
98
  ## Docs
85
99
 
86
100
  See the [**docs**](https://testing-library.com/docs/svelte-testing-library/intro) over at the Testing Library website.
@@ -119,23 +133,29 @@ Thanks goes to these people ([emoji key][emojis]):
119
133
  <!-- prettier-ignore-start -->
120
134
  <!-- markdownlint-disable -->
121
135
  <table>
122
- <tr>
123
- <td align="center"><a href="https://github.com/benmonro"><img src="https://avatars3.githubusercontent.com/u/399236?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ben Monro</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=benmonro" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=benmonro" title="Tests">⚠️</a> <a href="#ideas-benmonro" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=benmonro" title="Documentation">📖</a></td>
124
- <td align="center"><a href="https://twitter.com/EmilTholin"><img src="https://avatars0.githubusercontent.com/u/11573167?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Emil Tholin</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=EmilTholin" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=EmilTholin" title="Tests">⚠️</a> <a href="#ideas-EmilTholin" title="Ideas, Planning, & Feedback">🤔</a></td>
125
- <td align="center"><a href="https://medium.com/@oieduardorabelo"><img src="https://avatars1.githubusercontent.com/u/829902?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eduardo Rabelo</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=oieduardorabelo" title="Tests">⚠️</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=oieduardorabelo" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=oieduardorabelo" title="Documentation">📖</a> <a href="#example-oieduardorabelo" title="Examples">💡</a></td>
126
- <td align="center"><a href="http://timdeschryver.dev"><img src="https://avatars1.githubusercontent.com/u/28659384?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim Deschryver</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=timdeschryver" title="Documentation">📖</a></td>
127
- <td align="center"><a href="http://www.ematipico.com"><img src="https://avatars3.githubusercontent.com/u/602478?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Emanuele</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=ematipico" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=ematipico" title="Tests">⚠️</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=ematipico" title="Documentation">📖</a></td>
128
- <td align="center"><a href="https://github.com/pngwn"><img src="https://avatars1.githubusercontent.com/u/12937446?v=4?s=100" width="100px;" alt=""/><br /><sub><b>pngwn</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=pngwn" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=pngwn" title="Tests">⚠️</a></td>
129
- <td align="center"><a href="https://twitter.com/sebsilbermann"><img src="https://avatars3.githubusercontent.com/u/12292047?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sebastian Silbermann</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=eps1lon" title="Code">💻</a></td>
130
- </tr>
131
- <tr>
132
- <td align="center"><a href="https://github.com/mihar-22"><img src="https://avatars3.githubusercontent.com/u/14304599?s=460&v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rahim Alwer</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=mihar-22" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=mihar-22" title="Documentation">📖</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=mihar-22" title="Tests">⚠️</a> <a href="https://github.com/testing-library/svelte-testing-library/pulls?q=is%3Apr+reviewed-by%3Amihar-22" title="Reviewed Pull Requests">👀</a></td>
133
- <td align="center"><a href="https://github.com/MirrorBytes"><img src="https://avatars3.githubusercontent.com/u/22119469?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bob</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/issues?q=author%3AMirrorBytes" title="Bug reports">🐛</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=MirrorBytes" title="Code">💻</a></td>
134
- <td align="center"><a href="https://github.com/ronmerkin"><img src="https://avatars.githubusercontent.com/u/17492527?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ron Merkin</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=ronmerkin" title="Code">💻</a></td>
135
- <td align="center"><a href="http://www.benmccann.com"><img src="https://avatars.githubusercontent.com/u/322311?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ben McCann</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=benmccann" title="Tests">⚠️</a></td>
136
- <td align="center"><a href="https://johnbowser.dev/"><img src="https://avatars.githubusercontent.com/u/66637570?v=4?s=100" width="100px;" alt=""/><br /><sub><b>John Bowser</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=jgbowser" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=jgbowser" title="Tests">⚠️</a></td>
137
- <td align="center"><a href="https://github.com/ysaskia"><img src="https://avatars.githubusercontent.com/u/1370679?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yoann</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=ysaskia" title="Code">💻</a></td>
138
- </tr>
136
+ <tbody>
137
+ <tr>
138
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/benmonro"><img src="https://avatars3.githubusercontent.com/u/399236?v=4?s=100" width="100px;" alt="Ben Monro"/><br /><sub><b>Ben Monro</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=benmonro" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=benmonro" title="Tests">⚠️</a> <a href="#ideas-benmonro" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=benmonro" title="Documentation">📖</a></td>
139
+ <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/EmilTholin"><img src="https://avatars0.githubusercontent.com/u/11573167?v=4?s=100" width="100px;" alt="Emil Tholin"/><br /><sub><b>Emil Tholin</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=EmilTholin" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=EmilTholin" title="Tests">⚠️</a> <a href="#ideas-EmilTholin" title="Ideas, Planning, & Feedback">🤔</a></td>
140
+ <td align="center" valign="top" width="14.28%"><a href="https://medium.com/@oieduardorabelo"><img src="https://avatars1.githubusercontent.com/u/829902?v=4?s=100" width="100px;" alt="Eduardo Rabelo"/><br /><sub><b>Eduardo Rabelo</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=oieduardorabelo" title="Tests">⚠️</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=oieduardorabelo" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=oieduardorabelo" title="Documentation">📖</a> <a href="#example-oieduardorabelo" title="Examples">💡</a></td>
141
+ <td align="center" valign="top" width="14.28%"><a href="http://timdeschryver.dev"><img src="https://avatars1.githubusercontent.com/u/28659384?v=4?s=100" width="100px;" alt="Tim Deschryver"/><br /><sub><b>Tim Deschryver</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=timdeschryver" title="Documentation">📖</a></td>
142
+ <td align="center" valign="top" width="14.28%"><a href="http://www.ematipico.com"><img src="https://avatars3.githubusercontent.com/u/602478?v=4?s=100" width="100px;" alt="Emanuele"/><br /><sub><b>Emanuele</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=ematipico" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=ematipico" title="Tests">⚠️</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=ematipico" title="Documentation">📖</a></td>
143
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/pngwn"><img src="https://avatars1.githubusercontent.com/u/12937446?v=4?s=100" width="100px;" alt="pngwn"/><br /><sub><b>pngwn</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=pngwn" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=pngwn" title="Tests">⚠️</a></td>
144
+ <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/sebsilbermann"><img src="https://avatars3.githubusercontent.com/u/12292047?v=4?s=100" width="100px;" alt="Sebastian Silbermann"/><br /><sub><b>Sebastian Silbermann</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=eps1lon" title="Code">💻</a></td>
145
+ </tr>
146
+ <tr>
147
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/mihar-22"><img src="https://avatars3.githubusercontent.com/u/14304599?s=460&v=4?s=100" width="100px;" alt="Rahim Alwer"/><br /><sub><b>Rahim Alwer</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=mihar-22" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=mihar-22" title="Documentation">📖</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=mihar-22" title="Tests">⚠️</a> <a href="https://github.com/testing-library/svelte-testing-library/pulls?q=is%3Apr+reviewed-by%3Amihar-22" title="Reviewed Pull Requests">👀</a></td>
148
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/MirrorBytes"><img src="https://avatars3.githubusercontent.com/u/22119469?v=4?s=100" width="100px;" alt="Bob"/><br /><sub><b>Bob</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/issues?q=author%3AMirrorBytes" title="Bug reports">🐛</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=MirrorBytes" title="Code">💻</a></td>
149
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/ronmerkin"><img src="https://avatars.githubusercontent.com/u/17492527?v=4?s=100" width="100px;" alt="Ron Merkin"/><br /><sub><b>Ron Merkin</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=ronmerkin" title="Code">💻</a></td>
150
+ <td align="center" valign="top" width="14.28%"><a href="http://www.benmccann.com"><img src="https://avatars.githubusercontent.com/u/322311?v=4?s=100" width="100px;" alt="Ben McCann"/><br /><sub><b>Ben McCann</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=benmccann" title="Tests">⚠️</a></td>
151
+ <td align="center" valign="top" width="14.28%"><a href="https://johnbowser.dev/"><img src="https://avatars.githubusercontent.com/u/66637570?v=4?s=100" width="100px;" alt="John Bowser"/><br /><sub><b>John Bowser</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=jgbowser" title="Code">💻</a> <a href="https://github.com/testing-library/svelte-testing-library/commits?author=jgbowser" title="Tests">⚠️</a></td>
152
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/ysitbon"><img src="https://avatars.githubusercontent.com/u/1370679?v=4?s=100" width="100px;" alt="Yoann"/><br /><sub><b>Yoann</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=ysitbon" title="Code">💻</a></td>
153
+ <td align="center" valign="top" width="14.28%"><a href="https://techblog.babyl.ca/"><img src="https://avatars.githubusercontent.com/u/19954?v=4?s=100" width="100px;" alt="Yanick Champoux"/><br /><sub><b>Yanick Champoux</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=yanick" title="Code">💻</a></td>
154
+ </tr>
155
+ <tr>
156
+ <td align="center" valign="top" width="14.28%"><a href="https://michael.cousins.io/"><img src="https://avatars.githubusercontent.com/u/2963448?v=4?s=100" width="100px;" alt="Michael Cousins"/><br /><sub><b>Michael Cousins</b></sub></a><br /><a href="https://github.com/testing-library/svelte-testing-library/commits?author=mcous" title="Code">💻</a></td>
157
+ </tr>
158
+ </tbody>
139
159
  </table>
140
160
 
141
161
  <!-- markdownlint-restore -->
@@ -154,8 +174,8 @@ Contributions of any kind welcome!
154
174
 
155
175
  [npm]: https://www.npmjs.com/
156
176
  [node]: https://nodejs.org
157
- [build-badge]: https://img.shields.io/travis/testing-library/svelte-testing-library.svg?style=flat-square
158
- [build]: https://travis-ci.org/testing-library/svelte-testing-library
177
+ [build-badge]: https://img.shields.io/github/actions/workflow/status/testing-library/svelte-testing-library/release.yml?style=flat-square
178
+ [build]: https://github.com/testing-library/svelte-testing-library/actions
159
179
  [coverage-badge]: https://img.shields.io/codecov/c/github/testing-library/svelte-testing-library.svg?style=flat-square
160
180
  [coverage]: https://codecov.io/github/testing-library/svelte-testing-library
161
181
  [version-badge]: https://img.shields.io/npm/v/@testing-library/svelte.svg?style=flat-square
@@ -164,7 +184,7 @@ Contributions of any kind welcome!
164
184
  [npmtrends]: http://www.npmtrends.com/@testing-library/svelte
165
185
  [discord-badge]: https://img.shields.io/discord/723559267868737556.svg?color=7389D8&labelColor=6A7EC2&logo=discord&logoColor=ffffff&style=flat-square
166
186
  [discord]: https://discord.gg/testing-library
167
- [license-badge]: https://img.shields.io/github/license/testing-library/svelte-testing-library?color=b
187
+ [license-badge]: https://img.shields.io/github/license/testing-library/svelte-testing-library?color=b&style=flat-square
168
188
  [license]: https://github.com/testing-library/svelte-testing-library/blob/main/LICENSE
169
189
  [prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
170
190
  [prs]: http://makeapullrequest.com
@@ -187,4 +207,3 @@ Contributions of any kind welcome!
187
207
  [stackoverflow]: https://stackoverflow.com/questions/tagged/svelte-testing-library
188
208
 
189
209
  <!-- prettier-ignore-end -->
190
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testing-library/svelte",
3
- "version": "4.1.0",
3
+ "version": "4.2.1",
4
4
  "description": "Simple and complete Svelte testing utilities that encourage good testing practices.",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -8,6 +8,10 @@
8
8
  "types": "./types/index.d.ts",
9
9
  "default": "./src/index.js"
10
10
  },
11
+ "./svelte5": {
12
+ "types": "./types/index.d.ts",
13
+ "default": "./src/svelte5-index.js"
14
+ },
11
15
  "./vitest": {
12
16
  "default": "./src/vitest.js"
13
17
  }
@@ -44,73 +48,61 @@
44
48
  ],
45
49
  "scripts": {
46
50
  "toc": "doctoc README.md",
47
- "lint": "(prettier . --check || true) && eslint .",
51
+ "lint": "prettier . --check && eslint .",
52
+ "lint:delta": "npm-run-all -p prettier:delta eslint:delta",
53
+ "prettier:delta": "prettier --check `./scripts/changed-files`",
54
+ "eslint:delta": "eslint `./scripts/changed-files`",
48
55
  "format": "prettier . --write && eslint . --fix",
56
+ "format:delta": "npm-run-all format:prettier:delta format:eslint:delta",
57
+ "format:prettier:delta": "prettier --write `./scripts/changed-files`",
58
+ "format:eslint:delta": "eslint --fix `./scripts/changed-files`",
59
+ "setup": "npm install && npm run validate",
49
60
  "test": "vitest run --coverage",
50
61
  "test:watch": "vitest",
51
62
  "test:update": "vitest run --update",
52
- "setup": "npm install && npm run validate",
53
- "validate": "npm-run-all lint test",
63
+ "test:vitest:jsdom": "vitest run --coverage --environment jsdom",
64
+ "test:vitest:happy-dom": "vitest run --coverage --environment happy-dom",
65
+ "types": "svelte-check",
66
+ "validate": "npm-run-all test:vitest:* types",
54
67
  "contributors:add": "all-contributors add",
55
68
  "contributors:generate": "all-contributors generate"
56
69
  },
57
70
  "peerDependencies": {
58
- "svelte": "^3 || ^4"
71
+ "svelte": "^3 || ^4 || ^5"
59
72
  },
60
73
  "dependencies": {
61
74
  "@testing-library/dom": "^9.3.1"
62
75
  },
63
76
  "devDependencies": {
64
- "@commitlint/cli": "^17.6.6",
65
- "@commitlint/config-conventional": "^17.6.6",
66
- "@sveltejs/vite-plugin-svelte": "^2.4.2",
77
+ "@sveltejs/vite-plugin-svelte": "^3.0.2",
67
78
  "@testing-library/jest-dom": "^6.3.0",
68
- "@typescript-eslint/eslint-plugin": "^6.19.1",
69
- "@typescript-eslint/parser": "^6.19.1",
79
+ "@testing-library/user-event": "^14.5.2",
80
+ "@typescript-eslint/eslint-plugin": "6.19.1",
81
+ "@typescript-eslint/parser": "6.19.1",
70
82
  "@vitest/coverage-v8": "^0.33.0",
71
- "all-contributors-cli": "^6.26.0",
83
+ "all-contributors-cli": "^6.26.1",
72
84
  "doctoc": "^2.2.1",
73
- "eslint": "^8.43.0",
74
- "eslint-config-prettier": "^9.1.0",
75
- "eslint-config-standard": "^17.1.0",
76
- "eslint-plugin-import": "^2.27.5",
77
- "eslint-plugin-n": "^16.0.1",
78
- "eslint-plugin-promise": "^6.1.1",
79
- "eslint-plugin-simple-import-sort": "^10.0.0",
80
- "eslint-plugin-svelte": "^2.32.0",
81
- "eslint-plugin-vitest-globals": "^1.3.1",
82
- "husky": "^8.0.3",
85
+ "eslint": "8.56.0",
86
+ "eslint-config-prettier": "9.1.0",
87
+ "eslint-config-standard": "17.1.0",
88
+ "eslint-plugin-import": "2.29.1",
89
+ "eslint-plugin-json-files": "^4.1.0",
90
+ "eslint-plugin-n": "16.6.2",
91
+ "eslint-plugin-promise": "6.1.1",
92
+ "eslint-plugin-simple-import-sort": "10.0.0",
93
+ "eslint-plugin-svelte": "2.35.1",
94
+ "eslint-plugin-vitest-globals": "1.4.0",
95
+ "expect-type": "^0.17.3",
96
+ "happy-dom": "^13.3.1",
83
97
  "jsdom": "^22.1.0",
84
- "lint-staged": "^13.2.3",
85
98
  "npm-run-all": "^4.1.5",
86
- "prettier": "^3.0.0",
87
- "prettier-plugin-svelte": "^3.1.2",
88
- "svelte": "^4.0.1",
99
+ "prettier": "3.2.4",
100
+ "prettier-plugin-svelte": "3.1.2",
101
+ "svelte": "^4.2.10",
102
+ "svelte-check": "^3.6.3",
89
103
  "svelte-jester": "^3.0.0",
90
104
  "typescript": "^5.3.3",
91
- "vite": "^4.3.9",
105
+ "vite": "^5.1.1",
92
106
  "vitest": "^0.33.0"
93
- },
94
- "lint-staged": {
95
- "{README.md,.all-contributorsrc}": [
96
- "npm run toc",
97
- "npm run contributors:generate",
98
- "npx --no-install prettier --write README.md .all-contributorsrc",
99
- "git add README.md .all-contributorsrc"
100
- ],
101
- "src/**/*": [
102
- "npx --no-install vitest related --run"
103
- ],
104
- "*.{js,cjs,ts,svelte,json,yml,yaml}": [
105
- "npx --no-install prettier --check"
106
- ],
107
- "*.{js,cjs,ts,svelte}": [
108
- "npx --no-install eslint"
109
- ]
110
- },
111
- "commitlint": {
112
- "extends": [
113
- "@commitlint/config-conventional"
114
- ]
115
107
  }
116
108
  }
@@ -1,6 +1,6 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`render > should accept svelte component options 1`] = `
3
+ exports[`render > should accept svelte v4 component options 1`] = `
4
4
  <body>
5
5
  <div>
6
6
  <h1
@@ -18,8 +18,31 @@ exports[`render > should accept svelte component options 1`] = `
18
18
  <button>
19
19
  Button
20
20
  </button>
21
- <!--&lt;Comp&gt;-->
22
21
  <div />
23
22
  </div>
24
23
  </body>
25
24
  `;
25
+
26
+ exports[`render > should accept svelte v5 component options 1`] = `
27
+ <body>
28
+
29
+
30
+
31
+ <section>
32
+ <h1
33
+ data-testid="test"
34
+ >
35
+ Hello World!
36
+ </h1>
37
+
38
+ <div>
39
+ we have context
40
+ </div>
41
+
42
+ <button>
43
+ Button
44
+ </button>
45
+
46
+ </section>
47
+ </body>
48
+ `;
@@ -1,6 +1,6 @@
1
1
  import { beforeEach, describe, expect, test } from 'vitest'
2
2
 
3
- import { act, fireEvent, render as stlRender } from '..'
3
+ import { act, fireEvent, render as stlRender } from '@testing-library/svelte'
4
4
  import Comp from './fixtures/Comp.svelte'
5
5
 
6
6
  describe('act', () => {
@@ -7,7 +7,7 @@ describe('auto-cleanup-skip', () => {
7
7
 
8
8
  beforeAll(async () => {
9
9
  process.env.STL_SKIP_AUTO_CLEANUP = 'true'
10
- const stl = await import('..')
10
+ const stl = await import('@testing-library/svelte')
11
11
  render = stl.render
12
12
  })
13
13
 
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, test } from 'vitest'
2
2
 
3
- import { render } from '..'
3
+ import { render } from '@testing-library/svelte'
4
4
  import Comp from './fixtures/Comp.svelte'
5
5
 
6
6
  describe('auto-cleanup', () => {
@@ -0,0 +1,36 @@
1
+ import { describe, expect, test, vi } from 'vitest'
2
+ import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
3
+
4
+ import { act, cleanup, render } from '@testing-library/svelte'
5
+ import Mounter from './fixtures/Mounter.svelte'
6
+
7
+ const onExecuted = vi.fn()
8
+ const onDestroyed = vi.fn()
9
+ const renderSubject = () => render(Mounter, { onExecuted, onDestroyed })
10
+
11
+ describe('cleanup', () => {
12
+ test('cleanup deletes element', async () => {
13
+ renderSubject()
14
+ cleanup()
15
+
16
+ expect(document.body).toBeEmptyDOMElement()
17
+ })
18
+
19
+ test.runIf(SVELTE_VERSION < '5')('cleanup unmounts component', async () => {
20
+ await act(renderSubject)
21
+ cleanup()
22
+
23
+ expect(onDestroyed).toHaveBeenCalledOnce()
24
+ })
25
+
26
+ test('cleanup handles unexpected errors during mount', () => {
27
+ onExecuted.mockImplementation(() => {
28
+ throw new Error('oh no!')
29
+ })
30
+
31
+ expect(renderSubject).toThrowError()
32
+ cleanup()
33
+
34
+ expect(document.body).toBeEmptyDOMElement()
35
+ })
36
+ })
@@ -1,9 +1,10 @@
1
1
  import { expect, test } from 'vitest'
2
2
 
3
- import { render } from '..'
3
+ import { render } from '@testing-library/svelte'
4
4
  import Comp from './fixtures/Context.svelte'
5
+ import { IS_HAPPYDOM, IS_SVELTE_5 } from './utils.js'
5
6
 
6
- test('can set a context', () => {
7
+ test.skipIf(IS_SVELTE_5 && IS_HAPPYDOM)('can set a context', () => {
7
8
  const message = 'Got it'
8
9
 
9
10
  const { getByText } = render(Comp, {
@@ -1,7 +1,7 @@
1
1
  import { prettyDOM } from '@testing-library/dom'
2
2
  import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
3
3
 
4
- import { render } from '..'
4
+ import { render } from '@testing-library/svelte'
5
5
  import Comp from './fixtures/Comp.svelte'
6
6
 
7
7
  describe('debug', () => {
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, test } from 'vitest'
2
2
 
3
- import { fireEvent, render } from '..'
3
+ import { fireEvent, render } from '@testing-library/svelte'
4
4
  import Comp from './fixtures/Comp.svelte'
5
5
 
6
6
  describe('events', () => {
@@ -0,0 +1,19 @@
1
+ <script>
2
+ import { onDestroy, onMount } from 'svelte'
3
+
4
+ export let onExecuted = undefined
5
+ export let onMounted = undefined
6
+ export let onDestroyed = undefined
7
+
8
+ onExecuted?.()
9
+
10
+ onMount(() => {
11
+ onMounted?.()
12
+ })
13
+
14
+ onDestroy(() => {
15
+ onDestroyed?.()
16
+ })
17
+ </script>
18
+
19
+ <button />
@@ -0,0 +1,17 @@
1
+ <script>
2
+ import { onDestroy, onMount } from 'svelte'
3
+
4
+ export let onExecuted = undefined
5
+ export let onMounted = undefined
6
+ export let onDestroyed = undefined
7
+
8
+ export let name = ''
9
+
10
+ onExecuted?.()
11
+
12
+ onMount(() => onMounted?.())
13
+
14
+ onDestroy(() => onDestroyed?.())
15
+ </script>
16
+
17
+ <div data-testid="test">Hello {name}!</div>
@@ -0,0 +1,5 @@
1
+ <script lang="ts">
2
+ export let name: string
3
+ </script>
4
+
5
+ <h1>hello {name}</h1>
@@ -0,0 +1,18 @@
1
+ <script>
2
+ import { blur } from 'svelte/transition'
3
+
4
+ let show = false
5
+ let introDone = false
6
+ </script>
7
+
8
+ <button on:click={() => (show = true)}>Show</button>
9
+
10
+ {#if show}
11
+ <div in:blur={{ duration: 64 }} on:introend={() => (introDone = true)}>
12
+ {#if introDone}
13
+ <p data-testid="intro-done">Done</p>
14
+ {:else}
15
+ <p data-testid="intro-pending">Pending</p>
16
+ {/if}
17
+ </div>
18
+ {/if}
@@ -0,0 +1,34 @@
1
+ import { describe, expect, test, vi } from 'vitest'
2
+
3
+ import { act, render, screen } from '@testing-library/svelte'
4
+ import Mounter from './fixtures/Mounter.svelte'
5
+ import { IS_HAPPYDOM, IS_SVELTE_5 } from './utils.js'
6
+
7
+ const onMounted = vi.fn()
8
+ const onDestroyed = vi.fn()
9
+ const renderSubject = () => render(Mounter, { onMounted, onDestroyed })
10
+
11
+ describe.skipIf(IS_SVELTE_5 && IS_HAPPYDOM)('mount and destroy', () => {
12
+ test('component is mounted', async () => {
13
+ renderSubject()
14
+
15
+ const content = screen.getByRole('button')
16
+
17
+ expect(content).toBeInTheDocument()
18
+ await act()
19
+ expect(onMounted).toHaveBeenCalledOnce()
20
+ })
21
+
22
+ test('component is destroyed', async () => {
23
+ const { unmount } = renderSubject()
24
+
25
+ await act()
26
+ unmount()
27
+
28
+ const content = screen.queryByRole('button')
29
+
30
+ expect(content).not.toBeInTheDocument()
31
+ await act()
32
+ expect(onDestroyed).toHaveBeenCalledOnce()
33
+ })
34
+ })
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, test } from 'vitest'
2
2
 
3
- import { render } from '..'
3
+ import { render } from '@testing-library/svelte'
4
4
  import Comp from './fixtures/Comp.svelte'
5
5
 
6
6
  describe('multi-base', () => {
@@ -1,6 +1,7 @@
1
+ import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
1
2
  import { beforeEach, describe, expect, test } from 'vitest'
2
3
 
3
- import { act, render as stlRender } from '..'
4
+ import { act, render as stlRender } from '@testing-library/svelte'
4
5
  import Comp from './fixtures/Comp.svelte'
5
6
  import CompDefault from './fixtures/Comp2.svelte'
6
7
 
@@ -11,13 +12,13 @@ describe('render', () => {
11
12
  return stlRender(Comp, {
12
13
  target: document.body,
13
14
  props,
14
- ...additional
15
+ ...additional,
15
16
  })
16
17
  }
17
18
 
18
19
  beforeEach(() => {
19
20
  props = {
20
- name: 'World'
21
+ name: 'World',
21
22
  }
22
23
  })
23
24
 
@@ -41,7 +42,9 @@ describe('render', () => {
41
42
  })
42
43
 
43
44
  test('change props with accessors', async () => {
44
- const { component, getByText } = render({ accessors: true })
45
+ const { component, getByText } = render(
46
+ SVELTE_VERSION < '5' ? { accessors: true } : {}
47
+ )
45
48
 
46
49
  expect(getByText('Hello World!')).toBeInTheDocument()
47
50
 
@@ -59,23 +62,41 @@ describe('render', () => {
59
62
  expect(getByText('Hello World!')).toBeInTheDocument()
60
63
  })
61
64
 
62
- test('should accept svelte component options', () => {
63
- const target = document.createElement('div')
64
- const div = document.createElement('div')
65
- document.body.appendChild(target)
66
- target.appendChild(div)
67
- const { container } = stlRender(Comp, {
68
- target,
69
- anchor: div,
70
- props: { name: 'World' },
71
- context: new Map([['name', 'context']])
72
- })
73
- expect(container).toMatchSnapshot()
74
- })
65
+ test.runIf(SVELTE_VERSION < '5')(
66
+ 'should accept svelte v4 component options',
67
+ () => {
68
+ const target = document.createElement('div')
69
+ const div = document.createElement('div')
70
+ document.body.appendChild(target)
71
+ target.appendChild(div)
72
+ const { container } = stlRender(Comp, {
73
+ target,
74
+ anchor: div,
75
+ props: { name: 'World' },
76
+ context: new Map([['name', 'context']]),
77
+ })
78
+ expect(container).toMatchSnapshot()
79
+ }
80
+ )
81
+
82
+ test.runIf(SVELTE_VERSION >= '5')(
83
+ 'should accept svelte v5 component options',
84
+ () => {
85
+ const target = document.createElement('section')
86
+ document.body.appendChild(target)
87
+
88
+ const { container } = stlRender(Comp, {
89
+ target,
90
+ props: { name: 'World' },
91
+ context: new Map([['name', 'context']]),
92
+ })
93
+ expect(container).toMatchSnapshot()
94
+ }
95
+ )
75
96
 
76
97
  test('should throw error when mixing svelte component options and props', () => {
77
98
  expect(() => {
78
- stlRender(Comp, { anchor: '', name: 'World' })
99
+ stlRender(Comp, { props: {}, name: 'World' })
79
100
  }).toThrow(/Unknown options were found/)
80
101
  })
81
102
 
@@ -86,17 +107,15 @@ describe('render', () => {
86
107
  })
87
108
 
88
109
  test('correctly find component constructor on the default property', () => {
89
- const { getByText } = render(CompDefault, { props: { name: 'World' } })
110
+ const { getByText } = stlRender(CompDefault, { props: { name: 'World' } })
90
111
 
91
112
  expect(getByText('Hello World!')).toBeInTheDocument()
92
113
  })
93
114
 
94
115
  test("accept the 'context' option", () => {
95
116
  const { getByText } = stlRender(Comp, {
96
- props: {
97
- name: 'Universe'
98
- },
99
- context: new Map([['name', 'context']])
117
+ props: { name: 'Universe' },
118
+ context: new Map([['name', 'context']]),
100
119
  })
101
120
 
102
121
  expect(getByText('we have context')).toBeInTheDocument()
@@ -1,38 +1,41 @@
1
1
  /**
2
2
  * @jest-environment jsdom
3
3
  */
4
- import { describe, expect, test } from 'vitest'
4
+ import { expect, test, vi } from 'vitest'
5
5
 
6
- import { render } from '..'
7
- import Comp from './fixtures/Comp.svelte'
6
+ import { render, waitFor } from '@testing-library/svelte'
8
7
 
9
- describe('rerender', () => {
10
- test('mounts new component successfully', () => {
11
- const { container, rerender } = render(Comp, { props: { name: 'World 1' } })
8
+ import Comp from './fixtures/Rerender.svelte'
12
9
 
13
- expect(container.firstChild).toHaveTextContent('Hello World 1!')
14
- rerender({ props: { name: 'World 2' } })
15
- expect(container.firstChild).toHaveTextContent('Hello World 2!')
10
+ test('mounts new component successfully', async () => {
11
+ const onMounted = vi.fn()
12
+ const onDestroyed = vi.fn()
13
+
14
+ const { getByTestId, rerender } = render(Comp, {
15
+ props: { name: 'World 1', onMounted, onDestroyed },
16
16
  })
17
17
 
18
- test('destroys old component', () => {
19
- let isDestroyed
18
+ const expectToRender = (content) =>
19
+ waitFor(() => {
20
+ expect(getByTestId('test')).toHaveTextContent(content)
21
+ expect(onMounted).toHaveBeenCalledOnce()
22
+ })
20
23
 
21
- const { rerender, component } = render(Comp, { props: { name: '' } })
24
+ await expectToRender('Hello World 1!')
22
25
 
23
- component.$$.on_destroy.push(() => {
24
- isDestroyed = true
25
- })
26
- rerender({ props: { name: '' } })
27
- expect(isDestroyed).toBeTruthy()
28
- })
26
+ console.warn = vi.fn()
29
27
 
30
- test('destroys old components on multiple rerenders', () => {
31
- const { rerender, queryByText } = render(Comp, { props: { name: 'Neil' } })
28
+ rerender({ props: { name: 'World 2' } })
29
+ await expectToRender('Hello World 2!')
30
+ expect(onDestroyed).not.toHaveBeenCalled()
32
31
 
33
- rerender({ props: { name: 'Alex' } })
34
- expect(queryByText('Hello Neil!')).not.toBeInTheDocument()
35
- rerender({ props: { name: 'Geddy' } })
36
- expect(queryByText('Hello Alex!')).not.toBeInTheDocument()
37
- })
32
+ expect(console.warn).toHaveBeenCalledOnce()
33
+
34
+ console.warn.mockClear()
35
+ onDestroyed.mockReset()
36
+ rerender({ name: 'World 3' })
37
+ await expectToRender('Hello World 3!')
38
+ expect(onDestroyed).not.toHaveBeenCalled()
39
+
40
+ expect(console.warn).not.toHaveBeenCalled()
38
41
  })
@@ -0,0 +1,32 @@
1
+ import { userEvent } from '@testing-library/user-event'
2
+ import { beforeEach, describe, expect, test, vi } from 'vitest'
3
+
4
+ import { IS_JSDOM, IS_SVELTE_5 } from './utils.js'
5
+
6
+ import { render, screen, waitFor } from '@testing-library/svelte'
7
+ import Transitioner from './fixtures/Transitioner.svelte'
8
+
9
+ describe.runIf(!IS_SVELTE_5)('transitions', () => {
10
+ beforeEach(() => {
11
+ if (!IS_JSDOM) return
12
+
13
+ const raf = (fn) => setTimeout(() => fn(new Date()), 16)
14
+ vi.stubGlobal('requestAnimationFrame', raf)
15
+ })
16
+
17
+ test('on:introend', async () => {
18
+ const user = userEvent.setup()
19
+
20
+ render(Transitioner)
21
+ const start = screen.getByRole('button')
22
+ await user.click(start)
23
+
24
+ const pending = screen.getByTestId('intro-pending')
25
+ expect(pending).toBeInTheDocument()
26
+
27
+ await waitFor(() => {
28
+ const done = screen.queryByTestId('intro-done')
29
+ expect(done).toBeInTheDocument()
30
+ })
31
+ })
32
+ })
@@ -0,0 +1,7 @@
1
+ import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
2
+
3
+ export const IS_JSDOM = window.navigator.userAgent.includes('jsdom')
4
+
5
+ export const IS_HAPPYDOM = !IS_JSDOM // right now it's happy or js
6
+
7
+ export const IS_SVELTE_5 = SVELTE_VERSION >= '5'
package/src/index.js CHANGED
@@ -13,3 +13,4 @@ if (typeof afterEach === 'function' && !process.env.STL_SKIP_AUTO_CLEANUP) {
13
13
  }
14
14
 
15
15
  export * from './pure.js'
16
+ export * from '@testing-library/dom'
package/src/pure.js CHANGED
@@ -1,12 +1,14 @@
1
1
  import {
2
2
  fireEvent as dtlFireEvent,
3
3
  getQueriesForElement,
4
- prettyDOM
4
+ prettyDOM,
5
5
  } from '@testing-library/dom'
6
- import { tick } from 'svelte'
6
+ import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
7
+ import * as Svelte from 'svelte'
7
8
 
8
- const containerCache = new Set()
9
- const componentCache = new Set()
9
+ const IS_SVELTE_5 = /^5\./.test(SVELTE_VERSION)
10
+ export const targetCache = new Set()
11
+ export const componentCache = new Set()
10
12
 
11
13
  const svelteComponentOptions = [
12
14
  'accessors',
@@ -14,124 +16,138 @@ const svelteComponentOptions = [
14
16
  'props',
15
17
  'hydrate',
16
18
  'intro',
17
- 'context'
19
+ 'context',
18
20
  ]
19
21
 
20
- const render = (
21
- Component,
22
- { target, ...options } = {},
23
- { container, queries } = {}
24
- ) => {
25
- container = container || document.body
26
- target = target || container.appendChild(document.createElement('div'))
22
+ export const buildCheckProps = (svelteComponentOptions) => (options) => {
23
+ const isProps = !Object.keys(options).some((option) =>
24
+ svelteComponentOptions.includes(option)
25
+ )
27
26
 
28
- const ComponentConstructor = Component.default || Component
29
-
30
- const checkProps = (options) => {
31
- const isProps = !Object.keys(options).some((option) =>
32
- svelteComponentOptions.includes(option)
27
+ // Check if any props and Svelte options were accidentally mixed.
28
+ if (!isProps) {
29
+ const unrecognizedOptions = Object.keys(options).filter(
30
+ (option) => !svelteComponentOptions.includes(option)
33
31
  )
34
32
 
35
- // Check if any props and Svelte options were accidentally mixed.
36
- if (!isProps) {
37
- const unrecognizedOptions = Object.keys(options).filter(
38
- (option) => !svelteComponentOptions.includes(option)
39
- )
40
-
41
- if (unrecognizedOptions.length > 0) {
42
- throw Error(`
33
+ if (unrecognizedOptions.length > 0) {
34
+ throw Error(`
43
35
  Unknown options were found [${unrecognizedOptions}]. This might happen if you've mixed
44
36
  passing in props with Svelte options into the render function. Valid Svelte options
45
37
  are [${svelteComponentOptions}]. You can either change the prop names, or pass in your
46
38
  props for that component via the \`props\` option.\n\n
47
39
  Eg: const { /** Results **/ } = render(MyComponent, { props: { /** props here **/ } })\n\n
48
40
  `)
49
- }
50
-
51
- return options
52
41
  }
53
42
 
54
- return { props: options }
43
+ return options
55
44
  }
56
45
 
57
- let component = new ComponentConstructor({
58
- target,
59
- ...checkProps(options)
60
- })
61
-
62
- containerCache.add({ container, target, component })
63
- componentCache.add(component)
64
-
65
- component.$$.on_destroy.push(() => {
66
- componentCache.delete(component)
67
- })
68
-
69
- return {
70
- container,
71
- component,
72
- debug: (el = container) => console.log(prettyDOM(el)),
73
- rerender: (options) => {
74
- if (componentCache.has(component)) component.$destroy()
75
-
76
- // eslint-disable-next-line no-new
77
- component = new ComponentConstructor({
78
- target,
79
- ...checkProps(options)
80
- })
46
+ return { props: options }
47
+ }
48
+
49
+ const checkProps = buildCheckProps(svelteComponentOptions)
81
50
 
82
- containerCache.add({ container, target, component })
83
- componentCache.add(component)
51
+ const buildRenderComponent =
52
+ ({ target, ComponentConstructor }) =>
53
+ (options) => {
54
+ options = { target, ...checkProps(options) }
84
55
 
56
+ if (IS_SVELTE_5)
57
+ throw new Error('for Svelte 5, use `@testing-library/svelte/svelte5`')
58
+
59
+ const component = new ComponentConstructor(options)
60
+
61
+ componentCache.add(component)
62
+
63
+ // TODO(mcous, 2024-02-11): remove this behavior in the next major version
64
+ // It is unnecessary has no path to implementation in Svelte v5
65
+ if (!IS_SVELTE_5) {
85
66
  component.$$.on_destroy.push(() => {
86
67
  componentCache.delete(component)
87
68
  })
88
- },
89
- unmount: () => {
90
- if (componentCache.has(component)) component.$destroy()
91
- },
92
- ...getQueriesForElement(container, queries)
69
+ }
70
+
71
+ return component
93
72
  }
94
- }
95
73
 
96
- const cleanupAtContainer = (cached) => {
97
- const { target, component } = cached
74
+ export const buildRender =
75
+ (buildRenderComponent) =>
76
+ (Component, { target, ...options } = {}, { container, queries } = {}) => {
77
+ container = container || document.body
78
+ target = target || container.appendChild(document.createElement('div'))
79
+ targetCache.add(target)
80
+
81
+ const ComponentConstructor = Component.default || Component
82
+
83
+ const renderComponent = buildRenderComponent({
84
+ target,
85
+ ComponentConstructor,
86
+ })
87
+
88
+ let component = renderComponent(options)
89
+
90
+ return {
91
+ container,
92
+ component,
93
+ debug: (el = container) => console.log(prettyDOM(el)),
94
+ rerender: async (props) => {
95
+ if (props.props) {
96
+ console.warn(
97
+ 'rerender({ props: {...} }) deprecated, use rerender({...}) instead'
98
+ )
99
+ props = props.props
100
+ }
101
+ component.$set(props)
102
+ await Svelte.tick()
103
+ },
104
+ unmount: () => {
105
+ cleanupComponent(component)
106
+ },
107
+ ...getQueriesForElement(container, queries),
108
+ }
109
+ }
98
110
 
99
- if (componentCache.has(component)) component.$destroy()
111
+ export const render = buildRender(buildRenderComponent)
100
112
 
101
- if (target.parentNode === document.body) {
102
- document.body.removeChild(target)
113
+ export const cleanupComponent = (component) => {
114
+ const inCache = componentCache.delete(component)
115
+
116
+ if (inCache) {
117
+ component.$destroy()
103
118
  }
119
+ }
120
+
121
+ const cleanupTarget = (target) => {
122
+ const inCache = targetCache.delete(target)
104
123
 
105
- containerCache.delete(cached)
124
+ if (inCache && target.parentNode === document.body) {
125
+ document.body.removeChild(target)
126
+ }
106
127
  }
107
128
 
108
- const cleanup = () => {
109
- Array.from(containerCache.keys()).forEach(cleanupAtContainer)
129
+ export const cleanup = () => {
130
+ componentCache.forEach(cleanupComponent)
131
+ targetCache.forEach(cleanupTarget)
110
132
  }
111
133
 
112
- const act = async (fn) => {
134
+ export const act = async (fn) => {
113
135
  if (fn) {
114
136
  await fn()
115
137
  }
116
- return tick()
138
+ return Svelte.tick()
117
139
  }
118
140
 
119
- const fireEvent = async (...args) => {
141
+ export const fireEvent = async (...args) => {
120
142
  const event = dtlFireEvent(...args)
121
- await tick()
143
+ await Svelte.tick()
122
144
  return event
123
145
  }
124
146
 
125
147
  Object.keys(dtlFireEvent).forEach((key) => {
126
148
  fireEvent[key] = async (...args) => {
127
149
  const event = dtlFireEvent[key](...args)
128
- await tick()
150
+ await Svelte.tick()
129
151
  return event
130
152
  }
131
153
  })
132
-
133
- /* eslint-disable import/export */
134
-
135
- export * from '@testing-library/dom'
136
-
137
- export { render, cleanup, fireEvent, act }
@@ -0,0 +1,17 @@
1
+ import { act, cleanup } from './svelte5.js'
2
+
3
+ // If we're running in a test runner that supports afterEach
4
+ // then we'll automatically run cleanup afterEach test
5
+ // this ensures that tests run in isolation from each other
6
+ // if you don't like this then either import the `pure` module
7
+ // or set the STL_SKIP_AUTO_CLEANUP env variable to 'true'.
8
+ if (typeof afterEach === 'function' && !process.env.STL_SKIP_AUTO_CLEANUP) {
9
+ afterEach(async () => {
10
+ await act()
11
+ cleanup()
12
+ })
13
+ }
14
+
15
+ export * from './svelte5.js'
16
+ export * from '@testing-library/dom'
17
+ export { act, fireEvent } from './pure.js'
package/src/svelte5.js ADDED
@@ -0,0 +1,41 @@
1
+ import { createClassComponent } from 'svelte/legacy'
2
+ import {
3
+ componentCache,
4
+ cleanup,
5
+ buildCheckProps,
6
+ buildRender,
7
+ } from './pure.js'
8
+
9
+ const svelteComponentOptions = [
10
+ 'target',
11
+ 'props',
12
+ 'events',
13
+ 'context',
14
+ 'intro',
15
+ 'recover',
16
+ ]
17
+
18
+ const checkProps = buildCheckProps(svelteComponentOptions)
19
+
20
+ const buildRenderComponent =
21
+ ({ target, ComponentConstructor }) =>
22
+ (options) => {
23
+ options = { target, ...checkProps(options) }
24
+
25
+ const component = createClassComponent({
26
+ component: ComponentConstructor,
27
+ ...options,
28
+ })
29
+
30
+ componentCache.add(component)
31
+
32
+ return component
33
+ }
34
+
35
+ const render = buildRender(buildRenderComponent)
36
+
37
+ /* eslint-disable import/export */
38
+
39
+ import { act, fireEvent } from './pure.js'
40
+
41
+ export { render, cleanup, fireEvent, act }
package/src/vitest.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { afterEach } from 'vitest'
2
2
 
3
- import { act, cleanup } from './pure.js'
3
+ import { act, cleanup } from '@testing-library/svelte'
4
4
 
5
5
  afterEach(async () => {
6
6
  await act()
package/types/index.d.ts CHANGED
@@ -2,25 +2,42 @@
2
2
  // Project: https://github.com/testing-library/svelte-testing-library
3
3
  // Definitions by: Rahim Alwer <https://github.com/mihar-22>
4
4
 
5
- import {BoundFunction, EventType,Queries, queries} from '@testing-library/dom'
6
- import { ComponentConstructorOptions,ComponentProps, SvelteComponent } from 'svelte'
5
+ import {
6
+ BoundFunction,
7
+ EventType,
8
+ Queries,
9
+ queries,
10
+ } from '@testing-library/dom'
11
+ import {
12
+ ComponentConstructorOptions,
13
+ ComponentProps,
14
+ SvelteComponent,
15
+ } from 'svelte'
7
16
 
8
17
  export * from '@testing-library/dom'
9
18
 
10
- type SvelteComponentOptions<C extends SvelteComponent> = ComponentProps<C> | Pick<ComponentConstructorOptions<ComponentProps<C>>, "anchor" | "props" | "hydrate" | "intro" | "context">
19
+ type SvelteComponentOptions<C extends SvelteComponent> =
20
+ | ComponentProps<C>
21
+ | Pick<
22
+ ComponentConstructorOptions<ComponentProps<C>>,
23
+ 'anchor' | 'props' | 'hydrate' | 'intro' | 'context'
24
+ >
11
25
 
12
26
  type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
13
27
 
14
- type Constructor<T> = new (...args: any[]) => T;
28
+ type Constructor<T> = new (...args: any[]) => T
15
29
 
16
30
  /**
17
31
  * Render a Component into the Document.
18
32
  */
19
- export type RenderResult<C extends SvelteComponent, Q extends Queries = typeof queries> = {
33
+ export type RenderResult<
34
+ C extends SvelteComponent,
35
+ Q extends Queries = typeof queries,
36
+ > = {
20
37
  container: HTMLElement
21
38
  component: C
22
39
  debug: (el?: HTMLElement | DocumentFragment) => void
23
- rerender: (options: SvelteComponentOptions<C>) => void
40
+ rerender: (props: ComponentProps<C>) => Promise<void>
24
41
  unmount: () => void
25
42
  } & { [P in keyof Q]: BoundFunction<Q[P]> }
26
43
 
@@ -38,7 +55,7 @@ export function render<C extends SvelteComponent>(
38
55
  export function render<C extends SvelteComponent, Q extends Queries>(
39
56
  component: Constructor<C>,
40
57
  componentOptions?: SvelteComponentOptions<C>,
41
- renderOptions?: RenderOptions<Q>,
58
+ renderOptions?: RenderOptions<Q>
42
59
  ): RenderResult<C, Q>
43
60
 
44
61
  /**
@@ -50,13 +67,19 @@ export function cleanup(): void
50
67
  * Fires DOM events on an element provided by @testing-library/dom. Since Svelte needs to flush
51
68
  * pending state changes via `tick`, these methods have been override and now return a promise.
52
69
  */
53
- export type FireFunction = (element: Document | Element | Window, event: Event) => Promise<boolean>;
70
+ export type FireFunction = (
71
+ element: Document | Element | Window,
72
+ event: Event
73
+ ) => Promise<boolean>
54
74
 
55
75
  export type FireObject = {
56
- [K in EventType]: (element: Document | Element | Window, options?: {}) => Promise<boolean>;
57
- };
76
+ [K in EventType]: (
77
+ element: Document | Element | Window,
78
+ options?: {}
79
+ ) => Promise<boolean>
80
+ }
58
81
 
59
- export const fireEvent: FireFunction & FireObject;
82
+ export const fireEvent: FireFunction & FireObject
60
83
 
61
84
  /**
62
85
  * Calls a function and notifies Svelte to flush any pending state changes.
@@ -1,40 +0,0 @@
1
- <script>
2
- import { onDestroy } from 'svelte'
3
-
4
- let timer
5
- let lapse = 0
6
- let running = false
7
-
8
- function handleRunClick () {
9
- if (running) {
10
- clearInterval(timer)
11
- } else {
12
- const startTime = Date.now() - lapse
13
-
14
- timer = setInterval(() => {
15
- lapse = Date.now() - startTime
16
- }, 1)
17
- }
18
- running = true
19
- }
20
-
21
- function handleClearClick () {
22
- clearInterval(timer)
23
- lapse = 0
24
- running = false
25
- }
26
-
27
- onDestroy(() => {
28
- clearInterval(timer)
29
- })
30
- </script>
31
-
32
- <style></style>
33
-
34
- <span>{lapse}ms</span>
35
-
36
- <button on:click={handleRunClick}>
37
- {running ? 'Stop' : 'Start'}
38
- </button>
39
-
40
- <button on:click={handleClearClick}>Clear</button>
@@ -1,35 +0,0 @@
1
- import { describe, expect, test, vi } from 'vitest'
2
-
3
- import { act, fireEvent, render } from '..'
4
- import Stopwatch from './fixtures/Stopwatch.svelte'
5
-
6
- describe('unmount', () => {
7
- test('unmounts component successfully', async () => {
8
- console.warn = vi.fn()
9
-
10
- const { unmount, getByText, container } = render(Stopwatch)
11
-
12
- await fireEvent.click(getByText('Start'))
13
-
14
- unmount()
15
-
16
- // Hey there reader! You don't need to have an assertion like this one
17
- // this is just me making sure that the unmount function works.
18
- // You don't need to do this in your apps. Just rely on the fact that this works.
19
- expect(container.innerHTML).toBe('<div></div>')
20
-
21
- await act()
22
- expect(console.warn).not.toHaveBeenCalled()
23
- })
24
-
25
- test('destroying component directly and calling unmount does not log warning', async () => {
26
- console.warn = vi.fn()
27
-
28
- const { unmount, component } = render(Stopwatch)
29
-
30
- component.$destroy()
31
- unmount()
32
-
33
- expect(console.warn).not.toHaveBeenCalled()
34
- })
35
- })