test: use screen exposed by React Testing Library (#2832)

This commit is contained in:
Marcin Kulpa 2024-11-04 05:17:52 +01:00 committed by GitHub
parent c87a5d69ad
commit dcc4c098ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 100 additions and 94 deletions

View File

@ -6,7 +6,7 @@ import {
useState,
} from 'react'
import type { ReactNode } from 'react'
import { act, fireEvent, render } from '@testing-library/react'
import { act, fireEvent, render, screen } from '@testing-library/react'
import ReactDOM from 'react-dom'
import { afterEach, expect, it, vi } from 'vitest'
import { create } from 'zustand'
@ -58,13 +58,13 @@ it('uses the store with no args', async () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<>
<Counter />
</>,
)
await findByText('count: 1')
await screen.findByText('count: 1')
})
it('uses the store with selectors', async () => {
@ -80,13 +80,13 @@ it('uses the store with selectors', async () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<>
<Counter />
</>,
)
await findByText('count: 1')
await screen.findByText('count: 1')
})
it('uses the store with a selector and equality checker', async () => {
@ -110,21 +110,21 @@ it('uses the store with a selector and equality checker', async () => {
)
}
const { findByText } = render(
render(
<>
<Component />
</>,
)
await findByText('renderCount: 1, value: 0')
await screen.findByText('renderCount: 1, value: 0')
// This will not cause a re-render.
act(() => setState({ item: { value: 1 } }))
await findByText('renderCount: 1, value: 0')
await screen.findByText('renderCount: 1, value: 0')
// This will cause a re-render.
act(() => setState({ item: { value: 2 } }))
await findByText('renderCount: 2, value: 2')
await screen.findByText('renderCount: 2, value: 2')
})
it('only re-renders if selected state has changed', async () => {
@ -147,16 +147,16 @@ it('only re-renders if selected state has changed', async () => {
return <button onClick={inc}>button</button>
}
const { getByText, findByText } = render(
render(
<>
<Counter />
<Control />
</>,
)
fireEvent.click(getByText('button'))
fireEvent.click(screen.getByText('button'))
await findByText('count: 1')
await screen.findByText('count: 1')
expect(counterRenderCount).toBe(2)
expect(controlRenderCount).toBe(1)
@ -179,13 +179,13 @@ it('can batch updates', async () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<>
<Counter />
</>,
)
await findByText('count: 2')
await screen.findByText('count: 2')
})
it('can update the selector', async () => {
@ -200,19 +200,19 @@ it('can update the selector', async () => {
return <div>{useBoundStore(selector)}</div>
}
const { findByText, rerender } = render(
const { rerender } = render(
<StrictMode>
<Component selector={(s) => s.one} />
</StrictMode>,
)
await findByText('one')
await screen.findByText('one')
rerender(
<StrictMode>
<Component selector={(s) => s.two} />
</StrictMode>,
)
await findByText('two')
await screen.findByText('two')
})
it('can update the equality checker', async () => {
@ -236,7 +236,7 @@ it('can update the equality checker', async () => {
}
// Set an equality checker that always returns false to always re-render.
const { findByText, rerender } = render(
const { rerender } = render(
<>
<Component equalityFn={() => false} />
</>,
@ -244,7 +244,7 @@ it('can update the equality checker', async () => {
// This will cause a re-render due to the equality checker.
act(() => setState({ value: 0 }))
await findByText('renderCount: 2, value: 0')
await screen.findByText('renderCount: 2, value: 0')
// Set an equality checker that always returns true to never re-render.
rerender(
@ -255,7 +255,7 @@ it('can update the equality checker', async () => {
// This will NOT cause a re-render due to the equality checker.
act(() => setState({ value: 1 }))
await findByText('renderCount: 3, value: 0')
await screen.findByText('renderCount: 3, value: 0')
})
it('can call useBoundStore with progressively more arguments', async () => {
@ -282,12 +282,12 @@ it('can call useBoundStore with progressively more arguments', async () => {
}
// Render with no args.
const { findByText, rerender } = render(
const { rerender } = render(
<>
<Component />
</>,
)
await findByText('renderCount: 1, value: {"value":0}')
await screen.findByText('renderCount: 1, value: {"value":0}')
// Render with selector.
rerender(
@ -295,7 +295,7 @@ it('can call useBoundStore with progressively more arguments', async () => {
<Component selector={(s) => s.value} />
</>,
)
await findByText('renderCount: 2, value: 0')
await screen.findByText('renderCount: 2, value: 0')
// Render with selector and equality checker.
rerender(
@ -309,10 +309,10 @@ it('can call useBoundStore with progressively more arguments', async () => {
// Should not cause a re-render because new value is less than previous.
act(() => setState({ value: -1 }))
await findByText('renderCount: 3, value: 0')
await screen.findByText('renderCount: 3, value: 0')
act(() => setState({ value: 1 }))
await findByText('renderCount: 4, value: 1')
await screen.findByText('renderCount: 4, value: 1')
})
it('can throw an error in selector', async () => {
@ -347,19 +347,20 @@ it('can throw an error in selector', async () => {
return <div>no error</div>
}
const { findByText } = render(
render(
<StrictMode>
<ErrorBoundary>
<Component />
</ErrorBoundary>
</StrictMode>,
)
await findByText('no error')
await screen.findByText('no error')
act(() => {
setState({ value: 123 })
})
await findByText('errored')
await screen.findByText('errored')
})
it('can throw an error in equality checker', async () => {
@ -395,19 +396,20 @@ it('can throw an error in equality checker', async () => {
return <div>no error</div>
}
const { findByText } = render(
render(
<StrictMode>
<ErrorBoundary>
<Component />
</ErrorBoundary>
</StrictMode>,
)
await findByText('no error')
await screen.findByText('no error')
act(() => {
setState({ value: 123 })
})
await findByText('errored')
await screen.findByText('errored')
})
it('can get the store', () => {
@ -492,22 +494,22 @@ it('only calls selectors when necessary with static selector', async () => {
)
}
const { rerender, findByText } = render(
const { rerender } = render(
<>
<Component />
</>,
)
await findByText('static: 1')
await screen.findByText('static: 1')
rerender(
<>
<Component />
</>,
)
await findByText('static: 1')
await screen.findByText('static: 1')
act(() => setState({ a: 1, b: 1 }))
await findByText('static: 2')
await screen.findByText('static: 2')
})
it('only calls selectors when necessary (traditional)', async () => {
@ -533,25 +535,25 @@ it('only calls selectors when necessary (traditional)', async () => {
)
}
const { rerender, findByText } = render(
const { rerender } = render(
<>
<Component />
</>,
)
await findByText('inline: 1')
await findByText('static: 1')
await screen.findByText('inline: 1')
await screen.findByText('static: 1')
rerender(
<>
<Component />
</>,
)
await findByText('inline: 2')
await findByText('static: 1')
await screen.findByText('inline: 2')
await screen.findByText('static: 1')
act(() => setState({ a: 1, b: 1 }))
await findByText('inline: 4')
await findByText('static: 2')
await screen.findByText('inline: 4')
await screen.findByText('static: 2')
})
it('ensures parent components subscribe before children', async () => {
@ -592,15 +594,15 @@ it('ensures parent components subscribe before children', async () => {
)
}
const { getByText, findByText } = render(
render(
<StrictMode>
<Parent />
</StrictMode>,
)
fireEvent.click(getByText('change state'))
fireEvent.click(screen.getByText('change state'))
await findByText('child 3')
await screen.findByText('child 3')
})
// https://github.com/pmndrs/zustand/issues/84
@ -635,17 +637,17 @@ it('ensures the correct subscriber is removed on unmount', async () => {
)
}
const { findAllByText } = render(
render(
<>
<Component />
</>,
)
expect((await findAllByText('count: 1')).length).toBe(2)
expect((await screen.findAllByText('count: 1')).length).toBe(2)
act(increment)
expect((await findAllByText('count: 2')).length).toBe(2)
expect((await screen.findAllByText('count: 2')).length).toBe(2)
})
// https://github.com/pmndrs/zustand/issues/86
@ -664,7 +666,7 @@ it('ensures a subscriber is not mistakenly overwritten', async () => {
}
// Add 1st subscriber.
const { findAllByText, rerender } = render(
const { rerender } = render(
<StrictMode>
<Count1 />
</StrictMode>,
@ -689,8 +691,8 @@ it('ensures a subscriber is not mistakenly overwritten', async () => {
// Call all subscribers
act(() => setState({ count: 1 }))
expect((await findAllByText('count1: 1')).length).toBe(2)
expect((await findAllByText('count2: 1')).length).toBe(1)
expect((await screen.findAllByText('count1: 1')).length).toBe(2)
expect((await screen.findAllByText('count2: 1')).length).toBe(1)
})
it('works with non-object state', async () => {
@ -707,16 +709,16 @@ it('works with non-object state', async () => {
)
}
const { getByText, findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 1')
await screen.findByText('count: 1')
fireEvent.click(getByText('button'))
await findByText('count: 2')
fireEvent.click(screen.getByText('button'))
await screen.findByText('count: 2')
})
it('works with "undefined" state', async () => {
@ -733,5 +735,5 @@ it('works with "undefined" state', async () => {
</StrictMode>,
)
await findByText('str: undefined')
await screen.findByText('str: undefined')
})

View File

@ -1,5 +1,5 @@
import { StrictMode, useEffect } from 'react'
import { act, render, waitFor } from '@testing-library/react'
import { act, render, screen, waitFor } from '@testing-library/react'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { create } from 'zustand'
import { createJSONStorage, persist } from 'zustand/middleware'
@ -75,14 +75,14 @@ describe('persist middleware with async configuration', () => {
)
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 0, name: empty')
await findByText('count: 42, name: test-storage')
await screen.findByText('count: 0, name: empty')
await screen.findByText('count: 42, name: test-storage')
expect(onRehydrateStorageSpy).toBeCalledWith(
{ count: 42, name: 'test-storage' },
undefined,
@ -113,13 +113,13 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 0')
await screen.findByText('count: 0')
await waitFor(() => {
expect(onRehydrateStorageSpy).toBeCalledWith(
undefined,
@ -151,19 +151,20 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 0')
await screen.findByText('count: 0')
await waitFor(() => {
expect(onRehydrateStorageSpy).toBeCalledWith({ count: 0 }, undefined)
})
// Write something to the store
act(() => useBoundStore.setState({ count: 42 }))
await findByText('count: 42')
await screen.findByText('count: 42')
expect(setItemSpy).toBeCalledWith(
'test-storage',
JSON.stringify({ state: { count: 42 }, version: 0 }),
@ -180,12 +181,13 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText: findByText2 } = render(
render(
<StrictMode>
<Counter2 />
</StrictMode>,
)
await findByText2('count: 42')
await screen.findByText('count: 42')
await waitFor(() => {
expect(onRehydrateStorageSpy2).toBeCalledWith({ count: 42 }, undefined)
})
@ -221,14 +223,14 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 0')
await findByText('count: 99')
await screen.findByText('count: 0')
await screen.findByText('count: 99')
expect(migrateSpy).toBeCalledWith({ count: 42 }, 12)
expect(setItemSpy).toBeCalledWith(
'test-storage',
@ -283,14 +285,14 @@ describe('persist middleware with async configuration', () => {
)
}
const { findByText } = render(
render(
<StrictMode>
<Component />
</StrictMode>,
)
await findByText('count: 42')
await findByText('name: test')
await screen.findByText('count: 42')
await screen.findByText('name: test')
expect(useBoundStore.getState()).toEqual(
expect.objectContaining({
@ -327,13 +329,13 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 0')
await screen.findByText('count: 0')
await waitFor(() => {
expect(console.error).toHaveBeenCalled()
expect(onRehydrateStorageSpy).toBeCalledWith({ count: 0 }, undefined)
@ -371,13 +373,13 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 0')
await screen.findByText('count: 0')
await waitFor(() => {
expect(onRehydrateStorageSpy).toBeCalledWith(
undefined,
@ -420,13 +422,13 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 1')
await screen.findByText('count: 1')
// The 'onRehydrateStorage' spy is invoked prior to rehydration, so it should
// be passed the default state.
@ -463,13 +465,13 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 0')
await screen.findByText('count: 0')
await waitFor(() => {
expect(onRehydrateStorageSpy).toBeCalledWith(
{ count: 1, unstorableMethod },
@ -515,13 +517,13 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 1')
await screen.findByText('count: 1')
expect(useBoundStore.getState()).toEqual({
count: 1,
actions: {
@ -554,13 +556,13 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 1')
await screen.findByText('count: 1')
expect(useBoundStore.getState()).toEqual({
count: 1,
})
@ -689,13 +691,13 @@ describe('persist middleware with async configuration', () => {
return <div>count: {count}</div>
}
const { findByText } = render(
render(
<StrictMode>
<Counter />
</StrictMode>,
)
await findByText('count: 2')
await screen.findByText('count: 2')
expect(useBoundStore.getState().count).toEqual(2)
})
@ -730,13 +732,13 @@ describe('persist middleware with async configuration', () => {
return <div>map: {map.get('foo')}</div>
}
const { findByText } = render(
render(
<StrictMode>
<MapDisplay />
</StrictMode>,
)
await findByText('map: bar')
await screen.findByText('map: bar')
expect(onRehydrateStorageSpy).toBeCalledWith(
{ map: new Map([['foo', 'bar']]) },
undefined,
@ -767,12 +769,13 @@ describe('persist middleware with async configuration', () => {
return <div>map-content: {map.get('foo')}</div>
}
const { findByText } = render(
render(
<StrictMode>
<MapDisplay />
</StrictMode>,
)
await findByText('map-content:')
await screen.findByText('map-content:')
await waitFor(() => {
expect(onRehydrateStorageSpy).toBeCalledWith({ map }, undefined)
})
@ -780,7 +783,7 @@ describe('persist middleware with async configuration', () => {
// Write something to the store
const updatedMap = new Map(map).set('foo', 'bar')
act(() => useBoundStore.setState({ map: updatedMap }))
await findByText('map-content: bar')
await screen.findByText('map-content: bar')
expect(setItemSpy).toBeCalledWith(
'test-storage',
@ -801,12 +804,13 @@ describe('persist middleware with async configuration', () => {
return <div>map-content: {map.get('foo')}</div>
}
const { findByText: findByText2 } = render(
render(
<StrictMode>
<MapDisplay2 />
</StrictMode>,
)
await findByText2('map-content: bar')
await screen.findByText('map-content: bar')
await waitFor(() => {
expect(onRehydrateStorageSpy2).toBeCalledWith(
{ map: updatedMap },