diff --git a/lib/runner.js b/lib/runner.js index 6161ccc00..526fbde16 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -89,20 +89,26 @@ Runner.prototype._runTestWithHooks = function (test) { tests.push(test); tests.push.apply(tests, afterHooks); - var context = {}; + // wrapper to allow context to be a primitive value + var contextWrapper = { + context: {} + }; return eachSeries(tests, function (test) { - return this._runTest(test, context); + Object.defineProperty(test, 'context', { + get: function () { + return contextWrapper.context; + }, + set: function (val) { + contextWrapper.context = val; + } + }); + + return this._runTest(test); }.bind(this)).catch(noop); }; -Runner.prototype._runTest = function (test, context) { - // shared context (only applies to tests with hooks around them) - // set only if `context` is an object (can be index number) - if (typeof context === 'object') { - test.context = context; - } - +Runner.prototype._runTest = function (test) { // add test result regardless of state // but on error, don't execute next tests return test.run() diff --git a/lib/test.js b/lib/test.js index a8c9dda40..49e618023 100644 --- a/lib/test.js +++ b/lib/test.js @@ -106,7 +106,7 @@ Test.prototype.run = function () { this._timeout = setTimeout(function () {}, TIMEOUT_MAX_VALUE); try { - var ret = this.fn.call(this.context, this); + var ret = this.fn(this); if (ret && typeof ret.then === 'function') { ret diff --git a/readme.md b/readme.md index 912ce6fe4..9d33649d3 100644 --- a/readme.md +++ b/readme.md @@ -237,6 +237,20 @@ test(t => { }); ``` +The context is by default an object, but it can also be directly assigned: + +```js +test.beforeEach(t => { + t.context = 'unicorn'; + t.end(); +}); + +test(t => { + t.is(t.context, 'unicorn'); + 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). diff --git a/test/test.js b/test/test.js index 156069fa9..fd52b4ccc 100644 --- a/test/test.js +++ b/test/test.js @@ -748,30 +748,51 @@ test('hooks - shared context', function (t) { var runner = new Runner(); runner.addBeforeHook(function (a) { - a.is(this.arr, undefined); - this.arr = []; + a.is(a.context.arr, undefined); + a.context.arr = []; a.end(); }); runner.addAfterHook(function (a) { - a.is(this.arr, undefined); + a.is(a.context.arr, undefined); a.end(); }); runner.addBeforeEachHook(function (a) { - this.arr = ['a']; + a.context.arr = ['a']; a.end(); }); runner.addTest(function (a) { - this.arr.push('b'); - a.same(this.arr, ['a', 'b']); + a.context.arr.push('b'); + a.same(a.context.arr, ['a', 'b']); a.end(); }); runner.addAfterEachHook(function (a) { - this.arr.push('c'); - a.same(this.arr, ['a', 'b', 'c']); + a.context.arr.push('c'); + a.same(a.context.arr, ['a', 'b', 'c']); + a.end(); + }); + + runner.run().then(function () { + t.is(runner.stats.failCount, 0); + t.end(); + }); +}); + +test('hooks - shared context of any type', function (t) { + t.plan(1); + + var runner = new Runner(); + + runner.addBeforeEachHook(function (a) { + a.context = 'foo'; + a.end(); + }); + + runner.addTest(function (a) { + a.is(a.context, 'foo'); a.end(); });