Skip to content

Commit fa5dca4

Browse files
Add loadProject store test
1 parent 33152af commit fa5dca4

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

src/__mocks__/zustand.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copied from https://zustand.docs.pmnd.rs/guides/testing#jest
2+
// __mocks__/zustand.ts
3+
import * as zustand from "zustand";
4+
import { act } from "@testing-library/react";
5+
6+
const { create: actualCreate, createStore: actualCreateStore } =
7+
jest.requireActual<typeof zustand>("zustand");
8+
9+
// a variable to hold reset functions for all stores declared in the app
10+
export const storeResetFns = new Set<() => void>();
11+
12+
const createUncurried = <T>(stateCreator: zustand.StateCreator<T>) => {
13+
const store = actualCreate(stateCreator);
14+
const initialState = store.getInitialState();
15+
storeResetFns.add(() => {
16+
store.setState(initialState, true);
17+
});
18+
return store;
19+
};
20+
21+
// when creating a store, we get its initial state, create a reset function and add it in the set
22+
export const create = (<T>(stateCreator: zustand.StateCreator<T>) => {
23+
console.log("zustand create mock");
24+
25+
// to support curried version of create
26+
return typeof stateCreator === "function"
27+
? createUncurried(stateCreator)
28+
: createUncurried;
29+
}) as typeof zustand.create;
30+
31+
const createStoreUncurried = <T>(stateCreator: zustand.StateCreator<T>) => {
32+
const store = actualCreateStore(stateCreator);
33+
const initialState = store.getInitialState();
34+
storeResetFns.add(() => {
35+
store.setState(initialState, true);
36+
});
37+
return store;
38+
};
39+
40+
// when creating a store, we get its initial state, create a reset function and add it in the set
41+
export const createStore = (<T>(stateCreator: zustand.StateCreator<T>) => {
42+
console.log("zustand createStore mock");
43+
44+
// to support curried version of createStore
45+
return typeof stateCreator === "function"
46+
? createStoreUncurried(stateCreator)
47+
: createStoreUncurried;
48+
}) as typeof zustand.createStore;
49+
50+
// reset all stores after each test run
51+
afterEach(() => {
52+
act(() => {
53+
storeResetFns.forEach((resetFn) => {
54+
resetFn();
55+
});
56+
});
57+
});

src/store.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { act, renderHook } from "@testing-library/react";
2+
import { useStore } from "./store";
3+
import { Project } from "@microbit/makecode-embed/react";
4+
import { makecodeIcons } from "./utils/icons";
5+
import { GestureData } from "./model";
6+
7+
const projectHeader = {
8+
target: "microbit",
9+
targetVersion: "7.0.42",
10+
editor: "blocksprj",
11+
name: "Simple AI exercise timer",
12+
meta: {},
13+
pubId: "",
14+
pubCurrent: false,
15+
id: "f102d806-f767-45c6-3af3-35b3be9dbdcd",
16+
recentUse: 1728049865,
17+
modificationTime: 1728049865,
18+
path: "Simple-AI-exercise-timer",
19+
cloudCurrent: false,
20+
saveId: null,
21+
githubCurrent: false,
22+
_rev: "",
23+
isDeleted: false,
24+
cloudVersion: "",
25+
cloudLastSyncTime: 1,
26+
};
27+
28+
const gestureData = [
29+
{ name: "action1", ID: 1, icon: makecodeIcons.Heart, recordings: [] },
30+
{ name: "action2", ID: 2, icon: makecodeIcons.House, recordings: [] },
31+
] as GestureData[];
32+
33+
const sampleProject: Project = {
34+
header: projectHeader,
35+
text: {
36+
"README.md": "",
37+
"autogenerated.ts": "",
38+
"dataset.json": JSON.stringify({ data: gestureData }),
39+
},
40+
};
41+
42+
describe("loadProject", () => {
43+
test("imports gesture data", () => {
44+
const { result } = renderHook(() => useStore());
45+
act(() => result.current.loadProject(sampleProject));
46+
47+
expect(result.current.gestures.length).toEqual(gestureData.length);
48+
expect(result.current.model).toEqual(undefined);
49+
});
50+
});

0 commit comments

Comments
 (0)