repos / starfx

supercharged async flow control library.
git clone https://github.com/neurosnap/starfx.git

starfx / test
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});