Coverage

90%
473
430
43

chai.js

100%
17
17
0
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.5.2';
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
261var expect = require('./interface/expect');
271exports.use(expect);
28
291var should = require('./interface/should');
301exports.use(should);
31
321var assert = require('./interface/assert');
331exports.use(assert);

assertion.js

100%
167
167
0
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 node.js and in all browsers.
30 *
31 * The `should` interface extends `Object.prototype` to provide a single getter as
32 * the starting point for your language assertions. It works on node.js and in
33 * all browsers except Internet Explorer.
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 , toString = Object.prototype.toString
51 , inspect = require('./utils/inspect');
52
53/*!
54 * Module export.
55 */
56
571module.exports = Assertion;
58
59
60/*!
61 * # Assertion Constructor
62 *
63 * Creates object for chaining.
64 *
65 * @api private
66 */
67
681function Assertion (obj, msg, stack) {
69738 this.ssfi = stack || arguments.callee;
70738 this.obj = obj;
71738 this.msg = msg;
72}
73
74/*!
75 * ## Assertion.includeStack
76 * , toString = Object.prototype.toString
77 *
78 * User configurable property, influences whether stack trace
79 * is included in Assertion error message. Default of false
80 * suppresses stack trace in the error message
81 *
82 * Assertion.includeStack = true; // enable stack on error
83 *
84 * @api public
85 */
86
871Assertion.includeStack = false;
88
89/*!
90 * # .assert(expression, message, negateMessage, expected, actual)
91 *
92 * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
93 *
94 * @name assert
95 * @param {Philosophical} expression to be tested
96 * @param {String} message to display if fails
97 * @param {String} negatedMessage to display if negated expression fails
98 * @param {*} expected value (remember to check for negation)
99 * @param {*} actual (optional) will default to `this.obj`
100 * @api private
101 */
102
1031Assertion.prototype.assert = function (expr, msg, negateMsg, expected, actual) {
104744 actual = actual || this.obj;
105744 var msg = (this.negate ? negateMsg : msg)
106 , ok = this.negate ? !expr : expr;
107
108744 if (!ok) {
109167 throw new AssertionError({
110 message: this.msg ? this.msg + ': ' + msg : msg // include custom message if available
111 , actual: actual
112 , expected: expected
113 , stackStartFunction: (Assertion.includeStack) ? this.assert : this.ssfi
114 });
115 }
116};
117
118/*!
119 * # inspect
120 *
121 * Returns the current object stringified.
122 *
123 * @name inspect
124 * @api private
125 */
126
1271Object.defineProperty(Assertion.prototype, 'inspect',
128 { get: function () {
1291462 return inspect(this.obj);
130 }
131 , configurable: true
132});
133
134/**
135 * # to
136 *
137 * Language chain.
138 *
139 * @name to
140 * @api public
141 */
142
1431Object.defineProperty(Assertion.prototype, 'to',
144 { get: function () {
145408 return this;
146 }
147 , configurable: true
148});
149
150/**
151 * # be
152 *
153 * Language chain.
154 *
155 * @name be
156 * @api public
157 */
158
1591Object.defineProperty(Assertion.prototype, 'be',
160 { get: function () {
161163 return this;
162 }
163 , configurable: true
164});
165
166/**
167 * # been
168 *
169 * Language chain. Also tests `tense` to past for addon
170 * modules that use the tense feature.
171 *
172 * @name been
173 * @api public
174 */
175
1761Object.defineProperty(Assertion.prototype, 'been',
177 { get: function () {
1781 this.tense = 'past';
1791 return this;
180 }
181 , configurable: true
182});
183
184/**
185 * # an
186 *
187 * Language chain.
188 *
189 * @name an
190 * @api public
191 */
192
1931Object.defineProperty(Assertion.prototype, 'an',
194 { get: function () {
1954 return this;
196 }
197 , configurable: true
198});
199/**
200 * # is
201 *
202 * Language chain.
203 *
204 * @name is
205 * @api public
206 */
207
2081Object.defineProperty(Assertion.prototype, 'is',
209 { get: function () {
21094 return this;
211 }
212 , configurable: true
213});
214
215/**
216 * # and
217 *
218 * Language chain.
219 *
220 * @name and
221 * @api public
222 */
223
2241Object.defineProperty(Assertion.prototype, 'and',
225 { get: function () {
2261 return this;
227 }
228 , configurable: true
229});
230
231/**
232 * # have
233 *
234 * Language chain.
235 *
236 * @name have
237 * @api public
238 */
239
2401Object.defineProperty(Assertion.prototype, 'have',
241 { get: function () {
24292 return this;
243 }
244 , configurable: true
245});
246
247/**
248 * # with
249 *
250 * Language chain.
251 *
252 * @name with
253 * @api public
254 */
255
2561Object.defineProperty(Assertion.prototype, 'with',
257 { get: function () {
2582 return this;
259 }
260 , configurable: true
261});
262
263/**
264 * # .not
265 *
266 * Negates any of assertions following in the chain.
267 *
268 * @name not
269 * @api public
270 */
271
2721Object.defineProperty(Assertion.prototype, 'not',
273 { get: function () {
274145 this.negate = true;
275145 return this;
276 }
277 , configurable: true
278});
279
280/**
281 * # .ok
282 *
283 * Assert object truthiness.
284 *
285 * expect('everthing').to.be.ok;
286 * expect(false).to.not.be.ok;
287 * expect(undefined).to.not.be.ok;
288 * expect(null).to.not.be.ok;
289 *
290 * @name ok
291 * @api public
292 */
293
2941Object.defineProperty(Assertion.prototype, 'ok',
295 { get: function () {
29623 this.assert(
297 this.obj
298 , 'expected ' + this.inspect + ' to be truthy'
299 , 'expected ' + this.inspect + ' to be falsy');
300
30115 return this;
302 }
303 , configurable: true
304});
305
306/**
307 * # .true
308 *
309 * Assert object is true
310 *
311 * @name true
312 * @api public
313 */
314
3151Object.defineProperty(Assertion.prototype, 'true',
316 { get: function () {
31712 this.assert(
318 true === this.obj
319 , 'expected ' + this.inspect + ' to be true'
320 , 'expected ' + this.inspect + ' to be false'
321 , this.negate ? false : true
322 );
323
3247 return this;
325 }
326 , configurable: true
327});
328
329/**
330 * # .false
331 *
332 * Assert object is false
333 *
334 * @name false
335 * @api public
336 */
337
3381Object.defineProperty(Assertion.prototype, 'false',
339 { get: function () {
34012 this.assert(
341 false === this.obj
342 , 'expected ' + this.inspect + ' to be false'
343 , 'expected ' + this.inspect + ' to be true'
344 , this.negate ? true : false
345 );
346
3478 return this;
348 }
349 , configurable: true
350});
351
352/**
353 * # .exist
354 *
355 * Assert object exists (null).
356 *
357 * var foo = 'hi'
358 * , bar;
359 * expect(foo).to.exist;
360 * expect(bar).to.not.exist;
361 *
362 * @name exist
363 * @api public
364 */
365
3661Object.defineProperty(Assertion.prototype, 'exist',
367 { get: function () {
3686 this.assert(
369 null != this.obj
370 , 'expected ' + this.inspect + ' to exist'
371 , 'expected ' + this.inspect + ' to not exist'
372 );
373
3744 return this;
375 }
376 , configurable: true
377});
378
379/**
380 * # .empty
381 *
382 * Assert object's length to be 0.
383 *
384 * expect([]).to.be.empty;
385 *
386 * @name empty
387 * @api public
388 */
389
3901Object.defineProperty(Assertion.prototype, 'empty',
391 { get: function () {
39232 var expected = this.obj;
393
39432 if (Array.isArray(this.obj)) {
3958 expected = this.obj.length;
39624 } else if (typeof this.obj === 'object') {
39716 expected = Object.keys(this.obj).length;
398 }
399
40032 this.assert(
401 !expected
402 , 'expected ' + this.inspect + ' to be empty'
403 , 'expected ' + this.inspect + ' not to be empty');
404
40516 return this;
406 }
407 , configurable: true
408});
409
410/**
411 * # .arguments
412 *
413 * Assert object is an instanceof arguments.
414 *
415 * function test () {
416 * expect(arguments).to.be.arguments;
417 * }
418 *
419 * @name arguments
420 * @api public
421 */
422
4231Object.defineProperty(Assertion.prototype, 'arguments',
424 { get: function () {
4254 this.assert(
426 '[object Arguments]' == Object.prototype.toString.call(this.obj)
427 , 'expected ' + this.inspect + ' to be arguments'
428 , 'expected ' + this.inspect + ' to not be arguments'
429 , '[object Arguments]'
430 , Object.prototype.toString.call(this.obj)
431 );
432
4334 return this;
434 }
435 , configurable: true
436});
437
438/**
439 * # .equal(value)
440 *
441 * Assert strict equality.
442 *
443 * expect('hello').to.equal('hello');
444 *
445 * @name equal
446 * @param {*} value
447 * @api public
448 */
449
4501Assertion.prototype.equal = function (val) {
451161 this.assert(
452 val === this.obj
453 , 'expected ' + this.inspect + ' to equal ' + inspect(val)
454 , 'expected ' + this.inspect + ' to not equal ' + inspect(val)
455 , val );
456
457151 return this;
458};
459
460/**
461 * # .eql(value)
462 *
463 * Assert deep equality.
464 *
465 * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
466 *
467 * @name eql
468 * @param {*} value
469 * @api public
470 */
471
4721Assertion.prototype.eql = function (obj) {
47314 this.assert(
474 eql(obj, this.obj)
475 , 'expected ' + this.inspect + ' to equal ' + inspect(obj)
476 , 'expected ' + this.inspect + ' to not equal ' + inspect(obj)
477 , obj );
478
47910 return this;
480};
481
482/**
483 * # .above(value)
484 *
485 * Assert greater than `value`.
486 *
487 * expect(10).to.be.above(5);
488 *
489 * @name above
490 * @param {Number} value
491 * @api public
492 */
493
4941Assertion.prototype.above = function (val) {
49512 this.assert(
496 this.obj > val
497 , 'expected ' + this.inspect + ' to be above ' + val
498 , 'expected ' + this.inspect + ' to be below ' + val);
499
5008 return this;
501};
502
503/**
504 * # .below(value)
505 *
506 * Assert less than `value`.
507 *
508 * expect(5).to.be.below(10);
509 *
510 * @name below
511 * @param {Number} value
512 * @api public
513 */
514
5151Assertion.prototype.below = function (val) {
51612 this.assert(
517 this.obj < val
518 , 'expected ' + this.inspect + ' to be below ' + val
519 , 'expected ' + this.inspect + ' to be above ' + val);
520
5218 return this;
522};
523
524/**
525 * # .within(start, finish)
526 *
527 * Assert that a number is within a range.
528 *
529 * expect(7).to.be.within(5,10);
530 *
531 * @name within
532 * @param {Number} start lowerbound inclusive
533 * @param {Number} finish upperbound inclusive
534 * @api public
535 */
536
5371Assertion.prototype.within = function (start, finish) {
53812 var range = start + '..' + finish;
539
54012 this.assert(
541 this.obj >= start && this.obj <= finish
542 , 'expected ' + this.inspect + ' to be within ' + range
543 , 'expected ' + this.inspect + ' to not be within ' + range);
544
5458 return this;
546};
547
548/**
549 * # .a(type)
550 *
551 * Assert typeof.
552 *
553 * expect('test').to.be.a('string');
554 *
555 * @name a
556 * @param {String} type
557 * @api public
558 */
559
5601Assertion.prototype.a = function (type) {
561128 var klass = type.charAt(0).toUpperCase() + type.slice(1);
562
563128 this.assert(
564 '[object ' + klass + ']' === toString.call(this.obj)
565 , 'expected ' + this.inspect + ' to be a ' + type
566 , 'expected ' + this.inspect + ' not to be a ' + type
567 , '[object ' + klass + ']'
568 , toString.call(this.obj)
569 );
570
571114 return this;
572};
573
574/**
575 * # .instanceof(constructor)
576 *
577 * Assert instanceof.
578 *
579 * var Tea = function (name) { this.name = name; }
580 * , Chai = new Tea('chai');
581 *
582 * expect(Chai).to.be.an.instanceOf(Tea);
583 *
584 * @name instanceof
585 * @param {Constructor}
586 * @alias instanceOf
587 * @api public
588 */
589
5901Assertion.prototype.instanceof = function (constructor) {
5919 var name = constructor.name;
5929 this.assert(
593 this.obj instanceof constructor
594 , 'expected ' + this.inspect + ' to be an instance of ' + name
595 , 'expected ' + this.inspect + ' to not be an instance of ' + name);
596
5975 return this;
598};
599
600/**
601 * # .property(name, [value])
602 *
603 * Assert that property of `name` exists, optionally with `value`.
604 *
605 * var obj = { foo: 'bar' }
606 * expect(obj).to.have.property('foo');
607 * expect(obj).to.have.property('foo', 'bar');
608 * expect(obj).to.have.property('foo').to.be.a('string');
609 *
610 * @name property
611 * @param {String} name
612 * @param {*} value (optional)
613 * @returns value of property for chaining
614 * @api public
615 */
616
6171Assertion.prototype.property = function (name, val) {
61837 if (this.negate && undefined !== val) {
6194 if (undefined === this.obj[name]) {
6202 throw new Error(this.inspect + ' has no property ' + inspect(name));
621 }
622 } else {
62333 this.assert(
624 undefined !== this.obj[name]
625 , 'expected ' + this.inspect + ' to have a property ' + inspect(name)
626 , 'expected ' + this.inspect + ' to not have property ' + inspect(name));
627 }
628
62930 if (undefined !== val) {
63011 this.assert(
631 val === this.obj[name]
632 , 'expected ' + this.inspect + ' to have a property ' + inspect(name) + ' of ' +
633 inspect(val) + ', but got ' + inspect(this.obj[name])
634 , 'expected ' + this.inspect + ' to not have a property ' + inspect(name) + ' of ' + inspect(val)
635 , val
636 , this.obj[val]
637 );
638 }
639
64024 this.obj = this.obj[name];
64124 return this;
642};
643
644/**
645 * # .ownProperty(name)
646 *
647 * Assert that has own property by `name`.
648 *
649 * expect('test').to.have.ownProperty('length');
650 *
651 * @name ownProperty
652 * @alias haveOwnProperty
653 * @param {String} name
654 * @api public
655 */
656
6571Assertion.prototype.ownProperty = function (name) {
6588 this.assert(
659 this.obj.hasOwnProperty(name)
660 , 'expected ' + this.inspect + ' to have own property ' + inspect(name)
661 , 'expected ' + this.inspect + ' to not have own property ' + inspect(name));
6626 return this;
663};
664
665/**
666 * # .length(val)
667 *
668 * Assert that object has expected length.
669 *
670 * expect([1,2,3]).to.have.length(3);
671 * expect('foobar').to.have.length(6);
672 *
673 * @name length
674 * @alias lengthOf
675 * @param {Number} length
676 * @api public
677 */
678
6791Assertion.prototype.length = function (n) {
68016 new Assertion(this.obj).to.have.property('length');
68113 var len = this.obj.length;
682
68313 this.assert(
684 len == n
685 , 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len
686 , 'expected ' + this.inspect + ' to not have a length of ' + len
687 , n
688 , len
689 );
690
6919 return this;
692};
693
694/**
695 * # .match(regexp)
696 *
697 * Assert that matches regular expression.
698 *
699 * expect('foobar').to.match(/^foo/);
700 *
701 * @name match
702 * @param {RegExp} RegularExpression
703 * @api public
704 */
705
7061Assertion.prototype.match = function (re) {
70711 this.assert(
708 re.exec(this.obj)
709 , 'expected ' + this.inspect + ' to match ' + re
710 , 'expected ' + this.inspect + ' not to match ' + re);
711
7127 return this;
713};
714
715/**
716 * # .include(obj)
717 *
718 * Assert the inclusion of an object in an Array or substring in string.
719 *
720 * expect([1,2,3]).to.include(2);
721 *
722 * @name include
723 * @param {Object|String|Number} obj
724 * @api public
725 */
726
7271Assertion.prototype.include = function (obj) {
72817 this.assert(
729 ~this.obj.indexOf(obj)
730 , 'expected ' + this.inspect + ' to include ' + inspect(obj)
731 , 'expected ' + this.inspect + ' to not include ' + inspect(obj));
732
73313 return this;
734};
735
736/**
737 * # .string(string)
738 *
739 * Assert inclusion of string in string.
740 *
741 * expect('foobar').to.have.string('bar');
742 *
743 * @name string
744 * @param {String} string
745 * @api public
746 */
747
7481Assertion.prototype.string = function (str) {
74915 new Assertion(this.obj).is.a('string');
750
75113 this.assert(
752 ~this.obj.indexOf(str)
753 , 'expected ' + this.inspect + ' to contain ' + inspect(str)
754 , 'expected ' + this.inspect + ' to not contain ' + inspect(str));
755
7568 return this;
757};
758
759
760
761/**
762 * # contain
763 *
764 * Toggles the `contain` flag for the `keys` assertion.
765 *
766 * @name contain
767 * @api public
768 */
769
7701Object.defineProperty(Assertion.prototype, 'contain',
771 { get: function () {
77237 this.contains = true;
77337 return this;
774 },
775 configurable: true
776});
777
778/**
779 * # .keys(key1, [key2], [...])
780 *
781 * Assert exact keys or the inclusing of keys using the `contain` modifier.
782 *
783 * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
784 * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
785 *
786 * @name keys
787 * @alias key
788 * @param {String|Array} Keys
789 * @api public
790 */
791
7921Assertion.prototype.keys = function(keys) {
79356 var str
794 , ok = true;
795
79656 keys = keys instanceof Array
797 ? keys
798 : Array.prototype.slice.call(arguments);
799
80064 if (!keys.length) throw new Error('keys required');
801
80248 var actual = Object.keys(this.obj)
803 , len = keys.length;
804
805 // Inclusion
80648 ok = keys.every(function(key){
80770 return ~actual.indexOf(key);
808 });
809
810 // Strict
81148 if (!this.negate && !this.contains) {
81212 ok = ok && keys.length == actual.length;
813 }
814
815 // Key string
81648 if (len > 1) {
81726 keys = keys.map(function(key){
81854 return inspect(key);
819 });
82026 var last = keys.pop();
82126 str = keys.join(', ') + ', and ' + last;
822 } else {
82322 str = inspect(keys[0]);
824 }
825
826 // Form
82748 str = (len > 1 ? 'keys ' : 'key ') + str;
828
829 // Have / include
83048 str = (this.contains ? 'contain ' : 'have ') + str;
831
832 // Assertion
83348 this.assert(
834 ok
835 , 'expected ' + this.inspect + ' to ' + str
836 , 'expected ' + this.inspect + ' to not ' + str
837 , keys
838 , Object.keys(this.obj)
839 );
840
84132 return this;
842}
843
844/**
845 * # .throw(constructor)
846 *
847 * Assert that a function will throw a specific type of error or that error
848 * thrown will match a RegExp or include a string.
849 *
850 * var fn = function () { throw new ReferenceError('This is a bad function.'); }
851 * expect(fn).to.throw(ReferenceError);
852 * expect(fn).to.throw(/bad function/);
853 * expect(fn).to.not.throw('good function');
854 * expect(fn).to.throw(ReferenceError, /bad function/);
855 *
856 * Please note that when a throw expectation is negated, it will check each
857 * parameter independently, starting with Error constructor type. The appropriate way
858 * to check for the existence of a type of error but for a message that does not match
859 * is to use `and`.
860 *
861 * expect(fn).to.throw(ReferenceError).and.not.throw(/good function/);
862 *
863 * @name throw
864 * @alias throws
865 * @alias Throw
866 * @param {ErrorConstructor} constructor
867 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
868 * @api public
869 */
870
8711Assertion.prototype.throw = function (constructor, msg) {
87265 new Assertion(this.obj).is.a('function');
873
87465 var thrown = false;
875
87665 if (arguments.length === 0) {
87711 msg = null;
87811 constructor = null;
87954 } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
88011 msg = constructor;
88111 constructor = null;
882 }
883
88465 try {
88565 this.obj();
886 } catch (err) {
887 // first, check constructor
88852 if (constructor && 'function' === typeof constructor) {
88931 this.assert(
890 err instanceof constructor && err.name == constructor.name
891 , 'expected ' + this.inspect + ' to throw ' + constructor.name + ' but a ' + err.name + ' was thrown'
892 , 'expected ' + this.inspect + ' to not throw ' + constructor.name );
89336 if (!msg) return this;
894 }
895 // next, check message
89631 if (err.message && msg && msg instanceof RegExp) {
89713 this.assert(
898 msg.exec(err.message)
899 , 'expected ' + this.inspect + ' to throw error matching ' + msg + ' but got ' + inspect(err.message)
900 , 'expected ' + this.inspect + ' to throw error not matching ' + msg
901 );
9027 return this;
90318 } else if (err.message && msg && 'string' === typeof msg) {
9048 this.assert(
905 ~err.message.indexOf(msg)
906 , 'expected ' + this.inspect + ' to throw error including ' + inspect(msg) + ' but got ' + inspect(err.message)
907 , 'expected ' + this.inspect + ' to throw error not including ' + inspect(msg)
908 );
9096 return this;
910 } else {
91110 thrown = true;
912 }
913 }
914
91523 var name = (constructor ? constructor.name : 'an error');
916
91723 this.assert(
918 thrown === true
919 , 'expected ' + this.inspect + ' to throw ' + name
920 , 'expected ' + this.inspect + ' to not throw ' + name);
921
92215 return this;
923};
924
925/**
926 * # .respondTo(method)
927 *
928 * Assert that object/class will respond to a method.
929 *
930 * expect(Klass).to.respondTo('bar');
931 * expect(obj).to.respondTo('bar');
932 *
933 * @name respondTo
934 * @param {String} method
935 * @api public
936 */
937
9381Assertion.prototype.respondTo = function (method) {
93910 var context = ('function' === typeof this.obj)
940 ? this.obj.prototype[method]
941 : this.obj[method];
942
94310 this.assert(
944 'function' === typeof context
945 , 'expected ' + this.inspect + ' to respond to ' + inspect(method)
946 , 'expected ' + this.inspect + ' to not respond to ' + inspect(method)
947 , 'function'
948 , typeof context
949 );
950
9516 return this;
952};
953
954/**
955 * # .satisfy(method)
956 *
957 * Assert that passes a truth test.
958 *
959 * expect(1).to.satisfy(function(num) { return num > 0; });
960 *
961 * @name satisfy
962 * @param {Function} matcher
963 * @api public
964 */
965
9661Assertion.prototype.satisfy = function (matcher) {
9674 this.assert(
968 matcher(this.obj)
969 , 'expected ' + this.inspect + ' to satisfy ' + inspect(matcher)
970 , 'expected ' + this.inspect + ' to not satisfy' + inspect(matcher)
971 , this.negate ? false : true
972 , matcher(this.obj)
973 );
974
9752 return this;
976};
977
978/**
979 * # .closeTo(expected, delta)
980 *
981 * Assert that actual is equal to +/- delta.
982 *
983 * expect(1.5).to.be.closeTo(1, 0.5);
984 *
985 * @name closeTo
986 * @param {Number} expected
987 * @param {Number} delta
988 * @api public
989 */
990
9911Assertion.prototype.closeTo = function (expected, delta) {
9924 this.assert(
993 (this.obj - delta === expected) || (this.obj + delta === expected)
994 , 'expected ' + this.inspect + ' to be close to ' + expected + ' +/- ' + delta
995 , 'expected ' + this.inspect + ' not to be close to ' + expected + ' +/- ' + delta);
996
9972 return this;
998};
999
1000/*!
1001 * Aliases.
1002 */
1003
10041(function alias(name, as){
10058 Assertion.prototype[as] = Assertion.prototype[name];
10068 return alias;
1007})
1008('length', 'lengthOf')
1009('keys', 'key')
1010('ownProperty', 'haveOwnProperty')
1011('above', 'greaterThan')
1012('below', 'lessThan')
1013('throw', 'throws')
1014('throw', 'Throw') // for troublesome browsers
1015('instanceof', 'instanceOf');

