BigW Consortium Gitlab

smart_interval_spec.js 5.83 KB
Newer Older
1
import '~/smart_interval';
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

(() => {
  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,
      lazyStart: false,
17 18
      immediateExecution: false,
      hiddenInterval: null,
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
    };

    if (config) {
      _.extend(defaultParams, config);
    }

    return new gl.SmartInterval(defaultParams);
  }

  describe('SmartInterval', function () {
    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 *
40
            (intervalConfig.incrementByFactorOf ** (iterationCount - 1)); // 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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
          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(() => {
          interval.cancel();

          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.
105
        setFixtures('<div></div>');
106 107 108 109 110 111 112 113 114 115 116

        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
117
          interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
118 119 120 121 122 123

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

124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
      it('should change to the hidden interval when page is not visible', function (done) {
        const HIDDEN_INTERVAL = 1500;
        const interval = createDefaultSmartInterval({ hiddenInterval: HIDDEN_INTERVAL });

        setTimeout(() => {
          expect(interval.state.intervalId).toBeTruthy();
          expect(interval.getCurrentInterval() >= DEFAULT_STARTING_INTERVAL &&
            interval.getCurrentInterval() <= DEFAULT_MAX_INTERVAL).toBeTruthy();

          // simulates triggering of visibilitychange event
          interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });

          expect(interval.state.intervalId).toBeTruthy();
          expect(interval.getCurrentInterval()).toBe(HIDDEN_INTERVAL);
          done();
        }, DEFAULT_SHORT_TIMEOUT);
      });

142 143 144 145 146 147 148
      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
149
          interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
150 151 152 153

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

          // simulates triggering of visibilitychange event
154
          interval.handleVisibilityChange({ target: { visibilityState: 'visible' } });
155 156 157 158 159 160 161 162 163 164 165

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

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

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

        setTimeout(() => {
166
          $(document).triggerHandler('beforeunload');
167 168 169 170 171
          expect(interval.state.intervalId).toBeUndefined();
          expect(interval.getCurrentInterval()).toBe(interval.cfg.startingInterval);
          done();
        }, DEFAULT_SHORT_TIMEOUT);
      });
172 173 174 175 176

      it('should execute callback before first interval', function () {
        const interval = createDefaultSmartInterval({ immediateExecution: true });
        expect(interval.cfg.immediateExecution).toBeFalsy();
      });
177 178 179
    });
  });
})(window.gl || (window.gl = {}));