mirror of
https://github.com/pmndrs/zustand.git
synced 2025-12-08 19:45:52 +00:00
chore(test): stop testing deprecated features and test subscribe in vanilla (#2244)
* chore(test): update test to stop testing deprecated features * chore(test): add subscribe test for zustand/vanilla * chore(test): only verify that subscribe exists on `create` * chore(test): switch type of test
This commit is contained in:
parent
662f38a8c3
commit
9baf0a5d38
@ -3,11 +3,12 @@ import { act, fireEvent, render } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { create } from 'zustand'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { createWithEqualityFn } from 'zustand/traditional'
|
||||
import { shallow } from 'zustand/vanilla/shallow'
|
||||
|
||||
describe('types', () => {
|
||||
it('works with useBoundStore and array selector (#1107)', () => {
|
||||
const useBoundStore = create(() => ({
|
||||
const useBoundStore = createWithEqualityFn(() => ({
|
||||
villages: [] as { name: string }[],
|
||||
}))
|
||||
const Component = () => {
|
||||
@ -18,7 +19,7 @@ describe('types', () => {
|
||||
})
|
||||
|
||||
it('works with useBoundStore and string selector (#1107)', () => {
|
||||
const useBoundStore = create(() => ({
|
||||
const useBoundStore = createWithEqualityFn(() => ({
|
||||
refetchTimestamp: '',
|
||||
}))
|
||||
const Component = () => {
|
||||
|
||||
@ -1,123 +1,9 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { create } from 'zustand'
|
||||
import { subscribeWithSelector } from 'zustand/middleware'
|
||||
|
||||
describe('subscribe()', () => {
|
||||
it('should not be called if new state identity is the same', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = create(() => initialState)
|
||||
|
||||
subscribe(spy)
|
||||
setState(initialState)
|
||||
expect(spy).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should be called if new state identity is different', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, getState, subscribe } = create(() => initialState)
|
||||
|
||||
subscribe(spy)
|
||||
setState({ ...getState() })
|
||||
expect(spy).toHaveBeenCalledWith(initialState, initialState)
|
||||
})
|
||||
|
||||
it('should not be called when state slice is the same', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = create(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
subscribe((s) => s.value, spy)
|
||||
setState({ other: 'b' })
|
||||
expect(spy).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should be called when state slice changes', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = create(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
subscribe((s) => s.value, spy)
|
||||
setState({ value: initialState.value + 1 })
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
expect(spy).toHaveBeenCalledWith(initialState.value + 1, initialState.value)
|
||||
})
|
||||
|
||||
it('should not be called when equality checker returns true', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = create(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
subscribe((s) => s, spy, { equalityFn: () => true })
|
||||
setState({ value: initialState.value + 2 })
|
||||
expect(spy).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should be called when equality checker returns false', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = create(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
subscribe((s) => s.value, spy, { equalityFn: () => false })
|
||||
setState({ value: initialState.value + 2 })
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
expect(spy).toHaveBeenCalledWith(initialState.value + 2, initialState.value)
|
||||
})
|
||||
|
||||
it('should unsubscribe correctly', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = create(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
const unsub = subscribe((s) => s.value, spy)
|
||||
|
||||
setState({ value: initialState.value + 1 })
|
||||
unsub()
|
||||
setState({ value: initialState.value + 2 })
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
expect(spy).toHaveBeenCalledWith(initialState.value + 1, initialState.value)
|
||||
})
|
||||
|
||||
it('should keep consistent behavior with equality check', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { getState, setState, subscribe } = create(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
const isRoughEqual = (x: number, y: number) => Math.abs(x - y) < 1
|
||||
setState({ value: 0 })
|
||||
spy.mockReset()
|
||||
const spy2 = vi.fn()
|
||||
let prevValue = getState().value
|
||||
const unsub = subscribe((s) => {
|
||||
if (isRoughEqual(prevValue, s.value)) {
|
||||
// skip assuming values are equal
|
||||
return
|
||||
}
|
||||
spy(s.value, prevValue)
|
||||
prevValue = s.value
|
||||
})
|
||||
const unsub2 = subscribe((s) => s.value, spy2, { equalityFn: isRoughEqual })
|
||||
setState({ value: 0.5 })
|
||||
setState({ value: 1 })
|
||||
unsub()
|
||||
unsub2()
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
expect(spy).toHaveBeenCalledWith(1, 0)
|
||||
expect(spy2).toHaveBeenCalledTimes(1)
|
||||
expect(spy2).toHaveBeenCalledWith(1, 0)
|
||||
it('should correctly have access to subscribe', () => {
|
||||
const { subscribe } = create(() => ({ value: 1 }))
|
||||
expect(typeof subscribe).toBe('function')
|
||||
})
|
||||
})
|
||||
|
||||
123
tests/vanilla/subscribe.test.tsx
Normal file
123
tests/vanilla/subscribe.test.tsx
Normal file
@ -0,0 +1,123 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { subscribeWithSelector } from 'zustand/middleware'
|
||||
import { createStore } from 'zustand/vanilla'
|
||||
|
||||
describe('subscribe()', () => {
|
||||
it('should not be called if new state identity is the same', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = createStore(() => initialState)
|
||||
|
||||
subscribe(spy)
|
||||
setState(initialState)
|
||||
expect(spy).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should be called if new state identity is different', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, getState, subscribe } = createStore(() => initialState)
|
||||
|
||||
subscribe(spy)
|
||||
setState({ ...getState() })
|
||||
expect(spy).toHaveBeenCalledWith(initialState, initialState)
|
||||
})
|
||||
|
||||
it('should not be called when state slice is the same', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = createStore(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
subscribe((s) => s.value, spy)
|
||||
setState({ other: 'b' })
|
||||
expect(spy).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should be called when state slice changes', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = createStore(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
subscribe((s) => s.value, spy)
|
||||
setState({ value: initialState.value + 1 })
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
expect(spy).toHaveBeenCalledWith(initialState.value + 1, initialState.value)
|
||||
})
|
||||
|
||||
it('should not be called when equality checker returns true', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = createStore(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
subscribe((s) => s, spy, { equalityFn: () => true })
|
||||
setState({ value: initialState.value + 2 })
|
||||
expect(spy).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should be called when equality checker returns false', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = createStore(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
subscribe((s) => s.value, spy, { equalityFn: () => false })
|
||||
setState({ value: initialState.value + 2 })
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
expect(spy).toHaveBeenCalledWith(initialState.value + 2, initialState.value)
|
||||
})
|
||||
|
||||
it('should unsubscribe correctly', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { setState, subscribe } = createStore(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
const unsub = subscribe((s) => s.value, spy)
|
||||
|
||||
setState({ value: initialState.value + 1 })
|
||||
unsub()
|
||||
setState({ value: initialState.value + 2 })
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
expect(spy).toHaveBeenCalledWith(initialState.value + 1, initialState.value)
|
||||
})
|
||||
|
||||
it('should keep consistent behavior with equality check', () => {
|
||||
const spy = vi.fn()
|
||||
const initialState = { value: 1, other: 'a' }
|
||||
const { getState, setState, subscribe } = createStore(
|
||||
subscribeWithSelector(() => initialState),
|
||||
)
|
||||
|
||||
const isRoughEqual = (x: number, y: number) => Math.abs(x - y) < 1
|
||||
setState({ value: 0 })
|
||||
spy.mockReset()
|
||||
const spy2 = vi.fn()
|
||||
let prevValue = getState().value
|
||||
const unsub = subscribe((s) => {
|
||||
if (isRoughEqual(prevValue, s.value)) {
|
||||
// skip assuming values are equal
|
||||
return
|
||||
}
|
||||
spy(s.value, prevValue)
|
||||
prevValue = s.value
|
||||
})
|
||||
const unsub2 = subscribe((s) => s.value, spy2, { equalityFn: isRoughEqual })
|
||||
setState({ value: 0.5 })
|
||||
setState({ value: 1 })
|
||||
unsub()
|
||||
unsub2()
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
expect(spy).toHaveBeenCalledWith(1, 0)
|
||||
expect(spy2).toHaveBeenCalledTimes(1)
|
||||
expect(spy2).toHaveBeenCalledWith(1, 0)
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user