diff --git a/src/__tests__/fixtures/Rerender.svelte b/src/__tests__/fixtures/Rerender.svelte
new file mode 100644
index 0000000..aac1600
--- /dev/null
+++ b/src/__tests__/fixtures/Rerender.svelte
@@ -0,0 +1,15 @@
+
+
+
Hello {name}!
+
+{$mountCounter}
diff --git a/src/__tests__/rerender.test.js b/src/__tests__/rerender.test.js
index e3eddb2..d6cbc21 100644
--- a/src/__tests__/rerender.test.js
+++ b/src/__tests__/rerender.test.js
@@ -1,38 +1,38 @@
/**
* @jest-environment jsdom
*/
-import { describe, expect, test } from 'vitest'
+import { expect, test, vi } from 'vitest'
+import { writable } from 'svelte/store'
-import { render } from '..'
-import Comp from './fixtures/Comp.svelte'
+import { render, waitFor } from '..'
+import Comp from './fixtures/Rerender.svelte'
-describe('rerender', () => {
- test('mounts new component successfully', () => {
- const { container, rerender } = render(Comp, { props: { name: 'World 1' } })
+const mountCounter = writable(0)
- expect(container.firstChild).toHaveTextContent('Hello World 1!')
- rerender({ props: { name: 'World 2' } })
- expect(container.firstChild).toHaveTextContent('Hello World 2!')
+test('mounts new component successfully', async () => {
+ const { getByTestId, rerender } = render(Comp, {
+ props: { name: 'World 1' },
+ context: new Map(Object.entries({ mountCounter })),
})
- test('destroys old component', () => {
- let isDestroyed
+ const expectToRender = (content) =>
+ waitFor(() => {
+ expect(getByTestId('test')).toHaveTextContent(content)
+ expect(getByTestId('mount-counter')).toHaveTextContent('1')
+ })
- const { rerender, component } = render(Comp, { props: { name: '' } })
+ await expectToRender('Hello World 1!')
- component.$$.on_destroy.push(() => {
- isDestroyed = true
- })
- rerender({ props: { name: '' } })
- expect(isDestroyed).toBeTruthy()
- })
+ console.warn = vi.fn()
- test('destroys old components on multiple rerenders', () => {
- const { rerender, queryByText } = render(Comp, { props: { name: 'Neil' } })
+ rerender({ props: { name: 'World 2' } })
+ await expectToRender('Hello World 2!')
- rerender({ props: { name: 'Alex' } })
- expect(queryByText('Hello Neil!')).not.toBeInTheDocument()
- rerender({ props: { name: 'Geddy' } })
- expect(queryByText('Hello Alex!')).not.toBeInTheDocument()
- })
+ expect(console.warn).toHaveBeenCalled()
+
+ console.warn.mockClear()
+ rerender({ name: 'World 3' })
+ await expectToRender('Hello World 3!')
+
+ expect(console.warn).not.toHaveBeenCalled()
})
diff --git a/src/pure.js b/src/pure.js
index 6d49434..59c62ff 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 })
@@ -70,26 +70,20 @@ const render = (
container,
component,
debug: (el = container) => console.log(prettyDOM(el)),
- rerender: (options) => {
- if (componentCache.has(component)) component.$destroy()
-
- // eslint-disable-next-line no-new
- component = new ComponentConstructor({
- target,
- ...checkProps(options)
- })
-
- containerCache.add({ container, target, component })
- componentCache.add(component)
-
- component.$$.on_destroy.push(() => {
- componentCache.delete(component)
- })
+ rerender: async (props) => {
+ if (props.props) {
+ console.warn(
+ 'rerender({ props: {...} }) deprecated, use rerender({...}) instead'
+ )
+ props = props.props
+ }
+ component.$set(props)
+ await tick()
},
unmount: () => {
if (componentCache.has(component)) component.$destroy()
},
- ...getQueriesForElement(container, queries)
+ ...getQueriesForElement(container, queries),
}
}
diff --git a/types/index.d.ts b/types/index.d.ts
index 26d85d7..d60d779 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -2,25 +2,42 @@
// Project: https://github.com/testing-library/svelte-testing-library
// Definitions by: Rahim Alwer
-import {BoundFunction, EventType,Queries, queries} from '@testing-library/dom'
-import { ComponentConstructorOptions,ComponentProps, SvelteComponent } from 'svelte'
+import {
+ BoundFunction,
+ EventType,
+ Queries,
+ queries,
+} from '@testing-library/dom'
+import {
+ ComponentConstructorOptions,
+ ComponentProps,
+ SvelteComponent,
+} from 'svelte'
export * from '@testing-library/dom'
-type SvelteComponentOptions = ComponentProps | Pick>, "anchor" | "props" | "hydrate" | "intro" | "context">
+type SvelteComponentOptions =
+ | ComponentProps
+ | Pick<
+ ComponentConstructorOptions>,
+ 'anchor' | 'props' | 'hydrate' | 'intro' | 'context'
+ >
type Omit = Pick>
-type Constructor = new (...args: any[]) => T;
+type Constructor = new (...args: any[]) => T
/**
* Render a Component into the Document.
*/
-export type RenderResult = {
+export type RenderResult<
+ C extends SvelteComponent,
+ Q extends Queries = typeof queries,
+> = {
container: HTMLElement
component: C
debug: (el?: HTMLElement | DocumentFragment) => void
- rerender: (options: SvelteComponentOptions) => void
+ rerender: (props: ComponentProps) => Promise
unmount: () => void
} & { [P in keyof Q]: BoundFunction }
@@ -38,7 +55,7 @@ export function render(
export function render(
component: Constructor,
componentOptions?: SvelteComponentOptions,
- renderOptions?: RenderOptions,
+ renderOptions?: RenderOptions
): RenderResult
/**
@@ -50,13 +67,19 @@ export function cleanup(): void
* Fires DOM events on an element provided by @testing-library/dom. Since Svelte needs to flush
* pending state changes via `tick`, these methods have been override and now return a promise.
*/
-export type FireFunction = (element: Document | Element | Window, event: Event) => Promise;
+export type FireFunction = (
+ element: Document | Element | Window,
+ event: Event
+) => Promise
export type FireObject = {
- [K in EventType]: (element: Document | Element | Window, options?: {}) => Promise;
-};
+ [K in EventType]: (
+ element: Document | Element | Window,
+ options?: {}
+ ) => Promise
+}
-export const fireEvent: FireFunction & FireObject;
+export const fireEvent: FireFunction & FireObject
/**
* Calls a function and notifies Svelte to flush any pending state changes.