Coverage

90%
602
544
58

chai.js

100%
16
16
0
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
71var used = []
8 , exports = module.exports = {};
9
10/*!
11 * Chai version
12 */
13
141exports.version = '1.0.0alpha1';
15
16/*!
17 * Primary `Assertion` prototype
18 */
19
201exports.Assertion = require('./assertion');
21
22/*!
23 * Assertion Error
24 */
25
261exports.AssertionError = require('./error');
27
28/*!
29 * Utils for plugins (not exported)
30 */
31
321var util = require('./utils');
33
34/**
35 * # .use(function)
36 *
37 * Provides a way to extend the internals of Chai
38 *
39 * @param {Function}
40 * @returns {this} for chaining
41 * @api public
42 */
43
441exports.use = function (fn) {
456 if (!~used.indexOf(fn)) {
465 fn(this, util);
475 used.push(fn);
48 }
49
506 return this;
51};
52
53/*!
54 * Expect interface
55 */
56
571var expect = require('./interface/expect');
581exports.use(expect);
59
60/*!
61 * Should interface
62 */
63
641var should = require('./interface/should');
651exports.use(should);
66
67/*!
68 * Assert interface
69 */
70
711var assert = require('./interface/assert');
721exports.use(assert);

assertion.js

100%
190
190
0
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011-2012 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 , toString = Object.prototype.toString
50 , util = require('./utils')
51 , flag = util.flag;
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) {
69841 flag(this, 'ssfi', stack || arguments.callee);
70841 flag(this, 'object', obj);
71841 flag(this, 'message', msg);
72}
73
74/*!
75 * ## Assertion.includeStack
76 *
77 * User configurable property, influences whether stack trace
78 * is included in Assertion error message. Default of false
79 * suppresses stack trace in the error message
80 *
81 * Assertion.includeStack = true; // enable stack on error
82 *
83 * @api public
84 */
85
861Assertion.includeStack = false;
87
88/*!
89 * # .assert(expression, message, negateMessage, expected, actual)
90 *
91 * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
92 *
93 * @name assert
94 * @param {Philosophical} expression to be tested
95 * @param {String} message to display if fails
96 * @param {String} negatedMessage to display if negated expression fails
97 * @param {Mixed} expected value (remember to check for negation)
98 * @param {Mixed} actual (optional) will default to `this.obj`
99 * @api private
100 */
101
1021Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual) {
103847 var msg = util.getMessage(this, arguments)
104 , actual = util.getActual(this, arguments)
105 , ok = util.test(this, arguments);
106
107847 if (!ok) {
108187 throw new AssertionError({
109 message: msg
110 , actual: actual
111 , expected: expected
112 , stackStartFunction: (Assertion.includeStack) ? this.assert : flag(this, 'ssfi')
113 });
114 }
115};
116
117/**
118 * # to
119 *
120 * Language chain.
121 *
122 * @name to
123 * @api public
124 */
125
1261Object.defineProperty(Assertion.prototype, 'to',
127 { get: function () {
128460 return this;
129 }
130 , configurable: true
131});
132
133/**
134 * # be
135 *
136 * Language chain.
137 *
138 * @name be
139 * @api public
140 */
141
1421Object.defineProperty(Assertion.prototype, 'be',
143 { get: function () {
144183 return this;
145 }
146 , configurable: true
147});
148
149/**
150 * # been
151 *
152 * Language chain. Also tests `tense` to past for addon
153 * modules that use the tense feature.
154 *
155 * @name been
156 * @api public
157 */
158
1591Object.defineProperty(Assertion.prototype, 'been',
160 { get: function () {
1611 flag(this, 'tense', 'past');
1621 return this;
163 }
164 , configurable: true
165});
166
167/**
168 * # .a(type)
169 *
170 * Assert typeof. Also can be used as a language chain.
171 *
172 * expect('test').to.be.a('string');
173 * expect(foo).to.be.an.instanceof(Foo);
174 *
175 * @name a
176 * @alias an
177 * @param {String} type
178 * @api public
179 */
180
1811var an = function () {
182178 var assert = function(type) {
183174 var obj = flag(this, 'object')
184 , klass = type.charAt(0).toUpperCase() + type.slice(1);
185
186174 this.assert(
187 '[object ' + klass + ']' === toString.call(obj)
188 , 'expected #{this} to be a ' + type
189 , 'expected #{this} not to be a ' + type
190 , '[object ' + klass + ']'
191 , toString.call(obj)
192 );
193
194153 return this;
195 };
196
197178 assert.__proto__ = this;
198178 return assert;
199};
200
2011Object.defineProperty(Assertion.prototype, 'an',
202 { get: an
203 , configurable: true
204});
205
2061Object.defineProperty(Assertion.prototype, 'a',
207 { get: an
208 , configurable: true
209});
210
211/**
212 * # .include(value)
213 *
214 * Assert the inclusion of an object in an Array or substring in string.
215 * Also toggles the `contain` flag for the `keys` assertion if used as property.
216 *
217 * expect([1,2,3]).to.include(2);
218 *
219 * @name include
220 * @alias contain
221 * @param {Object|String|Number} obj
222 * @api public
223 */
2241var include = function () {
22553 flag(this, 'contains', true);
226
22753 var assert = function(val) {
22817 var obj = flag(this, 'object')
22917 this.assert(
230 ~obj.indexOf(val)
231 , 'expected #{this} to include ' + util.inspect(val)
232 , 'expected #{this} to not include ' + util.inspect(val));
233
23413 return this;
235 };
236
23753 assert.__proto__ = this;
23853 return assert;
239};
240
2411Object.defineProperty(Assertion.prototype, 'contain',
242 { get: include
243 , configurable: true
244});
245
2461Object.defineProperty(Assertion.prototype, 'include',
247 { get: include
248 , configurable: true
249});
250
251
252/**
253 * # is
254 *
255 * Language chain.
256 *
257 * @name is
258 * @api public
259 */
260
2611Object.defineProperty(Assertion.prototype, 'is',
262 { get: function () {
263124 return this;
264 }
265 , configurable: true
266});
267
268/**
269 * # and
270 *
271 * Language chain.
272 *
273 * @name and
274 * @api public
275 */
276
2771Object.defineProperty(Assertion.prototype, 'and',
278 { get: function () {
2791 return this;
280 }
281 , configurable: true
282});
283
284/**
285 * # have
286 *
287 * Language chain.
288 *
289 * @name have
290 * @api public
291 */
292
2931Object.defineProperty(Assertion.prototype, 'have',
294 { get: function () {
29593 return this;
296 }
297 , configurable: true
298});
299
300/**
301 * # with
302 *
303 * Language chain.
304 *
305 * @name with
306 * @api public
307 */
308
3091Object.defineProperty(Assertion.prototype, 'with',
310 { get: function () {
3112 return this;
312 }
313 , configurable: true
314});
315
316/**
317 * # .not
318 *
319 * Negates any of assertions following in the chain.
320 *
321 * @name not
322 * @api public
323 */
324
3251Object.defineProperty(Assertion.prototype, 'not',
326 { get: function () {
327176 flag(this, 'negate', true);
328176 return this;
329 }
330 , configurable: true
331});
332
333/**
334 * # .ok
335 *
336 * Assert object truthiness.
337 *
338 * expect('everthing').to.be.ok;
339 * expect(false).to.not.be.ok;
340 * expect(undefined).to.not.be.ok;
341 * expect(null).to.not.be.ok;
342 *
343 * @name ok
344 * @api public
345 */
346
3471Object.defineProperty(Assertion.prototype, 'ok',
348 { get: function () {
34922 this.assert(
350 flag(this, 'object')
351 , 'expected #{this} to be truthy'
352 , 'expected #{this} to be falsy');
353
35414 return this;
355 }
356 , configurable: true
357});
358
359/**
360 * # .true
361 *
362 * Assert object is true
363 *
364 * @name true
365 * @api public
366 */
367
3681Object.defineProperty(Assertion.prototype, 'true',
369 { get: function () {
37012 this.assert(
371 true === flag(this, 'object')
372 , 'expected #{this} to be true'
373 , 'expected #{this} to be false'
374 , this.negate ? false : true
375 );
376
3777 return this;
378 }
379 , configurable: true
380});
381
382/**
383 * # .false
384 *
385 * Assert object is false
386 *
387 * @name false
388 * @api public
389 */
390
3911Object.defineProperty(Assertion.prototype, 'false',
392 { get: function () {
39312 this.assert(
394 false === flag(this, 'object')
395 , 'expected #{this} to be false'
396 , 'expected #{this} to be true'
397 , this.negate ? true : false
398 );
399
4008 return this;
401 }
402 , configurable: true
403});
404
405/**
406 * # .exist
407 *
408 * Assert object exists (null).
409 *
410 * var foo = 'hi'
411 * , bar;
412 * expect(foo).to.exist;
413 * expect(bar).to.not.exist;
414 *
415 * @name exist
416 * @api public
417 */
418
4191Object.defineProperty(Assertion.prototype, 'exist',
420 { get: function () {
4216 this.assert(
422 null != flag(this, 'object')
423 , 'expected #{this} to exist'
424 , 'expected #{this} to not exist'
425 );
426
4274 return this;
428 }
429 , configurable: true
430});
431
432/**
433 * # .empty
434 *
435 * Assert object's length to be 0.
436 *
437 * expect([]).to.be.empty;
438 *
439 * @name empty
440 * @api public
441 */
442
4431Object.defineProperty(Assertion.prototype, 'empty',
444 { get: function () {
44532 var obj = flag(this, 'object')
446 , expected = obj;
447
44832 if (Array.isArray(obj)) {
4498 expected = obj.length;
45024 } else if (typeof obj === 'object') {
45116 expected = Object.keys(obj).length;
452 }
453
45432 this.assert(
455 !expected
456 , 'expected #{this} to be empty'
457 , 'expected #{this} not to be empty');
458
45916 return this;
460 }
461 , configurable: true
462});
463
464/**
465 * # .arguments
466 *
467 * Assert object is an instanceof arguments.
468 *
469 * function test () {
470 * expect(arguments).to.be.arguments;
471 * }
472 *
473 * @name arguments
474 * @api public
475 */
476
4771Object.defineProperty(Assertion.prototype, 'arguments',
478 { get: function () {
4794 var obj = flag(this, 'object');
4804 this.assert(
481 '[object Arguments]' == Object.prototype.toString.call(obj)
482 , 'expected #{this} to be arguments'
483 , 'expected #{this} to not be arguments'
484 , '[object Arguments]'
485 , Object.prototype.toString.call(obj)
486 );
487
4884 return this;
489 }
490 , configurable: true
491});
492
493/**
494 * # .equal(value)
495 *
496 * Assert strict equality.
497 *
498 * expect('hello').to.equal('hello');
499 *
500 * @name equal
501 * @param {*} value
502 * @api public
503 */
504
5051Assertion.prototype.equal = function (val) {
506177 this.assert(
507 val === flag(this, 'object')
508 , 'expected #{this} to equal #{exp}'
509 , 'expected #{this} to not equal #{exp}'
510 , val );
511
512167 return this;
513};
514
515/**
516 * # .eql(value)
517 *
518 * Assert deep equality.
519 *
520 * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
521 *
522 * @name eql
523 * @param {*} value
524 * @api public
525 */
526
5271Assertion.prototype.eql = function (obj) {
52814 this.assert(
529 util.eql(obj, flag(this, 'object'))
530 , 'expected #{this} to equal #{exp}'
531 , 'expected #{this} to not equal #{exp}'
532 , obj );
533
53410 return this;
535};
536
537/**
538 * # .above(value)
539 *
540 * Assert greater than `value`.
541 *
542 * expect(10).to.be.above(5);
543 *
544 * @name above
545 * @alias mt
546 * @param {Number} value
547 * @api public
548 */
549
5501Assertion.prototype.above = function (val) {
55112 this.assert(
552 flag(this, 'object') > val
553 , 'expected #{this} to be above ' + val
554 , 'expected #{this} to be below ' + val);
555
5568 return this;
557};
558
559/**
560 * # .below(value)
561 *
562 * Assert less than `value`.
563 *
564 * expect(5).to.be.below(10);
565 *
566 * @name below
567 * @alias lt
568 * @param {Number} value
569 * @api public
570 */
571
5721Assertion.prototype.below = function (val) {
57312 this.assert(
574 flag(this, 'object') < val
575 , 'expected #{this} to be below ' + val
576 , 'expected #{this} to be above ' + val);
577
5788 return this;
579};
580
581/**
582 * # .within(start, finish)
583 *
584 * Assert that a number is within a range.
585 *
586 * expect(7).to.be.within(5,10);
587 *
588 * @name within
589 * @param {Number} start lowerbound inclusive
590 * @param {Number} finish upperbound inclusive
591 * @api public
592 */
593
5941Assertion.prototype.within = function (start, finish) {
59512 var obj = flag(this, 'object')
596 , range = start + '..' + finish;
597
59812 this.assert(
599 obj >= start && obj <= finish
600 , 'expected #{this} to be within ' + range
601 , 'expected #{this} to not be within ' + range);
602
6038 return this;
604};
605
606/**
607 * # .instanceof(constructor)
608 *
609 * Assert instanceof.
610 *
611 * var Tea = function (name) { this.name = name; }
612 * , Chai = new Tea('chai');
613 *
614 * expect(Chai).to.be.an.instanceof(Tea);
615 *
616 * @name instanceof
617 * @param {Constructor}
618 * @alias instanceOf
619 * @api public
620 */
621
6221Assertion.prototype.instanceOf = function (constructor) {
62314 var name = util.getName(constructor);
62414 this.assert(
625 flag(this, 'object') instanceof constructor
626 , 'expected #{this} to be an instance of ' + name
627 , 'expected #{this} to not be an instance of ' + name);
628
6297 return this;
630};
631
632/**
633 * # .property(name, [value])
634 *
635 * Assert that property of `name` exists, optionally with `value`.
636 *
637 * var obj = { foo: 'bar' }
638 * expect(obj).to.have.property('foo');
639 * expect(obj).to.have.property('foo', 'bar');
640 * expect(obj).to.have.property('foo').to.be.a('string');
641 *
642 * @name property
643 * @param {String} name
644 * @param {*} value (optional)
645 * @returns value of property for chaining
646 * @api public
647 */
648
6491Assertion.prototype.property = function (name, val) {
65038 var obj = flag(this, 'object')
651 , value = util.getPathValue(name, obj)
652 , negate = flag(this, 'negate');
653
65438 if (negate && undefined !== val) {
6554 if (undefined === value) {
6562 throw new Error(util.inspect(obj) + ' has no property ' + util.inspect(name));
657 }
658 } else {
65934 this.assert(
660 undefined !== value
661 , 'expected #{this} to have a property ' + util.inspect(name)
662 , 'expected #{this} to not have property ' + util.inspect(name));
663 }
664
66531 if (undefined !== val) {
66611 this.assert(
667 val === value
668 , 'expected #{this} to have a property ' + util.inspect(name) + ' of #{exp}, but got #{act}'
669 , 'expected #{this} to not have a property ' + util.inspect(name) + ' of #{act}'
670 , val
671 , value
672 );
673 }
674
67525 flag(this, 'object', value);
67625 return this;
677};
678
679/**
680 * # .ownProperty(name)
681 *
682 * Assert that has own property by `name`.
683 *
684 * expect('test').to.have.ownProperty('length');
685 *
686 * @name ownProperty
687 * @alias haveOwnProperty
688 * @param {String} name
689 * @api public
690 */
691
6921Assertion.prototype.ownProperty = function (name) {
6938 var obj = flag(this, 'object');
6948 this.assert(
695 obj.hasOwnProperty(name)
696 , 'expected #{this} to have own property ' + util.inspect(name)
697 , 'expected #{this} to not have own property ' + util.inspect(name));
6986 return this;
699};
700
701/**
702 * # .length(val)
703 *
704 * Assert that object has expected length.
705 *
706 * expect([1,2,3]).to.have.length(3);
707 * expect('foobar').to.have.length(6);
708 *
709 * @name length
710 * @alias lengthOf
711 * @param {Number} length
712 * @api public
713 */
714
7151Assertion.prototype.length = function (n) {
71616 var obj = flag(this, 'object');
71716 new Assertion(obj).to.have.property('length');
71813 var len = obj.length;
719
72013 this.assert(
721 len == n
722 , 'expected #{this} to have a length of #{exp} but got #{act}'
723 , 'expected #{this} to not have a length of #{act}'
724 , n
725 , len
726 );
727
7289 return this;
729};
730
731/**
732 * # .match(regexp)
733 *
734 * Assert that matches regular expression.
735 *
736 * expect('foobar').to.match(/^foo/);
737 *
738 * @name match
739 * @param {RegExp} RegularExpression
740 * @api public
741 */
742
7431Assertion.prototype.match = function (re) {
7448 var obj = flag(this, 'object');
7458 this.assert(
746 re.exec(obj)
747 , 'expected #{this} to match ' + re
748 , 'expected #{this} not to match ' + re);
749
7504 return this;
751};
752
753
754/**
755 * # .string(string)
756 *
757 * Assert inclusion of string in string.
758 *
759 * expect('foobar').to.have.string('bar');
760 *
761 * @name string
762 * @param {String} string
763 * @api public
764 */
765
7661Assertion.prototype.string = function (str) {
76714 var obj = flag(this, 'object');
76814 new Assertion(obj).is.a('string');
769
77012 this.assert(
771 ~obj.indexOf(str)
772 , 'expected #{this} to contain ' + util.inspect(str)
773 , 'expected #{this} to not contain ' + util.inspect(str));
774
7757 return this;
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 obj = flag(this, 'object')
794 , str
795 , ok = true;
796
79756 keys = keys instanceof Array
798 ? keys
799 : Array.prototype.slice.call(arguments);
800
80164 if (!keys.length) throw new Error('keys required');
802
80348 var actual = Object.keys(obj)
804 , len = keys.length;
805
806 // Inclusion
80748 ok = keys.every(function(key){
80870 return ~actual.indexOf(key);
809 });
810
811 // Strict
81248 if (!flag(this, 'negate') && !flag(this, 'contains')) {
81312 ok = ok && keys.length == actual.length;
814 }
815
816 // Key string
81748 if (len > 1) {
81826 keys = keys.map(function(key){
81954 return util.inspect(key);
820 });
82126 var last = keys.pop();
82226 str = keys.join(', ') + ', and ' + last;
823 } else {
82422 str = util.inspect(keys[0]);
825 }
826
827 // Form
82848 str = (len > 1 ? 'keys ' : 'key ') + str;
829
830 // Have / include
83148 str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
832
833 // Assertion
83448 this.assert(
835 ok
836 , 'expected #{this} to ' + str
837 , 'expected #{this} to not ' + str
838 , keys
839 , Object.keys(obj)
840 );
841
84232 return this;
843}
844
845/**
846 * # .throw(constructor)
847 *
848 * Assert that a function will throw a specific type of error, or specific type of error
849 * (as determined using `instanceof`), optionally with a RegExp or string inclusion test
850 * for the error's message.
851 *
852 * var err = new ReferenceError('This is a bad function.');
853 * var fn = function () { throw err; }
854 * expect(fn).to.throw(ReferenceError);
855 * expect(fn).to.throw(Error);
856 * expect(fn).to.throw(/bad function/);
857 * expect(fn).to.not.throw('good function');
858 * expect(fn).to.throw(ReferenceError, /bad function/);
859 * expect(fn).to.throw(err);
860 * expect(fn).to.not.throw(new RangeError('Out of range.'));
861 *
862 * Please note that when a throw expectation is negated, it will check each
863 * parameter independently, starting with error constructor type. The appropriate way
864 * to check for the existence of a type of error but for a message that does not match
865 * is to use `and`.
866 *
867 * expect(fn).to.throw(ReferenceError).and.not.throw(/good function/);
868 *
869 * @name throw
870 * @alias throws
871 * @alias Throw
872 * @param {ErrorConstructor} constructor
873 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
874 * @api public
875 */
876
8771Assertion.prototype.Throw = function (constructor, msg) {
87897 var obj = flag(this, 'object');
87997 new Assertion(obj).is.a('function');
880
88197 var thrown = false
882 , desiredError = null
883 , name = null;
884
88597 if (arguments.length === 0) {
88613 msg = null;
88713 constructor = null;
88884 } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
88911 msg = constructor;
89011 constructor = null;
89173 } else if (constructor && constructor instanceof Error) {
89220 desiredError = constructor;
89320 constructor = null;
89420 msg = null;
89553 } else if (typeof constructor === 'function') {
89645 name = (new constructor()).name;
897 } else {
8988 constructor = null;
899 }
900
90197 try {
90297 obj();
903 } catch (err) {
904 // first, check desired error
90580 if (desiredError) {
90616 this.assert(
907 err === desiredError
908 , 'expected #{this} to throw ' + util.inspect(desiredError) + ' but ' + util.inspect(err) + ' was thrown'
909 , 'expected #{this} to not throw ' + util.inspect(desiredError)
910 );
91110 return this;
912 }
913 // next, check constructor
91464 if (constructor) {
91541 this.assert(
916 err instanceof constructor
917 , 'expected #{this} to throw ' + name + ' but a ' + err.name + ' was thrown'
918 , 'expected #{this} to not throw ' + name );
91948 if (!msg) return this;
920 }
921 // next, check message
92233 if (err.message && msg && msg instanceof RegExp) {
92313 this.assert(
924 msg.exec(err.message)
925 , 'expected #{this} to throw error matching ' + msg + ' but got ' + util.inspect(err.message)
926 , 'expected #{this} to throw error not matching ' + msg
927 );
9287 return this;
92920 } else if (err.message && msg && 'string' === typeof msg) {
9308 this.assert(
931 ~err.message.indexOf(msg)
932 , 'expected #{this} to throw error including #{exp} but got #{act}'
933 , 'expected #{this} to throw error not including #{act}'
934 , msg
935 , err.message
936 );
9376 return this;
938 } else {
93912 thrown = true;
940 }
941 }
942
94329 var expectedThrown = name ? name : desiredError ? util.inspect(desiredError) : 'an error';
944
94529 this.assert(
946 thrown === true
947 , 'expected #{this} to throw ' + expectedThrown
948 , 'expected #{this} to not throw ' + expectedThrown);
949
95019 return this;
951};
952
953/**
954 * # .respondTo(method)
955 *
956 * Assert that object/class will respond to a method.
957 *
958 * expect(Klass).to.respondTo('bar');
959 * expect(obj).to.respondTo('bar');
960 *
961 * @name respondTo
962 * @param {String} method
963 * @api public
964 */
965
9661Assertion.prototype.respondTo = function (method) {
96710 var obj = flag(this, 'object')
968 , context = ('function' === typeof obj)
969 ? obj.prototype[method]
970 : obj[method];
971
97210 this.assert(
973 'function' === typeof context
974 , 'expected #{this} to respond to ' + util.inspect(method)
975 , 'expected #{this} to not respond to ' + util.inspect(method)
976 , 'function'
977 , typeof context
978 );
979
9806 return this;
981};
982
983/**
984 * # .satisfy(method)
985 *
986 * Assert that passes a truth test.
987 *
988 * expect(1).to.satisfy(function(num) { return num > 0; });
989 *
990 * @name satisfy
991 * @param {Function} matcher
992 * @api public
993 */
994
9951Assertion.prototype.satisfy = function (matcher) {
9964 var obj = flag(this, 'object');
9974 this.assert(
998 matcher(obj)
999 , 'expected #{this} to satisfy ' + util.inspect(matcher)
1000 , 'expected #{this} to not satisfy' + util.inspect(matcher)
1001 , this.negate ? false : true
1002 , matcher(obj)
1003 );
1004
10052 return this;
1006};
1007
1008/**
1009 * # .closeTo(expected, delta)
1010 *
1011 * Assert that actual is equal to +/- delta.
1012 *
1013 * expect(1.5).to.be.closeTo(1, 0.5);
1014 *
1015 * @name closeTo
1016 * @param {Number} expected
1017 * @param {Number} delta
1018 * @api public
1019 */
1020
10211Assertion.prototype.closeTo = function (expected, delta) {
10224 var obj = flag(this, 'object');
10234 this.assert(
1024 (obj - delta === expected) || (obj + delta === expected)
1025 , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
1026 , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta);
1027
10282 return this;
1029};
1030
1031/*!
1032 * Aliases.
1033 */
1034
10351(function alias(name, as){
103611 Assertion.prototype[as] = Assertion.prototype[name];
103711 return alias;
1038})
1039('equal', 'eq')
1040('above', 'mt')
1041('below', 'lt')
1042('length', 'lengthOf')
1043('keys', 'key')
1044('ownProperty', 'haveOwnProperty')
1045('above', 'greaterThan')
1046('below', 'lessThan')
1047('Throw', 'throws')
1048('Throw', 'throw')
1049('instanceOf', 'instanceof');

