Coverage

83%
459
381
78

chai.js

94%
19
18
1
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
71var used = [];
81var exports = module.exports = {};
9
101exports.version = '0.4.0';
11
121exports.Assertion = require('./assertion');
131exports.AssertionError = require('./error');
14
151exports.inspect = require('./utils/inspect');
16
171exports.use = function (fn) {
185 if (!~used.indexOf(fn)) {
194 fn(this);
204 used.push(fn);
21 }
22
235 return this;
24};
25
261exports.fail = function (actual, expected, message, operator, stackStartFunction) {
270 throw new exports.AssertionError({
28 message: message,
29 actual: actual,
30 expected: expected,
31 operator: operator,
32 stackStartFunction: stackStartFunction
33 });
34};
35
361var expect = require('./interface/expect');
371exports.use(expect);
38
391var should = require('./interface/should');
401exports.use(should);
41
421var assert = require('./interface/assert');
431exports.use(assert);

assertion.js

97%
152
148
4
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 *
6 * Primarily a refactor of: should.js
7 * https://github.com/visionmedia/should.js
8 * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
9 * MIT Licensed
10 */
11
12/**
13 * ### BDD Style Introduction
14 *
15 * The BDD style is exposed through `expect` or `should` interfaces. In both
16 * scenarios, you chain together natural language assertions.
17 *
18 * // expect
19 * var expect = require('chai').expect;
20 * expect(foo).to.equal('bar');
21 *
22 * // should
23 * var should = require('chai').should();
24 * foo.should.equal('bar');
25 *
26 * #### Differences
27 *
28 * The `expect` interface provides a function as a starting point for chaining
29 * your language assertions. It works on both node.js and in the browser.
30 *
31 * The `should` interface extends `Object.prototype` to provide a single getter as
32 * the starting point for your language assertions. Most browser don't like
33 * extensions to `Object.prototype` so it is not recommended for browser use.
34 *
35 * #### Configuration
36 *
37 * By default, Chai does not show stack traces upon an AssertionError. This can
38 * be changed by modifying the `includeStack` parameter for chai.Assertion. For example:
39 *
40 * var chai = require('chai');
41 * chai.Assertion.includeStack = true; // defaults to false
42 */
43
44/*!
45 * Module dependencies.
46 */
47
481var AssertionError = require('./error')
49 , eql = require('./utils/eql')
50 , inspect = require('./utils/inspect');
51
52/*!
53 * Module export.
54 */
55
561module.exports = Assertion;
57
58
59/*!
60 * # Assertion Constructor
61 *
62 * Creates object for chaining.
63 *
64 * @api private
65 */
66
671function Assertion (obj, msg, stack) {
68556 this.ssfi = stack || arguments.callee;
69556 this.obj = obj;
70556 this.msg = msg;
71}
72
73/*!
74 * ## Assertion.includeStack
75 *
76 * User configurable property, influences whether stack trace
77 * is included in Assertion error message. Default of false
78 * suppresses stack trace in the error message
79 *
80 * Assertion.includeStack = true; // enable stack on error
81 *
82 * @api public
83 */
84
851Assertion.includeStack = false;
86
87/*!
88 * # .assert(expression, message, negateMessage)
89 *
90 * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
91 *
92 * @name assert
93 * @param {Philosophical} expression to be tested
94 * @param {String} message to display if fails
95 * @param {String} negatedMessage to display if negated expression fails
96 * @api private
97 */
98
991Assertion.prototype.assert = function (expr, msg, negateMsg) {
100551 var msg = (this.negate ? negateMsg : msg)
101 , ok = this.negate ? !expr : expr;
102
103551 if (!ok) {
104124 throw new AssertionError({
105 operator: this.msg,
106 message: msg,
107 stackStartFunction: (Assertion.includeStack) ? this.assert : this.ssfi
108 });
109 }
110};
111
112/*!
113 * # inspect
114 *
115 * Returns the current object stringified.
116 *
117 * @name inspect
118 * @api private
119 */
120
1211Object.defineProperty(Assertion.prototype, 'inspect',
122 { get: function () {
1231104 return inspect(this.obj);
124 },
125 configurable: true
126});
127
128/**
129 * # to
130 *
131 * Language chain.
132 *
133 * @name to
134 * @api public
135 */
136
1371Object.defineProperty(Assertion.prototype, 'to',
138 { get: function () {
139323 return this;
140 },
141 configurable: true
142});
143
144/**
145 * # be
146 *
147 * Language chain.
148 *
149 * @name be
150 * @api public
151 */
152
1531Object.defineProperty(Assertion.prototype, 'be',
154 { get: function () {
15598 return this;
156 },
157 configurable: true
158});
159
160/**
161 * # been
162 *
163 * Language chain. Also tests `tense` to past for addon
164 * modules that use the tense feature.
165 *
166 * @name been
167 * @api public
168 */
169
1701Object.defineProperty(Assertion.prototype, 'been',
171 { get: function () {
1720 this.tense = 'past';
1730 return this;
174 },
175 configurable: true
176});
177
178/**
179 * # an
180 *
181 * Language chain.
182 *
183 * @name an
184 * @api public
185 */
186
1871Object.defineProperty(Assertion.prototype, 'an',
188 { get: function () {
1894 return this;
190 },
191 configurable: true
192});
193/**
194 * # is
195 *
196 * Language chain.
197 *
198 * @name is
199 * @api public
200 */
201
2021Object.defineProperty(Assertion.prototype, 'is',
203 { get: function () {
20472 return this;
205 },
206 configurable: true
207});
208
209/**
210 * # and
211 *
212 * Language chain.
213 *
214 * @name and
215 * @api public
216 */
217
2181Object.defineProperty(Assertion.prototype, 'and',
219 { get: function () {
2201 return this;
221 },
222 configurable: true
223});
224
225/**
226 * # have
227 *
228 * Language chain.
229 *
230 * @name have
231 * @api public
232 */
233
2341Object.defineProperty(Assertion.prototype, 'have',
235 { get: function () {
23697 return this;
237 },
238 configurable: true
239});
240
241/**
242 * # with
243 *
244 * Language chain.
245 *
246 * @name with
247 * @api public
248 */
249
2501Object.defineProperty(Assertion.prototype, 'with',
251 { get: function () {
2522 return this;
253 },
254 configurable: true
255});
256
257/**
258 * # .not
259 *
260 * Negates any of assertions following in the chain.
261 *
262 * @name not
263 * @api public
264 */
265
2661Object.defineProperty(Assertion.prototype, 'not',
267 { get: function () {
268108 this.negate = true;
269108 return this;
270 },
271 configurable: true
272});
273
274/**
275 * # .ok
276 *
277 * Assert object truthiness.
278 *
279 * expect('everthing').to.be.ok;
280 * expect(false).to.not.be.ok;
281 * expect(undefined).to.not.be.ok;
282 * expect(null).to.not.be.ok;
283 *
284 * @name ok
285 * @api public
286 */
287
2881Object.defineProperty(Assertion.prototype, 'ok',
289 { get: function () {
29019 this.assert(
291 this.obj
292 , 'expected ' + this.inspect + ' to be truthy'
293 , 'expected ' + this.inspect + ' to be falsey');
294
29512 return this;
296 },
297 configurable: true
298});
299
300/**
301 * # .true
302 *
303 * Assert object is true
304 *
305 * @name true
306 * @api public
307 */
308
3091Object.defineProperty(Assertion.prototype, 'true',
310 { get: function () {
31112 this.assert(
312 true === this.obj
313 , 'expected ' + this.inspect + ' to be true'
314 , 'expected ' + this.inspect + ' to be false');
315
3167 return this;
317 },
318 configurable: true
319});
320
321/**
322 * # .false
323 *
324 * Assert object is false
325 *
326 * @name false
327 * @api public
328 */
329
3301Object.defineProperty(Assertion.prototype, 'false',
331 { get: function () {
33211 this.assert(
333 false === this.obj
334 , 'expected ' + this.inspect + ' to be false'
335 , 'expected ' + this.inspect + ' to be true');
336
3377 return this;
338 },
339 configurable: true
340});
341
342/**
343 * # .exist
344 *
345 * Assert object exists (null).
346 *
347 * var foo = 'hi'
348 * , bar;
349 * expect(foo).to.exist;
350 * expect(bar).to.not.exist;
351 *
352 * @name exist
353 * @api public
354 */
355
3561Object.defineProperty(Assertion.prototype, 'exist',
357 { get: function () {
3586 this.assert(
359 null != this.obj
360 , 'expected ' + this.inspect + ' to exist'
361 , 'expected ' + this.inspect + ' to not exist');
362
3634 return this;
364 },
365 configurable: true
366});
367
368/**
369 * # .empty
370 *
371 * Assert object's length to be 0.
372 *
373 * expect([]).to.be.empty;
374 *
375 * @name empty
376 * @api public
377 */
378
3791Object.defineProperty(Assertion.prototype, 'empty',
380 { get: function () {
38114 new Assertion(this.obj).to.have.property('length');
382
38312 this.assert(
384 0 === this.obj.length
385 , 'expected ' + this.inspect + ' to be empty'
386 , 'expected ' + this.inspect + ' not to be empty');
387
3886 return this;
389 },
390 configurable: true
391});
392
393/**
394 * # .arguments
395 *
396 * Assert object is an instanceof arguments.
397 *
398 * function test () {
399 * expect(arguments).to.be.arguments;
400 * }
401 *
402 * @name arguments
403 * @api public
404 */
405
4061Object.defineProperty(Assertion.prototype, 'arguments',
407 { get: function () {
4084 this.assert(
409 '[object Arguments]' == Object.prototype.toString.call(this.obj)
410 , 'expected ' + this.inspect + ' to be arguments'
411 , 'expected ' + this.inspect + ' to not be arguments');
412
4134 return this;
414 },
415 configurable: true
416});
417
418/**
419 * # .equal(value)
420 *
421 * Assert strict equality.
422 *
423 * expect('hello').to.equal('hello');
424 *
425 * @name equal
426 * @param {*} value
427 * @api public
428 */
429
4301Assertion.prototype.equal = function (val) {
431132 this.assert(
432 val === this.obj
433 , 'expected ' + this.inspect + ' to equal ' + inspect(val)
434 , 'expected ' + this.inspect + ' to not equal ' + inspect(val));
435
436128 return this;
437};
438
439/**
440 * # .eql(value)
441 *
442 * Assert deep equality.
443 *
444 * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
445 *
446 * @name eql
447 * @param {*} value
448 * @api public
449 */
450
4511Assertion.prototype.eql = function (obj) {
45210 this.assert(
453 eql(obj, this.obj)
454 , 'expected ' + this.inspect + ' to equal ' + inspect(obj)
455 , 'expected ' + this.inspect + ' to not equal ' + inspect(obj));
4568 return this;
457};
458
459/**
460 * # .above(value)
461 *
462 * Assert greater than `value`.
463 *
464 * expect(10).to.be.above(5);
465 *
466 * @name above
467 * @param {Number} value
468 * @api public
469 */
470
4711Assertion.prototype.above = function (val) {
47212 this.assert(
473 this.obj > val
474 , 'expected ' + this.inspect + ' to be above ' + val
475 , 'expected ' + this.inspect + ' to be below ' + val);
476
4778 return this;
478};
479
480/**
481 * # .below(value)
482 *
483 * Assert less than `value`.
484 *
485 * expect(5).to.be.below(10);
486 *
487 * @name below
488 * @param {Number} value
489 * @api public
490 */
491
4921Assertion.prototype.below = function (val) {
4930 this.assert(
494 this.obj < val
495 , 'expected ' + this.inspect + ' to be below ' + val
496 , 'expected ' + this.inspect + ' to be above ' + val);
497
4980 return this;
499};
500
501/**
502 * # .within(start, finish)
503 *
504 * Assert that a number is within a range.
505 *
506 * expect(7).to.be.within(5,10);
507 *
508 * @name within
509 * @param {Number} start lowerbound inclusive
510 * @param {Number} finish upperbound inclusive
511 * @api public
512 */
513
5141Assertion.prototype.within = function (start, finish) {
51512 var range = start + '..' + finish;
516
51712 this.assert(
518 this.obj >= start && this.obj <= finish
519 , 'expected ' + this.inspect + ' to be within ' + range
520 , 'expected ' + this.inspect + ' to not be within ' + range);
521
5228 return this;
523};
524
525/**
526 * # .a(type)
527 *
528 * Assert typeof.
529 *
530 * expect('test').to.be.a('string');
531 *
532 * @name a
533 * @param {String} type
534 * @api public
535 */
536
5371Assertion.prototype.a = function (type) {
53878 this.assert(
539 type == typeof this.obj
540 , 'expected ' + this.inspect + ' to be a ' + type
541 , 'expected ' + this.inspect + ' not to be a ' + type);
542
54368 return this;
544};
545
546/**
547 * # .instanceof(constructor)
548 *
549 * Assert instanceof.
550 *
551 * var Tea = function (name) { this.name = name; }
552 * , Chai = new Tea('chai');
553 *
554 * expect(Chai).to.be.an.instanceOf(Tea);
555 *
556 * @name instanceof
557 * @param {Constructor}
558 * @alias instanceOf
559 * @api public
560 */
561
5621Assertion.prototype.instanceof = function (constructor) {
5636 var name = constructor.name;
5646 this.assert(
565 this.obj instanceof constructor
566 , 'expected ' + this.inspect + ' to be an instance of ' + name
567 , 'expected ' + this.inspect + ' to not be an instance of ' + name);
568
5693 return this;
570};
571
572/**
573 * # .property(name, [value])
574 *
575 * Assert that property of `name` exists, optionally with `value`.
576 *
577 * var obj = { foo: 'bar' }
578 * expect(obj).to.have.property('foo');
579 * expect(obj).to.have.property('foo', 'bar');
580 * expect(obj).to.have.property('foo').to.be.a('string');
581 *
582 * @name property
583 * @param {String} name
584 * @param {*} value (optional)
585 * @returns value of property for chaining
586 * @api public
587 */
588
5891Assertion.prototype.property = function (name, val) {
59047 if (this.negate && undefined !== val) {
5914 if (undefined === this.obj[name]) {
5922 throw new Error(this.inspect + ' has no property ' + inspect(name));
593 }
594 } else {
59543 this.assert(
596 undefined !== this.obj[name]
597 , 'expected ' + this.inspect + ' to have a property ' + inspect(name)
598 , 'expected ' + this.inspect + ' to not have property ' + inspect(name));
599 }
600
60139 if (undefined !== val) {
60211 this.assert(
603 val === this.obj[name]
604 , 'expected ' + this.inspect + ' to have a property ' + inspect(name) + ' of ' +
605 inspect(val) + ', but got ' + inspect(this.obj[name])
606 , 'expected ' + this.inspect + ' to not have a property ' + inspect(name) + ' of ' + inspect(val));
607 }
608
60933 this.obj = this.obj[name];
61033 return this;
611};
612
613/**
614 * # .ownProperty(name)
615 *
616 * Assert that has own property by `name`.
617 *
618 * expect('test').to.have.ownProperty('length');
619 *
620 * @name ownProperty
621 * @alias haveOwnProperty
622 * @param {String} name
623 * @api public
624 */
625
6261Assertion.prototype.ownProperty = function (name) {
6278 this.assert(
628 this.obj.hasOwnProperty(name)
629 , 'expected ' + this.inspect + ' to have own property ' + inspect(name)
630 , 'expected ' + this.inspect + ' to not have own property ' + inspect(name));
6316 return this;
632};
633
634/**
635 * # .length(val)
636 *
637 * Assert that object has expected length.
638 *
639 * expect([1,2,3]).to.have.length(3);
640 * expect('foobar').to.have.length(6);
641 *
642 * @name length
643 * @alias lengthOf
644 * @param {Number} length
645 * @api public
646 */
647
6481Assertion.prototype.length = function (n) {
64912 new Assertion(this.obj).to.have.property('length');
65010 var len = this.obj.length;
651
65210 this.assert(
653 len == n
654 , 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len
655 , 'expected ' + this.inspect + ' to not have a length of ' + len);
656
6577 return this;
658};
659
660/**
661 * # .match(regexp)
662 *
663 * Assert that matches regular expression.
664 *
665 * expect('foobar').to.match(/^foo/);
666 *
667 * @name match
668 * @param {RegExp} RegularExpression
669 * @api public
670 */
671
6721Assertion.prototype.match = function (re) {
67311 this.assert(
674 re.exec(this.obj)
675 , 'expected ' + this.inspect + ' to match ' + re
676 , 'expected ' + this.inspect + ' not to match ' + re);
677
6787 return this;
679};
680
681/**
682 * # .include(obj)
683 *
684 * Assert the inclusion of an object in an Array or substring in string.
685 *
686 * expect([1,2,3]).to.include(2);
687 *
688 * @name include
689 * @param {Object|String|Number} obj
690 * @api public
691 */
692
6931Assertion.prototype.include = function (obj) {
69416 this.assert(
695 ~this.obj.indexOf(obj)
696 , 'expected ' + this.inspect + ' to include ' + inspect(obj)
697 , 'expected ' + this.inspect + ' to not include ' + inspect(obj));
698
69912 return this;
700};
701
702/**
703 * # .string(string)
704 *
705 * Assert inclusion of string in string.
706 *
707 * expect('foobar').to.have.string('bar');
708 *
709 * @name string
710 * @param {String} string
711 * @api public
712 */
713
7141Assertion.prototype.string = function (str) {
71513 new Assertion(this.obj).is.a('string');
716
71711 this.assert(
718 ~this.obj.indexOf(str)
719 , 'expected ' + this.inspect + ' to contain ' + inspect(str)
720 , 'expected ' + this.inspect + ' to not contain ' + inspect(str));
721
7227 return this;
723};
724
725
726
727/**
728 * # contain
729 *
730 * Toggles the `contain` flag for the `keys` assertion.
731 *
732 * @name contain
733 * @api public
734 */
735
7361Object.defineProperty(Assertion.prototype, 'contain',
737 { get: function () {
73835 this.contains = true;
73935 return this;
740 },
741 configurable: true
742});
743
744/**
745 * # .keys(key1, [key2], [...])
746 *
747 * Assert exact keys or the inclusing of keys using the `contain` modifier.
748 *
749 * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
750 * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
751 *
752 * @name keys
753 * @alias key
754 * @param {String|Array} Keys
755 * @api public
756 */
757
7581Assertion.prototype.keys = function(keys) {
75956 var str
760 , ok = true;
761
76256 keys = keys instanceof Array
763 ? keys
764 : Array.prototype.slice.call(arguments);
765
76664 if (!keys.length) throw new Error('keys required');
767
76848 var actual = Object.keys(this.obj)
769 , len = keys.length;
770
771 // Inclusion
77248 ok = keys.every(function(key){
77370 return ~actual.indexOf(key);
774 });
775
776 // Strict
77748 if (!this.negate && !this.contains) {
77812 ok = ok && keys.length == actual.length;
779 }
780
781 // Key string
78248 if (len > 1) {
78326 keys = keys.map(function(key){
78454 return inspect(key);
785 });
78626 var last = keys.pop();
78726 str = keys.join(', ') + ', and ' + last;
788 } else {
78922 str = inspect(keys[0]);
790 }
791
792 // Form
79348 str = (len > 1 ? 'keys ' : 'key ') + str;
794
795 // Have / include
79648 str = (this.contains ? 'contain ' : 'have ') + str;
797
798 // Assertion
79948 this.assert(
800 ok
801 , 'expected ' + this.inspect + ' to ' + str
802 , 'expected ' + this.inspect + ' to not ' + str);
803
80432 return this;
805}
806
807/**
808 * # .throw(constructor)
809 *
810 * Assert that a function will throw a specific type of error.
811 *
812 * var fn = function () { throw new ReferenceError(''); }
813 * expect(fn).to.throw(ReferenceError);
814 *
815 * @name throw
816 * @alias throws
817 * @alias Throw
818 * @param {ErrorConstructor} constructor
819 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
820 * @api public
821 */
822
8231Assertion.prototype.throw = function (constructor) {
82445 new Assertion(this.obj).is.a('function');
825
82645 var thrown = false;
827
82845 try {
82945 this.obj();
830 } catch (err) {
83135 if (constructor && 'function' === typeof constructor && constructor.constructor != RegExp) {
83220 this.assert(
833 err instanceof constructor && err.name == constructor.name
834 , 'expected ' + this.inspect + ' to throw ' + constructor.name + ' but a ' + err.name + ' was thrown'
835 , 'expected ' + this.inspect + ' to not throw ' + constructor.name );
83612 return this;
83715 } else if (constructor && constructor instanceof RegExp) {
8388 this.assert(
839 constructor.exec(err.message)
840 , 'expected ' + this.inspect + ' to throw error matching ' + constructor + ' but got ' + inspect(err.message)
841 , 'expected ' + this.inspect + ' to throw error not matching ' + constructor);
8424 return this;
843 } else {
8447 thrown = true;
845 }
846 }
847
84817 var name = (constructor ? constructor.name : 'an error');
849
85017 this.assert(
851 thrown === true
852 , 'expected ' + this.inspect + ' to throw ' + name
853 , 'expected ' + this.inspect + ' to not throw ' + name);
854
85511 return this;
856};
857
858/**
859 * # .respondTo(method)
860 *
861 * Assert that object/class will respond to a method.
862 *
863 * expect(Klass).to.respondTo('bar');
864 * expect(obj).to.respondTo('bar');
865 *
866 * @name respondTo
867 * @param {String} method
868 * @api public
869 */
870
8711Assertion.prototype.respondTo = function (method) {
87210 var context = ('function' === typeof this.obj)
873 ? this.obj.prototype[method]
874 : this.obj[method];
875
87610 this.assert(
877 'function' === typeof context
878 , 'expected ' + this.inspect + ' to respond to ' + inspect(method)
879 , 'expected ' + this.inspect + ' to not respond to ' + inspect(method));
880
8816 return this;
882};
883
884/**
885 * # .satisfy(method)
886 *
887 * Assert that passes a truth test.
888 *
889 * expect(1).to.satisfy(function(num) { return num > 0; });
890 *
891 * @name satisfy
892 * @param {Function} matcher
893 * @api public
894 */
895
8961Assertion.prototype.satisfy = function (matcher) {
8974 this.assert(
898 matcher(this.obj)
899 , 'expected ' + this.inspect + ' to satisfy ' + inspect(matcher)
900 , 'expected ' + this.inspect + ' to not satisfy' + inspect(matcher));
901
9022 return this;
903};
904
905/**
906 * # .closeTo(expected, delta)
907 *
908 * Assert that actual is equal to +/- delta.
909 *
910 * expect(1.5).to.be.closeTo(1, 0.5);
911 *
912 * @name closeTo
913 * @param {Number} expected
914 * @param {Number} delta
915 * @api public
916 */
917
9181Assertion.prototype.closeTo = function (expected, delta) {
9194 this.assert(
920 (this.obj - delta === expected) || (this.obj + delta === expected)
921 , 'expected ' + this.inspect + ' to be close to ' + expected + ' +/- ' + delta
922 , 'expected ' + this.inspect + ' not to be close to ' + expected + ' +/- ' + delta);
923
9242 return this;
925};
926
927/*!
928 * Aliases.
929 */
930
9311(function alias(name, as){
9328 Assertion.prototype[as] = Assertion.prototype[name];
9338 return alias;
934})
935('length', 'lengthOf')
936('keys', 'key')
937('ownProperty', 'haveOwnProperty')
938('above', 'greaterThan')
939('below', 'lessThan')
940('throw', 'throws')
941('throw', 'Throw') // for troublesome browsers
942('instanceof', 'instanceOf');

