repos / starfx

a micro-mvc framework for react apps
git clone https://github.com/neurosnap/starfx.git

starfx / src / test
Eric Bower  ·  2025-06-06

put.test.ts

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