smart_interval_spec.js.es6 4.84 KB
Newer Older
1 2 3
//= require jquery
//= require smart_interval

4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
(() => {
  const DEFAULT_MAX_INTERVAL = 100;
  const DEFAULT_STARTING_INTERVAL = 5;
  const DEFAULT_SHORT_TIMEOUT = 75;
  const DEFAULT_LONG_TIMEOUT = 1000;
  const DEFAULT_INCREMENT_FACTOR = 2;

  function createDefaultSmartInterval(config) {
    const defaultParams = {
      callback: () => {},
      startingInterval: DEFAULT_STARTING_INTERVAL,
      maxInterval: DEFAULT_MAX_INTERVAL,
      incrementByFactorOf: DEFAULT_INCREMENT_FACTOR,
      delayStartBy: 0,
      lazyStart: false,
    };
20

21 22 23 24 25 26
    if (config) {
      _.extend(defaultParams, config);
    }

    return new gl.SmartInterval(defaultParams);
  }
27

28
  describe('SmartInterval', function () {
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
    describe('Increment Interval', function () {
      beforeEach(function () {
        this.smartInterval = createDefaultSmartInterval();
      });

      it('should increment the interval delay', function (done) {
        const interval = this.smartInterval;
        setTimeout(() => {
          const intervalConfig = this.smartInterval.cfg;
          const iterationCount = 4;
          const maxIntervalAfterIterations = intervalConfig.startingInterval *
            Math.pow(intervalConfig.incrementByFactorOf, (iterationCount - 1)); // 40
          const currentInterval = interval.getCurrentInterval();

          // Provide some flexibility for performance of testing environment
          expect(currentInterval).toBeGreaterThan(intervalConfig.startingInterval);
          expect(currentInterval <= maxIntervalAfterIterations).toBeTruthy();

          done();
        }, DEFAULT_SHORT_TIMEOUT); // 4 iterations, increment by 2x = (5 + 10 + 20 + 40)
      });

      it('should not increment past maxInterval', function (done) {
        const interval = this.smartInterval;

        setTimeout(() => {
          const currentInterval = interval.getCurrentInterval();
          expect(currentInterval).toBe(interval.cfg.maxInterval);

          done();
        }, DEFAULT_LONG_TIMEOUT);
      });
    });

    describe('Public methods', function () {
      beforeEach(function () {
        this.smartInterval = createDefaultSmartInterval();
      });

      it('should cancel an interval', function (done) {
        const interval = this.smartInterval;

        setTimeout(() => {
          interval.cancel();

          const intervalId = interval.state.intervalId;
          const currentInterval = interval.getCurrentInterval();
          const intervalLowerLimit = interval.cfg.startingInterval;

          expect(intervalId).toBeUndefined();
          expect(currentInterval).toBe(intervalLowerLimit);

          done();
        }, DEFAULT_SHORT_TIMEOUT);
      });

      it('should resume an interval', function (done) {
        const interval = this.smartInterval;

        setTimeout(() => {
89
          interval.cancel();
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

          interval.resume();

          const intervalId = interval.state.intervalId;

          expect(intervalId).toBeTruthy();

          done();
        }, DEFAULT_SHORT_TIMEOUT);
      });
    });

    describe('DOM Events', function () {
      beforeEach(function () {
        // This ensures DOM and DOM events are initialized for these specs.
        fixture.set('<div></div>');

        this.smartInterval = createDefaultSmartInterval();
      });

      it('should pause when page is not visible', function (done) {
        const interval = this.smartInterval;

        setTimeout(() => {
          expect(interval.state.intervalId).toBeTruthy();

          // simulates triggering of visibilitychange event
          interval.state.pageVisibility = 'hidden';
          interval.handleVisibilityChange();

          expect(interval.state.intervalId).toBeUndefined();
          done();
        }, DEFAULT_SHORT_TIMEOUT);
      });

      it('should resume when page is becomes visible at the previous interval', function (done) {
        const interval = this.smartInterval;

        setTimeout(() => {
          expect(interval.state.intervalId).toBeTruthy();

          // simulates triggering of visibilitychange event
          interval.state.pageVisibility = 'hidden';
          interval.handleVisibilityChange();

          expect(interval.state.intervalId).toBeUndefined();

          // simulates triggering of visibilitychange event
          interval.state.pageVisibility = 'visible';
          interval.handleVisibilityChange();

          expect(interval.state.intervalId).toBeTruthy();

          done();
        }, DEFAULT_SHORT_TIMEOUT);
      });

      it('should cancel on page unload', function (done) {
        const interval = this.smartInterval;

        setTimeout(() => {
          $(document).trigger('page:before-unload');
          expect(interval.state.intervalId).toBeUndefined();
          expect(interval.getCurrentInterval()).toBe(interval.cfg.startingInterval);
          done();
        }, DEFAULT_SHORT_TIMEOUT);
      });
    });
  });
})(window.gl || (window.gl = {}));