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);