async function internalTestAssertRejects(swallowUnhandledRejections, factory) {
  try {
    // TODO(user): Stop the unhandled rejection handler from firing
    // rather than swallowing the errors.
    if (swallowUnhandledRejections) {
      GoogPromise.setUnhandledRejectionHandler(() => {});
    }

    let e;
    e = await assertRejects(
        'valid IThenable constructor throws Error', factory(() => {
          throw new Error('test0');
        }));
    assertEquals('test0', e.message);

    e = await assertRejects(
        'valid IThenable constructor throws string error', factory(() => {
          throw 'test1';
        }));
    assertEquals('test1', e);

    e = await assertRejects(
        'valid IThenable rejects Error', factory((_, reject) => {
          reject(new Error('test2'));
        }));
    assertEquals('test2', e.message);

    e = await assertRejects(
        'valid IThenable rejects string error', factory((_, reject) => {
          reject('test3');
        }));
    assertEquals('test3', e);

    e = await assertRejects(
        'assertRejects should fail with a resolved thenable', (async () => {
          await assertRejects(factory((resolve) => resolve(undefined)));
          fail('should always throw.');
        })());
    assertEquals(
        'IThenable passed into assertRejects did not reject', e.message);
    // Record this as an expected assertion: go/failonunreportedasserts
    TestCase.invalidateAssertionException(/** @type {?} */ (e));
  } finally {
    // restore the default exception handler.
    GoogPromise.setUnhandledRejectionHandler(throwException);
  }
}
Runs test suite (function) for a `Thenable` implementation covering
rejection.
@param {boolean} swallowUnhandledRejections
@param {function(function(function(?), function(?))): !IThenable<?>} factory
@suppress {strictMissingProperties} suppression added to enable type checking