Skip to content

Commit

Permalink
Introduce setupTestAdapter hook (emberjs#1165)
Browse files Browse the repository at this point in the history
While working on emberjs#1163, we encountered an issue with the test
adapter, where unmet expectations (when you set up a `respondTo`
for a test that was never triggered) did not cause the offending
test to fail. Instead, they became unhandled promise rejections
(i.e. "global errors") and fails the _next_ test that runs.

This is because we were using the `QUnit.{testStart,testDone}`
hooks as if they were a global version of `{before,after}Each`.
However, the global hooks are really intended for things like
test reporters and runs too late to affect things like the pass
or fail status of a test.

This commit introduces a `setupTestAdapter` function that uses
the normal (not global) APIs so that the failures are attached
to the correct test.
  • Loading branch information
chancancode authored and nummi committed Apr 5, 2020
1 parent 6eed90f commit 747c36c
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 51 deletions.
3 changes: 2 additions & 1 deletion tests/acceptance/app-picker-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import {
} from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { respondWith, disableDefaultResponseFor } from '../test-adapter';
import { setupTestAdapter, respondWith, disableDefaultResponseFor } from '../test-adapter';

module('App Picker', function(hooks) {
setupTestAdapter(hooks);
setupApplicationTest(hooks);

hooks.beforeEach(function() {
Expand Down
3 changes: 2 additions & 1 deletion tests/acceptance/component-tree-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { respondWith, sendMessage } from '../test-adapter';
import { setupTestAdapter, respondWith, sendMessage } from '../test-adapter';

function textFor(selector, context) {
return context.querySelector(selector).textContent.trim();
Expand Down Expand Up @@ -96,6 +96,7 @@ function getRenderTree() {
}

module('Component Tab', function (hooks) {
setupTestAdapter(hooks);
setupApplicationTest(hooks);

hooks.beforeEach(function() {
Expand Down
3 changes: 2 additions & 1 deletion tests/acceptance/container-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
fillIn,
currentURL
} from 'ember-test-helpers';
import { respondWith } from '../test-adapter';
import { setupTestAdapter, respondWith } from '../test-adapter';

function getTypes() {
return [
Expand Down Expand Up @@ -39,6 +39,7 @@ function getControllers() {
}

module('Container Tab', function(outer) {
setupTestAdapter(outer);
setupApplicationTest(outer);

module('With default types', function(inner) {
Expand Down
3 changes: 2 additions & 1 deletion tests/acceptance/data-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { respondWith, sendMessage } from '../test-adapter';
import { setupTestAdapter, respondWith, sendMessage } from '../test-adapter';

function getFilters() {
return [{ name: 'isNew', desc: 'New' }];
Expand Down Expand Up @@ -59,6 +59,7 @@ function getRecords(type) {
}

module('Data Tab', function(outer) {
setupTestAdapter(outer);
setupApplicationTest(outer);

module('Model Types', function(inner) {
Expand Down
3 changes: 2 additions & 1 deletion tests/acceptance/deprecation-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { visit, findAll, fillIn, click } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { enableOpenResource, respondWith, expectOpenResource, disableDefaultResponseFor } from '../test-adapter';
import { setupTestAdapter, enableOpenResource, respondWith, expectOpenResource, disableDefaultResponseFor } from '../test-adapter';

/*
Toggling the source can be done by clicking the
Expand Down Expand Up @@ -53,6 +53,7 @@ function deprecationsWithSource() {
}

module('Deprecation Tab', function(outer) {
setupTestAdapter(outer);
setupApplicationTest(outer);

outer.beforeEach(function() {
Expand Down
3 changes: 2 additions & 1 deletion tests/acceptance/info-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { visit, findAll } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import config from 'ember-inspector/config/environment';
import { respondWith } from '../test-adapter';
import { setupTestAdapter, respondWith } from '../test-adapter';

module('Info Tab', function(hooks) {
setupTestAdapter(hooks);
setupApplicationTest(hooks);

test("Libraries are displayed correctly", async function(assert) {
Expand Down
3 changes: 2 additions & 1 deletion tests/acceptance/object-inspector-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { respondWith, sendMessage } from '../test-adapter';
import { setupTestAdapter, respondWith, sendMessage } from '../test-adapter';

function objectFactory(props) {
return {
Expand Down Expand Up @@ -69,6 +69,7 @@ function objectToInspect() {
}

module('Object Inspector', function(hooks) {
setupTestAdapter(hooks);
setupApplicationTest(hooks);

test("The object displays correctly", async function (assert) {
Expand Down
3 changes: 2 additions & 1 deletion tests/acceptance/promise-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { respondWith, sendMessage } from '../test-adapter';
import { setupTestAdapter, respondWith, sendMessage } from '../test-adapter';

let guids = 0;

Expand All @@ -28,6 +28,7 @@ function generatePromise(props) {
}

module('Promise Tab', function(outer) {
setupTestAdapter(outer);
setupApplicationTest(outer);

outer.beforeEach(function() {
Expand Down
3 changes: 2 additions & 1 deletion tests/acceptance/render-tree-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { visit, findAll, click, fillIn } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { respondWith } from '../test-adapter';
import { setupTestAdapter, respondWith } from '../test-adapter';

function generateProfiles() {
return [
Expand All @@ -27,6 +27,7 @@ function generateProfiles() {
}

module('Render Tree Tab', function(outer) {
setupTestAdapter(outer);
setupApplicationTest(outer);

outer.afterEach(function() {
Expand Down
3 changes: 2 additions & 1 deletion tests/acceptance/route-tree-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { respondWith, sendMessage } from '../test-adapter';
import { setupTestAdapter, respondWith, sendMessage } from '../test-adapter';

function isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item));
Expand Down Expand Up @@ -75,6 +75,7 @@ function routeTree() {
}

module('Route Tree Tab', function(outer) {
setupTestAdapter(outer);
setupApplicationTest(outer);

outer.beforeEach(function() {
Expand Down
3 changes: 3 additions & 0 deletions tests/acceptance/whats-new-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { visit, find } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import Pretender from 'pretender';
import { setupTestAdapter } from '../test-adapter';


function urlFor(ref) {
return `https://raw.githubusercontent.com/emberjs/ember-inspector/${encodeURIComponent(ref)}/CHANGELOG.md`;
Expand Down Expand Up @@ -42,6 +44,7 @@ function generateContent(master = false) {
}

module('Whats New', function(outer) {
setupTestAdapter(outer);
setupApplicationTest(outer);

outer.beforeEach(function() {
Expand Down
82 changes: 41 additions & 41 deletions tests/test-adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,60 @@ let resourcesEnabled = false;
let resources = [];
let responders = [];

// Some default responders that are part of the normal application boot cycle
QUnit.testStart(() => {
respondWith('check-version', false, { isDefault: true });

respondWith('general:applicationBooted', {
type: 'general:applicationBooted',
applicationId: 'my-app',
applicationName: 'My App',
booted: true
}, { isDefault: true });

respondWith('app-picker-loaded', {
type: 'apps-loaded',
applicationId: null,
applicationName: null,
apps: [{
export function setupTestAdapter(hooks) {
// Some default responders that are part of the normal application boot cycle
hooks.beforeEach(function() {
respondWith('check-version', false, { isDefault: true });

respondWith('general:applicationBooted', {
type: 'general:applicationBooted',
applicationId: 'my-app',
applicationName: 'My App'
}]
}, { isDefault: true });

respondWith('app-selected', false, { isDefault: true });

respondWith('deprecation:getCount', ({ applicationId, applicationName }) => ({
type: 'deprecation:count',
applicationId,
applicationName,
count: 0
}), { isDefault: true });
});

// Ensure all expectations are met and reset the global states
QUnit.testDone(({ failed }) => {
if (failed === 0) {
applicationName: 'My App',
booted: true
}, { isDefault: true });

respondWith('app-picker-loaded', {
type: 'apps-loaded',
applicationId: null,
applicationName: null,
apps: [{
applicationId: 'my-app',
applicationName: 'My App'
}]
}, { isDefault: true });

respondWith('app-selected', false, { isDefault: true });

respondWith('deprecation:getCount', ({ applicationId, applicationName }) => ({
type: 'deprecation:count',
applicationId,
applicationName,
count: 0
}), { isDefault: true });
});

// Ensure all expectations are met and reset the global states
hooks.afterEach(function(assert) {
for (let { file, line, actual, expected, reject } of resources) {
if (!isNaN(expected) && actual !== expected) {
QUnit.assert.strictEqual(actual, expected, `Expceting resouce ${file}:${line} to be opened ${expected} time(s)`);
assert.strictEqual(actual, expected, `Expceting resouce ${file}:${line} to be opened ${expected} time(s)`);
reject(`Expceting resouce ${file}:${line} to be opened ${expected} time(s), was opened ${actual} time(s)`);
}
}

for (let { type, isDefault, actual, expected, reject } of responders) {
if (!isDefault && !isNaN(expected) && actual !== expected) {
QUnit.assert.strictEqual(actual, expected, `The correct amount of ${type} messages are sent`);
assert.strictEqual(actual, expected, `The correct amount of ${type} messages are sent`);
reject(`Expecting ${expected} ${type} messages, got ${actual}`);
}
}
}

adapter = null;
resourcesEnabled = false;
resources.length = 0;
responders.length = 0;
});
adapter = null;
resourcesEnabled = false;
resources.length = 0;
responders.length = 0;
});
}

/**
* Allow `openResouce` to be called on the adapter.
Expand Down

0 comments on commit 747c36c

Please sign in to comment.