error.js

79%
24
19
5
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/*!
8 * Module dependancies
9 */
10
111var fs = require('fs');
12
13/*!
14 * Main export
15 */
16
171module.exports = AssertionError;
18
19/**
20 * # AssertionError (constructor)
21 *
22 * Create a new assertion error based on the Javascript
23 * `Error` prototype.
24 *
25 * **Options**
26 * - message
27 * - actual
28 * - expected
29 * - operator
30 * - startStackFunction
31 *
32 * @param {Object} options
33 * @api public
34 */
35
361function AssertionError (options) {
37189 options = options || {};
38189 this.message = options.message;
39189 this.actual = options.actual;
40189 this.expected = options.expected;
41189 this.operator = options.operator;
42
43189 if (options.stackStartFunction && Error.captureStackTrace) {
44 // We need the raw stack so we can make a JSON
45 // object for writing to the logs.
46188 var stackStartFunction = options.stackStartFunction
47 , orig = Error.prepareStackTrace;
48
49 // Custom stack track
50376 Error.prepareStackTrace = function(_, stack){ return stack; };
51188 Error.captureStackTrace(this, stackStartFunction);
52188 this.__stack = this.stack;
53
54 // return original
55188 Error.prepareStackTrace = orig;
56
57188 Object.defineProperty(this, 'stack',
58 { get: function () {
59 // If we have a stack trace then
60 // we are going to get the contents
61 // of the line that errored
620 if (this.__stack[1]) {
630 var filename = this.__stack[1].getFileName()
64 , lineno = this.__stack[1].getLineNumber()
65 , line = fs.readFileSync(filename, 'utf8').split('\n')[lineno - 1].trim();
660 return this.message + '\n[' + lineno + '] ' + filename + '\n' + line;
67
68 // Else, just return the message.
69 } else {
700 return this.message;
71 }
72 }
73 }
74 );
75 }
76}
77
78/*!
79 * Inherit from Error
80 */
81
821AssertionError.prototype = Object.create(Error.prototype);
831AssertionError.prototype.name = 'AssertionError';
841AssertionError.prototype.constructor = AssertionError;
85
86/**
87 * # toString()
88 *
89 * Override default to string method
90 */
91
921AssertionError.prototype.toString = function() {
930 return this.message;
94};

