Skip to content

Update dependency chai to v4 (dev) - autoclosed

renovateBOT requested to merge renovate/dev-chai-4.x into dev

This Merge Request updates dependency chai from v3.5.0 to v4.1.2

Release Notes

v4.0.0

4.0.0

4.0 has been a huge undertaking by the chai community! A lot has changed to ensure Chai 4 is a stable, reliable, well documented codebase. Here are just some of the major improvements:

  • almost all documentation has been rewritten, with detailed instructions on how assertions work, which flags they can be combined with and the best practices for how to use them.

  • deep equality has been rewritten from the ground up to support ES6 types like Map and Set, and better support existing types. It is now also much, much faster than before and allows us to bring some great improvements in upcoming releases.

  • we have made sure the deep flag now only ever does deep equality. Beforehand, it would sometimes also be used to test nested properties (for example expect(foo).to.have.deep.property('bar.baz'). For nested assertions, please now use the .nested flag.

  • many assertions have become more strict, which means you get better error messages explaining where things have gone wrong. For the most part, this wont mean error messages where there weren't error messages before, but it will mean better error messages to replace the, sometimes cryptic, default TypeError messages.

  • we've added detections and helpful error messages for common mistakes and typos. The error messages will, in some cases, point you to documentation or in other cases suggest alternatives. These messages will continue to be improved in future releases, so let us know if you have any suggestions!

Breaking Changes

  • We no longer support Node v0.10 and v0.12 (since their LTS has ended) (MRs: #816, #901)

  • Instead of allowing the user to write the path of a property, now the deep flag performs a deep equality comparison when used with the .property assertion.
    If you want the old behavior of using the dot or bracket notation to denote the property you want to assert against you can use the new .nested flag. (Related Issues: #745, #743, MRs: #758, #757)

    ``` js
    const obj = {a: 1};

    // The .deep flag now does deep equality comparisons
    expect({foo: obj}).to.have.deep.property('foo', {a: 1});

    // Use the nested flag if you want to assert against a nested property using the bracket or dot notation
    expect({foo: obj}).to.have.nested.property('foo.a', 1);

    // You can also use both flags combined
    const obj2 = {a: {b: 2}};
    expect({foo: obj2}).to.have.deep.nested.property('foo.a', {b: 2});
    ```

    Please notice that the old methods which used the old behavior of the deep flag on the assert interface have been renamed. They all have had the deep word changed by the nested word. If you want to know more about this please take a look at #757.

  • Previously, expect(obj).not.property(name, val) would throw an Error if obj didn't have a property named name. This change causes the assertion to pass instead.
    The assert.propertyNotVal and assert.deepPropertyNotVal assertions were renamed to assert.notPropertyVal and assert.notDeepPropertyVal, respectively. (Related Issues: #16, #743, #758)

  • You can now use the deep flag for the .include assertion in order to perform a deep equality check to see if something is included on the target.
    Previously, .include was using strict equality (===) for non-negated property inclusion, but deep equality for negated property inclusion and array inclusion.
    This change causes the .include assertion to always use strict equality unless the deep flag is set.
    Please take a look at this comment if you want to know more about it. (Related Issues: #743, MRs: #760, #761)

    js const obj = {a: 1}; expect([obj]).to.deep.include({a:1}); expect({foo: obj}).to.deep.include({foo: {a:1}});

  • Fix unstable behavior of the NaN assertion. Now we use the suggested ES6 implementation.
    The new implementation is now more correct, strict and simple. While the old one threw false positives, the new implementation only checks if something is NaN (or not if the .not flag is used) and nothing else. (Related Issues: #498, #682, #681, MRs: #508)

    `` js // OnlyNaNwill be considered to beNaN` and nothing else
    expect(NaN).to.be.NaN;

    // Anything that is not NaN cannot be considered as NaN
    expect('randomString').not.to.be.NaN;
    expect(true).not.to.be.NaN;
    expect({}).not.to.be.NaN;
    expect(4).not.to.be.NaN;
    ```

  • The Typed Array types are now truncated if they're too long (in this case, if they exceed the truncateThreshold value on the config). (Related Issues: #441, MRs: #576)

    ``` js
    var arr = [];
    for (var i = 1; i <= 1000; i++) {
    arr.push(i);
    }

    // The assertion below will truncate the diff shown and the enormous typed array will be shown as:
    // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, … ] instead of printing the whole typed array
    chai.expect(new Float32Array(100)).to.equal(1);
    ```

  • The assertions: within, above, least, below, most, increase, decrease will throw an error if the assertion's target or arguments are not numbers. (Related Issues: #691, MRs: #692, #796)

    ``` js
    // These will throw errors, for example:
    expect(null).to.be.within(0, 1);
    expect(null).to.be.above(10);
    expect(null).to.be.at.least(20);
    expect(null).to.be.below(20);
    expect(null).to.be.at.most(20);
    expect(null).to.increase.by(20);
    expect(null).to.decrease.by(20);

    // This will not:
    expect('string').to.have.a.lengthOf.at.least(3);
    ```

  • Previously, expect(obj).not.ownProperty(name, val) would throw an Error if obj didn't have an own property (non-inherited) named name. This change causes the assertion to pass instead. (Related Issues: #795, #, MRs: #744, #810)*

    js expect({ foo: 'baz' }).to.not.have.own.property('quux', 'baz');

  • The .empty assertion will now throw when it is passed non-string primitives and functions (MRs: #763, #812)

    js // These will throw TypeErrors: expect(Symbol()).to.be.empty; expect(function() {}).to.be.empty; expect(true).to.be.empty; expect(1).to.be.empty

  • Assertion subject (obj) changes when using ownProperty or own.property and thus enables chaining. (Related Issues: #281, MRs: #641)

    js expect({val: 20}).to.have.own.property('val').above(10);

  • The .change, .increase, and .decrease assertions changed from chainable method assertions to method assertions. They don't have any chaining behavior, and there's no generic semantic benefit to chaining them. (Related Issues: #917, MRs: #925)

// This will not work anymore because there is no benefit to chaining these assertions:
expect(function() {}).to.change.by(2)
expect(function() {}).to.increase.by(2)
expect(function() {}).to.decrease.by(2)
  • The utils (second argument passed to the chai.use callback function) no longer exports the getPathValue function. If you want to use that please use the pathval module, which is what chai uses internally now. (Related Issues: #457, #737, MRs: #830)

  • (For plugin authors) Throw when calling _superon overwriteMethodif the method being overwritten is undefined.
    Currently if the method you are trying to overwrite is not defined and your new method calls _super it will throw an Error.(Related Issues: #467, MRs: #528)
    Before this change, calling _super would simply return this.

    `` js // Considering the methodimaginaryMethod` does not exist, this would throw an error for example:
    chai.use(function (chai, utilities) {
    chai.Assertion.overwriteMethod('imaginaryMethod', function (_super) {
    return function () {
    _super.apply(this, arguments);
    }
    });
    });

    // This will throw an error since you are calling _super which should be a method (in this case, the overwritten assertion) that does not exist
    expect('anything').to.imaginaryMethod();
    ```

  • (For plugin authors) Now showDiff is turned on by default whenever the showDiff flag is anything other than false.
    This issue will mostly affect plugin creators or anyone that made extensions to the core, since this affects the Assertion.assert method. (Related Issues: #574, MRs: #515)

    `` js // Now whenever you callAssertion.assertwith anything that is not false for theshowDiffflag it will be true // The assertion error that was thrown will have theshowDiffflag turned on since it was not passed to theassert` method
    try {
    new chai.Assertion().assert(
    'one' === 'two'
    , 'expected #{this} to equal #{exp}'
    , 'expected #{this} to not equal #{act}'
    , 'one'
    , 'two'
    );
    } catch(e) {
    assert.isTrue(e.showDiff);
    }

    // The assertion error that was thrown will have the showDiff flag turned off since here we passed false explicitly
    try {
    new chai.Assertion().assert(
    'one' === 'two'
    , 'expected #{this} to equal #{exp}'
    , 'expected #{this} to not equal #{act}'
    , 'one'
    , 'two'
    , false
    );
    } catch(e) {
    assert.isFalse(e.showDiff);
    }
    ```

New Features

  • Throw when non-existent property is read. (Related Issues: #407, #766 MRs: #721, #770)
    This is a potentially breaking change. Your build will fail if you have typos in your property assertions
    Before 4.x.x when using property assertions they would not throw an error if you wrote it incorrectly.
    The example below, for example, would pass:

    ``` js
    expect(true).to.be.ture; // Oops, typo, now Chai will throw an Error

    Since this implementation depends on ES6 `Proxies` it will only work on platforms that support it.
    This property can be enabled (default) or disabled through the config.useProxy property, for example:

    js
    chai.config.useProxy = false; // disable use of Proxy
    ```

  • Add fix suggestions when accessing a nonexistent property in proxy mode. (Related Issues: #771, MRs: #782)
    When a nonexistent property is accessed in proxy mode, Chai will compute the levenshtein distance to all possible properties in order to suggest the best fix to the user.

    ``` js
    expect(false).to.be.fals; // Error: Invalid Chai property: fals. Did you mean "false"?
    expect('foo').to.be.undefind; // Error: Invalid Chai property: undefind. Did you mean "undefined"?

    // If the Levenshtein distance between the word and any Chai property is greater than 4, no fix will be suggested
    expect('foo').to.be.fdsakfdsafsagsadgagsdfasf // error thrown, no fix suggested
    ```

  • When non-chainable methods (including overwritten non-chainable methods) are used incorrectly an error will be thrown with a helpful error message. (MRs: #789)

    js expect(true).to.equal.true; // Invalid Chai property: equal.true. See docs for proper usage of "equal".

  • Add a new configuration setting that describes which keys will be ignored when checking for non-existing properties on an assertion before throwing an error.
    Since this implementation depends on ES6 Proxies it will only work on platforms that support it. Also, if you disable config.useProxy, this setting will have no effect. (Related Issues: #765, MRs: #774)

    ``` js
    chai.config.proxyExcludedKeys.push('nonExistingProp');

    expect('my string').to.nonExistingProp; // This won't throw an error now
    ```

  • Add script that registers should as a side-effect. (Related Issues: #594, #693 MRs: #604)

    ``` js
    // You can now write:
    import 'chai/should';

    // as opposed to:
    import {should} from 'chai';
    should();
    ```

    You can also register should via a mocha option: mocha --require chai/should.

  • The change assertion accepts a function as object. (Related Issues: #544, MRs: #607)

    js // Now you can also check if the return value of a function changes, for example assert.increases( someOperation, () => getSomething().length )

  • You can also assert for a delta using the by assertion alongside the change, increase and decrease assertions. (Related Issues: #339, MRs: #621)

    `` js // You can use.by` to assert the amount you want something to change
    var obj = { val: 10 };
    var increaseByTwo = function() { obj.val += 2 };
    var decreaseByTwo = function() { obj.val -= 2 };
    var increaseByThree = function() { obj.val += 3 };

    expect(increaseByThree).to.change(obj, 'val').by(3);
    expect(increaseByTwo).to.increase(obj, 'val').by(2);
    expect(decreaseByTwo).to.decrease(obj, 'val').by(2);

    // Please notice that if you want to assert something did change but not by some amount you need to use .not after the change related assertion
    // Take a look at the examples below:
    expect(increaseByThree).to.change(obj, 'val').but.not.by(5)
    expect(increaseByTwo).to.increase(obj, 'val').but.not.by(1)
    expect(decreaseByTwo).to.decrease(obj, 'val').but.not.by(1)
    ```

  • The .keys assertion can now operate on maps and sets. (Related Issues: #632, MRs: #633, #668)

    `` js // The.keysassertion now works onmaps andset`s natively, like the examples below:
    expect(new Map([[{objKey: 'value'}, 'value'], [1, 2]])).to.contain.key({objKey: 'value'});
    expect(new Map([[{objKey: 'value'}, 'value'], [1, 2]])).to.contain.any.keys([{objKey: 'value'}, {anotherKey: 'anotherValue'}]);
    expect(new Map([['firstKey', 'firstValue'], [1, 2]])).to.contain.all.keys('firstKey', 1);
    expect(new Set([['foo', 'bar'], ['example', 1]])).to.have.any.keys('foo');

    // You can also use .deep when asserting agains Maps and Sets
    expect(new Map([[{objKey: 'value'}, 'value'], [1, 2]])).to.contain.any.deep.keys([{objKey: 'value'}, {anotherKey: 'anotherValue'}]);
    expect(new Map([['firstKey', 'firstValue'], [1, 2]])).to.contain.all.deep.keys('firstKey', 1);
    expect(new Set([['foo', 'bar'], ['example', 1]])).to.have.any.deep.keys('foo');
    ```

  • Add compatibility with strict mode. (Related Issues: #578, MRs: #665)

    js // This means you can now run your code with the `--use_strict` flag on Node // If want to understand more about this please read the issue related to this change

  • Add does and but as new no-op assertion. (Related Issues: #700, #339 MRs: #621, #701)

    js // You can now write assertions forming phrases with these two new words: expect(increaseByThree).to.change(obj, 'val').but.not.by(5); expect(foobar).to.have.property("baz").which.does.not.have.property("thing");

  • Allow use to be imported using new ES6 module syntax. (Related Issues: #718, MRs: #724)

    `` js // You can now importuse` using the ES6 module syntax, like the example below:
    import sinonChai from "sinon-chai";
    import {expect, use} from "chai";

    use(sinonChai);

    You can also use `require` alongside the new ES6 destructuring feature:

    js
    const sinonChai = require('sinon-chai');
    const {expect, use} = require("chai");

    use(sinonChai);
    ```

  • Add ordered flag for members assertion. (Related Issues: #717, MRs: #728)

    js // You can now use the `ordered` flag to assert the order of elements when using the `members` assertion: expect([1, 2, 3]).to.include.ordered.members([1, 2]); // This passes expect([1, 2, 3]).to.include.ordered.members([2, 3]); // This will fail! Read the docs to know more.

  • Add .own flag to .property assertion. It does the same thing as .ownProperty and cannot be used alongisde the new .nested flag. (Related Issues: #795, MRs: #810)

    ``` js
    expect({a: 1}).to.have.own.property('a');

    // The example below will thrown an Error
    expect({a: {b: 1}}).to.have.own.nested.property('a.b', 1);
    ```

  • Add .deep support to .property assertion. (Related Issues: #795, MRs: #810)

    js expect({ foo: { bar: 'baz' } }).to.have.deep.own.property('foo', { bar: 'baz' }); expect({ foo: { bar: { baz: 'quux' } } }).to.have.deep.nested.property('foo.bar', { baz: 'quux' });

  • The .empty assertion will now work with ES6 collections (MRs: #763, #812, #814)
    Please notice that this assertion will throw an error when it is passed a WeakMap or WeakSet.

    ``` js
    expect(new Set()).to.be.empty;
    expect(new Map()).to.be.empty;

    // The examples below will throw a TypeError:
    expect(new WeakSet()).to.be.empty;
    expect(new WeakMap()).to.be.empty;
    ```

  • Add script that registers should as a side-effect. This change allows you to register should via a mocha option by using: mocha spec.js -r chai/register-should and also allows you to register the testing style globally. (Issues: #693, MRs: #868)

    js require('chai/register-should'); // Using Should style

  • Add script that registers assert as a side-effect. This change allows you to register assert via a mocha option by using: mocha spec.js -r chai/register-assert (Issues: #693, MRs: #868, #872)

    js require('chai/register-assert'); // Using Assert style

  • Add script that registers expect as a side-effect. This change allows you to register expect via a mocha option by using: mocha spec.js -r chai/register-expect (Issues: #693, MRs: #868, #872)

    js require('chai/register-expect'); // Using Expect style

  • When the length assertion is chained directly off of an uninvoked method, it references function's built-in length property instead of Chai's length assertion. This commit adds a guard to Chai methods to detect this problem and throw a helpful error message that advises the user on how to correct it. (Issues: #684, #841, MRs: #897)

  • Allows the lockSsfi flag to be set when creating new Assertion. This flag controls whether or not the given ssfi flag should retain its current value, even as assertions are chained off of this object. This is usually set to true when creating a new assertion from within another assertion. It's also temporarily set to true before an overwritten assertion gets called by the overwriting assertion. (Issues: #878, #904, MRs: #922)

    // This will lock the stack stack function from this line on
    // The SSFI is the reference to the starting point for removing irrelevant frames from the stack trace
    new Assertion(obj, msg, ssfi, true).to.have.property('length')
  • The nestedInclude, deepNestedInclude, ownInclude and deepOwnInclude assertions and there negated pairs were added to the assert interface. (Issues: #905, MRs: #964)

    // '[]' and '.' in property names can be escaped using double backslashes.
    assert.nestedInclude({'.a': {'b': 'x'}}, {'\.a.[b]': 'x'});
    assert.notNestedInclude({'.a': {'b': 'x'}}, {'\.a.b': 'y'});
    assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}});
    assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}});
    assert.ownInclude({ a: 1 }, { a: 1 });
    assert.notOwnInclude({ a: 1 }, { b: 2 });
    assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}});
    assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}});

Bug Fixes

  • Fix missing msg argument for change related assertions. (Related Issues: None, MRs: #606)
  • The addMethod function returns a new assertion with flags copied over instead of this. (Related Issues: #562, #684, #723, MRs: #642, #660)
  • Fix stacktraces for overwritten properties and methods. (Related Issues: #659, #661)
  • Fix bug when testing Symbol equality with should syntax. (Related Issues: #669, MRs: #672)
  • Fix bug when asserting some valid ES6 keys. (Related Issues: #674, MRs: #676)
  • Fix bug caused when custom inspect method is used and this method calls stylize. (MRs: #680)
  • Fix ownProperty on objects with no prototype. (Related Issues: #688, MRs: #689)
  • Fix swapped expected and actual results for the .members assertion. (Related Issues: #511, MRs: #702)
  • Fix same.members to properly handle duplicates by treating each one as a unique member. (Related Issues: #590, MRs: #739)
  • Fix deep.have.same.members() that was not printing a diff. (MRs: #509)
  • Diff will be shown for assert's equal and notEqual methods. (Related Issues: #790, MRs: #794)
  • The overwriteMethod, overwriteProperty, addChainableMethod, overwriteChainableMethod functions will return new assertion with flags copied over instead of this. (Related Issues: #562, #642, #791, MRs: #799)
  • Proxy-related implementation frames were showing up in the stack traces for failed property assertions. Now we remove them by setting the proxy getter (instead of the property getter) as the starting point to remove all implementation frames. (MRs: #884)
  • Negated keys assertions will now consider size of sets. (Related Issues: #919, MRs: #924)
  • Whenever passed something that is not an instance of a function, the instanceof assertion will now throw an error informing the user that he should pass a constructor to this assertion, but instead he has passed . (Related Issues: #893, MRs: #924)
  • Fix all issues on expect/should interfaces that were causing implementation frames to leak through. Also improve the internal Chai error test helper to validate stack traces. (Issues: #878, #904, MRs: #922)
  • This fixes custom messages not always being respected. (Issues: #922, #947, #904, MRs: #916, #923)
  • Fix PhantomJS 1.x incompatibility (Issues: #966, MRs: #890)

v4.0.1

4.0.1

Of course, any major release cannot go without a quick bugfix release shortly after - and here's ours!

Bug Fixes

  • Remove package.json browser field which was mistakenly added, and caused bundler tools like Browserify or Webpack to fail as it attempted to rebundle an already bundled file. (#978, #982)

v4.0.2

We have another bugfix release, addressing some issues for WebPack 1 users.

Bug Fixes

  • Revert getting version information from package.json, some bundler tools like Webpack do not come default with json loaders despite Node being able to handle this. This change moves back to hardcoding the version number in the codebase. (#985, #986)

v4.1.0

This release includes one new feature and a few bug fixes.

New Features

  • Add ES6 collection support to include() (#970, #994; @shvaikalesh)

Bug Fixes

  • Allow dates for isBelow and isAbove assertions (#980, #990; @v1adko)
  • fix: check target's type in .property assertion (#992; @meeber)

Chores

  • Add a missing var keyword found by lgtm.com (#988; @samlanning)
  • refactor: expectTypes to access ssfi flag (#993; @meeber)
  • Create CODEOWNERS (#1004; @keithamus)

v4.1.1

This release includes a few bug and documentation fixes.

Bug Fixes

  • fix: .instanceof to allow DOM interfaces in IE11 (#1000, #1008; @meeber)
  • fix: .include to work with all objects (#1009, #1012; @meeber)

Docs

  • fix: correct hasAnyKeys comment error (#1014; @zenHeart)
  • docs: re-indent hasAnyKeys code (#1016; @keithamus)

v4.1.2

This release fixes a bug when running in certain environments, and includes a few minor documentation fixes.

Bug Fixes

  • fix: update deep-eql to version 3.0.0 (#1020)
  • fix: replace code causing breakage under strict CSP (#1032; @Alhadis)

Docs

  • docs: add missing assert parameters (#1017, #1023; @Hpauric)
  • docs: update year in license file (#1025; @yanca018)

Commits

**v4.0.0**
  • 33e4403 test: added custom message test to negated .nested-, .deep-, .own.include
  • b744130 Assert: made documentation more descriptive
  • f3adfd9 fix: PhantomJS 1.x incompatibility (#966)
  • 0825826 Merge pull request #964 from zetamorph/assert-nestedInclude-ownInclude
  • 8ba95a7 Remove bump command to change lib/chai.js
  • 30a4451 Merge pull request #967 from lucasfcosta/remove-lib-bump
  • 0fe98b1 chai@4.0.0
  • 6349ff4 Merge pull request #972 from lucasfcosta/release-4.0.0
  • 545ca2f chore: uncomment travis lines
  • ab1fbad Merge pull request #973 from chaijs/chore-uncomment-travis-deploy
**v4.0.1**
  • d0ace69 Update supported node version badge in README FIX #975
  • eba5b42 chore(package): update browserify to version 14.4.0
  • b38b8d7 fix: (#978) remove browser field (#982)
**v4.0.2** **v4.1.0**
  • 7e466af Add a missing var keyword found by lgtm.com
  • e6ddf64 fix: check target's type in `.property` assertion
  • e7b2384 refactor: `expectTypes` to access `ssfi` flag
  • 351e968 Merge pull request #992 from meeber/property-target-type
  • 9116bc8 Merge pull request #993 from meeber/refactor-expect-types
  • 5daceab Merge pull request #988 from samlanning/missing-var
  • 3bcb21c Merge pull request #979 from chaijs/greenkeeper/browserify-14.4.0
  • 3c932e2 feat: allow dates for isBelow and isAbove assertions (#990)
  • 2eddd79 Add ES6 collection support to include() (#994)
  • 45cb327 chai@4.1.0
  • 11a6f85 test: skip failing `.include` tests in IE11
  • 3397dda Merge pull request #1005 from meeber/skip-failing-tests
  • cf70b11 Create CODEOWNERS
  • cad9933 Merge pull request #1004 from chaijs/code-owners
  • df9073c Merge pull request #998 from v1adko/make-release
**v4.1.1**
  • c107abb fix: `.instanceof` to allow DOM interfaces in IE11
  • 1847ef8 Merge pull request #1008 from meeber/fix-ie11-instanceof
  • c01cf30 fix: `.include` to work with all objects
  • 113a5b8 fix: correct hasAnyKeys comment error
  • 8fa24f2 Merge pull request #1014 from zenHeart/fix-hasAnyKeys-comment
  • b625497 Merge pull request #1012 from meeber/fix-include-types
  • 92d2cca docs: re-indent hasAnyKeys code
  • d2e9599 Merge pull request #1016 from chaijs/fix-reindent-code-1014
  • ac48db3 chai@4.1.1
  • 02ddebd Merge pull request #1019 from meeber/release-4.1.1
**v4.1.2**

This MR has been generated by Renovate Bot.

Edited by renovateBOT

Merge request reports

Loading