error.js

91%
23
21
2
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
71var fail = require('./chai').fail;
8
91module.exports = AssertionError;
10
11/*!
12 * Inspired by node.js assert module
13 * https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js
14 */
151function AssertionError (options) {
16124 options = options || {};
17124 this.name = 'AssertionError';
18124 this.message = options.message;
19124 this.actual = options.actual;
20124 this.expected = options.expected;
21124 this.operator = options.operator;
22124 var stackStartFunction = options.stackStartFunction || fail;
23
24124 if (Error.captureStackTrace) {
25124 Error.captureStackTrace(this, stackStartFunction);
26 }
27}
28
291AssertionError.prototype.__proto__ = Error.prototype;
30
311AssertionError.prototype.summary = function() {
322 var str = '';
33
342 if (this.operator) {
350 str += 'In: \'' + this.operator + '\'\n\t';
36 }
37
382 str += '' + this.name + (this.message ? ': ' + this.message : '');
39
402 return str;
41};
42
431AssertionError.prototype.details = function() {
440 return this.summary();
45};
46
471AssertionError.prototype.toString = function() {
482 return this.summary();
49};

utils/eql.js

68%
45
31
14
LineHitsSource
1// This is directly from Node.js assert
2// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js
3
4
51module.exports = _deepEqual;
6
7// For browser implementation
81if (!Buffer) {
91 var Buffer = {
10 isBuffer: function () {
116 return false;
12 }
13 };
14}
15
161function _deepEqual(actual, expected) {
17 // 7.1. All identical values are equivalent, as determined by ===.
1812 if (actual === expected) {
196 return true;
20
216 } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
220 if (actual.length != expected.length) return false;
23
240 for (var i = 0; i < actual.length; i++) {
250 if (actual[i] !== expected[i]) return false;
26 }
27
280 return true;
29
30 // 7.2. If the expected value is a Date object, the actual value is
31 // equivalent if it is also a Date object that refers to the same time.
326 } else if (actual instanceof Date && expected instanceof Date) {
330 return actual.getTime() === expected.getTime();
34
35 // 7.3. Other pairs that do not both pass typeof value == 'object',
36 // equivalence is determined by ==.
376 } else if (typeof actual != 'object' && typeof expected != 'object') {
384 return actual === expected;
39
40 // 7.4. For all other Object pairs, including Array objects, equivalence is
41 // determined by having the same number of owned properties (as verified
42 // with Object.prototype.hasOwnProperty.call), the same set of keys
43 // (although not necessarily the same order), equivalent values for every
44 // corresponding key, and an identical 'prototype' property. Note: this
45 // accounts for both named and indexed properties on Arrays.
46 } else {
472 return objEquiv(actual, expected);
48 }
49}
50
511function isUndefinedOrNull(value) {
524 return value === null || value === undefined;
53}
54
551function isArguments(object) {
562 return Object.prototype.toString.call(object) == '[object Arguments]';
57}
58
591function objEquiv(a, b) {
602 if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
610 return false;
62 // an identical 'prototype' property.
632 if (a.prototype !== b.prototype) return false;
64 //~~~I've managed to break Object.keys through screwy arguments passing.
65 // Converting to array solves the problem.
662 if (isArguments(a)) {
670 if (!isArguments(b)) {
680 return false;
69 }
700 a = pSlice.call(a);
710 b = pSlice.call(b);
720 return _deepEqual(a, b);
73 }
742 try {
752 var ka = Object.keys(a),
76 kb = Object.keys(b),
77 key, i;
78 } catch (e) {//happens when one is a string literal and the other isn't
790 return false;
80 }
81 // having the same number of owned properties (keys incorporates
82 // hasOwnProperty)
832 if (ka.length != kb.length)
840 return false;
85 //the same set of keys (although not necessarily the same order),
862 ka.sort();
872 kb.sort();
88 //~~~cheap key test
892 for (i = ka.length - 1; i >= 0; i--) {
902 if (ka[i] != kb[i])
910 return false;
92 }
93 //equivalent values for every corresponding key, and
94 //~~~possibly expensive deep test
952 for (i = ka.length - 1; i >= 0; i--) {
962 key = ka[i];
972 if (!_deepEqual(a[key], b[key])) return false;
98 }
992 return true;
100}

