Skip to content

Commit 6533bb3

Browse files
committed
feat(svelte5): add Svelte 5 support into main entry point
1 parent ee1c966 commit 6533bb3

20 files changed

+311
-244
lines changed

.eslintrc.cjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ module.exports = {
2525
},
2626
rules: {
2727
'no-undef-init': 'off',
28+
'prefer-const': 'off',
2829
},
2930
},
3031
{
@@ -49,5 +50,6 @@ module.exports = {
4950
ecmaVersion: 2022,
5051
sourceType: 'module',
5152
},
53+
globals: { $state: 'readonly', $props: 'readonly' },
5254
ignorePatterns: ['!/.*'],
5355
}

README.md

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ primary guiding principle is:
7171
This module is distributed via [npm][npm] which is bundled with [node][node] and
7272
should be installed as one of your project's `devDependencies`:
7373

74-
```
74+
```shell
7575
npm install --save-dev @testing-library/svelte
7676
```
7777

78-
This library has `peerDependencies` listings for `svelte >= 3`.
78+
This library supports `svelte` versions `3`, `4`, and `5`.
7979

8080
You may also be interested in installing `@testing-library/jest-dom` so you can use
8181
[the custom jest matchers](https://github.com/testing-library/jest-dom).
@@ -102,22 +102,6 @@ See the [setup docs][] for more detailed setup instructions, including for other
102102
[vitest]: https://vitest.dev/
103103
[setup docs]: https://testing-library.com/docs/svelte-testing-library/setup
104104

105-
### Svelte 5 support
106-
107-
If you are riding the bleeding edge of Svelte 5, you'll need to either
108-
import from `@testing-library/svelte/svelte5` instead of `@testing-library/svelte`, or add an alias to your `vite.config.js`:
109-
110-
```js
111-
export default defineConfig({
112-
plugins: [svelte(), svelteTesting()],
113-
test: {
114-
alias: {
115-
'@testing-library/svelte': '@testing-library/svelte/svelte5',
116-
},
117-
},
118-
})
119-
```
120-
121105
## Docs
122106

123107
See the [**docs**](https://testing-library.com/docs/svelte-testing-library/intro) over at the Testing Library website.

jest.config.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
22

3-
const IS_SVELTE_5 = SVELTE_VERSION >= '5'
3+
const SVELTE_TRANSFORM_PATTERN =
4+
SVELTE_VERSION >= '5' ? '^.+\\.svelte(?:\\.js)?$' : '^.+\\.svelte$'
45

56
export default {
67
testMatch: ['<rootDir>/src/__tests__/**/*.test.js'],
78
transform: {
8-
'^.+\\.svelte$': 'svelte-jester',
9+
[SVELTE_TRANSFORM_PATTERN]: 'svelte-jester',
910
},
1011
moduleFileExtensions: ['js', 'svelte'],
1112
extensionsToTreatAsEsm: ['.svelte'],
@@ -14,9 +15,6 @@ export default {
1415
injectGlobals: false,
1516
moduleNameMapper: {
1617
'^vitest$': '<rootDir>/src/__tests__/_jest-vitest-alias.js',
17-
'^@testing-library/svelte$': IS_SVELTE_5
18-
? '<rootDir>/src/svelte5-index.js'
19-
: '<rootDir>/src/index.js',
2018
},
2119
resetMocks: true,
2220
restoreMocks: true,

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
},
1111
"./svelte5": {
1212
"types": "./types/index.d.ts",
13-
"default": "./src/svelte5-index.js"
13+
"default": "./src/index.js"
1414
},
1515
"./vitest": {
1616
"default": "./src/vitest.js"
@@ -120,7 +120,7 @@
120120
"prettier-plugin-svelte": "3.2.3",
121121
"svelte": "^3 || ^4 || ^5",
122122
"svelte-check": "^3.6.3",
123-
"svelte-jester": "^3.0.0",
123+
"svelte-jester": "^5.0.0",
124124
"typescript": "^5.3.3",
125125
"vite": "^5.1.1",
126126
"vitest": "^1.5.2"

src/__tests__/auto-cleanup.test.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
22

3-
import { IS_SVELTE_5 } from './utils.js'
4-
5-
const importSvelteTestingLibrary = async () =>
6-
IS_SVELTE_5 ? import('../svelte5-index.js') : import('../index.js')
7-
83
const globalAfterEach = vi.fn()
94

105
describe('auto-cleanup', () => {
@@ -19,7 +14,7 @@ describe('auto-cleanup', () => {
1914
})
2015

2116
test('calls afterEach with cleanup if globally defined', async () => {
22-
const { render } = await importSvelteTestingLibrary()
17+
const { render } = await import('../index.js')
2318

2419
expect(globalAfterEach).toHaveBeenCalledTimes(1)
2520
expect(globalAfterEach).toHaveBeenLastCalledWith(expect.any(Function))
@@ -35,7 +30,7 @@ describe('auto-cleanup', () => {
3530
test('does not call afterEach if process STL_SKIP_AUTO_CLEANUP is set', async () => {
3631
process.env.STL_SKIP_AUTO_CLEANUP = 'true'
3732

38-
await importSvelteTestingLibrary()
33+
await import('../index.js')
3934

4035
expect(globalAfterEach).toHaveBeenCalledTimes(0)
4136
})

src/__tests__/fixtures/Comp.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<!-- svelte-ignore options_deprecated_accessors -->
12
<svelte:options accessors />
23

34
<script>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
let { name = 'World' } = $props()
3+
4+
let buttonText = $state('Button')
5+
6+
function handleClick() {
7+
buttonText = 'Button Clicked'
8+
}
9+
</script>
10+
11+
<h1 data-testid="test">Hello {name}!</h1>
12+
13+
<button onclick={handleClick}>{buttonText}</button>

src/__tests__/fixtures/Mounter.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
})
1717
</script>
1818
19-
<button />
19+
<button></button>

src/__tests__/render.test.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import { render } from '@testing-library/svelte'
2-
import { describe, expect, test } from 'vitest'
2+
import { beforeAll, describe, expect, test } from 'vitest'
33

4-
import Comp from './fixtures/Comp.svelte'
5-
import { IS_SVELTE_5 } from './utils.js'
4+
import { COMPONENT_FIXTURES } from './utils.js'
65

7-
describe('render', () => {
6+
describe.each(COMPONENT_FIXTURES)('render ($mode)', ({ component }) => {
87
const props = { name: 'World' }
8+
let Comp
9+
10+
beforeAll(async () => {
11+
Comp = await import(component)
12+
})
913

1014
test('renders component into the document', () => {
1115
const { getByText } = render(Comp, { props })
@@ -65,7 +69,7 @@ describe('render', () => {
6569
expect(baseElement.firstChild).toBe(container)
6670
})
6771

68-
test.skipIf(IS_SVELTE_5)('should accept anchor option in Svelte v4', () => {
72+
test('should accept anchor option', () => {
6973
const baseElement = document.body
7074
const target = document.createElement('section')
7175
const anchor = document.createElement('div')

src/__tests__/rerender.test.js

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import { act, render, screen } from '@testing-library/svelte'
2-
import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
3-
import { describe, expect, test, vi } from 'vitest'
2+
import { beforeAll, describe, expect, test, vi } from 'vitest'
43

5-
import Comp from './fixtures/Comp.svelte'
4+
import { COMPONENT_FIXTURES, IS_SVELTE_5, MODE_RUNES } from './utils.js'
5+
6+
describe.each(COMPONENT_FIXTURES)('rerender ($mode)', ({ mode, component }) => {
7+
let Comp
8+
9+
beforeAll(async () => {
10+
Comp = await import(component)
11+
})
612

7-
describe('rerender', () => {
813
test('updates props', async () => {
914
const { rerender } = render(Comp, { name: 'World' })
1015
const element = screen.getByText('Hello World!')
@@ -29,13 +34,12 @@ describe('rerender', () => {
2934
)
3035
})
3136

32-
test('change props with accessors', async () => {
33-
const { component, getByText } = render(
34-
Comp,
35-
SVELTE_VERSION < '5'
36-
? { accessors: true, props: { name: 'World' } }
37-
: { name: 'World' }
38-
)
37+
test.skipIf(mode === MODE_RUNES)('change props with accessors', async () => {
38+
const componentOptions = IS_SVELTE_5
39+
? { name: 'World' }
40+
: { accessors: true, props: { name: 'World' } }
41+
42+
const { component, getByText } = render(Comp, componentOptions)
3943
const element = getByText('Hello World!')
4044

4145
expect(element).toBeInTheDocument()

0 commit comments

Comments
 (0)