Skip to content

merge branch-align-render-options with next #331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
48 changes: 0 additions & 48 deletions src/__tests__/__snapshots__/render.test.js.snap

This file was deleted.

8 changes: 4 additions & 4 deletions src/__tests__/debug.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ import Comp from './fixtures/Comp.svelte'

describe('debug', () => {
beforeEach(() => {
vi.spyOn(console, 'log').mockImplementation(() => { })
vi.spyOn(console, 'log').mockImplementation(() => {})
})

afterEach(() => {
console.log.mockRestore()
})

test('pretty prints the container', () => {
const { container, debug } = render(Comp, { props: { name: 'world' } })
test('pretty prints the base element', () => {
const { baseElement, debug } = render(Comp, { props: { name: 'world' } })

debug()

expect(console.log).toHaveBeenCalledTimes(1)
expect(console.log).toHaveBeenCalledWith(prettyDOM(container))
expect(console.log).toHaveBeenCalledWith(prettyDOM(baseElement))
})
})
10 changes: 4 additions & 6 deletions src/__tests__/fixtures/Comp.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@

let buttonText = 'Button'

const contextName = getContext('name')

function handleClick () {
function handleClick() {
buttonText = 'Button Clicked'
}

const contextName = getContext('name')
</script>

<h1 data-testid="test">Hello {name}!</h1>

<div>we have {contextName}</div>

<button on:click={handleClick}>{buttonText}</button>

<style></style>
<div>we have {contextName}</div>
15 changes: 0 additions & 15 deletions src/__tests__/fixtures/Comp2.svelte

This file was deleted.

17 changes: 0 additions & 17 deletions src/__tests__/fixtures/Rerender.svelte

This file was deleted.

2 changes: 2 additions & 0 deletions src/__tests__/fixtures/Simple.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script lang="ts">
export let name: string
export let count: number
</script>

<h1>hello {name}</h1>
<p>count: {count}</p>
134 changes: 63 additions & 71 deletions src/__tests__/render.test.js
Original file line number Diff line number Diff line change
@@ -1,119 +1,111 @@
import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
import { beforeEach, describe, expect, test } from 'vitest'
import { describe, expect, test } from 'vitest'

import { act, render as stlRender } from '@testing-library/svelte'
import { act, render } from '@testing-library/svelte'
import Comp from './fixtures/Comp.svelte'
import CompDefault from './fixtures/Comp2.svelte'

describe('render', () => {
let props

const render = (additional = {}) => {
return stlRender(Comp, {
target: document.body,
props,
...additional,
})
}

beforeEach(() => {
props = {
name: 'World',
}
})
const props = { name: 'World' }

test('renders component into the document', () => {
const { getByText } = render()
const { getByText } = render(Comp, { props })

expect(getByText('Hello World!')).toBeInTheDocument()
})

// Dear reader, this is not something you generally want to do in your tests.
test('programmatically change props', async () => {
const { component, getByText } = render()

test('accepts props directly', () => {
const { getByText } = render(Comp, props)
expect(getByText('Hello World!')).toBeInTheDocument()
})

await act(() => {
component.$set({ name: 'Worlds' })
})
test('throws error when mixing svelte component options and props', () => {
expect(() => {
render(Comp, { props, name: 'World' })
}).toThrow(/Unknown options/)
})

expect(getByText('Hello Worlds!')).toBeInTheDocument()
test('throws error when mixing target option and props', () => {
expect(() => {
render(Comp, { target: document.createElement('div'), name: 'World' })
}).toThrow(/Unknown options/)
})

test('change props with accessors', async () => {
const { component, getByText } = render(
SVELTE_VERSION < '5' ? { accessors: true } : {}
)
test('should return a container object wrapping the DOM of the rendered component', () => {
const { container, getByTestId } = render(Comp, props)
const firstElement = getByTestId('test')

expect(getByText('Hello World!')).toBeInTheDocument()
expect(container.firstChild).toBe(firstElement)
})

expect(component.name).toBe('World')
test('should return a baseElement object, which holds the container', () => {
const { baseElement, container } = render(Comp, props)

await act(() => {
component.value = 'Planet'
})
expect(baseElement).toBe(document.body)
expect(baseElement.firstChild).toBe(container)
})

expect(getByText('Hello World!')).toBeInTheDocument()
test('if target is provided, use it as container and baseElement', () => {
const target = document.createElement('div')
const { baseElement, container } = render(Comp, { props, target })

expect(container).toBe(target)
expect(baseElement).toBe(target)
})

test('should accept props directly', () => {
const { getByText } = stlRender(Comp, { name: 'World' })
expect(getByText('Hello World!')).toBeInTheDocument()
test('allow baseElement to be specified', () => {
const customBaseElement = document.createElement('div')

const { baseElement, container } = render(
Comp,
{ props },
{ baseElement: customBaseElement }
)

expect(baseElement).toBe(customBaseElement)
expect(baseElement.firstChild).toBe(container)
})

test.runIf(SVELTE_VERSION < '5')(
'should accept svelte v4 component options',
() => {
const target = document.createElement('div')
const div = document.createElement('div')
document.body.appendChild(target)
target.appendChild(div)
const { container } = stlRender(Comp, {
target,
anchor: div,
props: { name: 'World' },
context: new Map([['name', 'context']]),
})
expect(container).toMatchSnapshot()
}
)

test.runIf(SVELTE_VERSION >= '5')(
'should accept svelte v5 component options',
'should accept anchor option in Svelte v4',
() => {
const baseElement = document.body
const target = document.createElement('section')
document.body.appendChild(target)

const { container } = stlRender(Comp, {
target,
props: { name: 'World' },
context: new Map([['name', 'context']]),
})
expect(container).toMatchSnapshot()
const anchor = document.createElement('div')
baseElement.appendChild(target)
target.appendChild(anchor)

const { getByTestId } = render(
Comp,
{ props, target, anchor },
{ baseElement }
)
const firstElement = getByTestId('test')

expect(target.firstChild).toBe(firstElement)
expect(target.lastChild).toBe(anchor)
}
)

test('should throw error when mixing svelte component options and props', () => {
expect(() => {
stlRender(Comp, { props: {}, name: 'World' })
render(Comp, { props: {}, name: 'World' })
}).toThrow(/Unknown options were found/)
})

test('should return a container object, which contains the DOM of the rendered component', () => {
const { container } = render()
const { baseElement } = render(Comp)

expect(container.innerHTML).toBe(document.body.innerHTML)
expect(baseElement.innerHTML).toBe(document.body.innerHTML)
})

test('correctly find component constructor on the default property', () => {
const { getByText } = stlRender(CompDefault, { props: { name: 'World' } })
const { getByText } = render(Comp, { props: { name: 'World' } })

expect(getByText('Hello World!')).toBeInTheDocument()
})

test("accept the 'context' option", () => {
const { getByText } = stlRender(Comp, {
const { getByText } = render(Comp, {
props: { name: 'Universe' },
context: new Map([['name', 'context']]),
})
Expand Down
63 changes: 38 additions & 25 deletions src/__tests__/rerender.test.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,54 @@
/**
* @jest-environment jsdom
*/
import { expect, test, vi } from 'vitest'
import { describe, expect, test, vi } from 'vitest'
import { VERSION as SVELTE_VERSION } from 'svelte/compiler'

import { render, waitFor } from '@testing-library/svelte'
import { act, screen, render, waitFor } from '@testing-library/svelte'

import Comp from './fixtures/Rerender.svelte'
import Comp from './fixtures/Comp.svelte'

test('mounts new component successfully', async () => {
const onMounted = vi.fn()
const onDestroyed = vi.fn()
describe('rerender', () => {
test('updates props', async () => {
const { rerender } = render(Comp, { name: 'World' })
const element = screen.getByText('Hello World!')

const { getByTestId, rerender } = render(Comp, {
props: { name: 'World 1', onMounted, onDestroyed },
await rerender({ name: 'Dolly' })

expect(element).toHaveTextContent('Hello Dolly!')
})

const expectToRender = (content) =>
waitFor(() => {
expect(getByTestId('test')).toHaveTextContent(content)
expect(onMounted).toHaveBeenCalledOnce()
})
test('warns if incorrect arguments shape used', async () => {
vi.stubGlobal('console', { warn: vi.fn() })

const { rerender } = render(Comp, { name: 'World' })
const element = screen.getByText('Hello World!')

await expectToRender('Hello World 1!')
await rerender({ props: { name: 'Dolly' } })

console.warn = vi.fn()
expect(element).toHaveTextContent('Hello Dolly!')
expect(console.warn).toHaveBeenCalledOnce()
expect(console.warn).toHaveBeenCalledWith(
expect.stringMatching(/deprecated/iu)
)
})

rerender({ props: { name: 'World 2' } })
await expectToRender('Hello World 2!')
expect(onDestroyed).not.toHaveBeenCalled()
test('change props with accessors', async () => {
const { component, getByText } = render(
Comp,
SVELTE_VERSION < '5'
? { accessors: true, props: { name: 'World' } }
: { name: 'World' }
)
const element = getByText('Hello World!')

expect(console.warn).toHaveBeenCalledOnce()
expect(element).toBeInTheDocument()
expect(component.name).toBe('World')

console.warn.mockClear()
onDestroyed.mockReset()
rerender({ name: 'World 3' })
await expectToRender('Hello World 3!')
expect(onDestroyed).not.toHaveBeenCalled()
await act(() => {
component.name = 'Planet'
})

expect(console.warn).not.toHaveBeenCalled()
expect(element).toHaveTextContent('Hello Planet!')
})
})
Loading