utils/index.js

100%
13
13
0
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/*!
8 * Main exports
9 */
10
111var exports = module.exports = {};
12
13/*!
14 * test utility
15 */
16
171exports.test = require('./test');
18
19/*!
20 * message utility
21 */
22
231exports.getMessage = require('./getMessage');
24
25/*!
26 * actual utility
27 */
28
291exports.getActual = require('./getActual');
30
31/*!
32 * Inspect util
33 */
34
351exports.inspect = require('./inspect');
36
37/*!
38 * Flag utility
39 */
40
411exports.flag = require('./flag');
42
43/*!
44 * Deep equal utility
45 */
46
471exports.eql = require('./eql');
48
49/*!
50 * Deep path value
51 */
52
531exports.getPathValue = require('./getPathValue');
54
55/*!
56 * Function name
57 */
58
591exports.getName = require('./getName');
60
61/*!
62 * add Property
63 */
64
651exports.addProperty = require('./addProperty');
66
67/*!
68 * add Method
69 */
70
711exports.addMethod = require('./addMethod');
72
73/*!
74 * overwrite Property
75 */
76
771exports.overwriteProperty = require('./overwriteProperty');
78
79/*!
80 * overwrite Method
81 */
82
831exports.overwriteMethod = require('./overwriteMethod');

