diff --git a/lib/createTopLevelExpect.js b/lib/createTopLevelExpect.js index bd00b346f..d2d616d9c 100644 --- a/lib/createTopLevelExpect.js +++ b/lib/createTopLevelExpect.js @@ -1584,18 +1584,20 @@ expectPrototype.clone = function () { expectPrototype.child = function () { this._assertTopLevelExpect(); - const childExpect = createTopLevelExpect({ - assertions: {}, - types: [], - typeByName: {}, - output: this.output.clone(), - format: this.outputFormat(), - installedPlugins: [], - }); - const parent = (childExpect.parent = this); + const childExpect = createTopLevelExpect( + { + assertions: {}, + types: [], + typeByName: {}, + output: this.output.clone(), + format: this.outputFormat(), + installedPlugins: [], + }, + this + ); childExpect.exportAssertion = function (testDescription, handler) { - parent.addAssertion(testDescription, handler, childExpect); + childExpect.parent.addAssertion(testDescription, handler, childExpect); return this; }; childExpect.exportType = function (type) { @@ -1603,11 +1605,11 @@ expectPrototype.child = function () { childExpect.addType(type); } - parent.addType(type, childExpect); + childExpect.parent.addType(type, childExpect); return this; }; childExpect.exportStyle = function (name, handler, allowRedefinition) { - parent.addStyle( + childExpect.parent.addStyle( name, function (...args) { const childOutput = childExpect.createOutput(this.format); @@ -1907,18 +1909,26 @@ Object.defineProperty(expectPrototype, 'argTypes', { }, }); -function createTopLevelExpect({ - assertions = {}, - typeByName = { any: anyType }, - types = [anyType], - output, - format = magicpen.defaultFormat, - installedPlugins = [], -} = {}) { +function createTopLevelExpect( + { + assertions = {}, + typeByName = { any: anyType }, + types = [anyType], + output, + format = magicpen.defaultFormat, + installedPlugins = [], + } = {}, + parentExpect +) { const expect = function (...args) { return expect._expect(new Context(), args); }; - utils.setPrototypeOfOrExtend(expect, expectPrototype); + if (parentExpect) { + expect.parent = parentExpect; + utils.setPrototypeOfOrExtend(expect, parentExpect); + } else { + utils.setPrototypeOfOrExtend(expect, expectPrototype); + } if (!output) { output = magicpen(); @@ -1928,6 +1938,7 @@ function createTopLevelExpect({ return extend(expect, { _topLevelExpect: expect, _outputFormat: format, + _frozen: false, assertions, typeByName, installedPlugins, diff --git a/test/api/hook.js b/test/api/hook.js index de5cbb69a..0ddfc6a20 100644 --- a/test/api/hook.js +++ b/test/api/hook.js @@ -46,7 +46,7 @@ describe('hook', () => { }); describe('with expect.child', () => { - it('should not affect child instances made before installing the hook', () => { + it('should affect child instances made before installing the hook', () => { const parentExpect = expect.clone(); const childExpect = parentExpect.child(); @@ -59,7 +59,7 @@ describe('hook', () => { }); childExpect(123, 'to equal', 123); - expect(called, 'to be false'); + expect(called, 'to be true'); }); it('should not affect child instances made after installing the hook', () => { @@ -128,7 +128,8 @@ describe('hook', () => { // Regression test for https://gitter.im/unexpectedjs/unexpected?at=5fb42b73747be107c1c76095 it('should not break `this` in clones created after installing the hook', function () { - expect.hook(function (next) { + const parentExpect = expect.clone(); + parentExpect.hook(function (next) { return function (context, ...rest) { return next(context, ...rest); };