mocha_rails 0.0.3 → 0.0.4

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.
@@ -79,11 +79,19 @@ require.register("assertion.js", function(module, exports, require){
79
79
  * #### Differences
80
80
  *
81
81
  * The `expect` interface provides a function as a starting point for chaining
82
- * your language assertions. It works on both node.js and in the browser.
82
+ * your language assertions. It works on node.js and in all browsers.
83
83
  *
84
84
  * The `should` interface extends `Object.prototype` to provide a single getter as
85
- * the starting point for your language assertions. Most browser don't like
86
- * extensions to `Object.prototype` so it is not recommended for browser use.
85
+ * the starting point for your language assertions. It works on node.js and in
86
+ * all browsers except Internet Explorer.
87
+ *
88
+ * #### Configuration
89
+ *
90
+ * By default, Chai does not show stack traces upon an AssertionError. This can
91
+ * be changed by modifying the `includeStack` parameter for chai.Assertion. For example:
92
+ *
93
+ * var chai = require('chai');
94
+ * chai.Assertion.includeStack = true; // defaults to false
87
95
  */
88
96
 
89
97
  /*!
@@ -92,6 +100,7 @@ require.register("assertion.js", function(module, exports, require){
92
100
 
93
101
  var AssertionError = require('./error')
94
102
  , eql = require('./utils/eql')
103
+ , toString = Object.prototype.toString
95
104
  , inspect = require('./utils/inspect');
96
105
 
97
106
  /*!
@@ -100,6 +109,7 @@ var AssertionError = require('./error')
100
109
 
101
110
  module.exports = Assertion;
102
111
 
112
+
103
113
  /*!
104
114
  * # Assertion Constructor
105
115
  *
@@ -115,7 +125,22 @@ function Assertion (obj, msg, stack) {
115
125
  }
116
126
 
117
127
  /*!
118
- * # .assert(expression, message, negateMessage)
128
+ * ## Assertion.includeStack
129
+ * , toString = Object.prototype.toString
130
+ *
131
+ * User configurable property, influences whether stack trace
132
+ * is included in Assertion error message. Default of false
133
+ * suppresses stack trace in the error message
134
+ *
135
+ * Assertion.includeStack = true; // enable stack on error
136
+ *
137
+ * @api public
138
+ */
139
+
140
+ Assertion.includeStack = false;
141
+
142
+ /*!
143
+ * # .assert(expression, message, negateMessage, expected, actual)
119
144
  *
120
145
  * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
121
146
  *
@@ -123,18 +148,22 @@ function Assertion (obj, msg, stack) {
123
148
  * @param {Philosophical} expression to be tested
124
149
  * @param {String} message to display if fails
125
150
  * @param {String} negatedMessage to display if negated expression fails
126
- * @api privage
151
+ * @param {*} expected value (remember to check for negation)
152
+ * @param {*} actual (optional) will default to `this.obj`
153
+ * @api private
127
154
  */
128
155
 
129
- Assertion.prototype.assert = function (expr, msg, negateMsg) {
156
+ Assertion.prototype.assert = function (expr, msg, negateMsg, expected, actual) {
157
+ actual = actual || this.obj;
130
158
  var msg = (this.negate ? negateMsg : msg)
131
159
  , ok = this.negate ? !expr : expr;
132
160
 
133
161
  if (!ok) {
134
162
  throw new AssertionError({
135
- operator: this.msg,
136
- message: msg,
137
- stackStartFunction: this.ssfi
163
+ message: this.msg ? this.msg + ': ' + msg : msg // include custom message if available
164
+ , actual: actual
165
+ , expected: expected
166
+ , stackStartFunction: (Assertion.includeStack) ? this.assert : this.ssfi
138
167
  });
139
168
  }
140
169
  };
@@ -152,6 +181,7 @@ Object.defineProperty(Assertion.prototype, 'inspect',
152
181
  { get: function () {
153
182
  return inspect(this.obj);
154
183
  }
184
+ , configurable: true
155
185
  });
156
186
 
157
187
  /**
@@ -167,6 +197,7 @@ Object.defineProperty(Assertion.prototype, 'to',
167
197
  { get: function () {
168
198
  return this;
169
199
  }
200
+ , configurable: true
170
201
  });
171
202
 
172
203
  /**
@@ -182,6 +213,7 @@ Object.defineProperty(Assertion.prototype, 'be',
182
213
  { get: function () {
183
214
  return this;
184
215
  }
216
+ , configurable: true
185
217
  });
186
218
 
187
219
  /**
@@ -199,6 +231,7 @@ Object.defineProperty(Assertion.prototype, 'been',
199
231
  this.tense = 'past';
200
232
  return this;
201
233
  }
234
+ , configurable: true
202
235
  });
203
236
 
204
237
  /**
@@ -214,6 +247,7 @@ Object.defineProperty(Assertion.prototype, 'an',
214
247
  { get: function () {
215
248
  return this;
216
249
  }
250
+ , configurable: true
217
251
  });
218
252
  /**
219
253
  * # is
@@ -228,6 +262,7 @@ Object.defineProperty(Assertion.prototype, 'is',
228
262
  { get: function () {
229
263
  return this;
230
264
  }
265
+ , configurable: true
231
266
  });
232
267
 
233
268
  /**
@@ -243,6 +278,7 @@ Object.defineProperty(Assertion.prototype, 'and',
243
278
  { get: function () {
244
279
  return this;
245
280
  }
281
+ , configurable: true
246
282
  });
247
283
 
248
284
  /**
@@ -258,6 +294,7 @@ Object.defineProperty(Assertion.prototype, 'have',
258
294
  { get: function () {
259
295
  return this;
260
296
  }
297
+ , configurable: true
261
298
  });
262
299
 
263
300
  /**
@@ -273,6 +310,7 @@ Object.defineProperty(Assertion.prototype, 'with',
273
310
  { get: function () {
274
311
  return this;
275
312
  }
313
+ , configurable: true
276
314
  });
277
315
 
278
316
  /**
@@ -289,6 +327,7 @@ Object.defineProperty(Assertion.prototype, 'not',
289
327
  this.negate = true;
290
328
  return this;
291
329
  }
330
+ , configurable: true
292
331
  });
293
332
 
294
333
  /**
@@ -310,10 +349,11 @@ Object.defineProperty(Assertion.prototype, 'ok',
310
349
  this.assert(
311
350
  this.obj
312
351
  , 'expected ' + this.inspect + ' to be truthy'
313
- , 'expected ' + this.inspect + ' to be falsey');
352
+ , 'expected ' + this.inspect + ' to be falsy');
314
353
 
315
354
  return this;
316
355
  }
356
+ , configurable: true
317
357
  });
318
358
 
319
359
  /**
@@ -330,10 +370,13 @@ Object.defineProperty(Assertion.prototype, 'true',
330
370
  this.assert(
331
371
  true === this.obj
332
372
  , 'expected ' + this.inspect + ' to be true'
333
- , 'expected ' + this.inspect + ' to be false');
373
+ , 'expected ' + this.inspect + ' to be false'
374
+ , this.negate ? false : true
375
+ );
334
376
 
335
377
  return this;
336
378
  }
379
+ , configurable: true
337
380
  });
338
381
 
339
382
  /**
@@ -350,10 +393,13 @@ Object.defineProperty(Assertion.prototype, 'false',
350
393
  this.assert(
351
394
  false === this.obj
352
395
  , 'expected ' + this.inspect + ' to be false'
353
- , 'expected ' + this.inspect + ' to be true');
396
+ , 'expected ' + this.inspect + ' to be true'
397
+ , this.negate ? true : false
398
+ );
354
399
 
355
400
  return this;
356
401
  }
402
+ , configurable: true
357
403
  });
358
404
 
359
405
  /**
@@ -375,10 +421,12 @@ Object.defineProperty(Assertion.prototype, 'exist',
375
421
  this.assert(
376
422
  null != this.obj
377
423
  , 'expected ' + this.inspect + ' to exist'
378
- , 'expected ' + this.inspect + ' to not exist');
424
+ , 'expected ' + this.inspect + ' to not exist'
425
+ );
379
426
 
380
427
  return this;
381
428
  }
429
+ , configurable: true
382
430
  });
383
431
 
384
432
  /**
@@ -394,15 +442,22 @@ Object.defineProperty(Assertion.prototype, 'exist',
394
442
 
395
443
  Object.defineProperty(Assertion.prototype, 'empty',
396
444
  { get: function () {
397
- new Assertion(this.obj).to.have.property('length');
445
+ var expected = this.obj;
446
+
447
+ if (Array.isArray(this.obj)) {
448
+ expected = this.obj.length;
449
+ } else if (typeof this.obj === 'object') {
450
+ expected = Object.keys(this.obj).length;
451
+ }
398
452
 
399
453
  this.assert(
400
- 0 === this.obj.length
454
+ !expected
401
455
  , 'expected ' + this.inspect + ' to be empty'
402
456
  , 'expected ' + this.inspect + ' not to be empty');
403
457
 
404
458
  return this;
405
459
  }
460
+ , configurable: true
406
461
  });
407
462
 
408
463
  /**
@@ -423,10 +478,14 @@ Object.defineProperty(Assertion.prototype, 'arguments',
423
478
  this.assert(
424
479
  '[object Arguments]' == Object.prototype.toString.call(this.obj)
425
480
  , 'expected ' + this.inspect + ' to be arguments'
426
- , 'expected ' + this.inspect + ' to not be arguments');
481
+ , 'expected ' + this.inspect + ' to not be arguments'
482
+ , '[object Arguments]'
483
+ , Object.prototype.toString.call(this.obj)
484
+ );
427
485
 
428
486
  return this;
429
487
  }
488
+ , configurable: true
430
489
  });
431
490
 
432
491
  /**
@@ -445,7 +504,8 @@ Assertion.prototype.equal = function (val) {
445
504
  this.assert(
446
505
  val === this.obj
447
506
  , 'expected ' + this.inspect + ' to equal ' + inspect(val)
448
- , 'expected ' + this.inspect + ' to not equal ' + inspect(val));
507
+ , 'expected ' + this.inspect + ' to not equal ' + inspect(val)
508
+ , val );
449
509
 
450
510
  return this;
451
511
  };
@@ -466,7 +526,9 @@ Assertion.prototype.eql = function (obj) {
466
526
  this.assert(
467
527
  eql(obj, this.obj)
468
528
  , 'expected ' + this.inspect + ' to equal ' + inspect(obj)
469
- , 'expected ' + this.inspect + ' to not equal ' + inspect(obj));
529
+ , 'expected ' + this.inspect + ' to not equal ' + inspect(obj)
530
+ , obj );
531
+
470
532
  return this;
471
533
  };
472
534
 
@@ -549,10 +611,15 @@ Assertion.prototype.within = function (start, finish) {
549
611
  */
550
612
 
551
613
  Assertion.prototype.a = function (type) {
614
+ var klass = type.charAt(0).toUpperCase() + type.slice(1);
615
+
552
616
  this.assert(
553
- type == typeof this.obj
617
+ '[object ' + klass + ']' === toString.call(this.obj)
554
618
  , 'expected ' + this.inspect + ' to be a ' + type
555
- , 'expected ' + this.inspect + ' not to be a ' + type);
619
+ , 'expected ' + this.inspect + ' not to be a ' + type
620
+ , '[object ' + klass + ']'
621
+ , toString.call(this.obj)
622
+ );
556
623
 
557
624
  return this;
558
625
  };
@@ -617,7 +684,10 @@ Assertion.prototype.property = function (name, val) {
617
684
  val === this.obj[name]
618
685
  , 'expected ' + this.inspect + ' to have a property ' + inspect(name) + ' of ' +
619
686
  inspect(val) + ', but got ' + inspect(this.obj[name])
620
- , 'expected ' + this.inspect + ' to not have a property ' + inspect(name) + ' of ' + inspect(val));
687
+ , 'expected ' + this.inspect + ' to not have a property ' + inspect(name) + ' of ' + inspect(val)
688
+ , val
689
+ , this.obj[val]
690
+ );
621
691
  }