utils/inspect.js

76%
123
94
29
LineHitsSource
1// This is (almost) directly from Node.js utils
2// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
3
41module.exports = inspect;
5
6/**
7 * Echos the value of a value. Trys to print the value out
8 * in the best way possible given the different types.
9 *
10 * @param {Object} obj The object to print out.
11 * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
12 * properties of objects.
13 * @param {Number} depth Depth in which to descend in object. Default is 2.
14 * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
15 * output. Default is false (no coloring).
16 */
171function inspect(obj, showHidden, depth, colors) {
181745 var ctx = {
19 showHidden: showHidden,
20 seen: [],
212137 stylize: function (str) { return str; }
22 };
231745 return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
24}
25
261function formatValue(ctx, value, recurseTimes) {
27 // Provide a hook for user-specified inspect functions.
28 // Check that value is an object with an inspect function on it
292135 if (value && typeof value.inspect === 'function' &&
30 // Filter out the util module, it's inspect function is special
31 value.inspect !== exports.inspect &&
32 // Also filter out any prototype objects using the circular check.
33 !(value.constructor && value.constructor.prototype === value)) {
340 return value.inspect(recurseTimes);
35 }
36
37 // Primitive types cannot have properties
382135 var primitive = formatPrimitive(ctx, value);
392135 if (primitive) {
401675 return primitive;
41 }
42
43 // Look up the keys of the object.
44460 var visibleKeys = Object.keys(value);
45460 var keys = ctx.showHidden ? Object.getOwnPropertyNames(value) : visibleKeys;
46
47 // Some type of object without properties can be shortcutted.
48460 if (keys.length === 0) {
49248 if (typeof value === 'function') {
50222 var name = value.name ? ': ' + value.name : '';
51222 return ctx.stylize('[Function' + name + ']', 'special');
52 }
5326 if (isRegExp(value)) {
540 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
55 }
5626 if (isDate(value)) {
570 return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
58 }
5926 if (isError(value)) {
600 return formatError(value);
61 }
62 }
63
64238 var base = '', array = false, braces = ['{', '}'];
65
66 // Make Array say that they are Array
67238 if (isArray(value)) {
6878 array = true;
6978 braces = ['[', ']'];
70 }
71
72 // Make functions say that they are functions
73238 if (typeof value === 'function') {
740 var n = value.name ? ': ' + value.name : '';
750 base = ' [Function' + n + ']';
76 }
77
78 // Make RegExps say that they are RegExps
79238 if (isRegExp(value)) {
800 base = ' ' + RegExp.prototype.toString.call(value);
81 }
82
83 // Make dates with properties first say the date
84238 if (isDate(value)) {
850 base = ' ' + Date.prototype.toUTCString.call(value);
86 }
87
88 // Make error with message first say the error
89238 if (isError(value)) {
900 base = ' ' + formatError(value);
91 }
92
93238 if (keys.length === 0 && (!array || value.length == 0)) {
9426 return braces[0] + base + braces[1];
95 }
96
97212 if (recurseTimes < 0) {
980 if (isRegExp(value)) {
990 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
100 } else {
1010 return ctx.stylize('[Object]', 'special');
102 }
103 }
104
105212 ctx.seen.push(value);
106
107212 var output;
108212 if (array) {
10966 output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
110 } else {
111146 output = keys.map(function(key) {
112240 return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
113 });
114 }
115
116212 ctx.seen.pop();
117
118212 return reduceToSingleString(output, base, braces);
119}
120
121
1221function formatPrimitive(ctx, value) {
1232135 switch (typeof value) {
124 case 'undefined':
12518 return ctx.stylize('undefined', 'undefined');
126
127 case 'string':
1281199 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
129 .replace(/'/g, "\\'")
130 .replace(/\\"/g, '"') + '\'';
1311199 return ctx.stylize(simple, 'string');
132
133 case 'number':
134416 return ctx.stylize('' + value, 'number');
135
136 case 'boolean':
13742 return ctx.stylize('' + value, 'boolean');
138 }
139 // For some reason typeof null is "object", so special case here.
140460 if (value === null) {
1410 return ctx.stylize('null', 'null');
142 }
143}
144
145
1461function formatError(value) {
1470 return '[' + Error.prototype.toString.call(value) + ']';
148}
149
150
1511function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
15266 var output = [];
15366 for (var i = 0, l = value.length; i < l; ++i) {
154150 if (Object.prototype.hasOwnProperty.call(value, String(i))) {
155150 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
156 String(i), true));
157 } else {
1580 output.push('');
159 }
160 }
16166 keys.forEach(function(key) {
162150 if (!key.match(/^\d+$/)) {
1630 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
164 key, true));
165 }
166 });
16766 return output;
168}
169
170
1711function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
172390 var name, str;
173390 if (value.__lookupGetter__) {
174390 if (value.__lookupGetter__(key)) {
1750 if (value.__lookupSetter__(key)) {
1760 str = ctx.stylize('[Getter/Setter]', 'special');
177 } else {
1780 str = ctx.stylize('[Getter]', 'special');
179 }
180 } else {
181390 if (value.__lookupSetter__(key)) {
1820 str = ctx.stylize('[Setter]', 'special');
183 }
184 }
185 }
186390 if (visibleKeys.indexOf(key) < 0) {
1870 name = '[' + key + ']';
188 }
189390 if (!str) {
190390 if (ctx.seen.indexOf(value[key]) < 0) {
191390 if (recurseTimes === null) {
1920 str = formatValue(ctx, value[key], null);
193 } else {
194390 str = formatValue(ctx, value[key], recurseTimes - 1);
195 }
196390 if (str.indexOf('\n') > -1) {
1970 if (array) {
1980 str = str.split('\n').map(function(line) {
1990 return ' ' + line;
200 }).join('\n').substr(2);
201 } else {
2020 str = '\n' + str.split('\n').map(function(line) {
2030 return ' ' + line;
204 }).join('\n');
205 }
206 }
207 } else {
2080 str = ctx.stylize('[Circular]', 'special');
209 }
210 }
211390 if (typeof name === 'undefined') {
212390 if (array && key.match(/^\d+$/)) {
213150 return str;
214 }
215240 name = JSON.stringify('' + key);
216240 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
217228 name = name.substr(1, name.length - 2);
218228 name = ctx.stylize(name, 'name');
219 } else {
22012 name = name.replace(/'/g, "\\'")
221 .replace(/\\"/g, '"')
222 .replace(/(^"|"$)/g, "'");
22312 name = ctx.stylize(name, 'string');
224 }
225 }
226
227240 return name + ': ' + str;
228}
229
230
2311function reduceToSingleString(output, base, braces) {
232212 var numLinesEst = 0;
233212 var length = output.reduce(function(prev, cur) {
234390 numLinesEst++;
235390 if (cur.indexOf('\n') >= 0) numLinesEst++;
236390 return prev + cur.length + 1;
237 }, 0);
238
239212 if (length > 60) {
2400 return braces[0] +
241 (base === '' ? '' : base + '\n ') +
242 ' ' +
243 output.join(',\n ') +
244 ' ' +
245 braces[1];
246 }
247
248212 return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
249}
250
2511function isArray(ar) {
252238 return Array.isArray(ar) ||
253 (typeof ar === 'object' && objectToString(ar) === '[object Array]');
254}
255
2561function isRegExp(re) {
257264 return typeof re === 'object' && objectToString(re) === '[object RegExp]';
258}
259
2601function isDate(d) {
261264 return typeof d === 'object' && objectToString(d) === '[object Date]';
262}
263
2641function isError(e) {
265264 return typeof e === 'object' && objectToString(e) === '[object Error]';
266}
267
2681function objectToString(o) {
269952 return Object.prototype.toString.call(o);
270}

