Skip to content

Commit

Permalink
use latest zustand testing docs (#188)
Browse files Browse the repository at this point in the history
  • Loading branch information
charkour authored Oct 12, 2024
1 parent 3541243 commit cec8ec4
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 39 deletions.
58 changes: 45 additions & 13 deletions tests/__mocks__/zustand/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,54 @@
import { type StateCreator, create as actualCreate } from 'zustand';
import { act } from 'react-dom/test-utils';
import { afterEach } from 'vitest';
// https://github.com/pmndrs/zustand/blob/main/docs/guides/testing.md
import * as zustand from 'zustand';
import { act } from '@testing-library/react';

const { create: actualCreate, createStore: actualCreateStore } =
await vi.importActual<typeof zustand>('zustand');

// a variable to hold reset functions for all stores declared in the app
const storeResetFns = new Set<() => void>();
export const storeResetFns = new Set<() => void>();

const createUncurried = <T>(stateCreator: zustand.StateCreator<T>) => {
const store = actualCreate(stateCreator);
const initialState = store.getInitialState();
storeResetFns.add(() => {
store.setState(initialState, true);
});
return store;
};

// when creating a store, we get its initial state, create a reset function and add it in the set
const createStore = (createState: StateCreator<unknown>) => {
if (!createState) return createStore;
const store = actualCreate(createState);
const initialState = store.getState();
storeResetFns.add(() => store.setState(initialState, true));
export const create = (<T>(stateCreator: zustand.StateCreator<T>) => {
// to support curried version of create
return typeof stateCreator === 'function'
? createUncurried(stateCreator)
: createUncurried;
}) as typeof zustand.create;

const createStoreUncurried = <T>(stateCreator: zustand.StateCreator<T>) => {
const store = actualCreateStore(stateCreator);
const initialState = store.getInitialState();
storeResetFns.add(() => {
store.setState(initialState, true);
});
return store;
};

// Reset all stores after each test run
// when creating a store, we get its initial state, create a reset function and add it in the set
export const createStore = (<T>(stateCreator: zustand.StateCreator<T>) => {
// to support curried version of createStore
return typeof stateCreator === 'function'
? createStoreUncurried(stateCreator)
: createStoreUncurried;
}) as typeof zustand.createStore;

export const { useStore } = zustand;

// reset all stores after each test run
afterEach(() => {
act(() => storeResetFns.forEach((resetFn) => resetFn()));
act(() => {
storeResetFns.forEach((resetFn) => {
resetFn();
});
});
});

export { createStore };
5 changes: 2 additions & 3 deletions tests/__tests__/createVanillaTemporal.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { describe, it, expect, vi } from 'vitest';
vi.mock('zustand');
import { describe, it, expect } from 'vitest';
import { temporalStateCreator } from '../../src/temporal';
import { createStore } from 'zustand';
import { act } from 'react-dom/test-utils';
import { act } from '@testing-library/react';

interface MyState {
count: number;
Expand Down
4 changes: 1 addition & 3 deletions tests/__tests__/options.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';

vi.mock('zustand');
import { temporal } from '../../src/index';
import { createStore, type StoreApi } from 'zustand';
import { act } from 'react-dom/test-utils';
import { act } from '@testing-library/react';
import { shallow } from 'zustand/shallow';
import type {
_TemporalState,
Expand Down
14 changes: 4 additions & 10 deletions tests/__tests__/react.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { describe, it, expect } from 'vitest';
import React from 'react';
import { fireEvent, render } from '@testing-library/react';

describe('React Re-renders when state changes', () => {
it('it', () => {
const { queryByLabelText, getByLabelText, queryByText, getByText } = render(
<Reactive />,
);
const { queryByText, getByText } = render(<Reactive />);

expect(queryByText(/bears: 0/i)).toBeTruthy();
expect(queryByText(/increment/i)).toBeTruthy();
Expand Down Expand Up @@ -77,9 +74,8 @@ const useTemporalStore = <
U,
>(
selector: (state: ExtractState<S>) => U,
equality?: (a: U, b: U) => boolean,
): U => {
const state = useStore(useMyStore.temporal as any, selector, equality);
const state = useStore(useMyStore.temporal as any, selector);
return state;
};

Expand All @@ -97,10 +93,8 @@ const HistoryBar = () => {
};

const UndoBar = () => {
const { undo, redo } = useTemporalStore((state) => ({
undo: state.undo,
redo: state.redo,
}));
const undo = useTemporalStore((state) => state.undo);
const redo = useTemporalStore((state) => state.redo);
return (
<div>
<button onClick={() => undo()}>undo</button>
Expand Down
3 changes: 1 addition & 2 deletions tests/__tests__/zundo.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
vi.mock('zustand');
import { temporal } from '../../src/index';
import { createStore, type StoreApi } from 'zustand';
import { act } from 'react-dom/test-utils';
import { act } from '@testing-library/react';
import type { TemporalState, Write } from '../../src/types';

interface MyState {
Expand Down
1 change: 1 addition & 0 deletions tests/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
"resolveJsonModule": true,
"esModuleInterop": true,
"moduleResolution": "Bundler",
"types": ["vitest/globals"]
}
}
1 change: 0 additions & 1 deletion tests/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export default defineConfig({
environment: 'happy-dom',
dir: '.',
setupFiles: ['./vitest.setup.ts', 'vitest-localstorage-mock'],
mockReset: false,
coverage: {
include: ['**/src/**/*.{ts,tsx}'],
allowExternal: true,
Expand Down
10 changes: 3 additions & 7 deletions tests/vitest.setup.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import { afterEach } from 'vitest';
import { cleanup } from '@testing-library/react';
import '@testing-library/jest-dom/vitest';
// https://github.com/pmndrs/zustand/blob/main/docs/guides/testing.md
import '@testing-library/jest-dom';

// runs a cleanup after each test case (e.g. clearing happy-dom)
afterEach(() => {
cleanup();
});
vi.mock('zustand'); // to make it work like Jest (auto-mocking)

0 comments on commit cec8ec4

Please sign in to comment.