source: Dev/trunk/node_modules/should/lib/should.js @ 484

Last change on this file since 484 was 484, checked in by hendrikvanantwerpen, 11 years ago

Commit node_modules, to make checkouts and builds more deterministic.

File size: 24.5 KB
Line 
1/*!
2 * Should
3 * Copyright(c) 2010-2012 TJ Holowaychuk <tj@vision-media.ca>
4 * MIT Licensed
5 */
6
7/**
8 * Module dependencies.
9 */
10
11var util = require('./util')
12  , assert = require('assert')
13  , AssertionError = assert.AssertionError
14  , statusCodes = require('./http').STATUS_CODES
15  , eql = require('./eql')
16  , inspect = require('util').inspect;
17
18/**
19 * Our function should
20 * @param obj
21 * @returns {Assertion}
22 */
23var should = function(obj) {
24  return new Assertion(util.isWrapperType(obj) ? obj.valueOf(): obj);
25};
26
27should.inspect = function(obj, opts) {
28  if(util.isDate(obj) && typeof obj.inspect !== 'function') obj = obj.toISOString();
29  return inspect(obj, opts);
30};
31
32/**
33 * Expose assert to should
34 *
35 * This allows you to do things like below
36 * without require()ing the assert module.
37 *
38 *    should.equal(foo.bar, undefined);
39 *
40 */
41util.merge(should, assert);
42
43
44/**
45 * Assert _obj_ exists, with optional message.
46 *
47 * @param {*} obj
48 * @param {String} [msg]
49 * @api public
50 */
51should.exist = should.exists = function(obj, msg) {
52  if(null == obj) {
53    throw new AssertionError({
54      message: msg || ('expected ' + should.inspect(obj) + ' to exist')
55      , stackStartFunction: should.exist
56    });
57  }
58};
59
60/**
61 * Asserts _obj_ does not exist, with optional message.
62 *
63 * @param {*} obj
64 * @param {String} [msg]
65 * @api public
66 */
67
68should.not = {};
69should.not.exist = should.not.exists = function(obj, msg){
70  if (null != obj) {
71    throw new AssertionError({
72      message: msg || ('expected ' + should.inspect(obj) + ' to not exist')
73      , stackStartFunction: should.not.exist
74    });
75  }
76};
77
78/**
79 * Expose should to external world.
80 */
81exports = module.exports = should;
82
83
84/**
85 * Expose api via `Object#should`.
86 *
87 * @api public
88 */
89
90Object.defineProperty(Object.prototype, 'should', {
91  set: function(){},
92  get: function(){
93    return should(this);
94  },
95  configurable: true
96});
97
98/**
99 * Initialize a new `Assertion` with the given _obj_.
100 *
101 * @param {*} obj
102 * @api private
103 */
104
105var Assertion = should.Assertion = function Assertion(obj) {
106  this.obj = obj;
107};
108
109var hasOwnProperty = Object.prototype.hasOwnProperty;
110
111/**
112 * Prototype.
113 */
114
115Assertion.prototype = {
116
117  /**
118   * Assert _expr_ with the given _msg_ and _negatedMsg_.
119   *
120   * @param {Boolean} expr
121   * @param {function} msg
122   * @param {function} negatedMsg
123   * @param {Object} [expected]
124   * @param {Boolean} [showDiff]
125   * @param {String} [description]
126   * @api private
127   */
128
129  assert: function(expr, msg, negatedMsg, expected, showDiff, description){
130    msg = this.negate ? negatedMsg : msg
131
132    var ok = this.negate ? !expr : expr
133      , obj = this.obj;
134
135    if (ok) return;
136
137    var err = new AssertionError({
138        message: msg.call(this)
139      , actual: obj
140      , expected: expected
141      , stackStartFunction: this.assert
142      , negated: this.negate
143    });
144
145    err.showDiff = showDiff;
146    err.description = description
147
148    throw err;
149  },
150
151  /**
152   * Dummy getter.
153   *
154   * @api public
155   */
156
157  get an() {
158    return this;
159  },
160
161  /**
162   * Dummy getter.
163   *
164   * @api public
165   */
166
167  get of() {
168    return this;
169  },
170
171  /**
172   * Dummy getter.
173   *
174   * @api public
175   */
176
177  get a() {
178    return this;
179  },
180
181  /**
182   * Dummy getter.
183   *
184   * @api public
185   */
186
187  get and() {
188    return this;
189  },
190
191  /**
192   * Dummy getter.
193   *
194   * @api public
195   */
196
197  get be() {
198    return this;
199  },
200
201  /**
202   * Dummy getter.
203   *
204   * @api public
205   */
206
207  get have() {
208    return this;
209  },
210
211  /**
212   * Dummy getter.
213   *
214   * @api public
215   */
216
217  get with() {
218    return this;
219  },
220
221  /**
222   * Negation modifier.
223   *
224   * @api public
225   */
226
227  get not() {
228    this.negate = true;
229    return this;
230  },
231
232  /**
233   * Get object inspection string.
234   *
235   * @return {String}
236   * @api private
237   */
238
239  get inspect() {
240    return should.inspect(this.obj);
241  },
242
243  /**
244   * Assert instanceof `Arguments`.
245   *
246   * @api public
247   */
248
249  get arguments() {
250    this.assert(
251        util.isArguments(this.obj)
252      , function(){ return 'expected ' + this.inspect + ' to be arguments' }
253      , function(){ return 'expected ' + this.inspect + ' to not be arguments' });
254    return this;
255  },
256
257  /**
258   * Assert that object is empty.
259   *
260   * @api public
261   */
262
263  get empty() {
264    var length = this.obj.length;
265
266    if(util.isString(this.obj) || Array.isArray(this.obj) || util.isArguments(this.obj)) {
267      this.assert(
268        0 === length
269        , function(){ return 'expected ' + this.inspect + ' to be empty' }
270        , function(){ return 'expected ' + this.inspect + ' not to be empty' });
271    } else {
272      var ok = true;
273      for (var prop in this.obj) {
274        if(hasOwnProperty.call(this.obj, prop)) {
275          ok = false;
276          break;
277        }
278      }
279
280      this.assert(
281        ok
282        , function(){ return 'expected ' + this.inspect + ' to be empty' }
283        , function(){ return 'expected ' + this.inspect + ' not to be empty' });
284
285    }
286    return this;
287  },
288
289  /**
290   * Assert ok.
291   *
292   * @api public
293   */
294
295  get ok() {
296    this.assert(
297        this.obj
298      , function(){ return 'expected ' + this.inspect + ' to be truthy' }
299      , function(){ return 'expected ' + this.inspect + ' to be falsey' });
300    return this;
301  },
302
303  /**
304   * Assert true.
305   *
306   * @api public
307   */
308
309  get true() {
310    this.assert(
311        true === this.obj
312      , function(){ return 'expected ' + this.inspect + ' to be true' }
313      , function(){ return 'expected ' + this.inspect + ' not to be true' });
314    return this;
315  },
316
317  /**
318   * Assert false.
319   *
320   * @api public
321   */
322
323  get false() {
324    this.assert(
325        false === this.obj
326      , function(){ return 'expected ' + this.inspect + ' to be false' }
327      , function(){ return 'expected ' + this.inspect + ' not to be false' });
328    return this;
329  },
330
331  /**
332   * Assert NaN.
333   *
334   * @api public
335   */
336
337  get NaN() {
338    this.assert(
339        util.isNumber(this.obj) && isNaN(this.obj)
340      , function(){ return 'expected ' + this.inspect + ' to be NaN' }
341      , function(){ return 'expected ' + this.inspect + ' not to be NaN' });
342    return this;
343  },
344
345  /**
346   * Assert Infinity.
347   *
348   * @api public
349   */
350
351  get Infinity() {
352    this.assert(
353      util.isNumber(this.obj) && !isNaN(this.obj) && !isFinite(this.obj)
354      , function(){ return 'expected ' + this.inspect + ' to be Infinity' }
355      , function(){ return 'expected ' + this.inspect + ' not to be Infinity' });
356    return this;
357  },
358
359  /**
360   * Assert equal.
361   *
362   * @param {*} val
363   * @param {String} description
364   * @api public
365   */
366
367  eql: function(val, description){
368    this.assert(
369        eql(val, this.obj)
370      , function(){ return 'expected ' + this.inspect + ' to equal ' + should.inspect(val) + (description ? " | " + description : "") }
371      , function(){ return 'expected ' + this.inspect + ' to not equal ' + should.inspect(val) + (description ? " | " + description : "") }
372      , val
373      , true
374      , description);
375    return this;
376  },
377
378  /**
379   * Assert strict equal.
380   *
381   * @param {*} val
382   * @param {String} description
383   * @api public
384   */
385
386  equal: function(val, description){
387    this.assert(
388        val === this.obj
389      , function(){ return 'expected ' + this.inspect + ' to equal ' + should.inspect(val) + (description ? " | " + description : "") }
390      , function(){ return 'expected ' + this.inspect + ' to not equal ' + should.inspect(val) + (description ? " | " + description : "") }
391      , val
392      , void 0
393      , description);
394    return this;
395  },
396
397  /**
398   * Assert within start to finish (inclusive).
399   *
400   * @param {Number} start
401   * @param {Number} finish
402   * @param {String} description
403   * @api public
404   */
405
406  within: function(start, finish, description){
407    var range = start + '..' + finish;
408    this.assert(
409        this.obj >= start && this.obj <= finish
410      , function(){ return 'expected ' + this.inspect + ' to be within ' + range + (description ? " | " + description : "") }
411      , function(){ return 'expected ' + this.inspect + ' to not be within ' + range + (description ? " | " + description : "") }
412      , void 0
413      , void 0
414      , description);
415    return this;
416  },
417
418  /**
419   * Assert within value +- delta (inclusive).
420   *
421   * @param {Number} value
422   * @param {Number} delta
423   * @param {String} description
424   * @api public
425   */
426
427  approximately: function(value, delta, description) {
428    this.assert(
429      Math.abs(this.obj - value) <= delta
430      , function(){ return 'expected ' + this.inspect + ' to be approximately ' + value + " +- " + delta + (description ? " | " + description : "") }
431      , function(){ return 'expected ' + this.inspect + ' to not be approximately ' + value + " +- " + delta + (description ? " | " + description : "") }
432      , void 0
433      , void 0
434      , description);
435    return this;
436  },
437
438  /**
439   * Assert typeof.
440   *
441   * @param {*} type
442   * @param {String} description
443   * @api public
444   */
445  type: function(type, description){
446    this.assert(
447        type == typeof this.obj
448      , function(){ return 'expected ' + this.inspect + ' to have type ' + type + (description ? " | " + description : "") }
449      , function(){ return 'expected ' + this.inspect + ' not to have type ' + type  + (description ? " | " + description : "") }
450      , void 0
451      , void 0
452      , description);
453    return this;
454  },
455
456  /**
457   * Assert instanceof.
458   *
459   * @param {Function} constructor
460   * @param {String} description
461   * @api public
462   */
463
464  instanceof: function(constructor, description){
465    var name = constructor.name;
466    this.assert(
467        this.obj instanceof constructor
468      , function(){ return 'expected ' + this.inspect + ' to be an instance of ' + name + (description ? " | " + description : "") }
469      , function(){ return 'expected ' + this.inspect + ' not to be an instance of ' + name + (description ? " | " + description : "") }
470      , void 0
471      , void 0
472      , description);
473    return this;
474  },
475
476  /**
477   * Assert if given object is a function.
478   */
479  get Function(){
480    this.assert(
481      util.isFunction(this.obj)
482      , function(){ return 'expected ' + this.inspect + ' to be a function' }
483      , function(){ return 'expected ' + this.inspect + ' not to be a function' });
484    return this;
485  },
486
487  /**
488   * Assert given object is an object.
489   */
490  get Object(){
491    this.assert(
492      util.isObject(this.obj) && !Array.isArray(this.obj)
493      , function(){ return 'expected ' + this.inspect + ' to be an object' }
494      , function(){ return 'expected ' + this.inspect + ' not to be an object' });
495    return this;
496  },
497
498  /**
499   * Assert given object is a string
500   */
501  get String(){
502    this.assert(
503      util.isString(this.obj)
504      , function(){ return 'expected ' + this.inspect + ' to be a string' }
505      , function(){ return 'expected ' + this.inspect + ' not to be a string' });
506    return this;
507  },
508
509  /**
510   * Assert given object is an array
511   */
512  get Array(){
513    this.assert(
514      Array.isArray(this.obj)
515      , function(){ return 'expected ' + this.inspect + ' to be an array' }
516      , function(){ return 'expected ' + this.inspect + ' not to be an array' });
517    return this;
518  },
519
520  /**
521   * Assert given object is a number. NaN and Infinity are not numbers.
522   */
523  get Number(){
524    this.assert(
525      util.isNumber(this.obj) && isFinite(this.obj) && !isNaN(this.obj)
526      , function(){ return 'expected ' + this.inspect + ' to be a number' }
527      , function(){ return 'expected ' + this.inspect + ' not to be a number' });
528    return this;
529  },
530
531  /**
532   * Assert given object is a boolean
533   */
534  get Boolean(){
535    this.assert(
536      util.isBoolean(this.obj)
537      , function(){ return 'expected ' + this.inspect + ' to be a boolean' }
538      , function(){ return 'expected ' + this.inspect + ' not to be a boolean' });
539    return this;
540  },
541
542  /**
543   * Assert given object is an error
544   */
545  get Error() {
546    this.assert(
547      util.isError(this.obj)
548      , function(){ return 'expected ' + this.inspect + ' to be an error' }
549      , function(){ return 'expected ' + this.inspect + ' not to be an error' });
550    return this;
551  },
552  /**
553   * Assert numeric value above _n_.
554   *
555   * @param {Number} n
556   * @param {String} description
557   * @api public
558   */
559
560  above: function(n, description){
561    this.assert(
562        this.obj > n
563      , function(){ return 'expected ' + this.inspect + ' to be above ' + n + (description ? " | " + description : "") }
564      , function(){ return 'expected ' + this.inspect + ' to be below ' + n + (description ? " | " + description : "") }
565      , void 0
566      , void 0
567      , description);
568    return this;
569  },
570
571  /**
572   * Assert numeric value below _n_.
573   *
574   * @param {Number} n
575   * @param {String} description
576   * @api public
577   */
578
579  below: function(n, description){
580    this.assert(
581        this.obj < n
582      , function(){ return 'expected ' + this.inspect + ' to be below ' + n + (description ? " | " + description : "") }
583      , function(){ return 'expected ' + this.inspect + ' to be above ' + n + (description ? " | " + description : "") }
584      , void 0
585      , void 0
586      , description);
587    return this;
588  },
589
590  /**
591   * Assert string value matches _regexp_.
592   *
593   * @param {RegExp} regexp
594   * @param {String} description
595   * @api public
596   */
597
598  match: function(regexp, description){
599    this.assert(
600        regexp.exec(this.obj)
601      , function(){ return 'expected ' + this.inspect + ' to match ' + regexp + (description ? " | " + description : "") }
602      , function(){ return 'expected ' + this.inspect + ' not to match ' + regexp + (description ? " | " + description : "") }
603      , void 0
604      , void 0
605      , description);
606    return this;
607  },
608
609  /**
610   * Assert property "length" exists and has value of _n_.
611   *
612   * @param {Number} n
613   * @param {String} description
614   * @api public
615   */
616
617  length: function(n, description){
618    this.obj.should.have.property('length');
619    var len = this.obj.length;
620    this.assert(
621        n == len
622      , function(){ return 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len + (description ? " | " + description : "") }
623      , function(){ return 'expected ' + this.inspect + ' to not have a length of ' + len + (description ? " | " + description : "") }
624      , void 0
625      , void 0
626      , description);
627    return this;
628  },
629
630  /**
631   * Assert property _name_ exists, with optional _val_.
632   *
633   * @param {String} name
634   * @param {*} [val]
635   * @param {String} description
636   * @api public
637   */
638
639  property: function(name, val, description){
640    if (this.negate && undefined !== val) {
641      if (undefined === this.obj[name]) {
642        throw new Error(this.inspect + ' has no property ' + should.inspect(name) + (description ? " | " + description : ""));
643      }
644    } else {
645      this.assert(
646          undefined !== this.obj[name]
647        , function(){ return 'expected ' + this.inspect + ' to have a property ' + should.inspect(name) + (description ? " | " + description : "") }
648        , function(){ return 'expected ' + this.inspect + ' to not have a property ' + should.inspect(name) + (description ? " | " + description : "") }
649        , void 0
650        , void 0
651        , description);
652    }
653
654    if (undefined !== val) {
655      this.assert(
656          val === this.obj[name]
657        , function(){ return 'expected ' + this.inspect + ' to have a property ' + should.inspect(name)
658          + ' of ' + should.inspect(val) + ', but got ' + should.inspect(this.obj[name]) + (description ? " | " + description : "") }
659        , function(){ return 'expected ' + this.inspect + ' to not have a property ' + should.inspect(name) + ' of ' + should.inspect(val) + (description ? " | " + description : "") }
660        , void 0
661        , void 0
662        , description);
663    }
664
665    this.obj = this.obj[name];
666    return this;
667  },
668  /**
669   * Asset have given properties
670   * @param {Array|String ...} names
671   * @api public
672   */
673  properties: function(names) {
674    var str
675      , ok = true;
676
677    names = names instanceof Array
678      ? names
679      : Array.prototype.slice.call(arguments);
680
681    var len = names.length;
682
683    if (!len) throw new Error('names required');
684
685    // make sure they're all present
686    ok = names.every(function(name){
687      return this.obj[name] !== undefined;
688    }, this);
689
690    // key string
691    if (len > 1) {
692      names = names.map(function(name){
693        return should.inspect(name);
694      });
695      var last = names.pop();
696      str = names.join(', ') + ', and ' + last;
697    } else {
698      str = should.inspect(names[0]);
699    }
700
701    // message
702    str = 'have ' + (len > 1 ? 'properties ' : 'a property ') + str;
703
704    this.assert(
705      ok
706      , function(){ return 'expected ' + this.inspect + ' to ' + str }
707      , function(){ return 'expected ' + this.inspect + ' to not ' + str });
708
709    return this;
710  },
711
712  /**
713   * Assert own property _name_ exists.
714   *
715   * @param {String} name
716   * @param {String} description
717   * @api public
718   */
719
720  ownProperty: function(name, description){
721    this.assert(
722      hasOwnProperty.call(this.obj, name)
723      , function(){ return 'expected ' + this.inspect + ' to have own property ' + should.inspect(name) + (description ? " | " + description : "") }
724      , function(){ return 'expected ' + this.inspect + ' to not have own property ' + should.inspect(name) + (description ? " | " + description : "") }
725      , void 0
726      , void 0
727      , description);
728    this.obj = this.obj[name];
729    return this;
730  },
731
732  /**
733   * Assert that string starts with `str`.
734   * @param {String} str
735   * @param {String} description
736   * @api public
737   */
738
739  startWith: function(str, description) {
740    this.assert(0 === this.obj.indexOf(str)
741    , function() { return 'expected ' + this.inspect + ' to start with ' + should.inspect(str) + (description ? " | " + description : "") }
742    , function() { return 'expected ' + this.inspect + ' to not start with ' + should.inspect(str) + (description ? " | " + description : "") }
743    , void 0
744    , void 0
745    , description);
746    return this;
747  },
748
749  /**
750   * Assert that string ends with `str`.
751   * @param {String} str
752   * @param {String} description
753   * @api public
754   */
755
756  endWith: function(str, description) {
757    this.assert(-1 !== this.obj.indexOf(str, this.obj.length - str.length)
758    , function() { return 'expected ' + this.inspect + ' to end with ' + should.inspect(str) + (description ? " | " + description : "") }
759    , function() { return 'expected ' + this.inspect + ' to not end with ' + should.inspect(str) + (description ? " | " + description : "") }
760    , void 0
761    , void 0
762    , description);
763    return this;
764  },
765
766  /**
767   * Assert that `obj` is present via `.indexOf()` or that `obj` contains some sub-object.
768   *
769   * @param {*} obj
770   * @param {String} description
771   * @api public
772   */
773
774  include: function(obj, description){
775    if (!Array.isArray(this.obj) && !util.isString(this.obj)){
776      var cmp = {};
777      for (var key in obj) cmp[key] = this.obj[key];
778      this.assert(
779          eql(cmp, obj)
780        , function(){ return 'expected ' + this.inspect + ' to include an object equal to ' + should.inspect(obj) + (description ? " | " + description : "") }
781        , function(){ return 'expected ' + this.inspect + ' to not include an object equal to ' + should.inspect(obj) + (description ? " | " + description : "") }
782        , void 0
783        , void 0
784        , description);
785    } else {
786      this.assert(
787          ~this.obj.indexOf(obj)
788        , function(){ return 'expected ' + this.inspect + ' to include ' + should.inspect(obj) + (description ? " | " + description : "") }
789        , function(){ return 'expected ' + this.inspect + ' to not include ' + should.inspect(obj) + (description ? " | " + description : "") }
790        , void 0
791        , void 0
792        , description);
793    }
794    return this;
795  },
796
797  /**
798   * Assert that an object equal to `obj` is present.
799   *
800   * @param {Array} obj
801   * @param {String} description
802   * @api public
803   */
804
805  includeEql: function(obj, description){
806    this.assert(
807      this.obj.some(function(item) { return eql(obj, item); })
808      , function(){ return 'expected ' + this.inspect + ' to include an object equal to ' + should.inspect(obj) + (description ? " | " + description : "") }
809      , function(){ return 'expected ' + this.inspect + ' to not include an object equal to ' + should.inspect(obj) + (description ? " | " + description : "") }
810      , void 0
811      , void 0
812      , description);
813    return this;
814  },
815
816  /**
817   * Assert exact keys or inclusion of keys by using
818   * the `.include` modifier.
819   *
820   * @param {Array|String ...} keys
821   * @api public
822   */
823
824  keys: function(keys){
825    var str
826      , ok = true;
827
828    keys = keys instanceof Array
829      ? keys
830      : Array.prototype.slice.call(arguments);
831
832    if (!keys.length) throw new Error('keys required');
833
834    var actual = Object.keys(this.obj)
835      , len = keys.length;
836
837    // make sure they're all present
838    ok = keys.every(function(key){
839      return ~actual.indexOf(key);
840    });
841
842    // matching length
843    ok = ok && keys.length == actual.length;
844
845    // key string
846    if (len > 1) {
847      keys = keys.map(function(key){
848        return should.inspect(key);
849      });
850      var last = keys.pop();
851      str = keys.join(', ') + ', and ' + last;
852    } else {
853      str = should.inspect(keys[0]);
854    }
855
856    // message
857    str = 'have ' + (len > 1 ? 'keys ' : 'key ') + str;
858
859    this.assert(
860        ok
861      , function(){ return 'expected ' + this.inspect + ' to ' + str }
862      , function(){ return 'expected ' + this.inspect + ' to not ' + str });
863
864    return this;
865  },
866
867  /**
868   * Assert that header `field` has the given `val`.
869   *
870   * @param {String} field
871   * @param {String} val
872   * @return {Assertion} for chaining
873   * @api public
874   */
875
876  header: function(field, val){
877    this.obj.should
878      .have.property('headers').and
879      .have.property(field.toLowerCase(), val);
880    return this;
881  },
882
883  /**
884   * Assert `.statusCode` of `code`.
885   *
886   * @param {Number} code
887   * @return {Assertion} for chaining
888   * @api public
889   */
890
891  status:  function(code){
892    this.obj.should.have.property('statusCode');
893    var status = this.obj.statusCode;
894
895    this.assert(
896        code == status
897      , function(){ return 'expected response code of ' + code + ' ' + should.inspect(statusCodes[code])
898        + ', but got ' + status + ' ' + should.inspect(statusCodes[status]) }
899      , function(){ return 'expected to not respond with ' + code + ' ' + should.inspect(statusCodes[code]) });
900
901    return this;
902  },
903
904  /**
905   * Assert that this response has content-type: application/json.
906   *
907   * @return {Assertion} for chaining
908   * @api public
909   */
910
911  get json() {
912    this.obj.should.have.property('headers');
913    this.obj.headers.should.have.property('content-type');
914    this.obj.headers['content-type'].should.include('application/json');
915    return this;
916  },
917
918  /**
919   * Assert that this response has content-type: text/html.
920   *
921   * @return {Assertion} for chaining
922   * @api public
923   */
924
925  get html() {
926    this.obj.should.have.property('headers');
927    this.obj.headers.should.have.property('content-type');
928    this.obj.headers['content-type'].should.include('text/html');
929    return this;
930  },
931
932  /**
933   * Assert that this function will or will not
934   * throw an exception.
935   *
936   * @return {Assertion} for chaining
937   * @api public
938   */
939
940  throw: function(message){
941    var fn = this.obj
942      , err = {}
943      , errorInfo = ''
944      , ok = true;
945
946    try {
947      fn();
948      ok = false;
949    } catch (e) {
950      err = e;
951    }
952
953    if (ok) {
954      if ('string' == typeof message) {
955        ok = message == err.message;
956      } else if (message instanceof RegExp) {
957        ok = message.test(err.message);
958      } else if ('function' == typeof message) {
959        ok = err instanceof message;
960      }
961
962      if (message && !ok) {
963        if ('string' == typeof message) {
964          errorInfo = " with a message matching '" + message + "', but got '" + err.message + "'";
965        } else if (message instanceof RegExp) {
966          errorInfo = " with a message matching " + message + ", but got '" + err.message + "'";
967        } else if ('function' == typeof message) {
968          errorInfo = " of type " + message.name + ", but got " + err.constructor.name;
969        }
970      }
971    }
972
973    this.assert(
974        ok
975      , function(){ return 'expected an exception to be thrown' + errorInfo }
976      , function(){ return 'expected no exception to be thrown, got "' + err.message + '"' });
977
978    return this;
979  }
980};
981
982/**
983 * Aliases.
984 */
985
986(function alias(name, as){
987  Assertion.prototype[as] = Assertion.prototype[name];
988  return alias;
989})
990('instanceof', 'instanceOf')
991('throw', 'throwError')
992('length', 'lengthOf')
993('keys', 'key')
994('ownProperty', 'haveOwnProperty')
995('above', 'greaterThan')
996('below', 'lessThan')
997('include', 'contain')
998('equal', 'exactly');
999
Note: See TracBrowser for help on using the repository browser.