Skip to content

Commit

Permalink
Add hooks API for setupContainerTest() to improve beforeEach/afterEac…
Browse files Browse the repository at this point in the history
…h ordering
  • Loading branch information
simonihmig committed Feb 21, 2018
1 parent 74f83df commit ca5178c
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 36 deletions.
17 changes: 7 additions & 10 deletions addon-test-support/ember-mocha/setup-application-test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import {
beforeEach,
afterEach
} from 'mocha';
import {
setupApplicationContext,
teardownApplicationContext
} from '@ember/test-helpers';
import setupContainerTest from './setup-container-test';

export default function setupApplicationTest(options) {
afterEach(function() {
return teardownApplicationContext(this);
});

setupContainerTest(options);
let hooks = setupContainerTest(options);

beforeEach(function() {
hooks.beforeEach(function() {
return setupApplicationContext(this);
});
hooks.afterEach(function() {
return teardownApplicationContext(this);
});

return hooks;
}
61 changes: 51 additions & 10 deletions addon-test-support/ember-mocha/setup-container-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,26 @@ import {
teardownContext
} from '@ember/test-helpers';
import { assign, merge } from '@ember/polyfills';
import { resolve } from 'rsvp';

const _assign = assign || merge;

function chainHooks(hooks, context, promise = resolve()) {
hooks.forEach((fn) => {
promise = promise.then(fn.bind(context));
});
return promise;
}

export default function setupUnitTest(options) {
let originalContext;
let beforeEachHooks = [];
let afterEachHooks = [];

beforeEach(function() {
originalContext = _assign({}, this);

return setupContext(this, options).then(() => {
let promise = setupContext(this, options).then(() => {

let originalPauseTest = this.pauseTest;
this.pauseTest = function Mocha_pauseTest() {
Expand All @@ -25,19 +35,50 @@ export default function setupUnitTest(options) {
return originalPauseTest.call(this);
};
});

return chainHooks(beforeEachHooks, this, promise);
});

afterEach(function() {
return teardownContext(this).then(() => {
// delete any extraneous properties
for (let key in this) {
if (!(key in originalContext)) {
delete this[key];
let promise = chainHooks(afterEachHooks.reverse(), this);

return promise
.then(() => teardownContext(this))
.then(() => {
// delete any extraneous properties
for (let key in this) {
if (!(key in originalContext)) {
delete this[key];
}
}
}

// copy over the original values
_assign(this, originalContext);
});
// copy over the original values
_assign(this, originalContext);
});
});

/**
* Provide a workaround for the inconvenient FIFO-always order of beforeEach/afterEach calls
*
* ```js
* let hooks = setupTest();
* hooks.beforeEach(function() { ... });
* hooks.afterEach(function() { ... });
* ```
*
* beforeEach hooks are called after setupUnitTest#beforeEach in FIFO (first in first out) order
* afterEach hooks are called before setupUnitTest#afterEach in LIFO (last in first out) order
*
* @type {{beforeEach: (function(*)), afterEach: (function(*))}}
*/
let hooks = {
beforeEach(fn) {
beforeEachHooks.push(fn);
},
afterEach(fn) {
afterEachHooks.push(fn);
}
};

return hooks;
}
17 changes: 7 additions & 10 deletions addon-test-support/ember-mocha/setup-rendering-test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import {
beforeEach,
afterEach
} from 'mocha';
import {
setupRenderingContext,
teardownRenderingContext
} from '@ember/test-helpers';
import setupContainerTest from './setup-container-test';

export default function setupRenderingTest(options) {
afterEach(function() {
return teardownRenderingContext(this);
});

setupContainerTest(options);
let hooks = setupContainerTest(options);

beforeEach(function() {
hooks.beforeEach(function() {
return setupRenderingContext(this);
});
hooks.afterEach(function() {
return teardownRenderingContext(this);
});

return hooks;
}
26 changes: 20 additions & 6 deletions tests/acceptance/setup-application-test-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,27 @@ describe('setupApplicationTest', function() {

this.timeout(5000);

setupApplicationTest();
describe('acceptance test', function() {

it('can visit subroutes', async function() {
await visit('/');
expect(this.element.querySelector('h2').textContent.trim()).to.be.empty;
setupApplicationTest();

await visit('/foo');
expect(this.element.querySelector('h2').textContent.trim()).to.be.equal('this is an acceptance test');
it('can visit subroutes', async function() {
await visit('/');
expect(this.element.querySelector('h2').textContent.trim()).to.be.empty;

await visit('/foo');
expect(this.element.querySelector('h2').textContent.trim()).to.be.equal('this is an acceptance test');
});
});

describe('hooks API', function() {

let hooks = setupApplicationTest();

it('returns hooks API', function() {
expect(hooks)
.to.respondTo('beforeEach')
.and.to.respondTo('afterEach');
})
});
});
67 changes: 67 additions & 0 deletions tests/unit/setup-container-test-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { expect } from 'chai';
import { pauseTest, resumeTest } from '@ember/test-helpers';
import Service from '@ember/service';
import hasEmberVersion from 'ember-test-helpers/has-ember-version';
import { Promise } from 'rsvp';

describe('setupContainerTest', function() {
if (!hasEmberVersion(2, 4)) {
Expand Down Expand Up @@ -78,4 +79,70 @@ describe('setupContainerTest', function() {
this.set('name', 'blue');
});
});

describe('hooks API', function() {

describe('calls hooks in order', function() {
function setupFoo(hooks) {
hooks.beforeEach(function() {
expect(this.owner, 'Context is set up already').to.exist;
this.count = 0;
});
hooks.afterEach(function() {
expect(this.count, 'afterEach is called in LIFO order').to.equal(3);
});
}

let hooks = setupContainerTest();
setupFoo(hooks);

hooks.beforeEach(function() {
expect(this.count, 'beforeEach is called in FIFO order').to.equal(0);
this.count++;
});
hooks.afterEach(function() {
expect(this.count, 'afterEach is called in LIFO order').to.equal(2);
this.count++;
});

it('calls beforeEach/afterEach in FIFO/LIFO order', function() {
expect(this.count, 'afterEach is called in LIFO order').to.equal(1);
this.count++;
});
});

describe('is Promise aware', function() {

function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

let hooks = setupContainerTest();

hooks.beforeEach(function() {
return delay(10)
.then(() => this.count = 0);
});
hooks.beforeEach(function() {
expect(this.count, 'beforeEach waits for promise').to.equal(0);
return delay(10)
.then(() => this.count++);
});
hooks.afterEach(function() {
expect(this.count, 'afterEach waits for promise').to.equal(3);
});
hooks.afterEach(function() {
expect(this.count).to.equal(2);
return delay(10)
.then(() => this.count++);
});

it('beforeEach/afterEach chain up promises', function() {
expect(this.count, 'it() is called after beforeEach promises resolved').to.equal(1);
this.count++;
});
});

});

});
10 changes: 10 additions & 0 deletions tests/unit/setup-rendering-test-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,14 @@ describe('setupRenderingTest', function() {
});
});

describe('hooks API', function() {

let hooks = setupRenderingTest();

it('returns hooks API', function() {
expect(hooks)
.to.respondTo('beforeEach')
.and.to.respondTo('afterEach');
});
});
});

0 comments on commit ca5178c

Please sign in to comment.