Skip to content

Commit 9172cdf

Browse files
committed
wip
1 parent 54f23db commit 9172cdf

File tree

5 files changed

+455
-22
lines changed

5 files changed

+455
-22
lines changed

src/__tests__/render.test.js.orig

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
2+
import { describe, expect, test } from 'vitest'
3+
4+
<<<<<<< HEAD
5+
import { render } from '..'
6+
=======
7+
import { act, render as stlRender } from '@testing-library/svelte'
8+
>>>>>>> origin/next
9+
import Comp from './fixtures/Comp.svelte'
10+
11+
describe('render', () => {
12+
const props = { name: 'World' }
13+
14+
test('renders component into the document', () => {
15+
const { getByText } = render(Comp, { props })
16+
17+
expect(getByText('Hello World!')).toBeInTheDocument()
18+
})
19+
20+
test('accepts props directly', () => {
21+
const { getByText } = render(Comp, props)
22+
expect(getByText('Hello World!')).toBeInTheDocument()
23+
})
24+
25+
test('throws error when mixing svelte component options and props', () => {
26+
expect(() => {
27+
render(Comp, { props, name: 'World' })
28+
}).toThrow(/Unknown component options/)
29+
})
30+
31+
test('throws error when mixing target option and props', () => {
32+
expect(() => {
33+
render(Comp, { target: document.createElement('div'), name: 'World' })
34+
}).toThrow(/Unknown component options/)
35+
})
36+
37+
test('should return a container object wrapping the DOM of the rendered component', () => {
38+
const { container, getByTestId } = render(Comp, props)
39+
const firstElement = getByTestId('test')
40+
41+
expect(container.firstChild).toBe(firstElement)
42+
})
43+
44+
test('should return a baseElement object, which holds the container', () => {
45+
const { baseElement, container } = render(Comp, props)
46+
47+
expect(baseElement).toBe(document.body)
48+
expect(baseElement.firstChild).toBe(container)
49+
})
50+
51+
test('if target is provided, use it as container and baseElement', () => {
52+
const target = document.createElement('div')
53+
const { baseElement, container } = render(Comp, { props, target })
54+
55+
expect(container).toBe(target)
56+
expect(baseElement).toBe(target)
57+
})
58+
59+
test('allow baseElement to be specified', () => {
60+
const customBaseElement = document.createElement('div')
61+
62+
const { baseElement, container } = render(
63+
Comp,
64+
{ props },
65+
{ baseElement: customBaseElement }
66+
)
67+
68+
expect(baseElement).toBe(customBaseElement)
69+
expect(baseElement.firstChild).toBe(container)
70+
})
71+
72+
test.runIf(SVELTE_VERSION < '5')(
73+
'should accept anchor option in Svelte v4',
74+
() => {
75+
const baseElement = document.body
76+
const target = document.createElement('section')
77+
const anchor = document.createElement('div')
78+
baseElement.appendChild(target)
79+
target.appendChild(anchor)
80+
81+
const { getByTestId } = render(
82+
Comp,
83+
{ props, target, anchor },
84+
{ baseElement }
85+
)
86+
const firstElement = getByTestId('test')
87+
88+
expect(target.firstChild).toBe(firstElement)
89+
expect(target.lastChild).toBe(anchor)
90+
}
91+
)
92+
<<<<<<< HEAD
93+
=======
94+
95+
test('should throw error when mixing svelte component options and props', () => {
96+
expect(() => {
97+
stlRender(Comp, { props: {}, name: 'World' })
98+
}).toThrow(/Unknown options were found/)
99+
})
100+
101+
test('should return a container object, which contains the DOM of the rendered component', () => {
102+
const { container } = render()
103+
104+
expect(container.innerHTML).toBe(document.body.innerHTML)
105+
})
106+
107+
test('correctly find component constructor on the default property', () => {
108+
const { getByText } = stlRender(CompDefault, { props: { name: 'World' } })
109+
110+
expect(getByText('Hello World!')).toBeInTheDocument()
111+
})
112+
113+
test("accept the 'context' option", () => {
114+
const { getByText } = stlRender(Comp, {
115+
props: { name: 'Universe' },
116+
context: new Map([['name', 'context']]),
117+
})
118+
119+
expect(getByText('we have context')).toBeInTheDocument()
120+
})
121+
>>>>>>> origin/next
122+
})

