text: /** @license
   * Copyright 2016 Google LLC
   * SPDX-License-Identifier: Apache-2.0
   */
  
  describe('DownloadProgressEstimator', () => {
    /** @type {!shaka.offline.DownloadProgressEstimator} */
    let estimator;
  
    beforeEach(() => {
      estimator = new shaka.offline.DownloadProgressEstimator();
    });
  
    it('closing updates total download', () => {
      const id = estimator.open(/* estimate= */ 12);
      estimator.close(id, /* actual= */ 13);
  
      expect(estimator.getTotalDownloaded()).toBe(13);
    });
  
    // If we call |close| with an id that was not returned by |open|, then it
    // should be ignored.
    it('closing with invalid id is ignored', () => {
      expect(estimator.getTotalDownloaded()).toBe(0);
      estimator.close(72, /* actual= */ 13);
      expect(estimator.getTotalDownloaded()).toBe(0);
    });
  
    it('closing the same id twice has no effect', () => {
      expect(estimator.getEstimatedProgress()).toBe(0);
  
      estimator.open(/* estimate= */ 15);
      const id = estimator.open(/* estimate= */ 5);
  
      expect(estimator.getEstimatedProgress()).toBe(0);
  
      estimator.close(id, /* actual= */ 5);
      expect(estimator.getEstimatedProgress()).toBeCloseTo(0.25);
      expect(estimator.getTotalDownloaded()).toBe(5);
  
      // We will close |id| again, but nothing should change. We will even say
      // the downloaded size is different, but that should not change anything.
      estimator.close(id, /* actual= */ 200);
      expect(estimator.getEstimatedProgress()).toBeCloseTo(0.25);
      expect(estimator.getTotalDownloaded()).toBe(5);
    });
  
    // Calling both |open| and |close| should affect our progress. Calling |open|
    // should cause our progress to grow smaller (we are saying there is more work
    // to do) and calling |close| should cause our progress to grow larger (we are
    // saying we completed work).
    it('opening and closing updates progress', () => {
      expect(estimator.getEstimatedProgress()).toBe(0);
  
      const id0 = estimator.open(/* estimate= */ 5);
      const id1 = estimator.open(/* estimate= */ 15);
  
      expect(estimator.getEstimatedProgress()).toBe(0);
  
      estimator.close(id0, /* actual= */ 5);
      expect(estimator.getEstimatedProgress()).toBeCloseTo(0.25);
  
      estimator.close(id1, /* actual= */ 15);
      expect(estimator.getEstimatedProgress()).toBeCloseTo(1.0);
  
      // Open a new estimate with a size equal to all previous estimates. Since
      // everything else was closed, this should drop our progress from 100% to
      // 50%.
      estimator.open(/* estimate= */ 20);
      expect(estimator.getEstimatedProgress()).toBeCloseTo(0.5);
    });
  
    // When tracking progress, we want to use the estimated size. This means no
    // matter what value we provide for the actual downloaded size, it should not
    // affect the progress (the original estimate should be used).
    it('actual bytes do not affect progres', () => {
      expect(estimator.getEstimatedProgress()).toBe(0);
  
      estimator.open(/* estimate= */ 15);
      const id = estimator.open(/* estimate= */ 5);
  
      expect(estimator.getEstimatedProgress()).toBe(0);
  
      // Use an actual value so large that if used for progress, it would break
      // the progress value bounds.
      estimator.close(id, /* actual= */ 200);
      expect(estimator.getEstimatedProgress()).toBeCloseTo(0.25);
    });
  });
  