Skip to content

Commit

Permalink
Move regression tests for useSnapshot perf improvement to optimizatio…
Browse files Browse the repository at this point in the history
…n test file
  • Loading branch information
endash committed May 3, 2024
1 parent df94b9e commit 242839b
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 112 deletions.
112 changes: 0 additions & 112 deletions tests/basic.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,118 +173,6 @@ it('no extra re-renders (render func calls in non strict mode)', async () => {
expect(renderFn2).lastCalledWith(2)
})

it('no extra re-renders with nested useSnapshot (render func calls in non strict mode)', async () => {
const obj = proxy({ childCount: 0, parentCount: 0 })

const childRenderFn = vi.fn()
const Child = () => {
const snap = useSnapshot(obj)
childRenderFn(snap.childCount)
return (
<>
<div>childCount: {snap.childCount}</div>
<button onClick={() => ++obj.childCount}>childButton</button>
</>
)
}

const parentRenderFn = vi.fn()
const Parent = () => {
const snap = useSnapshot(obj)
parentRenderFn(snap.parentCount)
return (
<>
<div>parentCount: {snap.parentCount}</div>
<button onClick={() => ++obj.parentCount}>parentButton</button>
<Child />
</>
)
}

const { getByText } = render(<Parent />)

await waitFor(() => {
getByText('childCount: 0')
getByText('parentCount: 0')
})

expect(childRenderFn).toBeCalledTimes(1)
expect(childRenderFn).lastCalledWith(0)
expect(parentRenderFn).toBeCalledTimes(1)
expect(parentRenderFn).lastCalledWith(0)

obj.parentCount += 1

await waitFor(() => {
getByText('childCount: 0')
getByText('parentCount: 1')
})

expect(childRenderFn).toBeCalledTimes(2)
expect(childRenderFn).lastCalledWith(0)
expect(parentRenderFn).toBeCalledTimes(2)
expect(parentRenderFn).lastCalledWith(1)
})

it('no extra re-renders with child useSnapshot component (render func calls in non strict mode)', async () => {
const obj = proxy({ childCount: 0, anotherValue: 0 })

const childRenderFn = vi.fn()
const Child = () => {
const snap = useSnapshot(obj)
childRenderFn(snap.childCount)
return (
<>
<div>childCount: {snap.childCount}</div>
<button onClick={() => ++obj.childCount}>childButton</button>
</>
)
}

const parentRenderFn = vi.fn()
const Parent = () => {
const [parentCount, setParentCount] = useState(0)

parentRenderFn(parentCount)

return (
<>
<div>parentCount: {parentCount}</div>
<button onClick={() => setParentCount((v) => v + 1)}>
parentButton
</button>
<Child />
</>
)
}

const { getByText } = render(<Parent />)

await waitFor(() => {
getByText('childCount: 0')
getByText('parentCount: 0')
})

expect(childRenderFn).toBeCalledTimes(1)
expect(childRenderFn).lastCalledWith(0)
expect(parentRenderFn).toBeCalledTimes(1)
expect(parentRenderFn).lastCalledWith(0)

obj.anotherValue += 1

fireEvent.click(getByText('parentButton'))

await waitFor(() => {
getByText('childCount: 0')
getByText('parentCount: 1')
})

expect(childRenderFn).toBeCalledTimes(2)
expect(childRenderFn).lastCalledWith(0)
expect(parentRenderFn).toBeCalledTimes(2)
expect(parentRenderFn).lastCalledWith(1)
})

it('object in object', async () => {
const obj = proxy({ object: { count: 0 } })

Expand Down
116 changes: 116 additions & 0 deletions tests/optimization.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { useState } from 'react'
import { fireEvent, render, waitFor } from '@testing-library/react'
import { expect, it, vi } from 'vitest'
import { proxy, snapshot, useSnapshot } from 'valtio'

Check warning on line 4 in tests/optimization.test.tsx

View workflow job for this annotation

GitHub Actions / lint

'snapshot' is defined but never used. Allowed unused vars must match /^_/u

it('regression: useSnapshot renders should not fail consistency check with extra render (nested useSnapshot)', async () => {
const obj = proxy({ childCount: 0, parentCount: 0 })

const childRenderFn = vi.fn()
const Child = () => {
const snap = useSnapshot(obj)
childRenderFn(snap.childCount)
return (
<>
<div>childCount: {snap.childCount}</div>
<button onClick={() => ++obj.childCount}>childButton</button>
</>
)
}

const parentRenderFn = vi.fn()
const Parent = () => {
const snap = useSnapshot(obj)
parentRenderFn(snap.parentCount)
return (
<>
<div>parentCount: {snap.parentCount}</div>
<button onClick={() => ++obj.parentCount}>parentButton</button>
<Child />
</>
)
}

const { getByText } = render(<Parent />)

await waitFor(() => {
getByText('childCount: 0')
getByText('parentCount: 0')
})

expect(childRenderFn).toBeCalledTimes(1)
expect(childRenderFn).lastCalledWith(0)
expect(parentRenderFn).toBeCalledTimes(1)
expect(parentRenderFn).lastCalledWith(0)

obj.parentCount += 1

await waitFor(() => {
getByText('childCount: 0')
getByText('parentCount: 1')
})

expect(childRenderFn).toBeCalledTimes(2)
expect(childRenderFn).lastCalledWith(0)
expect(parentRenderFn).toBeCalledTimes(2)
expect(parentRenderFn).lastCalledWith(1)
})

it('regression: useSnapshot renders should not fail consistency check with extra render', async () => {
const obj = proxy({ childCount: 0, anotherValue: 0 })

const childRenderFn = vi.fn()
const Child = () => {
const snap = useSnapshot(obj)
childRenderFn(snap.childCount)
return (
<>
<div>childCount: {snap.childCount}</div>
<button onClick={() => ++obj.childCount}>childButton</button>
</>
)
}

const parentRenderFn = vi.fn()
const Parent = () => {
const [parentCount, setParentCount] = useState(0)

parentRenderFn(parentCount)

return (
<>
<div>parentCount: {parentCount}</div>
<button onClick={() => setParentCount((v) => v + 1)}>
parentButton
</button>
<Child />
</>
)
}

const { getByText } = render(<Parent />)

await waitFor(() => {
getByText('childCount: 0')
getByText('parentCount: 0')
})

expect(childRenderFn).toBeCalledTimes(1)
expect(childRenderFn).lastCalledWith(0)
expect(parentRenderFn).toBeCalledTimes(1)
expect(parentRenderFn).lastCalledWith(0)

obj.anotherValue += 1

fireEvent.click(getByText('parentButton'))

await waitFor(() => {
getByText('childCount: 0')
getByText('parentCount: 1')
})

expect(childRenderFn).toBeCalledTimes(2)
expect(childRenderFn).lastCalledWith(0)
expect(parentRenderFn).toBeCalledTimes(2)
expect(parentRenderFn).lastCalledWith(1)
})

0 comments on commit 242839b

Please sign in to comment.