chai 2.1.1 → 3.0.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
  *
@@ -75,6 +75,12 @@ module.exports = function (chai, _) {
75
75
  * expect({ foo: { bar: { baz: 'quux' } } })
76
76
  * .to.have.deep.property('foo.bar.baz', 'quux');
77
77
  *
78
+ * `.deep.property` special characters can be escaped
79
+ * by adding two slashes before the `.` or `[]`.
80
+ *
81
+ * var deepCss = { '.link': { '[target]': 42 }};
82
+ * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42);
83
+ *
78
84
  * @name deep
79
85
  * @api public
80
86
  */
@@ -87,7 +93,7 @@ module.exports = function (chai, _) {
87
93
  * ### .any
88
94
  *
89
95
  * Sets the `any` flag, (opposite of the `all` flag)
90
- * later used in the `keys` assertion.
96
+ * later used in the `keys` assertion.
91
97
  *
92
98
  * expect(foo).to.have.any.keys('bar', 'baz');
93
99
  *
@@ -104,7 +110,7 @@ module.exports = function (chai, _) {
104
110
  /**
105
111
  * ### .all
106
112
  *
107
- * Sets the `all` flag (opposite of the `any` flag)
113
+ * Sets the `all` flag (opposite of the `any` flag)
108
114
  * later used by the `keys` assertion.
109
115
  *
110
116
  * expect(foo).to.have.all.keys('bar', 'baz');
@@ -130,6 +136,12 @@ module.exports = function (chai, _) {
130
136
  * expect({ foo: 'bar' }).to.be.an('object');
131
137
  * expect(null).to.be.a('null');
132
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');
133
145
  *
134
146
  * // language chain
135
147
  * expect(foo).to.be.an.instanceof(Foo);
@@ -285,7 +297,7 @@ module.exports = function (chai, _) {
285
297
  * Asserts that the target is `null`.
286
298
  *
287
299
  * expect(null).to.be.null;
288
- * expect(undefined).not.to.be.null;
300
+ * expect(undefined).to.not.be.null;
289
301
  *
290
302
  * @name null
291
303
  * @api public
@@ -761,7 +773,7 @@ module.exports = function (chai, _) {
761
773
  * green: { tea: 'matcha' }
762
774
  * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]
763
775
  * };
764
-
776
+ *
765
777
  * expect(deepObj).to.have.deep.property('green.tea', 'matcha');
766
778
  * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
767
779
  * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');
@@ -793,6 +805,18 @@ module.exports = function (chai, _) {
793
805
  * .with.deep.property('[2]')
794
806
  * .that.deep.equals({ tea: 'konacha' });
795
807
  *
808
+ * Note that dots and bracket in `name` must be backslash-escaped when
809
+ * the `deep` flag is set, while they must NOT be escaped when the `deep`
810
+ * flag is not set.
811
+ *
812
+ * // simple referencing
813
+ * var css = { '.link[target]': 42 };
814
+ * expect(css).to.have.property('.link[target]', 42);
815
+ *
816
+ * // deep referencing
817
+ * var deepCss = { '.link': { '[target]': 42 }};
818
+ * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42);
819
+ *
796
820
  * @name property
797
821
  * @alias deep.property
798
822
  * @param {String} name
@@ -817,7 +841,7 @@ module.exports = function (chai, _) {
817
841
  ? pathInfo.value
818
842
  : obj[name];
819
843
 
820
- if (negate && undefined !== val) {
844
+ if (negate && arguments.length > 1) {
821
845
  if (undefined === value) {
822
846
  msg = (msg != null) ? msg + ': ' : '';
823
847
  throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
@@ -829,7 +853,7 @@ module.exports = function (chai, _) {
829
853
  , 'expected #{this} to not have ' + descriptor + _.inspect(name));
830
854
  }
831
855
 
832
- if (undefined !== val) {
856
+ if (arguments.length > 1) {
833
857
  this.assert(
834
858
  val === value
835
859
  , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
@@ -871,16 +895,59 @@ module.exports = function (chai, _) {
871
895
  Assertion.addMethod('haveOwnProperty', assertOwnProperty);
872
896
 
873
897
  /**
874
- * ### .length(value)
898
+ * ### .ownPropertyDescriptor(name[, descriptor[, message]])
875
899
  *
876
- * Asserts that the target's `length` property has
877
- * the expected value.
900
+ * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.
901
+ *
902
+ * expect('test').to.have.ownPropertyDescriptor('length');
903
+ * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });
904
+ * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });
905
+ * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);
906
+ * expect('test').ownPropertyDescriptor('length').to.have.keys('value');
878
907
  *
879
- * expect([ 1, 2, 3]).to.have.length(3);
880
- * expect('foobar').to.have.length(6);
908
+ * @name ownPropertyDescriptor
909
+ * @alias haveOwnPropertyDescriptor
910
+ * @param {String} name
911
+ * @param {Object} descriptor _optional_
912
+ * @param {String} message _optional_
913
+ * @api public
914
+ */
915
+
916
+ function assertOwnPropertyDescriptor (name, descriptor, msg) {
917
+ if (typeof descriptor === 'string') {
918
+ msg = descriptor;
919
+ descriptor = null;
920
+ }
921
+ if (msg) flag(this, 'message', msg);
922
+ var obj = flag(this, 'object');
923
+ var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);
924
+ if (actualDescriptor && descriptor) {
925
+ this.assert(
926
+ _.eql(descriptor, actualDescriptor)
927
+ , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)
928
+ , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)
929
+ , descriptor
930
+ , actualDescriptor
931
+ , true
932
+ );
933
+ } else {
934
+ this.assert(
935
+ actualDescriptor
936
+ , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)
937
+ , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)
938
+ );
939
+ }
940
+ flag(this, 'object', actualDescriptor);
941
+ }
942
+
943
+ Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);
944
+ Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);
945
+
946
+ /**
947
+ * ### .length
881
948
  *
882
- * Can also be used as a chain precursor to a value
883
- * comparison for the length property.
949
+ * Sets the `doLength` flag later used as a chain precursor to a value
950
+ * comparison for the `length` property.
884
951
  *
885
952
  * expect('foo').to.have.length.above(2);
886
953
  * expect([ 1, 2, 3 ]).to.have.length.above(2);
@@ -889,8 +956,25 @@ module.exports = function (chai, _) {
889
956
  * expect('foo').to.have.length.within(2,4);
890
957
  * expect([ 1, 2, 3 ]).to.have.length.within(2,4);
891
958
  *
959
+ * *Deprecation notice:* Using `length` as an assertion will be deprecated
960
+ * in version 2.4.0 and removed in 3.0.0. Code using the old style of
961
+ * asserting for `length` property value using `length(value)` should be
962
+ * switched to use `lengthOf(value)` instead.
963
+ *
892
964
  * @name length
893
- * @alias lengthOf
965
+ * @api public
966
+ */
967
+
968
+ /**
969
+ * ### .lengthOf(value[, message])
970
+ *
971
+ * Asserts that the target's `length` property has
972
+ * the expected value.
973
+ *
974
+ * expect([ 1, 2, 3]).to.have.lengthOf(3);
975
+ * expect('foobar').to.have.lengthOf(6);
976
+ *
977
+ * @name lengthOf
894
978
  * @param {Number} length
895
979
  * @param {String} message _optional_
896
980
  * @api public
@@ -926,12 +1010,12 @@ module.exports = function (chai, _) {
926
1010
  * expect('foobar').to.match(/^foo/);
927
1011
  *
928
1012
  * @name match
1013
+ * @alias matches
929
1014
  * @param {RegExp} RegularExpression
930
1015
  * @param {String} message _optional_
931
1016
  * @api public
932
1017
  */
