Skip to content

Commit

Permalink
chore: reformat
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvander committed Aug 22, 2024
1 parent 1d0d149 commit 38f9c3b
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 120 deletions.
2 changes: 1 addition & 1 deletion commitlint.config.mjs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export default { extends: ["@commitlint/config-conventional"] };
export default { extends: ["@commitlint/config-conventional"] }
16 changes: 2 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,8 @@
}
},
"description": "A Zustand middleware to create computed states.",
"files": [
"/dist"
],
"keywords": [
"zustand",
"computed",
"calculated",
"state",
"react",
"plugin",
"middleware",
"npm",
"typescript"
],
"files": ["/dist"],
"keywords": ["zustand", "computed", "calculated", "state", "react", "plugin", "middleware", "npm", "typescript"],
"license": "MIT",
"scripts": {
"check": "biome check --write",
Expand Down
210 changes: 105 additions & 105 deletions src/computed.test.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
import { describe, expect, test, beforeEach, mock } from "bun:test";
import { type StateCreator, create } from "zustand";
import { type ComputedStateOpts, computed } from "./computed";
import { describe, expect, test, beforeEach, mock } from "bun:test"
import { type StateCreator, create } from "zustand"
import { type ComputedStateOpts, computed } from "./computed"

type Store = {
count: number;
x: number;
y: number;
inc: () => void;
dec: () => void;
};
count: number
x: number
y: number
inc: () => void
dec: () => void
}

type ComputedStore = {
countSq: number;
countSq: number
nestedResult: {
stringified: string;
};
};
stringified: string
}
}

function computeState(state: Store): ComputedStore {
const nestedResult = {
stringified: JSON.stringify(state.count),
};
}

return {
countSq: state.count ** 2,
nestedResult,
};
}
}

describe("default config", () => {
const computeStateMock = mock(computeState);
const computeStateMock = mock(computeState)
const makeStore = () =>
create<Store, [["chrisvander/zustand-computed", ComputedStore]]>(
computed(
Expand All @@ -42,52 +42,52 @@ describe("default config", () => {
}),
computeStateMock,
),
);
)

let useStore: ReturnType<typeof makeStore>;
let useStore: ReturnType<typeof makeStore>
beforeEach(() => {
computeStateMock.mockClear();
useStore = makeStore();
});
computeStateMock.mockClear()
useStore = makeStore()
})

test("computed works on simple counter example", () => {
// note: this function should have been called once on store creation
expect(computeStateMock).toHaveBeenCalledTimes(1);
expect(useStore.getState().count).toEqual(1);
expect(useStore.getState().countSq).toEqual(1);
useStore.getState().inc();
expect(useStore.getState().count).toEqual(2);
expect(useStore.getState().countSq).toEqual(4);
useStore.getState().dec();
expect(useStore.getState().count).toEqual(1);
expect(useStore.getState().countSq).toEqual(1);
useStore.setState({ count: 4 });
expect(useStore.getState().countSq).toEqual(16);
expect(computeStateMock).toHaveBeenCalledTimes(4);
});
expect(computeStateMock).toHaveBeenCalledTimes(1)
expect(useStore.getState().count).toEqual(1)
expect(useStore.getState().countSq).toEqual(1)
useStore.getState().inc()
expect(useStore.getState().count).toEqual(2)
expect(useStore.getState().countSq).toEqual(4)
useStore.getState().dec()
expect(useStore.getState().count).toEqual(1)
expect(useStore.getState().countSq).toEqual(1)
useStore.setState({ count: 4 })
expect(useStore.getState().countSq).toEqual(16)
expect(computeStateMock).toHaveBeenCalledTimes(4)
})

test("computed does not modify object ref even after change", () => {
useStore.setState({ count: 4 });
expect(useStore.getState().count).toEqual(4);
const obj = useStore.getState().nestedResult;
useStore.setState({ count: 4 });
const toCompare = useStore.getState().nestedResult;
expect(obj).toEqual(toCompare);
});
useStore.setState({ count: 4 })
expect(useStore.getState().count).toEqual(4)
const obj = useStore.getState().nestedResult
useStore.setState({ count: 4 })
const toCompare = useStore.getState().nestedResult
expect(obj).toEqual(toCompare)
})

test("modifying variables x and y do not trigger compute function more than once, as they are not used in compute function", () => {
expect(computeStateMock).toHaveBeenCalledTimes(1);
useStore.setState({ x: 2 });
expect(computeStateMock).toHaveBeenCalledTimes(2);
useStore.setState({ x: 3 });
expect(computeStateMock).toHaveBeenCalledTimes(2);
useStore.setState({ y: 2 });
expect(computeStateMock).toHaveBeenCalledTimes(2);
});
});
expect(computeStateMock).toHaveBeenCalledTimes(1)
useStore.setState({ x: 2 })
expect(computeStateMock).toHaveBeenCalledTimes(2)
useStore.setState({ x: 3 })
expect(computeStateMock).toHaveBeenCalledTimes(2)
useStore.setState({ y: 2 })
expect(computeStateMock).toHaveBeenCalledTimes(2)
})
})

