@satoshibits/functional 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +12 -13
- package/dist/array-utils.test.d.ts +0 -2
- package/dist/array-utils.test.d.ts.map +0 -1
- package/dist/array-utils.test.js +0 -256
- package/dist/array-utils.test.js.map +0 -1
- package/dist/composition.test.d.ts +0 -2
- package/dist/composition.test.d.ts.map +0 -1
- package/dist/composition.test.js +0 -409
- package/dist/composition.test.js.map +0 -1
- package/dist/integration.test.d.mts +0 -2
- package/dist/integration.test.d.mts.map +0 -1
- package/dist/integration.test.mjs +0 -486
- package/dist/integration.test.mjs.map +0 -1
- package/dist/io.test.d.mts +0 -2
- package/dist/io.test.d.mts.map +0 -1
- package/dist/io.test.mjs +0 -373
- package/dist/io.test.mjs.map +0 -1
- package/dist/laws.test.d.mts +0 -2
- package/dist/laws.test.d.mts.map +0 -1
- package/dist/laws.test.mjs +0 -614
- package/dist/laws.test.mjs.map +0 -1
- package/dist/object-utils.test.d.ts +0 -2
- package/dist/object-utils.test.d.ts.map +0 -1
- package/dist/object-utils.test.js +0 -286
- package/dist/object-utils.test.js.map +0 -1
- package/dist/option-additions.test.d.mts +0 -2
- package/dist/option-additions.test.d.mts.map +0 -1
- package/dist/option-additions.test.mjs +0 -325
- package/dist/option-additions.test.mjs.map +0 -1
- package/dist/option.test.d.ts +0 -6
- package/dist/option.test.d.ts.map +0 -1
- package/dist/option.test.js +0 -606
- package/dist/option.test.js.map +0 -1
- package/dist/performance.test.d.ts +0 -2
- package/dist/performance.test.d.ts.map +0 -1
- package/dist/performance.test.js +0 -424
- package/dist/performance.test.js.map +0 -1
- package/dist/pipeline.test.d.ts +0 -2
- package/dist/pipeline.test.d.ts.map +0 -1
- package/dist/pipeline.test.js +0 -445
- package/dist/pipeline.test.js.map +0 -1
- package/dist/predicates.test.d.ts +0 -2
- package/dist/predicates.test.d.ts.map +0 -1
- package/dist/predicates.test.js +0 -375
- package/dist/predicates.test.js.map +0 -1
- package/dist/reader-result.test.d.ts +0 -2
- package/dist/reader-result.test.d.ts.map +0 -1
- package/dist/reader-result.test.js +0 -1259
- package/dist/reader-result.test.js.map +0 -1
- package/dist/reader.test.d.mts +0 -2
- package/dist/reader.test.d.mts.map +0 -1
- package/dist/reader.test.mjs +0 -288
- package/dist/reader.test.mjs.map +0 -1
- package/dist/result-additions.test.d.mts +0 -2
- package/dist/result-additions.test.d.mts.map +0 -1
- package/dist/result-additions.test.mjs +0 -325
- package/dist/result-additions.test.mjs.map +0 -1
- package/dist/result.test.d.ts +0 -2
- package/dist/result.test.d.ts.map +0 -1
- package/dist/result.test.js +0 -453
- package/dist/result.test.js.map +0 -1
- package/dist/task.test.d.mts +0 -2
- package/dist/task.test.d.mts.map +0 -1
- package/dist/task.test.mjs +0 -1006
- package/dist/task.test.mjs.map +0 -1
- package/dist/types.test.d.ts +0 -6
- package/dist/types.test.d.ts.map +0 -1
- package/dist/types.test.js +0 -447
- package/dist/types.test.js.map +0 -1
- package/dist/validation.test.d.ts +0 -2
- package/dist/validation.test.d.ts.map +0 -1
- package/dist/validation.test.js +0 -518
- package/dist/validation.test.js.map +0 -1
package/dist/task.test.mjs
DELETED
|
@@ -1,1006 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
39
|
-
import { Result } from "./result.mjs";
|
|
40
|
-
import { Task } from "./task.mjs";
|
|
41
|
-
describe("Task", function () {
|
|
42
|
-
describe("laziness", function () {
|
|
43
|
-
it("should not execute until run", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
44
|
-
var effect, task, result;
|
|
45
|
-
return __generator(this, function (_a) {
|
|
46
|
-
switch (_a.label) {
|
|
47
|
-
case 0:
|
|
48
|
-
effect = vi.fn(function () { return Promise.resolve(42); });
|
|
49
|
-
task = Task.fromPromise(effect);
|
|
50
|
-
expect(effect).not.toHaveBeenCalled();
|
|
51
|
-
return [4 /*yield*/, Task.run(task)];
|
|
52
|
-
case 1:
|
|
53
|
-
result = _a.sent();
|
|
54
|
-
expect(effect).toHaveBeenCalledTimes(1);
|
|
55
|
-
expect(result).toBe(42);
|
|
56
|
-
return [2 /*return*/];
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}); });
|
|
60
|
-
it("should execute each time run is called", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
61
|
-
var effect, task;
|
|
62
|
-
return __generator(this, function (_a) {
|
|
63
|
-
switch (_a.label) {
|
|
64
|
-
case 0:
|
|
65
|
-
effect = vi.fn(function () { return Promise.resolve("test"); });
|
|
66
|
-
task = Task.fromPromise(effect);
|
|
67
|
-
return [4 /*yield*/, Task.run(task)];
|
|
68
|
-
case 1:
|
|
69
|
-
_a.sent();
|
|
70
|
-
return [4 /*yield*/, Task.run(task)];
|
|
71
|
-
case 2:
|
|
72
|
-
_a.sent();
|
|
73
|
-
expect(effect).toHaveBeenCalledTimes(2);
|
|
74
|
-
return [2 /*return*/];
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}); });
|
|
78
|
-
});
|
|
79
|
-
describe("of", function () {
|
|
80
|
-
it("should create a task that resolves with the value", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
81
|
-
var task;
|
|
82
|
-
return __generator(this, function (_a) {
|
|
83
|
-
switch (_a.label) {
|
|
84
|
-
case 0:
|
|
85
|
-
task = Task.of(42);
|
|
86
|
-
return [4 /*yield*/, expect(Task.run(task)).resolves.toBe(42)];
|
|
87
|
-
case 1:
|
|
88
|
-
_a.sent();
|
|
89
|
-
return [2 /*return*/];
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}); });
|
|
93
|
-
it("should work with complex values", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
94
|
-
var value, task;
|
|
95
|
-
return __generator(this, function (_a) {
|
|
96
|
-
switch (_a.label) {
|
|
97
|
-
case 0:
|
|
98
|
-
value = { a: 1, b: "test" };
|
|
99
|
-
task = Task.of(value);
|
|
100
|
-
return [4 /*yield*/, expect(Task.run(task)).resolves.toEqual(value)];
|
|
101
|
-
case 1:
|
|
102
|
-
_a.sent();
|
|
103
|
-
return [2 /*return*/];
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}); });
|
|
107
|
-
});
|
|
108
|
-
describe("fromPromise", function () {
|
|
109
|
-
it("should create a Task from a Promise-returning function", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
110
|
-
var promiseFn, task;
|
|
111
|
-
return __generator(this, function (_a) {
|
|
112
|
-
switch (_a.label) {
|
|
113
|
-
case 0:
|
|
114
|
-
promiseFn = function () { return Promise.resolve(42); };
|
|
115
|
-
task = Task.fromPromise(promiseFn);
|
|
116
|
-
return [4 /*yield*/, expect(Task.run(task)).resolves.toBe(42)];
|
|
117
|
-
case 1:
|
|
118
|
-
_a.sent();
|
|
119
|
-
return [2 /*return*/];
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
}); });
|
|
123
|
-
it("should handle rejected Promises", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
124
|
-
var promiseFn, task;
|
|
125
|
-
return __generator(this, function (_a) {
|
|
126
|
-
switch (_a.label) {
|
|
127
|
-
case 0:
|
|
128
|
-
promiseFn = function () { return Promise.reject(new Error("test error")); };
|
|
129
|
-
task = Task.fromPromise(promiseFn);
|
|
130
|
-
return [4 /*yield*/, expect(Task.run(task)).rejects.toThrow("test error")];
|
|
131
|
-
case 1:
|
|
132
|
-
_a.sent();
|
|
133
|
-
return [2 /*return*/];
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
}); });
|
|
137
|
-
it("should be lazy - not execute until run", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
138
|
-
var effect, task;
|
|
139
|
-
return __generator(this, function (_a) {
|
|
140
|
-
switch (_a.label) {
|
|
141
|
-
case 0:
|
|
142
|
-
effect = vi.fn(function () { return Promise.resolve("lazy"); });
|
|
143
|
-
task = Task.fromPromise(effect);
|
|
144
|
-
expect(effect).not.toHaveBeenCalled();
|
|
145
|
-
return [4 /*yield*/, Task.run(task)];
|
|
146
|
-
case 1:
|
|
147
|
-
_a.sent();
|
|
148
|
-
expect(effect).toHaveBeenCalledTimes(1);
|
|
149
|
-
return [2 /*return*/];
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
}); });
|
|
153
|
-
it("should handle async functions", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
154
|
-
var asyncFn, task;
|
|
155
|
-
return __generator(this, function (_a) {
|
|
156
|
-
switch (_a.label) {
|
|
157
|
-
case 0:
|
|
158
|
-
asyncFn = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
159
|
-
return __generator(this, function (_a) {
|
|
160
|
-
switch (_a.label) {
|
|
161
|
-
case 0: return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 10); })];
|
|
162
|
-
case 1:
|
|
163
|
-
_a.sent();
|
|
164
|
-
return [2 /*return*/, "async result"];
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
}); };
|
|
168
|
-
task = Task.fromPromise(asyncFn);
|
|
169
|
-
return [4 /*yield*/, expect(Task.run(task)).resolves.toBe("async result")];
|
|
170
|
-
case 1:
|
|
171
|
-
_a.sent();
|
|
172
|
-
return [2 /*return*/];
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
}); });
|
|
176
|
-
});
|
|
177
|
-
describe("run", function () {
|
|
178
|
-
beforeEach(function () {
|
|
179
|
-
vi.useFakeTimers();
|
|
180
|
-
});
|
|
181
|
-
afterEach(function () {
|
|
182
|
-
vi.useRealTimers();
|
|
183
|
-
});
|
|
184
|
-
it("should execute a Task and return a Promise", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
185
|
-
var task, result;
|
|
186
|
-
return __generator(this, function (_a) {
|
|
187
|
-
switch (_a.label) {
|
|
188
|
-
case 0:
|
|
189
|
-
task = Task.of(100);
|
|
190
|
-
result = Task.run(task);
|
|
191
|
-
expect(result).toBeInstanceOf(Promise);
|
|
192
|
-
return [4 /*yield*/, expect(result).resolves.toBe(100)];
|
|
193
|
-
case 1:
|
|
194
|
-
_a.sent();
|
|
195
|
-
return [2 /*return*/];
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
}); });
|
|
199
|
-
it("should handle Tasks that reject", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
200
|
-
var task, result;
|
|
201
|
-
return __generator(this, function (_a) {
|
|
202
|
-
switch (_a.label) {
|
|
203
|
-
case 0:
|
|
204
|
-
task = function () { return Promise.reject(new Error("run error")); };
|
|
205
|
-
result = Task.run(task);
|
|
206
|
-
expect(result).toBeInstanceOf(Promise);
|
|
207
|
-
return [4 /*yield*/, expect(result).rejects.toThrow("run error")];
|
|
208
|
-
case 1:
|
|
209
|
-
_a.sent();
|
|
210
|
-
return [2 /*return*/];
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
}); });
|
|
214
|
-
it("should execute complex Task chains", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
215
|
-
var task;
|
|
216
|
-
return __generator(this, function (_a) {
|
|
217
|
-
switch (_a.label) {
|
|
218
|
-
case 0:
|
|
219
|
-
task = Task.chain(function (n) {
|
|
220
|
-
return Task.chain(function (doubled) {
|
|
221
|
-
return Task.of(doubled + 1);
|
|
222
|
-
})(Task.of(n * 2));
|
|
223
|
-
})(Task.of(5));
|
|
224
|
-
return [4 /*yield*/, expect(Task.run(task)).resolves.toBe(11)];
|
|
225
|
-
case 1:
|
|
226
|
-
_a.sent();
|
|
227
|
-
return [2 /*return*/];
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
}); });
|
|
231
|
-
it("should work with Task.delay", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
232
|
-
var task, promise, onDone, result;
|
|
233
|
-
return __generator(this, function (_a) {
|
|
234
|
-
switch (_a.label) {
|
|
235
|
-
case 0:
|
|
236
|
-
task = Task.chain(function () { return Task.of("done"); })(Task.delay(20));
|
|
237
|
-
promise = Task.run(task);
|
|
238
|
-
onDone = vi.fn();
|
|
239
|
-
promise.then(onDone);
|
|
240
|
-
// at 19ms, should still be pending
|
|
241
|
-
return [4 /*yield*/, vi.advanceTimersByTimeAsync(19)];
|
|
242
|
-
case 1:
|
|
243
|
-
// at 19ms, should still be pending
|
|
244
|
-
_a.sent();
|
|
245
|
-
expect(onDone).not.toHaveBeenCalled();
|
|
246
|
-
// at 20ms, should resolve
|
|
247
|
-
return [4 /*yield*/, vi.advanceTimersByTimeAsync(1)];
|
|
248
|
-
case 2:
|
|
249
|
-
// at 20ms, should resolve
|
|
250
|
-
_a.sent();
|
|
251
|
-
return [4 /*yield*/, promise];
|
|
252
|
-
case 3:
|
|
253
|
-
result = _a.sent();
|
|
254
|
-
expect(result).toBe("done");
|
|
255
|
-
expect(onDone).toHaveBeenCalledWith("done");
|
|
256
|
-
return [2 /*return*/];
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
}); });
|
|
260
|
-
});
|
|
261
|
-
describe("map", function () {
|
|
262
|
-
it("should transform the resolved value", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
263
|
-
var task, mapped;
|
|
264
|
-
return __generator(this, function (_a) {
|
|
265
|
-
switch (_a.label) {
|
|
266
|
-
case 0:
|
|
267
|
-
task = Task.of(10);
|
|
268
|
-
mapped = Task.map(function (n) { return n * 2; })(task);
|
|
269
|
-
return [4 /*yield*/, expect(Task.run(mapped)).resolves.toBe(20)];
|
|
270
|
-
case 1:
|
|
271
|
-
_a.sent();
|
|
272
|
-
return [2 /*return*/];
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
}); });
|
|
276
|
-
it("should not execute the original task until run", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
277
|
-
var effect, task, mapped;
|
|
278
|
-
return __generator(this, function (_a) {
|
|
279
|
-
switch (_a.label) {
|
|
280
|
-
case 0:
|
|
281
|
-
effect = vi.fn(function () { return Promise.resolve(5); });
|
|
282
|
-
task = Task.fromPromise(effect);
|
|
283
|
-
mapped = Task.map(function (n) { return n + 1; })(task);
|
|
284
|
-
expect(effect).not.toHaveBeenCalled();
|
|
285
|
-
return [4 /*yield*/, Task.run(mapped)];
|
|
286
|
-
case 1:
|
|
287
|
-
_a.sent();
|
|
288
|
-
expect(effect).toHaveBeenCalledTimes(1);
|
|
289
|
-
return [2 /*return*/];
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
}); });
|
|
293
|
-
it("should propagate rejection", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
294
|
-
var task, mapped;
|
|
295
|
-
return __generator(this, function (_a) {
|
|
296
|
-
switch (_a.label) {
|
|
297
|
-
case 0:
|
|
298
|
-
task = Task.fromPromise(function () { return Promise.reject(new Error("fail")); });
|
|
299
|
-
mapped = Task.map(function (n) { return n * 2; })(task);
|
|
300
|
-
return [4 /*yield*/, expect(Task.run(mapped)).rejects.toThrow("fail")];
|
|
301
|
-
case 1:
|
|
302
|
-
_a.sent();
|
|
303
|
-
return [2 /*return*/];
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
}); });
|
|
307
|
-
});
|
|
308
|
-
describe("chain / flatMap", function () {
|
|
309
|
-
it("should sequence async operations", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
310
|
-
var task1, task2, chained;
|
|
311
|
-
return __generator(this, function (_a) {
|
|
312
|
-
switch (_a.label) {
|
|
313
|
-
case 0:
|
|
314
|
-
task1 = Task.of(5);
|
|
315
|
-
task2 = function (n) { return Task.of(n * 2); };
|
|
316
|
-
chained = Task.chain(task2)(task1);
|
|
317
|
-
return [4 /*yield*/, expect(Task.run(chained)).resolves.toBe(10)];
|
|
318
|
-
case 1:
|
|
319
|
-
_a.sent();
|
|
320
|
-
return [2 /*return*/];
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
}); });
|
|
324
|
-
it("flatMap should be an alias for chain", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
325
|
-
var task1, task2, chained;
|
|
326
|
-
return __generator(this, function (_a) {
|
|
327
|
-
switch (_a.label) {
|
|
328
|
-
case 0:
|
|
329
|
-
task1 = Task.of(5);
|
|
330
|
-
task2 = function (n) { return Task.of(n * 2); };
|
|
331
|
-
chained = Task.flatMap(task2)(task1);
|
|
332
|
-
return [4 /*yield*/, expect(Task.run(chained)).resolves.toBe(10)];
|
|
333
|
-
case 1:
|
|
334
|
-
_a.sent();
|
|
335
|
-
return [2 /*return*/];
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
}); });
|
|
339
|
-
it("should maintain laziness through the chain", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
340
|
-
var effect1, effect2, task1, chained;
|
|
341
|
-
return __generator(this, function (_a) {
|
|
342
|
-
switch (_a.label) {
|
|
343
|
-
case 0:
|
|
344
|
-
effect1 = vi.fn(function () { return Promise.resolve(1); });
|
|
345
|
-
effect2 = vi.fn(function (n) { return Promise.resolve(n + 1); });
|
|
346
|
-
task1 = Task.fromPromise(effect1);
|
|
347
|
-
chained = Task.chain(function (n) {
|
|
348
|
-
return Task.fromPromise(function () { return effect2(n); });
|
|
349
|
-
})(task1);
|
|
350
|
-
expect(effect1).not.toHaveBeenCalled();
|
|
351
|
-
expect(effect2).not.toHaveBeenCalled();
|
|
352
|
-
return [4 /*yield*/, Task.run(chained)];
|
|
353
|
-
case 1:
|
|
354
|
-
_a.sent();
|
|
355
|
-
expect(effect1).toHaveBeenCalledTimes(1);
|
|
356
|
-
expect(effect2).toHaveBeenCalledTimes(1);
|
|
357
|
-
return [2 /*return*/];
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
}); });
|
|
361
|
-
it("should propagate rejection from first task", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
362
|
-
var task1, task2, chained;
|
|
363
|
-
return __generator(this, function (_a) {
|
|
364
|
-
switch (_a.label) {
|
|
365
|
-
case 0:
|
|
366
|
-
task1 = Task.fromPromise(function () { return Promise.reject(new Error("first")); });
|
|
367
|
-
task2 = function (n) { return Task.of(n * 2); };
|
|
368
|
-
chained = Task.chain(task2)(task1);
|
|
369
|
-
return [4 /*yield*/, expect(Task.run(chained)).rejects.toThrow("first")];
|
|
370
|
-
case 1:
|
|
371
|
-
_a.sent();
|
|
372
|
-
return [2 /*return*/];
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
}); });
|
|
376
|
-
it("should propagate rejection from second task", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
377
|
-
var task1, task2, chained;
|
|
378
|
-
return __generator(this, function (_a) {
|
|
379
|
-
switch (_a.label) {
|
|
380
|
-
case 0:
|
|
381
|
-
task1 = Task.of(5);
|
|
382
|
-
task2 = function (_n) {
|
|
383
|
-
return Task.fromPromise(function () { return Promise.reject(new Error("second")); });
|
|
384
|
-
};
|
|
385
|
-
chained = Task.chain(task2)(task1);
|
|
386
|
-
return [4 /*yield*/, expect(Task.run(chained)).rejects.toThrow("second")];
|
|
387
|
-
case 1:
|
|
388
|
-
_a.sent();
|
|
389
|
-
return [2 /*return*/];
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
}); });
|
|
393
|
-
});
|
|
394
|
-
describe("ap", function () {
|
|
395
|
-
it("should apply a task of a function to a task of a value", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
396
|
-
var add, taskFn, taskValue, result;
|
|
397
|
-
return __generator(this, function (_a) {
|
|
398
|
-
switch (_a.label) {
|
|
399
|
-
case 0:
|
|
400
|
-
add = function (a) { return function (b) { return a + b; }; };
|
|
401
|
-
taskFn = Task.of(add(5));
|
|
402
|
-
taskValue = Task.of(3);
|
|
403
|
-
result = Task.ap(taskValue)(taskFn);
|
|
404
|
-
return [4 /*yield*/, expect(Task.run(result)).resolves.toBe(8)];
|
|
405
|
-
case 1:
|
|
406
|
-
_a.sent();
|
|
407
|
-
return [2 /*return*/];
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
|
-
}); });
|
|
411
|
-
it("should run tasks in parallel", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
412
|
-
var fnResolved, valueResolved, taskFn, taskValue, result, value;
|
|
413
|
-
return __generator(this, function (_a) {
|
|
414
|
-
switch (_a.label) {
|
|
415
|
-
case 0:
|
|
416
|
-
fnResolved = false;
|
|
417
|
-
valueResolved = false;
|
|
418
|
-
taskFn = Task.fromPromise(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
419
|
-
return __generator(this, function (_a) {
|
|
420
|
-
switch (_a.label) {
|
|
421
|
-
case 0: return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 20); })];
|
|
422
|
-
case 1:
|
|
423
|
-
_a.sent();
|
|
424
|
-
fnResolved = true;
|
|
425
|
-
return [2 /*return*/, function (n) { return n * 2; }];
|
|
426
|
-
}
|
|
427
|
-
});
|
|
428
|
-
}); });
|
|
429
|
-
taskValue = Task.fromPromise(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
430
|
-
return __generator(this, function (_a) {
|
|
431
|
-
switch (_a.label) {
|
|
432
|
-
case 0: return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 10); })];
|
|
433
|
-
case 1:
|
|
434
|
-
_a.sent();
|
|
435
|
-
valueResolved = true;
|
|
436
|
-
return [2 /*return*/, 5];
|
|
437
|
-
}
|
|
438
|
-
});
|
|
439
|
-
}); });
|
|
440
|
-
result = Task.ap(taskValue)(taskFn);
|
|
441
|
-
return [4 /*yield*/, Task.run(result)];
|
|
442
|
-
case 1:
|
|
443
|
-
value = _a.sent();
|
|
444
|
-
expect(value).toBe(10);
|
|
445
|
-
expect(fnResolved).toBe(true);
|
|
446
|
-
expect(valueResolved).toBe(true);
|
|
447
|
-
return [2 /*return*/];
|
|
448
|
-
}
|
|
449
|
-
});
|
|
450
|
-
}); });
|
|
451
|
-
it("should propagate rejection from the function task", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
452
|
-
var taskFn, taskValue, result;
|
|
453
|
-
return __generator(this, function (_a) {
|
|
454
|
-
switch (_a.label) {
|
|
455
|
-
case 0:
|
|
456
|
-
taskFn = Task.fromPromise(function () {
|
|
457
|
-
return Promise.reject(new Error("function error"));
|
|
458
|
-
});
|
|
459
|
-
taskValue = Task.of(3);
|
|
460
|
-
result = Task.ap(taskValue)(taskFn);
|
|
461
|
-
return [4 /*yield*/, expect(Task.run(result)).rejects.toThrow("function error")];
|
|
462
|
-
case 1:
|
|
463
|
-
_a.sent();
|
|
464
|
-
return [2 /*return*/];
|
|
465
|
-
}
|
|
466
|
-
});
|
|
467
|
-
}); });
|
|
468
|
-
it("should propagate rejection from the value task", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
469
|
-
var taskFn, taskValue, result;
|
|
470
|
-
return __generator(this, function (_a) {
|
|
471
|
-
switch (_a.label) {
|
|
472
|
-
case 0:
|
|
473
|
-
taskFn = Task.of(function (n) { return n * 2; });
|
|
474
|
-
taskValue = Task.fromPromise(function () {
|
|
475
|
-
return Promise.reject(new Error("value error"));
|
|
476
|
-
});
|
|
477
|
-
result = Task.ap(taskValue)(taskFn);
|
|
478
|
-
return [4 /*yield*/, expect(Task.run(result)).rejects.toThrow("value error")];
|
|
479
|
-
case 1:
|
|
480
|
-
_a.sent();
|
|
481
|
-
return [2 /*return*/];
|
|
482
|
-
}
|
|
483
|
-
});
|
|
484
|
-
}); });
|
|
485
|
-
it("should propagate first rejection when both reject", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
486
|
-
var taskFn, taskValue, result;
|
|
487
|
-
return __generator(this, function (_a) {
|
|
488
|
-
switch (_a.label) {
|
|
489
|
-
case 0:
|
|
490
|
-
taskFn = Task.fromPromise(function () {
|
|
491
|
-
return Promise.reject(new Error("function error"));
|
|
492
|
-
});
|
|
493
|
-
taskValue = Task.fromPromise(function () {
|
|
494
|
-
return Promise.reject(new Error("value error"));
|
|
495
|
-
});
|
|
496
|
-
result = Task.ap(taskValue)(taskFn);
|
|
497
|
-
// Since they run in parallel, the first to reject wins
|
|
498
|
-
return [4 /*yield*/, expect(Task.run(result)).rejects.toThrow()];
|
|
499
|
-
case 1:
|
|
500
|
-
// Since they run in parallel, the first to reject wins
|
|
501
|
-
_a.sent();
|
|
502
|
-
return [2 /*return*/];
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
|
-
}); });
|
|
506
|
-
});
|
|
507
|
-
describe("sequence", function () {
|
|
508
|
-
beforeEach(function () {
|
|
509
|
-
vi.useFakeTimers();
|
|
510
|
-
});
|
|
511
|
-
afterEach(function () {
|
|
512
|
-
vi.useRealTimers();
|
|
513
|
-
});
|
|
514
|
-
it("should convert array of tasks to task of array", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
515
|
-
var tasks, sequenced;
|
|
516
|
-
return __generator(this, function (_a) {
|
|
517
|
-
switch (_a.label) {
|
|
518
|
-
case 0:
|
|
519
|
-
tasks = [Task.of(1), Task.of(2), Task.of(3)];
|
|
520
|
-
sequenced = Task.sequence(tasks);
|
|
521
|
-
return [4 /*yield*/, expect(Task.run(sequenced)).resolves.toEqual([1, 2, 3])];
|
|
522
|
-
case 1:
|
|
523
|
-
_a.sent();
|
|
524
|
-
return [2 /*return*/];
|
|
525
|
-
}
|
|
526
|
-
});
|
|
527
|
-
}); });
|
|
528
|
-
it("should run tasks in parallel", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
529
|
-
var delays, tasks, promise, result;
|
|
530
|
-
return __generator(this, function (_a) {
|
|
531
|
-
switch (_a.label) {
|
|
532
|
-
case 0:
|
|
533
|
-
delays = [30, 20, 10];
|
|
534
|
-
tasks = delays.map(function (ms) {
|
|
535
|
-
return Task.fromPromise(function () {
|
|
536
|
-
return new Promise(function (resolve) { return setTimeout(function () { return resolve(ms); }, ms); });
|
|
537
|
-
});
|
|
538
|
-
});
|
|
539
|
-
promise = Task.run(Task.sequence(tasks));
|
|
540
|
-
// all tasks run in parallel - advance time once by max delay (30ms)
|
|
541
|
-
return [4 /*yield*/, vi.advanceTimersByTimeAsync(30)];
|
|
542
|
-
case 1:
|
|
543
|
-
// all tasks run in parallel - advance time once by max delay (30ms)
|
|
544
|
-
_a.sent();
|
|
545
|
-
return [4 /*yield*/, promise];
|
|
546
|
-
case 2:
|
|
547
|
-
result = _a.sent();
|
|
548
|
-
expect(result).toEqual([30, 20, 10]);
|
|
549
|
-
return [2 /*return*/];
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
|
-
}); });
|
|
553
|
-
it("should handle empty array", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
554
|
-
var sequenced;
|
|
555
|
-
return __generator(this, function (_a) {
|
|
556
|
-
switch (_a.label) {
|
|
557
|
-
case 0:
|
|
558
|
-
sequenced = Task.sequence([]);
|
|
559
|
-
return [4 /*yield*/, expect(Task.run(sequenced)).resolves.toEqual([])];
|
|
560
|
-
case 1:
|
|
561
|
-
_a.sent();
|
|
562
|
-
return [2 /*return*/];
|
|
563
|
-
}
|
|
564
|
-
});
|
|
565
|
-
}); });
|
|
566
|
-
it("should propagate first rejection", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
567
|
-
var tasks, sequenced;
|
|
568
|
-
return __generator(this, function (_a) {
|
|
569
|
-
switch (_a.label) {
|
|
570
|
-
case 0:
|
|
571
|
-
tasks = [
|
|
572
|
-
Task.of(1),
|
|
573
|
-
Task.fromPromise(function () { return Promise.reject(new Error("fail")); }),
|
|
574
|
-
Task.of(3),
|
|
575
|
-
];
|
|
576
|
-
sequenced = Task.sequence(tasks);
|
|
577
|
-
return [4 /*yield*/, expect(Task.run(sequenced)).rejects.toThrow("fail")];
|
|
578
|
-
case 1:
|
|
579
|
-
_a.sent();
|
|
580
|
-
return [2 /*return*/];
|
|
581
|
-
}
|
|
582
|
-
});
|
|
583
|
-
}); });
|
|
584
|
-
});
|
|
585
|
-
describe("traverse", function () {
|
|
586
|
-
beforeEach(function () {
|
|
587
|
-
vi.useFakeTimers();
|
|
588
|
-
});
|
|
589
|
-
afterEach(function () {
|
|
590
|
-
vi.useRealTimers();
|
|
591
|
-
});
|
|
592
|
-
it("should map and sequence", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
593
|
-
var fn, traverse, result;
|
|
594
|
-
return __generator(this, function (_a) {
|
|
595
|
-
switch (_a.label) {
|
|
596
|
-
case 0:
|
|
597
|
-
fn = function (n) { return Task.of(n * 2); };
|
|
598
|
-
traverse = Task.traverse(fn);
|
|
599
|
-
return [4 /*yield*/, Task.run(traverse([1, 2, 3]))];
|
|
600
|
-
case 1:
|
|
601
|
-
result = _a.sent();
|
|
602
|
-
expect(result).toEqual([2, 4, 6]);
|
|
603
|
-
return [2 /*return*/];
|
|
604
|
-
}
|
|
605
|
-
});
|
|
606
|
-
}); });
|
|
607
|
-
it("should handle empty array", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
608
|
-
var fn, traverse, result;
|
|
609
|
-
return __generator(this, function (_a) {
|
|
610
|
-
switch (_a.label) {
|
|
611
|
-
case 0:
|
|
612
|
-
fn = function (n) { return Task.of(n * 2); };
|
|
613
|
-
traverse = Task.traverse(fn);
|
|
614
|
-
return [4 /*yield*/, Task.run(traverse([]))];
|
|
615
|
-
case 1:
|
|
616
|
-
result = _a.sent();
|
|
617
|
-
expect(result).toEqual([]);
|
|
618
|
-
return [2 /*return*/];
|
|
619
|
-
}
|
|
620
|
-
});
|
|
621
|
-
}); });
|
|
622
|
-
it("should run in parallel", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
623
|
-
var completed, fn, traverse, promise, result;
|
|
624
|
-
return __generator(this, function (_a) {
|
|
625
|
-
switch (_a.label) {
|
|
626
|
-
case 0:
|
|
627
|
-
completed = 0;
|
|
628
|
-
fn = function (n) {
|
|
629
|
-
return Task.fromPromise(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
630
|
-
return __generator(this, function (_a) {
|
|
631
|
-
switch (_a.label) {
|
|
632
|
-
case 0: return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, n * 10); })];
|
|
633
|
-
case 1:
|
|
634
|
-
_a.sent();
|
|
635
|
-
completed++;
|
|
636
|
-
return [2 /*return*/, n];
|
|
637
|
-
}
|
|
638
|
-
});
|
|
639
|
-
}); });
|
|
640
|
-
};
|
|
641
|
-
traverse = Task.traverse(fn);
|
|
642
|
-
promise = Task.run(traverse([3, 2, 1]));
|
|
643
|
-
// all tasks run in parallel - advance time once by max delay (3 * 10 = 30ms)
|
|
644
|
-
return [4 /*yield*/, vi.advanceTimersByTimeAsync(30)];
|
|
645
|
-
case 1:
|
|
646
|
-
// all tasks run in parallel - advance time once by max delay (3 * 10 = 30ms)
|
|
647
|
-
_a.sent();
|
|
648
|
-
return [4 /*yield*/, promise];
|
|
649
|
-
case 2:
|
|
650
|
-
result = _a.sent();
|
|
651
|
-
expect(result).toEqual([3, 2, 1]);
|
|
652
|
-
expect(completed).toBe(3);
|
|
653
|
-
return [2 /*return*/];
|
|
654
|
-
}
|
|
655
|
-
});
|
|
656
|
-
}); });
|
|
657
|
-
});
|
|
658
|
-
describe("sequenceT", function () {
|
|
659
|
-
it("should combine tuple of tasks", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
660
|
-
var t1, t2, t3, result;
|
|
661
|
-
return __generator(this, function (_a) {
|
|
662
|
-
switch (_a.label) {
|
|
663
|
-
case 0:
|
|
664
|
-
t1 = Task.of(1);
|
|
665
|
-
t2 = Task.of("hello");
|
|
666
|
-
t3 = Task.of(true);
|
|
667
|
-
return [4 /*yield*/, Task.run(Task.sequenceT(t1, t2, t3))];
|
|
668
|
-
case 1:
|
|
669
|
-
result = _a.sent();
|
|
670
|
-
expect(result).toEqual([1, "hello", true]);
|
|
671
|
-
return [2 /*return*/];
|
|
672
|
-
}
|
|
673
|
-
});
|
|
674
|
-
}); });
|
|
675
|
-
it("should handle empty tuple", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
676
|
-
var result;
|
|
677
|
-
return __generator(this, function (_a) {
|
|
678
|
-
switch (_a.label) {
|
|
679
|
-
case 0: return [4 /*yield*/, Task.run(Task.sequenceT())];
|
|
680
|
-
case 1:
|
|
681
|
-
result = _a.sent();
|
|
682
|
-
expect(result).toEqual([]);
|
|
683
|
-
return [2 /*return*/];
|
|
684
|
-
}
|
|
685
|
-
});
|
|
686
|
-
}); });
|
|
687
|
-
it("should propagate rejection", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
688
|
-
var t1, t2, combined;
|
|
689
|
-
return __generator(this, function (_a) {
|
|
690
|
-
switch (_a.label) {
|
|
691
|
-
case 0:
|
|
692
|
-
t1 = Task.of(1);
|
|
693
|
-
t2 = Task.fromPromise(function () { return Promise.reject(new Error("fail")); });
|
|
694
|
-
combined = Task.sequenceT(t1, t2);
|
|
695
|
-
return [4 /*yield*/, expect(Task.run(combined)).rejects.toThrow("fail")];
|
|
696
|
-
case 1:
|
|
697
|
-
_a.sent();
|
|
698
|
-
return [2 /*return*/];
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
}); });
|
|
702
|
-
});
|
|
703
|
-
describe("sequenceS", function () {
|
|
704
|
-
it("should combine record of tasks", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
705
|
-
var tasks, result;
|
|
706
|
-
return __generator(this, function (_a) {
|
|
707
|
-
switch (_a.label) {
|
|
708
|
-
case 0:
|
|
709
|
-
tasks = {
|
|
710
|
-
a: Task.of(1),
|
|
711
|
-
b: Task.of("hello"),
|
|
712
|
-
c: Task.of(true),
|
|
713
|
-
};
|
|
714
|
-
return [4 /*yield*/, Task.run(Task.sequenceS(tasks))];
|
|
715
|
-
case 1:
|
|
716
|
-
result = _a.sent();
|
|
717
|
-
expect(result).toEqual({ a: 1, b: "hello", c: true });
|
|
718
|
-
return [2 /*return*/];
|
|
719
|
-
}
|
|
720
|
-
});
|
|
721
|
-
}); });
|
|
722
|
-
it("should handle empty record", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
723
|
-
var result;
|
|
724
|
-
return __generator(this, function (_a) {
|
|
725
|
-
switch (_a.label) {
|
|
726
|
-
case 0: return [4 /*yield*/, Task.run(Task.sequenceS({}))];
|
|
727
|
-
case 1:
|
|
728
|
-
result = _a.sent();
|
|
729
|
-
expect(result).toEqual({});
|
|
730
|
-
return [2 /*return*/];
|
|
731
|
-
}
|
|
732
|
-
});
|
|
733
|
-
}); });
|
|
734
|
-
it("should propagate rejection", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
735
|
-
var tasks, combined;
|
|
736
|
-
return __generator(this, function (_a) {
|
|
737
|
-
switch (_a.label) {
|
|
738
|
-
case 0:
|
|
739
|
-
tasks = {
|
|
740
|
-
a: Task.of(1),
|
|
741
|
-
b: Task.fromPromise(function () { return Promise.reject(new Error("fail")); }),
|
|
742
|
-
};
|
|
743
|
-
combined = Task.sequenceS(tasks);
|
|
744
|
-
return [4 /*yield*/, expect(Task.run(combined)).rejects.toThrow("fail")];
|
|
745
|
-
case 1:
|
|
746
|
-
_a.sent();
|
|
747
|
-
return [2 /*return*/];
|
|
748
|
-
}
|
|
749
|
-
});
|
|
750
|
-
}); });
|
|
751
|
-
});
|
|
752
|
-
describe("delay", function () {
|
|
753
|
-
beforeEach(function () {
|
|
754
|
-
vi.useFakeTimers();
|
|
755
|
-
});
|
|
756
|
-
afterEach(function () {
|
|
757
|
-
vi.useRealTimers();
|
|
758
|
-
});
|
|
759
|
-
it("should delay execution", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
760
|
-
var promise, onDone;
|
|
761
|
-
return __generator(this, function (_a) {
|
|
762
|
-
switch (_a.label) {
|
|
763
|
-
case 0:
|
|
764
|
-
promise = Task.run(Task.delay(50));
|
|
765
|
-
onDone = vi.fn();
|
|
766
|
-
promise.then(onDone);
|
|
767
|
-
// at 49ms, should still be pending
|
|
768
|
-
return [4 /*yield*/, vi.advanceTimersByTimeAsync(49)];
|
|
769
|
-
case 1:
|
|
770
|
-
// at 49ms, should still be pending
|
|
771
|
-
_a.sent();
|
|
772
|
-
expect(onDone).not.toHaveBeenCalled();
|
|
773
|
-
// at 50ms, should resolve
|
|
774
|
-
return [4 /*yield*/, vi.advanceTimersByTimeAsync(1)];
|
|
775
|
-
case 2:
|
|
776
|
-
// at 50ms, should resolve
|
|
777
|
-
_a.sent();
|
|
778
|
-
return [4 /*yield*/, promise];
|
|
779
|
-
case 3:
|
|
780
|
-
_a.sent();
|
|
781
|
-
expect(onDone).toHaveBeenCalled();
|
|
782
|
-
return [2 /*return*/];
|
|
783
|
-
}
|
|
784
|
-
});
|
|
785
|
-
}); });
|
|
786
|
-
it("should handle zero delay", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
787
|
-
var promise;
|
|
788
|
-
return __generator(this, function (_a) {
|
|
789
|
-
switch (_a.label) {
|
|
790
|
-
case 0:
|
|
791
|
-
promise = Task.run(Task.delay(0));
|
|
792
|
-
// advance time by 0 to process microtasks
|
|
793
|
-
return [4 /*yield*/, vi.advanceTimersByTimeAsync(0)];
|
|
794
|
-
case 1:
|
|
795
|
-
// advance time by 0 to process microtasks
|
|
796
|
-
_a.sent();
|
|
797
|
-
return [4 /*yield*/, expect(promise).resolves.toBeUndefined()];
|
|
798
|
-
case 2:
|
|
799
|
-
_a.sent();
|
|
800
|
-
return [2 /*return*/];
|
|
801
|
-
}
|
|
802
|
-
});
|
|
803
|
-
}); });
|
|
804
|
-
it("should handle negative delay as zero delay", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
805
|
-
var promise;
|
|
806
|
-
return __generator(this, function (_a) {
|
|
807
|
-
switch (_a.label) {
|
|
808
|
-
case 0:
|
|
809
|
-
promise = Task.run(Task.delay(-100));
|
|
810
|
-
// negative values are treated as 0 by setTimeout
|
|
811
|
-
return [4 /*yield*/, vi.advanceTimersByTimeAsync(0)];
|
|
812
|
-
case 1:
|
|
813
|
-
// negative values are treated as 0 by setTimeout
|
|
814
|
-
_a.sent();
|
|
815
|
-
return [4 /*yield*/, expect(promise).resolves.toBeUndefined()];
|
|
816
|
-
case 2:
|
|
817
|
-
_a.sent();
|
|
818
|
-
return [2 /*return*/];
|
|
819
|
-
}
|
|
820
|
-
});
|
|
821
|
-
}); });
|
|
822
|
-
});
|
|
823
|
-
describe("chainFirst", function () {
|
|
824
|
-
it("should execute side effect but return original value", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
825
|
-
var sideEffect, task, result;
|
|
826
|
-
return __generator(this, function (_a) {
|
|
827
|
-
switch (_a.label) {
|
|
828
|
-
case 0:
|
|
829
|
-
sideEffect = vi.fn(function (n) { return Task.of("effect: ".concat(n)); });
|
|
830
|
-
task = Task.of(42);
|
|
831
|
-
return [4 /*yield*/, Task.run(Task.chainFirst(sideEffect)(task))];
|
|
832
|
-
case 1:
|
|
833
|
-
result = _a.sent();
|
|
834
|
-
expect(result).toBe(42);
|
|
835
|
-
expect(sideEffect).toHaveBeenCalledWith(42);
|
|
836
|
-
return [2 /*return*/];
|
|
837
|
-
}
|
|
838
|
-
});
|
|
839
|
-
}); });
|
|
840
|
-
it("should propagate rejection from side effect", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
841
|
-
var sideEffect, task, chained;
|
|
842
|
-
return __generator(this, function (_a) {
|
|
843
|
-
switch (_a.label) {
|
|
844
|
-
case 0:
|
|
845
|
-
sideEffect = function (_n) {
|
|
846
|
-
return Task.fromPromise(function () { return Promise.reject(new Error("side fail")); });
|
|
847
|
-
};
|
|
848
|
-
task = Task.of(42);
|
|
849
|
-
chained = Task.chainFirst(sideEffect)(task);
|
|
850
|
-
return [4 /*yield*/, expect(Task.run(chained)).rejects.toThrow("side fail")];
|
|
851
|
-
case 1:
|
|
852
|
-
_a.sent();
|
|
853
|
-
return [2 /*return*/];
|
|
854
|
-
}
|
|
855
|
-
});
|
|
856
|
-
}); });
|
|
857
|
-
it("should maintain laziness", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
858
|
-
var mainEffect, sideEffect, task, chained;
|
|
859
|
-
return __generator(this, function (_a) {
|
|
860
|
-
switch (_a.label) {
|
|
861
|
-
case 0:
|
|
862
|
-
mainEffect = vi.fn(function () { return Promise.resolve(10); });
|
|
863
|
-
sideEffect = vi.fn(function (n) { return Promise.resolve("side: ".concat(n)); });
|
|
864
|
-
task = Task.fromPromise(mainEffect);
|
|
865
|
-
chained = Task.chainFirst(function (n) {
|
|
866
|
-
return Task.fromPromise(function () { return sideEffect(n); });
|
|
867
|
-
})(task);
|
|
868
|
-
expect(mainEffect).not.toHaveBeenCalled();
|
|
869
|
-
expect(sideEffect).not.toHaveBeenCalled();
|
|
870
|
-
return [4 /*yield*/, Task.run(chained)];
|
|
871
|
-
case 1:
|
|
872
|
-
_a.sent();
|
|
873
|
-
expect(mainEffect).toHaveBeenCalledTimes(1);
|
|
874
|
-
expect(sideEffect).toHaveBeenCalledTimes(1);
|
|
875
|
-
return [2 /*return*/];
|
|
876
|
-
}
|
|
877
|
-
});
|
|
878
|
-
}); });
|
|
879
|
-
});
|
|
880
|
-
describe("error handling with Result", function () {
|
|
881
|
-
it("should work with Task<Result> for explicit error handling", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
882
|
-
var safeTask, result1, result2;
|
|
883
|
-
return __generator(this, function (_a) {
|
|
884
|
-
switch (_a.label) {
|
|
885
|
-
case 0:
|
|
886
|
-
safeTask = function (n) {
|
|
887
|
-
return n > 0
|
|
888
|
-
? Task.of(Result.ok(n * 2))
|
|
889
|
-
: Task.of(Result.err("negative number"));
|
|
890
|
-
};
|
|
891
|
-
return [4 /*yield*/, Task.run(safeTask(5))];
|
|
892
|
-
case 1:
|
|
893
|
-
result1 = _a.sent();
|
|
894
|
-
expect(result1).toEqual({ success: true, data: 10 });
|
|
895
|
-
return [4 /*yield*/, Task.run(safeTask(-5))];
|
|
896
|
-
case 2:
|
|
897
|
-
result2 = _a.sent();
|
|
898
|
-
expect(result2).toEqual({ success: false, error: "negative number" });
|
|
899
|
-
return [2 /*return*/];
|
|
900
|
-
}
|
|
901
|
-
});
|
|
902
|
-
}); });
|
|
903
|
-
});
|
|
904
|
-
describe("Functor laws", function () {
|
|
905
|
-
it("should satisfy identity law: map(id) ≅ id", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
906
|
-
var task, id, mapped, result1, result2;
|
|
907
|
-
return __generator(this, function (_a) {
|
|
908
|
-
switch (_a.label) {
|
|
909
|
-
case 0:
|
|
910
|
-
task = Task.of(42);
|
|
911
|
-
id = function (x) { return x; };
|
|
912
|
-
mapped = Task.map(id)(task);
|
|
913
|
-
return [4 /*yield*/, Task.run(task)];
|
|
914
|
-
case 1:
|
|
915
|
-
result1 = _a.sent();
|
|
916
|
-
return [4 /*yield*/, Task.run(mapped)];
|
|
917
|
-
case 2:
|
|
918
|
-
result2 = _a.sent();
|
|
919
|
-
expect(result1).toEqual(result2);
|
|
920
|
-
return [2 /*return*/];
|
|
921
|
-
}
|
|
922
|
-
});
|
|
923
|
-
}); });
|
|
924
|
-
it("should satisfy composition law: map(g∘f) ≅ map(g)∘map(f)", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
925
|
-
var task, f, g, composed1, composed2, result1, result2;
|
|
926
|
-
return __generator(this, function (_a) {
|
|
927
|
-
switch (_a.label) {
|
|
928
|
-
case 0:
|
|
929
|
-
task = Task.of(10);
|
|
930
|
-
f = function (n) { return n * 2; };
|
|
931
|
-
g = function (n) { return n + 1; };
|
|
932
|
-
composed1 = Task.map(function (x) { return g(f(x)); })(task);
|
|
933
|
-
composed2 = Task.map(g)(Task.map(f)(task));
|
|
934
|
-
return [4 /*yield*/, Task.run(composed1)];
|
|
935
|
-
case 1:
|
|
936
|
-
result1 = _a.sent();
|
|
937
|
-
return [4 /*yield*/, Task.run(composed2)];
|
|
938
|
-
case 2:
|
|
939
|
-
result2 = _a.sent();
|
|
940
|
-
expect(result1).toEqual(result2);
|
|
941
|
-
return [2 /*return*/];
|
|
942
|
-
}
|
|
943
|
-
});
|
|
944
|
-
}); });
|
|
945
|
-
});
|
|
946
|
-
describe("Monad laws", function () {
|
|
947
|
-
it("should satisfy left identity: chain(f)(of(x)) ≅ f(x)", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
948
|
-
var x, f, result1, result2;
|
|
949
|
-
return __generator(this, function (_a) {
|
|
950
|
-
switch (_a.label) {
|
|
951
|
-
case 0:
|
|
952
|
-
x = 42;
|
|
953
|
-
f = function (n) { return Task.of(n * 2); };
|
|
954
|
-
return [4 /*yield*/, Task.run(Task.chain(f)(Task.of(x)))];
|
|
955
|
-
case 1:
|
|
956
|
-
result1 = _a.sent();
|
|
957
|
-
return [4 /*yield*/, Task.run(f(x))];
|
|
958
|
-
case 2:
|
|
959
|
-
result2 = _a.sent();
|
|
960
|
-
expect(result1).toEqual(result2);
|
|
961
|
-
return [2 /*return*/];
|
|
962
|
-
}
|
|
963
|
-
});
|
|
964
|
-
}); });
|
|
965
|
-
it("should satisfy right identity: chain(of)(m) ≅ m", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
966
|
-
var task, chained, result1, result2;
|
|
967
|
-
return __generator(this, function (_a) {
|
|
968
|
-
switch (_a.label) {
|
|
969
|
-
case 0:
|
|
970
|
-
task = Task.of(42);
|
|
971
|
-
chained = Task.chain(Task.of)(task);
|
|
972
|
-
return [4 /*yield*/, Task.run(task)];
|
|
973
|
-
case 1:
|
|
974
|
-
result1 = _a.sent();
|
|
975
|
-
return [4 /*yield*/, Task.run(chained)];
|
|
976
|
-
case 2:
|
|
977
|
-
result2 = _a.sent();
|
|
978
|
-
expect(result1).toEqual(result2);
|
|
979
|
-
return [2 /*return*/];
|
|
980
|
-
}
|
|
981
|
-
});
|
|
982
|
-
}); });
|
|
983
|
-
it("should satisfy associativity: chain(g)(chain(f)(m)) ≅ chain(x => chain(g)(f(x)))(m)", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
984
|
-
var task, f, g, left, right, result1, result2;
|
|
985
|
-
return __generator(this, function (_a) {
|
|
986
|
-
switch (_a.label) {
|
|
987
|
-
case 0:
|
|
988
|
-
task = Task.of(10);
|
|
989
|
-
f = function (n) { return Task.of(n * 2); };
|
|
990
|
-
g = function (n) { return Task.of(n + 1); };
|
|
991
|
-
left = Task.chain(g)(Task.chain(f)(task));
|
|
992
|
-
right = Task.chain(function (x) { return Task.chain(g)(f(x)); })(task);
|
|
993
|
-
return [4 /*yield*/, Task.run(left)];
|
|
994
|
-
case 1:
|
|
995
|
-
result1 = _a.sent();
|
|
996
|
-
return [4 /*yield*/, Task.run(right)];
|
|
997
|
-
case 2:
|
|
998
|
-
result2 = _a.sent();
|
|
999
|
-
expect(result1).toEqual(result2);
|
|
1000
|
-
return [2 /*return*/];
|
|
1001
|
-
}
|
|
1002
|
-
});
|
|
1003
|
-
}); });
|
|
1004
|
-
});
|
|
1005
|
-
});
|
|
1006
|
-
//# sourceMappingURL=task.test.mjs.map
|