interface/expect.js

100%
3
3
0
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
71module.exports = function (chai) {
81 chai.expect = function (val, message) {
9216 return new chai.Assertion(val, message);
10 };
11};
12

interface/should.js

87%
24
21
3
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
71module.exports = function (chai) {
81 var Assertion = chai.Assertion;
9
101 chai.should = function () {
11 // modify Object.prototype to have `should`
121 Object.defineProperty(Object.prototype, 'should', {
13 set: function(){},
14 get: function(){
15144 if (this instanceof String || this instanceof Number) {
160 return new Assertion(this.constructor(this));
17144 } else if (this instanceof Boolean) {
180 return new Assertion(this == true);
19 }
20144 return new Assertion(this);
21 },
22 configurable: true
23 });
24
251 var should = {};
26
271 should.equal = function (val1, val2) {
2861 new Assertion(val1).to.equal(val2);
29 };
30
311 should.throw = function (fn, err) {
322 new Assertion(fn).to.throw(err);
33 };
34
351 should.exist = function (val) {
362 new Assertion(val).to.exist;
37 }
38
39 // negation
401 should.not = {}
41
421 should.not.equal = function (val1, val2) {
430 new Assertion(val1).to.not.equal(val2);
44 };
45
461 should.not.throw = function (fn, err) {
472 new Assertion(fn).to.not.throw(err);
48 };
49
501 should.not.exist = function (val) {
512 new Assertion(val).to.not.exist;
52 }
53
541 return should;
55 };
56};

