diff --git a/package.json b/package.json index c4fe765e19b..6d1141f8442 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "babel-plugin-filter-imports": "^2.0.4", "babel-plugin-module-resolver": "^3.2.0", "babel-template": "^6.26.0", - "backburner.js": "^2.4.2", + "backburner.js": "^2.5.0", "broccoli-babel-transpiler": "^7.1.2", "broccoli-concat": "^3.7.3", "broccoli-debug": "^0.6.4", diff --git a/packages/ember-testing/tests/adapters_test.js b/packages/ember-testing/tests/adapters_test.js index 943ed901c26..3dd4bbd049c 100644 --- a/packages/ember-testing/tests/adapters_test.js +++ b/packages/ember-testing/tests/adapters_test.js @@ -8,10 +8,12 @@ import { moduleFor, AbstractTestCase } from 'internal-test-helpers'; import { RSVP } from '@ember/-internals/runtime'; import { getDebugFunction, setDebugFunction } from '@ember/debug'; +const HAS_UNHANDLED_REJECTION_HANDLER = 'onunhandledrejection' in window; + const originalDebug = getDebugFunction('debug'); const noop = function() {}; -var App, originalAdapter, originalQUnit, originalWindowOnerror; +var App, originalAdapter, originalQUnit, originalWindowOnerror, originalQUnitUnhandledRejection; var originalConsoleError = console.error; // eslint-disable-line no-console @@ -32,15 +34,14 @@ class AdapterSetupAndTearDown extends AbstractTestCase { setDebugFunction('debug', noop); super(); originalAdapter = Test.adapter; - originalQUnit = window.QUnit; + originalQUnit = QUnit; originalWindowOnerror = window.onerror; + originalQUnitUnhandledRejection = QUnit.onUnhandledRejection; } afterEach() { - console.error = originalConsoleError; // eslint-disable-line no-console - } + super.afterEach(); - teardown() { setDebugFunction('debug', originalDebug); if (App) { run(App, App.destroy); @@ -52,6 +53,8 @@ class AdapterSetupAndTearDown extends AbstractTestCase { window.QUnit = originalQUnit; window.onerror = originalWindowOnerror; setOnerror(undefined); + console.error = originalConsoleError; // eslint-disable-line no-console + QUnit.onUnhandledRejection = originalQUnitUnhandledRejection; } } @@ -240,6 +243,11 @@ moduleFor( function testAdapter(message, generatePromise, timeout = 10) { return class PromiseFailureTests extends AdapterSetupAndTearDown { [`@test ${message} when TestAdapter without \`exception\` method is present - rsvp`](assert) { + if (!HAS_UNHANDLED_REJECTION_HANDLER) { + assert.expect(0); + return; + } + assert.expect(1); let thrown = new Error('the error'); @@ -247,13 +255,16 @@ function testAdapter(message, generatePromise, timeout = 10) { exception: undefined, }); - window.onerror = function(message) { + // prevent QUnit handler from failing test + QUnit.onUnhandledRejection = () => {}; + + window.onunhandledrejection = function(rejection) { assert.pushResult({ - result: /the error/.test(message), - actual: message, + result: /the error/.test(rejection.reason), + actual: rejection.reason, expected: 'to include `the error`', message: - 'error should bubble out to window.onerror, and therefore fail tests (due to QUnit implementing window.onerror)', + 'error should bubble out to window.onunhandledrejection, and therefore fail tests (due to QUnit implementing window.onunhandledrejection)', }); // prevent "bubbling" and therefore failing the test diff --git a/packages/ember/tests/error_handler_test.js b/packages/ember/tests/error_handler_test.js index ce419ddca3b..d2eb79b6a3e 100644 --- a/packages/ember/tests/error_handler_test.js +++ b/packages/ember/tests/error_handler_test.js @@ -4,6 +4,8 @@ import { getOnerror, setOnerror } from '@ember/-internals/error-handling'; import RSVP from 'rsvp'; import { moduleFor, AbstractTestCase } from 'internal-test-helpers'; +const HAS_UNHANDLED_REJECTION_HANDLER = 'onunhandledrejection' in window; +let QUNIT_ON_UNHANDLED_REJECTION = QUnit.onUnhandledRejection; let WINDOW_ONERROR; function runThatThrowsSync(message = 'Error for testing error handling') { @@ -26,6 +28,7 @@ moduleFor( window.onerror = WINDOW_ONERROR; setOnerror(undefined); + QUnit.onUnhandledRejection = QUNIT_ON_UNHANDLED_REJECTION; } ['@test by default there is no onerror - sync run'](assert) { @@ -238,6 +241,11 @@ moduleFor( [`@test errors in promise constructor when Ember.onerror which does rethrow is present - rsvp`]( assert ) { + if (!HAS_UNHANDLED_REJECTION_HANDLER) { + assert.expect(0); + return; + } + assert.expect(2); let thrown = new Error('the error'); @@ -250,17 +258,17 @@ moduleFor( throw error; }); - window.onerror = function(message) { + // prevent QUnit handler from failing test + QUnit.onUnhandledRejection = () => {}; + + window.onunhandledrejection = function(event) { assert.pushResult({ - result: /the error/.test(message), - actual: message, + result: /the error/.test(event.reason), + actual: event.reason, expected: 'to include `the error`', message: - 'error should bubble out to window.onerror, and therefore fail tests (due to QUnit implementing window.onerror)', + 'error should bubble out to window.onunhandledrejection, and therefore fail tests (due to QUnit implementing window.onunhandledrejection)', }); - - // prevent "bubbling" and therefore failing the test - return true; }; new RSVP.Promise(() => { @@ -299,6 +307,11 @@ moduleFor( [`@test errors in promise constructor when Ember.onerror which does rethrow is present (Ember.testing = false) - rsvp`]( assert ) { + if (!HAS_UNHANDLED_REJECTION_HANDLER) { + assert.expect(0); + return; + } + assert.expect(2); setTesting(false); @@ -312,17 +325,17 @@ moduleFor( throw error; }); - window.onerror = function(message) { + // prevent QUnit handler from failing test + QUnit.onUnhandledRejection = () => {}; + + window.onunhandledrejection = function(event) { assert.pushResult({ - result: /the error/.test(message), - actual: message, + result: /the error/.test(event.reason), + actual: event.reason, expected: 'to include `the error`', message: - 'error should bubble out to window.onerror, and therefore fail tests (due to QUnit implementing window.onerror)', + 'error should bubble out to window.onunhandledrejection, and therefore fail tests (due to QUnit implementing window.onunhandledrejection)', }); - - // prevent "bubbling" and therefore failing the test - return true; }; new RSVP.Promise(() => { @@ -360,6 +373,11 @@ moduleFor( [`@test errors in promise .then callback when Ember.onerror which does rethrow is present - rsvp`]( assert ) { + if (!HAS_UNHANDLED_REJECTION_HANDLER) { + assert.expect(0); + return; + } + assert.expect(2); let thrown = new Error('the error'); @@ -372,17 +390,17 @@ moduleFor( throw error; }); - window.onerror = function(message) { + // prevent QUnit handler from failing test + QUnit.onUnhandledRejection = () => {}; + + window.onunhandledrejection = function(event) { assert.pushResult({ - result: /the error/.test(message), - actual: message, + result: /the error/.test(event.reason), + actual: event.reason, expected: 'to include `the error`', message: - 'error should bubble out to window.onerror, and therefore fail tests (due to QUnit implementing window.onerror)', + 'error should bubble out to window.onunhandledrejection, and therefore fail tests (due to QUnit implementing window.onunhandledrejection)', }); - - // prevent "bubbling" and therefore failing the test - return true; }; RSVP.resolve().then(() => { @@ -421,6 +439,11 @@ moduleFor( [`@test errors in promise .then callback when Ember.onerror which does rethrow is present (Ember.testing = false) - rsvp`]( assert ) { + if (!HAS_UNHANDLED_REJECTION_HANDLER) { + assert.expect(0); + return; + } + assert.expect(2); setTesting(false); @@ -434,17 +457,17 @@ moduleFor( throw error; }); - window.onerror = function(message) { + // prevent QUnit handler from failing test + QUnit.onUnhandledRejection = () => {}; + + window.onunhandledrejection = function(event) { assert.pushResult({ - result: /the error/.test(message), - actual: message, + result: /the error/.test(event.reason), + actual: event.reason, expected: 'to include `the error`', message: - 'error should bubble out to window.onerror, and therefore fail tests (due to QUnit implementing window.onerror)', + 'error should bubble out to window.onunhandledrejection, and therefore fail tests (due to QUnit implementing window.onunhandledrejection)', }); - - // prevent "bubbling" and therefore failing the test - return true; }; RSVP.resolve().then(() => { @@ -482,6 +505,11 @@ moduleFor( [`@test errors in async promise .then callback when Ember.onerror which does rethrow is present - rsvp`]( assert ) { + if (!HAS_UNHANDLED_REJECTION_HANDLER) { + assert.expect(0); + return; + } + assert.expect(2); let thrown = new Error('the error'); @@ -494,17 +522,17 @@ moduleFor( throw error; }); - window.onerror = function(message) { + // prevent QUnit handler from failing test + QUnit.onUnhandledRejection = () => {}; + + window.onunhandledrejection = function(event) { assert.pushResult({ - result: /the error/.test(message), - actual: message, + result: /the error/.test(event.reason), + actual: event.reason, expected: 'to include `the error`', message: - 'error should bubble out to window.onerror, and therefore fail tests (due to QUnit implementing window.onerror)', + 'error should bubble out to window.onunhandledrejection, and therefore fail tests (due to QUnit implementing window.onunhandledrejection)', }); - - // prevent "bubbling" and therefore failing the test - return true; }; new RSVP.Promise(resolve => setTimeout(resolve, 10)).then(() => { @@ -543,6 +571,10 @@ moduleFor( [`@test errors in async promise .then callback when Ember.onerror which does rethrow is present (Ember.testing = false) - rsvp`]( assert ) { + if (!HAS_UNHANDLED_REJECTION_HANDLER) { + assert.expect(0); + return; + } assert.expect(2); setTesting(false); @@ -556,17 +588,17 @@ moduleFor( throw error; }); - window.onerror = function(message) { + // prevent QUnit handler from failing test + QUnit.onUnhandledRejection = () => {}; + + window.onunhandledrejection = function(event) { assert.pushResult({ - result: /the error/.test(message), - actual: message, + result: /the error/.test(event.reason), + actual: event.reason, expected: 'to include `the error`', message: - 'error should bubble out to window.onerror, and therefore fail tests (due to QUnit implementing window.onerror)', + 'error should bubble out to window.onunhandledrejection, and therefore fail tests (due to QUnit implementing window.onunhandledrejection)', }); - - // prevent "bubbling" and therefore failing the test - return true; }; new RSVP.Promise(resolve => setTimeout(resolve, 10)).then(() => { diff --git a/yarn.lock b/yarn.lock index deb582db2e5..5a74b47db9f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1339,10 +1339,10 @@ backbone@^1.1.2: dependencies: underscore ">=1.8.3" -backburner.js@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/backburner.js/-/backburner.js-2.4.2.tgz#4cc2d3e78592ddd46ae9a48cfc168ca883b56e6b" - integrity sha512-YFgfwWvelbJ9JxsVF+sph7nLB2qQfwDyUXCr+ZPyeU6HOXGAT0Rt+ro+mU1zRMnUfYG57nwaTiz1yqvqNO6jQQ== +backburner.js@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/backburner.js/-/backburner.js-2.5.0.tgz#d03ab8f7b77e708ac4bc7bea2258aa57177b560d" + integrity sha512-YkLvnh0jEA67NNJ+NqJrX4Yb/isanR7XHlb+Y+cMXkGtXzlgx2tHEnZPIWi2kbW9EwtCq3HTRcAF+mbzIhfoqg== backo2@1.0.2: version "1.0.2"