Coverage

90%
468
425
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.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
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) {
69733 this.ssfi = stack || arguments.callee;
70733 this.obj = obj;
71733 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)
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 * @api private
99 */
100
1011Assertion.prototype.assert = function (expr, msg, negateMsg, expected, actual) {
102739 actual = actual || this.obj;
103739 var msg = (this.negate ? negateMsg : msg)
104 , ok = this.negate ? !expr : expr;
105
106739 if (!ok) {
107166 throw new AssertionError({
108 message: this.msg ? this.msg + ': ' + msg : msg // include custom message if available
109 , actual: actual
110 , expected: expected
111 , stackStartFunction: (Assertion.includeStack) ? this.assert : this.ssfi
112 });
113 }
114};
115
116/*!
117 * # inspect
118 *
119 * Returns the current object stringified.
120 *
121 * @name inspect
122 * @api private
123 */
124
1251Object.defineProperty(Assertion.prototype, 'inspect',
126 { get: function () {
1271480 return inspect(this.obj);
128 }
129 , configurable: true
130});
131
132/**
133 * # to
134 *
135 * Language chain.
136 *
137 * @name to
138 * @api public
139 */
140
1411Object.defineProperty(Assertion.prototype, 'to',
142 { get: function () {
143419 return this;
144 }
145 , configurable: true
146});
147
148/**
149 * # be
150 *
151 * Language chain.
152 *
153 * @name be
154 * @api public
155 */
156
1571Object.defineProperty(Assertion.prototype, 'be',
158 { get: function () {
159177 return this;
160 }
161 , configurable: true
162});
163
164/**
165 * # been
166 *
167 * Language chain. Also tests `tense` to past for addon
168 * modules that use the tense feature.
169 *
170 * @name been
171 * @api public
172 */
173
1741Object.defineProperty(Assertion.prototype, 'been',
175 { get: function () {
1761 this.tense = 'past';
1771 return this;
178 }
179 , configurable: true
180});
181
182/**
183 * # an
184 *
185 * Language chain.
186 *
187 * @name an
188 * @api public
189 */
190
1911Object.defineProperty(Assertion.prototype, 'an',
192 { get: function () {
1934 return this;
194 }
195 , configurable: true
196});
197/**
198 * # is
199 *
200 * Language chain.
201 *
202 * @name is
203 * @api public
204 */
205
2061Object.defineProperty(Assertion.prototype, 'is',
207 { get: function () {
20893 return this;
209 }
210 , configurable: true
211});
212
213/**
214 * # and
215 *
216 * Language chain.
217 *
218 * @name and
219 * @api public
220 */
221
2221Object.defineProperty(Assertion.prototype, 'and',
223 { get: function () {
2241 return this;
225 }
226 , configurable: true
227});
228
229/**
230 * # have
231 *
232 * Language chain.
233 *
234 * @name have
235 * @api public
236 */
237
2381Object.defineProperty(Assertion.prototype, 'have',
239 { get: function () {
24092 return this;
241 }
242 , configurable: true
243});
244
245/**
246 * # with
247 *
248 * Language chain.
249 *
250 * @name with
251 * @api public
252 */
253
2541Object.defineProperty(Assertion.prototype, 'with',
255 { get: function () {
2562 return this;
257 }
258 , configurable: true
259});
260
261/**
262 * # .not
263 *
264 * Negates any of assertions following in the chain.
265 *
266 * @name not
267 * @api public
268 */
269
2701Object.defineProperty(Assertion.prototype, 'not',
271 { get: function () {
272143 this.negate = true;
273143 return this;
274 }
275 , configurable: true
276});
277
278/**
279 * # .ok
280 *
281 * Assert object truthiness.
282 *
283 * expect('everthing').to.be.ok;
284 * expect(false).to.not.be.ok;
285 * expect(undefined).to.not.be.ok;
286 * expect(null).to.not.be.ok;
287 *
288 * @name ok
289 * @api public
290 */
291
2921Object.defineProperty(Assertion.prototype, 'ok',
293 { get: function () {
29423 this.assert(
295 this.obj
296 , 'expected ' + this.inspect + ' to be truthy'
297 , 'expected ' + this.inspect + ' to be falsy');
298
29915 return this;
300 }
301 , configurable: true
302});
303
304/**
305 * # .true
306 *
307 * Assert object is true
308 *
309 * @name true
310 * @api public
311 */
312
3131Object.defineProperty(Assertion.prototype, 'true',
314 { get: function () {
31526 this.assert(
316 true === this.obj
317 , 'expected ' + this.inspect + ' to be true'
318 , 'expected ' + this.inspect + ' to be false'
319 , this.negate ? false : true
320 );
321
32214 return this;
323 }
324 , configurable: true
325});
326
327/**
328 * # .false
329 *
330 * Assert object is false
331 *
332 * @name false
333 * @api public
334 */
335
3361Object.defineProperty(Assertion.prototype, 'false',
337 { get: function () {
33812 this.assert(
339 false === this.obj
340 , 'expected ' + this.inspect + ' to be false'
341 , 'expected ' + this.inspect + ' to be true'
342 , this.negate ? true : false
343 );
344
3458 return this;
346 }
347 , configurable: true
348});
349
350/**
351 * # .exist
352 *
353 * Assert object exists (null).
354 *
355 * var foo = 'hi'
356 * , bar;
357 * expect(foo).to.exist;
358 * expect(bar).to.not.exist;
359 *
360 * @name exist
361 * @api public
362 */
363
3641Object.defineProperty(Assertion.prototype, 'exist',
365 { get: function () {
3666 this.assert(
367 null != this.obj
368 , 'expected ' + this.inspect + ' to exist'
369 , 'expected ' + this.inspect + ' to not exist'
370 );
371
3724 return this;
373 }
374 , configurable: true
375});
376
377/**
378 * # .empty
379 *
380 * Assert object's length to be 0.
381 *
382 * expect([]).to.be.empty;
383 *
384 * @name empty
385 * @api public
386 */
387
3881Object.defineProperty(Assertion.prototype, 'empty',
389 { get: function () {
39032 var expected = this.obj;
391
39232 if (Array.isArray(this.obj)) {
3938 expected = this.obj.length;
39424 } else if (typeof this.obj === 'object') {
39516 expected = Object.keys(this.obj).length;
396 }
397
39832 this.assert(
399 !expected
400 , 'expected ' + this.inspect + ' to be empty'
401 , 'expected ' + this.inspect + ' not to be empty');
402
40316 return this;
404 }
405 , configurable: true
406});
407
408/**
409 * # .arguments
410 *
411 * Assert object is an instanceof arguments.
412 *
413 * function test () {
414 * expect(arguments).to.be.arguments;
415 * }
416 *
417 * @name arguments
418 * @api public
419 */
420
4211Object.defineProperty(Assertion.prototype, 'arguments',
422 { get: function () {
4234 this.assert(
424 '[object Arguments]' == Object.prototype.toString.call(this.obj)
425 , 'expected ' + this.inspect + ' to be arguments'
426 , 'expected ' + this.inspect + ' to not be arguments'
427 , '[object Arguments]'
428 , Object.prototype.toString.call(this.obj)
429 );
430
4314 return this;
432 }
433 , configurable: true
434});
435
436/**
437 * # .equal(value)
438 *
439 * Assert strict equality.
440 *
441 * expect('hello').to.equal('hello');
442 *
443 * @name equal
444 * @param {*} value
445 * @api public
446 */
447
4481Assertion.prototype.equal = function (val) {
449159 this.assert(
450 val === this.obj
451 , 'expected ' + this.inspect + ' to equal ' + inspect(val)
452 , 'expected ' + this.inspect + ' to not equal ' + inspect(val)
453 , val );
454
455150 return this;
456};
457
458/**
459 * # .eql(value)
460 *
461 * Assert deep equality.
462 *
463 * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
464 *
465 * @name eql
466 * @param {*} value
467 * @api public
468 */
469
4701Assertion.prototype.eql = function (obj) {
47114 this.assert(
472 eql(obj, this.obj)
473 , 'expected ' + this.inspect + ' to equal ' + inspect(obj)
474 , 'expected ' + this.inspect + ' to not equal ' + inspect(obj)
475 , obj );
476
47710 return this;
478};
479
480/**
481 * # .above(value)
482 *
483 * Assert greater than `value`.
484 *
485 * expect(10).to.be.above(5);
486 *
487 * @name above
488 * @param {Number} value
489 * @api public
490 */
491
4921Assertion.prototype.above = function (val) {
49312 this.assert(
494 this.obj > val
495 , 'expected ' + this.inspect + ' to be above ' + val
496 , 'expected ' + this.inspect + ' to be below ' + val);
497
4988 return this;
499};
500
501/**
502 * # .below(value)
503 *
504 * Assert less than `value`.
505 *
506 * expect(5).to.be.below(10);
507 *
508 * @name below
509 * @param {Number} value
510 * @api public
511 */
512
5131Assertion.prototype.below = function (val) {
51412 this.assert(
515 this.obj < val
516 , 'expected ' + this.inspect + ' to be below ' + val
517 , 'expected ' + this.inspect + ' to be above ' + val);
518
5198 return this;
520};
521
522/**
523 * # .within(start, finish)
524 *
525 * Assert that a number is within a range.
526 *
527 * expect(7).to.be.within(5,10);
528 *
529 * @name within
530 * @param {Number} start lowerbound inclusive
531 * @param {Number} finish upperbound inclusive
532 * @api public
533 */
534
5351Assertion.prototype.within = function (start, finish) {
53612 var range = start + '..' + finish;
537
53812 this.assert(
539 this.obj >= start && this.obj <= finish
540 , 'expected ' + this.inspect + ' to be within ' + range
541 , 'expected ' + this.inspect + ' to not be within ' + range);
542
5438 return this;
544};
545
546/**
547 * # .a(type)
548 *
549 * Assert typeof.
550 *
551 * expect('test').to.be.a('string');
552 *
553 * @name a
554 * @param {String} type
555 * @api public
556 */
557
5581Assertion.prototype.a = function (type) {
559127 var klass = type.charAt(0).toUpperCase() + type.slice(1);
560
561127 this.assert(
562 '[object ' + klass + ']' === toString.call(this.obj)
563 , 'expected ' + this.inspect + ' to be a ' + type
564 , 'expected ' + this.inspect + ' not to be a ' + type
565 , '[object ' + klass + ']'
566 , toString.call(this.obj)
567 );
568
569113 return this;
570};
571
572/**
573 * # .instanceof(constructor)
574 *
575 * Assert instanceof.
576 *
577 * var Tea = function (name) { this.name = name; }
578 * , Chai = new Tea('chai');
579 *
580 * expect(Chai).to.be.an.instanceOf(Tea);
581 *
582 * @name instanceof
583 * @param {Constructor}
584 * @alias instanceOf
585 * @api public
586 */
587
5881Assertion.prototype.instanceof = function (constructor) {
5899 var name = constructor.name;
5909 this.assert(
591 this.obj instanceof constructor
592 , 'expected ' + this.inspect + ' to be an instance of ' + name
593 , 'expected ' + this.inspect + ' to not be an instance of ' + name);
594
5955 return this;
596};
597
598/**
599 * # .property(name, [value])
600 *
601 * Assert that property of `name` exists, optionally with `value`.
602 *
603 * var obj = { foo: 'bar' }
604 * expect(obj).to.have.property('foo');
605 * expect(obj).to.have.property('foo', 'bar');
606 * expect(obj).to.have.property('foo').to.be.a('string');
607 *
608 * @name property
609 * @param {String} name
610 * @param {*} value (optional)
611 * @returns value of property for chaining
612 * @api public
613 */
614
6151Assertion.prototype.property = function (name, val) {
61637 if (this.negate && undefined !== val) {
6174 if (undefined === this.obj[name]) {
6182 throw new Error(this.inspect + ' has no property ' + inspect(name));
619 }
620 } else {
62133 this.assert(
622 undefined !== this.obj[name]
623 , 'expected ' + this.inspect + ' to have a property ' + inspect(name)
624 , 'expected ' + this.inspect + ' to not have property ' + inspect(name));
625 }
626
62730 if (undefined !== val) {
62811 this.assert(
629 val === this.obj[name]
630 , 'expected ' + this.inspect + ' to have a property ' + inspect(name) + ' of ' +
631 inspect(val) + ', but got ' + inspect(this.obj[name])
632 , 'expected ' + this.inspect + ' to not have a property ' + inspect(name) + ' of ' + inspect(val)
633 , val
634 , this.obj[val]
635 );
636 }
637
63824 this.obj = this.obj[name];
63924 return this;
640};
641
642/**
643 * # .ownProperty(name)
644 *
645 * Assert that has own property by `name`.
646 *
647 * expect('test').to.have.ownProperty('length');
648 *
649 * @name ownProperty
650 * @alias haveOwnProperty
651 * @param {String} name
652 * @api public
653 */
654
6551Assertion.prototype.ownProperty = function (name) {
6568 this.assert(
657 this.obj.hasOwnProperty(name)
658 , 'expected ' + this.inspect + ' to have own property ' + inspect(name)
659 , 'expected ' + this.inspect + ' to not have own property ' + inspect(name));
6606 return this;
661};
662
663/**
664 * # .length(val)
665 *
666 * Assert that object has expected length.
667 *
668 * expect([1,2,3]).to.have.length(3);
669 * expect('foobar').to.have.length(6);
670 *
671 * @name length
672 * @alias lengthOf
673 * @param {Number} length
674 * @api public
675 */
676
6771Assertion.prototype.length = function (n) {
67816 new Assertion(this.obj).to.have.property('length');
67913 var len = this.obj.length;
680
68113 this.assert(
682 len == n
683 , 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len
684 , 'expected ' + this.inspect + ' to not have a length of ' + len
685 , n
686 , len
687 );
688
6899 return this;
690};
691
692/**
693 * # .match(regexp)
694 *
695 * Assert that matches regular expression.
696 *
697 * expect('foobar').to.match(/^foo/);
698 *
699 * @name match
700 * @param {RegExp} RegularExpression
701 * @api public
702 */
703
7041Assertion.prototype.match = function (re) {
70511 this.assert(
706 re.exec(this.obj)
707 , 'expected ' + this.inspect + ' to match ' + re
708 , 'expected ' + this.inspect + ' not to match ' + re);
709
7107 return this;
711};
712
713/**
714 * # .include(obj)
715 *
716 * Assert the inclusion of an object in an Array or substring in string.
717 *
718 * expect([1,2,3]).to.include(2);
719 *
720 * @name include
721 * @param {Object|String|Number} obj
722 * @api public
723 */
724
7251Assertion.prototype.include = function (obj) {
72617 this.assert(
727 ~this.obj.indexOf(obj)
728 , 'expected ' + this.inspect + ' to include ' + inspect(obj)
729 , 'expected ' + this.inspect + ' to not include ' + inspect(obj));
730
73113 return this;
732};
733
734/**
735 * # .string(string)
736 *
737 * Assert inclusion of string in string.
738 *
739 * expect('foobar').to.have.string('bar');
740 *
741 * @name string
742 * @param {String} string
743 * @api public
744 */
745
7461Assertion.prototype.string = function (str) {
74715 new Assertion(this.obj).is.a('string');
748
74913 this.assert(
750 ~this.obj.indexOf(str)
751 , 'expected ' + this.inspect + ' to contain ' + inspect(str)
752 , 'expected ' + this.inspect + ' to not contain ' + inspect(str));
753
7548 return this;
755};
756
757
758
759/**
760 * # contain
761 *
762 * Toggles the `contain` flag for the `keys` assertion.
763 *
764 * @name contain
765 * @api public
766 */
767
7681Object.defineProperty(Assertion.prototype, 'contain',
769 { get: function () {
77037 this.contains = true;
77137 return this;
772 },
773 configurable: true
774});
775
776/**
777 * # .keys(key1, [key2], [...])
778 *
779 * Assert exact keys or the inclusing of keys using the `contain` modifier.
780 *
781 * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
782 * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
783 *
784 * @name keys
785 * @alias key
786 * @param {String|Array} Keys
787 * @api public
788 */
789
7901Assertion.prototype.keys = function(keys) {
79156 var str
792 , ok = true;
793
79456 keys = keys instanceof Array
795 ? keys
796 : Array.prototype.slice.call(arguments);
797
79864 if (!keys.length) throw new Error('keys required');
799
80048 var actual = Object.keys(this.obj)
801 , len = keys.length;
802
803 // Inclusion
80448 ok = keys.every(function(key){
80570 return ~actual.indexOf(key);
806 });
807
808 // Strict
80948 if (!this.negate && !this.contains) {
81012 ok = ok && keys.length == actual.length;
811 }
812
813 // Key string
81448 if (len > 1) {
81526 keys = keys.map(function(key){
81654 return inspect(key);
817 });
81826 var last = keys.pop();
81926 str = keys.join(', ') + ', and ' + last;
820 } else {
82122 str = inspect(keys[0]);
822 }
823
824 // Form
82548 str = (len > 1 ? 'keys ' : 'key ') + str;
826
827 // Have / include
82848 str = (this.contains ? 'contain ' : 'have ') + str;
829
830 // Assertion
83148 this.assert(
832 ok
833 , 'expected ' + this.inspect + ' to ' + str
834 , 'expected ' + this.inspect + ' to not ' + str
835 , keys
836 , Object.keys(this.obj)
837 );
838
83932 return this;
840}
841
842/**
843 * # .throw(constructor)
844 *
845 * Assert that a function will throw a specific type of error or that error
846 * thrown will match a RegExp or include a string.
847 *
848 * var fn = function () { throw new ReferenceError('This is a bad function.'); }
849 * expect(fn).to.throw(ReferenceError);
850 * expect(fn).to.throw(/bad function/);
851 * expect(fn).to.not.throw('good function');
852 * expect(fn).to.throw(ReferenceError, /bad function/);
853 *
854 * Please note that when a throw expectation is negated, it will check each
855 * parameter independently, starting with Error constructor type. The appropriate way
856 * to check for the existence of a type of error but for a message that does not match
857 * is to use `and`.
858 *
859 * expect(fn).to.throw(ReferenceError).and.not.throw(/good function/);
860 *
861 * @name throw
862 * @alias throws
863 * @alias Throw
864 * @param {ErrorConstructor} constructor
865 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
866 * @api public
867 */
868
8691Assertion.prototype.throw = function (constructor, msg) {
87064 new Assertion(this.obj).is.a('function');
871
87264 var thrown = false;
873
87464 if (arguments.length === 0) {
87511 msg = null;
87611 constructor = null;
87753 } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
87811 msg = constructor;
87911 constructor = null;
880 }
881
88264 try {
88364 this.obj();
884 } catch (err) {
885 // first, check constructor
88651 if (constructor && 'function' === typeof constructor) {
88730 this.assert(
888 err instanceof constructor && err.name == constructor.name
889 , 'expected ' + this.inspect + ' to throw ' + constructor.name + ' but a ' + err.name + ' was thrown'
890 , 'expected ' + this.inspect + ' to not throw ' + constructor.name );
89134 if (!msg) return this;
892 }
893 // next, check message
89431 if (err.message && msg && msg instanceof RegExp) {
89513 this.assert(
896 msg.exec(err.message)
897 , 'expected ' + this.inspect + ' to throw error matching ' + msg + ' but got ' + inspect(err.message)
898 , 'expected ' + this.inspect + ' to throw error not matching ' + msg
899 );
9007 return this;
90118 } else if (err.message && msg && 'string' === typeof msg) {
9028 this.assert(
903 ~err.message.indexOf(msg)
904 , 'expected ' + this.inspect + ' to throw error including ' + inspect(msg) + ' but got ' + inspect(err.message)
905 , 'expected ' + this.inspect + ' to throw error not including ' + inspect(msg)
906 );
9076 return this;
908 } else {
90910 thrown = true;
910 }
911 }
912
91323 var name = (constructor ? constructor.name : 'an error');
914
91523 this.assert(
916 thrown === true
917 , 'expected ' + this.inspect + ' to throw ' + name
918 , 'expected ' + this.inspect + ' to not throw ' + name);
919
92015 return this;
921};
922
923/**
924 * # .respondTo(method)
925 *
926 * Assert that object/class will respond to a method.
927 *
928 * expect(Klass).to.respondTo('bar');
929 * expect(obj).to.respondTo('bar');
930 *
931 * @name respondTo
932 * @param {String} method
933 * @api public
934 */
935
9361Assertion.prototype.respondTo = function (method) {
93710 var context = ('function' === typeof this.obj)
938 ? this.obj.prototype[method]
939 : this.obj[method];
940
94110 this.assert(
942 'function' === typeof context
943 , 'expected ' + this.inspect + ' to respond to ' + inspect(method)
944 , 'expected ' + this.inspect + ' to not respond to ' + inspect(method)
945 , 'function'
946 , typeof context
947 );
948
9496 return this;
950};
951
952/**
953 * # .satisfy(method)
954 *
955 * Assert that passes a truth test.
956 *
957 * expect(1).to.satisfy(function(num) { return num > 0; });
958 *
959 * @name satisfy
960 * @param {Function} matcher
961 * @api public
962 */
963
9641Assertion.prototype.satisfy = function (matcher) {
9654 this.assert(
966 matcher(this.obj)
967 , 'expected ' + this.inspect + ' to satisfy ' + inspect(matcher)
968 , 'expected ' + this.inspect + ' to not satisfy' + inspect(matcher)
969 , this.negate ? false : true
970 , matcher(this.obj)
971 );
972
9732 return this;
974};
975
976/**
977 * # .closeTo(expected, delta)
978 *
979 * Assert that actual is equal to +/- delta.
980 *
981 * expect(1.5).to.be.closeTo(1, 0.5);
982 *
983 * @name closeTo
984 * @param {Number} expected
985 * @param {Number} delta
986 * @api public
987 */
988
9891Assertion.prototype.closeTo = function (expected, delta) {
9904 this.assert(
991 (this.obj - delta === expected) || (this.obj + delta === expected)
992 , 'expected ' + this.inspect + ' to be close to ' + expected + ' +/- ' + delta
993 , 'expected ' + this.inspect + ' not to be close to ' + expected + ' +/- ' + delta);
994
9952 return this;
996};
997
998/*!
999 * Aliases.
1000 */
1001
10021(function alias(name, as){
10038 Assertion.prototype[as] = Assertion.prototype[name];
10048 return alias;
1005})
1006('length', 'lengthOf')
1007('keys', 'key')
1008('ownProperty', 'haveOwnProperty')
1009('above', 'greaterThan')
1010('below', 'lessThan')
1011('throw', 'throws')
1012('throw', 'Throw') // for troublesome browsers
1013('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) {
16166 options = options || {};
17166 this.name = 'AssertionError';
18166 this.message = options.message;
19166 this.actual = options.actual;
20166 this.expected = options.expected;
21166 this.operator = options.operator;
22166 var stackStartFunction = options.stackStartFunction || fail;
23
24166 if (Error.captureStackTrace) {
25166 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) {
182256 var ctx = {
19 showHidden: showHidden,
20 seen: [],
212648 stylize: function (str) { return str; }
22 };
232256 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
292686 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
382686 var primitive = formatPrimitive(ctx, value);
392686 if (primitive) {
402058 return primitive;
41 }
42
43 // Look up the keys of the object.
44628 var visibleKeys = Object.keys(value);
45628 var keys = ctx.showHidden ? Object.getOwnPropertyNames(value) : visibleKeys;
46
47 // Some type of object without properties can be shortcutted.
48628 if (keys.length === 0) {
49388 if (typeof value === 'function') {
50324 var name = value.name ? ': ' + value.name : '';
51324 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) {
1232686 switch (typeof value) {
124 case 'undefined':
12530 return ctx.stylize('undefined', 'undefined');
126
127 case 'string':
1281438 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
129 .replace(/'/g, "\\'")
130 .replace(/\\"/g, '"') + '\'';
1311438 return ctx.stylize(simple, 'string');
132
133 case 'number':
134492 return ctx.stylize('' + value, 'number');
135
136 case 'boolean':
13782 return ctx.stylize('' + value, 'boolean');
138 }
139 // For some reason typeof null is "object", so special case here.
140644 if (value === null) {
14116 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) {
9251 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%
74
74
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 * # .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) {
7743 var test = new Assertion(act, msg);
78
7943 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) {
1002 var test = new Assertion(act, msg);
101
1022 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) {
1232 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) {
1412 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) {
1592 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) {
1772 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) {
2302 new Assertion(val, msg).to.equal(null);
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) {
2482 new Assertion(val, msg).to.not.equal(null);
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) {
2652 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) {
2832 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) {
3193 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) {
3373 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) {
3553 new Assertion(val, msg).to.be.a('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) {
3763 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) {
4354 var obj = new Assertion(exp, msg);
436
4374 if (Array.isArray(exp)) {
4381 obj.to.include(inc);
4393 } else if ('string' === typeof exp) {
4403 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) {
4784 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) {
4993 if ('string' === typeof type) {
5001 msg = type;
5011 type = null;
502 }
503
5043 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) {
5253 if ('string' === typeof type) {
5261 msg = type;
5271 type = null;
528 }
529
5303 new Assertion(fn, msg).to.not.throw(type);
531 };
532
533 /**
534 * # .operator(val, operator, val2, [message])
535 *
536 * Compare two values using operator.
537 *
538 * assert.operator(1, '<', 2, 'everything is ok');
539 * assert.operator(1, '>', 2, 'this will fail');
540 *
541 * @name operator
542 * @param {*} object to test
543 * @param {String} operator
544 * @param {*} second object
545 * @param {String} message
546 * @api public
547 */
548
5491 assert.operator = function (val, operator, val2, msg) {
55015 if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
5511 throw new Error('Invalid operator "' + operator + '"');
552 }
55314 new Assertion(eval(val + operator + val2), msg).to.be.true;
554 };
555
556 /*!
557 * Undocumented / untested
558 */
559
5601 assert.ifError = function (val, msg) {
5614 new Assertion(val, msg).to.not.be.ok;
562 };
563
564 /*!
565 * Aliases.
566 */
567
5681 (function alias(name, as){
5692 assert[as] = assert[name];
5702 return alias;
571 })
572 ('length', 'lengthOf')
573 ('throws', 'throw');
574};