describe("custom config", () => {
const computeStateMock = mock(computeState);
const computeStateMock = mock(computeState)
const makeStore = (opts?: ComputedStateOpts<Store>) =>
create<Store, [["chrisvander/zustand-computed", ComputedStore]]>(
computed(
Expand All @@ -101,54 +101,54 @@ describe("custom config", () => {
computeStateMock,
opts,
),
);
)

beforeEach(() => {
computeStateMock.mockClear();
});
computeStateMock.mockClear()
})

test("computed does not update when a custom key selector is given", () => {
const useStore = makeStore({ keys: ["x", "y"] });
const useStore = makeStore({ keys: ["x", "y"] })
// because we only care about x and y, the compute function should not be called when count changes
expect(computeStateMock).toHaveBeenCalledTimes(1);
expect(useStore.getState().count).toEqual(1);
expect(useStore.getState().countSq).toEqual(1);
useStore.getState().inc();
expect(useStore.getState().count).toEqual(2);
expect(useStore.getState().countSq).toEqual(1);
useStore.getState().dec();
expect(useStore.getState().count).toEqual(1);
expect(useStore.getState().countSq).toEqual(1);
expect(computeStateMock).toHaveBeenCalledTimes(1);
});
expect(computeStateMock).toHaveBeenCalledTimes(1)
expect(useStore.getState().count).toEqual(1)
expect(useStore.getState().countSq).toEqual(1)
useStore.getState().inc()
expect(useStore.getState().count).toEqual(2)
expect(useStore.getState().countSq).toEqual(1)
useStore.getState().dec()
expect(useStore.getState().count).toEqual(1)
expect(useStore.getState().countSq).toEqual(1)
expect(computeStateMock).toHaveBeenCalledTimes(1)
})

test("disabling proxy causes compute to run every time", () => {
const useStore = makeStore({ disableProxy: true });
expect(computeStateMock).toHaveBeenCalledTimes(1);
useStore.setState({ count: 4 });
useStore.setState({ x: 2 });
useStore.setState({ y: 3 });
expect(useStore.getState().count).toEqual(4);
expect(useStore.getState().countSq).toEqual(16);
expect(computeStateMock).toHaveBeenCalledTimes(4);
});
});

type CountSlice = Pick<Store, "count" | "dec">;
type XYSlice = Pick<Store, "x" | "y" | "inc">;
const useStore = makeStore({ disableProxy: true })
expect(computeStateMock).toHaveBeenCalledTimes(1)
useStore.setState({ count: 4 })
useStore.setState({ x: 2 })
useStore.setState({ y: 3 })
expect(useStore.getState().count).toEqual(4)
expect(useStore.getState().countSq).toEqual(16)
expect(computeStateMock).toHaveBeenCalledTimes(4)
})
})

type CountSlice = Pick<Store, "count" | "dec">
type XYSlice = Pick<Store, "x" | "y" | "inc">
function computeSlice(state: CountSlice): ComputedStore {
const nestedResult = {
stringified: JSON.stringify(state.count),
};
}

return {
countSq: state.count ** 2,
nestedResult,
};
}
}

describe("slices pattern", () => {
const computeSliceMock = mock(computeSlice);
const computeSliceMock = mock(computeSlice)
const makeStore = () => {
const createCountSlice: StateCreator<
Store,
Expand All @@ -161,40 +161,40 @@ describe("slices pattern", () => {
dec: () => set((state) => ({ count: state.count - 1 })),
}),
computeSliceMock,
);
)

const createXySlice: StateCreator<Store, [], [], XYSlice> = (set) => ({
x: 1,
y: 1,
// this should not trigger compute function
inc: () => set((state) => ({ count: state.count + 2 })),
});
})

return create<Store & ComputedStore>()((...a) => ({
...createCountSlice(...a),
...createXySlice(...a),
}));
};
}))
}

beforeEach(() => {
computeSliceMock.mockClear();
});
computeSliceMock.mockClear()
})

test("computed works on slices pattern example", () => {
const useStore = makeStore();
expect(computeSliceMock).toHaveBeenCalledTimes(1);
expect(useStore.getState().count).toEqual(1);
expect(useStore.getState().countSq).toEqual(1);
useStore.getState().inc();
expect(useStore.getState().count).toEqual(3);
expect(useStore.getState().countSq).toEqual(1);
expect(computeSliceMock).toHaveBeenCalledTimes(1);
useStore.getState().dec();
expect(useStore.getState().count).toEqual(2);
expect(useStore.getState().countSq).toEqual(4);
expect(computeSliceMock).toHaveBeenCalledTimes(2);
useStore.setState({ count: 4 });
expect(useStore.getState().countSq).toEqual(16);
expect(computeSliceMock).toHaveBeenCalledTimes(3);
});
});
const useStore = makeStore()
expect(computeSliceMock).toHaveBeenCalledTimes(1)
expect(useStore.getState().count).toEqual(1)
expect(useStore.getState().countSq).toEqual(1)
useStore.getState().inc()
expect(useStore.getState().count).toEqual(3)
expect(useStore.getState().countSq).toEqual(1)
expect(computeSliceMock).toHaveBeenCalledTimes(1)
useStore.getState().dec()
expect(useStore.getState().count).toEqual(2)
expect(useStore.getState().countSq).toEqual(4)
expect(computeSliceMock).toHaveBeenCalledTimes(2)
useStore.setState({ count: 4 })
expect(useStore.getState().countSq).toEqual(16)
expect(computeSliceMock).toHaveBeenCalledTimes(3)
})
})

0 comments on commit 38f9c3b

Please sign in to comment.