Eric Bower
·
04 Mar 24
schema.test.ts
1import { asserts, describe, it } from "../test.ts";
2import { createSchema, createStore, select, slice } from "../store/mod.ts";
3
4const tests = describe("createSchema()");
5
6interface User {
7 id: string;
8 name: string;
9}
10interface UserWithRoles extends User {
11 roles: string[];
12}
13
14const emptyUser = { id: "", name: "" };
15
16it(tests, "default schema", async () => {
17 const [schema, initialState] = createSchema();
18 const store = createStore({ initialState });
19 asserts.assertEquals(store.getState(), {
20 cache: {},
21 loaders: {},
22 });
23
24 await store.run(function* () {
25 yield* schema.update(schema.loaders.start({ id: "1" }));
26 yield* schema.update(schema.cache.add({ "1": true }));
27 });
28
29 asserts.assertEquals(schema.cache.selectTable(store.getState()), {
30 "1": true,
31 });
32 asserts.assertEquals(
33 schema.loaders.selectById(store.getState(), { id: "1" }).status,
34 "loading",
35 );
36});
37
38it(tests, "general types and functionality", async () => {
39 const [db, initialState] = createSchema({
40 users: slice.table<User>({
41 initialState: { "1": { id: "1", name: "wow" } },
42 empty: emptyUser,
43 }),
44 token: slice.str(),
45 counter: slice.num(),
46 dev: slice.any<boolean>(false),
47 currentUser: slice.obj<User>(emptyUser),
48 cache: slice.table({ empty: {} }),
49 loaders: slice.loaders(),
50 });
51 const store = createStore({ initialState });
52
53 asserts.assertEquals(store.getState(), {
54 users: { "1": { id: "1", name: "wow" } },
55 token: "",
56 counter: 0,
57 dev: false,
58 currentUser: { id: "", name: "" },
59 cache: {},
60 loaders: {},
61 });
62 const userMap = db.users.selectTable(store.getState());
63 asserts.assertEquals(userMap, { "1": { id: "1", name: "wow" } });
64
65 await store.run(function* () {
66 yield* db.update([
67 db.users.add({ "2": { id: "2", name: "bob" } }),
68 db.users.patch({ "1": { name: "zzz" } }),
69 ]);
70
71 const users = yield* select(db.users.selectTable);
72 asserts.assertEquals(users, {
73 "1": { id: "1", name: "zzz" },
74 "2": { id: "2", name: "bob" },
75 });
76
77 yield* db.update(db.counter.increment());
78 const counter = yield* select(db.counter.select);
79 asserts.assertEquals(counter, 1);
80
81 yield* db.update(db.currentUser.update({ key: "name", value: "vvv" }));
82 const curUser = yield* select(db.currentUser.select);
83 asserts.assertEquals(curUser, { id: "", name: "vvv" });
84
85 yield* db.update(db.loaders.start({ id: "fetch-users" }));
86 const fetchLoader = yield* select(db.loaders.selectById, {
87 id: "fetch-users",
88 });
89 asserts.assertEquals(fetchLoader.id, "fetch-users");
90 asserts.assertEquals(fetchLoader.status, "loading");
91 asserts.assertNotEquals(fetchLoader.lastRun, 0);
92 });
93});
94
95it(tests, "can work with a nested object", async () => {
96 const [db, initialState] = createSchema({
97 currentUser: slice.obj<UserWithRoles>({ id: "", name: "", roles: [] }),
98 cache: slice.table({ empty: {} }),
99 loaders: slice.loaders(),
100 });
101 const store = createStore({ initialState });
102 await store.run(function* () {
103 yield* db.update(db.currentUser.update({ key: "name", value: "vvv" }));
104 const curUser = yield* select(db.currentUser.select);
105 asserts.assertEquals(curUser, { id: "", name: "vvv", roles: [] });
106
107 yield* db.update(
108 db.currentUser.update({ key: "roles", value: ["admin"] }),
109 );
110 const curUser2 = yield* select(db.currentUser.select);
111 asserts.assertEquals(curUser2, { id: "", name: "vvv", roles: ["admin"] });
112
113 yield* db.update(
114 db.currentUser.update({ key: "roles", value: ["admin", "users"] }),
115 );
116 const curUser3 = yield* select(db.currentUser.select);
117 asserts.assertEquals(curUser3, {
118 id: "",
119 name: "vvv",
120 roles: ["admin", "users"],
121 });
122 });
123});