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