utils/test.js

100%
4
4
0
LineHitsSource
1/*!
2 * Chai - test utility
3 * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/*!
8 * Module dependancies
9 */
10
111var flag = require('./flag');
12
13/**
14 * # test(object, expression)
15 *
16 * Test and object for expression.
17 *
18 * @param {Object} object (constructed Assertion)
19 * @param {Arguments} chai.Assertion.prototype.assert arguments
20 */
21
221module.exports = function (obj, args) {
23847 var negate = flag(obj, 'negate')
24 , expr = args[0];
25847 return negate ? !expr : expr;
26};

utils/flag.js

100%
5
5
0
LineHitsSource
1/*!
2 * Chai - flag utility
3 * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/**
8 * # flag(object ,key, [value])
9 *
10 * Get or set a flag value on an object. If a
11 * value is provided it will be set, else it will
12 * return the currently set value or `undefined` if
13 * the value is not set.
14 *
15 * @param {Object} object (constructed Assertion
16 * @param {String} key
17 * @param {Mixed} value (optional)
18 * @api private
19 */
20
211module.exports = function (obj, key, value) {
226513 var flags = obj.__flags || (obj.__flags = Object.create(null));
236513 if (arguments.length === 3) {
242778 flags[key] = value;
25 } else {
263735 return flags[key];
27 }
28};

utils/getMessage.js

