From a77feedb39944d335180e3ee87d64f7135ba8286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Tue, 14 May 2024 10:38:00 +0200 Subject: [PATCH 1/6] enable chaining of chai plugins --- lib/chai.js | 12 ++++-------- test/plugins.js | 52 ++++++++++++++++++++++++------------------------- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/lib/chai.js b/lib/chai.js index 507d9c76..6635c6c8 100644 --- a/lib/chai.js +++ b/lib/chai.js @@ -13,8 +13,6 @@ import {Assertion} from './chai/assertion.js'; import * as should from './chai/interface/should.js'; import {assert} from './chai/interface/assert.js'; -const used = []; - // Assertion Error export {AssertionError}; @@ -35,16 +33,14 @@ export function use(fn) { expect, assert, Assertion, - ...should + use, + ...should, }; - if (!~used.indexOf(fn)) { - fn(exports, util); - used.push(fn); - } + fn(exports, util); return exports; -}; +} // Utility Functions export {util}; diff --git a/test/plugins.js b/test/plugins.js index 4db1f44d..4dc1ee6a 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -1,42 +1,40 @@ -import * as chai from '../index.js'; +import {use, expect} from '../index.js'; -describe('plugins', function () { +function plugin(chai) { + if (chai.Assertion.prototype.testing) return; + + Object.defineProperty(chai.Assertion.prototype, 'testing', { + get: function () { + return 'successful'; + }, + }); +} - function plugin (chai) { - if (chai.Assertion.prototype.testing) return; +function anotherPlugin(chai) { + if (chai.Assertion.prototype.moreTesting) return; - Object.defineProperty(chai.Assertion.prototype, 'testing', { - get: function () { - return 'successful'; - } - }); - } + Object.defineProperty(chai.Assertion.prototype, 'moreTesting', { + get: function () { + return 'more success'; + }, + }); +} +describe('plugins', function () { it('basic usage', function () { - chai.use(plugin); - var expect = chai.expect; + const {expect} = use(plugin); expect(expect('').testing).to.equal('successful'); }); - it('double plugin', function () { - chai.expect(function () { - chai.use(plugin); + it('multiple plugins', function () { + expect(function () { + use(plugin).use(anotherPlugin); }).to.not.throw(); }); it('.use detached from chai object', function () { - function anotherPlugin (chai) { - Object.defineProperty(chai.Assertion.prototype, 'moreTesting', { - get: function () { - return 'more success'; - } - }); - } - - var use = chai.use; - use(anotherPlugin); - - var expect = chai.expect; + const {expect} = use(anotherPlugin); + expect(expect('').moreTesting).to.equal('more success'); }); }); From 44af64df89c1eaa26b9eea2ba2e8647cd9b766a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Tue, 14 May 2024 16:03:18 +0200 Subject: [PATCH 2/6] Add broken plugin test --- test/plugins.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/plugins.js b/test/plugins.js index 4dc1ee6a..be97331f 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -20,6 +20,15 @@ function anotherPlugin(chai) { }); } +function brokenPlugin(chai) { + chai.overwriteProperty('equal', function (_super) { + if (something) { + return _super.call(this); + } + return someOtherThing(); + }); +} + describe('plugins', function () { it('basic usage', function () { const {expect} = use(plugin); @@ -30,6 +39,11 @@ describe('plugins', function () { expect(function () { use(plugin).use(anotherPlugin); }).to.not.throw(); + + it("doesn't crash when there's a bad plugin", function () { + expect(() => { + use(brokenPlugin).use(brokenPlugin).use(brokenPlugin); + }).to.not.throw; }); it('.use detached from chai object', function () { From 0b0e60054a689d9087373cfe46d347595ed6351a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Tue, 14 May 2024 16:03:43 +0200 Subject: [PATCH 3/6] make multiple plugin test more concrete --- test/plugins.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/plugins.js b/test/plugins.js index be97331f..94a0c2da 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -35,10 +35,12 @@ describe('plugins', function () { expect(expect('').testing).to.equal('successful'); }); - it('multiple plugins', function () { - expect(function () { - use(plugin).use(anotherPlugin); - }).to.not.throw(); + it('multiple plugins apply all changes', function () { + const chai = use(plugin).use(anotherPlugin); + + expect(chai.expect('').testing).to.equal('successful'); + expect(chai.expect('').moreTesting).to.equal('more success'); + }); it("doesn't crash when there's a bad plugin", function () { expect(() => { From 7a417beb1143250ea0a2299fbb4aaf73876fa491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Thu, 16 May 2024 14:41:46 +0200 Subject: [PATCH 4/6] add should plugin tests --- test/plugins.js | 58 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/test/plugins.js b/test/plugins.js index 94a0c2da..483dd53f 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -1,4 +1,4 @@ -import {use, expect} from '../index.js'; +import {use, expect, Should} from '../index.js'; function plugin(chai) { if (chai.Assertion.prototype.testing) return; @@ -30,27 +30,53 @@ function brokenPlugin(chai) { } describe('plugins', function () { - it('basic usage', function () { - const {expect} = use(plugin); - expect(expect('').testing).to.equal('successful'); - }); - - it('multiple plugins apply all changes', function () { - const chai = use(plugin).use(anotherPlugin); - - expect(chai.expect('').testing).to.equal('successful'); - expect(chai.expect('').moreTesting).to.equal('more success'); - }); - it("doesn't crash when there's a bad plugin", function () { expect(() => { use(brokenPlugin).use(brokenPlugin).use(brokenPlugin); }).to.not.throw; }); - it('.use detached from chai object', function () { - const {expect} = use(anotherPlugin); + describe('should', () => { + before(() => { + Should(); + }); + + it('basic usage', function () { + use(plugin); + expect((42).should.testing).to.equal('successful'); + }); + + it('multiple plugins apply all changes', function () { + use(plugin).use(anotherPlugin); + + expect((42).should.testing).to.equal('successful'); + expect((42).should.moreTesting).to.equal('more success'); + }); + + it('.use detached from chai object', function () { + use(anotherPlugin); + + expect((42).should.moreTesting).to.equal('more success'); + }); + }); + + describe('expect', () => { + it('basic usage', function () { + const {expect} = use(plugin); + expect(expect('').testing).to.equal('successful'); + }); + + it('multiple plugins apply all changes', function () { + const chai = use(plugin).use(anotherPlugin); + + expect(chai.expect('').testing).to.equal('successful'); + expect(chai.expect('').moreTesting).to.equal('more success'); + }); + + it('.use detached from chai object', function () { + const {expect} = use(anotherPlugin); - expect(expect('').moreTesting).to.equal('more success'); + expect(expect('').moreTesting).to.equal('more success'); + }); }); }); From d8815c862e8abd3cbe330f4c523284f9f433e0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Thu, 16 May 2024 16:09:17 +0200 Subject: [PATCH 5/6] add assert tests --- test/plugins.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/plugins.js b/test/plugins.js index 483dd53f..43230415 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -3,6 +3,8 @@ import {use, expect, Should} from '../index.js'; function plugin(chai) { if (chai.Assertion.prototype.testing) return; + chai.assert.testing = 'successful'; + Object.defineProperty(chai.Assertion.prototype, 'testing', { get: function () { return 'successful'; @@ -13,6 +15,8 @@ function plugin(chai) { function anotherPlugin(chai) { if (chai.Assertion.prototype.moreTesting) return; + chai.assert.moreTesting = 'more success'; + Object.defineProperty(chai.Assertion.prototype, 'moreTesting', { get: function () { return 'more success'; @@ -79,4 +83,24 @@ describe('plugins', function () { expect(expect('').moreTesting).to.equal('more success'); }); }); + + describe('assert', () => { + it('basic usage', function () { + const {assert} = use(plugin); + expect(assert.testing).to.equal('successful'); + }); + + it('multiple plugins apply all changes', function () { + const chai = use(plugin).use(anotherPlugin); + + expect(chai.assert.testing).to.equal('successful'); + expect(chai.assert.moreTesting).to.equal('more success'); + }); + + it('.use detached from chai object', function () { + const {assert} = use(anotherPlugin); + + expect(assert.moreTesting).to.equal('more success'); + }); + }); }); From 2e9e2202b2d73e212eee0886a9df481cb328066a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Sun, 19 May 2024 11:10:00 +0000 Subject: [PATCH 6/6] just apply plugins globally in tests --- test/plugins.js | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/test/plugins.js b/test/plugins.js index 43230415..a3890d0e 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -1,5 +1,10 @@ -import {use, expect, Should} from '../index.js'; +import {use, assert, expect, Should} from '../index.js'; +/** + * A chai plugin that adds the `testing` property on chai assertions. + * + * @param {unknown} chai + */ function plugin(chai) { if (chai.Assertion.prototype.testing) return; @@ -12,6 +17,11 @@ function plugin(chai) { }); } +/** + * A chai plugin that adds the `moreTesting` property on chai assertions. + * + * @param {unknown} chai + */ function anotherPlugin(chai) { if (chai.Assertion.prototype.moreTesting) return; @@ -24,6 +34,11 @@ function anotherPlugin(chai) { }); } +/** + * A exmple of a "bad" plugin for chai that overwrites the `equal` property. + * + * @param {unknown} chai + */ function brokenPlugin(chai) { chai.overwriteProperty('equal', function (_super) { if (something) { @@ -34,6 +49,10 @@ function brokenPlugin(chai) { } describe('plugins', function () { + // Plugins are not applied "immutably" on chai so we want to just apply them + // here globally and then run all the tests. + use(plugin).use(anotherPlugin); + it("doesn't crash when there's a bad plugin", function () { expect(() => { use(brokenPlugin).use(brokenPlugin).use(brokenPlugin); @@ -46,60 +65,45 @@ describe('plugins', function () { }); it('basic usage', function () { - use(plugin); expect((42).should.testing).to.equal('successful'); }); it('multiple plugins apply all changes', function () { - use(plugin).use(anotherPlugin); - expect((42).should.testing).to.equal('successful'); expect((42).should.moreTesting).to.equal('more success'); }); it('.use detached from chai object', function () { - use(anotherPlugin); - expect((42).should.moreTesting).to.equal('more success'); }); }); describe('expect', () => { it('basic usage', function () { - const {expect} = use(plugin); expect(expect('').testing).to.equal('successful'); }); it('multiple plugins apply all changes', function () { - const chai = use(plugin).use(anotherPlugin); - - expect(chai.expect('').testing).to.equal('successful'); - expect(chai.expect('').moreTesting).to.equal('more success'); + expect(expect('').testing).to.equal('successful'); + expect(expect('').moreTesting).to.equal('more success'); }); it('.use detached from chai object', function () { - const {expect} = use(anotherPlugin); - expect(expect('').moreTesting).to.equal('more success'); }); }); describe('assert', () => { it('basic usage', function () { - const {assert} = use(plugin); expect(assert.testing).to.equal('successful'); }); it('multiple plugins apply all changes', function () { - const chai = use(plugin).use(anotherPlugin); - - expect(chai.assert.testing).to.equal('successful'); - expect(chai.assert.moreTesting).to.equal('more success'); + expect(assert.testing).to.equal('successful'); + expect(assert.moreTesting).to.equal('more success'); }); it('.use detached from chai object', function () { - const {assert} = use(anotherPlugin); - expect(assert.moreTesting).to.equal('more success'); }); });