Skip to content

Commit

Permalink
capricorn86#712@patch: Fix handling of callback arguments passing giv…
Browse files Browse the repository at this point in the history
…en to setTimeout / setInterval.
  • Loading branch information
CSchulz committed Feb 3, 2023
1 parent cdd1b99 commit f3bcc79
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 6 deletions.
6 changes: 4 additions & 2 deletions packages/happy-dom/src/window/IWindow.ts
Expand Up @@ -302,9 +302,10 @@ export default interface IWindow extends IEventTarget, NodeJS.Global {
*
* @param callback Function to be executed.
* @param [delay=0] Delay in ms.
* @param args Arguments passed to the callback function.
* @returns Timeout ID.
*/
setTimeout(callback: () => void, delay?: number): NodeJS.Timeout;
setTimeout(callback: Function, delay?: number, ...args: unknown[]): NodeJS.Timeout;

/**
* Cancels a timeout previously established by calling setTimeout().
Expand All @@ -318,9 +319,10 @@ export default interface IWindow extends IEventTarget, NodeJS.Global {
*
* @param callback Function to be executed.
* @param [delay=0] Delay in ms.
* @param args Arguments passed to the callback function.
* @returns Interval ID.
*/
setInterval(callback: () => void, delay?: number): NodeJS.Timeout;
setInterval(callback: Function, delay?: number, ...args: unknown[]): NodeJS.Timeout;

/**
* Cancels a timed repeating action which was previously established by a call to setInterval().
Expand Down
10 changes: 6 additions & 4 deletions packages/happy-dom/src/window/Window.ts
Expand Up @@ -622,12 +622,13 @@ export default class Window extends EventTarget implements IWindow {
* @override
* @param callback Function to be executed.
* @param [delay=0] Delay in ms.
* @param args Arguments passed to the callback function.
* @returns Timeout ID.
*/
public setTimeout(callback: () => void, delay = 0): NodeJS.Timeout {
public setTimeout(callback: Function, delay = 0, ...args: unknown[]): NodeJS.Timeout {
const id = this._setTimeout(() => {
this.happyDOM.asyncTaskManager.endTimer(id);
callback();
callback(...args);
}, delay);
this.happyDOM.asyncTaskManager.startTimer(id);
return id;
Expand All @@ -650,10 +651,11 @@ export default class Window extends EventTarget implements IWindow {
* @override
* @param callback Function to be executed.
* @param [delay=0] Delay in ms.
* @param args Arguments passed to the callback function.
* @returns Interval ID.
*/
public setInterval(callback: () => void, delay = 0): NodeJS.Timeout {
const id = this._setInterval(callback, delay);
public setInterval(callback: Function, delay = 0, ...args: unknown[]): NodeJS.Timeout {
const id = this._setInterval(callback, delay, ...args);
this.happyDOM.asyncTaskManager.startTimer(id);
return id;
}
Expand Down
66 changes: 66 additions & 0 deletions packages/happy-dom/test/window/Window.test.ts
Expand Up @@ -387,6 +387,35 @@ describe('Window', () => {
const timeoutId = window.setTimeout(() => done());
expect(timeoutId.constructor.name).toBe('Timeout');
});

it('Sets a timeout with single argument.', (done) => {
const callbackArgumentOne = 'hello';
const timeoutId = window.setTimeout(
(message: string) => {
expect(message).toBe(callbackArgumentOne);
done();
},
0,
callbackArgumentOne
);
expect(timeoutId.constructor.name).toBe('Timeout');
});

it('Sets a timeout with multiple arguments.', (done) => {
const callbackArgumentOne = 'hello';
const callbackArgumentTwo = 1337;
const timeoutId = window.setTimeout(
(message: string, num: number) => {
expect(message).toBe(callbackArgumentOne);
expect(num).toBe(callbackArgumentTwo);
done();
},
0,
callbackArgumentOne,
callbackArgumentTwo
);
expect(timeoutId.constructor.name).toBe('Timeout');
});
});

describe('clearTimeout()', () => {
Expand All @@ -409,6 +438,43 @@ describe('Window', () => {
}
});
});

it('Sets an interval with single argument.', (done) => {
const callbackArgumentOne = 'hello';
let count = 0;
const intervalId = window.setInterval(
(message: string) => {
expect(message).toBe(callbackArgumentOne);
count++;
if (count > 2) {
clearInterval(intervalId);
done();
}
},
0,
callbackArgumentOne
);
});

it('Sets an interval with multiple arguments.', (done) => {
const callbackArgumentOne = 'hello';
const callbackArgumentTwo = 1337;
let count = 0;
const intervalId = window.setInterval(
(message: string, num: number) => {
expect(message).toBe(callbackArgumentOne);
expect(num).toBe(callbackArgumentTwo);
count++;
if (count > 2) {
clearInterval(intervalId);
done();
}
},
0,
callbackArgumentOne,
callbackArgumentTwo
);
});
});

describe('clearInterval()', () => {
Expand Down

0 comments on commit f3bcc79

Please sign in to comment.