testAbortsAndErrors() {
    if (!window.Blob) {
      return;
    }

    const hashFn = new Md5();
    const blobHasher = new BlobHasher(hashFn, 13);
    const blob = new BlobMock('The quick brown fox jumps over the lazy dog');
    let abortEvents = 0;
    let errorEvents = 0;
    let completeEvents = 0;
    events.listen(blobHasher, BlobHasher.EventType.ABORT, () => {
      ++abortEvents;
    });
    events.listen(blobHasher, BlobHasher.EventType.ERROR, () => {
      ++errorEvents;
    });
    events.listen(blobHasher, BlobHasher.EventType.COMPLETE, () => {
      ++completeEvents;
    });

    // Immediate abort.
    blobHasher.hash(blob);
    assertEquals(0, abortEvents);
    assertEquals(0, errorEvents);
    assertEquals(0, completeEvents);
    blobHasher.abort();
    blobHasher.abort();
    assertEquals(1, abortEvents);
    assertEquals(0, errorEvents);
    assertEquals(0, completeEvents);
    abortEvents = 0;

    // Delayed abort.
    blobHasher.hash(blob);
    blobHasher.fileReader_.mockLoad();
    assertEquals(0, abortEvents);
    assertEquals(0, errorEvents);
    assertEquals(0, completeEvents);
    blobHasher.abort();
    blobHasher.abort();
    assertEquals(1, abortEvents);
    assertEquals(0, errorEvents);
    assertEquals(0, completeEvents);
    abortEvents = 0;

    // Immediate error.
    blobHasher.hash(blob);
    blobHasher.fileReader_.mockError();
    assertEquals(0, abortEvents);
    assertEquals(1, errorEvents);
    assertEquals(0, completeEvents);
    errorEvents = 0;

    // Delayed error.
    blobHasher.hash(blob);
    blobHasher.fileReader_.mockLoad();
    blobHasher.fileReader_.mockError();
    assertEquals(0, abortEvents);
    assertEquals(1, errorEvents);
    assertEquals(0, completeEvents);
    abortEvents = 0;
  }
@suppress {checkTypes,visibility,missingProperties} suppression added to
     enable type checking