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/karma.conf.js CHANGED
@@ -2,7 +2,7 @@ module.exports = function(config) {
2
2
  config.set({
3
3
  frameworks: [ 'mocha' ]
4
4
  , files: [
5
- 'build/build.js'
5
+ 'chai.js'
6
6
  , 'test/bootstrap/karma.js'
7
7
  , 'test/*.js'
8
8
  ]
@@ -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.to.be.null;
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 && undefined !== val) {
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 (undefined !== val) {
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
- * ### .length(value)
917
+ * ### .ownPropertyDescriptor(name[, descriptor[, message]])
893
918
  *
894
- * Asserts that the target's `length` property has
895
- * the expected value.
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
- * expect([ 1, 2, 3]).to.have.length(3);
898
- * expect('foobar').to.have.length(6);
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
- * Can also be used as a chain precursor to a value
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
- * @alias lengthOf
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', 7});
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([{'bar': 6}}]);
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 = 'object' === _.type(err) && "message" in err
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
- Assertion.addMethod('respondTo', function (method, msg) {
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
- Assertion.addMethod('satisfy', function (matcher, msg) {
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
  };