error.js

100%
15
15
0
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) {
16168 options = options || {};
17168 this.name = 'AssertionError';
18168 this.message = options.message;
19168 this.actual = options.actual;
20168 this.expected = options.expected;
21168 this.operator = options.operator;
22168 var stackStartFunction = options.stackStartFunction || fail;
23
24168 if (Error.captureStackTrace) {
25168 Error.captureStackTrace(this, stackStartFunction);
26 }
27}
28
291AssertionError.prototype.__proto__ = Error.prototype;
30
311AssertionError.prototype.toString = function() {
322 return this.message;
33};

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 () {
1112 return false;
12 }
13 };
14}
15
161function _deepEqual(actual, expected) {
17 // 7.1. All identical values are equivalent, as determined by ===.
1820 if (actual === expected) {
198 return true;
20
2112 } 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.
3212 } 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 ==.
3712 } else if (typeof actual != 'object' && typeof expected != 'object') {
386 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 {
476 return objEquiv(actual, expected);
48 }
49}
50
511function isUndefinedOrNull(value) {
5212 return value === null || value === undefined;
53}
54
551function isArguments(object) {
566 return Object.prototype.toString.call(object) == '[object Arguments]';
57}
58
591function objEquiv(a, b) {
606 if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
610 return false;
62 // an identical 'prototype' property.
636 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.
666 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 }
746 try {
756 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)
836 if (ka.length != kb.length)
840 return false;
85 //the same set of keys (although not necessarily the same order),
866 ka.sort();
876 kb.sort();
88 //~~~cheap key test
896 for (i = ka.length - 1; i >= 0; i--) {
906 if (ka[i] != kb[i])
910 return false;
92 }
93 //equivalent values for every corresponding key, and
94 //~~~possibly expensive deep test
956 for (i = ka.length - 1; i >= 0; i--) {
966 key = ka[i];
978 if (!_deepEqual(a[key], b[key])) return false;
98 }
994 return true;
100}