622
692
 
623
693
  this.obj = this.obj[name];
@@ -666,7 +736,10 @@ Assertion.prototype.length = function (n) {
666
736
  this.assert(
667
737
  len == n
668
738
  , 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len
669
- , 'expected ' + this.inspect + ' to not have a length of ' + len);
739
+ , 'expected ' + this.inspect + ' to not have a length of ' + len
740
+ , n
741
+ , len
742
+ );
670
743
 
671
744
  return this;
672
745
  };
@@ -697,7 +770,7 @@ Assertion.prototype.match = function (re) {
697
770
  *
698
771
  * Assert the inclusion of an object in an Array or substring in string.
699
772
  *
700
- * expect([1,2,3]).to.contain(2);
773
+ * expect([1,2,3]).to.include(2);
701
774
  *
702
775
  * @name include
703
776
  * @param {Object|String|Number} obj
@@ -718,7 +791,7 @@ Assertion.prototype.include = function (obj) {
718
791
  *
719
792
  * Assert inclusion of string in string.
720
793
  *
721
- * expect('foobar').to.include.string('bar');
794
+ * expect('foobar').to.have.string('bar');
722
795
  *
723
796
  * @name string
724
797
  * @param {String} string
@@ -751,7 +824,8 @@ Object.defineProperty(Assertion.prototype, 'contain',
751
824
  { get: function () {
752
825
  this.contains = true;
753
826
  return this;
754
- }
827
+ },
828
+ configurable: true
755
829
  });
756
830
 
757
831
  /**
@@ -812,7 +886,10 @@ Assertion.prototype.keys = function(keys) {
812
886
  this.assert(
813
887
  ok
814
888
  , 'expected ' + this.inspect + ' to ' + str
815
- , 'expected ' + this.inspect + ' to not ' + str);
889
+ , 'expected ' + this.inspect + ' to not ' + str
890
+ , keys
891
+ , Object.keys(this.obj)
892
+ );
816
893
 
817
894
  return this;
818
895
  }
@@ -820,10 +897,21 @@ Assertion.prototype.keys = function(keys) {
820
897
  /**
821
898
  * # .throw(constructor)
822
899
  *
823
- * Assert that a function will throw a specific type of error.
900
+ * Assert that a function will throw a specific type of error or that error
901
+ * thrown will match a RegExp or include a string.
824
902
  *
825
- * var fn = function () { throw new ReferenceError(''); }
903
+ * var fn = function () { throw new ReferenceError('This is a bad function.'); }
826
904
  * expect(fn).to.throw(ReferenceError);
905
+ * expect(fn).to.throw(/bad function/);
906
+ * expect(fn).to.not.throw('good function');
907
+ * expect(fn).to.throw(ReferenceError, /bad function/);
908
+ *
909
+ * Please note that when a throw expectation is negated, it will check each
910
+ * parameter independently, starting with Error constructor type. The appropriate way
911
+ * to check for the existence of a type of error but for a message that does not match
912
+ * is to use `and`.
913
+ *
914
+ * expect(fn).to.throw(ReferenceError).and.not.throw(/good function/);
827
915
  *
828
916
  * @name throw
829
917
  * @alias throws
@@ -833,25 +921,44 @@ Assertion.prototype.keys = function(keys) {
833
921
  * @api public
834
922
  */
835
923
 
836
- Assertion.prototype.throw = function (constructor) {
924
+ Assertion.prototype.throw = function (constructor, msg) {
837
925
  new Assertion(this.obj).is.a('function');
838
926
 
839
927
  var thrown = false;
840
928
 
929
+ if (arguments.length === 0) {
930
+ msg = null;
931
+ constructor = null;
932
+ } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
933
+ msg = constructor;
934
+ constructor = null;
935
+ }
936
+
841
937
  try {
842
938
  this.obj();
843
939
  } catch (err) {
844
- if (constructor && 'function' === typeof constructor && constructor.constructor != RegExp) {
940
+ // first, check constructor
941
+ if (constructor && 'function' === typeof constructor) {
845
942
  this.assert(
846
943
  err instanceof constructor && err.name == constructor.name
847
944
  , 'expected ' + this.inspect + ' to throw ' + constructor.name + ' but a ' + err.name + ' was thrown'
848
945
  , 'expected ' + this.inspect + ' to not throw ' + constructor.name );
946
+ if (!msg) return this;
947
+ }
948
+ // next, check message
949
+ if (err.message && msg && msg instanceof RegExp) {
950
+ this.assert(
951
+ msg.exec(err.message)
952
+ , 'expected ' + this.inspect + ' to throw error matching ' + msg + ' but got ' + inspect(err.message)
953
+ , 'expected ' + this.inspect + ' to throw error not matching ' + msg
954
+ );
849
955
  return this;
850
- } else if (constructor && constructor instanceof RegExp) {
956
+ } else if (err.message && msg && 'string' === typeof msg) {
851
957
  this.assert(
852
- constructor.exec(err.message)
853
- , 'expected ' + this.inspect + ' to throw error matching ' + constructor + ' but got ' + inspect(err.message)
854
- , 'expected ' + this.inspect + ' to throw error not matching ' + constructor);
958
+ ~err.message.indexOf(msg)
959
+ , 'expected ' + this.inspect + ' to throw error including ' + inspect(msg) + ' but got ' + inspect(err.message)
960
+ , 'expected ' + this.inspect + ' to throw error not including ' + inspect(msg)
961
+ );
855
962
  return this;
856
963
  } else {
857
964
  thrown = true;
@@ -868,6 +975,81 @@ Assertion.prototype.throw = function (constructor) {
868
975
  return this;
869
976
  };
870
977
 
978
+ /**
979
+ * # .respondTo(method)
980
+ *
981
+ * Assert that object/class will respond to a method.
982
+ *
983
+ * expect(Klass).to.respondTo('bar');
984
+ * expect(obj).to.respondTo('bar');
985
+ *
986
+ * @name respondTo
987
+ * @param {String} method
988
+ * @api public
989
+ */
990
+
991
+ Assertion.prototype.respondTo = function (method) {
992
+ var context = ('function' === typeof this.obj)
993
+ ? this.obj.prototype[method]
994
+ : this.obj[method];
995
+
996
+ this.assert(
997
+ 'function' === typeof context
998
+ , 'expected ' + this.inspect + ' to respond to ' + inspect(method)
999
+ , 'expected ' + this.inspect + ' to not respond to ' + inspect(method)
1000
+ , 'function'
1001
+ , typeof context
1002
+ );
1003
+
1004
+ return this;
1005
+ };
1006
+
1007
+ /**
1008
+ * # .satisfy(method)
1009
+ *
1010
+ * Assert that passes a truth test.
1011
+ *
1012
+ * expect(1).to.satisfy(function(num) { return num > 0; });
1013
+ *
1014
+ * @name satisfy
1015
+ * @param {Function} matcher
1016
+ * @api public
1017
+ */
1018
+
1019
+ Assertion.prototype.satisfy = function (matcher) {
1020
+ this.assert(
1021
+ matcher(this.obj)
1022
+ , 'expected ' + this.inspect + ' to satisfy ' + inspect(matcher)
1023
+ , 'expected ' + this.inspect + ' to not satisfy' + inspect(matcher)
1024
+ , this.negate ? false : true
1025
+ , matcher(this.obj)
1026
+ );
1027
+
1028
+ return this;
1029
+ };
1030
+
1031
+ /**
1032
+ * # .closeTo(expected, delta)
1033
+ *
1034
+ * Assert that actual is equal to +/- delta.
1035
+ *
1036
+ * expect(1.5).to.be.closeTo(1, 0.5);
1037
+ *
1038
+ * @name closeTo
1039
+ * @param {Number} expected
1040
+ * @param {Number} delta
1041
+ * @api public
1042
+ */
1043
+
1044
+ Assertion.prototype.closeTo = function (expected, delta) {
1045
+ this.assert(
1046
+ (this.obj - delta === expected) || (this.obj + delta === expected)
1047
+ , 'expected ' + this.inspect + ' to be close to ' + expected + ' +/- ' + delta
1048
+ , 'expected ' + this.inspect + ' not to be close to ' + expected + ' +/- ' + delta);
1049
+
1050
+ return this;
1051
+ };
1052
+
871
1053
  /*!
872
1054
  * Aliases.
873
1055
  */
@@ -897,7 +1079,7 @@ require.register("chai.js", function(module, exports, require){
897
1079
  var used = [];
898
1080
  var exports = module.exports = {};
899
1081
 
900
- exports.version = '0.3.2';
1082
+ exports.version = '0.5.2';
901
1083
 
902
1084
  exports.Assertion = require('./assertion');
903
1085
  exports.AssertionError = require('./error');
@@ -913,16 +1095,6 @@ exports.use = function (fn) {
913
1095
  return this;
914
1096
  };
915
1097
 
916
- exports.fail = function (actual, expected, message, operator, stackStartFunction) {
917
- throw new exports.AssertionError({
918
- message: message,
919
- actual: actual,
920
- expected: expected,
921
- operator: operator,
922
- stackStartFunction: stackStartFunction
923
- });
924
- };
925
-
926
1098
  var expect = require('./interface/expect');
927
1099
  exports.use(expect);
928
1100
 
@@ -965,25 +1137,10 @@ function AssertionError (options) {
965
1137
 
966
1138
  AssertionError.prototype.__proto__ = Error.prototype;
967
1139
 
968
- AssertionError.prototype.summary = function() {
969
- var str = '';
970
-
971
- if (this.operator) {
972
- str += 'In: \'' + this.operator + '\'\n\t';
973
- }
974
-
975
- str += '' + this.name + (this.message ? ': ' + this.message : '');
976
-
977
- return str;
978
- };
979
-
980
- AssertionError.prototype.details = function() {
981
- return this.summary();
982
- };
983
-
984
1140
  AssertionError.prototype.toString = function() {
985
- return this.summary();
1141
+ return this.message;
986
1142
  };
1143
+
987
1144
  }); // module: error.js
988
1145
 
989
1146
  require.register("interface/assert.js", function(module, exports, require){
@@ -1007,6 +1164,14 @@ require.register("interface/assert.js", function(module, exports, require){
1007
1164
  *
1008
1165
  * assert.typeOf(foo, 'string');
1009
1166
  * assert.equal(foo, 'bar');
1167
+ *
1168
+ * #### Configuration
1169
+ *
1170
+ * By default, Chai does not show stack traces upon an AssertionError. This can
1171
+ * be changed by modifying the `includeStack` parameter for chai.Assertion. For example:
1172
+ *
1173
+ * var chai = require('chai');
1174
+ * chai.Assertion.includeStack = true; // defaults to false
1010
1175
  */
1011
1176
 
1012
1177
  module.exports = function (chai) {
@@ -1022,6 +1187,29 @@ module.exports = function (chai) {
1022
1187
 
1023
1188
  var assert = chai.assert = {};
1024
1189
 
1190
+ /**
1191
+ * # .fail(actual, expect, msg, operator)
1192
+ *
1193
+ * Throw a failure. Node.js compatible.
1194
+ *
1195
+ * @name fail
1196
+ * @param {*} actual value
1197
+ * @param {*} expected value
1198
+ * @param {String} message
1199
+ * @param {String} operator
1200
+ * @api public
1201
+ */
1202
+
1203
+ assert.fail = function (actual, expected, message, operator) {
1204
+ throw new chai.AssertionError({
1205
+ actual: actual
1206
+ , expected: expected
1207
+ , message: message
1208
+ , operator: operator
1209
+ , stackStartFunction: assert.fail
1210
+ });
1211
+ }
1212
+
1025
1213
  /**
1026
1214
  * # .ok(object, [message])
1027
1215
  *
@@ -1208,7 +1396,7 @@ module.exports = function (chai) {
1208
1396
  */
1209
1397
 
1210
1398
  assert.isNull = function (val, msg) {
1211
- new Assertion(val, msg).to.not.exist;
1399
+ new Assertion(val, msg).to.equal(null);
1212
1400
  };
1213
1401
 
1214
1402
  /**
@@ -1226,7 +1414,7 @@ module.exports = function (chai) {
1226
1414
  */
1227
1415
 
1228
1416
  assert.isNotNull = function (val, msg) {
1229
- new Assertion(val, msg).to.exist;
1417
+ new Assertion(val, msg).to.not.equal(null);
1230
1418
  };
1231
1419
 
1232
1420
  /**
@@ -1246,6 +1434,24 @@ module.exports = function (chai) {
1246
1434
  new Assertion(val, msg).to.equal(undefined);
1247
1435
  };
1248
1436
 
1437
+ /**
1438
+ * # .isDefined(value, [message])
1439
+ *
1440
+ * Assert `value` is not undefined.
1441
+ *
1442
+ * var tea = 'cup of chai';
1443
+ * assert.isDefined(tea, 'no tea defined');
1444
+ *
1445
+ * @name isUndefined
1446
+ * @param {*} value
1447
+ * @param {String} message
1448
+ * @api public
1449
+ */
1450
+
1451
+ assert.isDefined = function (val, msg) {
1452
+ new Assertion(val, msg).to.not.equal(undefined);
1453
+ };
1454
+
1249
1455
  /**
1250
1456
  * # .isFunction(value, [message])
1251
1457
  *
@@ -1333,7 +1539,7 @@ module.exports = function (chai) {
1333
1539
  */
1334
1540
 
1335
1541
  assert.isNumber = function (val, msg) {
1336
- new Assertion(val, msg).to.be.instanceof(Number);
1542
+ new Assertion(val, msg).to.be.a('number');
1337
1543
  };
1338
1544
 
1339
1545
  /**
@@ -1511,6 +1717,33 @@ module.exports = function (chai) {
1511
1717
  new Assertion(fn, msg).to.not.throw(type);
1512
1718
  };
1513
1719
 
1720
+ /**
1721
+ * # .operator(val, operator, val2, [message])
1722
+ *
1723
+ * Compare two values using operator.
1724
+ *
1725
+ * assert.operator(1, '<', 2, 'everything is ok');
1726
+ * assert.operator(1, '>', 2, 'this will fail');
1727
+ *
1728
+ * @name operator
1729
+ * @param {*} object to test
1730
+ * @param {String} operator
1731
+ * @param {*} second object
1732
+ * @param {String} message
1733
+ * @api public
1734
+ */
1735
+
1736
+ assert.operator = function (val, operator, val2, msg) {
1737
+ if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
1738
+ throw new Error('Invalid operator "' + operator + '"');
1739
+ }
1740
+ var test = new Assertion(eval(val + operator + val2), msg);
1741
+ test.assert(
1742
+ true === test.obj
1743
+ , 'expected ' + inspect(val) + ' to be ' + operator + ' ' + inspect(val2)
1744
+ , 'expected ' + inspect(val) + ' to not be ' + operator + ' ' + inspect(val2) );
1745
+ };
1746
+
1514
1747
  /*!
1515
1748
  * Undocumented / untested
1516
1749
  */
@@ -1580,8 +1813,8 @@ module.exports = function (chai) {
1580
1813
  new Assertion(val1).to.equal(val2);
1581
1814
  };
1582
1815
 
1583
- should.throw = function (fn, err) {
1584
- new Assertion(fn).to.throw(err);
1816
+ should.throw = function (fn, errt, errs) {
1817
+ new Assertion(fn).to.throw(errt, errs);
1585
1818
  };
1586
1819
 
1587
1820
  should.exist = function (val) {
@@ -1595,8 +1828,8 @@ module.exports = function (chai) {
1595
1828
  new Assertion(val1).to.not.equal(val2);
1596
1829
  };
1597
1830
 
1598
- should.not.throw = function (fn, err) {
1599
- new Assertion(fn).to.not.throw(err);
1831
+ should.not.throw = function (fn, errt, errs) {
1832
+ new Assertion(fn).to.not.throw(errt, errs);
1600
1833
  };
1601
1834
 
1602
1835
  should.not.exist = function (val) {