Line | Hits | Source |
---|---|---|
1 | /*! | |
2 | * chai | |
3 | * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> | |
4 | * MIT Licensed | |
5 | */ | |
6 | ||
7 | 1 | var used = [] |
8 | , exports = module.exports = {}; | |
9 | ||
10 | /*! | |
11 | * Chai version | |
12 | */ | |
13 | ||
14 | 1 | exports.version = '1.0.0alpha1'; |
15 | ||
16 | /*! | |
17 | * Primary `Assertion` prototype | |
18 | */ | |
19 | ||
20 | 1 | exports.Assertion = require('./assertion'); |
21 | ||
22 | /*! | |
23 | * Assertion Error | |
24 | */ | |
25 | ||
26 | 1 | exports.AssertionError = require('./error'); |
27 | ||
28 | /*! | |
29 | * Utils for plugins (not exported) | |
30 | */ | |
31 | ||
32 | 1 | var 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 | ||
44 | 1 | exports.use = function (fn) { |
45 | 6 | if (!~used.indexOf(fn)) { |
46 | 5 | fn(this, util); |
47 | 5 | used.push(fn); |
48 | } | |
49 | ||
50 | 6 | return this; |
51 | }; | |
52 | ||
53 | /*! | |
54 | * Expect interface | |
55 | */ | |
56 | ||
57 | 1 | var expect = require('./interface/expect'); |
58 | 1 | exports.use(expect); |
59 | ||
60 | /*! | |
61 | * Should interface | |
62 | */ | |
63 | ||
64 | 1 | var should = require('./interface/should'); |
65 | 1 | exports.use(should); |
66 | ||
67 | /*! | |
68 | * Assert interface | |
69 | */ | |
70 | ||
71 | 1 | var assert = require('./interface/assert'); |
72 | 1 | exports.use(assert); |
Line | Hits | Source |
---|---|---|
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 | ||
48 | 1 | var AssertionError = require('./error') |
49 | , toString = Object.prototype.toString | |
50 | , util = require('./utils') | |
51 | , flag = util.flag; | |
52 | ||
53 | /*! | |
54 | * Module export. | |
55 | */ | |
56 | ||
57 | 1 | module.exports = Assertion; |
58 | ||
59 | ||
60 | /*! | |
61 | * # Assertion Constructor | |
62 | * | |
63 | * Creates object for chaining. | |
64 | * | |
65 | * @api private | |
66 | */ | |
67 | ||
68 | 1 | function Assertion (obj, msg, stack) { |
69 | 841 | flag(this, 'ssfi', stack || arguments.callee); |
70 | 841 | flag(this, 'object', obj); |
71 | 841 | 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 | ||
86 | 1 | Assertion.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 | ||
102 | 1 | Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual) { |
103 | 847 | var msg = util.getMessage(this, arguments) |
104 | , actual = util.getActual(this, arguments) | |
105 | , ok = util.test(this, arguments); | |
106 | ||
107 | 847 | if (!ok) { |
108 | 187 | 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 | ||
126 | 1 | Object.defineProperty(Assertion.prototype, 'to', |
127 | { get: function () { | |
128 | 460 | return this; |
129 | } | |
130 | , configurable: true | |
131 | }); | |
132 | ||
133 | /** | |
134 | * # be | |
135 | * | |
136 | * Language chain. | |
137 | * | |
138 | * @name be | |
139 | * @api public | |
140 | */ | |
141 | ||
142 | 1 | Object.defineProperty(Assertion.prototype, 'be', |
143 | { get: function () { | |
144 | 183 | 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 | ||
159 | 1 | Object.defineProperty(Assertion.prototype, 'been', |
160 | { get: function () { | |
161 | 1 | flag(this, 'tense', 'past'); |
162 | 1 | 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 | ||
181 | 1 | var an = function () { |
182 | 178 | var assert = function(type) { |
183 | 174 | var obj = flag(this, 'object') |
184 | , klass = type.charAt(0).toUpperCase() + type.slice(1); | |
185 | ||
186 | 174 | 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 | ||
194 | 153 | return this; |
195 | }; | |
196 | ||
197 | 178 | assert.__proto__ = this; |
198 | 178 | return assert; |
199 | }; | |
200 | ||
201 | 1 | Object.defineProperty(Assertion.prototype, 'an', |
202 | { get: an | |
203 | , configurable: true | |
204 | }); | |
205 | ||
206 | 1 | Object.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 | */ | |
224 | 1 | var include = function () { |
225 | 53 | flag(this, 'contains', true); |
226 | ||
227 | 53 | var assert = function(val) { |
228 | 17 | var obj = flag(this, 'object') |
229 | 17 | this.assert( |
230 | ~obj.indexOf(val) | |
231 | , 'expected #{this} to include ' + util.inspect(val) | |
232 | , 'expected #{this} to not include ' + util.inspect(val)); | |
233 | ||
234 | 13 | return this; |
235 | }; | |
236 | ||
237 | 53 | assert.__proto__ = this; |
238 | 53 | return assert; |
239 | }; | |
240 | ||
241 | 1 | Object.defineProperty(Assertion.prototype, 'contain', |
242 | { get: include | |
243 | , configurable: true | |
244 | }); | |
245 | ||
246 | 1 | Object.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 | ||
261 | 1 | Object.defineProperty(Assertion.prototype, 'is', |
262 | { get: function () { | |
263 | 124 | return this; |
264 | } | |
265 | , configurable: true | |
266 | }); | |
267 | ||
268 | /** | |
269 | * # and | |
270 | * | |
271 | * Language chain. | |
272 | * | |
273 | * @name and | |
274 | * @api public | |
275 | */ | |
276 | ||
277 | 1 | Object.defineProperty(Assertion.prototype, 'and', |
278 | { get: function () { | |
279 | 1 | return this; |
280 | } | |
281 | , configurable: true | |
282 | }); | |
283 | ||
284 | /** | |
285 | * # have | |
286 | * | |
287 | * Language chain. | |
288 | * | |
289 | * @name have | |
290 | * @api public | |
291 | */ | |
292 | ||
293 | 1 | Object.defineProperty(Assertion.prototype, 'have', |
294 | { get: function () { | |
295 | 93 | return this; |
296 | } | |
297 | , configurable: true | |
298 | }); | |
299 | ||
300 | /** | |
301 | * # with | |
302 | * | |
303 | * Language chain. | |
304 | * | |
305 | * @name with | |
306 | * @api public | |
307 | */ | |
308 | ||
309 | 1 | Object.defineProperty(Assertion.prototype, 'with', |
310 | { get: function () { | |
311 | 2 | 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 | ||
325 | 1 | Object.defineProperty(Assertion.prototype, 'not', |
326 | { get: function () { | |
327 | 176 | flag(this, 'negate', true); |
328 | 176 | 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 | ||
347 | 1 | Object.defineProperty(Assertion.prototype, 'ok', |
348 | { get: function () { | |
349 | 22 | this.assert( |
350 | flag(this, 'object') | |
351 | , 'expected #{this} to be truthy' | |
352 | , 'expected #{this} to be falsy'); | |
353 | ||
354 | 14 | 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 | ||
368 | 1 | Object.defineProperty(Assertion.prototype, 'true', |
369 | { get: function () { | |
370 | 12 | 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 | ||
377 | 7 | 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 | ||
391 | 1 | Object.defineProperty(Assertion.prototype, 'false', |
392 | { get: function () { | |
393 | 12 | 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 | ||
400 | 8 | 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 | ||
419 | 1 | Object.defineProperty(Assertion.prototype, 'exist', |
420 | { get: function () { | |
421 | 6 | this.assert( |
422 | null != flag(this, 'object') | |
423 | , 'expected #{this} to exist' | |
424 | , 'expected #{this} to not exist' | |
425 | ); | |
426 | ||
427 | 4 | 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 | ||
443 | 1 | Object.defineProperty(Assertion.prototype, 'empty', |
444 | { get: function () { | |
445 | 32 | var obj = flag(this, 'object') |
446 | , expected = obj; | |
447 | ||
448 | 32 | if (Array.isArray(obj)) { |
449 | 8 | expected = obj.length; |
450 | 24 | } else if (typeof obj === 'object') { |
451 | 16 | expected = Object.keys(obj).length; |
452 | } | |
453 | ||
454 | 32 | this.assert( |
455 | !expected | |
456 | , 'expected #{this} to be empty' | |
457 | , 'expected #{this} not to be empty'); | |
458 | ||
459 | 16 | 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 | ||
477 | 1 | Object.defineProperty(Assertion.prototype, 'arguments', |
478 | { get: function () { | |
479 | 4 | var obj = flag(this, 'object'); |
480 | 4 | 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 | ||
488 | 4 | 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 | ||
505 | 1 | Assertion.prototype.equal = function (val) { |
506 | 177 | this.assert( |
507 | val === flag(this, 'object') | |
508 | , 'expected #{this} to equal #{exp}' | |
509 | , 'expected #{this} to not equal #{exp}' | |
510 | , val ); | |
511 | ||
512 | 167 | 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 | ||
527 | 1 | Assertion.prototype.eql = function (obj) { |
528 | 14 | 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 | ||
534 | 10 | 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 | ||
550 | 1 | Assertion.prototype.above = function (val) { |
551 | 12 | this.assert( |
552 | flag(this, 'object') > val | |
553 | , 'expected #{this} to be above ' + val | |
554 | , 'expected #{this} to be below ' + val); | |
555 | ||
556 | 8 | 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 | ||
572 | 1 | Assertion.prototype.below = function (val) { |
573 | 12 | this.assert( |
574 | flag(this, 'object') < val | |
575 | , 'expected #{this} to be below ' + val | |
576 | , 'expected #{this} to be above ' + val); | |
577 | ||
578 | 8 | 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 | ||
594 | 1 | Assertion.prototype.within = function (start, finish) { |
595 | 12 | var obj = flag(this, 'object') |
596 | , range = start + '..' + finish; | |
597 | ||
598 | 12 | this.assert( |
599 | obj >= start && obj <= finish | |
600 | , 'expected #{this} to be within ' + range | |
601 | , 'expected #{this} to not be within ' + range); | |
602 | ||
603 | 8 | 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 | ||
622 | 1 | Assertion.prototype.instanceOf = function (constructor) { |
623 | 14 | var name = util.getName(constructor); |
624 | 14 | 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 | ||
629 | 7 | 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 | ||
649 | 1 | Assertion.prototype.property = function (name, val) { |
650 | 38 | var obj = flag(this, 'object') |
651 | , value = util.getPathValue(name, obj) | |
652 | , negate = flag(this, 'negate'); | |
653 | ||
654 | 38 | if (negate && undefined !== val) { |
655 | 4 | if (undefined === value) { |
656 | 2 | throw new Error(util.inspect(obj) + ' has no property ' + util.inspect(name)); |
657 | } | |
658 | } else { | |
659 | 34 | 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 | ||
665 | 31 | if (undefined !== val) { |
666 | 11 | 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 | ||
675 | 25 | flag(this, 'object', value); |
676 | 25 | 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 | ||
692 | 1 | Assertion.prototype.ownProperty = function (name) { |
693 | 8 | var obj = flag(this, 'object'); |
694 | 8 | 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)); | |
698 | 6 | 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 | ||
715 | 1 | Assertion.prototype.length = function (n) { |
716 | 16 | var obj = flag(this, 'object'); |
717 | 16 | new Assertion(obj).to.have.property('length'); |
718 | 13 | var len = obj.length; |
719 | ||
720 | 13 | 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 | ||
728 | 9 | 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 | ||
743 | 1 | Assertion.prototype.match = function (re) { |
744 | 8 | var obj = flag(this, 'object'); |
745 | 8 | this.assert( |
746 | re.exec(obj) | |
747 | , 'expected #{this} to match ' + re | |
748 | , 'expected #{this} not to match ' + re); | |
749 | ||
750 | 4 | 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 | ||
766 | 1 | Assertion.prototype.string = function (str) { |
767 | 14 | var obj = flag(this, 'object'); |
768 | 14 | new Assertion(obj).is.a('string'); |
769 | ||
770 | 12 | this.assert( |
771 | ~obj.indexOf(str) | |
772 | , 'expected #{this} to contain ' + util.inspect(str) | |
773 | , 'expected #{this} to not contain ' + util.inspect(str)); | |
774 | ||
775 | 7 | 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 | ||
792 | 1 | Assertion.prototype.keys = function(keys) { |
793 | 56 | var obj = flag(this, 'object') |
794 | , str | |
795 | , ok = true; | |
796 | ||
797 | 56 | keys = keys instanceof Array |
798 | ? keys | |
799 | : Array.prototype.slice.call(arguments); | |
800 | ||
801 | 64 | if (!keys.length) throw new Error('keys required'); |
802 | ||
803 | 48 | var actual = Object.keys(obj) |
804 | , len = keys.length; | |
805 | ||
806 | // Inclusion | |
807 | 48 | ok = keys.every(function(key){ |
808 | 70 | return ~actual.indexOf(key); |
809 | }); | |
810 | ||
811 | // Strict | |
812 | 48 | if (!flag(this, 'negate') && !flag(this, 'contains')) { |
813 | 12 | ok = ok && keys.length == actual.length; |
814 | } | |
815 | ||
816 | // Key string | |
817 | 48 | if (len > 1) { |
818 | 26 | keys = keys.map(function(key){ |
819 | 54 | return util.inspect(key); |
820 | }); | |
821 | 26 | var last = keys.pop(); |
822 | 26 | str = keys.join(', ') + ', and ' + last; |
823 | } else { | |
824 | 22 | str = util.inspect(keys[0]); |
825 | } | |
826 | ||
827 | // Form | |
828 | 48 | str = (len > 1 ? 'keys ' : 'key ') + str; |
829 | ||
830 | // Have / include | |
831 | 48 | str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; |
832 | ||
833 | // Assertion | |
834 | 48 | this.assert( |
835 | ok | |
836 | , 'expected #{this} to ' + str | |
837 | , 'expected #{this} to not ' + str | |
838 | , keys | |
839 | , Object.keys(obj) | |
840 | ); | |
841 | ||
842 | 32 | 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 | ||
877 | 1 | Assertion.prototype.Throw = function (constructor, msg) { |
878 | 97 | var obj = flag(this, 'object'); |
879 | 97 | new Assertion(obj).is.a('function'); |
880 | ||
881 | 97 | var thrown = false |
882 | , desiredError = null | |
883 | , name = null; | |
884 | ||
885 | 97 | if (arguments.length === 0) { |
886 | 13 | msg = null; |
887 | 13 | constructor = null; |
888 | 84 | } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) { |
889 | 11 | msg = constructor; |
890 | 11 | constructor = null; |
891 | 73 | } else if (constructor && constructor instanceof Error) { |
892 | 20 | desiredError = constructor; |
893 | 20 | constructor = null; |
894 | 20 | msg = null; |
895 | 53 | } else if (typeof constructor === 'function') { |
896 | 45 | name = (new constructor()).name; |
897 | } else { | |
898 | 8 | constructor = null; |
899 | } | |
900 | ||
901 | 97 | try { |
902 | 97 | obj(); |
903 | } catch (err) { | |
904 | // first, check desired error | |
905 | 80 | if (desiredError) { |
906 | 16 | 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 | ); | |
911 | 10 | return this; |
912 | } | |
913 | // next, check constructor | |
914 | 64 | if (constructor) { |
915 | 41 | 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 ); | |
919 | 48 | if (!msg) return this; |
920 | } | |
921 | // next, check message | |
922 | 33 | if (err.message && msg && msg instanceof RegExp) { |
923 | 13 | 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 | ); | |
928 | 7 | return this; |
929 | 20 | } else if (err.message && msg && 'string' === typeof msg) { |
930 | 8 | 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 | ); | |
937 | 6 | return this; |
938 | } else { | |
939 | 12 | thrown = true; |
940 | } | |
941 | } | |
942 | ||
943 | 29 | var expectedThrown = name ? name : desiredError ? util.inspect(desiredError) : 'an error'; |
944 | ||
945 | 29 | this.assert( |
946 | thrown === true | |
947 | , 'expected #{this} to throw ' + expectedThrown | |
948 | , 'expected #{this} to not throw ' + expectedThrown); | |
949 | ||
950 | 19 | 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 | ||
966 | 1 | Assertion.prototype.respondTo = function (method) { |
967 | 10 | var obj = flag(this, 'object') |
968 | , context = ('function' === typeof obj) | |
969 | ? obj.prototype[method] | |
970 | : obj[method]; | |
971 | ||
972 | 10 | 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 | ||
980 | 6 | 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 | ||
995 | 1 | Assertion.prototype.satisfy = function (matcher) { |
996 | 4 | var obj = flag(this, 'object'); |
997 | 4 | 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 | ||
1005 | 2 | 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 | ||
1021 | 1 | Assertion.prototype.closeTo = function (expected, delta) { |
1022 | 4 | var obj = flag(this, 'object'); |
1023 | 4 | 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 | ||
1028 | 2 | return this; |
1029 | }; | |
1030 | ||
1031 | /*! | |
1032 | * Aliases. | |
1033 | */ | |
1034 | ||
1035 | 1 | (function alias(name, as){ |
1036 | 11 | Assertion.prototype[as] = Assertion.prototype[name]; |
1037 | 11 | 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'); |
Line | Hits | Source |
---|---|---|
1 | /*! | |
2 | * chai | |
3 | * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> | |
4 | * MIT Licensed | |
5 | */ | |
6 | ||
7 | /*! | |
8 | * Module dependancies | |
9 | */ | |
10 | ||
11 | 1 | var fs = require('fs'); |
12 | ||
13 | /*! | |
14 | * Main export | |
15 | */ | |
16 | ||
17 | 1 | module.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 | ||
36 | 1 | function AssertionError (options) { |
37 | 189 | options = options || {}; |
38 | 189 | this.message = options.message; |
39 | 189 | this.actual = options.actual; |
40 | 189 | this.expected = options.expected; |
41 | 189 | this.operator = options.operator; |
42 | ||
43 | 189 | if (options.stackStartFunction && Error.captureStackTrace) { |
44 | // We need the raw stack so we can make a JSON | |
45 | // object for writing to the logs. | |
46 | 188 | var stackStartFunction = options.stackStartFunction |
47 | , orig = Error.prepareStackTrace; | |
48 | ||
49 | // Custom stack track | |
50 | 376 | Error.prepareStackTrace = function(_, stack){ return stack; }; |
51 | 188 | Error.captureStackTrace(this, stackStartFunction); |
52 | 188 | this.__stack = this.stack; |
53 | ||
54 | // return original | |
55 | 188 | Error.prepareStackTrace = orig; |
56 | ||
57 | 188 | 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 | |
62 | 0 | if (this.__stack[1]) { |
63 | 0 | var filename = this.__stack[1].getFileName() |
64 | , lineno = this.__stack[1].getLineNumber() | |
65 | , line = fs.readFileSync(filename, 'utf8').split('\n')[lineno - 1].trim(); | |
66 | 0 | return this.message + '\n[' + lineno + '] ' + filename + '\n' + line; |
67 | ||
68 | // Else, just return the message. | |
69 | } else { | |
70 | 0 | return this.message; |
71 | } | |
72 | } | |
73 | } | |
74 | ); | |
75 | } | |
76 | } | |
77 | ||
78 | /*! | |
79 | * Inherit from Error | |
80 | */ | |
81 | ||
82 | 1 | AssertionError.prototype = Object.create(Error.prototype); |
83 | 1 | AssertionError.prototype.name = 'AssertionError'; |
84 | 1 | AssertionError.prototype.constructor = AssertionError; |
85 | ||
86 | /** | |
87 | * # toString() | |
88 | * | |
89 | * Override default to string method | |
90 | */ | |
91 | ||
92 | 1 | AssertionError.prototype.toString = function() { |
93 | 0 | return this.message; |
94 | }; |
Line | Hits | Source |
---|---|---|
1 | /*! | |
2 | * chai | |
3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
4 | * MIT Licensed | |
5 | */ | |
6 | ||
7 | /*! | |
8 | * Main exports | |
9 | */ | |
10 | ||
11 | 1 | var exports = module.exports = {}; |
12 | ||
13 | /*! | |
14 | * test utility | |
15 | */ | |
16 | ||
17 | 1 | exports.test = require('./test'); |
18 | ||
19 | /*! | |
20 | * message utility | |
21 | */ | |
22 | ||
23 | 1 | exports.getMessage = require('./getMessage'); |
24 | ||
25 | /*! | |
26 | * actual utility | |
27 | */ | |
28 | ||
29 | 1 | exports.getActual = require('./getActual'); |
30 | ||
31 | /*! | |
32 | * Inspect util | |
33 | */ | |
34 | ||
35 | 1 | exports.inspect = require('./inspect'); |
36 | ||
37 | /*! | |
38 | * Flag utility | |
39 | */ | |
40 | ||
41 | 1 | exports.flag = require('./flag'); |
42 | ||
43 | /*! | |
44 | * Deep equal utility | |
45 | */ | |
46 | ||
47 | 1 | exports.eql = require('./eql'); |
48 | ||
49 | /*! | |
50 | * Deep path value | |
51 | */ | |
52 | ||
53 | 1 | exports.getPathValue = require('./getPathValue'); |
54 | ||
55 | /*! | |
56 | * Function name | |
57 | */ | |
58 | ||
59 | 1 | exports.getName = require('./getName'); |
60 | ||
61 | /*! | |
62 | * add Property | |
63 | */ | |
64 | ||
65 | 1 | exports.addProperty = require('./addProperty'); |
66 | ||
67 | /*! | |
68 | * add Method | |
69 | */ | |
70 | ||
71 | 1 | exports.addMethod = require('./addMethod'); |
72 | ||
73 | /*! | |
74 | * overwrite Property | |
75 | */ | |
76 | ||
77 | 1 | exports.overwriteProperty = require('./overwriteProperty'); |
78 | ||
79 | /*! | |
80 | * overwrite Method | |
81 | */ | |
82 | ||
83 | 1 | exports.overwriteMethod = require('./overwriteMethod'); |
Line | Hits | Source |
---|---|---|
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 | ||
11 | 1 | var 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 | ||
22 | 1 | module.exports = function (obj, args) { |
23 | 847 | var negate = flag(obj, 'negate') |
24 | , expr = args[0]; | |
25 | 847 | return negate ? !expr : expr; |
26 | }; |
Line | Hits | Source |
---|---|---|
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 | ||
21 | 1 | module.exports = function (obj, key, value) { |
22 | 6513 | var flags = obj.__flags || (obj.__flags = Object.create(null)); |
23 | 6513 | if (arguments.length === 3) { |
24 | 2778 | flags[key] = value; |
25 | } else { | |
26 | 3735 | return flags[key]; |
27 | } | |
28 | }; |
Line | Hits | Source |
---|---|---|
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 | ||
11 | 1 | var 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 | ||
31 | 1 | module.exports = function (obj, args) { |
32 | 847 | 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 | ||
38 | 847 | msg = msg |
39 | .replace(/#{this}/g, inspect(val)) | |
40 | .replace(/#{act}/g, inspect(actual)) | |
41 | .replace(/#{exp}/g, inspect(expected)); | |
42 | ||
43 | 847 | return obj.msg ? obj.msg + ': ' + msg : msg; |
44 | }; |
Line | Hits | Source |
---|---|---|
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 | ||
16 | 1 | module.exports = function (obj, args) { |
17 | 1694 | var actual = args[4]; |
18 | 1694 | return 'undefined' !== actual ? actual : obj.obj; |
19 | }; |
Line | Hits | Source |
---|---|---|
1 | // This is (almost) directly from Node.js utils | |
2 | // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js | |
3 | ||
4 | 1 | var getName = require('./getName'); |
5 | ||
6 | 1 | module.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 | */ | |
19 | 1 | function inspect(obj, showHidden, depth, colors) { |
20 | 2934 | var ctx = { |
21 | showHidden: showHidden, | |
22 | seen: [], | |
23 | 3208 | stylize: function (str) { return str; } |
24 | }; | |
25 | 2934 | return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); |
26 | } | |
27 | ||
28 | 1 | function 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 | |
31 | 3335 | 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)) { | |
36 | 0 | return value.inspect(recurseTimes); |
37 | } | |
38 | ||
39 | // Primitive types cannot have properties | |
40 | 3335 | var primitive = formatPrimitive(ctx, value); |
41 | 3335 | if (primitive) { |
42 | 2748 | return primitive; |
43 | } | |
44 | ||
45 | // Look up the keys of the object. | |
46 | 587 | var visibleKeys = Object.keys(value); |
47 | 587 | 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. | |
52 | 587 | if (keys.length === 0 || (isError(value) && ( |
53 | (keys.length === 1 && keys[0] === 'stack') || | |
54 | (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') | |
55 | ))) { | |
56 | 364 | if (typeof value === 'function') { |
57 | 277 | var name = getName(value); |
58 | 277 | var nameSuffix = name ? ': ' + name : ''; |
59 | 277 | return ctx.stylize('[Function' + nameSuffix + ']', 'special'); |
60 | } | |
61 | 87 | if (isRegExp(value)) { |
62 | 0 | return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
63 | } | |
64 | 87 | if (isDate(value)) { |
65 | 0 | return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); |
66 | } | |
67 | 87 | if (isError(value)) { |
68 | 50 | return formatError(value); |
69 | } | |
70 | } | |
71 | ||
72 | 260 | var base = '', array = false, braces = ['{', '}']; |
73 | ||
74 | // Make Array say that they are Array | |
75 | 260 | if (isArray(value)) { |
76 | 148 | array = true; |
77 | 148 | braces = ['[', ']']; |
78 | } | |
79 | ||
80 | // Make functions say that they are functions | |
81 | 260 | if (typeof value === 'function') { |
82 | 1 | var n = value.name ? ': ' + value.name : ''; |
83 | 1 | base = ' [Function' + n + ']'; |
84 | } | |
85 | ||
86 | // Make RegExps say that they are RegExps | |
87 | 260 | if (isRegExp(value)) { |
88 | 0 | base = ' ' + RegExp.prototype.toString.call(value); |
89 | } | |
90 | ||
91 | // Make dates with properties first say the date | |
92 | 260 | if (isDate(value)) { |
93 | 0 | base = ' ' + Date.prototype.toUTCString.call(value); |
94 | } | |
95 | ||
96 | // Make error with message first say the error | |
97 | 260 | if (isError(value)) { |
98 | 0 | base = ' ' + formatError(value); |
99 | } | |
100 | ||
101 | 260 | if (keys.length === 0 && (!array || value.length == 0)) { |
102 | 37 | return braces[0] + base + braces[1]; |
103 | } | |
104 | ||
105 | 223 | if (recurseTimes < 0) { |
106 | 0 | if (isRegExp(value)) { |
107 | 0 | return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
108 | } else { | |
109 | 0 | return ctx.stylize('[Object]', 'special'); |
110 | } | |
111 | } | |
112 | ||
113 | 223 | ctx.seen.push(value); |
114 | ||
115 | 223 | var output; |
116 | 223 | if (array) { |
117 | 134 | output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); |
118 | } else { | |
119 | 89 | output = keys.map(function(key) { |
120 | 182 | return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); |
121 | }); | |
122 | } | |
123 | ||
124 | 223 | ctx.seen.pop(); |
125 | ||
126 | 223 | return reduceToSingleString(output, base, braces); |
127 | } | |
128 | ||
129 | ||
130 | 1 | function formatPrimitive(ctx, value) { |
131 | 3335 | switch (typeof value) { |
132 | case 'undefined': | |
133 | 852 | return ctx.stylize('undefined', 'undefined'); |
134 | ||
135 | case 'string': | |
136 | 1469 | var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') |
137 | .replace(/'/g, "\\'") | |
138 | .replace(/\\"/g, '"') + '\''; | |
139 | 1469 | return ctx.stylize(simple, 'string'); |
140 | ||
141 | case 'number': | |
142 | 343 | return ctx.stylize('' + value, 'number'); |
143 | ||
144 | case 'boolean': | |
145 | 75 | return ctx.stylize('' + value, 'boolean'); |
146 | } | |
147 | // For some reason typeof null is "object", so special case here. | |
148 | 596 | if (value === null) { |
149 | 9 | return ctx.stylize('null', 'null'); |
150 | } | |
151 | } | |
152 | ||
153 | ||
154 | 1 | function formatError(value) { |
155 | 50 | return '[' + Error.prototype.toString.call(value) + ']'; |
156 | } | |
157 | ||
158 | ||
159 | 1 | function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { |
160 | 134 | var output = []; |
161 | 134 | for (var i = 0, l = value.length; i < l; ++i) { |
162 | 220 | if (Object.prototype.hasOwnProperty.call(value, String(i))) { |
163 | 220 | output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
164 | String(i), true)); | |
165 | } else { | |
166 | 0 | output.push(''); |
167 | } | |
168 | } | |
169 | 134 | keys.forEach(function(key) { |
170 | 220 | if (!key.match(/^\d+$/)) { |
171 | 0 | output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
172 | key, true)); | |
173 | } | |
174 | }); | |
175 | 134 | return output; |
176 | } | |
177 | ||
178 | ||
179 | 1 | function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { |
180 | 402 | var name, str; |
181 | 402 | if (value.__lookupGetter__) { |
182 | 402 | if (value.__lookupGetter__(key)) { |
183 | 1 | if (value.__lookupSetter__(key)) { |
184 | 1 | str = ctx.stylize('[Getter/Setter]', 'special'); |
185 | } else { | |
186 | 0 | str = ctx.stylize('[Getter]', 'special'); |
187 | } | |
188 | } else { | |
189 | 401 | if (value.__lookupSetter__(key)) { |
190 | 0 | str = ctx.stylize('[Setter]', 'special'); |
191 | } | |
192 | } | |
193 | } | |
194 | 402 | if (visibleKeys.indexOf(key) < 0) { |
195 | 0 | name = '[' + key + ']'; |
196 | } | |
197 | 402 | if (!str) { |
198 | 401 | if (ctx.seen.indexOf(value[key]) < 0) { |
199 | 401 | if (recurseTimes === null) { |
200 | 0 | str = formatValue(ctx, value[key], null); |
201 | } else { | |
202 | 401 | str = formatValue(ctx, value[key], recurseTimes - 1); |
203 | } | |
204 | 401 | if (str.indexOf('\n') > -1) { |
205 | 1 | if (array) { |
206 | 0 | str = str.split('\n').map(function(line) { |
207 | 0 | return ' ' + line; |
208 | }).join('\n').substr(2); | |
209 | } else { | |
210 | 1 | str = '\n' + str.split('\n').map(function(line) { |
211 | 39 | return ' ' + line; |
212 | }).join('\n'); | |
213 | } | |
214 | } | |
215 | } else { | |
216 | 0 | str = ctx.stylize('[Circular]', 'special'); |
217 | } | |
218 | } | |
219 | 402 | if (typeof name === 'undefined') { |
220 | 402 | if (array && key.match(/^\d+$/)) { |
221 | 220 | return str; |
222 | } | |
223 | 182 | name = JSON.stringify('' + key); |
224 | 182 | if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { |
225 | 173 | name = name.substr(1, name.length - 2); |
226 | 173 | name = ctx.stylize(name, 'name'); |
227 | } else { | |
228 | 9 | name = name.replace(/'/g, "\\'") |
229 | .replace(/\\"/g, '"') | |
230 | .replace(/(^"|"$)/g, "'"); | |
231 | 9 | name = ctx.stylize(name, 'string'); |
232 | } | |
233 | } | |
234 | ||
235 | 182 | return name + ': ' + str; |
236 | } | |
237 | ||
238 | ||
239 | 1 | function reduceToSingleString(output, base, braces) { |
240 | 223 | var numLinesEst = 0; |
241 | 223 | var length = output.reduce(function(prev, cur) { |
242 | 402 | numLinesEst++; |
243 | 403 | if (cur.indexOf('\n') >= 0) numLinesEst++; |
244 | 402 | return prev + cur.length + 1; |
245 | }, 0); | |
246 | ||
247 | 223 | if (length > 60) { |
248 | 2 | return braces[0] + |
249 | (base === '' ? '' : base + '\n ') + | |
250 | ' ' + | |
251 | output.join(',\n ') + | |
252 | ' ' + | |
253 | braces[1]; | |
254 | } | |
255 | ||
256 | 221 | return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; |
257 | } | |
258 | ||
259 | 1 | function isArray(ar) { |
260 | 260 | return Array.isArray(ar) || |
261 | (typeof ar === 'object' && objectToString(ar) === '[object Array]'); | |
262 | } | |
263 | ||
264 | 1 | function isRegExp(re) { |
265 | 347 | return typeof re === 'object' && objectToString(re) === '[object RegExp]'; |
266 | } | |
267 | ||
268 | 1 | function isDate(d) { |
269 | 347 | return typeof d === 'object' && objectToString(d) === '[object Date]'; |
270 | } | |
271 | ||
272 | 1 | function isError(e) { |
273 | 570 | return typeof e === 'object' && objectToString(e) === '[object Error]'; |
274 | } | |
275 | ||
276 | 1 | function objectToString(o) { |
277 | 1371 | return Object.prototype.toString.call(o); |
278 | } |
Line | Hits | Source |
---|---|---|
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 | ||
15 | 1 | module.exports = function (func) { |
16 | 321 | if (func.name) return func.name; |
17 | ||
18 | 261 | var match = /^\s?function ([^(]*)\(/.exec(func); |
19 | 261 | return match && match[1] ? match[1] : ""; |
20 | }; |
Line | Hits | Source |
---|---|---|
1 | // This is directly from Node.js assert | |
2 | // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js | |
3 | ||
4 | ||
5 | 1 | module.exports = _deepEqual; |
6 | ||
7 | // For browser implementation | |
8 | 1 | if (!Buffer) { |
9 | 1 | var Buffer = { |
10 | isBuffer: function () { | |
11 | 12 | return false; |
12 | } | |
13 | }; | |
14 | } | |
15 | ||
16 | 1 | function _deepEqual(actual, expected) { |
17 | // 7.1. All identical values are equivalent, as determined by ===. | |
18 | 20 | if (actual === expected) { |
19 | 8 | return true; |
20 | ||
21 | 12 | } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { |
22 | 0 | if (actual.length != expected.length) return false; |
23 | ||
24 | 0 | for (var i = 0; i < actual.length; i++) { |
25 | 0 | if (actual[i] !== expected[i]) return false; |
26 | } | |
27 | ||
28 | 0 | 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. | |
32 | 12 | } else if (actual instanceof Date && expected instanceof Date) { |
33 | 0 | return actual.getTime() === expected.getTime(); |
34 | ||
35 | // 7.3. Other pairs that do not both pass typeof value == 'object', | |
36 | // equivalence is determined by ==. | |
37 | 12 | } else if (typeof actual != 'object' && typeof expected != 'object') { |
38 | 6 | 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 { | |
47 | 6 | return objEquiv(actual, expected); |
48 | } | |
49 | } | |
50 | ||
51 | 1 | function isUndefinedOrNull(value) { |
52 | 12 | return value === null || value === undefined; |
53 | } | |
54 | ||
55 | 1 | function isArguments(object) { |
56 | 6 | return Object.prototype.toString.call(object) == '[object Arguments]'; |
57 | } | |
58 | ||
59 | 1 | function objEquiv(a, b) { |
60 | 6 | if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) |
61 | 0 | return false; |
62 | // an identical 'prototype' property. | |
63 | 6 | 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. | |
66 | 6 | if (isArguments(a)) { |
67 | 0 | if (!isArguments(b)) { |
68 | 0 | return false; |
69 | } | |
70 | 0 | a = pSlice.call(a); |
71 | 0 | b = pSlice.call(b); |
72 | 0 | return _deepEqual(a, b); |
73 | } | |
74 | 6 | try { |
75 | 6 | 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 | |
79 | 0 | return false; |
80 | } | |
81 | // having the same number of owned properties (keys incorporates | |
82 | // hasOwnProperty) | |
83 | 6 | if (ka.length != kb.length) |
84 | 0 | return false; |
85 | //the same set of keys (although not necessarily the same order), | |
86 | 6 | ka.sort(); |
87 | 6 | kb.sort(); |
88 | //~~~cheap key test | |
89 | 6 | for (i = ka.length - 1; i >= 0; i--) { |
90 | 6 | if (ka[i] != kb[i]) |
91 | 0 | return false; |
92 | } | |
93 | //equivalent values for every corresponding key, and | |
94 | //~~~possibly expensive deep test | |
95 | 6 | for (i = ka.length - 1; i >= 0; i--) { |
96 | 6 | key = ka[i]; |
97 | 8 | if (!_deepEqual(a[key], b[key])) return false; |
98 | } | |
99 | 4 | return true; |
100 | } |
Line | Hits | Source |
---|---|---|
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 | ||
37 | 1 | var getPathValue = module.exports = function (path, obj) { |
38 | 42 | var parsed = parsePath(path); |
39 | 42 | 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 | ||
60 | 1 | function parsePath (path) { |
61 | 42 | var parts = path.split('.').filter(Boolean); |
62 | 42 | return parts.map(function (value) { |
63 | 44 | var re = /([A-Za-z0-9]+)\[(\d+)\]$/ |
64 | , mArr = re.exec(value) | |
65 | , val; | |
66 | 46 | if (mArr) val = { p: mArr[1], i: parseFloat(mArr[2]) }; |
67 | 44 | return val || value; |
68 | }); | |
69 | 1 | }; |
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 | ||
85 | 1 | function _getPathValue (parsed, obj) { |
86 | 42 | var tmp = obj |
87 | , res; | |
88 | 42 | for (var i = 0, l = parsed.length; i < l; i++) { |
89 | 44 | var part = parsed[i]; |
90 | 44 | if (tmp) { |
91 | 44 | if ('object' === typeof part && tmp[part.p]) { |
92 | 2 | tmp = tmp[part.p][part.i]; |
93 | } else { | |
94 | 42 | tmp = tmp[part]; |
95 | } | |
96 | 86 | if (i == (l - 1)) res = tmp; |
97 | } else { | |
98 | 0 | res = undefined; |
99 | } | |
100 | } | |
101 | 42 | return res; |
102 | 1 | }; |
Line | Hits | Source |
---|---|---|
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 | ||
28 | 1 | module.exports = function (ctx, name, getter) { |
29 | 0 | var context = ('function' === typeof ctx) ? ctx.prototype : ctx; |
30 | 0 | Object.defineProperty(context, name, |
31 | { get: function () { | |
32 | 0 | getter.call(this); |
33 | 0 | return this; |
34 | } | |
35 | , configurable: true | |
36 | }); | |
37 | }; |
Line | Hits | Source |
---|---|---|
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 | ||
28 | 1 | module.exports = function (ctx, name, method) { |
29 | 0 | var context = ('function' === typeof ctx) ? ctx.prototype : ctx; |
30 | 0 | context[name] = function () { |
31 | 0 | method.apply(this, arguments); |
32 | 0 | return this; |
33 | }; | |
34 | }; |
Line | Hits | Source |
---|---|---|
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 | ||
35 | 1 | module.exports = function (ctx, name, getter) { |
36 | 0 | var context = ('function' === typeof ctx) ? ctx.prototype : ctx |
37 | , _get = Object.getOwnPropertyDescriptor(context, name) | |
38 | 0 | , _super = function () { return this; }; |
39 | ||
40 | 0 | if (_get && 'function' === typeof _get.get) |
41 | 0 | _super = _get.get |
42 | ||
43 | 0 | Object.defineProperty(context, name, |
44 | { get: getter(_super) | |
45 | , configurable: true | |
46 | }); | |
47 | }; |
Line | Hits | Source |
---|---|---|
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 | ||
36 | 1 | module.exports = function (ctx, name, method) { |
37 | 0 | var context = ('function' === typeof ctx) ? ctx.prototype : ctx |
38 | , _method = context[name] | |
39 | 0 | , _super = function () { return this; }; |
40 | ||
41 | 0 | if (_method && 'function' === typeof _method) |
42 | 0 | _super = _method; |
43 | ||
44 | 0 | context[name] = method(_super); |
45 | }; |
Line | Hits | Source |
---|---|---|
1 | /*! | |
2 | * chai | |
3 | * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> | |
4 | * MIT Licensed | |
5 | */ | |
6 | ||
7 | 1 | module.exports = function (chai, util) { |
8 | 1 | chai.expect = function (val, message) { |
9 | 276 | return new chai.Assertion(val, message); |
10 | }; | |
11 | }; | |
12 |
Line | Hits | Source |
---|---|---|
1 | /*! | |
2 | * chai | |
3 | * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> | |
4 | * MIT Licensed | |
5 | */ | |
6 | ||
7 | 1 | module.exports = function (chai, util) { |
8 | 1 | var Assertion = chai.Assertion; |
9 | ||
10 | 1 | chai.should = function () { |
11 | // modify Object.prototype to have `should` | |
12 | 1 | Object.defineProperty(Object.prototype, 'should', { |
13 | set: function(){}, | |
14 | get: function(){ | |
15 | 188 | if (this instanceof String || this instanceof Number) { |
16 | 1 | return new Assertion(this.constructor(this)); |
17 | 187 | } else if (this instanceof Boolean) { |
18 | 0 | return new Assertion(this == true); |
19 | } | |
20 | 187 | return new Assertion(this); |
21 | }, | |
22 | configurable: true | |
23 | }); | |
24 | ||
25 | 1 | var should = {}; |
26 | ||
27 | 1 | should.equal = function (val1, val2) { |
28 | 76 | new Assertion(val1).to.equal(val2); |
29 | }; | |
30 | ||
31 | 1 | should.Throw = function (fn, errt, errs) { |
32 | 7 | new Assertion(fn).to.Throw(errt, errs); |
33 | }; | |
34 | ||
35 | 1 | should.exist = function (val) { |
36 | 2 | new Assertion(val).to.exist; |
37 | } | |
38 | ||
39 | // negation | |
40 | 1 | should.not = {} |
41 | ||
42 | 1 | should.not.equal = function (val1, val2) { |
43 | 1 | new Assertion(val1).to.not.equal(val2); |
44 | }; | |
45 | ||
46 | 1 | should.not.Throw = function (fn, errt, errs) { |
47 | 3 | new Assertion(fn).to.not.Throw(errt, errs); |
48 | }; | |
49 | ||
50 | 1 | should.not.exist = function (val) { |
51 | 2 | new Assertion(val).to.not.exist; |
52 | } | |
53 | ||
54 | 1 | should['throw'] = should['Throw']; |
55 | 1 | should.not['throw'] = should.not['Throw']; |
56 | ||
57 | 1 | return should; |
58 | }; | |
59 | }; |
Line | Hits | Source |
---|---|---|
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 | ||
31 | 1 | module.exports = function (chai, util) { |
32 | ||
33 | /*! | |
34 | * Chai dependencies. | |
35 | */ | |
36 | ||
37 | 1 | var Assertion = chai.Assertion |
38 | , flag = util.flag; | |
39 | ||
40 | /*! | |
41 | * Module export. | |
42 | */ | |
43 | ||
44 | 1 | 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 | ||
59 | 1 | assert.fail = function (actual, expected, message, operator) { |
60 | 1 | 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 | ||
83 | 1 | assert.ok = function (val, msg) { |
84 | 6 | 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 | ||
101 | 1 | assert.equal = function (act, exp, msg) { |
102 | 52 | var test = new Assertion(act, msg); |
103 | ||
104 | 52 | 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 | ||
127 | 1 | assert.notEqual = function (act, exp, msg) { |
128 | 2 | var test = new Assertion(act, msg); |
129 | ||
130 | 2 | 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 | ||
153 | 1 | assert.strictEqual = function (act, exp, msg) { |
154 | 2 | 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 | ||
171 | 1 | assert.notStrictEqual = function (act, exp, msg) { |
172 | 2 | 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 | ||
189 | 1 | assert.deepEqual = function (act, exp, msg) { |
190 | 2 | 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 | ||
207 | 1 | assert.notDeepEqual = function (act, exp, msg) { |
208 | 2 | 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 | ||
225 | 1 | assert.isTrue = function (val, msg) { |
226 | 4 | 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 | ||
243 | 1 | assert.isFalse = function (val, msg) { |
244 | 3 | 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 | ||
260 | 1 | assert.isNull = function (val, msg) { |
261 | 2 | 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 | ||
278 | 1 | assert.isNotNull = function (val, msg) { |
279 | 2 | 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 | ||
295 | 1 | assert.isUndefined = function (val, msg) { |
296 | 2 | 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 | ||
313 | 1 | assert.isDefined = function (val, msg) { |
314 | 2 | 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 | ||
331 | 1 | assert.isFunction = function (val, msg) { |
332 | 2 | 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 | ||
349 | 1 | assert.isNotFunction = function (val, msg) { |
350 | 2 | 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 | ||
367 | 1 | assert.isObject = function (val, msg) { |
368 | 5 | 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 | ||
385 | 1 | assert.isNotObject = function (val, msg) { |
386 | 2 | 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 | ||
403 | 1 | assert.isArray = function (val, msg) { |
404 | 3 | 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 | ||
421 | 1 | assert.isNotArray = function (val, msg) { |
422 | 3 | 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 | ||
439 | 1 | assert.isString = function (val, msg) { |
440 | 3 | 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 | ||
457 | 1 | assert.isNotString = function (val, msg) { |
458 | 3 | 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 | ||
475 | 1 | assert.isNumber = function (val, msg) { |
476 | 3 | 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 | ||
493 | 1 | assert.isNotNumber = function (val, msg) { |
494 | 3 | 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 | ||
514 | 1 | assert.isBoolean = function (val, msg) { |
515 | 3 | 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 | ||
535 | 1 | assert.isNotBoolean = function (val, msg) { |
536 | 3 | 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 | ||
553 | 1 | assert.typeOf = function (val, type, msg) { |
554 | 4 | 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 | ||
571 | 1 | assert.notTypeOf = function (val, type, msg) { |
572 | 2 | 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 | ||
592 | 1 | assert.instanceOf = function (val, type, msg) { |
593 | 2 | 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 | ||
613 | 1 | assert.notInstanceOf = function (val, type, msg) { |
614 | 2 | 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 | ||
633 | 1 | assert.include = function (exp, inc, msg) { |
634 | 3 | var obj = new Assertion(exp, msg); |
635 | ||
636 | 3 | if (Array.isArray(exp)) { |
637 | 1 | obj.to.include(inc); |
638 | 2 | } else if ('string' === typeof exp) { |
639 | 2 | 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 | ||
657 | 1 | assert.match = function (exp, re, msg) { |
658 | 0 | 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 | ||
676 | 1 | assert.length = function (exp, len, msg) { |
677 | 4 | 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 | ||
697 | 1 | assert.throws = function (fn, type, msg) { |
698 | 3 | if ('string' === typeof type) { |
699 | 1 | msg = type; |
700 | 1 | type = null; |
701 | } | |
702 | ||
703 | 3 | 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 | ||
723 | 1 | assert.doesNotThrow = function (fn, type, msg) { |
724 | 3 | if ('string' === typeof type) { |
725 | 1 | msg = type; |
726 | 1 | type = null; |
727 | } | |
728 | ||
729 | 3 | 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 | ||
748 | 1 | assert.operator = function (val, operator, val2, msg) { |
749 | 15 | if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) { |
750 | 1 | throw new Error('Invalid operator "' + operator + '"'); |
751 | } | |
752 | 14 | var test = new Assertion(eval(val + operator + val2), msg); |
753 | 14 | 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 | ||
763 | 1 | assert.ifError = function (val, msg) { |
764 | 4 | new Assertion(val, msg).to.not.be.ok; |
765 | }; | |
766 | ||
767 | /*! | |
768 | * Aliases. | |
769 | */ | |
770 | ||
771 | 1 | (function alias(name, as){ |
772 | 2 | assert[as] = assert[name]; |
773 | 2 | return alias; |
774 | }) | |
775 | ('length', 'lengthOf') | |
776 | ('throws', 'throw'); | |
777 | }; |