debian-mirror-gitlab/spec/javascripts/smart_interval_spec.js

235 lines
7 KiB
JavaScript
Raw Normal View History

2018-05-09 12:01:36 +05:30
import $ from 'jquery';
2020-04-08 14:13:33 +05:30
import { assignIn } from 'lodash';
2018-11-18 11:00:15 +05:30
import waitForPromises from 'spec/helpers/wait_for_promises';
2020-01-01 13:55:28 +05:30
import SmartInterval from '~/smart_interval';
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('SmartInterval', function() {
2017-08-17 22:00:37 +05:30
const DEFAULT_MAX_INTERVAL = 100;
const DEFAULT_STARTING_INTERVAL = 5;
const DEFAULT_SHORT_TIMEOUT = 75;
const DEFAULT_INCREMENT_FACTOR = 2;
function createDefaultSmartInterval(config) {
const defaultParams = {
2018-03-17 18:26:18 +05:30
callback: () => Promise.resolve(),
2017-08-17 22:00:37 +05:30
startingInterval: DEFAULT_STARTING_INTERVAL,
maxInterval: DEFAULT_MAX_INTERVAL,
incrementByFactorOf: DEFAULT_INCREMENT_FACTOR,
lazyStart: false,
immediateExecution: false,
hiddenInterval: null,
};
if (config) {
2020-04-08 14:13:33 +05:30
assignIn(defaultParams, config);
2017-08-17 22:00:37 +05:30
}
2018-03-17 18:26:18 +05:30
return new SmartInterval(defaultParams);
2017-08-17 22:00:37 +05:30
}
2018-11-18 11:00:15 +05:30
beforeEach(() => {
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
2018-12-13 13:39:08 +05:30
describe('Increment Interval', function() {
it('should increment the interval delay', done => {
2018-11-18 11:00:15 +05:30
const smartInterval = createDefaultSmartInterval();
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
waitForPromises()
.then(() => {
const intervalConfig = smartInterval.cfg;
const iterationCount = 4;
2018-12-13 13:39:08 +05:30
const maxIntervalAfterIterations =
intervalConfig.startingInterval * intervalConfig.incrementByFactorOf ** iterationCount;
2018-11-18 11:00:15 +05:30
const currentInterval = smartInterval.getCurrentInterval();
// Provide some flexibility for performance of testing environment
expect(currentInterval).toBeGreaterThan(intervalConfig.startingInterval);
expect(currentInterval).toBeLessThanOrEqual(maxIntervalAfterIterations);
})
.then(done)
.catch(done.fail);
2018-03-17 18:26:18 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should not increment past maxInterval', done => {
2018-11-18 11:00:15 +05:30
const smartInterval = createDefaultSmartInterval({ maxInterval: DEFAULT_STARTING_INTERVAL });
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
jasmine.clock().tick(DEFAULT_STARTING_INTERVAL);
jasmine.clock().tick(DEFAULT_STARTING_INTERVAL * DEFAULT_INCREMENT_FACTOR);
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
waitForPromises()
.then(() => {
const currentInterval = smartInterval.getCurrentInterval();
2018-12-13 13:39:08 +05:30
2018-11-18 11:00:15 +05:30
expect(currentInterval).toBe(smartInterval.cfg.maxInterval);
})
.then(done)
.catch(done.fail);
2017-08-17 22:00:37 +05:30
});
2018-11-18 11:00:15 +05:30
it('does not increment while waiting for callback', done => {
2018-03-17 18:26:18 +05:30
const smartInterval = createDefaultSmartInterval({
callback: () => new Promise($.noop),
2017-08-17 22:00:37 +05:30
});
2018-03-17 18:26:18 +05:30
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
2018-11-18 11:00:15 +05:30
waitForPromises()
.then(() => {
const oneInterval = smartInterval.cfg.startingInterval * DEFAULT_INCREMENT_FACTOR;
2018-12-13 13:39:08 +05:30
2018-11-18 11:00:15 +05:30
expect(smartInterval.getCurrentInterval()).toEqual(oneInterval);
})
.then(done)
.catch(done.fail);
2018-03-17 18:26:18 +05:30
});
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('Public methods', function() {
beforeEach(function() {
2018-03-17 18:26:18 +05:30
this.smartInterval = createDefaultSmartInterval();
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should cancel an interval', function(done) {
2018-03-17 18:26:18 +05:30
const interval = this.smartInterval;
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
interval.cancel();
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
waitForPromises()
.then(() => {
const { intervalId } = interval.state;
const currentInterval = interval.getCurrentInterval();
const intervalLowerLimit = interval.cfg.startingInterval;
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
expect(intervalId).toBeUndefined();
expect(currentInterval).toBe(intervalLowerLimit);
})
.then(done)
.catch(done.fail);
2018-03-17 18:26:18 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should resume an interval', function(done) {
2018-03-17 18:26:18 +05:30
const interval = this.smartInterval;
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
2018-03-17 18:26:18 +05:30
2018-11-18 11:00:15 +05:30
interval.cancel();
2018-03-17 18:26:18 +05:30
2018-11-18 11:00:15 +05:30
interval.resume();
2018-03-17 18:26:18 +05:30
2018-11-18 11:00:15 +05:30
waitForPromises()
.then(() => {
const { intervalId } = interval.state;
2018-12-13 13:39:08 +05:30
2018-11-18 11:00:15 +05:30
expect(intervalId).toBeTruthy();
})
.then(done)
.catch(done.fail);
2017-08-17 22:00:37 +05:30
});
2018-03-17 18:26:18 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
describe('DOM Events', function() {
beforeEach(function() {
2018-03-17 18:26:18 +05:30
// This ensures DOM and DOM events are initialized for these specs.
setFixtures('<div></div>');
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
this.smartInterval = createDefaultSmartInterval();
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should pause when page is not visible', function(done) {
2018-03-17 18:26:18 +05:30
const interval = this.smartInterval;
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
waitForPromises()
.then(() => {
expect(interval.state.intervalId).toBeTruthy();
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
// simulates triggering of visibilitychange event
interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
expect(interval.state.intervalId).toBeUndefined();
})
.then(done)
.catch(done.fail);
2018-03-17 18:26:18 +05:30
});
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
it('should change to the hidden interval when page is not visible', done => {
2018-03-17 18:26:18 +05:30
const HIDDEN_INTERVAL = 1500;
const interval = createDefaultSmartInterval({ hiddenInterval: HIDDEN_INTERVAL });
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
waitForPromises()
.then(() => {
expect(interval.state.intervalId).toBeTruthy();
2018-12-13 13:39:08 +05:30
expect(
interval.getCurrentInterval() >= DEFAULT_STARTING_INTERVAL &&
interval.getCurrentInterval() <= DEFAULT_MAX_INTERVAL,
).toBeTruthy();
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
// simulates triggering of visibilitychange event
interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
expect(interval.state.intervalId).toBeTruthy();
expect(interval.getCurrentInterval()).toBe(HIDDEN_INTERVAL);
})
.then(done)
.catch(done.fail);
2018-03-17 18:26:18 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should resume when page is becomes visible at the previous interval', function(done) {
2018-03-17 18:26:18 +05:30
const interval = this.smartInterval;
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
waitForPromises()
.then(() => {
expect(interval.state.intervalId).toBeTruthy();
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
// simulates triggering of visibilitychange event
interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
expect(interval.state.intervalId).toBeUndefined();
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
// simulates triggering of visibilitychange event
interval.handleVisibilityChange({ target: { visibilityState: 'visible' } });
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
expect(interval.state.intervalId).toBeTruthy();
})
.then(done)
.catch(done.fail);
2018-03-17 18:26:18 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should cancel on page unload', function(done) {
2018-03-17 18:26:18 +05:30
const interval = this.smartInterval;
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
waitForPromises()
.then(() => {
$(document).triggerHandler('beforeunload');
2018-12-13 13:39:08 +05:30
2018-11-18 11:00:15 +05:30
expect(interval.state.intervalId).toBeUndefined();
expect(interval.getCurrentInterval()).toBe(interval.cfg.startingInterval);
})
.then(done)
.catch(done.fail);
2018-03-17 18:26:18 +05:30
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should execute callback before first interval', function() {
2018-03-17 18:26:18 +05:30
const interval = createDefaultSmartInterval({ immediateExecution: true });
2018-12-13 13:39:08 +05:30
2018-03-17 18:26:18 +05:30
expect(interval.cfg.immediateExecution).toBeFalsy();
2017-08-17 22:00:37 +05:30
});
});
2018-03-17 18:26:18 +05:30
});