repos / starfx

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

starfx / test
Eric Bower · 04 Mar 24

put.test.ts

  1import { describe, expect, it } from "../test.ts";
  2import { ActionContext, each, put, sleep, spawn, take } from "../mod.ts";
  3import { createStore } from "../store/mod.ts";
  4
  5const putTests = describe("put()");
  6
  7it(putTests, "should send actions through channel", async () => {
  8  const actual: string[] = [];
  9
 10  function* genFn(arg: string) {
 11    const actions = yield* ActionContext;
 12    const task = yield* spawn(function* () {
 13      for (const action of yield* each(actions)) {
 14        actual.push(action.type);
 15        yield* each.next();
 16      }
 17    });
 18
 19    yield* put({
 20      type: arg,
 21    });
 22    yield* put({
 23      type: "2",
 24    });
 25    actions.close();
 26    yield* task;
 27  }
 28
 29  const store = createStore({ initialState: {} });
 30  await store.run(() => genFn("arg"));
 31
 32  const expected = ["arg", "2"];
 33  expect(actual).toEqual(expected);
 34});
 35
 36it(putTests, "should handle nested puts", async () => {
 37  const actual: string[] = [];
 38
 39  function* genA() {
 40    yield* put({
 41      type: "a",
 42    });
 43    actual.push("put a");
 44  }
 45
 46  function* genB() {
 47    yield* take(["a"]);
 48    yield* put({
 49      type: "b",
 50    });
 51    actual.push("put b");
 52  }
 53
 54  function* root() {
 55    yield* spawn(genB);
 56    yield* spawn(genA);
 57  }
 58
 59  const store = createStore({ initialState: {} });
 60  await store.run(() => root());
 61
 62  const expected = ["put b", "put a"];
 63  expect(actual).toEqual(expected);
 64});
 65
 66it(
 67  putTests,
 68  "should not cause stack overflow when puts are emitted while dispatching saga",
 69  async () => {
 70    function* root() {
 71      for (let i = 0; i < 10_000; i += 1) {
 72        yield* put({ type: "test" });
 73      }
 74      yield* sleep(0);
 75    }
 76
 77    const store = createStore({ initialState: {} });
 78    await store.run(() => root());
 79    expect(true).toBe(true);
 80  },
 81);
 82
 83it(
 84  putTests,
 85  "should not miss `put` that was emitted directly after creating a task (caused by another `put`)",
 86  async () => {
 87    const actual: string[] = [];
 88
 89    function* root() {
 90      yield* spawn(function* firstspawn() {
 91        yield* sleep(10);
 92        yield* put({ type: "c" });
 93        yield* put({ type: "do not miss" });
 94      });
 95
 96      yield* take("c");
 97
 98      const tsk = yield* spawn(function* () {
 99        yield* take("do not miss");
100        actual.push("didn't get missed");
101      });
102      yield* tsk;
103    }
104
105    const store = createStore({ initialState: {} });
106    await store.run(root);
107    const expected = ["didn't get missed"];
108    expect(actual).toEqual(expected);
109  },
110);