mirror of
https://github.com/chaijs/chai
synced 2024-11-15 00:07:11 +00:00
Fix bug when asserting some valid ES6 keys
- Resolution of https://github.com/chaijs/chai/issues/674 - Add compareByInspect utility for use with assertKeys sorts - Add getOwnEnumerableProperties utility - Add getOwnEnumerablePropertySymbols utility - Add Symbol support to the inspect utility - Add tests to utilities, should, expect, and assert
This commit is contained in:
parent
4f7284662c
commit
e22835116c
10 changed files with 473 additions and 4 deletions
|
@ -1170,7 +1170,7 @@ module.exports = function (chai, _) {
|
|||
}
|
||||
|
||||
} else {
|
||||
actual = Object.keys(obj);
|
||||
actual = _.getOwnEnumerableProperties(obj);
|
||||
|
||||
switch (_.type(keys)) {
|
||||
case 'array':
|
||||
|
@ -1184,7 +1184,10 @@ module.exports = function (chai, _) {
|
|||
keys = Array.prototype.slice.call(arguments);
|
||||
}
|
||||
|
||||
keys = keys.map(String);
|
||||
// Only stringify non-Symbols because Symbols would become "Symbol()"
|
||||
keys = keys.map(function (val) {
|
||||
return typeof val === 'symbol' ? val : String(val);
|
||||
});
|
||||
}
|
||||
|
||||
if (!keys.length) throw new Error('keys required');
|
||||
|
@ -1248,8 +1251,8 @@ module.exports = function (chai, _) {
|
|||
ok
|
||||
, 'expected #{this} to ' + str
|
||||
, 'expected #{this} to not ' + str
|
||||
, expected.slice(0).sort()
|
||||
, actual.sort()
|
||||
, expected.slice(0).sort(_.compareByInspect)
|
||||
, actual.sort(_.compareByInspect)
|
||||
, true
|
||||
);
|
||||
}
|
||||
|
|
31
lib/chai/utils/compareByInspect.js
Normal file
31
lib/chai/utils/compareByInspect.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*!
|
||||
* Chai - compareByInspect utility
|
||||
* Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Module dependancies
|
||||
*/
|
||||
|
||||
var inspect = require('./inspect');
|
||||
|
||||
/**
|
||||
* ### .compareByInspect (mixed, mixed)
|
||||
*
|
||||
* To be used as a compareFunction with Array.prototype.sort. Compares elements
|
||||
* using inspect instead of default behavior of using toString so that Symbols
|
||||
* and objects with irregular/missing toString can still be sorted without a
|
||||
* TypeError.
|
||||
*
|
||||
* @param {Mixed} first element to compare
|
||||
* @param {Mixed} second element to compare
|
||||
* @returns {Number} -1 if 'a' should come before 'b'; otherwise 1
|
||||
* @name compareByInspect
|
||||
* @namespace Utils
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function (a, b) {
|
||||
return inspect(a) < inspect(b) ? -1 : 1;
|
||||
};
|
29
lib/chai/utils/getOwnEnumerableProperties.js
Normal file
29
lib/chai/utils/getOwnEnumerableProperties.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*!
|
||||
* Chai - getOwnEnumerableProperties utility
|
||||
* Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Module dependancies
|
||||
*/
|
||||
|
||||
var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
|
||||
|
||||
/**
|
||||
* ### .getOwnEnumerableProperties(object)
|
||||
*
|
||||
* This allows the retrieval of directly-owned enumerable property names and
|
||||
* symbols of an object. This function is necessary because Object.keys only
|
||||
* returns enumerable property names, not enumerable property symbols.
|
||||
*
|
||||
* @param {Object} object
|
||||
* @returns {Array}
|
||||
* @namespace Utils
|
||||
* @name getOwnEnumerableProperties
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function getOwnEnumerableProperties(obj) {
|
||||
return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj));
|
||||
};
|
27
lib/chai/utils/getOwnEnumerablePropertySymbols.js
Normal file
27
lib/chai/utils/getOwnEnumerablePropertySymbols.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*!
|
||||
* Chai - getOwnEnumerablePropertySymbols utility
|
||||
* Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* ### .getOwnEnumerablePropertySymbols(object)
|
||||
*
|
||||
* This allows the retrieval of directly-owned enumerable property symbols of an
|
||||
* object. This function is necessary because Object.getOwnPropertySymbols
|
||||
* returns both enumerable and non-enumerable property symbols.
|
||||
*
|
||||
* @param {Object} object
|
||||
* @returns {Array}
|
||||
* @namespace Utils
|
||||
* @name getOwnEnumerablePropertySymbols
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function getOwnEnumerablePropertySymbols(obj) {
|
||||
if (typeof Object.getOwnPropertySymbols !== 'function') return [];
|
||||
|
||||
return Object.getOwnPropertySymbols(obj).filter(function (sym) {
|
||||
return Object.getOwnPropertyDescriptor(obj, sym).enumerable;
|
||||
});
|
||||
};
|
|
@ -128,3 +128,21 @@ exports.addChainableMethod = require('./addChainableMethod');
|
|||
*/
|
||||
|
||||
exports.overwriteChainableMethod = require('./overwriteChainableMethod');
|
||||
|
||||
/*!
|
||||
* Compare by inspect method
|
||||
*/
|
||||
|
||||
exports.compareByInspect = require('./compareByInspect');
|
||||
|
||||
/*!
|
||||
* Get own enumerable property symbols method
|
||||
*/
|
||||
|
||||
exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
|
||||
|
||||
/*!
|
||||
* Get own enumerable properties method
|
||||
*/
|
||||
|
||||
exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties');
|
||||
|
|
|
@ -200,6 +200,9 @@ function formatPrimitive(ctx, value) {
|
|||
|
||||
case 'boolean':
|
||||
return ctx.stylize('' + value, 'boolean');
|
||||
|
||||
case 'symbol':
|
||||
return ctx.stylize(value.toString(), 'symbol');
|
||||
}
|
||||
// For some reason typeof null is "object", so special case here.
|
||||
if (value === null) {
|
||||
|
|
|
@ -558,6 +558,42 @@ describe('assert', function () {
|
|||
assert.doesNotHaveAnyKeys({ foo: 1, bar: 2 }, { baz: 1, biz: 2, fake: 3 });
|
||||
assert.doesNotHaveAnyKeys({ foo: 1, bar: 2 }, { baz: 1 });
|
||||
|
||||
var enumProp1 = 'enumProp1'
|
||||
, enumProp2 = 'enumProp2'
|
||||
, nonEnumProp = 'nonEnumProp'
|
||||
, obj = {};
|
||||
|
||||
obj[enumProp1] = 'enumProp1';
|
||||
obj[enumProp2] = 'enumProp2';
|
||||
|
||||
Object.defineProperty(obj, nonEnumProp, {
|
||||
enumerable: false,
|
||||
value: 'nonEnumProp'
|
||||
});
|
||||
|
||||
assert.hasAllKeys(obj, [enumProp1, enumProp2]);
|
||||
assert.doesNotHaveAllKeys(obj, [enumProp1, enumProp2, nonEnumProp]);
|
||||
|
||||
if (typeof Symbol === 'function') {
|
||||
var sym1 = Symbol('sym1')
|
||||
, sym2 = Symbol('sym2')
|
||||
, sym3 = Symbol('sym3')
|
||||
, str = 'str'
|
||||
, obj = {};
|
||||
|
||||
obj[sym1] = 'sym1';
|
||||
obj[sym2] = 'sym2';
|
||||
obj[str] = 'str';
|
||||
|
||||
Object.defineProperty(obj, sym3, {
|
||||
enumerable: false,
|
||||
value: 'sym3'
|
||||
});
|
||||
|
||||
assert.hasAllKeys(obj, [sym1, sym2, str]);
|
||||
assert.doesNotHaveAllKeys(obj, [sym1, sym2, sym3, str]);
|
||||
}
|
||||
|
||||
if (typeof Map !== 'undefined') {
|
||||
var aKey = {thisIs: 'anExampleObject'};
|
||||
var anotherKey = {doingThisBecauseOf: 'referential equality'};
|
||||
|
@ -577,6 +613,25 @@ describe('assert', function () {
|
|||
assert.doesNotHaveAnyKeys(new Map([[aKey, 'aValue'], [anotherKey, 'anotherValue']]), [ 'thisDoesNotExist', 'thisToo', {iDoNot: 'exist'} ]);
|
||||
assert.doesNotHaveAllKeys(new Map([[aKey, 'aValue'], [anotherKey, 'anotherValue']]), [ aKey, {iDoNot: 'exist'} ]);
|
||||
|
||||
var weirdMapKey1 = Object.create(null)
|
||||
, weirdMapKey2 = {toString: NaN}
|
||||
, weirdMapKey3 = [];
|
||||
assert.hasAllKeys(new Map([[weirdMapKey1, 'val1'], [weirdMapKey2, 'val2']]), [weirdMapKey1, weirdMapKey2]);
|
||||
assert.doesNotHaveAllKeys(new Map([[weirdMapKey1, 'val1'], [weirdMapKey2, 'val2']]), [weirdMapKey1, weirdMapKey3]);
|
||||
|
||||
if (typeof Symbol === 'function') {
|
||||
var symMapKey1 = Symbol()
|
||||
, symMapKey2 = Symbol()
|
||||
, symMapKey3 = Symbol();
|
||||
|
||||
assert.hasAllKeys(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]), [symMapKey1, symMapKey2]);
|
||||
assert.hasAnyKeys(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]), [symMapKey1, symMapKey3]);
|
||||
assert.containsAllKeys(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]), [symMapKey2, symMapKey1]);
|
||||
|
||||
assert.doesNotHaveAllKeys(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]), [symMapKey1, symMapKey3]);
|
||||
assert.doesNotHaveAnyKeys(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]), [symMapKey3]);
|
||||
}
|
||||
|
||||
err(function(){
|
||||
assert.hasAllKeys(new Map([[{1: 20}, 'number']]));
|
||||
}, "keys required");
|
||||
|
@ -637,6 +692,25 @@ describe('assert', function () {
|
|||
assert.doesNotHaveAnyKeys(new Set([aKey, anotherKey]), [ 20, 1, {iDoNot: 'exist'} ]);
|
||||
assert.doesNotHaveAllKeys(new Set([aKey, anotherKey]), [ 'thisDoesNotExist', 'thisToo', {iDoNot: 'exist'} ]);
|
||||
|
||||
var weirdSetKey1 = Object.create(null)
|
||||
, weirdSetKey2 = {toString: NaN}
|
||||
, weirdSetKey3 = [];
|
||||
assert.hasAllKeys(new Set([weirdSetKey1, weirdSetKey2]), [weirdSetKey1, weirdSetKey2]);
|
||||
assert.doesNotHaveAllKeys(new Set([weirdSetKey1, weirdSetKey2]), [weirdSetKey1, weirdSetKey3]);
|
||||
|
||||
if (typeof Symbol === 'function') {
|
||||
var symSetKey1 = Symbol()
|
||||
, symSetKey2 = Symbol()
|
||||
, symSetKey3 = Symbol();
|
||||
|
||||
assert.hasAllKeys(new Set([symSetKey1, symSetKey2]), [symSetKey1, symSetKey2]);
|
||||
assert.hasAnyKeys(new Set([symSetKey1, symSetKey2]), [symSetKey1, symSetKey3]);
|
||||
assert.containsAllKeys(new Set([symSetKey1, symSetKey2]), [symSetKey2, symSetKey1]);
|
||||
|
||||
assert.doesNotHaveAllKeys(new Set([symSetKey1, symSetKey2]), [symSetKey1, symSetKey3]);
|
||||
assert.doesNotHaveAnyKeys(new Set([symSetKey1, symSetKey2]), [symSetKey3]);
|
||||
}
|
||||
|
||||
err(function(){
|
||||
assert.hasAllKeys(new Set([{1: 20}, 'number']));
|
||||
}, "keys required");
|
||||
|
|
|
@ -743,6 +743,42 @@ describe('expect', function () {
|
|||
expect({ foo: 1, bar: 2 }).not.have.all.keys({ 'baz': 8, 'foo': 7 });
|
||||
expect({ foo: 1, bar: 2 }).not.contain.all.keys({ 'baz': 8, 'foo': 7 });
|
||||
|
||||
var enumProp1 = 'enumProp1'
|
||||
, enumProp2 = 'enumProp2'
|
||||
, nonEnumProp = 'nonEnumProp'
|
||||
, obj = {};
|
||||
|
||||
obj[enumProp1] = 'enumProp1';
|
||||
obj[enumProp2] = 'enumProp2';
|
||||
|
||||
Object.defineProperty(obj, nonEnumProp, {
|
||||
enumerable: false,
|
||||
value: 'nonEnumProp'
|
||||
});
|
||||
|
||||
expect(obj).to.have.all.keys([enumProp1, enumProp2]);
|
||||
expect(obj).to.not.have.all.keys([enumProp1, enumProp2, nonEnumProp]);
|
||||
|
||||
if (typeof Symbol === 'function') {
|
||||
var sym1 = Symbol('sym1')
|
||||
, sym2 = Symbol('sym2')
|
||||
, sym3 = Symbol('sym3')
|
||||
, str = 'str'
|
||||
, obj = {};
|
||||
|
||||
obj[sym1] = 'sym1';
|
||||
obj[sym2] = 'sym2';
|
||||
obj[str] = 'str';
|
||||
|
||||
Object.defineProperty(obj, sym3, {
|
||||
enumerable: false,
|
||||
value: 'sym3'
|
||||
});
|
||||
|
||||
expect(obj).to.have.all.keys([sym1, sym2, str]);
|
||||
expect(obj).to.not.have.all.keys([sym1, sym2, sym3, str]);
|
||||
}
|
||||
|
||||
if (typeof Map !== 'undefined') {
|
||||
var aKey = {thisIs: 'anExampleObject'};
|
||||
var anotherKey = {doingThisBecauseOf: 'referential equality'};
|
||||
|
@ -766,6 +802,28 @@ describe('expect', function () {
|
|||
expect(new Map([[aKey, 'aValue'], [anotherKey, 'anotherValue']])).to.not.have.any.keys([20, 1, {13: 37}]);
|
||||
expect(new Map([[aKey, 'aValue'], [anotherKey, 'anotherValue']])).to.not.have.all.keys([aKey, {'iDoNot': 'exist'}]);
|
||||
|
||||
var weirdMapKey1 = Object.create(null)
|
||||
, weirdMapKey2 = {toString: NaN}
|
||||
, weirdMapKey3 = [];
|
||||
expect(new Map([[weirdMapKey1, 'val1'], [weirdMapKey2, 'val2']])).to.have.all.keys([weirdMapKey1, weirdMapKey2]);
|
||||
expect(new Map([[weirdMapKey1, 'val1'], [weirdMapKey2, 'val2']])).to.not.have.all.keys([weirdMapKey1, weirdMapKey3]);
|
||||
|
||||
if (typeof Symbol === 'function') {
|
||||
var symMapKey1 = Symbol()
|
||||
, symMapKey2 = Symbol()
|
||||
, symMapKey3 = Symbol();
|
||||
|
||||
expect(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']])).to.have.all.keys(symMapKey1, symMapKey2);
|
||||
expect(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']])).to.have.any.keys(symMapKey1, symMapKey3);
|
||||
expect(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']])).to.contain.all.keys(symMapKey2, symMapKey1);
|
||||
expect(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']])).to.contain.any.keys(symMapKey3, symMapKey1);
|
||||
|
||||
expect(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']])).to.not.have.all.keys(symMapKey1, symMapKey3);
|
||||
expect(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']])).to.not.have.any.keys(symMapKey3);
|
||||
expect(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']])).to.not.contain.all.keys(symMapKey3, symMapKey1);
|
||||
expect(new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']])).to.not.contain.any.keys(symMapKey3);
|
||||
}
|
||||
|
||||
err(function(){
|
||||
expect(new Map().set({ foo: 1 })).to.have.keys();
|
||||
}, "keys required");
|
||||
|
@ -806,6 +864,28 @@ describe('expect', function () {
|
|||
expect(new Set([aKey, anotherKey])).to.not.have.any.keys([20, 1, {13: 37}]);
|
||||
expect(new Set([aKey, anotherKey])).to.not.have.all.keys([aKey, {'iDoNot': 'exist'}]);
|
||||
|
||||
var weirdSetKey1 = Object.create(null)
|
||||
, weirdSetKey2 = {toString: NaN}
|
||||
, weirdSetKey3 = [];
|
||||
expect(new Set([weirdSetKey1, weirdSetKey2])).to.have.all.keys([weirdSetKey1, weirdSetKey2]);
|
||||
expect(new Set([weirdSetKey1, weirdSetKey2])).to.not.have.all.keys([weirdSetKey1, weirdSetKey3]);
|
||||
|
||||
if (typeof Symbol === 'function') {
|
||||
var symSetKey1 = Symbol()
|
||||
, symSetKey2 = Symbol()
|
||||
, symSetKey3 = Symbol();
|
||||
|
||||
expect(new Set([symSetKey1, symSetKey2])).to.have.all.keys(symSetKey1, symSetKey2);
|
||||
expect(new Set([symSetKey1, symSetKey2])).to.have.any.keys(symSetKey1, symSetKey3);
|
||||
expect(new Set([symSetKey1, symSetKey2])).to.contain.all.keys(symSetKey2, symSetKey1);
|
||||
expect(new Set([symSetKey1, symSetKey2])).to.contain.any.keys(symSetKey3, symSetKey1);
|
||||
|
||||
expect(new Set([symSetKey1, symSetKey2])).to.not.have.all.keys(symSetKey1, symSetKey3);
|
||||
expect(new Set([symSetKey1, symSetKey2])).to.not.have.any.keys(symSetKey3);
|
||||
expect(new Set([symSetKey1, symSetKey2])).to.not.contain.all.keys(symSetKey3, symSetKey1);
|
||||
expect(new Set([symSetKey1, symSetKey2])).to.not.contain.any.keys(symSetKey3);
|
||||
}
|
||||
|
||||
err(function(){
|
||||
expect(new Set().add({ foo: 1 })).to.have.keys();
|
||||
}, "keys required");
|
||||
|
|
|
@ -585,6 +585,42 @@ describe('should', function() {
|
|||
({ 1: 1, 2: 2 }).should.have.any.keys(1, 3);
|
||||
({ 1: 1, 2: 2 }).should.contain.keys(1);
|
||||
|
||||
var enumProp1 = 'enumProp1'
|
||||
, enumProp2 = 'enumProp2'
|
||||
, nonEnumProp = 'nonEnumProp'
|
||||
, obj = {};
|
||||
|
||||
obj[enumProp1] = 'enumProp1';
|
||||
obj[enumProp2] = 'enumProp2';
|
||||
|
||||
Object.defineProperty(obj, nonEnumProp, {
|
||||
enumerable: false,
|
||||
value: 'nonEnumProp'
|
||||
});
|
||||
|
||||
obj.should.have.all.keys([enumProp1, enumProp2]);
|
||||
obj.should.not.have.all.keys([enumProp1, enumProp2, nonEnumProp]);
|
||||
|
||||
if (typeof Symbol === 'function') {
|
||||
var sym1 = Symbol('sym1')
|
||||
, sym2 = Symbol('sym2')
|
||||
, sym3 = Symbol('sym3')
|
||||
, str = 'str'
|
||||
, obj = {};
|
||||
|
||||
obj[sym1] = 'sym1';
|
||||
obj[sym2] = 'sym2';
|
||||
obj[str] = 'str';
|
||||
|
||||
Object.defineProperty(obj, sym3, {
|
||||
enumerable: false,
|
||||
value: 'sym3'
|
||||
});
|
||||
|
||||
obj.should.have.all.keys([sym1, sym2, str]);
|
||||
obj.should.not.have.all.keys([sym1, sym2, sym3, str]);
|
||||
}
|
||||
|
||||
if (typeof Map !== 'undefined') {
|
||||
var aKey = {thisIs: 'anExampleObject'};
|
||||
var anotherKey = {doingThisBecauseOf: 'referential equality'};
|
||||
|
@ -607,6 +643,28 @@ describe('should', function() {
|
|||
new Map([[aKey, 'aValue'], [anotherKey, 'anotherValue']]).should.not.have.any.keys([20, 1, {13: 37}]);
|
||||
new Map([[aKey, 'aValue'], [anotherKey, 'anotherValue']]).should.not.have.all.keys([aKey, {'iDoNot': 'exist'}]);
|
||||
|
||||
var weirdMapKey1 = Object.create(null)
|
||||
, weirdMapKey2 = {toString: NaN}
|
||||
, weirdMapKey3 = [];
|
||||
new Map([[weirdMapKey1, 'val1'], [weirdMapKey2, 'val2']]).should.have.all.keys([weirdMapKey1, weirdMapKey2]);
|
||||
new Map([[weirdMapKey1, 'val1'], [weirdMapKey2, 'val2']]).should.not.have.all.keys([weirdMapKey1, weirdMapKey3]);
|
||||
|
||||
if (typeof Symbol === 'function') {
|
||||
var symMapKey1 = Symbol()
|
||||
, symMapKey2 = Symbol()
|
||||
, symMapKey3 = Symbol();
|
||||
|
||||
new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]).should.have.all.keys(symMapKey1, symMapKey2);
|
||||
new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]).should.have.any.keys(symMapKey1, symMapKey3);
|
||||
new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]).should.contain.all.keys(symMapKey2, symMapKey1);
|
||||
new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]).should.contain.any.keys(symMapKey3, symMapKey1);
|
||||
|
||||
new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]).should.not.have.all.keys(symMapKey1, symMapKey3);
|
||||
new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]).should.not.have.any.keys(symMapKey3);
|
||||
new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]).should.not.contain.all.keys(symMapKey3, symMapKey1);
|
||||
new Map([[symMapKey1, 'symValue1'], [symMapKey2, 'symValue2']]).should.not.contain.any.keys(symMapKey3);
|
||||
}
|
||||
|
||||
err(function(){
|
||||
new Map().set({ foo: 1 }).should.have.keys();
|
||||
}, "keys required");
|
||||
|
@ -647,6 +705,28 @@ describe('should', function() {
|
|||
new Set([aKey, anotherKey]).should.not.have.any.keys([20, 1, {13: 37}]);
|
||||
new Set([aKey, anotherKey]).should.not.have.all.keys([aKey, {'iDoNot': 'exist'}]);
|
||||
|
||||
var weirdSetKey1 = Object.create(null)
|
||||
, weirdSetKey2 = {toString: NaN}
|
||||
, weirdSetKey3 = [];
|
||||
new Set([weirdSetKey1, weirdSetKey2]).should.have.all.keys([weirdSetKey1, weirdSetKey2]);
|
||||
new Set([weirdSetKey1, weirdSetKey2]).should.not.have.all.keys([weirdSetKey1, weirdSetKey3]);
|
||||
|
||||
if (typeof Symbol === 'function') {
|
||||
var symSetKey1 = Symbol()
|
||||
, symSetKey2 = Symbol()
|
||||
, symSetKey3 = Symbol();
|
||||
|
||||
new Set([symSetKey1, symSetKey2]).should.have.all.keys(symSetKey1, symSetKey2);
|
||||
new Set([symSetKey1, symSetKey2]).should.have.any.keys(symSetKey1, symSetKey3);
|
||||
new Set([symSetKey1, symSetKey2]).should.contain.all.keys(symSetKey2, symSetKey1);
|
||||
new Set([symSetKey1, symSetKey2]).should.contain.any.keys(symSetKey3, symSetKey1);
|
||||
|
||||
new Set([symSetKey1, symSetKey2]).should.not.have.all.keys(symSetKey1, symSetKey3);
|
||||
new Set([symSetKey1, symSetKey2]).should.not.have.any.keys(symSetKey3);
|
||||
new Set([symSetKey1, symSetKey2]).should.not.contain.all.keys(symSetKey3, symSetKey1);
|
||||
new Set([symSetKey1, symSetKey2]).should.not.contain.any.keys(symSetKey3);
|
||||
}
|
||||
|
||||
err(function(){
|
||||
new Set().add({ foo: 1 }).should.have.keys();
|
||||
}, "keys required");
|
||||
|
|
|
@ -630,6 +630,15 @@ describe('utilities', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('inspect Symbol', function () {
|
||||
if (typeof Symbol !== 'function') return;
|
||||
|
||||
chai.use(function (_chai, _) {
|
||||
expect(_.inspect(Symbol())).to.equal('Symbol()');
|
||||
expect(_.inspect(Symbol('cat'))).to.equal('Symbol(cat)');
|
||||
});
|
||||
});
|
||||
|
||||
it('addChainableMethod', function () {
|
||||
chai.use(function (_chai, _) {
|
||||
_chai.Assertion.addChainableMethod('x',
|
||||
|
@ -704,4 +713,119 @@ describe('utilities', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('compareByInspect', function () {
|
||||
chai.use(function (_chai, _) {
|
||||
var cbi = _.compareByInspect;
|
||||
|
||||
// "'c" is less than "'d"
|
||||
expect(cbi('cat', 'dog')).to.equal(-1);
|
||||
expect(cbi('dog', 'cat')).to.equal(1);
|
||||
expect(cbi('cat', 'cat')).to.equal(1);
|
||||
|
||||
// "{ cat: [ [ 'dog', 1" is less than "{ cat [ [ 'dog', 2"
|
||||
expect(cbi({'cat': [['dog', 1]]}, {'cat': [['dog', 2]]})).to.equal(-1);
|
||||
expect(cbi({'cat': [['dog', 2]]}, {'cat': [['dog', 1]]})).to.equal(1);
|
||||
|
||||
if (typeof Symbol === 'function') {
|
||||
// "Symbol(c" is less than "Symbol(d"
|
||||
expect(cbi(Symbol('cat'), Symbol('dog'))).to.equal(-1);
|
||||
expect(cbi(Symbol('dog'), Symbol('cat'))).to.equal(1);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOwnEnumerablePropertySymbols', function () {
|
||||
var gettem;
|
||||
|
||||
beforeEach(function () {
|
||||
chai.use(function (_chai, _) {
|
||||
gettem = _.getOwnEnumerablePropertySymbols;
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an empty array if no symbols', function () {
|
||||
var obj = {}
|
||||
, cat = 'cat';
|
||||
|
||||
obj[cat] = 42;
|
||||
|
||||
expect(gettem(obj)).to.not.include(cat);
|
||||
});
|
||||
|
||||
it('returns enumerable symbols only', function () {
|
||||
if (typeof Symbol !== 'function') return;
|
||||
|
||||
var cat = Symbol('cat')
|
||||
, dog = Symbol('dog')
|
||||
, frog = Symbol('frog')
|
||||
, cow = 'cow'
|
||||
, obj = {};
|
||||
|
||||
obj[cat] = 'meow';
|
||||
obj[dog] = 'woof';
|
||||
|
||||
Object.defineProperty(obj, frog, {
|
||||
enumerable: false,
|
||||
value: 'ribbit'
|
||||
});
|
||||
|
||||
obj[cow] = 'moo';
|
||||
|
||||
expect(gettem(obj)).to.have.same.members([cat, dog]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOwnEnumerableProperties', function () {
|
||||
var gettem;
|
||||
|
||||
beforeEach(function () {
|
||||
chai.use(function (_chai, _) {
|
||||
gettem = _.getOwnEnumerableProperties;
|
||||
});
|
||||
});
|
||||
|
||||
it('returns enumerable property names if no symbols', function () {
|
||||
var cat = 'cat'
|
||||
, dog = 'dog'
|
||||
, frog = 'frog'
|
||||
, obj = {};
|
||||
|
||||
obj[cat] = 'meow'
|
||||
obj[dog] = 'woof';
|
||||
|
||||
Object.defineProperty(obj, frog, {
|
||||
enumerable: false,
|
||||
value: 'ribbit'
|
||||
});
|
||||
|
||||
expect(gettem(obj)).to.have.same.members([cat, dog]);
|
||||
});
|
||||
|
||||
it('returns enumerable property names and symbols', function () {
|
||||
if (typeof Symbol !== 'function') return;
|
||||
|
||||
var cat = Symbol('cat')
|
||||
, dog = Symbol('dog')
|
||||
, frog = Symbol('frog')
|
||||
, bird = 'bird'
|
||||
, cow = 'cow'
|
||||
, obj = {};
|
||||
|
||||
obj[cat] = 'meow';
|
||||
obj[dog] = 'woof';
|
||||
obj[bird] = 'chirp';
|
||||
|
||||
Object.defineProperty(obj, frog, {
|
||||
enumerable: false,
|
||||
value: 'ribbit'
|
||||
});
|
||||
|
||||
Object.defineProperty(obj, cow, {
|
||||
enumerable: false,
|
||||
value: 'moo'
|
||||
});
|
||||
|
||||
expect(gettem(obj)).to.have.same.members([cat, dog, bird]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue