You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					490 lines
				
				11 KiB
			
		
		
			
		
	
	
					490 lines
				
				11 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"use strict";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const promisify = require("util.promisify");
							 | 
						||
| 
								 | 
							
								const gensync = require("../");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const TEST_ERROR = new Error("TEST_ERROR");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const DID_ERROR = new Error("DID_ERROR");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const doSuccess = gensync({
							 | 
						||
| 
								 | 
							
								  sync: () => 42,
							 | 
						||
| 
								 | 
							
								  async: () => Promise.resolve(42),
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const doError = gensync({
							 | 
						||
| 
								 | 
							
								  sync: () => {
							 | 
						||
| 
								 | 
							
								    throw DID_ERROR;
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  async: () => Promise.reject(DID_ERROR),
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function throwTestError() {
							 | 
						||
| 
								 | 
							
								  throw TEST_ERROR;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								async function expectResult(
							 | 
						||
| 
								 | 
							
								  fn,
							 | 
						||
| 
								 | 
							
								  arg,
							 | 
						||
| 
								 | 
							
								  { error, value, expectSync = false, syncErrback = expectSync }
							 | 
						||
| 
								 | 
							
								) {
							 | 
						||
| 
								 | 
							
								  if (!expectSync) {
							 | 
						||
| 
								 | 
							
								    expect(() => fn.sync(arg)).toThrow(TEST_ERROR);
							 | 
						||
| 
								 | 
							
								  } else if (error) {
							 | 
						||
| 
								 | 
							
								    expect(() => fn.sync(arg)).toThrow(error);
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    expect(fn.sync(arg)).toBe(value);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (error) {
							 | 
						||
| 
								 | 
							
								    await expect(fn.async(arg)).rejects.toBe(error);
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    await expect(fn.async(arg)).resolves.toBe(value);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await new Promise((resolve, reject) => {
							 | 
						||
| 
								 | 
							
								    let sync = true;
							 | 
						||
| 
								 | 
							
								    fn.errback(arg, (err, val) => {
							 | 
						||
| 
								 | 
							
								      try {
							 | 
						||
| 
								 | 
							
								        expect(err).toBe(error);
							 | 
						||
| 
								 | 
							
								        expect(val).toBe(value);
							 | 
						||
| 
								 | 
							
								        expect(sync).toBe(syncErrback);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        resolve();
							 | 
						||
| 
								 | 
							
								      } catch (e) {
							 | 
						||
| 
								 | 
							
								        reject(e);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    sync = false;
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								describe("gensync({})", () => {
							 | 
						||
| 
								 | 
							
								  describe("option validation", () => {
							 | 
						||
| 
								 | 
							
								    test("disallow async and errback handler together", () => {
							 | 
						||
| 
								 | 
							
								      try {
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: throwTestError,
							 | 
						||
| 
								 | 
							
								          async: throwTestError,
							 | 
						||
| 
								 | 
							
								          errback: throwTestError,
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throwTestError();
							 | 
						||
| 
								 | 
							
								      } catch (err) {
							 | 
						||
| 
								 | 
							
								        expect(err.message).toMatch(
							 | 
						||
| 
								 | 
							
								          /Expected one of either opts.async or opts.errback, but got _both_\./
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								        expect(err.code).toBe("GENSYNC_OPTIONS_ERROR");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test("disallow missing sync handler", () => {
							 | 
						||
| 
								 | 
							
								      try {
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          async: throwTestError,
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throwTestError();
							 | 
						||
| 
								 | 
							
								      } catch (err) {
							 | 
						||
| 
								 | 
							
								        expect(err.message).toMatch(/Expected opts.sync to be a function./);
							 | 
						||
| 
								 | 
							
								        expect(err.code).toBe("GENSYNC_OPTIONS_ERROR");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test("errback callback required", () => {
							 | 
						||
| 
								 | 
							
								      const fn = gensync({
							 | 
						||
| 
								 | 
							
								        sync: throwTestError,
							 | 
						||
| 
								 | 
							
								        async: throwTestError,
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      try {
							 | 
						||
| 
								 | 
							
								        fn.errback();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throwTestError();
							 | 
						||
| 
								 | 
							
								      } catch (err) {
							 | 
						||
| 
								 | 
							
								        expect(err.message).toMatch(/function called without callback/);
							 | 
						||
| 
								 | 
							
								        expect(err.code).toBe("GENSYNC_ERRBACK_NO_CALLBACK");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  describe("generator function metadata", () => {
							 | 
						||
| 
								 | 
							
								    test("automatic naming", () => {
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: function readFileSync() {},
							 | 
						||
| 
								 | 
							
								          async: () => {},
							 | 
						||
| 
								 | 
							
								        }).name
							 | 
						||
| 
								 | 
							
								      ).toBe("readFile");
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: function readFile() {},
							 | 
						||
| 
								 | 
							
								          async: () => {},
							 | 
						||
| 
								 | 
							
								        }).name
							 | 
						||
| 
								 | 
							
								      ).toBe("readFile");
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: function readFileAsync() {},
							 | 
						||
| 
								 | 
							
								          async: () => {},
							 | 
						||
| 
								 | 
							
								        }).name
							 | 
						||
| 
								 | 
							
								      ).toBe("readFileAsync");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: () => {},
							 | 
						||
| 
								 | 
							
								          async: function readFileSync() {},
							 | 
						||
| 
								 | 
							
								        }).name
							 | 
						||
| 
								 | 
							
								      ).toBe("readFileSync");
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: () => {},
							 | 
						||
| 
								 | 
							
								          async: function readFile() {},
							 | 
						||
| 
								 | 
							
								        }).name
							 | 
						||
| 
								 | 
							
								      ).toBe("readFile");
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: () => {},
							 | 
						||
| 
								 | 
							
								          async: function readFileAsync() {},
							 | 
						||
| 
								 | 
							
								        }).name
							 | 
						||
| 
								 | 
							
								      ).toBe("readFile");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: () => {},
							 | 
						||
| 
								 | 
							
								          errback: function readFileSync() {},
							 | 
						||
| 
								 | 
							
								        }).name
							 | 
						||
| 
								 | 
							
								      ).toBe("readFileSync");
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: () => {},
							 | 
						||
| 
								 | 
							
								          errback: function readFile() {},
							 | 
						||
| 
								 | 
							
								        }).name
							 | 
						||
| 
								 | 
							
								      ).toBe("readFile");
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: () => {},
							 | 
						||
| 
								 | 
							
								          errback: function readFileAsync() {},
							 | 
						||
| 
								 | 
							
								        }).name
							 | 
						||
| 
								 | 
							
								      ).toBe("readFileAsync");
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test("explicit naming", () => {
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          name: "readFile",
							 | 
						||
| 
								 | 
							
								          sync: () => {},
							 | 
						||
| 
								 | 
							
								          async: () => {},
							 | 
						||
| 
								 | 
							
								        }).name
							 | 
						||
| 
								 | 
							
								      ).toBe("readFile");
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test("default arity", () => {
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          sync: function(a, b, c, d, e, f, g) {
							 | 
						||
| 
								 | 
							
								            throwTestError();
							 | 
						||
| 
								 | 
							
								          },
							 | 
						||
| 
								 | 
							
								          async: throwTestError,
							 | 
						||
| 
								 | 
							
								        }).length
							 | 
						||
| 
								 | 
							
								      ).toBe(7);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test("explicit arity", () => {
							 | 
						||
| 
								 | 
							
								      expect(
							 | 
						||
| 
								 | 
							
								        gensync({
							 | 
						||
| 
								 | 
							
								          arity: 3,
							 | 
						||
| 
								 | 
							
								          sync: throwTestError,
							 | 
						||
| 
								 | 
							
								          async: throwTestError,
							 | 
						||
| 
								 | 
							
								        }).length
							 | 
						||
| 
								 | 
							
								      ).toBe(3);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  describe("'sync' handler", async () => {
							 | 
						||
| 
								 | 
							
								    test("success", async () => {
							 | 
						||
| 
								 | 
							
								      const fn = gensync({
							 | 
						||
| 
								 | 
							
								        sync: (...args) => JSON.stringify(args),
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      await expectResult(fn, 42, { value: "[42]", expectSync: true });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test("failure", async () => {
							 | 
						||
| 
								 | 
							
								      const fn = gensync({
							 | 
						||
| 
								 | 
							
								        sync: (...args) => {
							 | 
						||
| 
								 | 
							
								          throw JSON.stringify(args);
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      await expectResult(fn, 42, { error: "[42]", expectSync: true });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  describe("'async' handler", async () => {
							 | 
						||
| 
								 | 
							
								    test("success", async () => {
							 | 
						||
| 
								 | 
							
								      const fn = gensync({
							 | 
						||
| 
								 | 
							
								        sync: throwTestError,
							 | 
						||
| 
								 | 
							
								        async: (...args) => Promise.resolve(JSON.stringify(args)),
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      await expectResult(fn, 42, { value: "[42]" });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test("failure", async () => {
							 | 
						||
| 
								 | 
							
								      const fn = gensync({
							 | 
						||
| 
								 | 
							
								        sync: throwTestError,
							 | 
						||
| 
								 | 
							
								        async: (...args) => Promise.reject(JSON.stringify(args)),
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      await expectResult(fn, 42, { error: "[42]" });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  describe("'errback' sync handler", async () => {
							 | 
						||
| 
								 | 
							
								    test("success", async () => {
							 | 
						||
| 
								 | 
							
								      const fn = gensync({
							 | 
						||
| 
								 | 
							
								        sync: throwTestError,
							 | 
						||
| 
								 | 
							
								        errback: (...args) => args.pop()(null, JSON.stringify(args)),
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      await expectResult(fn, 42, { value: "[42]", syncErrback: true });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test("failure", async () => {
							 | 
						||
| 
								 | 
							
								      const fn = gensync({
							 | 
						||
| 
								 | 
							
								        sync: throwTestError,
							 | 
						||
| 
								 | 
							
								        errback: (...args) => args.pop()(JSON.stringify(args)),
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      await expectResult(fn, 42, { error: "[42]", syncErrback: true });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  describe("'errback' async handler", async () => {
							 | 
						||
| 
								 | 
							
								    test("success", async () => {
							 | 
						||
| 
								 | 
							
								      const fn = gensync({
							 | 
						||
| 
								 | 
							
								        sync: throwTestError,
							 | 
						||
| 
								 | 
							
								        errback: (...args) =>
							 | 
						||
| 
								 | 
							
								          process.nextTick(() => args.pop()(null, JSON.stringify(args))),
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      await expectResult(fn, 42, { value: "[42]" });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test("failure", async () => {
							 | 
						||
| 
								 | 
							
								      const fn = gensync({
							 | 
						||
| 
								 | 
							
								        sync: throwTestError,
							 | 
						||
| 
								 | 
							
								        errback: (...args) =>
							 | 
						||
| 
								 | 
							
								          process.nextTick(() => args.pop()(JSON.stringify(args))),
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      await expectResult(fn, 42, { error: "[42]" });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								describe("gensync(function* () {})", () => {
							 | 
						||
| 
								 | 
							
								  test("sync throw before body", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*(arg = throwTestError()) {});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      error: TEST_ERROR,
							 | 
						||
| 
								 | 
							
								      syncErrback: true,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("sync throw inside body", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      throwTestError();
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      error: TEST_ERROR,
							 | 
						||
| 
								 | 
							
								      syncErrback: true,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("async throw inside body", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      const val = yield* doSuccess();
							 | 
						||
| 
								 | 
							
								      throwTestError();
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      error: TEST_ERROR,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("error inside body", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      yield* doError();
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      error: DID_ERROR,
							 | 
						||
| 
								 | 
							
								      expectSync: true,
							 | 
						||
| 
								 | 
							
								      syncErrback: false,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("successful return value", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      const value = yield* doSuccess();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      expect(value).toBe(42);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return 84;
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      value: 84,
							 | 
						||
| 
								 | 
							
								      expectSync: true,
							 | 
						||
| 
								 | 
							
								      syncErrback: false,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("successful final value", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      return 42;
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      value: 42,
							 | 
						||
| 
								 | 
							
								      expectSync: true,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("yield unexpected object", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      yield {};
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    try {
							 | 
						||
| 
								 | 
							
								      await fn.async();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      throwTestError();
							 | 
						||
| 
								 | 
							
								    } catch (err) {
							 | 
						||
| 
								 | 
							
								      expect(err.message).toMatch(
							 | 
						||
| 
								 | 
							
								        /Got unexpected yielded value in gensync generator/
							 | 
						||
| 
								 | 
							
								      );
							 | 
						||
| 
								 | 
							
								      expect(err.code).toBe("GENSYNC_EXPECTED_START");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("yield suspend yield", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      yield Symbol.for("gensync:v1:start");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // Should be "yield*" for no error.
							 | 
						||
| 
								 | 
							
								      yield {};
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    try {
							 | 
						||
| 
								 | 
							
								      await fn.async();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      throwTestError();
							 | 
						||
| 
								 | 
							
								    } catch (err) {
							 | 
						||
| 
								 | 
							
								      expect(err.message).toMatch(/Expected GENSYNC_SUSPEND, got {}/);
							 | 
						||
| 
								 | 
							
								      expect(err.code).toBe("GENSYNC_EXPECTED_SUSPEND");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("yield suspend return", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      yield Symbol.for("gensync:v1:start");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // Should be "yield*" for no error.
							 | 
						||
| 
								 | 
							
								      return {};
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    try {
							 | 
						||
| 
								 | 
							
								      await fn.async();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      throwTestError();
							 | 
						||
| 
								 | 
							
								    } catch (err) {
							 | 
						||
| 
								 | 
							
								      expect(err.message).toMatch(/Unexpected generator completion/);
							 | 
						||
| 
								 | 
							
								      expect(err.code).toBe("GENSYNC_EXPECTED_SUSPEND");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								describe("gensync.all()", () => {
							 | 
						||
| 
								 | 
							
								  test("success", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      const result = yield* gensync.all([doSuccess(), doSuccess()]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      expect(result).toEqual([42, 42]);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      value: undefined,
							 | 
						||
| 
								 | 
							
								      expectSync: true,
							 | 
						||
| 
								 | 
							
								      syncErrback: false,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("error first", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      yield* gensync.all([doError(), doSuccess()]);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      error: DID_ERROR,
							 | 
						||
| 
								 | 
							
								      expectSync: true,
							 | 
						||
| 
								 | 
							
								      syncErrback: false,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("error last", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      yield* gensync.all([doSuccess(), doError()]);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      error: DID_ERROR,
							 | 
						||
| 
								 | 
							
								      expectSync: true,
							 | 
						||
| 
								 | 
							
								      syncErrback: false,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("empty list", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      yield* gensync.all([]);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      value: undefined,
							 | 
						||
| 
								 | 
							
								      expectSync: true,
							 | 
						||
| 
								 | 
							
								      syncErrback: false,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								describe("gensync.race()", () => {
							 | 
						||
| 
								 | 
							
								  test("success", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      const result = yield* gensync.race([doSuccess(), doError()]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      expect(result).toEqual(42);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      value: undefined,
							 | 
						||
| 
								 | 
							
								      expectSync: true,
							 | 
						||
| 
								 | 
							
								      syncErrback: false,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test("error", async () => {
							 | 
						||
| 
								 | 
							
								    const fn = gensync(function*() {
							 | 
						||
| 
								 | 
							
								      yield* gensync.race([doError(), doSuccess()]);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    await expectResult(fn, undefined, {
							 | 
						||
| 
								 | 
							
								      error: DID_ERROR,
							 | 
						||
| 
								 | 
							
								      expectSync: true,
							 | 
						||
| 
								 | 
							
								      syncErrback: false,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								});
							 |