100%
5
5
0
LineHitsSource
1/*!
2 * Chai - message composition utility
3 * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/*!
8 * Module dependancies
9 */
10
111var flag = require('./flag')
12 , getActual = require('./getActual')
13 , inspect = require('./inspect');
14
15/**
16 * # getMessage(object, message, negateMessage)
17 *
18 * Construct the error message based on flags
19 * and template tags. Template tags will return
20 * a stringified inspection of the object referenced.
21 *
22 * Messsage template tags:
23 * - `#{this}` current asserted object
24 * - `#{act}` actual value
25 * - `#{exp}` expected value
26 *
27 * @param {Object} object (constructed Assertion)
28 * @param {Arguments} chai.Assertion.prototype.assert arguments
29 */
30
311module.exports = function (obj, args) {
32847 var negate = flag(obj, 'negate')
33 , val = flag(obj, 'object')
34 , expected = args[3]
35 , actual = getActual(obj, args)
36 , msg = negate ? args[2] : args[1];
37
38847 msg = msg
39 .replace(/#{this}/g, inspect(val))
40 .replace(/#{act}/g, inspect(actual))
41 .replace(/#{exp}/g, inspect(expected));
42
43847 return obj.msg ? obj.msg + ': ' + msg : msg;
44};

utils/getActual.js

100%
3
3
0
LineHitsSource
1/*!
2 * Chai - getActual utility
3 * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/**
8 * # getActual(object, [actual])
9 *
10 * Returns the `actual` value for an Assertion
11 *
12 * @param {Object} object (constructed Assertion)
13 * @param {Arguments} chai.Assertion.prototype.assert arguments
14 */
15
161module.exports = function (obj, args) {
171694 var actual = args[4];
181694 return 'undefined' !== actual ? actual : obj.obj;
19};

utils/inspect.js

85%
125
107
18
LineHitsSource
1// This is (almost) directly from Node.js utils
2// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
3
41var getName = require('./getName');
5
61module.exports = inspect;
7
8/**
9 * Echos the value of a value. Trys to print the value out
10 * in the best way possible given the different types.
11 *
12 * @param {Object} obj The object to print out.
13 * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
14 * properties of objects.
15 * @param {Number} depth Depth in which to descend in object. Default is 2.
16 * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
17 * output. Default is false (no coloring).
18 */
191function inspect(obj, showHidden, depth, colors) {
202934 var ctx = {
21 showHidden: showHidden,
22 seen: [],
233208 stylize: function (str) { return str; }
24 };
252934 return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
26}
27
281function formatValue(ctx, value, recurseTimes) {
29 // Provide a hook for user-specified inspect functions.
30 // Check that value is an object with an inspect function on it
313335 if (value && typeof value.inspect === 'function' &&
32 // Filter out the util module, it's inspect function is special
33 value.inspect !== exports.inspect &&
34 // Also filter out any prototype objects using the circular check.
35 !(value.constructor && value.constructor.prototype === value)) {
360 return value.inspect(recurseTimes);
37 }
38
39 // Primitive types cannot have properties
403335 var primitive = formatPrimitive(ctx, value);
413335 if (primitive) {
422748 return primitive;
43 }
44
45 // Look up the keys of the object.
46587 var visibleKeys = Object.keys(value);
47587 var keys = ctx.showHidden ? Object.getOwnPropertyNames(value) : visibleKeys;
48
49 // Some type of object without properties can be shortcutted.
50 // In IE, errors have a single `stack` property, or if they are vanilla `Error`,
51 // a `stack` plus `description` property; ignore those for consistency.
52587 if (keys.length === 0 || (isError(value) && (
53 (keys.length === 1 && keys[0] === 'stack') ||
54 (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')
55 ))) {
56364 if (typeof value === 'function') {
57277 var name = getName(value);
58277 var nameSuffix = name ? ': ' + name : '';
59277 return ctx.stylize('[Function' + nameSuffix + ']', 'special');
60 }
6187 if (isRegExp(value)) {
620 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
63 }
6487 if (isDate(value)) {
650 return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
66 }
6787 if (isError(value)) {
6850 return formatError(value);
69 }
70 }
71
72260 var base = '', array = false, braces = ['{', '}'];
73
74 // Make Array say that they are Array
75260 if (isArray(value)) {
76148 array = true;
77148 braces = ['[', ']'];
78 }
79
80 // Make functions say that they are functions
81260 if (typeof value === 'function') {
821 var n = value.name ? ': ' + value.name : '';
831 base = ' [Function' + n + ']';
84 }
85
86 // Make RegExps say that they are RegExps
87260 if (isRegExp(value)) {
880 base = ' ' + RegExp.prototype.toString.call(value);
89 }
90
91 // Make dates with properties first say the date
92260 if (isDate(value)) {
930 base = ' ' + Date.prototype.toUTCString.call(value);
94 }
95
96 // Make error with message first say the error
97260 if (isError(value)) {
980 base = ' ' + formatError(value);
99 }
100
101260 if (keys.length === 0 && (!array || value.length == 0)) {
10237 return braces[0] + base + braces[1];
103 }
104
105223 if (recurseTimes < 0) {
1060 if (isRegExp(value)) {
1070 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
108 } else {
1090 return ctx.stylize('[Object]', 'special');
110 }
111 }
112
113223 ctx.seen.push(value);
114
115223 var output;
116223 if (array) {
117134 output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
118 } else {
11989 output = keys.map(function(key) {
120182 return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
121 });
122 }
123
124223 ctx.seen.pop();
125
126223 return reduceToSingleString(output, base, braces);
127}
128
129
1301function formatPrimitive(ctx, value) {
1313335 switch (typeof value) {
132 case 'undefined':
133852 return ctx.stylize('undefined', 'undefined');
134
135 case 'string':
1361469 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
137 .replace(/'/g, "\\'")
138 .replace(/\\"/g, '"') + '\'';
1391469 return ctx.stylize(simple, 'string');
140
141 case 'number':
142343 return ctx.stylize('' + value, 'number');
143
144 case 'boolean':
14575 return ctx.stylize('' + value, 'boolean');
146 }
147 // For some reason typeof null is "object", so special case here.
148596 if (value === null) {
1499 return ctx.stylize('null', 'null');
150 }
151}
152
153
1541function formatError(value) {
15550 return '[' + Error.prototype.toString.call(value) + ']';
156}
157
158
1591function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
160134 var output = [];
161134 for (var i = 0, l = value.length; i < l; ++i) {
162220 if (Object.prototype.hasOwnProperty.call(value, String(i))) {
163220 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
164 String(i), true));
165 } else {
1660 output.push('');
167 }
168 }
169134 keys.forEach(function(key) {
170220 if (!key.match(/^\d+$/)) {
1710 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
172 key, true));
173 }
174 });
175134 return output;
176}
177
178
1791function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
180402 var name, str;
181402 if (value.__lookupGetter__) {
182402 if (value.__lookupGetter__(key)) {
1831 if (value.__lookupSetter__(key)) {
1841 str = ctx.stylize('[Getter/Setter]', 'special');
185 } else {
1860 str = ctx.stylize('[Getter]', 'special');
187 }
188 } else {
189401 if (value.__lookupSetter__(key)) {
1900 str = ctx.stylize('[Setter]', 'special');
191 }
192 }
193 }
194402 if (visibleKeys.indexOf(key) < 0) {
1950 name = '[' + key + ']';
196 }
197402 if (!str) {
198401 if (ctx.seen.indexOf(value[key]) < 0) {
199401 if (recurseTimes === null) {
2000 str = formatValue(ctx, value[key], null);
201 } else {
202401 str = formatValue(ctx, value[key], recurseTimes - 1);
203 }
204401 if (str.indexOf('\n') > -1) {
2051 if (array) {
2060 str = str.split('\n').map(function(line) {
2070 return ' ' + line;
208 }).join('\n').substr(2);
209 } else {
2101 str = '\n' + str.split('\n').map(function(line) {
21139 return ' ' + line;
212 }).join('\n');
213 }
214 }
215 } else {
2160 str = ctx.stylize('[Circular]', 'special');
217 }
218 }
219402 if (typeof name === 'undefined') {
220402 if (array && key.match(/^\d+$/)) {
221220 return str;
222 }
223182 name = JSON.stringify('' + key);
224182 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
225173 name = name.substr(1, name.length - 2);
226173 name = ctx.stylize(name, 'name');
227 } else {
2289 name = name.replace(/'/g, "\\'")
229 .replace(/\\"/g, '"')
230 .replace(/(^"|"$)/g, "'");
2319 name = ctx.stylize(name, 'string');
232 }
233 }
234
235182 return name + ': ' + str;
236}
237
238
2391function reduceToSingleString(output, base, braces) {
240223 var numLinesEst = 0;
241223 var length = output.reduce(function(prev, cur) {
242402 numLinesEst++;
243403 if (cur.indexOf('\n') >= 0) numLinesEst++;
244402 return prev + cur.length + 1;
245 }, 0);
246
247223 if (length > 60) {
2482 return braces[0] +
249 (base === '' ? '' : base + '\n ') +
250 ' ' +
251 output.join(',\n ') +
252 ' ' +
253 braces[1];
254 }
255
256221 return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
257}
258
2591function isArray(ar) {
260260 return Array.isArray(ar) ||
261 (typeof ar === 'object' && objectToString(ar) === '[object Array]');
262}
263
2641function isRegExp(re) {
265347 return typeof re === 'object' && objectToString(re) === '[object RegExp]';
266}
267
2681function isDate(d) {
269347 return typeof d === 'object' && objectToString(d) === '[object Date]';
270}
271
2721function isError(e) {
273570 return typeof e === 'object' && objectToString(e) === '[object Error]';
274}
275
2761function objectToString(o) {
2771371 return Object.prototype.toString.call(o);
278}

utils/getName.js

100%
4
4
0
LineHitsSource
1/*!
2 * Chai - getName utility
3 * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/**
8 * # getName(func)
9 *
10 * Gets the name of a function, in a cross-browser way.
11 *
12 * @param {Function} a function (usually a constructor)
13 */
14
151module.exports = function (func) {
16321 if (func.name) return func.name;
17
18261 var match = /^\s?function ([^(]*)\(/.exec(func);
19261 return match && match[1] ? match[1] : "";
20};

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/getPathValue.js

95%
22
21
1
LineHitsSource
1/**
2 * Chai - getPathValue utility
3 * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
4 * @see https://github.com/logicalparadox/filtr
5 * MIT Licensed
6 */
7
8/**
9 * # .getPathValue(path, object)
10 *
11 * This allows the retrieval of values in an
12 * object given a string path.
13 *
14 * var obj = {
15 * prop1: {
16 * arr: ['a', 'b', 'c']
17 * , str: 'Hello'
18 * }
19 * , prop2: {
20 * arr: [ { nested: 'Universe' } ]
21 * , str: 'Hello again!'
22 * }
23 * }
24 *
25 * The following would be the results.
26 *
27 * getPathValue('prop1.str', obj); // Hello
28 * getPathValue('prop1.att[2]', obj); // b
29 * getPathValue('prop2.arr[0].nested', obj); // Universe
30 *
31 * @param {String} path
32 * @param {Object} object
33 * @returns {Object} value or `undefined`
34 * @api public
35 */
36
371var getPathValue = module.exports = function (path, obj) {
3842 var parsed = parsePath(path);
3942 return _getPathValue(parsed, obj);
40};
41
42/*!
43 * ## parsePath(path)
44 *
45 * Helper function used to parse string object
46 * paths. Use in conjunction with `_getPathValue`.
47 *
48 * var parsed = parsePath('myobject.property.subprop');
49 *
50 * ### Paths:
51 *
52 * * Can be as near infinitely deep and nested
53 * * Arrays are also valid using the formal `myobject.document[3].property`.
54 *
55 * @param {String} path
56 * @returns {Object} parsed
57 * @api private
58 */
59
601function parsePath (path) {
6142 var parts = path.split('.').filter(Boolean);
6242 return parts.map(function (value) {
6344 var re = /([A-Za-z0-9]+)\[(\d+)\]$/
64 , mArr = re.exec(value)
65 , val;
6646 if (mArr) val = { p: mArr[1], i: parseFloat(mArr[2]) };
6744 return val || value;
68 });
691};
70
71/**
72 * ## _getPathValue(parsed, obj)
73 *
74 * Helper companion function for `.parsePath` that returns
75 * the value located at the parsed address.
76 *
77 * var value = getPathValue(parsed, obj);
78 *
79 * @param {Object} parsed definition from `parsePath`.
80 * @param {Object} object to search against
81 * @returns {Object|Undefined} value
82 * @api private
83 */
84
851function _getPathValue (parsed, obj) {
8642 var tmp = obj
87 , res;
8842 for (var i = 0, l = parsed.length; i < l; i++) {
8944 var part = parsed[i];
9044 if (tmp) {
9144 if ('object' === typeof part && tmp[part.p]) {
922 tmp = tmp[part.p][part.i];
93 } else {
9442 tmp = tmp[part];
95 }
9686 if (i == (l - 1)) res = tmp;
97 } else {
980 res = undefined;
99 }
100 }
10142 return res;
1021};

utils/addProperty.js

20%
5
1
4
LineHitsSource
1/*!
2 * Chai - addProperty utility
3 * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/**
8 * # addProperty (ctx, name, getter)
9 *
10 * Adds a property to the prototype of an object.
11 *
12 * utils.addProperty(chai.Assertion, 'foo', function () {
13 * var obj = utils.flag(this, 'object');
14 * new chai.Assertion(obj).to.be.instanceof(Foo);
15 * return this;
16 * });
17 *
18 * Then can be used as any other assertion:
19 *
20 * expect(myFoo).to.be.foo;
21 *
22 * @param {Function|Object} context chai.Assertion || chai.Assertion.prototype
23 * @param {String} name of property to add
24 * @param {Function} getter function to used for name
25 * @api public
26 */
27
281module.exports = function (ctx, name, getter) {
290 var context = ('function' === typeof ctx) ? ctx.prototype : ctx;
300 Object.defineProperty(context, name,
31 { get: function () {
320 getter.call(this);
330 return this;
34 }
35 , configurable: true
36 });
37};

utils/addMethod.js

20%
5
1
4
LineHitsSource
1/*!
2 * Chai - addMethod utility
3 * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/**
8 * # addMethod (ctx, name, method)
9 *
10 * Adds a method to the prototype of an object.
11 *
12 * utils.addMethod(chai.Assertion, 'foo', function (str) {
13 * var obj = utils.flag(this, 'object');
14 * new chai.Assertion(obj).to.be.equal(str);
15 * return this;
16 * });
17 *
18 * Then can be used as any other assertion.
19 *
20 * expect(fooStr).to.be.foo('bar');
21 *
22 * @param {Function|Object} context chai.Assertion || chai.Assertion.prototype
23 * @param {String} name of method to add
24 * @param {Function} method function to used for name
25 * @api public
26 */
27
281module.exports = function (ctx, name, method) {
290 var context = ('function' === typeof ctx) ? ctx.prototype : ctx;
300 context[name] = function () {
310 method.apply(this, arguments);
320 return this;
33 };
34};

utils/overwriteProperty.js

16%
6
1
5
LineHitsSource
1/*!
2 * Chai - overwriteProperty utility
3 * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/**
8 * # overwriteProperty (ctx, name, fn)
9 *
10 * Overwites an already existing property getter and provides
11 * access to previous value. Must return function to use as getter.
12 *
13 * utils.overwriteProperty(chai.Assertion, 'ok', function (_super) {
14 * return function () {
15 * var obj = utils.flag(this, 'object');
16 * if (obj instanceof Foo) {
17 * new chai.Assertion(obj.name).to.equal('bar');
18 * return this;
19 * } else {
20 * return _super.call(this);
21 * }
22 * }
23 * });
24 *
25 * Then can be used as any other assertion.
26 *
27 * expect(myFoo).to.be.ok;
28 *
29 * @param {Function|Object} context chai.Assertion || chai.Assertion.prototype
30 * @param {String} name of property to overwrite
31 * @param {Function} method must return function to be used for name
32 * @api public
33 */
34
351module.exports = function (ctx, name, getter) {
360 var context = ('function' === typeof ctx) ? ctx.prototype : ctx
37 , _get = Object.getOwnPropertyDescriptor(context, name)
380 , _super = function () { return this; };
39
400 if (_get && 'function' === typeof _get.get)
410 _super = _get.get
42
430 Object.defineProperty(context, name,
44 { get: getter(_super)
45 , configurable: true
46 });
47};

utils/overwriteMethod.js

16%
6
1
5
LineHitsSource
1/*!
2 * Chai - overwriteMethod utility
3 * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
7/**
8 * # overwriteProperty (ctx, name, fn)
9 *
10 * Overwites an already existing method and provides
11 * access to previous function. Must return function
12 * to be used for name.
13 *
14 * utils.overwriteMethod(chai.Assertion, 'equal', function (_super) {
15 * return function (str) {
16 * var obj = utils.flag(this, 'object');
17 * if (obj instanceof Foo) {
18 * new chai.Assertion(obj.value).to.equal(str);
19 * return this;
20 * } else {
21 * return _super.apply(this, argument);
22 * }
23 * }
24 * });
25 *
26 * Then can be used as any other assertion.
27 *
28 * expect(myFoo).to.equal('bar');
29 *
30 * @param {Function|Object} context chai.Assertion || chai.Assertion.prototype
31 * @param {String} name of method to overwrite
32 * @param {Function} method function to be used for name
33 * @api public
34 */
35
361module.exports = function (ctx, name, method) {
370 var context = ('function' === typeof ctx) ? ctx.prototype : ctx
38 , _method = context[name]
390 , _super = function () { return this; };
40
410 if (_method && 'function' === typeof _method)
420 _super = _method;
43
440 context[name] = method(_super);
45};

interface/expect.js

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

interface/should.js

96%
26
25
1
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
4 * MIT Licensed
5 */
6
71module.exports = function (chai, util) {
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(){
15188 if (this instanceof String || this instanceof Number) {
161 return new Assertion(this.constructor(this));
17187 } else if (this instanceof Boolean) {
180 return new Assertion(this == true);
19 }
20187 return new Assertion(this);
21 },
22 configurable: true
23 });
24
251 var should = {};
26
271 should.equal = function (val1, val2) {
2876 new Assertion(val1).to.equal(val2);
29 };
30
311 should.Throw = function (fn, errt, errs) {
327 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) {
473 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 should['throw'] = should['Throw'];
551 should.not['throw'] = should.not['Throw'];
56
571 return should;
58 };
59};

interface/assert.js

98%
95
94
1
LineHitsSource
1/*!
2 * chai
3 * Copyright(c) 2011-2012 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, util) {
32
33 /*!
34 * Chai dependencies.
35 */
36
371 var Assertion = chai.Assertion
38 , flag = util.flag;
39
40 /*!
41 * Module export.
42 */
43
441 var assert = chai.assert = {};
45
46 /**
47 * # .fail(actual, expect, msg, operator)
48 *
49 * Throw a failure. Node.js compatible.
50 *
51 * @name fail
52 * @param {*} actual value
53 * @param {*} expected value
54 * @param {String} message
55 * @param {String} operator
56 * @api public
57 */
58
591 assert.fail = function (actual, expected, message, operator) {
601 throw new chai.AssertionError({
61 actual: actual
62 , expected: expected
63 , message: message
64 , operator: operator
65 , stackStartFunction: assert.fail
66 });
67 }
68
69 /**
70 * # .ok(object, [message])
71 *
72 * Assert object is truthy.
73 *
74 * assert.ok('everthing', 'everything is ok');
75 * assert.ok(false, 'this will fail');
76 *
77 * @name ok
78 * @param {*} object to test
79 * @param {String} message
80 * @api public
81 */
82
831 assert.ok = function (val, msg) {
846 new Assertion(val, msg).is.ok;
85 };
86
87 /**
88 * # .equal(actual, expected, [message])
89 *
90 * Assert strict equality.
91 *
92 * assert.equal(3, 3, 'these numbers are equal');
93 *
94 * @name equal
95 * @param {*} actual
96 * @param {*} expected
97 * @param {String} message
98 * @api public
99 */
100
1011 assert.equal = function (act, exp, msg) {
10252 var test = new Assertion(act, msg);
103
10452 test.assert(
105 exp == flag(test, 'object')
106 , 'expected #{this} to equal #{exp}'
107 , 'expected #{this} to not equal #{act}'
108 , exp
109 , act
110 );
111 };
112
113 /**
114 * # .notEqual(actual, expected, [message])
115 *
116 * Assert not equal.
117 *
118 * assert.notEqual(3, 4, 'these numbers are not equal');
119 *
120 * @name notEqual
121 * @param {*} actual
122 * @param {*} expected
123 * @param {String} message
124 * @api public
125 */
126
1271 assert.notEqual = function (act, exp, msg) {
1282 var test = new Assertion(act, msg);
129
1302 test.assert(
131 exp != flag(test, 'object')
132 , 'expected #{this} to not equal #{exp}'
133 , 'expected #{this} to equal #{act}'
134 , exp
135 , act
136 );
137 };
138
139 /**
140 * # .strictEqual(actual, expected, [message])
141 *
142 * Assert strict equality.
143 *
144 * assert.strictEqual(true, true, 'these booleans are strictly equal');
145 *
146 * @name strictEqual
147 * @param {*} actual
148 * @param {*} expected
149 * @param {String} message
150 * @api public
151 */
152
1531 assert.strictEqual = function (act, exp, msg) {
1542 new Assertion(act, msg).to.equal(exp);
155 };
156
157 /**
158 * # .notStrictEqual(actual, expected, [message])
159 *
160 * Assert strict equality.
161 *
162 * assert.notStrictEqual(1, true, 'these booleans are not strictly equal');
163 *
164 * @name notStrictEqual
165 * @param {*} actual
166 * @param {*} expected
167 * @param {String} message
168 * @api public
169 */
170
1711 assert.notStrictEqual = function (act, exp, msg) {
1722 new Assertion(act, msg).to.not.equal(exp);
173 };
174
175 /**
176 * # .deepEqual(actual, expected, [message])
177 *
178 * Assert not deep equality.
179 *
180 * assert.deepEqual({ tea: 'green' }, { tea: 'green' });
181 *
182 * @name deepEqual
183 * @param {*} actual
184 * @param {*} expected
185 * @param {String} message
186 * @api public
187 */
188
1891 assert.deepEqual = function (act, exp, msg) {
1902 new Assertion(act, msg).to.eql(exp);
191 };
192
193 /**
194 * # .notDeepEqual(actual, expected, [message])
195 *
196 * Assert not deep equality.
197 *
198 * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
199 *
200 * @name notDeepEqual
201 * @param {*} actual
202 * @param {*} expected
203 * @param {String} message
204 * @api public
205 */
206
2071 assert.notDeepEqual = function (act, exp, msg) {
2082 new Assertion(act, msg).to.not.eql(exp);
209 };
210
211 /**
212 * # .isTrue(value, [message])
213 *
214 * Assert `value` is true.
215 *
216 * var tea_served = true;
217 * assert.isTrue(tea_served, 'the tea has been served');
218 *
219 * @name isTrue
220 * @param {Boolean} value
221 * @param {String} message
222 * @api public
223 */
224
2251 assert.isTrue = function (val, msg) {
2264 new Assertion(val, msg).is['true'];
227 };
228
229 /**
230 * # .isFalse(value, [message])
231 *
232 * Assert `value` is false.
233 *
234 * var tea_served = false;
235 * assert.isFalse(tea_served, 'no tea yet? hmm...');
236 *
237 * @name isFalse
238 * @param {Boolean} value
239 * @param {String} message
240 * @api public
241 */
242
2431 assert.isFalse = function (val, msg) {
2443 new Assertion(val, msg).is['false'];
245 };
246
247 /**
248 * # .isNull(value, [message])
249 *
250 * Assert `value` is null.
251 *
252 * assert.isNull(err, 'no errors');
253 *
254 * @name isNull
255 * @param {*} value
256 * @param {String} message
257 * @api public
258 */
259
2601 assert.isNull = function (val, msg) {
2612 new Assertion(val, msg).to.equal(null);
262 };
263
264 /**
265 * # .isNotNull(value, [message])
266 *
267 * Assert `value` is not null.
268 *
269 * var tea = 'tasty chai';
270 * assert.isNotNull(tea, 'great, time for tea!');
271 *
272 * @name isNotNull
273 * @param {*} value
274 * @param {String} message
275 * @api public
276 */
277
2781 assert.isNotNull = function (val, msg) {
2792 new Assertion(val, msg).to.not.equal(null);
280 };
281
282 /**
283 * # .isUndefined(value, [message])
284 *
285 * Assert `value` is undefined.
286 *
287 * assert.isUndefined(tea, 'no tea defined');
288 *
289 * @name isUndefined
290 * @param {*} value
291 * @param {String} message
292 * @api public
293 */
294
2951 assert.isUndefined = function (val, msg) {
2962 new Assertion(val, msg).to.equal(undefined);
297 };
298
299 /**
300 * # .isDefined(value, [message])
301 *
302 * Assert `value` is not undefined.
303 *
304 * var tea = 'cup of chai';
305 * assert.isDefined(tea, 'no tea defined');
306 *
307 * @name isUndefined
308 * @param {*} value
309 * @param {String} message
310 * @api public
311 */
312
3131 assert.isDefined = function (val, msg) {
3142 new Assertion(val, msg).to.not.equal(undefined);
315 };
316
317 /**
318 * # .isFunction(value, [message])
319 *
320 * Assert `value` is a function.
321 *
322 * var serve_tea = function () { return 'cup of tea'; };
323 * assert.isFunction(serve_tea, 'great, we can have tea now');
324 *
325 * @name isFunction
326 * @param {Function} value
327 * @param {String} message
328 * @api public
329 */
330
3311 assert.isFunction = function (val, msg) {
3322 new Assertion(val, msg).to.be.a('function');
333 };
334
335 /**
336 * # .isNotFunction(value, [message])
337 *
338 * Assert `value` is NOT a function.
339 *
340 * var serve_tea = [ 'heat', 'pour', 'sip' ];
341 * assert.isNotFunction(serve_tea, 'great, we can have tea now');
342 *
343 * @name isNotFunction
344 * @param {Mixed} value
345 * @param {String} message
346 * @api public
347 */
348
3491 assert.isNotFunction = function (val, msg) {
3502 new Assertion(val, msg).to.not.be.a('function');
351 };
352
353 /**
354 * # .isObject(value, [message])
355 *
356 * Assert `value` is an object.
357 *
358 * var selection = { name: 'Chai', serve: 'with spices' };
359 * assert.isObject(selection, 'tea selection is an object');
360 *
361 * @name isObject
362 * @param {Object} value
363 * @param {String} message
364 * @api public
365 */
366
3671 assert.isObject = function (val, msg) {
3685 new Assertion(val, msg).to.be.a('object');
369 };
370
371 /**
372 * # .isNotObject(value, [message])
373 *
374 * Assert `value` is NOT an object.
375 *
376 * var selection = 'chai'
377 * assert.isObject(selection, 'tea selection is not an object');
378 *
379 * @name isNotObject
380 * @param {Mixed} value
381 * @param {String} message
382 * @api public
383 */
384
3851 assert.isNotObject = function (val, msg) {
3862 new Assertion(val, msg).to.not.be.a('object');
387 };
388
389 /**
390 * # .isArray(value, [message])
391 *
392 * Assert `value` is an instance of Array.
393 *
394 * var menu = [ 'green', 'chai', 'oolong' ];
395 * assert.isArray(menu, 'what kind of tea do we want?');
396 *
397 * @name isArray
398 * @param {Mixed} value
399 * @param {String} message
400 * @api public
401 */
402
4031 assert.isArray = function (val, msg) {
4043 new Assertion(val, msg).to.be.instanceOf(Array);
405 };
406
407 /**
408 * # .isArray(value, [message])
409 *
410 * Assert `value` is NOT an instance of Array.
411 *
412 * var menu = 'green|chai|oolong';
413 * assert.isNotArray(menu, 'what kind of tea do we want?');
414 *
415 * @name isNotArray
416 * @param {Mixed} value
417 * @param {String} message
418 * @api public
419 */
420
4211 assert.isNotArray = function (val, msg) {
4223 new Assertion(val, msg).to.not.be.instanceOf(Array);
423 };
424
425 /**
426 * # .isString(value, [message])
427 *
428 * Assert `value` is a string.
429 *
430 * var teaorder = 'chai';
431 * assert.isString(tea_order, 'order placed');
432 *
433 * @name isString
434 * @param {String} value
435 * @param {String} message
436 * @api public
437 */
438
4391 assert.isString = function (val, msg) {
4403 new Assertion(val, msg).to.be.a('string');
441 };
442
443 /**
444 * # .isNotString(value, [message])
445 *
446 * Assert `value` is NOT a string.
447 *
448 * var teaorder = 4;
449 * assert.isNotString(tea_order, 'order placed');
450 *
451 * @name isNotString
452 * @param {Mixed} value
453 * @param {String} message
454 * @api public
455 */
456
4571 assert.isNotString = function (val, msg) {
4583 new Assertion(val, msg).to.not.be.a('string');
459 };
460
461 /**
462 * # .isNumber(value, [message])
463 *
464 * Assert `value` is a number
465 *
466 * var cups = 2;
467 * assert.isNumber(cups, 'how many cups');
468 *
469 * @name isNumber
470 * @param {Number} value
471 * @param {String} message
472 * @api public
473 */
474
4751 assert.isNumber = function (val, msg) {
4763 new Assertion(val, msg).to.be.a('number');
477 };
478
479 /**
480 * # .isNotNumber(value, [message])
481 *
482 * Assert `value` NOT is a number
483 *
484 * var cups = '2 cups please';
485 * assert.isNotNumber(cups, 'how many cups');
486 *
487 * @name isNotNumber
488 * @param {Mixed} value
489 * @param {String} message
490 * @api public
491 */
492
4931 assert.isNotNumber = function (val, msg) {
4943 new Assertion(val, msg).to.not.be.a('number');
495 };
496
497 /**
498 * # .isBoolean(value, [message])
499 *
500 * Assert `value` is a boolean
501 *
502 * var teaready = true
503 * , teaserved = false;
504 *
505 * assert.isBoolean(tea_ready, 'is the tea ready');
506 * assert.isBoolean(tea_served, 'has tea been served');
507 *
508 * @name isBoolean
509 * @param {Mixed} value
510 * @param {String} message
511 * @api public
512 */
513
5141 assert.isBoolean = function (val, msg) {
5153 new Assertion(val, msg).to.be.a('boolean');
516 };
517
518 /**
519 * # .isNotBoolean(value, [message])
520 *
521 * Assert `value` is NOT a boolean
522 *
523 * var teaready = 'yep'
524 * , teaserved = 'nope';
525 *
526 * assert.isNotBoolean(tea_ready, 'is the tea ready');
527 * assert.isNotBoolean(tea_served, 'has tea been served');
528 *
529 * @name isNotBoolean
530 * @param {Mixed} value
531 * @param {String} message
532 * @api public
533 */
534
5351 assert.isNotBoolean = function (val, msg) {
5363 new Assertion(val, msg).to.not.be.a('boolean');
537 };
538
539 /**
540 * # .typeOf(value, name, [message])
541 *
542 * Assert typeof `value` is `name`.
543 *
544 * assert.typeOf('tea', 'string', 'we have a string');
545 *
546 * @name typeOf
547 * @param {Mixed} value
548 * @param {String} typeof name
549 * @param {String} message
550 * @api public
551 */
552
5531 assert.typeOf = function (val, type, msg) {
5544 new Assertion(val, msg).to.be.a(type);
555 };
556
557 /**
558 * # .notTypeOf(value, name, [message])
559 *
560 * Assert typeof `value` is NOT `name`.
561 *
562 * assert.notTypeOf('tea', 'string', 'we have a string');
563 *
564 * @name notTypeOf
565 * @param {Mixed} value
566 * @param {String} typeof name
567 * @param {String} message
568 * @api public
569 */
570
5711 assert.notTypeOf = function (val, type, msg) {
5722 new Assertion(val, msg).to.not.be.a(type);
573 };
574
575 /**
576 * # .instanceOf(object, constructor, [message])
577 *
578 * Assert `value` is instanceof `constructor`.
579 *
580 * var Tea = function (name) { this.name = name; }
581 * , Chai = new Tea('chai');
582 *
583 * assert.instanceOf(Chai, Tea, 'chai is an instance of tea');
584 *
585 * @name instanceOf
586 * @param {Object} object
587 * @param {Constructor} constructor
588 * @param {String} message
589 * @api public
590 */
591
5921 assert.instanceOf = function (val, type, msg) {
5932 new Assertion(val, msg).to.be.instanceOf(type);
594 };
595
596 /**
597 * # .notInstanceOf(object, constructor, [message])
598 *
599 * Assert `value` is NOT instanceof `constructor`.
600 *
601 * var Tea = function (name) { this.name = name; }
602 * , Chai = new String('chai');
603 *
604 * assert.notInstanceOf(Chai, Tea, 'chai is an instance of tea');
605 *
606 * @name notInstanceOf
607 * @param {Object} object
608 * @param {Constructor} constructor
609 * @param {String} message
610 * @api public
611 */
612
6131 assert.notInstanceOf = function (val, type, msg) {
6142 new Assertion(val, msg).to.not.be.instanceOf(type);
615 };
616
617 /**
618 * # .include(value, includes, [message])
619 *
620 * Assert the inclusion of an object in another. Works
621 * for strings and arrays.
622 *
623 * assert.include('foobar', 'bar', 'foobar contains string `var`);
624 * assert.include([ 1, 2, 3], 3, 'array contains value);
625 *
626 * @name include
627 * @param {Array|String} value
628 * @param {*} includes
629 * @param {String} message
630 * @api public
631 */
632
6331 assert.include = function (exp, inc, msg) {
6343 var obj = new Assertion(exp, msg);
635
6363 if (Array.isArray(exp)) {
6371 obj.to.include(inc);
6382 } else if ('string' === typeof exp) {
6392 obj.to.contain.string(inc);
640 }
641 };
642
643 /**
644 * # .match(value, regex, [message])
645 *
646 * Assert that `value` matches regular expression.
647 *
648 * assert.match('foobar', /^foo/, 'Regexp matches');
649 *
650 * @name match
651 * @param {*} value
652 * @param {RegExp} RegularExpression
653 * @param {String} message
654 * @api public
655 */
656
6571 assert.match = function (exp, re, msg) {
6580 new Assertion(exp, msg).to.match(re);
659 };
660
661 /**
662 * # .length(object, length, [message])
663 *
664 * Assert that object has expected length.
665 *
666 * assert.length([1,2,3], 3, 'Array has length of 3');
667 * assert.length('foobar', 5, 'String has length of 6');
668 *
669 * @name length
670 * @param {*} value
671 * @param {Number} length
672 * @param {String} message
673 * @api public
674 */
675
6761 assert.length = function (exp, len, msg) {
6774 new Assertion(exp, msg).to.have.length(len);
678 };
679
680 /**
681 * # .throws(function, [constructor/regexp], [message])
682 *
683 * Assert that a function will throw a specific
684 * type of error.
685 *
686 * assert.throw(fn, ReferenceError, 'function throw reference error');
687 *
688 * @name throws
689 * @alias throw
690 * @param {Function} function to test
691 * @param {ErrorConstructor} constructor
692 * @param {String} message
693 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
694 * @api public
695 */
696
6971 assert.throws = function (fn, type, msg) {
6983 if ('string' === typeof type) {
6991 msg = type;
7001 type = null;
701 }
702
7033 new Assertion(fn, msg).to.Throw(type);
704 };
705
706 /**
707 * # .doesNotThrow(function, [constructor/regexp], [message])
708 *
709 * Assert that a function will throw a specific
710 * type of error.
711 *
712 * var fn = function (err) { if (err) throw Error(err) };
713 * assert.doesNotThrow(fn, Error, 'function throw reference error');
714 *
715 * @name doesNotThrow
716 * @param {Function} function to test
717 * @param {ErrorConstructor} constructor
718 * @param {String} message
719 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
720 * @api public
721 */
722
7231 assert.doesNotThrow = function (fn, type, msg) {
7243 if ('string' === typeof type) {
7251 msg = type;
7261 type = null;
727 }
728
7293 new Assertion(fn, msg).to.not.Throw(type);
730 };
731
732 /**
733 * # .operator(val, operator, val2, [message])
734 *
735 * Compare two values using operator.
736 *
737 * assert.operator(1, '<', 2, 'everything is ok');
738 * assert.operator(1, '>', 2, 'this will fail');
739 *
740 * @name operator
741 * @param {*} object to test
742 * @param {String} operator
743 * @param {*} second object
744 * @param {String} message
745 * @api public
746 */
747
7481 assert.operator = function (val, operator, val2, msg) {
74915 if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
7501 throw new Error('Invalid operator "' + operator + '"');
751 }
75214 var test = new Assertion(eval(val + operator + val2), msg);
75314 test.assert(
754 true === flag(test, 'object')
755 , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
756 , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );
757 };
758
759 /*!
760 * Undocumented / untested
761 */
762
7631 assert.ifError = function (val, msg) {
7644 new Assertion(val, msg).to.not.be.ok;
765 };
766
767 /*!
768 * Aliases.
769 */
770
7711 (function alias(name, as){
7722 assert[as] = assert[name];
7732 return alias;
774 })
775 ('length', 'lengthOf')
776 ('throws', 'throw');
777};