Drop support for the eval form of setTimeout and setInterval in the mock clock

This commit is contained in:
Steve Gravrock
2025-09-14 09:21:37 -07:00
parent 3cbf4dc27b
commit 27297de3b8
3 changed files with 18 additions and 45 deletions

View File

@@ -3492,10 +3492,9 @@ getJasmineRequireObj().CurrentRunableTracker = function() {
return CurrentRunableTracker; return CurrentRunableTracker;
}; };
// Warning: don't add "use strict" to this file. Doing so potentially changes
// the behavior of user code that does things like setTimeout("var x = 1;")
// while the mock clock is installed.
getJasmineRequireObj().DelayedFunctionScheduler = function(j$) { getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
'use strict';
function DelayedFunctionScheduler() { function DelayedFunctionScheduler() {
this.scheduledLookup_ = []; this.scheduledLookup_ = [];
this.scheduledFunctions_ = {}; this.scheduledFunctions_ = {};
@@ -3518,20 +3517,10 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
timeoutKey, timeoutKey,
runAtMillis runAtMillis
) { ) {
let f;
if (typeof funcToCall === 'string') { if (typeof funcToCall === 'string') {
// setTimeout("some code") and setInterval("some code") are legal, if throw new Error(
// not recommended. We don't do that ourselves, but user code might. 'The mock clock does not support the eval form of setTimeout and setInterval. Pass a function instead of a string.'
// This allows such code to work when the mock clock is installed.
j$.getEnv().deprecated(
"The eval form of setTimeout and setInterval is deprecated and will stop working in a future version of Jasmine's mock clock. Pass a function instead of a string."
); );
f = function() {
// eslint-disable-next-line no-eval
return eval(funcToCall);
};
} else {
f = funcToCall;
} }
millis = millis || 0; millis = millis || 0;
@@ -3540,7 +3529,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
const funcToSchedule = { const funcToSchedule = {
runAtMillis: runAtMillis, runAtMillis: runAtMillis,
funcToCall: f, funcToCall,
recurring: recurring, recurring: recurring,
params: params, params: params,
timeoutKey: timeoutKey, timeoutKey: timeoutKey,

View File

@@ -1,4 +1,6 @@
describe('DelayedFunctionScheduler', function() { describe('DelayedFunctionScheduler', function() {
'use strict';
it('schedules a function for later execution', function() { it('schedules a function for later execution', function() {
const scheduler = new jasmineUnderTest.DelayedFunctionScheduler(), const scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'); fn = jasmine.createSpy('fn');
@@ -12,21 +14,14 @@ describe('DelayedFunctionScheduler', function() {
expect(fn).toHaveBeenCalled(); expect(fn).toHaveBeenCalled();
}); });
it('schedules a string for later execution', function() { it('throws if a string is passed', function() {
const scheduler = new jasmineUnderTest.DelayedFunctionScheduler(), const scheduler = new jasmineUnderTest.DelayedFunctionScheduler();
strfn = 'horrible = true;';
spyOn(jasmineUnderTest.getEnv(), 'deprecated');
scheduler.scheduleFunction(strfn, 0); expect(function() {
expect(jasmineUnderTest.getEnv().deprecated).toHaveBeenCalledWith( scheduler.scheduleFunction('horrible = true;', 0);
'The eval form of setTimeout and setInterval is deprecated and will ' + }).toThrowError(
"stop working in a future version of Jasmine's mock clock. Pass a " + 'The mock clock does not support the eval form of setTimeout and setInterval. Pass a function instead of a string.'
'function instead of a string.'
); );
scheduler.tick(0);
expect(horrible).toEqual(true);
}); });
it('#tick defaults to 0', function() { it('#tick defaults to 0', function() {

View File

@@ -1,7 +1,6 @@
// Warning: don't add "use strict" to this file. Doing so potentially changes
// the behavior of user code that does things like setTimeout("var x = 1;")
// while the mock clock is installed.
getJasmineRequireObj().DelayedFunctionScheduler = function(j$) { getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
'use strict';
function DelayedFunctionScheduler() { function DelayedFunctionScheduler() {
this.scheduledLookup_ = []; this.scheduledLookup_ = [];
this.scheduledFunctions_ = {}; this.scheduledFunctions_ = {};
@@ -24,20 +23,10 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
timeoutKey, timeoutKey,
runAtMillis runAtMillis
) { ) {
let f;
if (typeof funcToCall === 'string') { if (typeof funcToCall === 'string') {
// setTimeout("some code") and setInterval("some code") are legal, if throw new Error(
// not recommended. We don't do that ourselves, but user code might. 'The mock clock does not support the eval form of setTimeout and setInterval. Pass a function instead of a string.'
// This allows such code to work when the mock clock is installed.
j$.getEnv().deprecated(
"The eval form of setTimeout and setInterval is deprecated and will stop working in a future version of Jasmine's mock clock. Pass a function instead of a string."
); );
f = function() {
// eslint-disable-next-line no-eval
return eval(funcToCall);
};
} else {
f = funcToCall;
} }
millis = millis || 0; millis = millis || 0;
@@ -46,7 +35,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
const funcToSchedule = { const funcToSchedule = {
runAtMillis: runAtMillis, runAtMillis: runAtMillis,
funcToCall: f, funcToCall,
recurring: recurring, recurring: recurring,
params: params, params: params,
timeoutKey: timeoutKey, timeoutKey: timeoutKey,