From 40be00310dda9261e31c0e179c88fd0bac057e12 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Fri, 24 Sep 2021 11:22:04 -0700 Subject: [PATCH 1/2] Don't immediately move to the next queueable fn on async error This allows assertion failures and other errors that occcur after the async error to be routed to the correct spec/suite. Previously, Jasmine treated global errors and unhandled promise rejections just like exceptions thrown from a synchronous spec: it recorded the error as a spec failure and moved on. Now, global errors and uhandled rejections are recorded as failures but the current queueable fn will continue until it either signals completion or times out. Global errors and unhandled rejections are different from synchronous exceptions: it's common for the queueable fn that caused them to continue executing. Immediately moving on often meant that the queueable fn would produce expectation failures or other errors when a different spec or suite was running, thus causing those failures to be routed to the wrong place. --- lib/jasmine-core/jasmine.js | 1 - spec/core/QueueRunnerSpec.js | 13 ++++++++++--- src/core/QueueRunner.js | 1 - 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 6c05f9c1..7ac7ad41 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -7872,7 +7872,6 @@ getJasmineRequireObj().QueueRunner = function(j$) { completedSynchronously = true, handleError = function handleError(error) { onException(error); - next(error); }, cleanup = once(function cleanup() { if (timeoutId !== void 0) { diff --git a/spec/core/QueueRunnerSpec.js b/spec/core/QueueRunnerSpec.js index 7333b02a..7eea2563 100644 --- a/spec/core/QueueRunnerSpec.js +++ b/spec/core/QueueRunnerSpec.js @@ -669,9 +669,13 @@ describe('QueueRunner', function() { jasmine.clock().uninstall(); }); - it('skips to cleanup functions on the first exception', function() { + it('skips to cleanup functions once the fn completes after an unhandled exception', function() { var errorListeners = [], - queueableFn = { fn: function(done) {} }, + queueableFn = { + fn: function(done) { + queueableFnDone = done; + } + }, nextQueueableFn = { fn: jasmine.createSpy('nextFunction') }, cleanupFn = { fn: jasmine.createSpy('cleanup') }, queueRunner = new jasmineUnderTest.QueueRunner({ @@ -686,10 +690,13 @@ describe('QueueRunner', function() { queueableFns: [queueableFn, nextQueueableFn], cleanupFns: [cleanupFn], completeOnFirstError: true - }); + }), + queueableFnDone; queueRunner.execute(); errorListeners[errorListeners.length - 1](new Error('error')); + expect(cleanupFn.fn).not.toHaveBeenCalled(); + queueableFnDone(); expect(nextQueueableFn.fn).not.toHaveBeenCalled(); expect(cleanupFn.fn).toHaveBeenCalled(); }); diff --git a/src/core/QueueRunner.js b/src/core/QueueRunner.js index be9e7f62..679da4a5 100644 --- a/src/core/QueueRunner.js +++ b/src/core/QueueRunner.js @@ -89,7 +89,6 @@ getJasmineRequireObj().QueueRunner = function(j$) { completedSynchronously = true, handleError = function handleError(error) { onException(error); - next(error); }, cleanup = once(function cleanup() { if (timeoutId !== void 0) { From 3b28ee7c29e6d244d485995ed78490afa67a2cb0 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Fri, 24 Sep 2021 14:24:22 -0700 Subject: [PATCH 2/2] Fixed extra deprecation when passing custom equality testers to MatchersUtil#contains --- lib/jasmine-core/jasmine.js | 11 ++++++++--- spec/core/matchers/matchersUtilSpec.js | 16 ++++++++++++++++ src/core/matchers/matchersUtil.js | 11 ++++++++--- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 58887e75..d084a3d9 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -5493,8 +5493,13 @@ getJasmineRequireObj().MatchersUtil = function(j$) { (!!haystack && !haystack.indexOf) ) { for (var i = 0; i < haystack.length; i++) { - if (this.equals(haystack[i], needle, customTesters)) { - return true; + try { + this.suppressDeprecation_ = true; + if (this.equals(haystack[i], needle, customTesters)) { + return true; + } + } finally { + this.suppressDeprecation_ = false; } } return false; @@ -5613,7 +5618,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) { if (isDiffBuilder(customTestersOrDiffBuilder)) { diffBuilder = customTestersOrDiffBuilder; } else { - if (customTestersOrDiffBuilder) { + if (customTestersOrDiffBuilder && !this.suppressDeprecation_) { j$.getEnv().deprecated( 'Passing custom equality testers ' + 'to MatchersUtil#equals is deprecated. ' + diff --git a/spec/core/matchers/matchersUtilSpec.js b/spec/core/matchers/matchersUtilSpec.js index 3d86f01d..7fc9fc85 100644 --- a/spec/core/matchers/matchersUtilSpec.js +++ b/spec/core/matchers/matchersUtilSpec.js @@ -1235,6 +1235,22 @@ describe('matchersUtil', function() { expect(matchersUtil.contains([1, 2], 3)).toBe(true); }); + it('logs a single deprecation warning when custom equality testers are passed', function() { + // TODO: remove this in the next major release. + var matchersUtil = new jasmineUnderTest.MatchersUtil(), + deprecated = spyOn(jasmineUnderTest.getEnv(), 'deprecated'); + + matchersUtil.contains([0], 0, []); + + expect(deprecated).toHaveBeenCalledOnceWith( + jasmine.stringMatching( + 'Passing custom equality testers ' + + 'to MatchersUtil#contains is deprecated. ' + + 'See for details.' + ) + ); + }); + it('fails when actual is undefined', function() { var matchersUtil = new jasmineUnderTest.MatchersUtil(); expect(matchersUtil.contains(undefined, 'A')).toBe(false); diff --git a/src/core/matchers/matchersUtil.js b/src/core/matchers/matchersUtil.js index bba9797c..f8819549 100644 --- a/src/core/matchers/matchersUtil.js +++ b/src/core/matchers/matchersUtil.js @@ -51,8 +51,13 @@ getJasmineRequireObj().MatchersUtil = function(j$) { (!!haystack && !haystack.indexOf) ) { for (var i = 0; i < haystack.length; i++) { - if (this.equals(haystack[i], needle, customTesters)) { - return true; + try { + this.suppressDeprecation_ = true; + if (this.equals(haystack[i], needle, customTesters)) { + return true; + } + } finally { + this.suppressDeprecation_ = false; } } return false; @@ -171,7 +176,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) { if (isDiffBuilder(customTestersOrDiffBuilder)) { diffBuilder = customTestersOrDiffBuilder; } else { - if (customTestersOrDiffBuilder) { + if (customTestersOrDiffBuilder && !this.suppressDeprecation_) { j$.getEnv().deprecated( 'Passing custom equality testers ' + 'to MatchersUtil#equals is deprecated. ' +