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..a3890d0e 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -1,42 +1,110 @@ -import * as chai 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; + + chai.assert.testing = 'successful'; + + Object.defineProperty(chai.Assertion.prototype, 'testing', { + get: function () { + return 'successful'; + }, + }); +} + +/** + * A chai plugin that adds the `moreTesting` property on chai assertions. + * + * @param {unknown} 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'; + }, + }); +} + +/** + * 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) { + return _super.call(this); + } + return someOtherThing(); + }); +} 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); + }).to.not.throw; + }); - function plugin (chai) { - if (chai.Assertion.prototype.testing) return; + describe('should', () => { + before(() => { + Should(); + }); + + it('basic usage', function () { + expect((42).should.testing).to.equal('successful'); + }); - Object.defineProperty(chai.Assertion.prototype, 'testing', { - get: function () { - return 'successful'; - } + it('multiple plugins apply all changes', function () { + expect((42).should.testing).to.equal('successful'); + expect((42).should.moreTesting).to.equal('more success'); }); - } - it('basic usage', function () { - chai.use(plugin); - var expect = chai.expect; - expect(expect('').testing).to.equal('successful'); + it('.use detached from chai object', function () { + expect((42).should.moreTesting).to.equal('more success'); + }); }); - it('double plugin', function () { - chai.expect(function () { - chai.use(plugin); - }).to.not.throw(); + describe('expect', () => { + it('basic usage', function () { + expect(expect('').testing).to.equal('successful'); + }); + + it('multiple plugins apply all changes', function () { + expect(expect('').testing).to.equal('successful'); + expect(expect('').moreTesting).to.equal('more success'); + }); + + it('.use detached from chai object', function () { + expect(expect('').moreTesting).to.equal('more success'); + }); }); - it('.use detached from chai object', function () { - function anotherPlugin (chai) { - Object.defineProperty(chai.Assertion.prototype, 'moreTesting', { - get: function () { - return 'more success'; - } - }); - } + describe('assert', () => { + it('basic usage', function () { + expect(assert.testing).to.equal('successful'); + }); - var use = chai.use; - use(anotherPlugin); + it('multiple plugins apply all changes', function () { + expect(assert.testing).to.equal('successful'); + expect(assert.moreTesting).to.equal('more success'); + }); - var expect = chai.expect; - expect(expect('').moreTesting).to.equal('more success'); + it('.use detached from chai object', function () { + expect(assert.moreTesting).to.equal('more success'); + }); }); });