chai 2.3.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +21 -17
- package/History.md +7 -0
- package/README.md +35 -84
- package/ReleaseNotes.md +7 -0
- package/bower.json +0 -1
- package/chai.js +3928 -3623
- package/karma.conf.js +1 -1
- package/lib/chai/assertion.js +2 -2
- package/lib/chai/core/assertions.js +192 -32
- package/lib/chai/interface/assert.js +286 -37
- package/lib/chai/utils/addProperty.js +8 -1
- package/lib/chai/utils/getPathInfo.js +1 -1
- package/lib/chai/utils/getProperties.js +2 -2
- package/lib/chai/utils/hasProperty.js +1 -1
- package/lib/chai/utils/index.js +1 -1
- package/lib/chai.js +1 -1
- package/package.json +13 -11
- package/lib/chai/utils/type.js +0 -45
package/karma.conf.js
CHANGED
package/lib/chai/assertion.js
CHANGED
|
@@ -81,8 +81,8 @@ module.exports = function (_chai, util) {
|
|
|
81
81
|
util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
* ### .assert(expression, message, negateMessage, expected, actual)
|
|
84
|
+
/**
|
|
85
|
+
* ### .assert(expression, message, negateMessage, expected, actual, showDiff)
|
|
86
86
|
*
|
|
87
87
|
* Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
|
|
88
88
|
*
|
|
@@ -136,6 +136,12 @@ module.exports = function (chai, _) {
|
|
|
136
136
|
* expect({ foo: 'bar' }).to.be.an('object');
|
|
137
137
|
* expect(null).to.be.a('null');
|
|
138
138
|
* expect(undefined).to.be.an('undefined');
|
|
139
|
+
* expect(new Promise).to.be.a('promise');
|
|
140
|
+
* expect(new Float32Array()).to.be.a('float32array');
|
|
141
|
+
* expect(Symbol()).to.be.a('symbol');
|
|
142
|
+
*
|
|
143
|
+
* // es6 overrides
|
|
144
|
+
* expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');
|
|
139
145
|
*
|
|
140
146
|
* // language chain
|
|
141
147
|
* expect(foo).to.be.an.instanceof(Foo);
|
|
@@ -208,7 +214,7 @@ module.exports = function (chai, _) {
|
|
|
208
214
|
for (var k in val) subset[k] = obj[k];
|
|
209
215
|
expected = _.eql(subset, val);
|
|
210
216
|
} else {
|
|
211
|
-
expected = obj && ~obj.indexOf(val);
|
|
217
|
+
expected = (obj != undefined) && ~obj.indexOf(val);
|
|
212
218
|
}
|
|
213
219
|
this.assert(
|
|
214
220
|
expected
|
|
@@ -325,6 +331,25 @@ module.exports = function (chai, _) {
|
|
|
325
331
|
);
|
|
326
332
|
});
|
|
327
333
|
|
|
334
|
+
/**
|
|
335
|
+
* ### .NaN
|
|
336
|
+
* Asserts that the target is `NaN`.
|
|
337
|
+
*
|
|
338
|
+
* expect('foo').to.be.NaN;
|
|
339
|
+
* expect(4).not.to.be.NaN;
|
|
340
|
+
*
|
|
341
|
+
* @name NaN
|
|
342
|
+
* @api public
|
|
343
|
+
*/
|
|
344
|
+
|
|
345
|
+
Assertion.addProperty('NaN', function () {
|
|
346
|
+
this.assert(
|
|
347
|
+
isNaN(flag(this, 'object'))
|
|
348
|
+
, 'expected #{this} to be NaN'
|
|
349
|
+
, 'expected #{this} not to be NaN'
|
|
350
|
+
);
|
|
351
|
+
});
|
|
352
|
+
|
|
328
353
|
/**
|
|
329
354
|
* ### .exist
|
|
330
355
|
*
|
|
@@ -367,17 +392,8 @@ module.exports = function (chai, _) {
|
|
|
367
392
|
*/
|
|
368
393
|
|
|
369
394
|
Assertion.addProperty('empty', function () {
|
|
370
|
-
var obj = flag(this, 'object')
|
|
371
|
-
, expected = obj;
|
|
372
|
-
|
|
373
|
-
if (Array.isArray(obj) || 'string' === typeof object) {
|
|
374
|
-
expected = obj.length;
|
|
375
|
-
} else if (typeof obj === 'object') {
|
|
376
|
-
expected = Object.keys(obj).length;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
395
|
this.assert(
|
|
380
|
-
|
|
396
|
+
Object.keys(Object(flag(this, 'object'))).length === 0
|
|
381
397
|
, 'expected #{this} to be empty'
|
|
382
398
|
, 'expected #{this} not to be empty'
|
|
383
399
|
);
|
|
@@ -835,7 +851,7 @@ module.exports = function (chai, _) {
|
|
|
835
851
|
? pathInfo.value
|
|
836
852
|
: obj[name];
|
|
837
853
|
|
|
838
|
-
if (negate &&
|
|
854
|
+
if (negate && arguments.length > 1) {
|
|
839
855
|
if (undefined === value) {
|
|
840
856
|
msg = (msg != null) ? msg + ': ' : '';
|
|
841
857
|
throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
|
|
@@ -847,7 +863,7 @@ module.exports = function (chai, _) {
|
|
|
847
863
|
, 'expected #{this} to not have ' + descriptor + _.inspect(name));
|
|
848
864
|
}
|
|
849
865
|
|
|
850
|
-
if (
|
|
866
|
+
if (arguments.length > 1) {
|
|
851
867
|
this.assert(
|
|
852
868
|
val === value
|
|
853
869
|
, 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
|
|
@@ -938,16 +954,10 @@ module.exports = function (chai, _) {
|
|
|
938
954
|
Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);
|
|
939
955
|
|
|
940
956
|
/**
|
|
941
|
-
* ### .length
|
|
942
|
-
*
|
|
943
|
-
* Asserts that the target's `length` property has
|
|
944
|
-
* the expected value.
|
|
945
|
-
*
|
|
946
|
-
* expect([ 1, 2, 3]).to.have.length(3);
|
|
947
|
-
* expect('foobar').to.have.length(6);
|
|
957
|
+
* ### .length
|
|
948
958
|
*
|
|
949
|
-
*
|
|
950
|
-
* comparison for the length property.
|
|
959
|
+
* Sets the `doLength` flag later used as a chain precursor to a value
|
|
960
|
+
* comparison for the `length` property.
|
|
951
961
|
*
|
|
952
962
|
* expect('foo').to.have.length.above(2);
|
|
953
963
|
* expect([ 1, 2, 3 ]).to.have.length.above(2);
|
|
@@ -956,8 +966,25 @@ module.exports = function (chai, _) {
|
|
|
956
966
|
* expect('foo').to.have.length.within(2,4);
|
|
957
967
|
* expect([ 1, 2, 3 ]).to.have.length.within(2,4);
|
|
958
968
|
*
|
|
969
|
+
* *Deprecation notice:* Using `length` as an assertion will be deprecated
|
|
970
|
+
* in version 2.4.0 and removed in 3.0.0. Code using the old style of
|
|
971
|
+
* asserting for `length` property value using `length(value)` should be
|
|
972
|
+
* switched to use `lengthOf(value)` instead.
|
|
973
|
+
*
|
|
959
974
|
* @name length
|
|
960
|
-
* @
|
|
975
|
+
* @api public
|
|
976
|
+
*/
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* ### .lengthOf(value[, message])
|
|
980
|
+
*
|
|
981
|
+
* Asserts that the target's `length` property has
|
|
982
|
+
* the expected value.
|
|
983
|
+
*
|
|
984
|
+
* expect([ 1, 2, 3]).to.have.lengthOf(3);
|
|
985
|
+
* expect('foobar').to.have.lengthOf(6);
|
|
986
|
+
*
|
|
987
|
+
* @name lengthOf
|
|
961
988
|
* @param {Number} length
|
|
962
989
|
* @param {String} message _optional_
|
|
963
990
|
* @api public
|
|
@@ -993,12 +1020,12 @@ module.exports = function (chai, _) {
|
|
|
993
1020
|
* expect('foobar').to.match(/^foo/);
|
|
994
1021
|
*
|
|
995
1022
|
* @name match
|
|
1023
|
+
* @alias matches
|
|
996
1024
|
* @param {RegExp} RegularExpression
|
|
997
1025
|
* @param {String} message _optional_
|
|
998
1026
|
* @api public
|
|
999
1027
|
*/
|
|
1000
|
-
|
|
1001
|
-
Assertion.addMethod('match', function (re, msg) {
|
|
1028
|
+
function assertMatch(re, msg) {
|
|
1002
1029
|
if (msg) flag(this, 'message', msg);
|
|
1003
1030
|
var obj = flag(this, 'object');
|
|
1004
1031
|
this.assert(
|
|
@@ -1006,7 +1033,10 @@ module.exports = function (chai, _) {
|
|
|
1006
1033
|
, 'expected #{this} to match ' + re
|
|
1007
1034
|
, 'expected #{this} not to match ' + re
|
|
1008
1035
|
);
|
|
1009
|
-
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
Assertion.addMethod('match', assertMatch);
|
|
1039
|
+
Assertion.addMethod('matches', assertMatch);
|
|
1010
1040
|
|
|
1011
1041
|
/**
|
|
1012
1042
|
* ### .string(string)
|
|
@@ -1063,7 +1093,7 @@ module.exports = function (chai, _) {
|
|
|
1063
1093
|
* expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);
|
|
1064
1094
|
* expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});
|
|
1065
1095
|
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);
|
|
1066
|
-
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(
|
|
1096
|
+
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});
|
|
1067
1097
|
*
|
|
1068
1098
|
*
|
|
1069
1099
|
* @name keys
|
|
@@ -1255,7 +1285,7 @@ module.exports = function (chai, _) {
|
|
|
1255
1285
|
}
|
|
1256
1286
|
|
|
1257
1287
|
// next, check message
|
|
1258
|
-
var message = '
|
|
1288
|
+
var message = 'error' === _.type(err) && "message" in err
|
|
1259
1289
|
? err.message
|
|
1260
1290
|
: '' + err;
|
|
1261
1291
|
|
|
@@ -1329,12 +1359,13 @@ module.exports = function (chai, _) {
|
|
|
1329
1359
|
* expect(Klass).itself.to.respondTo('baz');
|
|
1330
1360
|
*
|
|
1331
1361
|
* @name respondTo
|
|
1362
|
+
* @alias respondsTo
|
|
1332
1363
|
* @param {String} method
|
|
1333
1364
|
* @param {String} message _optional_
|
|
1334
1365
|
* @api public
|
|
1335
1366
|
*/
|
|
1336
1367
|
|
|
1337
|
-
|
|
1368
|
+
function respondTo (method, msg) {
|
|
1338
1369
|
if (msg) flag(this, 'message', msg);
|
|
1339
1370
|
var obj = flag(this, 'object')
|
|
1340
1371
|
, itself = flag(this, 'itself')
|
|
@@ -1347,7 +1378,10 @@ module.exports = function (chai, _) {
|
|
|
1347
1378
|
, 'expected #{this} to respond to ' + _.inspect(method)
|
|
1348
1379
|
, 'expected #{this} to not respond to ' + _.inspect(method)
|
|
1349
1380
|
);
|
|
1350
|
-
}
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
Assertion.addMethod('respondTo', respondTo);
|
|
1384
|
+
Assertion.addMethod('respondsTo', respondTo);
|
|
1351
1385
|
|
|
1352
1386
|
/**
|
|
1353
1387
|
* ### .itself
|
|
@@ -1377,12 +1411,13 @@ module.exports = function (chai, _) {
|
|
|
1377
1411
|
* expect(1).to.satisfy(function(num) { return num > 0; });
|
|
1378
1412
|
*
|
|
1379
1413
|
* @name satisfy
|
|
1414
|
+
* @alias satisfies
|
|
1380
1415
|
* @param {Function} matcher
|
|
1381
1416
|
* @param {String} message _optional_
|
|
1382
1417
|
* @api public
|
|
1383
1418
|
*/
|
|
1384
1419
|
|
|
1385
|
-
|
|
1420
|
+
function satisfy (matcher, msg) {
|
|
1386
1421
|
if (msg) flag(this, 'message', msg);
|
|
1387
1422
|
var obj = flag(this, 'object');
|
|
1388
1423
|
var result = matcher(obj);
|
|
@@ -1393,7 +1428,10 @@ module.exports = function (chai, _) {
|
|
|
1393
1428
|
, this.negate ? false : true
|
|
1394
1429
|
, result
|
|
1395
1430
|
);
|
|
1396
|
-
}
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
Assertion.addMethod('satisfy', satisfy);
|
|
1434
|
+
Assertion.addMethod('satisfies', satisfy);
|
|
1397
1435
|
|
|
1398
1436
|
/**
|
|
1399
1437
|
* ### .closeTo(expected, delta)
|
|
@@ -1598,4 +1636,126 @@ module.exports = function (chai, _) {
|
|
|
1598
1636
|
Assertion.addChainableMethod('decrease', assertDecreases);
|
|
1599
1637
|
Assertion.addChainableMethod('decreases', assertDecreases);
|
|
1600
1638
|
|
|
1639
|
+
/**
|
|
1640
|
+
* ### .extensible
|
|
1641
|
+
*
|
|
1642
|
+
* Asserts that the target is extensible (can have new properties added to
|
|
1643
|
+
* it).
|
|
1644
|
+
*
|
|
1645
|
+
* var nonExtensibleObject = Object.preventExtensions({});
|
|
1646
|
+
* var sealedObject = Object.seal({});
|
|
1647
|
+
* var frozenObject = Object.freeze({});
|
|
1648
|
+
*
|
|
1649
|
+
* expect({}).to.be.extensible;
|
|
1650
|
+
* expect(nonExtensibleObject).to.not.be.extensible;
|
|
1651
|
+
* expect(sealedObject).to.not.be.extensible;
|
|
1652
|
+
* expect(frozenObject).to.not.be.extensible;
|
|
1653
|
+
*
|
|
1654
|
+
* @name extensible
|
|
1655
|
+
* @api public
|
|
1656
|
+
*/
|
|
1657
|
+
|
|
1658
|
+
Assertion.addProperty('extensible', function() {
|
|
1659
|
+
var obj = flag(this, 'object');
|
|
1660
|
+
|
|
1661
|
+
// In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.
|
|
1662
|
+
// In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.
|
|
1663
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
|
|
1664
|
+
// The following provides ES6 behavior when a TypeError is thrown under ES5.
|
|
1665
|
+
|
|
1666
|
+
var isExtensible;
|
|
1667
|
+
|
|
1668
|
+
try {
|
|
1669
|
+
isExtensible = Object.isExtensible(obj);
|
|
1670
|
+
} catch (err) {
|
|
1671
|
+
if (err instanceof TypeError) isExtensible = false;
|
|
1672
|
+
else throw err;
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
this.assert(
|
|
1676
|
+
isExtensible
|
|
1677
|
+
, 'expected #{this} to be extensible'
|
|
1678
|
+
, 'expected #{this} to not be extensible'
|
|
1679
|
+
);
|
|
1680
|
+
});
|
|
1681
|
+
|
|
1682
|
+
/**
|
|
1683
|
+
* ### .sealed
|
|
1684
|
+
*
|
|
1685
|
+
* Asserts that the target is sealed (cannot have new properties added to it
|
|
1686
|
+
* and its existing properties cannot be removed).
|
|
1687
|
+
*
|
|
1688
|
+
* var sealedObject = Object.seal({});
|
|
1689
|
+
* var frozenObject = Object.freeze({});
|
|
1690
|
+
*
|
|
1691
|
+
* expect(sealedObject).to.be.sealed;
|
|
1692
|
+
* expect(frozenObject).to.be.sealed;
|
|
1693
|
+
* expect({}).to.not.be.sealed;
|
|
1694
|
+
*
|
|
1695
|
+
* @name sealed
|
|
1696
|
+
* @api public
|
|
1697
|
+
*/
|
|
1698
|
+
|
|
1699
|
+
Assertion.addProperty('sealed', function() {
|
|
1700
|
+
var obj = flag(this, 'object');
|
|
1701
|
+
|
|
1702
|
+
// In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.
|
|
1703
|
+
// In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.
|
|
1704
|
+
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed
|
|
1705
|
+
// The following provides ES6 behavior when a TypeError is thrown under ES5.
|
|
1706
|
+
|
|
1707
|
+
var isSealed;
|
|
1708
|
+
|
|
1709
|
+
try {
|
|
1710
|
+
isSealed = Object.isSealed(obj);
|
|
1711
|
+
} catch (err) {
|
|
1712
|
+
if (err instanceof TypeError) isSealed = true;
|
|
1713
|
+
else throw err;
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
this.assert(
|
|
1717
|
+
isSealed
|
|
1718
|
+
, 'expected #{this} to be sealed'
|
|
1719
|
+
, 'expected #{this} to not be sealed'
|
|
1720
|
+
);
|
|
1721
|
+
});
|
|
1722
|
+
|
|
1723
|
+
/**
|
|
1724
|
+
* ### .frozen
|
|
1725
|
+
*
|
|
1726
|
+
* Asserts that the target is frozen (cannot have new properties added to it
|
|
1727
|
+
* and its existing properties cannot be modified).
|
|
1728
|
+
*
|
|
1729
|
+
* var frozenObject = Object.freeze({});
|
|
1730
|
+
*
|
|
1731
|
+
* expect(frozenObject).to.be.frozen;
|
|
1732
|
+
* expect({}).to.not.be.frozen;
|
|
1733
|
+
*
|
|
1734
|
+
* @name frozen
|
|
1735
|
+
* @api public
|
|
1736
|
+
*/
|
|
1737
|
+
|
|
1738
|
+
Assertion.addProperty('frozen', function() {
|
|
1739
|
+
var obj = flag(this, 'object');
|
|
1740
|
+
|
|
1741
|
+
// In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.
|
|
1742
|
+
// In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.
|
|
1743
|
+
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen
|
|
1744
|
+
// The following provides ES6 behavior when a TypeError is thrown under ES5.
|
|
1745
|
+
|
|
1746
|
+
var isFrozen;
|
|
1747
|
+
|
|
1748
|
+
try {
|
|
1749
|
+
isFrozen = Object.isFrozen(obj);
|
|
1750
|
+
} catch (err) {
|
|
1751
|
+
if (err instanceof TypeError) isFrozen = true;
|
|
1752
|
+
else throw err;
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
this.assert(
|
|
1756
|
+
isFrozen
|
|
1757
|
+
, 'expected #{this} to be frozen'
|
|
1758
|
+
, 'expected #{this} to not be frozen'
|
|
1759
|
+
);
|
|
1760
|
+
});
|
|
1601
1761
|
};
|