async function testDashParser(manifestText, expected, ignoreDrmInfo = false) {
    const netEngine = new shaka.test.FakeNetworkingEngine();
    netEngine.setDefaultText(manifestText);
    const dashParser = new shaka.dash.DashParser();

    const config = shaka.util.PlayerConfiguration.createDefault().manifest;
    config.ignoreDrmInfo = ignoreDrmInfo || false;
    dashParser.configure(config);

    const playerInterface = {
      networkingEngine: netEngine,
      modifyManifestRequest: (request, manifestInfo) => {},
      modifySegmentRequest: (request, segmentInfo) => {},
      filter: (manifest) => Promise.resolve(),
      makeTextStreamsForClosedCaptions: (manifest) => {},
      onTimelineRegionAdded: fail,  // Should not have any EventStream elements.
      onEvent: fail,
      onError: fail,
      isLowLatencyMode: () => false,
      updateDuration: () => {},
      newDrmInfo: (stream) => {},
      onManifestUpdated: () => {},
      getBandwidthEstimate: () => 1e6,
      onMetadata: () => {},
      disableStream: (stream) => {},
      addFont: (name, url) => {},
    };

    const actual = await dashParser.start(
        'http://example.com', playerInterface);
    expect(actual).toEqual(expected);
    // When the above expectation fails, it is far too hard to read the output
    // and debug the test failure.  So we also do these more targetted
    // comparisons below, which will be easier to read and debug.  The full
    // comparison above remains to catch anything we haven't written a more
    // targetted expectation for below.

    for (let i = 0; i < actual.variants.length; ++i) {
      // NOTE: ['sample'] is how we get access to the partial object given to
      // jasmine.objectContaining().

      const actualVariant = actual.variants[i];
      const expectedVariant = expected['sample'].variants[i];

      const actualVideo = actualVariant.video;
      const expectedVideo = expectedVariant['sample'].video;

      const actualDrmInfos = actualVideo.drmInfos;
      const expectedDrmInfos = expectedVideo['sample'].drmInfos;
      expect(actualDrmInfos).withContext(`video drmInfos, i=${i}`)
          .toEqual(expectedDrmInfos);

      const actualKeyIds = actualVideo.keyIds;
      const expectedKeyIds = expectedVideo['sample'].keyIds;
      expect(actualKeyIds).withContext(`video keyIds, i=${i}`)
          .toEqual(expectedKeyIds);
    }
  }
Tests that the parser produces the correct results.

@param {string} manifestText
@param {Object} expected A Manifest-like object.  The parser output is
  expected to match this.
@param {boolean=} ignoreDrmInfo
@return {!Promise}