chai 2.2.0 → 3.2.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 +21 -0
- package/README.md +35 -81
- package/ReleaseNotes.md +38 -0
- package/bower.json +0 -1
- package/chai.js +3929 -3688
- package/karma.conf.js +1 -1
- package/lib/chai/assertion.js +2 -2
- package/lib/chai/core/assertions.js +210 -33
- package/lib/chai/interface/assert.js +198 -23
- 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 -10
- 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
|
*
|
|
@@ -93,7 +93,7 @@ module.exports = function (chai, _) {
|
|
|
93
93
|
* ### .any
|
|
94
94
|
*
|
|
95
95
|
* Sets the `any` flag, (opposite of the `all` flag)
|
|
96
|
-
* later used in the `keys` assertion.
|
|
96
|
+
* later used in the `keys` assertion.
|
|
97
97
|
*
|
|
98
98
|
* expect(foo).to.have.any.keys('bar', 'baz');
|
|
99
99
|
*
|
|
@@ -110,7 +110,7 @@ module.exports = function (chai, _) {
|
|
|
110
110
|
/**
|
|
111
111
|
* ### .all
|
|
112
112
|
*
|
|
113
|
-
* Sets the `all` flag (opposite of the `any` flag)
|
|
113
|
+
* Sets the `all` flag (opposite of the `any` flag)
|
|
114
114
|
* later used by the `keys` assertion.
|
|
115
115
|
*
|
|
116
116
|
* expect(foo).to.have.all.keys('bar', 'baz');
|
|
@@ -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);
|
|
@@ -291,7 +297,7 @@ module.exports = function (chai, _) {
|
|
|
291
297
|
* Asserts that the target is `null`.
|
|
292
298
|
*
|
|
293
299
|
* expect(null).to.be.null;
|
|
294
|
-
* expect(undefined).not.
|
|
300
|
+
* expect(undefined).to.not.be.null;
|
|
295
301
|
*
|
|
296
302
|
* @name null
|
|
297
303
|
* @api public
|
|
@@ -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
|
*
|
|
@@ -767,7 +792,7 @@ module.exports = function (chai, _) {
|
|
|
767
792
|
* green: { tea: 'matcha' }
|
|
768
793
|
* , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]
|
|
769
794
|
* };
|
|
770
|
-
*
|
|
795
|
+
*
|
|
771
796
|
* expect(deepObj).to.have.deep.property('green.tea', 'matcha');
|
|
772
797
|
* expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
|
|
773
798
|
* expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');
|
|
@@ -835,7 +860,7 @@ module.exports = function (chai, _) {
|
|
|
835
860
|
? pathInfo.value
|
|
836
861
|
: obj[name];
|
|
837
862
|
|
|
838
|
-
if (negate &&
|
|
863
|
+
if (negate && arguments.length > 1) {
|
|
839
864
|
if (undefined === value) {
|
|
840
865
|
msg = (msg != null) ? msg + ': ' : '';
|
|
841
866
|
throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
|
|
@@ -847,7 +872,7 @@ module.exports = function (chai, _) {
|
|
|
847
872
|
, 'expected #{this} to not have ' + descriptor + _.inspect(name));
|
|
848
873
|
}
|
|
849
874
|
|
|
850
|
-
if (
|
|
875
|
+
if (arguments.length > 1) {
|
|
851
876
|
this.assert(
|
|
852
877
|
val === value
|
|
853
878
|
, 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
|
|
@@ -889,16 +914,59 @@ module.exports = function (chai, _) {
|
|
|
889
914
|
Assertion.addMethod('haveOwnProperty', assertOwnProperty);
|
|
890
915
|
|
|
891
916
|
/**
|
|
892
|
-
* ### .
|
|
917
|
+
* ### .ownPropertyDescriptor(name[, descriptor[, message]])
|
|
893
918
|
*
|
|
894
|
-
* Asserts that the target
|
|
895
|
-
*
|
|
919
|
+
* Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.
|
|
920
|
+
*
|
|
921
|
+
* expect('test').to.have.ownPropertyDescriptor('length');
|
|
922
|
+
* expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });
|
|
923
|
+
* expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });
|
|
924
|
+
* expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);
|
|
925
|
+
* expect('test').ownPropertyDescriptor('length').to.have.keys('value');
|
|
896
926
|
*
|
|
897
|
-
*
|
|
898
|
-
*
|
|
927
|
+
* @name ownPropertyDescriptor
|
|
928
|
+
* @alias haveOwnPropertyDescriptor
|
|
929
|
+
* @param {String} name
|
|
930
|
+
* @param {Object} descriptor _optional_
|
|
931
|
+
* @param {String} message _optional_
|
|
932
|
+
* @api public
|
|
933
|
+
*/
|
|
934
|
+
|
|
935
|
+
function assertOwnPropertyDescriptor (name, descriptor, msg) {
|
|
936
|
+
if (typeof descriptor === 'string') {
|
|
937
|
+
msg = descriptor;
|
|
938
|
+
descriptor = null;
|
|
939
|
+
}
|
|
940
|
+
if (msg) flag(this, 'message', msg);
|
|
941
|
+
var obj = flag(this, 'object');
|
|
942
|
+
var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);
|
|
943
|
+
if (actualDescriptor && descriptor) {
|
|
944
|
+
this.assert(
|
|
945
|
+
_.eql(descriptor, actualDescriptor)
|
|
946
|
+
, 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)
|
|
947
|
+
, 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)
|
|
948
|
+
, descriptor
|
|
949
|
+
, actualDescriptor
|
|
950
|
+
, true
|
|
951
|
+
);
|
|
952
|
+
} else {
|
|
953
|
+
this.assert(
|
|
954
|
+
actualDescriptor
|
|
955
|
+
, 'expected #{this} to have an own property descriptor for ' + _.inspect(name)
|
|
956
|
+
, 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
flag(this, 'object', actualDescriptor);
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);
|
|
963
|
+
Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* ### .length
|
|
899
967
|
*
|
|
900
|
-
*
|
|
901
|
-
* comparison for the length property.
|
|
968
|
+
* Sets the `doLength` flag later used as a chain precursor to a value
|
|
969
|
+
* comparison for the `length` property.
|
|
902
970
|
*
|
|
903
971
|
* expect('foo').to.have.length.above(2);
|
|
904
972
|
* expect([ 1, 2, 3 ]).to.have.length.above(2);
|
|
@@ -907,8 +975,25 @@ module.exports = function (chai, _) {
|
|
|
907
975
|
* expect('foo').to.have.length.within(2,4);
|
|
908
976
|
* expect([ 1, 2, 3 ]).to.have.length.within(2,4);
|
|
909
977
|
*
|
|
978
|
+
* *Deprecation notice:* Using `length` as an assertion will be deprecated
|
|
979
|
+
* in version 2.4.0 and removed in 3.0.0. Code using the old style of
|
|
980
|
+
* asserting for `length` property value using `length(value)` should be
|
|
981
|
+
* switched to use `lengthOf(value)` instead.
|
|
982
|
+
*
|
|
910
983
|
* @name length
|
|
911
|
-
* @
|
|
984
|
+
* @api public
|
|
985
|
+
*/
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* ### .lengthOf(value[, message])
|
|
989
|
+
*
|
|
990
|
+
* Asserts that the target's `length` property has
|
|
991
|
+
* the expected value.
|
|
992
|
+
*
|
|
993
|
+
* expect([ 1, 2, 3]).to.have.lengthOf(3);
|
|
994
|
+
* expect('foobar').to.have.lengthOf(6);
|
|
995
|
+
*
|
|
996
|
+
* @name lengthOf
|
|
912
997
|
* @param {Number} length
|
|
913
998
|
* @param {String} message _optional_
|
|
914
999
|
* @api public
|
|
@@ -944,12 +1029,12 @@ module.exports = function (chai, _) {
|
|
|
944
1029
|
* expect('foobar').to.match(/^foo/);
|
|
945
1030
|
*
|
|
946
1031
|
* @name match
|
|
1032
|
+
* @alias matches
|
|
947
1033
|
* @param {RegExp} RegularExpression
|
|
948
1034
|
* @param {String} message _optional_
|
|
949
1035
|
* @api public
|
|
950
1036
|
*/
|
|
951
|
-
|
|
952
|
-
Assertion.addMethod('match', function (re, msg) {
|
|
1037
|
+
function assertMatch(re, msg) {
|
|
953
1038
|
if (msg) flag(this, 'message', msg);
|
|
954
1039
|
var obj = flag(this, 'object');
|
|
955
1040
|
this.assert(
|
|
@@ -957,7 +1042,10 @@ module.exports = function (chai, _) {
|
|
|
957
1042
|
, 'expected #{this} to match ' + re
|
|
958
1043
|
, 'expected #{this} not to match ' + re
|
|
959
1044
|
);
|
|
960
|
-
}
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
Assertion.addMethod('match', assertMatch);
|
|
1048
|
+
Assertion.addMethod('matches', assertMatch);
|
|
961
1049
|
|
|
962
1050
|
/**
|
|
963
1051
|
* ### .string(string)
|
|
@@ -989,32 +1077,32 @@ module.exports = function (chai, _) {
|
|
|
989
1077
|
* ### .keys(key1, [key2], [...])
|
|
990
1078
|
*
|
|
991
1079
|
* Asserts that the target contains any or all of the passed-in keys.
|
|
992
|
-
* Use in combination with `any`, `all`, `contains`, or `have` will affect
|
|
1080
|
+
* Use in combination with `any`, `all`, `contains`, or `have` will affect
|
|
993
1081
|
* what will pass.
|
|
994
|
-
*
|
|
995
|
-
* When used in conjunction with `any`, at least one key that is passed
|
|
996
|
-
* in must exist in the target object. This is regardless whether or not
|
|
1082
|
+
*
|
|
1083
|
+
* When used in conjunction with `any`, at least one key that is passed
|
|
1084
|
+
* in must exist in the target object. This is regardless whether or not
|
|
997
1085
|
* the `have` or `contain` qualifiers are used. Note, either `any` or `all`
|
|
998
1086
|
* should be used in the assertion. If neither are used, the assertion is
|
|
999
1087
|
* defaulted to `all`.
|
|
1000
|
-
*
|
|
1001
|
-
* When both `all` and `contain` are used, the target object must have at
|
|
1088
|
+
*
|
|
1089
|
+
* When both `all` and `contain` are used, the target object must have at
|
|
1002
1090
|
* least all of the passed-in keys but may have more keys not listed.
|
|
1003
|
-
*
|
|
1091
|
+
*
|
|
1004
1092
|
* When both `all` and `have` are used, the target object must both contain
|
|
1005
1093
|
* all of the passed-in keys AND the number of keys in the target object must
|
|
1006
|
-
* match the number of keys passed in (in other words, a target object must
|
|
1094
|
+
* match the number of keys passed in (in other words, a target object must
|
|
1007
1095
|
* have all and only all of the passed-in keys).
|
|
1008
|
-
*
|
|
1096
|
+
*
|
|
1009
1097
|
* expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');
|
|
1010
1098
|
* expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');
|
|
1011
1099
|
* expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');
|
|
1012
1100
|
* expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);
|
|
1013
1101
|
* expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});
|
|
1014
1102
|
* expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);
|
|
1015
|
-
* expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo'
|
|
1103
|
+
* expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});
|
|
1016
1104
|
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);
|
|
1017
|
-
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(
|
|
1105
|
+
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});
|
|
1018
1106
|
*
|
|
1019
1107
|
*
|
|
1020
1108
|
* @name keys
|
|
@@ -1206,7 +1294,7 @@ module.exports = function (chai, _) {
|
|
|
1206
1294
|
}
|
|
1207
1295
|
|
|
1208
1296
|
// next, check message
|
|
1209
|
-
var message = '
|
|
1297
|
+
var message = 'error' === _.type(err) && "message" in err
|
|
1210
1298
|
? err.message
|
|
1211
1299
|
: '' + err;
|
|
1212
1300
|
|
|
@@ -1280,12 +1368,13 @@ module.exports = function (chai, _) {
|
|
|
1280
1368
|
* expect(Klass).itself.to.respondTo('baz');
|
|
1281
1369
|
*
|
|
1282
1370
|
* @name respondTo
|
|
1371
|
+
* @alias respondsTo
|
|
1283
1372
|
* @param {String} method
|
|
1284
1373
|
* @param {String} message _optional_
|
|
1285
1374
|
* @api public
|
|
1286
1375
|
*/
|
|
1287
1376
|
|
|
1288
|
-
|
|
1377
|
+
function respondTo (method, msg) {
|
|
1289
1378
|
if (msg) flag(this, 'message', msg);
|
|
1290
1379
|
var obj = flag(this, 'object')
|
|
1291
1380
|
, itself = flag(this, 'itself')
|
|
@@ -1298,7 +1387,10 @@ module.exports = function (chai, _) {
|
|
|
1298
1387
|
, 'expected #{this} to respond to ' + _.inspect(method)
|
|
1299
1388
|
, 'expected #{this} to not respond to ' + _.inspect(method)
|
|
1300
1389
|
);
|
|
1301
|
-
}
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
Assertion.addMethod('respondTo', respondTo);
|
|
1393
|
+
Assertion.addMethod('respondsTo', respondTo);
|
|
1302
1394
|
|
|
1303
1395
|
/**
|
|
1304
1396
|
* ### .itself
|
|
@@ -1328,12 +1420,13 @@ module.exports = function (chai, _) {
|
|
|
1328
1420
|
* expect(1).to.satisfy(function(num) { return num > 0; });
|
|
1329
1421
|
*
|
|
1330
1422
|
* @name satisfy
|
|
1423
|
+
* @alias satisfies
|
|
1331
1424
|
* @param {Function} matcher
|
|
1332
1425
|
* @param {String} message _optional_
|
|
1333
1426
|
* @api public
|
|
1334
1427
|
*/
|
|
1335
1428
|
|
|
1336
|
-
|
|
1429
|
+
function satisfy (matcher, msg) {
|
|
1337
1430
|
if (msg) flag(this, 'message', msg);
|
|
1338
1431
|
var obj = flag(this, 'object');
|
|
1339
1432
|
var result = matcher(obj);
|
|
@@ -1344,7 +1437,10 @@ module.exports = function (chai, _) {
|
|
|
1344
1437
|
, this.negate ? false : true
|
|
1345
1438
|
, result
|
|
1346
1439
|
);
|
|
1347
|
-
}
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
Assertion.addMethod('satisfy', satisfy);
|
|
1443
|
+
Assertion.addMethod('satisfies', satisfy);
|
|
1348
1444
|
|
|
1349
1445
|
/**
|
|
1350
1446
|
* ### .closeTo(expected, delta)
|
|
@@ -1549,4 +1645,85 @@ module.exports = function (chai, _) {
|
|
|
1549
1645
|
Assertion.addChainableMethod('decrease', assertDecreases);
|
|
1550
1646
|
Assertion.addChainableMethod('decreases', assertDecreases);
|
|
1551
1647
|
|
|
1648
|
+
/**
|
|
1649
|
+
* ### .extensible
|
|
1650
|
+
*
|
|
1651
|
+
* Asserts that the target is extensible (can have new properties added to
|
|
1652
|
+
* it).
|
|
1653
|
+
*
|
|
1654
|
+
* var nonExtensibleObject = Object.preventExtensions({});
|
|
1655
|
+
* var sealedObject = Object.seal({});
|
|
1656
|
+
* var frozenObject = Object.freeze({});
|
|
1657
|
+
*
|
|
1658
|
+
* expect({}).to.be.extensible;
|
|
1659
|
+
* expect(nonExtensibleObject).to.not.be.extensible;
|
|
1660
|
+
* expect(sealedObject).to.not.be.extensible;
|
|
1661
|
+
* expect(frozenObject).to.not.be.extensible;
|
|
1662
|
+
*
|
|
1663
|
+
* @name extensible
|
|
1664
|
+
* @api public
|
|
1665
|
+
*/
|
|
1666
|
+
|
|
1667
|
+
Assertion.addProperty('extensible', function() {
|
|
1668
|
+
var obj = flag(this, 'object');
|
|
1669
|
+
|
|
1670
|
+
this.assert(
|
|
1671
|
+
Object.isExtensible(obj)
|
|
1672
|
+
, 'expected #{this} to be extensible'
|
|
1673
|
+
, 'expected #{this} to not be extensible'
|
|
1674
|
+
);
|
|
1675
|
+
});
|
|
1676
|
+
|
|
1677
|
+
/**
|
|
1678
|
+
* ### .sealed
|
|
1679
|
+
*
|
|
1680
|
+
* Asserts that the target is sealed (cannot have new properties added to it
|
|
1681
|
+
* and its existing properties cannot be removed).
|
|
1682
|
+
*
|
|
1683
|
+
* var sealedObject = Object.seal({});
|
|
1684
|
+
* var frozenObject = Object.freeze({});
|
|
1685
|
+
*
|
|
1686
|
+
* expect(sealedObject).to.be.sealed;
|
|
1687
|
+
* expect(frozenObject).to.be.sealed;
|
|
1688
|
+
* expect({}).to.not.be.sealed;
|
|
1689
|
+
*
|
|
1690
|
+
* @name sealed
|
|
1691
|
+
* @api public
|
|
1692
|
+
*/
|
|
1693
|
+
|
|
1694
|
+
Assertion.addProperty('sealed', function() {
|
|
1695
|
+
var obj = flag(this, 'object');
|
|
1696
|
+
|
|
1697
|
+
this.assert(
|
|
1698
|
+
Object.isSealed(obj)
|
|
1699
|
+
, 'expected #{this} to be sealed'
|
|
1700
|
+
, 'expected #{this} to not be sealed'
|
|
1701
|
+
);
|
|
1702
|
+
});
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* ### .frozen
|
|
1706
|
+
*
|
|
1707
|
+
* Asserts that the target is frozen (cannot have new properties added to it
|
|
1708
|
+
* and its existing properties cannot be modified).
|
|
1709
|
+
*
|
|
1710
|
+
* var frozenObject = Object.freeze({});
|
|
1711
|
+
*
|
|
1712
|
+
* expect(frozenObject).to.be.frozen;
|
|
1713
|
+
* expect({}).to.not.be.frozen;
|
|
1714
|
+
*
|
|
1715
|
+
* @name frozen
|
|
1716
|
+
* @api public
|
|
1717
|
+
*/
|
|
1718
|
+
|
|
1719
|
+
Assertion.addProperty('frozen', function() {
|
|
1720
|
+
var obj = flag(this, 'object');
|
|
1721
|
+
|
|
1722
|
+
this.assert(
|
|
1723
|
+
Object.isFrozen(obj)
|
|
1724
|
+
, 'expected #{this} to be frozen'
|
|
1725
|
+
, 'expected #{this} to not be frozen'
|
|
1726
|
+
);
|
|
1727
|
+
});
|
|
1728
|
+
|
|
1552
1729
|
};
|