utils/inspect.js

77%
123
95
28
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) {
182300 var ctx = {
19 showHidden: showHidden,
20 seen: [],
212692 stylize: function (str) { return str; }
22 };
232300 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
292730 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
382730 var primitive = formatPrimitive(ctx, value);
392730 if (primitive) {
402098 return primitive;
41 }
42
43 // Look up the keys of the object.
44632 var visibleKeys = Object.keys(value);
45632 var keys = ctx.showHidden ? Object.getOwnPropertyNames(value) : visibleKeys;
46
47 // Some type of object without properties can be shortcutted.
48632 if (keys.length === 0) {
49392 if (typeof value === 'function') {
50328 var name = value.name ? ': ' + value.name : '';
51328 return ctx.stylize('[Function' + name + ']', 'special');
52 }
5364 if (isRegExp(value)) {
540 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
55 }
5664 if (isDate(value)) {
570 return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
58 }
5964 if (isError(value)) {
600 return formatError(value);
61 }
62 }
63
64304 var base = '', array = false, braces = ['{', '}'];
65
66 // Make Array say that they are Array
67304 if (isArray(value)) {
6896 array = true;
6996 braces = ['[', ']'];
70 }
71
72 // Make functions say that they are functions
73304 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
79304 if (isRegExp(value)) {
800 base = ' ' + RegExp.prototype.toString.call(value);
81 }
82
83 // Make dates with properties first say the date
84304 if (isDate(value)) {
850 base = ' ' + Date.prototype.toUTCString.call(value);
86 }
87
88 // Make error with message first say the error
89304 if (isError(value)) {
900 base = ' ' + formatError(value);
91 }
92
93304 if (keys.length === 0 && (!array || value.length == 0)) {
9464 return braces[0] + base + braces[1];
95 }
96
97240 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
105240 ctx.seen.push(value);
106
107240 var output;
108240 if (array) {
10972 output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
110 } else {
111168 output = keys.map(function(key) {
112266 return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
113 });
114 }
115
116240 ctx.seen.pop();
117
118240 return reduceToSingleString(output, base, braces);
119}
120
121
1221function formatPrimitive(ctx, value) {
1232730 switch (typeof value) {
124 case 'undefined':
12536 return ctx.stylize('undefined', 'undefined');
126
127 case 'string':
1281444 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
129 .replace(/'/g, "\\'")
130 .replace(/\\"/g, '"') + '\'';
1311444 return ctx.stylize(simple, 'string');
132
133 case 'number':
134546 return ctx.stylize('' + value, 'number');
135
136 case 'boolean':
13754 return ctx.stylize('' + value, 'boolean');
138 }
139 // For some reason typeof null is "object", so special case here.
140650 if (value === null) {
14118 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) {
15272 var output = [];
15372 for (var i = 0, l = value.length; i < l; ++i) {
154164 if (Object.prototype.hasOwnProperty.call(value, String(i))) {
155164 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
156 String(i), true));
157 } else {
1580 output.push('');
159 }
160 }
16172 keys.forEach(function(key) {
162164 if (!key.match(/^\d+$/)) {
1630 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
164 key, true));
165 }
166 });
16772 return output;
168}
169
170
1711function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
172430 var name, str;
173430 if (value.__lookupGetter__) {
174430 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 {
181430 if (value.__lookupSetter__(key)) {
1820 str = ctx.stylize('[Setter]', 'special');
183 }
184 }
185 }
186430 if (visibleKeys.indexOf(key) < 0) {
1870 name = '[' + key + ']';
188 }
189430 if (!str) {
190430 if (ctx.seen.indexOf(value[key]) < 0) {
191430 if (recurseTimes === null) {
1920 str = formatValue(ctx, value[key], null);
193 } else {
194430 str = formatValue(ctx, value[key], recurseTimes - 1);
195 }
196430 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 }
211430 if (typeof name === 'undefined') {
212430 if (array && key.match(/^\d+$/)) {
213164 return str;
214 }
215266 name = JSON.stringify('' + key);
216266 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
217248 name = name.substr(1, name.length - 2);
218248 name = ctx.stylize(name, 'name');
219 } else {
22018 name = name.replace(/'/g, "\\'")
221 .replace(/\\"/g, '"')
222 .replace(/(^"|"$)/g, "'");
22318 name = ctx.stylize(name, 'string');
224 }
225 }
226
227266 return name + ': ' + str;
228}
229
230
2311function reduceToSingleString(output, base, braces) {
232240 var numLinesEst = 0;
233240 var length = output.reduce(function(prev, cur) {
234430 numLinesEst++;
235430 if (cur.indexOf('\n') >= 0) numLinesEst++;
236430 return prev + cur.length + 1;
237 }, 0);
238
239240 if (length > 60) {
2400 return braces[0] +
241 (base === '' ? '' : base + '\n ') +
242 ' ' +
243 output.join(',\n ') +
244 ' ' +
245 braces[1];
246 }
247
248240 return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
249}
250
2511function isArray(ar) {
252304 return Array.isArray(ar) ||
253 (typeof ar === 'object' && objectToString(ar) === '[object Array]');
254}
255
2561function isRegExp(re) {
257368 return typeof re === 'object' && objectToString(re) === '[object RegExp]';
258}
259
2601function isDate(d) {
261368 return typeof d === 'object' && objectToString(d) === '[object Date]';
262}
263
2641function isError(e) {
265368 return typeof e === 'object' && objectToString(e) === '[object Error]';
266}
267
2681function objectToString(o) {
2691312 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) {
9252 return new chai.Assertion(val, message);
10 };
11};
12

