From bfec756e58fe3bf0f09798687d9c389c8e5cdd30 Mon Sep 17 00:00:00 2001 From: Adam Gruber Date: Sat, 15 Jun 2019 09:09:53 -0400 Subject: [PATCH] fix: using `addContext` inside a `before` or `after` hook should add context to the hook This worked as expected in versions of mocha prior to `6.0.0` but due to a change the assumptions made inside `addContext` no longer held true. --- CHANGELOG.md | 2 + src/addContext.js | 15 +++++-- test/addContext.test.js | 91 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 100 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f602ec4..cf9f34b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # mochawesome changelog ## [Unreleased] +### Fixed +- Issue where using `addContext` inside a `before` or `after` hook would incorrectly apply context to the test [#284](https://github.com/adamgruber/mochawesome/issues/284) ## [4.0.0] - 2019-06-04 ### Changed diff --git a/src/addContext.js b/src/addContext.js index 901daf9..b9ea746 100644 --- a/src/addContext.js +++ b/src/addContext.js @@ -83,10 +83,19 @@ const addContext = function (...args) { } /* Context is valid, now get the test object - * If `addContext` is called from inside a `beforeEach` or `afterEach` - * the test object will be `.currentTest`, otherwise just `.test` + * If `addContext` is called from inside a hook the test object + * will be `.currentTest`, and the hook will be `.test`. + * Otherwise the test is just `.test` and `.currentTest` is undefined. */ - const test = args[0].currentTest || args[0].test; + const currentTest = args[0].currentTest; + const activeTest = args[0].test; + + /* For `before` and `after`, add the context to the hook, + * otherwise add it to the actual test. + */ + const isEachHook = currentTest + && /^"(?:before|after)\seach"/.test(activeTest.title); + const test = isEachHook ? currentTest : activeTest; if (!test) { log(ERRORS.INVALID_TEST, 'error'); diff --git a/test/addContext.test.js b/test/addContext.test.js index ab7a9a0..bf2f469 100644 --- a/test/addContext.test.js +++ b/test/addContext.test.js @@ -2,12 +2,40 @@ const addContext = require('../src/addContext'); describe('addContext', () => { let testObj; + let activeTest; let test; let origConsoleError; + const makeHook = type => ({ + title: `"${type}" hook`, + body: 'function () {\n addContext(this, "i\'m in a before hook");\n }', + async: 0, + sync: true, + timedOut: false, + pending: false, + type: 'hook', + parent: '#', + ctx: '#', + file: '/test.js', + uuid: '9f4e292c-8668-4008-9dc4-589909f94054' + }); + beforeEach(() => { origConsoleError = console.error; console.error = function () {}; + + activeTest = { + title: 'sample test', + body: 'function () {\n addContext(this, "i\'m in a test");\n assert(true);\n }', + async: 0, + sync: true, + timedOut: false, + pending: false, + type: 'test', + file: '/test.js', + parent: '#', + ctx: '#' + }; }); afterEach(() => { @@ -17,7 +45,10 @@ describe('addContext', () => { function contextTests() { it('as a string', () => { addContext(testObj, 'test context'); - test.should.eql({ context: 'test context' }); + test.should.eql({ + ...test, + context: 'test context' + }); }); it('as an object', () => { @@ -26,6 +57,7 @@ describe('addContext', () => { value: true }); test.should.eql({ + ...test, context: { title: 'context title', value: true @@ -39,6 +71,7 @@ describe('addContext', () => { value: undefined }); test.should.eql({ + ...test, context: { title: 'context title', value: 'undefined' @@ -51,14 +84,33 @@ describe('addContext', () => { addContext(testObj, 'test context 2'); addContext(testObj, { title: 'test context 3', value: true }); test.should.eql({ - context: [ 'test context 1', 'test context 2', { title: 'test context 3', value: true } ] + ...test, + context: [ + 'test context 1', + 'test context 2', + { title: 'test context 3', value: true } + ] }); }); } describe('when run inside a test', () => { beforeEach(() => { - testObj = { test: {} }; + testObj = { + currentTest: undefined, + test: activeTest + }; + test = testObj.test; + }); + contextTests(); + }); + + describe('when run inside a before', () => { + beforeEach(() => { + testObj = { + currentTest: activeTest, + test: makeHook('before all') + }; test = testObj.test; }); contextTests(); @@ -66,7 +118,32 @@ describe('addContext', () => { describe('when run inside a beforeEach', () => { beforeEach(() => { - testObj = { currentTest: {} }; + testObj = { + currentTest: activeTest, + test: makeHook('before each') + }; + test = testObj.currentTest; + }); + contextTests(); + }); + + describe('when run inside an after', () => { + beforeEach(() => { + testObj = { + currentTest: activeTest, + test: makeHook('after all') + }; + test = testObj.test; + }); + contextTests(); + }); + + describe('when run inside an afterEach', () => { + beforeEach(() => { + testObj = { + currentTest: activeTest, + test: makeHook('after each') + }; test = testObj.currentTest; }); contextTests(); @@ -74,7 +151,11 @@ describe('addContext', () => { describe('No context is added when', () => { beforeEach(() => { - testObj = { test: {} }; + testObj = { + test: { + title: 'sample test' + } + }; test = testObj.test; });