From bdf63f240248abe5721ee8047c3c3479fd7cd36f Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Wed, 12 Nov 2025 21:53:29 -0800 Subject: [PATCH] Remove code to support browsers that don't have MessageChannel Jasmine hasn't actually run in any such browsers since 2.x. --- lib/jasmine-core/jasmine.js | 4 +- spec/core/StackClearerSpec.js | 11 - spec/core/integration/EnvSpec.js | 21 ++ .../integration/GlobalErrorHandlingSpec.js | 232 +++--------------- src/core/StackClearer.js | 4 +- 5 files changed, 53 insertions(+), 219 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 5970ccfa..47426afd 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -10829,12 +10829,10 @@ getJasmineRequireObj().StackClearer = function(j$) { // Unlike browsers, Node doesn't require us to do a periodic setTimeout // so we avoid the overhead. return nodeQueueMicrotaskImpl(global); - } else if (SAFARI_OR_WIN_WEBKIT || !global.MessageChannel /* tests */) { + } else if (SAFARI_OR_WIN_WEBKIT) { // queueMicrotask is dramatically faster than MessageChannel in Safari // and other WebKit-based browsers, such as the one distributed by Playwright // to test Safari-like behavior on Windows. - // Some of our own integration tests provide a mock queueMicrotask in all - // environments because it's simpler to mock than MessageChannel. return browserQueueMicrotaskImpl(global); } else { // MessageChannel is faster than queueMicrotask in supported browsers diff --git a/spec/core/StackClearerSpec.js b/spec/core/StackClearerSpec.js index 499fc11c..3ce1ac1e 100644 --- a/spec/core/StackClearerSpec.js +++ b/spec/core/StackClearerSpec.js @@ -73,17 +73,6 @@ describe('StackClearer', function() { } }; }); - - describe('when MessageChannel is unavailable', function() { - usesQueueMicrotaskWithSetTimeout(function() { - return { - navigator: { - userAgent: 'CERN-LineMode/2.15 libwww/2.17b3', - MessageChannel: undefined - } - }; - }); - }); }); describe('in Node', function() { diff --git a/spec/core/integration/EnvSpec.js b/spec/core/integration/EnvSpec.js index 9c4c9c47..5aa93a55 100644 --- a/spec/core/integration/EnvSpec.js +++ b/spec/core/integration/EnvSpec.js @@ -1118,6 +1118,13 @@ describe('Env integration', function() { removeEventListener() {}, queueMicrotask: function(fn) { queueMicrotask(fn); + }, + // Enough Node globals to make getStackClearer() return the microtask + // implementation, which is the easiest to mock + process: { + versions: { + node: '' + } } } }); @@ -1194,6 +1201,13 @@ describe('Env integration', function() { removeEventListener() {}, queueMicrotask: function(fn) { queueMicrotask(fn); + }, + // Enough Node globals to make getStackClearer() return the microtask + // implementation, which is the easiest to mock + process: { + versions: { + node: '' + } } } }); @@ -2807,6 +2821,13 @@ describe('Env integration', function() { }, queueMicrotask: function(fn) { queueMicrotask(fn); + }, + // Enough Node globals to make getStackClearer() return the microtask + // implementation, which is the easiest to mock + process: { + versions: { + node: '' + } } }; diff --git a/spec/core/integration/GlobalErrorHandlingSpec.js b/spec/core/integration/GlobalErrorHandlingSpec.js index 27fb96a5..f70ed601 100644 --- a/spec/core/integration/GlobalErrorHandlingSpec.js +++ b/spec/core/integration/GlobalErrorHandlingSpec.js @@ -11,8 +11,8 @@ describe('Global error handling (integration)', function() { env.cleanup_(); }); - it('reports errors that occur during loading', async function() { - const global = { + function mockGlobal() { + return { ...browserEventMethods(), setTimeout: function(fn, delay) { return setTimeout(fn, delay); @@ -23,9 +23,19 @@ describe('Global error handling (integration)', function() { queueMicrotask: function(fn) { queueMicrotask(fn); }, - onerror: function() {} + onerror: function() {}, + // Enough Node globals to make getStackClearer() return the microtask + // implementation, which is the easiest to mock + process: { + versions: { + node: '' + } + } }; + } + it('reports errors that occur during loading', async function() { + const global = mockGlobal(); env.cleanup_(); env = new privateUnderTest.Env({ global }); const reporter = jasmine.createSpyObj('reporter', [ @@ -69,20 +79,9 @@ describe('Global error handling (integration)', function() { describe('If suppressLoadErrors: true was passed', function() { it('does not install a global error handler during loading', async function() { + const global = mockGlobal(); const originalOnerror = jasmine.createSpy('original onerror'); - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - }, - onerror: originalOnerror - }; + global.onerror = originalOnerror; const globalErrors = new privateUnderTest.GlobalErrors(global); const onerror = jasmine.createSpy('onerror'); globalErrors.pushListener(onerror); @@ -114,18 +113,7 @@ describe('Global error handling (integration)', function() { describe('Handling unhandled exceptions', function() { it('routes unhandled exceptions to the running spec', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; + const global = mockGlobal(); env.cleanup_(); env = new privateUnderTest.Env({ global }); const reporter = jasmine.createSpyObj('fakeReporter', [ @@ -154,19 +142,7 @@ describe('Global error handling (integration)', function() { describe('When the most recently running spec has reported specDone', function() { it('routes unhandled exceptions to an ancestor suite', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn) { - clearTimeout(fn); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; - + const global = mockGlobal(); const stackClearer = privateUnderTest.getStackClearer(global); const realClearStack = stackClearer.clearStack; const clearStackCallbacks = {}; @@ -221,18 +197,7 @@ describe('Global error handling (integration)', function() { }); it('routes unhandled exceptions to the running suite', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; + const global = mockGlobal(); env.cleanup_(); env = new privateUnderTest.Env({ global }); const reporter = jasmine.createSpyObj('fakeReporter', [ @@ -273,19 +238,7 @@ describe('Global error handling (integration)', function() { describe('When the most recently suite has reported suiteDone', function() { it('routes unhandled exceptions to an ancestor suite', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; - + const global = mockGlobal(); const stackClearer = privateUnderTest.getStackClearer(global); const realClearStack = stackClearer.clearStack; const clearStackCallbacks = {}; @@ -344,18 +297,7 @@ describe('Global error handling (integration)', function() { describe('When the env has started reporting jasmineDone', function() { it('logs the error to the console', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; + const global = mockGlobal(); env.cleanup_(); env = new privateUnderTest.Env({ global }); @@ -386,19 +328,7 @@ describe('Global error handling (integration)', function() { }); it('routes all errors that occur during stack clearing somewhere', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn) { - clearTimeout(fn); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; - + const global = mockGlobal(); const stackClearer = privateUnderTest.getStackClearer(global); const realClearStack = stackClearer.clearStack; let clearStackCallCount = 0; @@ -462,18 +392,7 @@ describe('Global error handling (integration)', function() { describe('Handling unhandled promise rejections', function() { it('routes unhandled promise rejections to the running spec', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; + const global = mockGlobal(); env.cleanup_(); env = new privateUnderTest.Env({ global }); const reporter = jasmine.createSpyObj('fakeReporter', [ @@ -504,19 +423,7 @@ describe('Global error handling (integration)', function() { describe('When the most recently running spec has reported specDone', function() { it('routes unhandled promise rejections to an ancestor suite', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn) { - clearTimeout(fn); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; - + const global = mockGlobal(); const stackClearer = privateUnderTest.getStackClearer(global); const realClearStack = stackClearer.clearStack; const clearStackCallbacks = {}; @@ -571,18 +478,7 @@ describe('Global error handling (integration)', function() { }); it('routes unhandled promise rejections to the running suite', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; + const global = mockGlobal(); env.cleanup_(); env = new privateUnderTest.Env({ global }); const reporter = jasmine.createSpyObj('fakeReporter', [ @@ -625,19 +521,7 @@ describe('Global error handling (integration)', function() { describe('When the most recently suite has reported suiteDone', function() { it('routes unhandled promise rejections to an ancestor suite', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; - + const global = mockGlobal(); const stackClearer = privateUnderTest.getStackClearer(global); const realClearStack = stackClearer.clearStack; const clearStackCallbacks = {}; @@ -696,18 +580,7 @@ describe('Global error handling (integration)', function() { describe('When the env has started reporting jasmineDone', function() { it('logs the rejection to the console', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; + const global = mockGlobal(); env.cleanup_(); env = new privateUnderTest.Env({ global }); @@ -740,19 +613,7 @@ describe('Global error handling (integration)', function() { }); it('routes all unhandled promise rejections that occur during stack clearing somewhere', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn) { - clearTimeout(fn); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; - + const global = mockGlobal(); const stackClearer = privateUnderTest.getStackClearer(global); const realClearStack = stackClearer.clearStack; let clearStackCallCount = 0; @@ -826,18 +687,7 @@ describe('Global error handling (integration)', function() { let global, reporter; beforeEach(function() { - global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; + global = mockGlobal(); env.cleanup_(); env = new privateUnderTest.Env({ global }); env.configure({ detectLateRejectionHandling: true }); @@ -972,18 +822,7 @@ describe('Global error handling (integration)', function() { describe("When the unhandled rejection event doesn't have a promise", function() { it('reports the rejection', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; + const global = mockGlobal(); env = new privateUnderTest.Env({ global }); env.configure({ detectLateRejectionHandling: true }); const reporter = jasmine.createSpyObj('fakeReporter', [ @@ -1016,18 +855,7 @@ describe('Global error handling (integration)', function() { }); it('works when the suite is run multiple times', async function() { - const global = { - ...browserEventMethods(), - setTimeout: function(fn, delay) { - return setTimeout(fn, delay); - }, - clearTimeout: function(fn, delay) { - clearTimeout(fn, delay); - }, - queueMicrotask: function(fn) { - queueMicrotask(fn); - } - }; + const global = mockGlobal(); env.cleanup_(); env = new privateUnderTest.Env({ global }); env.configure({ autoCleanClosures: false }); diff --git a/src/core/StackClearer.js b/src/core/StackClearer.js index 1634b019..0af66f91 100644 --- a/src/core/StackClearer.js +++ b/src/core/StackClearer.js @@ -141,12 +141,10 @@ getJasmineRequireObj().StackClearer = function(j$) { // Unlike browsers, Node doesn't require us to do a periodic setTimeout // so we avoid the overhead. return nodeQueueMicrotaskImpl(global); - } else if (SAFARI_OR_WIN_WEBKIT || !global.MessageChannel /* tests */) { + } else if (SAFARI_OR_WIN_WEBKIT) { // queueMicrotask is dramatically faster than MessageChannel in Safari // and other WebKit-based browsers, such as the one distributed by Playwright // to test Safari-like behavior on Windows. - // Some of our own integration tests provide a mock queueMicrotask in all - // environments because it's simpler to mock than MessageChannel. return browserQueueMicrotaskImpl(global); } else { // MessageChannel is faster than queueMicrotask in supported browsers