interface/should.js

95%
24
23
1
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(){
15175 if (this instanceof String || this instanceof Number) {
161 return new Assertion(this.constructor(this));
17174 } else if (this instanceof Boolean) {
180 return new Assertion(this == true);
19 }
20174 return new Assertion(this);
21 },
22 configurable: true
23 });
24
251 var should = {};
26
271 should.equal = function (val1, val2) {
2870 new Assertion(val1).to.equal(val2);
29 };
30
311 should.throw = function (fn, errt, errs) {
324 new Assertion(fn).to.throw(errt, errs);
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) {
431 new Assertion(val1).to.not.equal(val2);
44 };
45
461 should.not.throw = function (fn, errt, errs) {
472 new Assertion(fn).to.not.throw(errt, errs);
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

100%
79
79
0
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 * # .fail(actual, expect, msg, operator)
46 *
47 * Throw a failure. Node.js compatible.
48 *
49 * @name fail
50 * @param {*} actual value
51 * @param {*} expected value
52 * @param {String} message
53 * @param {String} operator
54 * @api public
55 */
56
571 assert.fail = function (actual, expected, message, operator) {
581 throw new chai.AssertionError({
59 actual: actual
60 , expected: expected
61 , message: message
62 , operator: operator
63 , stackStartFunction: assert.fail
64 });
65 }
66
67 /**
68 * # .ok(object, [message])
69 *
70 * Assert object is truthy.
71 *
72 * assert.ok('everthing', 'everything is ok');
73 * assert.ok(false, 'this will fail');
74 *
75 * @name ok
76 * @param {*} object to test
77 * @param {String} message
78 * @api public
79 */
80
811 assert.ok = function (val, msg) {
827 new Assertion(val, msg).is.ok;
83 };
84
85 /**
86 * # .equal(actual, expected, [message])
87 *
88 * Assert strict equality.
89 *
90 * assert.equal(3, 3, 'these numbers are equal');
91 *
92 * @name equal
93 * @param {*} actual
94 * @param {*} expected
95 * @param {String} message
96 * @api public
97 */
98
991 assert.equal = function (act, exp, msg) {
10044 var test = new Assertion(act, msg);
101
10244 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 * # .notEqual(actual, expected, [message])
110 *
111 * Assert not equal.
112 *
113 * assert.notEqual(3, 4, 'these numbers are not equal');
114 *
115 * @name notEqual
116 * @param {*} actual
117 * @param {*} expected
118 * @param {String} message
119 * @api public
120 */
121
1221 assert.notEqual = function (act, exp, msg) {
1232 var test = new Assertion(act, msg);
124
1252 test.assert(
126 exp != test.obj
127 , 'expected ' + test.inspect + ' to equal ' + inspect(exp)
128 , 'expected ' + test.inspect + ' to not equal ' + inspect(exp));
129 };
130
131 /**
132 * # .strictEqual(actual, expected, [message])
133 *
134 * Assert strict equality.
135 *
136 * assert.strictEqual(true, true, 'these booleans are strictly equal');
137 *
138 * @name strictEqual
139 * @param {*} actual
140 * @param {*} expected
141 * @param {String} message
142 * @api public
143 */
144
1451 assert.strictEqual = function (act, exp, msg) {
1462 new Assertion(act, msg).to.equal(exp);
147 };
148
149 /**
150 * # .notStrictEqual(actual, expected, [message])
151 *
152 * Assert strict equality.
153 *
154 * assert.notStrictEqual(1, true, 'these booleans are not strictly equal');
155 *
156 * @name notStrictEqual
157 * @param {*} actual
158 * @param {*} expected
159 * @param {String} message
160 * @api public
161 */
162
1631 assert.notStrictEqual = function (act, exp, msg) {
1642 new Assertion(act, msg).to.not.equal(exp);
165 };
166
167 /**
168 * # .deepEqual(actual, expected, [message])
169 *
170 * Assert not deep equality.
171 *
172 * assert.deepEqual({ tea: 'green' }, { tea: 'green' });
173 *
174 * @name deepEqual
175 * @param {*} actual
176 * @param {*} expected
177 * @param {String} message
178 * @api public
179 */
180
1811 assert.deepEqual = function (act, exp, msg) {
1822 new Assertion(act, msg).to.eql(exp);
183 };
184
185 /**
186 * # .notDeepEqual(actual, expected, [message])
187 *
188 * Assert not deep equality.
189 *
190 * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
191 *
192 * @name notDeepEqual
193 * @param {*} actual
194 * @param {*} expected
195 * @param {String} message
196 * @api public
197 */
198
1991 assert.notDeepEqual = function (act, exp, msg) {
2002 new Assertion(act, msg).to.not.eql(exp);
201 };
202
203 /**
204 * # .isTrue(value, [message])
205 *
206 * Assert `value` is true.
207 *
208 * var tea_served = true;
209 * assert.isTrue(tea_served, 'the tea has been served');
210 *
211 * @name isTrue
212 * @param {Boolean} value
213 * @param {String} message
214 * @api public
215 */
216
2171 assert.isTrue = function (val, msg) {
2184 new Assertion(val, msg).is.true;
219 };
220
221 /**
222 * # .isFalse(value, [message])
223 *
224 * Assert `value` is false.
225 *
226 * var tea_served = false;
227 * assert.isFalse(tea_served, 'no tea yet? hmm...');
228 *
229 * @name isFalse
230 * @param {Boolean} value
231 * @param {String} message
232 * @api public
233 */
234
2351 assert.isFalse = function (val, msg) {
2363 new Assertion(val, msg).is.false;
237 };
238
239 /**
240 * # .isNull(value, [message])
241 *
242 * Assert `value` is null.
243 *
244 * assert.isNull(err, 'no errors');
245 *
246 * @name isNull
247 * @param {*} value
248 * @param {String} message
249 * @api public
250 */
251
2521 assert.isNull = function (val, msg) {
2532 new Assertion(val, msg).to.equal(null);
254 };
255
256 /**
257 * # .isNotNull(value, [message])
258 *
259 * Assert `value` is not null.
260 *
261 * var tea = 'tasty chai';
262 * assert.isNotNull(tea, 'great, time for tea!');
263 *
264 * @name isNotNull
265 * @param {*} value
266 * @param {String} message
267 * @api public
268 */
269
2701 assert.isNotNull = function (val, msg) {
2712 new Assertion(val, msg).to.not.equal(null);
272 };
273
274 /**
275 * # .isUndefined(value, [message])
276 *
277 * Assert `value` is undefined.
278 *
279 * assert.isUndefined(tea, 'no tea defined');
280 *
281 * @name isUndefined
282 * @param {*} value
283 * @param {String} message
284 * @api public
285 */
286
2871 assert.isUndefined = function (val, msg) {
2882 new Assertion(val, msg).to.equal(undefined);
289 };
290
291 /**
292 * # .isDefined(value, [message])
293 *
294 * Assert `value` is not undefined.
295 *
296 * var tea = 'cup of chai';
297 * assert.isDefined(tea, 'no tea defined');
298 *
299 * @name isUndefined
300 * @param {*} value
301 * @param {String} message
302 * @api public
303 */
304
3051 assert.isDefined = function (val, msg) {
3062 new Assertion(val, msg).to.not.equal(undefined);
307 };
308
309 /**
310 * # .isFunction(value, [message])
311 *
312 * Assert `value` is a function.
313 *
314 * var serve_tea = function () { return 'cup of tea'; };
315 * assert.isFunction(serve_tea, 'great, we can have tea now');
316 *
317 * @name isFunction
318 * @param {Function} value
319 * @param {String} message
320 * @api public
321 */
322
3231 assert.isFunction = function (val, msg) {
3242 new Assertion(val, msg).to.be.a('function');
325 };
326
327 /**
328 * # .isObject(value, [message])
329 *
330 * Assert `value` is an object.
331 *
332 * var selection = { name: 'Chai', serve: 'with spices' };
333 * assert.isObject(selection, 'tea selection is an object');
334 *
335 * @name isObject
336 * @param {Object} value
337 * @param {String} message
338 * @api public
339 */
340
3411 assert.isObject = function (val, msg) {
3425 new Assertion(val, msg).to.be.a('object');
343 };
344
345 /**
346 * # .isArray(value, [message])
347 *
348 * Assert `value` is an instance of Array.
349 *
350 * var menu = [ 'green', 'chai', 'oolong' ];
351 * assert.isArray(menu, 'what kind of tea do we want?');
352 *
353 * @name isArray
354 * @param {*} value
355 * @param {String} message
356 * @api public
357 */
358
3591 assert.isArray = function (val, msg) {
3603 new Assertion(val, msg).to.be.instanceof(Array);
361 };
362
363 /**
364 * # .isString(value, [message])
365 *
366 * Assert `value` is a string.
367 *
368 * var teaorder = 'chai';
369 * assert.isString(tea_order, 'order placed');
370 *
371 * @name isString
372 * @param {String} value
373 * @param {String} message
374 * @api public
375 */
376
3771 assert.isString = function (val, msg) {
3783 new Assertion(val, msg).to.be.a('string');
379 };
380
381 /**
382 * # .isNumber(value, [message])
383 *
384 * Assert `value` is a number
385 *
386 * var cups = 2;
387 * assert.isNumber(cups, 'how many cups');
388 *
389 * @name isNumber
390 * @param {Number} value
391 * @param {String} message
392 * @api public
393 */
394
3951 assert.isNumber = function (val, msg) {
3963 new Assertion(val, msg).to.be.a('number');
397 };
398
399 /**
400 * # .isBoolean(value, [message])
401 *
402 * Assert `value` is a boolean
403 *
404 * var teaready = true
405 * , teaserved = false;
406 *
407 * assert.isBoolean(tea_ready, 'is the tea ready');
408 * assert.isBoolean(tea_served, 'has tea been served');
409 *
410 * @name isBoolean
411 * @param {*} value
412 * @param {String} message
413 * @api public
414 */
415
4161 assert.isBoolean = function (val, msg) {
4173 new Assertion(val, msg).to.be.a('boolean');
418 };
419
420 /**
421 * # .typeOf(value, name, [message])
422 *
423 * Assert typeof `value` is `name`.
424 *
425 * assert.typeOf('tea', 'string', 'we have a string');
426 *
427 * @name typeOf
428 * @param {*} value
429 * @param {String} typeof name
430 * @param {String} message
431 * @api public
432 */
433
4341 assert.typeOf = function (val, type, msg) {
4354 new Assertion(val, msg).to.be.a(type);
436 };
437
438 /**
439 * # .instanceOf(object, constructor, [message])
440 *
441 * Assert `value` is instanceof `constructor`.
442 *
443 * var Tea = function (name) { this.name = name; }
444 * , Chai = new Tea('chai');
445 *
446 * assert.instanceOf(Chai, Tea, 'chai is an instance of tea');
447 *
448 * @name instanceOf
449 * @param {Object} object
450 * @param {Constructor} constructor
451 * @param {String} message
452 * @api public
453 */
454
4551 assert.instanceOf = function (val, type, msg) {
4562 new Assertion(val, msg).to.be.instanceof(type);
457 };
458
459 /**
460 * # .include(value, includes, [message])
461 *
462 * Assert the inclusion of an object in another. Works
463 * for strings and arrays.
464 *
465 * assert.include('foobar', 'bar', 'foobar contains string `var`);
466 * assert.include([ 1, 2, 3], 3, 'array contains value);
467 *
468 * @name include
469 * @param {Array|String} value
470 * @param {*} includes
471 * @param {String} message
472 * @api public
473 */
474
4751 assert.include = function (exp, inc, msg) {
4764 var obj = new Assertion(exp, msg);
477
4784 if (Array.isArray(exp)) {
4791 obj.to.include(inc);
4803 } else if ('string' === typeof exp) {
4813 obj.to.contain.string(inc);
482 }
483 };
484
485 /**
486 * # .match(value, regex, [message])
487 *
488 * Assert that `value` matches regular expression.
489 *
490 * assert.match('foobar', /^foo/, 'Regexp matches');
491 *
492 * @name match
493 * @param {*} value
494 * @param {RegExp} RegularExpression
495 * @param {String} message
496 * @api public
497 */
498
4991 assert.match = function (exp, re, msg) {
5001 new Assertion(exp, msg).to.match(re);
501 };
502
503 /**
504 * # .length(value, constructor, [message])
505 *
506 * Assert that object has expected length.
507 *
508 * assert.length([1,2,3], 3, 'Array has length of 3');
509 * assert.length('foobar', 5, 'String has length of 6');
510 *
511 * @name length
512 * @param {*} value
513 * @param {Number} length
514 * @param {String} message
515 * @api public
516 */
517
5181 assert.length = function (exp, len, msg) {
5194 new Assertion(exp, msg).to.have.length(len);
520 };
521
522 /**
523 * # .throws(function, [constructor/regexp], [message])
524 *
525 * Assert that a function will throw a specific
526 * type of error.
527 *
528 * assert.throw(fn, ReferenceError, 'function throw reference error');
529 *
530 * @name throws
531 * @alias throw
532 * @param {Function} function to test
533 * @param {ErrorConstructor} constructor
534 * @param {String} message
535 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
536 * @api public
537 */
538
5391 assert.throws = function (fn, type, msg) {
5403 if ('string' === typeof type) {
5411 msg = type;
5421 type = null;
543 }
544
5453 new Assertion(fn, msg).to.throw(type);
546 };
547
548 /**
549 * # .doesNotThrow(function, [constructor/regexp], [message])
550 *
551 * Assert that a function will throw a specific
552 * type of error.
553 *
554 * var fn = function (err) { if (err) throw Error(err) };
555 * assert.doesNotThrow(fn, Error, 'function throw reference error');
556 *
557 * @name doesNotThrow
558 * @param {Function} function to test
559 * @param {ErrorConstructor} constructor
560 * @param {String} message
561 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
562 * @api public
563 */
564
5651 assert.doesNotThrow = function (fn, type, msg) {
5663 if ('string' === typeof type) {
5671 msg = type;
5681 type = null;
569 }
570
5713 new Assertion(fn, msg).to.not.throw(type);
572 };
573
574 /**
575 * # .operator(val, operator, val2, [message])
576 *
577 * Compare two values using operator.
578 *
579 * assert.operator(1, '<', 2, 'everything is ok');
580 * assert.operator(1, '>', 2, 'this will fail');
581 *
582 * @name operator
583 * @param {*} object to test
584 * @param {String} operator
585 * @param {*} second object
586 * @param {String} message
587 * @api public
588 */
589
5901 assert.operator = function (val, operator, val2, msg) {
59115 if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
5921 throw new Error('Invalid operator "' + operator + '"');
593 }
59414 var test = new Assertion(eval(val + operator + val2), msg);
59514 test.assert(
596 true === test.obj
597 , 'expected ' + inspect(val) + ' to be ' + operator + ' ' + inspect(val2)
598 , 'expected ' + inspect(val) + ' to not be ' + operator + ' ' + inspect(val2) );
599 };
600
601 /*!
602 * Undocumented / untested
603 */
604
6051 assert.ifError = function (val, msg) {
6064 new Assertion(val, msg).to.not.be.ok;
607 };
608
609 /*!
610 * Aliases.
611 */
612
6131 (function alias(name, as){
6142 assert[as] = assert[name];
6152 return alias;
616 })
617 ('length', 'lengthOf')
618 ('throws', 'throw');
619};