JavaScript async/await

async/awaitは最初はあまりしっくりきていなかったのですが、testを書きながら動作確認すると理解できました。

async function
  return value
    ✔ is an instance of Promise
    ✔ is resolved with return value
    ✔ is rejected with thrown value
  await
    without catch
      ✔ awaits promise to resolve
      ✔ throws rejected promise
    with catch
      ✔ throws catchable inside the async function
import assert from 'assert';

const foo = {};
const f = async () => foo;
const g = async () => {
  throw 'bar';
};
const f2 = async () => {
  const res = await f();
  if(res === foo) return res;
}
const g2 = async () => {
  await g();
  return 'baz';
}
const h = async () => {
  try {
    await g();
    return 'baz';
  } catch (err) {
    return err;
  }
};
const ಠ_ಠ  = new Error('should not reach here');

describe('async function', () => {
  describe('return value', () => {
    it('is an instance of Promise', () => {
      assert(f() instanceof Promise);
    });

    it('is resolved with return value', (done) => {
      f().then((res) => {
        if (res === foo) {
          done();
      } else {
        done(ಠ_ಠ );
      }
      });
    });

    it('is rejected with thrown value', (done) => {
      g()
        .then(() => done(ಠ_ಠ ))
        .catch((err) => {
          if (err === 'bar') {
            done();
          } else {
            done(ಠ_ಠ );
          }
        });
    });
  })

  describe('await', () => {
    describe('without catch', () => {
      it('awaits promise to resolve', (done) => {
        f2()
          .then((res) => {
            if (res === foo) {
              done();
            } else {
              done(ಠ_ಠ );
            }
          });
      });

      it('throws rejected promise', (done) => {
        g2()
          .then(() => done(ಠ_ಠ ))
          .catch((err) => {
            if (err === 'bar') {
              done();
            } else {
              done(ಠ_ಠ );
            }
          });
      });
    });

    describe('with catch', () => {
      it('throws catchable inside the async function', (done) => {
        h()
          .then((res) => {
            if (res === 'bar') {
              done();
            } else {
              done(ಠ_ಠ );
            }
          })
          .catch(() => done(ಠ_ಠ ));
      });
    });
  });
});