src/__tests__/rerender.test.js.orig

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<<<<<<< HEAD
2+
import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
3+
import { describe, expect, test, vi } from 'vitest'
4+
5+
import { act, render, screen } from '..'
6+
import Comp from './fixtures/Comp.svelte'
7+
=======
8+
/**
9+
* @jest-environment jsdom
10+
*/
11+
import { expect, test, vi } from 'vitest'
12+
13+
import { render, waitFor } from '@testing-library/svelte'
14+
15+
import Comp from './fixtures/Rerender.svelte'
16+
>>>>>>> origin/next
17+
18+
describe('rerender', () => {
19+
test('updates props', async () => {
20+
const { rerender } = render(Comp, { name: 'World' })
21+
const element = screen.getByText('Hello World!')
22+
23+
await rerender({ name: 'Dolly' })
24+
25+
expect(element).toHaveTextContent('Hello Dolly!')
26+
})
27+
28+
test('warns if incorrect arguments shape used', async () => {
29+
vi.stubGlobal('console', { warn: vi.fn() })
30+
31+
const { rerender } = render(Comp, { name: 'World' })
32+
const element = screen.getByText('Hello World!')
33+
34+
await rerender({ props: { name: 'Dolly' } })
35+
36+
expect(element).toHaveTextContent('Hello Dolly!')
37+
expect(console.warn).toHaveBeenCalledOnce()
38+
expect(console.warn).toHaveBeenCalledWith(
39+
expect.stringMatching(/deprecated/iu)
40+
)
41+
})
42+
43+
test('change props with accessors', async () => {
44+
const { component, getByText } = render(
45+
Comp,
46+
SVELTE_VERSION < '5'
47+
? { accessors: true, props: { name: 'World' } }
48+
: { name: 'World' }
49+
)
50+
const element = getByText('Hello World!')
51+
52+
expect(element).toBeInTheDocument()
53+
expect(component.name).toBe('World')
54+
55+
await act(() => {
56+
component.name = 'Planet'
57+
})
58+
59+
expect(element).toHaveTextContent('Hello Planet!')
60+
})
61+
})

src/pure.js

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ import {
55
} from '@testing-library/dom'
66
import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
77
import * as Svelte from 'svelte'
8-
import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
9-
10-
const IS_SVELTE_5 = SVELTE_VERSION >= '5'
118

9+
const IS_SVELTE_5 = /^5\./.test(SVELTE_VERSION)
1210
export const targetCache = new Set()
1311
export const componentCache = new Set()
1412

@@ -22,24 +20,27 @@ const svelteComponentOptions = [
2220
]
2321

2422
export const buildCheckProps = (svelteComponentOptions) => (options) => {
25-
const isProps = !Object.keys(options).some((option) =>
23+
const isOptions = Object.keys(options).some((option) =>
2624
svelteComponentOptions.includes(option)
2725
)
2826

2927
// Check if any props and Svelte options were accidentally mixed.
30-
if (!isProps) {
28+
if (isOptions) {
3129
const unrecognizedOptions = Object.keys(options).filter(
3230
(option) => !svelteComponentOptions.includes(option)
3331
)
3432

3533
if (unrecognizedOptions.length > 0) {
3634
throw Error(`
37-
Unknown options were found [${unrecognizedOptions}]. This might happen if you've mixed
38-
passing in props with Svelte options into the render function. Valid Svelte options
39-
are [${svelteComponentOptions}]. You can either change the prop names, or pass in your
40-
props for that component via the \`props\` option.\n\n
41-
Eg: const { /** Results **/ } = render(MyComponent, { props: { /** props here **/ } })\n\n
42-
`)
35+
Unknown component options: [${unrecognizedOptions.join(', ')}]
36+
Valid Svelte component options: [${svelteComponentOptions.join(', ')}]
37+
38+
This error occurs if props are mixed with Svelte component options,
39+
or any props use the same name as a Svelte component option.
40+
Either rename the props, or place props under the \`props\` option.
41+
42+
Eg: const { /** results **/ } = render(MyComponent, { props: { /** props here **/ } })
43+
`)
4344
}
4445

4546
return options
@@ -53,7 +54,7 @@ const checkProps = buildCheckProps(svelteComponentOptions)
5354
const buildRenderComponent =
5455
({ target, ComponentConstructor }) =>
5556
(options) => {
56-
options = { target, ...checkProps(options) }
57+
options = checkProps(options)
5758

5859
if (IS_SVELTE_5)
5960
throw new Error('for Svelte 5, use `@testing-library/svelte/svelte5`')
@@ -75,9 +76,13 @@ const buildRenderComponent =
7576

7677
export const buildRender =
7778
(buildRenderComponent) =>
78-
(Component, { target, ...options } = {}, { container, queries } = {}) => {
79-
container = container || document.body
80-
target = target || container.appendChild(document.createElement('div'))
79+
(Component, options = {}, renderOptions = {}) => {
80+
const baseElement =
81+
renderOptions.baseElement ?? options.target ?? document.body
82+
83+
const target =
84+
options.target ?? baseElement.appendChild(document.createElement('div'))
85+
8186
targetCache.add(target)
8287

8388
const ComponentConstructor = Component.default || Component
@@ -87,7 +92,7 @@ export const buildRender =
8792
ComponentConstructor,
8893
})
8994

90-
let component = renderComponent(options)
95+
let component = renderComponent({ target, ...options })
9196

9297
return {
9398
container,
@@ -116,11 +121,7 @@ export const cleanupComponent = (component) => {
116121
const inCache = componentCache.delete(component)
117122

118123
if (inCache) {
119-
if (IS_SVELTE_5) {
120-
Svelte.unmount(component)
121-
} else {
122-
component.$destroy()
123-
}
124+
component.$destroy()
124125
}
125126
}
126127

0 commit comments

Comments
 (0)