Skip to content

Before/after hooks #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,5 @@ setImmediate(function () {

module.exports = runner.addTest.bind(runner);
module.exports.serial = runner.addSerialTest.bind(runner);
module.exports.before = runner.addBeforeHook.bind(runner);
module.exports.after = runner.addAfterHook.bind(runner);
52 changes: 31 additions & 21 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ function Runner(opts) {
this.tests = {};
this.tests.concurrent = [];
this.tests.serial = [];
this.tests.before = [];
this.tests.after = [];
}

util.inherits(Runner, EventEmitter);
Expand All @@ -34,8 +36,16 @@ Runner.prototype.addSerialTest = function (title, cb) {
this.tests.serial.push(new Test(title, cb));
};

Runner.prototype.concurrent = function (cb) {
each(this.tests.concurrent, function (test, i, next) {
Runner.prototype.addBeforeHook = function (title, cb) {
this.tests.before.push(new Test(title, cb));
};

Runner.prototype.addAfterHook = function (title, cb) {
this.tests.after.push(new Test(title, cb));
};

Runner.prototype.concurrent = function (tests, cb) {
each(tests, function (test, i, next) {
test.run(function (err, duration) {
if (err) {
this.stats.failCount++;
Expand All @@ -53,8 +63,8 @@ Runner.prototype.concurrent = function (cb) {
}.bind(this), cb);
};

Runner.prototype.serial = function (cb) {
eachSerial(this.tests.serial, function (test, next) {
Runner.prototype.serial = function (tests, cb) {
eachSerial(tests, function (test, next) {
test.run(function (err, duration) {
if (err) {
this.stats.failCount++;
Expand All @@ -75,23 +85,23 @@ Runner.prototype.serial = function (cb) {
Runner.prototype.run = function (cb) {
var concurrent = this.tests.concurrent;
var serial = this.tests.serial;

if (serial.length > 0 && concurrent.length === 0) {
this.serial(this.end.bind(this, cb));
return;
}

if (serial.length === 0 && concurrent.length > 0) {
this.concurrent(this.end.bind(this, cb));
return;
}

if (serial.length > 0 && concurrent.length > 0) {
this.serial(this.concurrent.bind(this, this.end.bind(this, cb)));
return;
}

this.end(cb);
var before = this.tests.before;
var after = this.tests.after;

// TODO: refactor this bullshit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

;) Might want to do that haha.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relevant: #38

// @vdemedes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I thought about converting this.serial and this.concurrent to return promises, but decided postpone that. Wanted to hear feedback on a PR and thought that you might not like too much changes at once, haha

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, promisification should be a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could do that after this PR gets merged (to avoid merge conflicts in commit history), no probs

this.serial(before, function () {
if (this.stats.failCount > 0) {
return this.end(cb);
}

this.serial(serial, function () {
this.concurrent(concurrent, function () {
this.serial(after, function () {
this.end(cb);
}.bind(this));
}.bind(this));
}.bind(this));
}.bind(this));
};

Runner.prototype.end = function (cb) {
Expand Down
28 changes: 28 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,34 @@ test.serial(function (t) {
```


### Before/after hooks

When setup and/or teardown is required, you can use `test.before()` and `test.after()`,
used in the same manner as `test()`.
The test function given to `test.before()` and `test.after()` is called before/after all tests.

```js
// shortcuts for convenience
var before = test.before;
var after = test.after;

before(function (t) {
// this test runs before all others
t.end();
});

after(function (t) {
// this test runs after all others
t.end();
});

test(function (t) {
// regular test
t.end();
});
```


### Custom assertion module

You can use any assertion module instead or in addition to the one that comes with AVA, but you won't be able to use the `.plan()` method, [yet](https://github.com/sindresorhus/ava/issues/25).
Expand Down
76 changes: 76 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,82 @@ test('record test duration', function (t) {
});
});

test('hooks - before', function (t) {
t.plan(1);

var runner = new Runner();
var arr = [];

runner.addBeforeHook(function (a) {
arr.push('a');

a.end();
});

runner.addTest(function (a) {
arr.push('b');

a.end();
});

runner.run(function () {
t.same(arr, ['a', 'b']);
t.end();
});
});

test('hooks - after', function (t) {
t.plan(1);

var runner = new Runner();
var arr = [];

runner.addAfterHook(function (a) {
arr.push('b');

a.end();
});

runner.addTest(function (a) {
arr.push('a');

a.end();
});

runner.run(function () {
t.same(arr, ['a', 'b']);
t.end();
});
});

test('hooks - stop if before hooks failed', function (t) {
t.plan(1);

var runner = new Runner();
var arr = [];

runner.addBeforeHook(function (a) {
arr.push('a');

a.end();
});

runner.addBeforeHook(function () {
throw new Error('something went wrong');
});

runner.addTest(function (a) {
arr.push('b');

a.end();
});

runner.run(function () {
t.same(arr, ['a']);
t.end();
});
});

test('ES2015 support', function (t) {
t.plan(2);

Expand Down