source: imaps-frontend/node_modules/gensync/test/index.test.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 10.8 KB
RevLine 
[d565449]1"use strict";
2
3const promisify = require("util.promisify");
4const gensync = require("../");
5
6const TEST_ERROR = new Error("TEST_ERROR");
7
8const DID_ERROR = new Error("DID_ERROR");
9
10const doSuccess = gensync({
11 sync: () => 42,
12 async: () => Promise.resolve(42),
13});
14
15const doError = gensync({
16 sync: () => {
17 throw DID_ERROR;
18 },
19 async: () => Promise.reject(DID_ERROR),
20});
21
22function throwTestError() {
23 throw TEST_ERROR;
24}
25
26async function expectResult(
27 fn,
28 arg,
29 { error, value, expectSync = false, syncErrback = expectSync }
30) {
31 if (!expectSync) {
32 expect(() => fn.sync(arg)).toThrow(TEST_ERROR);
33 } else if (error) {
34 expect(() => fn.sync(arg)).toThrow(error);
35 } else {
36 expect(fn.sync(arg)).toBe(value);
37 }
38
39 if (error) {
40 await expect(fn.async(arg)).rejects.toBe(error);
41 } else {
42 await expect(fn.async(arg)).resolves.toBe(value);
43 }
44
45 await new Promise((resolve, reject) => {
46 let sync = true;
47 fn.errback(arg, (err, val) => {
48 try {
49 expect(err).toBe(error);
50 expect(val).toBe(value);
51 expect(sync).toBe(syncErrback);
52
53 resolve();
54 } catch (e) {
55 reject(e);
56 }
57 });
58 sync = false;
59 });
60}
61
62describe("gensync({})", () => {
63 describe("option validation", () => {
64 test("disallow async and errback handler together", () => {
65 try {
66 gensync({
67 sync: throwTestError,
68 async: throwTestError,
69 errback: throwTestError,
70 });
71
72 throwTestError();
73 } catch (err) {
74 expect(err.message).toMatch(
75 /Expected one of either opts.async or opts.errback, but got _both_\./
76 );
77 expect(err.code).toBe("GENSYNC_OPTIONS_ERROR");
78 }
79 });
80
81 test("disallow missing sync handler", () => {
82 try {
83 gensync({
84 async: throwTestError,
85 });
86
87 throwTestError();
88 } catch (err) {
89 expect(err.message).toMatch(/Expected opts.sync to be a function./);
90 expect(err.code).toBe("GENSYNC_OPTIONS_ERROR");
91 }
92 });
93
94 test("errback callback required", () => {
95 const fn = gensync({
96 sync: throwTestError,
97 async: throwTestError,
98 });
99
100 try {
101 fn.errback();
102
103 throwTestError();
104 } catch (err) {
105 expect(err.message).toMatch(/function called without callback/);
106 expect(err.code).toBe("GENSYNC_ERRBACK_NO_CALLBACK");
107 }
108 });
109 });
110
111 describe("generator function metadata", () => {
112 test("automatic naming", () => {
113 expect(
114 gensync({
115 sync: function readFileSync() {},
116 async: () => {},
117 }).name
118 ).toBe("readFile");
119 expect(
120 gensync({
121 sync: function readFile() {},
122 async: () => {},
123 }).name
124 ).toBe("readFile");
125 expect(
126 gensync({
127 sync: function readFileAsync() {},
128 async: () => {},
129 }).name
130 ).toBe("readFileAsync");
131
132 expect(
133 gensync({
134 sync: () => {},
135 async: function readFileSync() {},
136 }).name
137 ).toBe("readFileSync");
138 expect(
139 gensync({
140 sync: () => {},
141 async: function readFile() {},
142 }).name
143 ).toBe("readFile");
144 expect(
145 gensync({
146 sync: () => {},
147 async: function readFileAsync() {},
148 }).name
149 ).toBe("readFile");
150
151 expect(
152 gensync({
153 sync: () => {},
154 errback: function readFileSync() {},
155 }).name
156 ).toBe("readFileSync");
157 expect(
158 gensync({
159 sync: () => {},
160 errback: function readFile() {},
161 }).name
162 ).toBe("readFile");
163 expect(
164 gensync({
165 sync: () => {},
166 errback: function readFileAsync() {},
167 }).name
168 ).toBe("readFileAsync");
169 });
170
171 test("explicit naming", () => {
172 expect(
173 gensync({
174 name: "readFile",
175 sync: () => {},
176 async: () => {},
177 }).name
178 ).toBe("readFile");
179 });
180
181 test("default arity", () => {
182 expect(
183 gensync({
184 sync: function(a, b, c, d, e, f, g) {
185 throwTestError();
186 },
187 async: throwTestError,
188 }).length
189 ).toBe(7);
190 });
191
192 test("explicit arity", () => {
193 expect(
194 gensync({
195 arity: 3,
196 sync: throwTestError,
197 async: throwTestError,
198 }).length
199 ).toBe(3);
200 });
201 });
202
203 describe("'sync' handler", async () => {
204 test("success", async () => {
205 const fn = gensync({
206 sync: (...args) => JSON.stringify(args),
207 });
208
209 await expectResult(fn, 42, { value: "[42]", expectSync: true });
210 });
211
212 test("failure", async () => {
213 const fn = gensync({
214 sync: (...args) => {
215 throw JSON.stringify(args);
216 },
217 });
218
219 await expectResult(fn, 42, { error: "[42]", expectSync: true });
220 });
221 });
222
223 describe("'async' handler", async () => {
224 test("success", async () => {
225 const fn = gensync({
226 sync: throwTestError,
227 async: (...args) => Promise.resolve(JSON.stringify(args)),
228 });
229
230 await expectResult(fn, 42, { value: "[42]" });
231 });
232
233 test("failure", async () => {
234 const fn = gensync({
235 sync: throwTestError,
236 async: (...args) => Promise.reject(JSON.stringify(args)),
237 });
238
239 await expectResult(fn, 42, { error: "[42]" });
240 });
241 });
242
243 describe("'errback' sync handler", async () => {
244 test("success", async () => {
245 const fn = gensync({
246 sync: throwTestError,
247 errback: (...args) => args.pop()(null, JSON.stringify(args)),
248 });
249
250 await expectResult(fn, 42, { value: "[42]", syncErrback: true });
251 });
252
253 test("failure", async () => {
254 const fn = gensync({
255 sync: throwTestError,
256 errback: (...args) => args.pop()(JSON.stringify(args)),
257 });
258
259 await expectResult(fn, 42, { error: "[42]", syncErrback: true });
260 });
261 });
262
263 describe("'errback' async handler", async () => {
264 test("success", async () => {
265 const fn = gensync({
266 sync: throwTestError,
267 errback: (...args) =>
268 process.nextTick(() => args.pop()(null, JSON.stringify(args))),
269 });
270
271 await expectResult(fn, 42, { value: "[42]" });
272 });
273
274 test("failure", async () => {
275 const fn = gensync({
276 sync: throwTestError,
277 errback: (...args) =>
278 process.nextTick(() => args.pop()(JSON.stringify(args))),
279 });
280
281 await expectResult(fn, 42, { error: "[42]" });
282 });
283 });
284});
285
286describe("gensync(function* () {})", () => {
287 test("sync throw before body", async () => {
288 const fn = gensync(function*(arg = throwTestError()) {});
289
290 await expectResult(fn, undefined, {
291 error: TEST_ERROR,
292 syncErrback: true,
293 });
294 });
295
296 test("sync throw inside body", async () => {
297 const fn = gensync(function*() {
298 throwTestError();
299 });
300
301 await expectResult(fn, undefined, {
302 error: TEST_ERROR,
303 syncErrback: true,
304 });
305 });
306
307 test("async throw inside body", async () => {
308 const fn = gensync(function*() {
309 const val = yield* doSuccess();
310 throwTestError();
311 });
312
313 await expectResult(fn, undefined, {
314 error: TEST_ERROR,
315 });
316 });
317
318 test("error inside body", async () => {
319 const fn = gensync(function*() {
320 yield* doError();
321 });
322
323 await expectResult(fn, undefined, {
324 error: DID_ERROR,
325 expectSync: true,
326 syncErrback: false,
327 });
328 });
329
330 test("successful return value", async () => {
331 const fn = gensync(function*() {
332 const value = yield* doSuccess();
333
334 expect(value).toBe(42);
335
336 return 84;
337 });
338
339 await expectResult(fn, undefined, {
340 value: 84,
341 expectSync: true,
342 syncErrback: false,
343 });
344 });
345
346 test("successful final value", async () => {
347 const fn = gensync(function*() {
348 return 42;
349 });
350
351 await expectResult(fn, undefined, {
352 value: 42,
353 expectSync: true,
354 });
355 });
356
357 test("yield unexpected object", async () => {
358 const fn = gensync(function*() {
359 yield {};
360 });
361
362 try {
363 await fn.async();
364
365 throwTestError();
366 } catch (err) {
367 expect(err.message).toMatch(
368 /Got unexpected yielded value in gensync generator/
369 );
370 expect(err.code).toBe("GENSYNC_EXPECTED_START");
371 }
372 });
373
374 test("yield suspend yield", async () => {
375 const fn = gensync(function*() {
376 yield Symbol.for("gensync:v1:start");
377
378 // Should be "yield*" for no error.
379 yield {};
380 });
381
382 try {
383 await fn.async();
384
385 throwTestError();
386 } catch (err) {
387 expect(err.message).toMatch(/Expected GENSYNC_SUSPEND, got {}/);
388 expect(err.code).toBe("GENSYNC_EXPECTED_SUSPEND");
389 }
390 });
391
392 test("yield suspend return", async () => {
393 const fn = gensync(function*() {
394 yield Symbol.for("gensync:v1:start");
395
396 // Should be "yield*" for no error.
397 return {};
398 });
399
400 try {
401 await fn.async();
402
403 throwTestError();
404 } catch (err) {
405 expect(err.message).toMatch(/Unexpected generator completion/);
406 expect(err.code).toBe("GENSYNC_EXPECTED_SUSPEND");
407 }
408 });
409});
410
411describe("gensync.all()", () => {
412 test("success", async () => {
413 const fn = gensync(function*() {
414 const result = yield* gensync.all([doSuccess(), doSuccess()]);
415
416 expect(result).toEqual([42, 42]);
417 });
418
419 await expectResult(fn, undefined, {
420 value: undefined,
421 expectSync: true,
422 syncErrback: false,
423 });
424 });
425
426 test("error first", async () => {
427 const fn = gensync(function*() {
428 yield* gensync.all([doError(), doSuccess()]);
429 });
430
431 await expectResult(fn, undefined, {
432 error: DID_ERROR,
433 expectSync: true,
434 syncErrback: false,
435 });
436 });
437
438 test("error last", async () => {
439 const fn = gensync(function*() {
440 yield* gensync.all([doSuccess(), doError()]);
441 });
442
443 await expectResult(fn, undefined, {
444 error: DID_ERROR,
445 expectSync: true,
446 syncErrback: false,
447 });
448 });
449
450 test("empty list", async () => {
451 const fn = gensync(function*() {
452 yield* gensync.all([]);
453 });
454
455 await expectResult(fn, undefined, {
456 value: undefined,
457 expectSync: true,
458 syncErrback: false,
459 });
460 });
461});
462
463describe("gensync.race()", () => {
464 test("success", async () => {
465 const fn = gensync(function*() {
466 const result = yield* gensync.race([doSuccess(), doError()]);
467
468 expect(result).toEqual(42);
469 });
470
471 await expectResult(fn, undefined, {
472 value: undefined,
473 expectSync: true,
474 syncErrback: false,
475 });
476 });
477
478 test("error", async () => {
479 const fn = gensync(function*() {
480 yield* gensync.race([doError(), doSuccess()]);
481 });
482
483 await expectResult(fn, undefined, {
484 error: DID_ERROR,
485 expectSync: true,
486 syncErrback: false,
487 });
488 });
489});
Note: See TracBrowser for help on using the repository browser.