* Avoid generating timers with IDs that conflict with native
* Fixes #2068
* Merges #2069 from @atscott
This commit is contained in:
Steve Gravrock
2025-07-15 16:47:25 -07:00
3 changed files with 30 additions and 7 deletions

View File

@@ -3440,7 +3440,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
this.scheduledLookup_ = [];
this.scheduledFunctions_ = {};
this.currentTime_ = 0;
this.delayedFnCount_ = 0;
this.delayedFnStartCount_ = 1e12; // arbitrarily large number to avoid collisions with native timer IDs;
this.deletedKeys_ = [];
this.tick = function(millis, tickDate) {
@@ -3472,7 +3472,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
}
millis = millis || 0;
timeoutKey = timeoutKey || ++this.delayedFnCount_;
timeoutKey = timeoutKey || ++this.delayedFnStartCount_;
runAtMillis = runAtMillis || this.currentTime_ + millis;
const funcToSchedule = {

View File

@@ -86,12 +86,13 @@ describe('DelayedFunctionScheduler', function() {
it('increments scheduled fns ids unless one is passed', function() {
const scheduler = new jasmineUnderTest.DelayedFunctionScheduler();
expect(scheduler.scheduleFunction(function() {}, 0)).toBe(1);
expect(scheduler.scheduleFunction(function() {}, 0)).toBe(2);
const initial = scheduler.scheduleFunction(function() {}, 0);
expect(scheduler.scheduleFunction(function() {}, 0)).toBe(initial + 1);
expect(scheduler.scheduleFunction(function() {}, 0)).toBe(initial + 2);
expect(scheduler.scheduleFunction(function() {}, 0, [], false, 123)).toBe(
123
);
expect(scheduler.scheduleFunction(function() {}, 0)).toBe(3);
expect(scheduler.scheduleFunction(function() {}, 0)).toBe(initial + 3);
});
it('#removeFunctionWithId removes a previously scheduled function with a given id', function() {
@@ -313,6 +314,28 @@ describe('DelayedFunctionScheduler', function() {
expect(tickDate).toHaveBeenCalledWith(1);
});
it('does not conflict with native timer IDs', function() {
const NODE_JS =
typeof process !== 'undefined' &&
process.versions &&
typeof process.versions.node === 'string';
if (NODE_JS) {
pending('numeric timer ID conflicts only relevant for browsers.');
}
const nativeTimeoutId = setTimeout(function() {}, 100);
const scheduler = new jasmineUnderTest.DelayedFunctionScheduler();
const fn = jasmine.createSpy('fn');
for (let i = 0; i < nativeTimeoutId; i++) {
scheduler.scheduleFunction(fn, 0, [], false);
}
scheduler.removeFunctionWithId(nativeTimeoutId);
scheduler.tick(1);
expect(fn).toHaveBeenCalledTimes(nativeTimeoutId);
});
describe('ticking inside a scheduled function', function() {
let clock;

View File

@@ -6,7 +6,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
this.scheduledLookup_ = [];
this.scheduledFunctions_ = {};
this.currentTime_ = 0;
this.delayedFnCount_ = 0;
this.delayedFnStartCount_ = 1e12; // arbitrarily large number to avoid collisions with native timer IDs;
this.deletedKeys_ = [];
this.tick = function(millis, tickDate) {
@@ -38,7 +38,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
}
millis = millis || 0;
timeoutKey = timeoutKey || ++this.delayedFnCount_;
timeoutKey = timeoutKey || ++this.delayedFnStartCount_;
runAtMillis = runAtMillis || this.currentTime_ + millis;
const funcToSchedule = {