933
-
934
- Assertion.addMethod('match', function (re, msg) {
1018
+ function assertMatch(re, msg) {
935
1019
  if (msg) flag(this, 'message', msg);
936
1020
  var obj = flag(this, 'object');
937
1021
  this.assert(
@@ -939,7 +1023,10 @@ module.exports = function (chai, _) {
939
1023
  , 'expected #{this} to match ' + re
940
1024
  , 'expected #{this} not to match ' + re
941
1025
  );
942
- });
1026
+ }
1027
+
1028
+ Assertion.addMethod('match', assertMatch);
1029
+ Assertion.addMethod('matches', assertMatch);
943
1030
 
944
1031
  /**
945
1032
  * ### .string(string)
@@ -971,32 +1058,32 @@ module.exports = function (chai, _) {
971
1058
  * ### .keys(key1, [key2], [...])
972
1059
  *
973
1060
  * Asserts that the target contains any or all of the passed-in keys.
974
- * Use in combination with `any`, `all`, `contains`, or `have` will affect
1061
+ * Use in combination with `any`, `all`, `contains`, or `have` will affect
975
1062
  * what will pass.
976
- *
977
- * When used in conjunction with `any`, at least one key that is passed
978
- * in must exist in the target object. This is regardless whether or not
1063
+ *
1064
+ * When used in conjunction with `any`, at least one key that is passed
1065
+ * in must exist in the target object. This is regardless whether or not
979
1066
  * the `have` or `contain` qualifiers are used. Note, either `any` or `all`
980
1067
  * should be used in the assertion. If neither are used, the assertion is
981
1068
  * defaulted to `all`.
982
- *
983
- * When both `all` and `contain` are used, the target object must have at
1069
+ *
1070
+ * When both `all` and `contain` are used, the target object must have at
984
1071
  * least all of the passed-in keys but may have more keys not listed.
985
- *
1072
+ *
986
1073
  * When both `all` and `have` are used, the target object must both contain
987
1074
  * all of the passed-in keys AND the number of keys in the target object must
988
- * match the number of keys passed in (in other words, a target object must
1075
+ * match the number of keys passed in (in other words, a target object must
989
1076
  * have all and only all of the passed-in keys).
990
- *
1077
+ *
991
1078
  * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');
992
1079
  * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');
993
1080
  * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');
994
1081
  * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);
995
1082
  * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});
996
1083
  * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);
997
- * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo', 7});
1084
+ * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});
998
1085
  * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);
999
- * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys([{'bar': 6}}]);
1086
+ * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});
1000
1087
  *
1001
1088
  *
1002
1089
  * @name keys
@@ -1188,7 +1275,7 @@ module.exports = function (chai, _) {
1188
1275
  }
1189
1276
 
1190
1277
  // next, check message
1191
- var message = 'object' === _.type(err) && "message" in err
1278
+ var message = 'error' === _.type(err) && "message" in err
1192
1279
  ? err.message
1193
1280
  : '' + err;
1194
1281
 
@@ -700,7 +700,7 @@ module.exports = function (chai, util) {
700
700
  *
701
701
  * Asserts that `haystack` does not include `needle`. Works
702
702
  * for strings and arrays.
703
- *i
703
+ *
704
704
  * assert.notInclude('foobar', 'baz', 'string not include substring');
705
705
  * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');
706
706
  *
@@ -1004,10 +1004,36 @@ module.exports = function (chai, util) {
1004
1004
  */
1005
1005
 
1006
1006
  assert.operator = function (val, operator, val2, msg) {
1007
- if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
1008
- throw new Error('Invalid operator "' + operator + '"');
1007
+ var ok;
1008
+ switch(operator) {
1009
+ case '==':
1010
+ ok = val == val2;
1011
+ break;
1012
+ case '===':
1013
+ ok = val === val2;
1014
+ break;
1015
+ case '>':
1016
+ ok = val > val2;
1017
+ break;
1018
+ case '>=':
1019
+ ok = val >= val2;
1020
+ break;
1021
+ case '<':
1022
+ ok = val < val2;
1023
+ break;
1024
+ case '<=':
1025
+ ok = val <= val2;
1026
+ break;
1027
+ case '!=':
1028
+ ok = val != val2;
1029
+ break;
1030
+ case '!==':
1031
+ ok = val !== val2;
1032
+ break;
1033
+ default:
1034
+ throw new Error('Invalid operator "' + operator + '"');
1009
1035
  }
1010
- var test = new Assertion(eval(val + operator + val2), msg);
1036
+ var test = new Assertion(ok, msg);
1011
1037
  test.assert(
1012
1038
  true === flag(test, 'object')
1013
1039
  , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
@@ -1217,11 +1243,24 @@ module.exports = function (chai, util) {
1217
1243
  }
1218
1244
 
1219
1245
  /*!
1220
- * Undocumented / untested
1246
+ * ### .ifError(object)
1247
+ *
1248
+ * Asserts if value is not a false value, and throws if it is a true value.
1249
+ * This is added to allow for chai to be a drop-in replacement for Node's
1250
+ * assert class.
1251
+ *
1252
+ * var err = new Error('I am a custom error');
1253
+ * assert.ifError(err); // Rethrows err!
1254
+ *
1255
+ * @name ifError
1256
+ * @param {Object} object
1257
+ * @api public
1221
1258
  */
1222
1259
 
1223
- assert.ifError = function (val, msg) {
1224
- new Assertion(val, msg).to.not.be.ok;
1260
+ assert.ifError = function (val) {
1261
+ if (val) {
1262
+ throw(val);
1263
+ }
1225
1264
  };
1226
1265
 
1227
1266
  /*!
@@ -34,7 +34,7 @@ module.exports = function getPathInfo(path, obj) {
34
34
  var info = {
35
35
  parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,
36
36
  name: last.p || last.i,
37
- value: _getPathValue(parsed, obj),
37
+ value: _getPathValue(parsed, obj)
38
38
  };
39
39
  info.exists = hasProperty(info.name, info.parent);
40
40
 
@@ -54,6 +54,7 @@ module.exports = function getPathInfo(path, obj) {
54
54
  *
55
55
  * * Can be as near infinitely deep and nested
56
56
  * * Arrays are also valid using the formal `myobject.document[3].property`.
57
+ * * Literal dots and brackets (not delimiter) must be backslash-escaped.
57
58
  *
58
59
  * @param {String} path
59
60
  * @returns {Object} parsed
@@ -61,13 +62,13 @@ module.exports = function getPathInfo(path, obj) {
61
62
  */
62
63
 
63
64
  function parsePath (path) {
64
- var str = path.replace(/\[/g, '.[')
65
+ var str = path.replace(/([^\\])\[/g, '$1.[')
65
66
  , parts = str.match(/(\\\.|[^.]+?)+/g);
66
67
  return parts.map(function (value) {
67
- var re = /\[(\d+)\]$/
68
+ var re = /^\[(\d+)\]$/
68
69
  , mArr = re.exec(value);
69
70
  if (mArr) return { i: parseFloat(mArr[1]) };
70
- else return { p: value };
71
+ else return { p: value.replace(/\\([.\[\]])/g, '$1') };
71
72
  });
72
73
  }
73
74
 
@@ -4,7 +4,7 @@
4
4
  * MIT Licensed
5
5
  */
6
6
 
7
- var type = require('./type');
7
+ var type = require('type-detect');
8
8
 
9
9
  /**
10
10
  * ### .hasProperty(object, name)
@@ -20,7 +20,7 @@ exports.test = require('./test');
20
20
  * type utility
21
21
  */
22
22
 
23
- exports.type = require('./type');
23
+ exports.type = require('type-detect');
24
24
 
25
25
  /*!
26
26
  * message utility
package/lib/chai.js CHANGED
@@ -11,7 +11,7 @@ var used = []
11
11
  * Chai version
12
12
  */
13
13
 
14
- exports.version = '2.1.1';
14
+ exports.version = '3.0.0';
15
15
 
16
16
  /*!
17
17
  * Assertion Error
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "Veselin Todorov <hi@vesln.com>",
18
18
  "John Firebaugh <john.firebaugh@gmail.com>"
19
19
  ],
20
- "version": "2.1.1",
20
+ "version": "3.0.0",
21
21
  "repository": {
22
22
  "type": "git",
23
23
  "url": "https://github.com/chaijs/chai"
@@ -33,16 +33,19 @@
33
33
  "node": ">= 0.4.0"
34
34
  },
35
35
  "dependencies": {
36
- "assertion-error": "1.0.0",
37
- "deep-eql": "0.1.3"
36
+ "assertion-error": "^1.0.1",
37
+ "deep-eql": "^0.1.3",
38
+ "type-detect": "^1.0.0"
38
39
  },
39
40
  "devDependencies": {
40
- "component": "*",
41
- "karma": "0.12.x",
42
- "karma-mocha": "*",
43
- "karma-sauce-launcher": "0.2.x",
44
- "karma-phantomjs-launcher": "0.1.1",
45
- "mocha": "1.21.x",
46
- "istanbul": "0.2.x"
41
+ "browserify": "^10.2.1",
42
+ "bump-cli": "^1.1.3",
43
+ "karma": "^0.12.0",
44
+ "karma-mocha": "^0.1.10",
45
+ "karma-sauce-launcher": "^0.2.11",
46
+ "karma-phantomjs-launcher": "^0.2.0",
47
+ "karma-firefox-launcher": "^0.1.6",
48
+ "mocha": "^2.2.5",
49
+ "istanbul": "^0.3.14"
47
50
  }
48
51
  }
@@ -1,45 +0,0 @@
1
- /*!
2
- * Chai - type utility
3
- * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
4
- * MIT Licensed
5
- */
6
-
7
- /*!
8
- * Detectable javascript natives
9
- */
10
-
11
- var natives = {
12
- '[object Arguments]': 'arguments'
13
- , '[object Array]': 'array'
14
- , '[object Date]': 'date'
15
- , '[object Function]': 'function'
16
- , '[object Number]': 'number'
17
- , '[object RegExp]': 'regexp'
18
- , '[object String]': 'string'
19
- };
20
-
21
- /**
22
- * ### type(object)
23
- *
24
- * Better implementation of `typeof` detection that can
25
- * be used cross-browser. Handles the inconsistencies of
26
- * Array, `null`, and `undefined` detection.
27
- *
28
- * utils.type({}) // 'object'
29
- * utils.type(null) // `null'
30
- * utils.type(undefined) // `undefined`
31
- * utils.type([]) // `array`
32
- *
33
- * @param {Mixed} object to detect type of
34
- * @name type
35
- * @api private
36
- */
37
-
38
- module.exports = function (obj) {
39
- var str = Object.prototype.toString.call(obj);
40
- if (natives[str]) return natives[str];
41
- if (obj === null) return 'null';
42
- if (obj === undefined) return 'undefined';
43
- if (obj === Object(obj)) return 'object';
44
- return typeof obj;
45
- };