From dc80a282baf961fce8720ab87529630568da3496 Mon Sep 17 00:00:00 2001 From: Bjarki Date: Thu, 1 Jul 2021 20:21:44 +0000 Subject: [PATCH 1/5] Make j$.isError_ compatible with Trusted Types The isError_ check uses a heuristic that calls the Function constructor to determine if the given value is an Error object. This results in a runtime violation in test suites that enforce Trusted Types. Since Trusted Types are only supported in modern browsers (currently, Chromium-based browsers), we can use a more straightforward heuristic in environments where Trusted Types are supported. Fixes #1910. See that thread for more details. --- lib/jasmine-core/jasmine.js | 10 ++++++++++ src/core/base.js | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 1ad0935a..406c6b67 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -270,6 +270,16 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { if (value instanceof Error) { return true; } + if ( + typeof window !== 'undefined' && + typeof window.trustedTypes !== 'undefined' + ) { + return ( + value && + typeof value.stack === 'string' && + typeof value.message === 'string' + ); + } if (value && value.constructor && value.constructor.constructor) { var valueGlobal = value.constructor.constructor('return this'); if (j$.isFunction_(valueGlobal)) { diff --git a/src/core/base.js b/src/core/base.js index c40c6559..1d31d89d 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -102,6 +102,16 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { if (value instanceof Error) { return true; } + if ( + typeof window !== 'undefined' && + typeof window.trustedTypes !== 'undefined' + ) { + return ( + value && + typeof value.stack === 'string' && + typeof value.message === 'string' + ); + } if (value && value.constructor && value.constructor.constructor) { var valueGlobal = value.constructor.constructor('return this'); if (j$.isFunction_(valueGlobal)) { From 88b90ec25803c126fe185ac4866ad417aede511d Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Mon, 19 Jul 2021 10:31:53 -0700 Subject: [PATCH 2/5] Backfilled unit tests for j$.isError_ --- spec/core/baseSpec.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/spec/core/baseSpec.js b/spec/core/baseSpec.js index 51b90063..dd5dd225 100644 --- a/spec/core/baseSpec.js +++ b/spec/core/baseSpec.js @@ -29,6 +29,43 @@ describe('base helpers', function() { } }, 100); }); + + it('returns true for an Error subclass', function() { + function MyError() {} + MyError.prototype = new Error(); + expect(jasmineUnderTest.isError_(new MyError())).toBe(true); + }); + + it('returns true for an un-thrown Error with no message in this environment', function() { + expect(jasmineUnderTest.isError_(new Error())).toBe(true); + }); + + it('returns true for an Error that originated from another frame', function() { + var iframe, error; + + if (typeof window === 'undefined') { + pending('This test only runs in browsers.'); + } + + iframe = document.createElement('iframe'); + iframe.style.display = 'none'; + document.body.appendChild(iframe); + + try { + error = iframe.contentWindow.eval('new Error()'); + expect(jasmineUnderTest.isError_(error)).toBe(true); + } finally { + document.body.removeChild(iframe); + } + }); + + it('returns false for a falsy value', function() { + expect(jasmineUnderTest.isError_(undefined)).toBe(false); + }); + + it('returns false for a non-Error object', function() { + expect(jasmineUnderTest.isError_({})).toBe(false); + }); }); describe('isAsymmetricEqualityTester_', function() { From 3513249d732348c9faa26552e7636790d711900e Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Mon, 19 Jul 2021 12:08:18 -0700 Subject: [PATCH 3/5] Built distribution --- lib/jasmine-core/jasmine.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 661968a1..06c35e71 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -1585,6 +1585,7 @@ getJasmineRequireObj().Env = function(j$) { * @name Env#hideDisabled * @since 3.2.0 * @function + * @deprecated Use the `hideDisabled` option with {@link Env#configure} */ this.hideDisabled = function(value) { this.deprecated( From c1d1d69be2416f3854b32017a792249715428cd8 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Mon, 19 Jul 2021 12:02:42 -0700 Subject: [PATCH 4/5] Fixed test failures in Chrome and Edge --- lib/jasmine-core/jasmine.js | 8 +++++--- src/core/base.js | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 06c35e71..8700ca69 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -267,6 +267,10 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { }; j$.isError_ = function(value) { + if (!value) { + return false; + } + if (value instanceof Error) { return true; } @@ -275,9 +279,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { typeof window.trustedTypes !== 'undefined' ) { return ( - value && - typeof value.stack === 'string' && - typeof value.message === 'string' + typeof value.stack === 'string' && typeof value.message === 'string' ); } if (value && value.constructor && value.constructor.constructor) { diff --git a/src/core/base.js b/src/core/base.js index 1d31d89d..89cd2b6e 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -99,6 +99,10 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { }; j$.isError_ = function(value) { + if (!value) { + return false; + } + if (value instanceof Error) { return true; } @@ -107,9 +111,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { typeof window.trustedTypes !== 'undefined' ) { return ( - value && - typeof value.stack === 'string' && - typeof value.message === 'string' + typeof value.stack === 'string' && typeof value.message === 'string' ); } if (value && value.constructor && value.constructor.constructor) { From c10ab4e7041ed2f9ab79bac2f6a505a6bb3b48e9 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Tue, 20 Jul 2021 16:50:31 -0700 Subject: [PATCH 5/5] Updated deprecation links --- lib/jasmine-core/jasmine.js | 17 +++++++++-------- ...asymmetricEqualityTesterArgCompatShimSpec.js | 4 ++-- .../core/integration/CustomAsyncMatchersSpec.js | 4 ++-- spec/core/integration/CustomMatchersSpec.js | 4 ++-- spec/core/matchers/matchersUtilSpec.js | 6 +++--- src/core/Env.js | 4 ++-- .../asymmetricEqualityTesterArgCompatShim.js | 2 +- src/core/matchers/matchersUtil.js | 6 +++--- src/core/requireCore.js | 4 ++-- 9 files changed, 26 insertions(+), 25 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index ac6c0eda..790ed107 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -88,7 +88,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) { 'Use the pp method of the matchersUtil passed to the matcher factory ' + "or the asymmetric equality tester's `asymmetricMatch` method " + 'instead. See ' + - ' for details.' + ' for details.' ); return j$.basicPrettyPrinter_; } @@ -104,7 +104,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) { 'jasmine.matchersUtil is deprecated and will be removed ' + 'in a future release. Use the instance passed to the matcher factory or ' + "the asymmetric equality tester's `asymmetricMatch` method instead. " + - 'See for details.' + 'See for details.' ); return staticMatchersUtil; } @@ -1336,7 +1336,7 @@ getJasmineRequireObj().Env = function(j$) { '" ' + 'accepts custom equality testers, but this parameter will no longer be ' + 'passed in a future release. ' + - 'See for details.' + 'See for details.' ); } @@ -1361,7 +1361,7 @@ getJasmineRequireObj().Env = function(j$) { '" ' + 'accepts custom equality testers, but this parameter will no longer be ' + 'passed in a future release. ' + - 'See for details.' + 'See for details.' ); } @@ -1672,6 +1672,7 @@ getJasmineRequireObj().Env = function(j$) { * @name Env#hideDisabled * @since 3.2.0 * @function + * @deprecated Use the `hideDisabled` option with {@link Env#configure} */ this.hideDisabled = function(value) { this.deprecated( @@ -3067,7 +3068,7 @@ getJasmineRequireObj().asymmetricEqualityTesterArgCompatShim = function(j$) { 'The second argument to asymmetricMatch is now a ' + 'MatchersUtil. Using it as an array of custom equality testers is ' + 'deprecated and will stop working in a future release. ' + - 'See for details.' + 'See for details.' ); return src[propName]; } @@ -5274,7 +5275,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) { j$.getEnv().deprecated( 'Passing custom equality testers ' + 'to MatchersUtil#contains is deprecated. ' + - 'See for details.' + 'See for details.' ); } @@ -5411,7 +5412,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) { j$.getEnv().deprecated( 'Passing custom equality testers ' + 'to MatchersUtil#equals is deprecated. ' + - 'See for details.' + 'See for details.' ); } @@ -5419,7 +5420,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) { j$.getEnv().deprecated( 'Diff builder should be passed ' + 'as the third argument to MatchersUtil#equals, not the fourth. ' + - 'See for details.' + 'See for details.' ); } diff --git a/spec/core/asymmetricEqualityTesterArgCompatShimSpec.js b/spec/core/asymmetricEqualityTesterArgCompatShimSpec.js index 26bb90fd..45275f38 100644 --- a/spec/core/asymmetricEqualityTesterArgCompatShimSpec.js +++ b/spec/core/asymmetricEqualityTesterArgCompatShimSpec.js @@ -24,7 +24,7 @@ describe('asymmetricEqualityTesterArgCompatShim', function() { 'The second argument to asymmetricMatch is now a MatchersUtil. ' + 'Using it as an array of custom equality testers is deprecated and will stop ' + 'working in a future release. ' + - 'See for details.'; + 'See for details.'; expect(shim.length).toBe(2); expect(deprecated).toHaveBeenCalledWith(expectedMessage); @@ -45,7 +45,7 @@ describe('asymmetricEqualityTesterArgCompatShim', function() { 'The second argument to asymmetricMatch is now a MatchersUtil. ' + 'Using it as an array of custom equality testers is deprecated and will stop ' + 'working in a future release. ' + - 'See for details.'; + 'See for details.'; expect(shim.filter).toBe(Array.prototype.filter); expect(deprecated).toHaveBeenCalledWith(expectedMessage); diff --git a/spec/core/integration/CustomAsyncMatchersSpec.js b/spec/core/integration/CustomAsyncMatchersSpec.js index 5cc16c82..590234b8 100644 --- a/spec/core/integration/CustomAsyncMatchersSpec.js +++ b/spec/core/integration/CustomAsyncMatchersSpec.js @@ -222,14 +222,14 @@ describe('Custom Async Matchers (Integration)', function() { jasmine.stringMatching( 'The matcher factory for "toBeFoo" accepts custom equality testers, ' + 'but this parameter will no longer be passed in a future release. ' + - 'See for details.' + 'See for details.' ) ); expect(env.deprecated).toHaveBeenCalledWith( jasmine.stringMatching( 'The matcher factory for "toBeBar" accepts custom equality testers, ' + 'but this parameter will no longer be passed in a future release. ' + - 'See for details.' + 'See for details.' ) ); done(); diff --git a/spec/core/integration/CustomMatchersSpec.js b/spec/core/integration/CustomMatchersSpec.js index 3fcb0a07..205c52ac 100644 --- a/spec/core/integration/CustomMatchersSpec.js +++ b/spec/core/integration/CustomMatchersSpec.js @@ -370,14 +370,14 @@ describe('Custom Matchers (Integration)', function() { jasmine.stringMatching( 'The matcher factory for "toBeFoo" accepts custom equality testers, ' + 'but this parameter will no longer be passed in a future release. ' + - 'See for details.' + 'See for details.' ) ); expect(env.deprecated).toHaveBeenCalledWith( jasmine.stringMatching( 'The matcher factory for "toBeBar" accepts custom equality testers, ' + 'but this parameter will no longer be passed in a future release. ' + - 'See for details.' + 'See for details.' ) ); done(); diff --git a/spec/core/matchers/matchersUtilSpec.js b/spec/core/matchers/matchersUtilSpec.js index f3ce7797..3d86f01d 100644 --- a/spec/core/matchers/matchersUtilSpec.js +++ b/spec/core/matchers/matchersUtilSpec.js @@ -1115,7 +1115,7 @@ describe('matchersUtil', function() { jasmine.stringMatching( 'Passing custom equality testers ' + 'to MatchersUtil#equals is deprecated. ' + - 'See for details.' + 'See for details.' ) ); }); @@ -1130,7 +1130,7 @@ describe('matchersUtil', function() { jasmine.stringMatching( 'Diff builder should be passed as the ' + 'third argument to MatchersUtil#equals, not the fourth. ' + - 'See for details.' + 'See for details.' ) ); }); @@ -1218,7 +1218,7 @@ describe('matchersUtil', function() { expect(deprecated).toHaveBeenCalledWith( jasmine.stringMatching( 'Passing custom equality testers to MatchersUtil#contains is deprecated. ' + - 'See for details.' + 'See for details.' ) ); }); diff --git a/src/core/Env.js b/src/core/Env.js index d1f78c8f..12878621 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -317,7 +317,7 @@ getJasmineRequireObj().Env = function(j$) { '" ' + 'accepts custom equality testers, but this parameter will no longer be ' + 'passed in a future release. ' + - 'See for details.' + 'See for details.' ); } @@ -342,7 +342,7 @@ getJasmineRequireObj().Env = function(j$) { '" ' + 'accepts custom equality testers, but this parameter will no longer be ' + 'passed in a future release. ' + - 'See for details.' + 'See for details.' ); } diff --git a/src/core/asymmetricEqualityTesterArgCompatShim.js b/src/core/asymmetricEqualityTesterArgCompatShim.js index 7ba21831..2a16b48f 100644 --- a/src/core/asymmetricEqualityTesterArgCompatShim.js +++ b/src/core/asymmetricEqualityTesterArgCompatShim.js @@ -92,7 +92,7 @@ getJasmineRequireObj().asymmetricEqualityTesterArgCompatShim = function(j$) { 'The second argument to asymmetricMatch is now a ' + 'MatchersUtil. Using it as an array of custom equality testers is ' + 'deprecated and will stop working in a future release. ' + - 'See for details.' + 'See for details.' ); return src[propName]; } diff --git a/src/core/matchers/matchersUtil.js b/src/core/matchers/matchersUtil.js index f6b249cb..16c2d32e 100644 --- a/src/core/matchers/matchersUtil.js +++ b/src/core/matchers/matchersUtil.js @@ -38,7 +38,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) { j$.getEnv().deprecated( 'Passing custom equality testers ' + 'to MatchersUtil#contains is deprecated. ' + - 'See for details.' + 'See for details.' ); } @@ -175,7 +175,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) { j$.getEnv().deprecated( 'Passing custom equality testers ' + 'to MatchersUtil#equals is deprecated. ' + - 'See for details.' + 'See for details.' ); } @@ -183,7 +183,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) { j$.getEnv().deprecated( 'Diff builder should be passed ' + 'as the third argument to MatchersUtil#equals, not the fourth. ' + - 'See for details.' + 'See for details.' ); } diff --git a/src/core/requireCore.js b/src/core/requireCore.js index 80de1e28..6372fd68 100644 --- a/src/core/requireCore.js +++ b/src/core/requireCore.js @@ -66,7 +66,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) { 'Use the pp method of the matchersUtil passed to the matcher factory ' + "or the asymmetric equality tester's `asymmetricMatch` method " + 'instead. See ' + - ' for details.' + ' for details.' ); return j$.basicPrettyPrinter_; } @@ -82,7 +82,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) { 'jasmine.matchersUtil is deprecated and will be removed ' + 'in a future release. Use the instance passed to the matcher factory or ' + "the asymmetric equality tester's `asymmetricMatch` method instead. " + - 'See for details.' + 'See for details.' ); return staticMatchersUtil; }