JSlang.dev

JavaScript Deep Dives with Wolfram. Since 2015
Inclusive, Test-Driven, Spec-Focused, Collaborative.

September 15, 2022
TestsSource
Async Generators

Source Code

The source code we wrote during the event.

import {strict as assert} from 'assert';

describe('What happens when you mix yielded types (static value and promise)?', () => {
  async function* generatorFunction() {
    yield 1;
    yield Promise.resolve(2);
  }
  it('yielding a static value and a promise returns two Promise<static>', async () => {
    const generator = generatorFunction();
    await generator.next();
    assert.deepEqual(await generator.next(), {done: false, value: 2});
  });
  it('calling an additional next() will yield no value and done=true', async () => {
    const generator = generatorFunction();
    await generator.next();
    await generator.next();
    let result = await generator.next();
    assert.deepEqual(result, {done: true, value: undefined});
    assert.equal('value' in result, true);
  });
});

describe('for await - how does it work? what kind of syntactic sugar is it?', () => {
  async function* generatorFunction() {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
  }
  it('can we write an alternative for-await-of?', async () => {
    const values = [];
    for await (const value of generatorFunction()) {
      values.push(value);
    }

    const valuesAlternative = [];
    const generator = generatorFunction();
    for (let result = await generator.next(); result.done !== true; result = await generator.next()) {
      valuesAlternative.push(result.value);
    }

    assert.deepEqual(values, valuesAlternative);
  });

  async function* generatorFunctionWithReturn() {
    return 42;
  }
  it('a return inside an async-generator returns done=true and a value AND always undefined afterwards', async () => {
    const generator = generatorFunctionWithReturn();
    assert.deepEqual(await generator.next(), {done:true, value: 42});
    assert.deepEqual(await generator.next(), {done:true, value: undefined});
    assert.deepEqual(await generator.next(), {done:true, value: undefined});
  });
  it('a return value inside an async generator is ignored by a for-await-of', async () => {
    const values = [];
    for await (const value of generatorFunctionWithReturn()) {
      values.push(value);
    }
    assert.deepEqual(values, []);
  });

  it('yielding an async value also works with our custom-for-await implementation', async () => {
    async function* generatorFunction() {
      const executor = (resolve, reject) => {
        setTimeout(() => resolve(42), 10);
      };
      yield new Promise(executor);
      yield 23;
    }

    const values = [];
    for await (const value of generatorFunction()) {
      values.push(value);
    }

    const valuesAlternative = [];
    const generator = generatorFunction();
    for (let result = await generator.next(); result.done !== true; result = await generator.next()) {
      valuesAlternative.push(result.value);
    }

    assert.deepEqual(values, valuesAlternative);
    assert.deepEqual(values, [42, 23]);
  });
});