Files
lodash/test/throttle.spec.ts
2023-09-16 16:18:43 -07:00

262 lines
6.8 KiB
TypeScript

import assert from 'node:assert';
import lodashStable from 'lodash';
import { identity, isModularize, argv, isPhantom } from './utils';
import throttle from '../src/throttle';
import runInContext from '../src/runInContext';
describe('throttle', () => {
it('should throttle a function', (done) => {
let callCount = 0,
throttled = throttle(() => {
callCount++;
}, 32);
throttled();
throttled();
throttled();
const lastCount = callCount;
assert.ok(callCount);
setTimeout(() => {
assert.ok(callCount > lastCount);
done();
}, 64);
});
it('subsequent calls should return the result of the first call', (done) => {
const throttled = throttle(identity, 32),
results = [throttled('a'), throttled('b')];
assert.deepStrictEqual(results, ['a', 'a']);
setTimeout(() => {
const results = [throttled('c'), throttled('d')];
assert.notStrictEqual(results[0], 'a');
assert.notStrictEqual(results[0], undefined);
assert.notStrictEqual(results[1], 'd');
assert.notStrictEqual(results[1], undefined);
done();
}, 64);
});
it('should clear timeout when `func` is called', (done) => {
if (!isModularize) {
let callCount = 0,
dateCount = 0;
const lodash = runInContext({
Date: {
now: function () {
return ++dateCount === 5 ? Infinity : +new Date();
},
},
});
const throttled = lodash.throttle(() => {
callCount++;
}, 32);
throttled();
throttled();
setTimeout(() => {
assert.strictEqual(callCount, 2);
done();
}, 64);
} else {
done();
}
});
it('should not trigger a trailing call when invoked once', (done) => {
let callCount = 0,
throttled = throttle(() => {
callCount++;
}, 32);
throttled();
assert.strictEqual(callCount, 1);
setTimeout(() => {
assert.strictEqual(callCount, 1);
done();
}, 64);
});
lodashStable.times(2, (index) => {
it(`should trigger a call when invoked repeatedly${
index ? ' and `leading` is `false`' : ''
}`, (done) => {
let callCount = 0,
limit = argv || isPhantom ? 1000 : 320,
options = index ? { leading: false } : {},
throttled = throttle(
() => {
callCount++;
},
32,
options,
);
const start = +new Date();
while (new Date() - start < limit) {
throttled();
}
const actual = callCount > 1;
setTimeout(() => {
assert.ok(actual);
done();
}, 1);
});
});
it('should trigger a second throttled call as soon as possible', (done) => {
let callCount = 0;
const throttled = throttle(
() => {
callCount++;
},
128,
{ leading: false },
);
throttled();
setTimeout(() => {
assert.strictEqual(callCount, 1);
throttled();
}, 192);
setTimeout(() => {
assert.strictEqual(callCount, 1);
}, 254);
setTimeout(() => {
assert.strictEqual(callCount, 2);
done();
}, 384);
});
it('should apply default options', (done) => {
let callCount = 0,
throttled = throttle(
() => {
callCount++;
},
32,
{},
);
throttled();
throttled();
assert.strictEqual(callCount, 1);
setTimeout(() => {
assert.strictEqual(callCount, 2);
done();
}, 128);
});
it('should support a `leading` option', () => {
const withLeading = throttle(identity, 32, { leading: true });
assert.strictEqual(withLeading('a'), 'a');
const withoutLeading = throttle(identity, 32, { leading: false });
assert.strictEqual(withoutLeading('a'), undefined);
});
it('should support a `trailing` option', (done) => {
let withCount = 0,
withoutCount = 0;
const withTrailing = throttle(
(value) => {
withCount++;
return value;
},
64,
{ trailing: true },
);
const withoutTrailing = throttle(
(value) => {
withoutCount++;
return value;
},
64,
{ trailing: false },
);
assert.strictEqual(withTrailing('a'), 'a');
assert.strictEqual(withTrailing('b'), 'a');
assert.strictEqual(withoutTrailing('a'), 'a');
assert.strictEqual(withoutTrailing('b'), 'a');
setTimeout(() => {
assert.strictEqual(withCount, 2);
assert.strictEqual(withoutCount, 1);
done();
}, 256);
});
it('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', (done) => {
let callCount = 0;
const throttled = throttle(
() => {
callCount++;
},
64,
{ trailing: false },
);
throttled();
throttled();
setTimeout(() => {
throttled();
throttled();
}, 96);
setTimeout(() => {
assert.ok(callCount > 1);
done();
}, 192);
});
it('should work with a system time of `0`', (done) => {
if (!isModularize) {
let callCount = 0,
dateCount = 0;
const lodash = runInContext({
Date: {
now: function () {
return ++dateCount < 4 ? 0 : +new Date();
},
},
});
const throttled = lodash.throttle((value) => {
callCount++;
return value;
}, 32);
const results = [throttled('a'), throttled('b'), throttled('c')];
assert.deepStrictEqual(results, ['a', 'a', 'a']);
assert.strictEqual(callCount, 1);
setTimeout(() => {
assert.strictEqual(callCount, 2);
done();
}, 64);
} else {
done();
}
});
});