Skip to content

Commit

Permalink
Core: Fix IE 10 and IE 11 compatibility of internal Promise with sino…
Browse files Browse the repository at this point in the history
…n.useFakeTimers

The Promise polyfill needs to save the unmodified reference to the
`setImmediate` function in IE, for use in `Promise._immediateFn`.

This broke in QUnit 2.14.0, with the introduction of internal Promise usage
as part of #1535. 

Closes #1738.
  • Loading branch information
timmywil authored Feb 8, 2024
1 parent 5b86ff0 commit 0b776c1
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 7 deletions.
18 changes: 11 additions & 7 deletions lib/promise-polyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Patches for use in QUnit:
- 2021-01-10: Add 'globalThis' to globalNS implementation to support SpiderMonkey.
- 2024-02-07: Save unmodified setImmediate to avoid conflicts with Sinon fake timers.
*/

(function () { 'use strict';
Expand Down Expand Up @@ -373,16 +375,18 @@ Promise.race = function(arr) {
};

// Use polyfill for setImmediate for performance gains
Promise._immediateFn =
// @ts-ignore
if (typeof setImmediate === 'function') {
// @ts-ignore
(typeof setImmediate === 'function' &&
function(fn) {
// @ts-ignore
setImmediate(fn);
}) ||
function(fn) {
var setImmediateFunc = setImmediate;
Promise._immediateFn = function(fn) {
setImmediateFunc(fn);
};
} else {
Promise._immediateFn = function(fn) {
setTimeoutFunc(fn, 0);
};
}

Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
if (typeof console !== 'undefined' && console) {
Expand Down
46 changes: 46 additions & 0 deletions test/main/promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,27 @@ var defer = typeof setTimeout !== 'undefined'
Promise.resolve().then(fn);
};

// Get the global namespace the same way as the Promise polyfill.
var globalNS = (function () {
if (typeof globalThis !== 'undefined') {
// eslint-disable-next-line no-undef
return globalThis;
}
if (typeof self !== 'undefined') {
// eslint-disable-next-line no-undef
return self;
}
if (typeof window !== 'undefined') {
// eslint-disable-next-line no-undef
return window;
}
if (typeof global !== 'undefined') {
// eslint-disable-next-line no-undef
return global;
}
throw new Error('unable to locate global object');
})();

// NOTE: Adds 1 assertion
function createMockPromise (assert, reject, value) {
if (arguments.length < 3) {
Expand Down Expand Up @@ -247,4 +268,29 @@ QUnit.module('Support for Promise', function () {

return createMockPromise(assert, true, new Error('this is an error'));
});

QUnit.module('compatible with fake timers', {
beforeEach: function (assert) {
this.setTimeout = globalNS.setTimeout;
globalNS.setTimeout = function () {};
if (globalNS.setImmediate) {
this.setImmediate = globalNS.setImmediate;
globalNS.setImmediate = function () {};
}
// Adds 1 assertion
return createMockPromise(assert);
},
afterEach: function (assert) {
globalNS.setTimeout = this.setTimeout;
if (this.setImmediate) {
globalNS.setImmediate = this.setImmediate;
}
// Adds 1 assertion
return createMockPromise(assert);
}
});

QUnit.test('test', function (assert) {
assert.expect(2);
});
});

0 comments on commit 0b776c1

Please sign in to comment.