interface/assert.js

64%
70
45
25
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/**
8 * ### TDD Style Introduction
9 *
10 * The TDD style is exposed through `assert` interfaces. This provides
11 * the classic assert.`test` notation, similiar to that packaged with
12 * node.js. This assert module, however, provides several additional
13 * tests and is browser compatible.
14 *
15 * // assert
16 * var assert = require('chai').assert;
17 * , foo = 'bar';
18 *
19 * assert.typeOf(foo, 'string');
20 * assert.equal(foo, 'bar');
21 *
22 * #### Configuration
23 *
24 * By default, Chai does not show stack traces upon an AssertionError. This can
25 * be changed by modifying the `includeStack` parameter for chai.Assertion. For example:
26 *
27 * var chai = require('chai');
28 * chai.Assertion.includeStack = true; // defaults to false
29 */
30
311module.exports = function (chai) {
32 /*!
33 * Chai dependencies.
34 */
351 var Assertion = chai.Assertion
36 , inspect = chai.inspect;
37
38 /*!
39 * Module export.
40 */
41
421 var assert = chai.assert = {};
43
44 /**
45 * # .ok(object, [message])
46 *
47 * Assert object is truthy.
48 *
49 * assert.ok('everthing', 'everything is ok');
50 * assert.ok(false, 'this will fail');
51 *
52 * @name ok
53 * @param {*} object to test
54 * @param {String} message
55 * @api public
56 */
57
581 assert.ok = function (val, msg) {
597 new Assertion(val, msg).is.ok;
60 };
61
62 /**
63 * # .equal(actual, expected, [message])
64 *
65 * Assert strict equality.
66 *
67 * assert.equal(3, 3, 'these numbers are equal');
68 *
69 * @name equal
70 * @param {*} actual
71 * @param {*} expected
72 * @param {String} message
73 * @api public
74 */
75
761 assert.equal = function (act, exp, msg) {
7716 var test = new Assertion(act, msg);
78
7916 test.assert(
80 exp == test.obj
81 , 'expected ' + test.inspect + ' to equal ' + inspect(exp)
82 , 'expected ' + test.inspect + ' to not equal ' + inspect(exp));
83 };
84
85 /**
86 * # .notEqual(actual, expected, [message])
87 *
88 * Assert not equal.
89 *
90 * assert.notEqual(3, 4, 'these numbers are not equal');
91 *
92 * @name notEqual
93 * @param {*} actual
94 * @param {*} expected
95 * @param {String} message
96 * @api public
97 */
98
991 assert.notEqual = function (act, exp, msg) {
1000 var test = new Assertion(act, msg);
101
1020 test.assert(
103 exp != test.obj
104 , 'expected ' + test.inspect + ' to equal ' + inspect(exp)
105 , 'expected ' + test.inspect + ' to not equal ' + inspect(exp));
106 };
107
108 /**
109 * # .strictEqual(actual, expected, [message])
110 *
111 * Assert strict equality.
112 *
113 * assert.strictEqual(true, true, 'these booleans are strictly equal');
114 *
115 * @name strictEqual
116 * @param {*} actual
117 * @param {*} expected
118 * @param {String} message
119 * @api public
120 */
121
1221 assert.strictEqual = function (act, exp, msg) {
1230 new Assertion(act, msg).to.equal(exp);
124 };
125
126 /**
127 * # .notStrictEqual(actual, expected, [message])
128 *
129 * Assert strict equality.
130 *
131 * assert.notStrictEqual(1, true, 'these booleans are not strictly equal');
132 *
133 * @name notStrictEqual
134 * @param {*} actual
135 * @param {*} expected
136 * @param {String} message
137 * @api public
138 */
139
1401 assert.notStrictEqual = function (act, exp, msg) {
1410 new Assertion(act, msg).to.not.equal(exp);
142 };
143
144 /**
145 * # .deepEqual(actual, expected, [message])
146 *
147 * Assert not deep equality.
148 *
149 * assert.deepEqual({ tea: 'green' }, { tea: 'green' });
150 *
151 * @name deepEqual
152 * @param {*} actual
153 * @param {*} expected
154 * @param {String} message
155 * @api public
156 */
157
1581 assert.deepEqual = function (act, exp, msg) {
1590 new Assertion(act, msg).to.eql(exp);
160 };
161
162 /**
163 * # .notDeepEqual(actual, expected, [message])
164 *
165 * Assert not deep equality.
166 *
167 * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
168 *
169 * @name notDeepEqual
170 * @param {*} actual
171 * @param {*} expected
172 * @param {String} message
173 * @api public
174 */
175
1761 assert.notDeepEqual = function (act, exp, msg) {
1770 new Assertion(act, msg).to.not.eql(exp);
178 };
179
180 /**
181 * # .isTrue(value, [message])
182 *
183 * Assert `value` is true.
184 *
185 * var tea_served = true;
186 * assert.isTrue(tea_served, 'the tea has been served');
187 *
188 * @name isTrue
189 * @param {Boolean} value
190 * @param {String} message
191 * @api public
192 */
193
1941 assert.isTrue = function (val, msg) {
1954 new Assertion(val, msg).is.true;
196 };
197
198 /**
199 * # .isFalse(value, [message])
200 *
201 * Assert `value` is false.
202 *
203 * var tea_served = false;
204 * assert.isFalse(tea_served, 'no tea yet? hmm...');
205 *
206 * @name isFalse
207 * @param {Boolean} value
208 * @param {String} message
209 * @api public
210 */
211
2121 assert.isFalse = function (val, msg) {
2133 new Assertion(val, msg).is.false;
214 };
215
216 /**
217 * # .isNull(value, [message])
218 *
219 * Assert `value` is null.
220 *
221 * assert.isNull(err, 'no errors');
222 *
223 * @name isNull
224 * @param {*} value
225 * @param {String} message
226 * @api public
227 */
228
2291 assert.isNull = function (val, msg) {
2300 new Assertion(val, msg).to.not.exist;
231 };
232
233 /**
234 * # .isNotNull(value, [message])
235 *
236 * Assert `value` is not null.
237 *
238 * var tea = 'tasty chai';
239 * assert.isNotNull(tea, 'great, time for tea!');
240 *
241 * @name isNotNull
242 * @param {*} value
243 * @param {String} message
244 * @api public
245 */
246
2471 assert.isNotNull = function (val, msg) {
2480 new Assertion(val, msg).to.exist;
249 };
250
251 /**
252 * # .isUndefined(value, [message])
253 *
254 * Assert `value` is undefined.
255 *
256 * assert.isUndefined(tea, 'no tea defined');
257 *
258 * @name isUndefined
259 * @param {*} value
260 * @param {String} message
261 * @api public
262 */
263
2641 assert.isUndefined = function (val, msg) {
2650 new Assertion(val, msg).to.equal(undefined);
266 };
267
268 /**
269 * # .isFunction(value, [message])
270 *
271 * Assert `value` is a function.
272 *
273 * var serve_tea = function () { return 'cup of tea'; };
274 * assert.isFunction(serve_tea, 'great, we can have tea now');
275 *
276 * @name isFunction
277 * @param {Function} value
278 * @param {String} message
279 * @api public
280 */
281
2821 assert.isFunction = function (val, msg) {
2830 new Assertion(val, msg).to.be.a('function');
284 };
285
286 /**
287 * # .isObject(value, [message])
288 *
289 * Assert `value` is an object.
290 *
291 * var selection = { name: 'Chai', serve: 'with spices' };
292 * assert.isObject(selection, 'tea selection is an object');
293 *
294 * @name isObject
295 * @param {Object} value
296 * @param {String} message
297 * @api public
298 */
299
3001 assert.isObject = function (val, msg) {
3015 new Assertion(val, msg).to.be.a('object');
302 };
303
304 /**
305 * # .isArray(value, [message])
306 *
307 * Assert `value` is an instance of Array.
308 *
309 * var menu = [ 'green', 'chai', 'oolong' ];
310 * assert.isArray(menu, 'what kind of tea do we want?');
311 *
312 * @name isArray
313 * @param {*} value
314 * @param {String} message
315 * @api public
316 */
317
3181 assert.isArray = function (val, msg) {
3190 new Assertion(val, msg).to.be.instanceof(Array);
320 };
321
322 /**
323 * # .isString(value, [message])
324 *
325 * Assert `value` is a string.
326 *
327 * var teaorder = 'chai';
328 * assert.isString(tea_order, 'order placed');
329 *
330 * @name isString
331 * @param {String} value
332 * @param {String} message
333 * @api public
334 */
335
3361 assert.isString = function (val, msg) {
3370 new Assertion(val, msg).to.be.a('string');
338 };
339
340 /**
341 * # .isNumber(value, [message])
342 *
343 * Assert `value` is a number
344 *
345 * var cups = 2;
346 * assert.isNumber(cups, 'how many cups');
347 *
348 * @name isNumber
349 * @param {Number} value
350 * @param {String} message
351 * @api public
352 */
353
3541 assert.isNumber = function (val, msg) {
3550 new Assertion(val, msg).to.be.instanceof(Number);
356 };
357
358 /**
359 * # .isBoolean(value, [message])
360 *
361 * Assert `value` is a boolean
362 *
363 * var teaready = true
364 * , teaserved = false;
365 *
366 * assert.isBoolean(tea_ready, 'is the tea ready');
367 * assert.isBoolean(tea_served, 'has tea been served');
368 *
369 * @name isBoolean
370 * @param {*} value
371 * @param {String} message
372 * @api public
373 */
374
3751 assert.isBoolean = function (val, msg) {
3760 new Assertion(val, msg).to.be.a('boolean');
377 };
378
379 /**
380 * # .typeOf(value, name, [message])
381 *
382 * Assert typeof `value` is `name`.
383 *
384 * assert.typeOf('tea', 'string', 'we have a string');
385 *
386 * @name typeOf
387 * @param {*} value
388 * @param {String} typeof name
389 * @param {String} message
390 * @api public
391 */
392
3931 assert.typeOf = function (val, type, msg) {
3944 new Assertion(val, msg).to.be.a(type);
395 };
396
397 /**
398 * # .instanceOf(object, constructor, [message])
399 *
400 * Assert `value` is instanceof `constructor`.
401 *
402 * var Tea = function (name) { this.name = name; }
403 * , Chai = new Tea('chai');
404 *
405 * assert.instanceOf(Chai, Tea, 'chai is an instance of tea');
406 *
407 * @name instanceOf
408 * @param {Object} object
409 * @param {Constructor} constructor
410 * @param {String} message
411 * @api public
412 */
413
4141 assert.instanceOf = function (val, type, msg) {
4152 new Assertion(val, msg).to.be.instanceof(type);
416 };
417
418 /**
419 * # .include(value, includes, [message])
420 *
421 * Assert the inclusion of an object in another. Works
422 * for strings and arrays.
423 *
424 * assert.include('foobar', 'bar', 'foobar contains string `var`);
425 * assert.include([ 1, 2, 3], 3, 'array contains value);
426 *
427 * @name include
428 * @param {Array|String} value
429 * @param {*} includes
430 * @param {String} message
431 * @api public
432 */
433
4341 assert.include = function (exp, inc, msg) {
4351 var obj = new Assertion(exp, msg);
436
4371 if (Array.isArray(exp)) {
4380 obj.to.include(inc);
4391 } else if ('string' === typeof exp) {
4401 obj.to.contain.string(inc);
441 }
442 };
443
444 /**
445 * # .match(value, regex, [message])
446 *
447 * Assert that `value` matches regular expression.
448 *
449 * assert.match('foobar', /^foo/, 'Regexp matches');
450 *
451 * @name match
452 * @param {*} value
453 * @param {RegExp} RegularExpression
454 * @param {String} message
455 * @api public
456 */
457
4581 assert.match = function (exp, re, msg) {
4591 new Assertion(exp, msg).to.match(re);
460 };
461
462 /**
463 * # .length(value, constructor, [message])
464 *
465 * Assert that object has expected length.
466 *
467 * assert.length([1,2,3], 3, 'Array has length of 3');
468 * assert.length('foobar', 5, 'String has length of 6');
469 *
470 * @name length
471 * @param {*} value
472 * @param {Number} length
473 * @param {String} message
474 * @api public
475 */
476
4771 assert.length = function (exp, len, msg) {
4780 new Assertion(exp, msg).to.have.length(len);
479 };
480
481 /**
482 * # .throws(function, [constructor/regexp], [message])
483 *
484 * Assert that a function will throw a specific
485 * type of error.
486 *
487 * assert.throw(fn, ReferenceError, 'function throw reference error');
488 *
489 * @name throws
490 * @alias throw
491 * @param {Function} function to test
492 * @param {ErrorConstructor} constructor
493 * @param {String} message
494 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
495 * @api public
496 */
497
4981 assert.throws = function (fn, type, msg) {
4990 if ('string' === typeof type) {
5000 msg = type;
5010 type = null;
502 }
503
5040 new Assertion(fn, msg).to.throw(type);
505 };
506
507 /**
508 * # .doesNotThrow(function, [constructor/regexp], [message])
509 *
510 * Assert that a function will throw a specific
511 * type of error.
512 *
513 * var fn = function (err) { if (err) throw Error(err) };
514 * assert.doesNotThrow(fn, Error, 'function throw reference error');
515 *
516 * @name doesNotThrow
517 * @param {Function} function to test
518 * @param {ErrorConstructor} constructor
519 * @param {String} message
520 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
521 * @api public
522 */
523
5241 assert.doesNotThrow = function (fn, type, msg) {
5250 if ('string' === typeof type) {
5260 msg = type;
5270 type = null;
528 }
529
5300 new Assertion(fn, msg).to.not.throw(type);
531 };
532
533 /*!
534 * Undocumented / untested
535 */
536
5371 assert.ifError = function (val, msg) {
5380 new Assertion(val, msg).to.not.be.ok;
539 };
540
541 /*!
542 * Aliases.
543 */
544
5451 (function alias(name, as){
5462 assert[as] = assert[name];
5472 return alias;
548 })
549 ('length', 'lengthOf')
550 ('throws', 'throw');
551};