04dc2b76d7
* master: (181 commits) Fixed adding to list bug Remove unnecessary queries for .atom and .json in Dashboard::ProjectsController#index Fixed modal lists dropdown not updating when list is deleted Fixed remove btn error after creating new issue in list Removed duplicated test Removed Masonry, instead uses groups of data Uses mixins for repeated functions Fixed up specs Props use objects with required & type values Removes labels instead of closing issue when clicking remove button Fixed JS lint errors Fixed issue card spec Added webkit CSS properties Fixed bug with empty state showing after search Fixed users href path being incorrect Fixed bug where 2 un-selected issues would stay on selected tab Fixed DB schema Changed how components are added in objects Added remove button Add optional id property to the issue schema Fixed issue link href Disabled add issues button if no lists exist ...
179 lines
5.8 KiB
JavaScript
179 lines
5.8 KiB
JavaScript
require('~/smart_interval');
|
|
|
|
(() => {
|
|
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,
|
|
immediateExecution: false,
|
|
hiddenInterval: null,
|
|
};
|
|
|
|
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 *
|
|
(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(() => {
|
|
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.
|
|
setFixtures('<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.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
|
|
|
|
expect(interval.state.intervalId).toBeUndefined();
|
|
done();
|
|
}, DEFAULT_SHORT_TIMEOUT);
|
|
});
|
|
|
|
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);
|
|
});
|
|
|
|
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.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
|
|
|
|
expect(interval.state.intervalId).toBeUndefined();
|
|
|
|
// simulates triggering of visibilitychange event
|
|
interval.handleVisibilityChange({ target: { visibilityState: 'visible' } });
|
|
|
|
expect(interval.state.intervalId).toBeTruthy();
|
|
|
|
done();
|
|
}, DEFAULT_SHORT_TIMEOUT);
|
|
});
|
|
|
|
it('should cancel on page unload', function (done) {
|
|
const interval = this.smartInterval;
|
|
|
|
setTimeout(() => {
|
|
$(document).triggerHandler('beforeunload');
|
|
expect(interval.state.intervalId).toBeUndefined();
|
|
expect(interval.getCurrentInterval()).toBe(interval.cfg.startingInterval);
|
|
done();
|
|
}, DEFAULT_SHORT_TIMEOUT);
|
|
});
|
|
|
|
it('should execute callback before first interval', function () {
|
|
const interval = createDefaultSmartInterval({ immediateExecution: true });
|
|
expect(interval.cfg.immediateExecution).toBeFalsy();
|
|
});
|
|
});
|
|
});
|
|
})(window.gl || (window.gl = {}));
|