diff --git a/chai.js b/chai.js index 67b70508c..0c5868deb 100644 --- a/chai.js +++ b/chai.js @@ -14,7 +14,7 @@ var used = []; * Chai version */ -exports.version = '4.1.0'; +exports.version = '4.1.1'; /*! * Assertion Error @@ -830,53 +830,18 @@ module.exports = function (chai, _) { function include (val, msg) { if (msg) flag(this, 'message', msg); - - _.expectTypes(this, [ - 'array', 'object', 'string', - 'map', 'set', 'weakset', - ]); - + var obj = flag(this, 'object') - , objType = _.type(obj).toLowerCase(); - - // This block is for asserting a subset of properties in an object. - if (objType === 'object') { - var props = Object.keys(val) - , negate = flag(this, 'negate') - , firstErr = null - , numErrs = 0; - - props.forEach(function (prop) { - var propAssertion = new Assertion(obj); - _.transferFlags(this, propAssertion, true); - flag(propAssertion, 'lockSsfi', true); - - if (!negate || props.length === 1) { - propAssertion.property(prop, val[prop]); - return; - } - - try { - propAssertion.property(prop, val[prop]); - } catch (err) { - if (!_.checkError.compatibleConstructor(err, AssertionError)) throw err; - if (firstErr === null) firstErr = err; - numErrs++; - } - }, this); - - // When validating .not.include with multiple properties, we only want - // to throw an assertion error if all of the properties are included, - // in which case we throw the first property assertion error that we - // encountered. - if (negate && props.length > 1 && numErrs === props.length) throw firstErr; + , objType = _.type(obj).toLowerCase() + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , descriptor = isDeep ? 'deep ' : ''; - return; - } + flagMsg = flagMsg ? flagMsg + ': ' : ''; - var isDeep = flag(this, 'deep') - , descriptor = isDeep ? 'deep ' : '' - , included = false; + var included = false; switch (objType) { case 'string': @@ -885,10 +850,6 @@ module.exports = function (chai, _) { case 'weakset': if (isDeep) { - var flagMsg = flag(this, 'message') - , ssfi = flag(this, 'ssfi'); - flagMsg = flagMsg ? flagMsg + ': ' : ''; - throw new AssertionError( flagMsg + 'unable to use .deep.include with WeakSet', undefined, @@ -925,6 +886,53 @@ module.exports = function (chai, _) { included = obj.indexOf(val) !== -1; } break; + + default: + // This block is for asserting a subset of properties in an object. + // `_.expectTypes` isn't used here because `.include` should work with + // objects with a custom `@@toStringTag`. + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + 'object tested must be an array, a map, an object,' + + ' a set, a string, or a weakset, but ' + objType + ' given', + undefined, + ssfi + ); + } + + var props = Object.keys(val) + , firstErr = null + , numErrs = 0; + + props.forEach(function (prop) { + var propAssertion = new Assertion(obj); + _.transferFlags(this, propAssertion, true); + flag(propAssertion, 'lockSsfi', true); + + if (!negate || props.length === 1) { + propAssertion.property(prop, val[prop]); + return; + } + + try { + propAssertion.property(prop, val[prop]); + } catch (err) { + if (!_.checkError.compatibleConstructor(err, AssertionError)) { + throw err; + } + if (firstErr === null) firstErr = err; + numErrs++; + } + }, this); + + // When validating .not.include with multiple properties, we only want + // to throw an assertion error if all of the properties are included, + // in which case we throw the first property assertion error that we + // encountered. + if (negate && props.length > 1 && numErrs === props.length) { + throw firstErr; + } + return; } // Assert inclusion in collection or substring in a string. @@ -1962,28 +1970,25 @@ module.exports = function (chai, _) { var target = flag(this, 'object') var ssfi = flag(this, 'ssfi'); var flagMsg = flag(this, 'message'); - var validInstanceOfTarget = constructor === Object(constructor) && ( - typeof constructor === 'function' || - (typeof Symbol !== 'undefined' && - typeof Symbol.hasInstance !== 'undefined' && - Symbol.hasInstance in constructor) - ); - if (!validInstanceOfTarget) { - flagMsg = flagMsg ? flagMsg + ': ' : ''; - var constructorType = constructor === null ? 'null' : typeof constructor; - throw new AssertionError( - flagMsg + 'The instanceof assertion needs a constructor but ' + constructorType + ' was given.', - undefined, - ssfi - ); + try { + var isInstanceOf = target instanceof constructor; + } catch (err) { + if (err instanceof TypeError) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'The instanceof assertion needs a constructor but ' + + _.type(constructor) + ' was given.', + undefined, + ssfi + ); + } + throw err; } - var isInstanceOf = target instanceof constructor - var name = _.getName(constructor); if (name === null) { - name = 'an unnamed constructor'; + name = 'an unnamed constructor'; } this.assert( @@ -5762,10 +5767,10 @@ module.exports = function (chai, util) { * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * - * assert.hasAnyKey({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); - * assert.hasAnyKey({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337]); - * assert.hasAnyKey(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'thisKeyDoesNotExist']); - * assert.hasAnyKey(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'thisKeyDoesNotExist']); + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337}); + * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); * * @name hasAnyKeys * @param {Mixed} object diff --git a/lib/chai.js b/lib/chai.js index c1afbee92..2ad493bcb 100644 --- a/lib/chai.js +++ b/lib/chai.js @@ -10,7 +10,7 @@ var used = []; * Chai version */ -exports.version = '4.1.0'; +exports.version = '4.1.1'; /*! * Assertion Error diff --git a/package.json b/package.json index d0c86fc69..b56609084 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "Veselin Todorov ", "John Firebaugh " ], - "version": "4.1.0", + "version": "4.1.1", "repository": { "type": "git", "url": "https://github.com/chaijs/chai"