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

compose.test.ts

 1import { Err, Ok, type Result, compose, run, safe, sleep } from "../index.js";
 2import { expect, test } from "../test.js";
 3
 4test("should compose middleware", async () => {
 5  const mdw = compose<{ one: string; three: string; result: Result<void> }>([
 6    function* (ctx, next) {
 7      ctx.one = "two";
 8      yield* next();
 9    },
10    function* (ctx, next) {
11      ctx.three = "four";
12      yield* next();
13    },
14  ]);
15  const actual = await run(function* () {
16    const ctx = { one: "", three: "", result: Ok(void 0) };
17    yield* mdw(ctx);
18    return ctx;
19  });
20
21  const expected = {
22    // we should see the mutation
23    one: "two",
24    three: "four",
25    result: Ok(void 0),
26  };
27  expect(actual).toEqual(expected);
28});
29
30test("order of execution", async () => {
31  const mdw = compose<{ actual: string; result: Result<void> }>([
32    function* (ctx, next) {
33      ctx.actual += "a";
34      yield* next();
35      ctx.actual += "g";
36    },
37    function* (ctx, next) {
38      yield* sleep(10);
39      ctx.actual += "b";
40      yield* next();
41      yield* sleep(10);
42      ctx.actual += "f";
43    },
44    function* (ctx, next) {
45      ctx.actual += "c";
46      yield* next();
47      ctx.actual += "d";
48      yield* sleep(30);
49      ctx.actual += "e";
50    },
51  ]);
52
53  const actual = await run(function* () {
54    const ctx = { actual: "", result: Ok(void 0) };
55    yield* mdw(ctx);
56    return ctx;
57  });
58  const expected = {
59    actual: "abcdefg",
60    result: Ok(void 0),
61  };
62  expect(actual).toEqual(expected);
63});
64
65test("when error is discovered, it should throw", async () => {
66  const err = new Error("boom");
67  const mdw = compose([
68    function* (_, next) {
69      yield* next();
70      expect.fail();
71    },
72    function* (_, next) {
73      yield* next();
74      throw err;
75    },
76  ]);
77  const actual = await run(function* () {
78    const ctx = {};
79    const result = yield* safe(() => mdw(ctx));
80    return result;
81  });
82
83  const expected = Err(err);
84  expect(actual).toEqual(expected);
85});