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 | 1 | var exports = module.exports = {}; |
9 | ||
10 | 1 | exports.version = '0.5.2'; |
11 | ||
12 | 1 | exports.Assertion = require('./assertion'); |
13 | 1 | exports.AssertionError = require('./error'); |
14 | ||
15 | 1 | exports.inspect = require('./utils/inspect'); |
16 | ||
17 | 1 | exports.use = function (fn) { |
18 | 5 | if (!~used.indexOf(fn)) { |
19 | 4 | fn(this); |
20 | 4 | used.push(fn); |
21 | } | |
22 | ||
23 | 5 | return this; |
24 | }; | |
25 | ||
26 | 1 | var expect = require('./interface/expect'); |
27 | 1 | exports.use(expect); |
28 | ||
29 | 1 | var should = require('./interface/should'); |
30 | 1 | exports.use(should); |
31 | ||
32 | 1 | var assert = require('./interface/assert'); |
33 | 1 | exports.use(assert); |
Line | Hits | Source |
---|---|---|
1 | /*! | |
2 | * chai | |
3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
4 | * MIT Licensed | |
5 | * | |
6 | * Primarily a refactor of: should.js | |
7 | * https://github.com/visionmedia/should.js | |
8 | * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca> | |
9 | * MIT Licensed | |
10 | */ | |
11 | ||
12 | /** | |
13 | * ### BDD Style Introduction | |
14 | * | |
15 | * The BDD style is exposed through `expect` or `should` interfaces. In both | |
16 | * scenarios, you chain together natural language assertions. | |
17 | * | |
18 | * // expect | |
19 | * var expect = require('chai').expect; | |
20 | * expect(foo).to.equal('bar'); | |
21 | * | |
22 | * // should | |
23 | * var should = require('chai').should(); | |
24 | * foo.should.equal('bar'); | |
25 | * | |
26 | * #### Differences | |
27 | * | |
28 | * The `expect` interface provides a function as a starting point for chaining | |
29 | * your language assertions. It works on node.js and in all browsers. | |
30 | * | |
31 | * The `should` interface extends `Object.prototype` to provide a single getter as | |
32 | * the starting point for your language assertions. It works on node.js and in | |
33 | * all browsers except Internet Explorer. | |
34 | * | |
35 | * #### Configuration | |
36 | * | |
37 | * By default, Chai does not show stack traces upon an AssertionError. This can | |
38 | * be changed by modifying the `includeStack` parameter for chai.Assertion. For example: | |
39 | * | |
40 | * var chai = require('chai'); | |
41 | * chai.Assertion.includeStack = true; // defaults to false | |
42 | */ | |
43 | ||
44 | /*! | |
45 | * Module dependencies. | |
46 | */ | |
47 | ||
48 | 1 | var AssertionError = require('./error') |
49 | , eql = require('./utils/eql') | |
50 | , toString = Object.prototype.toString | |
51 | , inspect = require('./utils/inspect'); | |
52 | ||
53 | /*! | |
54 | * Module export. | |
55 | */ | |
56 | ||
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 | 738 | this.ssfi = stack || arguments.callee; |
70 | 738 | this.obj = obj; |
71 | 738 | this.msg = msg; |
72 | } | |
73 | ||
74 | /*! | |
75 | * ## Assertion.includeStack | |
76 | * , toString = Object.prototype.toString | |
77 | * | |
78 | * User configurable property, influences whether stack trace | |
79 | * is included in Assertion error message. Default of false | |
80 | * suppresses stack trace in the error message | |
81 | * | |
82 | * Assertion.includeStack = true; // enable stack on error | |
83 | * | |
84 | * @api public | |
85 | */ | |
86 | ||
87 | 1 | Assertion.includeStack = false; |
88 | ||
89 | /*! | |
90 | * # .assert(expression, message, negateMessage, expected, actual) | |
91 | * | |
92 | * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. | |
93 | * | |
94 | * @name assert | |
95 | * @param {Philosophical} expression to be tested | |
96 | * @param {String} message to display if fails | |
97 | * @param {String} negatedMessage to display if negated expression fails | |
98 | * @param {*} expected value (remember to check for negation) | |
99 | * @param {*} actual (optional) will default to `this.obj` | |
100 | * @api private | |
101 | */ | |
102 | ||
103 | 1 | Assertion.prototype.assert = function (expr, msg, negateMsg, expected, actual) { |
104 | 744 | actual = actual || this.obj; |
105 | 744 | var msg = (this.negate ? negateMsg : msg) |
106 | , ok = this.negate ? !expr : expr; | |
107 | ||
108 | 744 | if (!ok) { |
109 | 167 | throw new AssertionError({ |
110 | message: this.msg ? this.msg + ': ' + msg : msg // include custom message if available | |
111 | , actual: actual | |
112 | , expected: expected | |
113 | , stackStartFunction: (Assertion.includeStack) ? this.assert : this.ssfi | |
114 | }); | |
115 | } | |
116 | }; | |
117 | ||
118 | /*! | |
119 | * # inspect | |
120 | * | |
121 | * Returns the current object stringified. | |
122 | * | |
123 | * @name inspect | |
124 | * @api private | |
125 | */ | |
126 | ||
127 | 1 | Object.defineProperty(Assertion.prototype, 'inspect', |
128 | { get: function () { | |
129 | 1462 | return inspect(this.obj); |
130 | } | |
131 | , configurable: true | |
132 | }); | |
133 | ||
134 | /** | |
135 | * # to | |
136 | * | |
137 | * Language chain. | |
138 | * | |
139 | * @name to | |
140 | * @api public | |
141 | */ | |
142 | ||
143 | 1 | Object.defineProperty(Assertion.prototype, 'to', |
144 | { get: function () { | |
145 | 408 | return this; |
146 | } | |
147 | , configurable: true | |
148 | }); | |
149 | ||
150 | /** | |
151 | * # be | |
152 | * | |
153 | * Language chain. | |
154 | * | |
155 | * @name be | |
156 | * @api public | |
157 | */ | |
158 | ||
159 | 1 | Object.defineProperty(Assertion.prototype, 'be', |
160 | { get: function () { | |
161 | 163 | return this; |
162 | } | |
163 | , configurable: true | |
164 | }); | |
165 | ||
166 | /** | |
167 | * # been | |
168 | * | |
169 | * Language chain. Also tests `tense` to past for addon | |
170 | * modules that use the tense feature. | |
171 | * | |
172 | * @name been | |
173 | * @api public | |
174 | */ | |
175 | ||
176 | 1 | Object.defineProperty(Assertion.prototype, 'been', |
177 | { get: function () { | |
178 | 1 | this.tense = 'past'; |
179 | 1 | return this; |
180 | } | |
181 | , configurable: true | |
182 | }); | |
183 | ||
184 | /** | |
185 | * # an | |
186 | * | |
187 | * Language chain. | |
188 | * | |
189 | * @name an | |
190 | * @api public | |
191 | */ | |
192 | ||
193 | 1 | Object.defineProperty(Assertion.prototype, 'an', |
194 | { get: function () { | |
195 | 4 | return this; |
196 | } | |
197 | , configurable: true | |
198 | }); | |
199 | /** | |
200 | * # is | |
201 | * | |
202 | * Language chain. | |
203 | * | |
204 | * @name is | |
205 | * @api public | |
206 | */ | |
207 | ||
208 | 1 | Object.defineProperty(Assertion.prototype, 'is', |
209 | { get: function () { | |
210 | 94 | return this; |
211 | } | |
212 | , configurable: true | |
213 | }); | |
214 | ||
215 | /** | |
216 | * # and | |
217 | * | |
218 | * Language chain. | |
219 | * | |
220 | * @name and | |
221 | * @api public | |
222 | */ | |
223 | ||
224 | 1 | Object.defineProperty(Assertion.prototype, 'and', |
225 | { get: function () { | |
226 | 1 | return this; |
227 | } | |
228 | , configurable: true | |
229 | }); | |
230 | ||
231 | /** | |
232 | * # have | |
233 | * | |
234 | * Language chain. | |
235 | * | |
236 | * @name have | |
237 | * @api public | |
238 | */ | |
239 | ||
240 | 1 | Object.defineProperty(Assertion.prototype, 'have', |
241 | { get: function () { | |
242 | 92 | return this; |
243 | } | |
244 | , configurable: true | |
245 | }); | |
246 | ||
247 | /** | |
248 | * # with | |
249 | * | |
250 | * Language chain. | |
251 | * | |
252 | * @name with | |
253 | * @api public | |
254 | */ | |
255 | ||
256 | 1 | Object.defineProperty(Assertion.prototype, 'with', |
257 | { get: function () { | |
258 | 2 | return this; |
259 | } | |
260 | , configurable: true | |
261 | }); | |
262 | ||
263 | /** | |
264 | * # .not | |
265 | * | |
266 | * Negates any of assertions following in the chain. | |
267 | * | |
268 | * @name not | |
269 | * @api public | |
270 | */ | |
271 | ||
272 | 1 | Object.defineProperty(Assertion.prototype, 'not', |
273 | { get: function () { | |
274 | 145 | this.negate = true; |
275 | 145 | return this; |
276 | } | |
277 | , configurable: true | |
278 | }); | |
279 | ||
280 | /** | |
281 | * # .ok | |
282 | * | |
283 | * Assert object truthiness. | |
284 | * | |
285 | * expect('everthing').to.be.ok; | |
286 | * expect(false).to.not.be.ok; | |
287 | * expect(undefined).to.not.be.ok; | |
288 | * expect(null).to.not.be.ok; | |
289 | * | |
290 | * @name ok | |
291 | * @api public | |
292 | */ | |
293 | ||
294 | 1 | Object.defineProperty(Assertion.prototype, 'ok', |
295 | { get: function () { | |
296 | 23 | this.assert( |
297 | this.obj | |
298 | , 'expected ' + this.inspect + ' to be truthy' | |
299 | , 'expected ' + this.inspect + ' to be falsy'); | |
300 | ||
301 | 15 | return this; |
302 | } | |
303 | , configurable: true | |
304 | }); | |
305 | ||
306 | /** | |
307 | * # .true | |
308 | * | |
309 | * Assert object is true | |
310 | * | |
311 | * @name true | |
312 | * @api public | |
313 | */ | |
314 | ||
315 | 1 | Object.defineProperty(Assertion.prototype, 'true', |
316 | { get: function () { | |
317 | 12 | this.assert( |
318 | true === this.obj | |
319 | , 'expected ' + this.inspect + ' to be true' | |
320 | , 'expected ' + this.inspect + ' to be false' | |
321 | , this.negate ? false : true | |
322 | ); | |
323 | ||
324 | 7 | return this; |
325 | } | |
326 | , configurable: true | |
327 | }); | |
328 | ||
329 | /** | |
330 | * # .false | |
331 | * | |
332 | * Assert object is false | |
333 | * | |
334 | * @name false | |
335 | * @api public | |
336 | */ | |
337 | ||
338 | 1 | Object.defineProperty(Assertion.prototype, 'false', |
339 | { get: function () { | |
340 | 12 | this.assert( |
341 | false === this.obj | |
342 | , 'expected ' + this.inspect + ' to be false' | |
343 | , 'expected ' + this.inspect + ' to be true' | |
344 | , this.negate ? true : false | |
345 | ); | |
346 | ||
347 | 8 | return this; |
348 | } | |
349 | , configurable: true | |
350 | }); | |
351 | ||
352 | /** | |
353 | * # .exist | |
354 | * | |
355 | * Assert object exists (null). | |
356 | * | |
357 | * var foo = 'hi' | |
358 | * , bar; | |
359 | * expect(foo).to.exist; | |
360 | * expect(bar).to.not.exist; | |
361 | * | |
362 | * @name exist | |
363 | * @api public | |
364 | */ | |
365 | ||
366 | 1 | Object.defineProperty(Assertion.prototype, 'exist', |
367 | { get: function () { | |
368 | 6 | this.assert( |
369 | null != this.obj | |
370 | , 'expected ' + this.inspect + ' to exist' | |
371 | , 'expected ' + this.inspect + ' to not exist' | |
372 | ); | |
373 | ||
374 | 4 | return this; |
375 | } | |
376 | , configurable: true | |
377 | }); | |
378 | ||
379 | /** | |
380 | * # .empty | |
381 | * | |
382 | * Assert object's length to be 0. | |
383 | * | |
384 | * expect([]).to.be.empty; | |
385 | * | |
386 | * @name empty | |
387 | * @api public | |
388 | */ | |
389 | ||
390 | 1 | Object.defineProperty(Assertion.prototype, 'empty', |
391 | { get: function () { | |
392 | 32 | var expected = this.obj; |
393 | ||
394 | 32 | if (Array.isArray(this.obj)) { |
395 | 8 | expected = this.obj.length; |
396 | 24 | } else if (typeof this.obj === 'object') { |
397 | 16 | expected = Object.keys(this.obj).length; |
398 | } | |
399 | ||
400 | 32 | this.assert( |
401 | !expected | |
402 | , 'expected ' + this.inspect + ' to be empty' | |
403 | , 'expected ' + this.inspect + ' not to be empty'); | |
404 | ||
405 | 16 | return this; |
406 | } | |
407 | , configurable: true | |
408 | }); | |
409 | ||
410 | /** | |
411 | * # .arguments | |
412 | * | |
413 | * Assert object is an instanceof arguments. | |
414 | * | |
415 | * function test () { | |
416 | * expect(arguments).to.be.arguments; | |
417 | * } | |
418 | * | |
419 | * @name arguments | |
420 | * @api public | |
421 | */ | |
422 | ||
423 | 1 | Object.defineProperty(Assertion.prototype, 'arguments', |
424 | { get: function () { | |
425 | 4 | this.assert( |
426 | '[object Arguments]' == Object.prototype.toString.call(this.obj) | |
427 | , 'expected ' + this.inspect + ' to be arguments' | |
428 | , 'expected ' + this.inspect + ' to not be arguments' | |
429 | , '[object Arguments]' | |
430 | , Object.prototype.toString.call(this.obj) | |
431 | ); | |
432 | ||
433 | 4 | return this; |
434 | } | |
435 | , configurable: true | |
436 | }); | |
437 | ||
438 | /** | |
439 | * # .equal(value) | |
440 | * | |
441 | * Assert strict equality. | |
442 | * | |
443 | * expect('hello').to.equal('hello'); | |
444 | * | |
445 | * @name equal | |
446 | * @param {*} value | |
447 | * @api public | |
448 | */ | |
449 | ||
450 | 1 | Assertion.prototype.equal = function (val) { |
451 | 161 | this.assert( |
452 | val === this.obj | |
453 | , 'expected ' + this.inspect + ' to equal ' + inspect(val) | |
454 | , 'expected ' + this.inspect + ' to not equal ' + inspect(val) | |
455 | , val ); | |
456 | ||
457 | 151 | return this; |
458 | }; | |
459 | ||
460 | /** | |
461 | * # .eql(value) | |
462 | * | |
463 | * Assert deep equality. | |
464 | * | |
465 | * expect({ foo: 'bar' }).to.eql({ foo: 'bar' }); | |
466 | * | |
467 | * @name eql | |
468 | * @param {*} value | |
469 | * @api public | |
470 | */ | |
471 | ||
472 | 1 | Assertion.prototype.eql = function (obj) { |
473 | 14 | this.assert( |
474 | eql(obj, this.obj) | |
475 | , 'expected ' + this.inspect + ' to equal ' + inspect(obj) | |
476 | , 'expected ' + this.inspect + ' to not equal ' + inspect(obj) | |
477 | , obj ); | |
478 | ||
479 | 10 | return this; |
480 | }; | |
481 | ||
482 | /** | |
483 | * # .above(value) | |
484 | * | |
485 | * Assert greater than `value`. | |
486 | * | |
487 | * expect(10).to.be.above(5); | |
488 | * | |
489 | * @name above | |
490 | * @param {Number} value | |
491 | * @api public | |
492 | */ | |
493 | ||
494 | 1 | Assertion.prototype.above = function (val) { |
495 | 12 | this.assert( |
496 | this.obj > val | |
497 | , 'expected ' + this.inspect + ' to be above ' + val | |
498 | , 'expected ' + this.inspect + ' to be below ' + val); | |
499 | ||
500 | 8 | return this; |
501 | }; | |
502 | ||
503 | /** | |
504 | * # .below(value) | |
505 | * | |
506 | * Assert less than `value`. | |
507 | * | |
508 | * expect(5).to.be.below(10); | |
509 | * | |
510 | * @name below | |
511 | * @param {Number} value | |
512 | * @api public | |
513 | */ | |
514 | ||
515 | 1 | Assertion.prototype.below = function (val) { |
516 | 12 | this.assert( |
517 | this.obj < val | |
518 | , 'expected ' + this.inspect + ' to be below ' + val | |
519 | , 'expected ' + this.inspect + ' to be above ' + val); | |
520 | ||
521 | 8 | return this; |
522 | }; | |
523 | ||
524 | /** | |
525 | * # .within(start, finish) | |
526 | * | |
527 | * Assert that a number is within a range. | |
528 | * | |
529 | * expect(7).to.be.within(5,10); | |
530 | * | |
531 | * @name within | |
532 | * @param {Number} start lowerbound inclusive | |
533 | * @param {Number} finish upperbound inclusive | |
534 | * @api public | |
535 | */ | |
536 | ||
537 | 1 | Assertion.prototype.within = function (start, finish) { |
538 | 12 | var range = start + '..' + finish; |
539 | ||
540 | 12 | this.assert( |
541 | this.obj >= start && this.obj <= finish | |
542 | , 'expected ' + this.inspect + ' to be within ' + range | |
543 | , 'expected ' + this.inspect + ' to not be within ' + range); | |
544 | ||
545 | 8 | return this; |
546 | }; | |
547 | ||
548 | /** | |
549 | * # .a(type) | |
550 | * | |
551 | * Assert typeof. | |
552 | * | |
553 | * expect('test').to.be.a('string'); | |
554 | * | |
555 | * @name a | |
556 | * @param {String} type | |
557 | * @api public | |
558 | */ | |
559 | ||
560 | 1 | Assertion.prototype.a = function (type) { |
561 | 128 | var klass = type.charAt(0).toUpperCase() + type.slice(1); |
562 | ||
563 | 128 | this.assert( |
564 | '[object ' + klass + ']' === toString.call(this.obj) | |
565 | , 'expected ' + this.inspect + ' to be a ' + type | |
566 | , 'expected ' + this.inspect + ' not to be a ' + type | |
567 | , '[object ' + klass + ']' | |
568 | , toString.call(this.obj) | |
569 | ); | |
570 | ||
571 | 114 | return this; |
572 | }; | |
573 | ||
574 | /** | |
575 | * # .instanceof(constructor) | |
576 | * | |
577 | * Assert instanceof. | |
578 | * | |
579 | * var Tea = function (name) { this.name = name; } | |
580 | * , Chai = new Tea('chai'); | |
581 | * | |
582 | * expect(Chai).to.be.an.instanceOf(Tea); | |
583 | * | |
584 | * @name instanceof | |
585 | * @param {Constructor} | |
586 | * @alias instanceOf | |
587 | * @api public | |
588 | */ | |
589 | ||
590 | 1 | Assertion.prototype.instanceof = function (constructor) { |
591 | 9 | var name = constructor.name; |
592 | 9 | this.assert( |
593 | this.obj instanceof constructor | |
594 | , 'expected ' + this.inspect + ' to be an instance of ' + name | |
595 | , 'expected ' + this.inspect + ' to not be an instance of ' + name); | |
596 | ||
597 | 5 | return this; |
598 | }; | |
599 | ||
600 | /** | |
601 | * # .property(name, [value]) | |
602 | * | |
603 | * Assert that property of `name` exists, optionally with `value`. | |
604 | * | |
605 | * var obj = { foo: 'bar' } | |
606 | * expect(obj).to.have.property('foo'); | |
607 | * expect(obj).to.have.property('foo', 'bar'); | |
608 | * expect(obj).to.have.property('foo').to.be.a('string'); | |
609 | * | |
610 | * @name property | |
611 | * @param {String} name | |
612 | * @param {*} value (optional) | |
613 | * @returns value of property for chaining | |
614 | * @api public | |
615 | */ | |
616 | ||
617 | 1 | Assertion.prototype.property = function (name, val) { |
618 | 37 | if (this.negate && undefined !== val) { |
619 | 4 | if (undefined === this.obj[name]) { |
620 | 2 | throw new Error(this.inspect + ' has no property ' + inspect(name)); |
621 | } | |
622 | } else { | |
623 | 33 | this.assert( |
624 | undefined !== this.obj[name] | |
625 | , 'expected ' + this.inspect + ' to have a property ' + inspect(name) | |
626 | , 'expected ' + this.inspect + ' to not have property ' + inspect(name)); | |
627 | } | |
628 | ||
629 | 30 | if (undefined !== val) { |
630 | 11 | this.assert( |
631 | val === this.obj[name] | |
632 | , 'expected ' + this.inspect + ' to have a property ' + inspect(name) + ' of ' + | |
633 | inspect(val) + ', but got ' + inspect(this.obj[name]) | |
634 | , 'expected ' + this.inspect + ' to not have a property ' + inspect(name) + ' of ' + inspect(val) | |
635 | , val | |
636 | , this.obj[val] | |
637 | ); | |
638 | } | |
639 | ||
640 | 24 | this.obj = this.obj[name]; |
641 | 24 | return this; |
642 | }; | |
643 | ||
644 | /** | |
645 | * # .ownProperty(name) | |
646 | * | |
647 | * Assert that has own property by `name`. | |
648 | * | |
649 | * expect('test').to.have.ownProperty('length'); | |
650 | * | |
651 | * @name ownProperty | |
652 | * @alias haveOwnProperty | |
653 | * @param {String} name | |
654 | * @api public | |
655 | */ | |
656 | ||
657 | 1 | Assertion.prototype.ownProperty = function (name) { |
658 | 8 | this.assert( |
659 | this.obj.hasOwnProperty(name) | |
660 | , 'expected ' + this.inspect + ' to have own property ' + inspect(name) | |
661 | , 'expected ' + this.inspect + ' to not have own property ' + inspect(name)); | |
662 | 6 | return this; |
663 | }; | |
664 | ||
665 | /** | |
666 | * # .length(val) | |
667 | * | |
668 | * Assert that object has expected length. | |
669 | * | |
670 | * expect([1,2,3]).to.have.length(3); | |
671 | * expect('foobar').to.have.length(6); | |
672 | * | |
673 | * @name length | |
674 | * @alias lengthOf | |
675 | * @param {Number} length | |
676 | * @api public | |
677 | */ | |
678 | ||
679 | 1 | Assertion.prototype.length = function (n) { |
680 | 16 | new Assertion(this.obj).to.have.property('length'); |
681 | 13 | var len = this.obj.length; |
682 | ||
683 | 13 | this.assert( |
684 | len == n | |
685 | , 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len | |
686 | , 'expected ' + this.inspect + ' to not have a length of ' + len | |
687 | , n | |
688 | , len | |
689 | ); | |
690 | ||
691 | 9 | return this; |
692 | }; | |
693 | ||
694 | /** | |
695 | * # .match(regexp) | |
696 | * | |
697 | * Assert that matches regular expression. | |
698 | * | |
699 | * expect('foobar').to.match(/^foo/); | |
700 | * | |
701 | * @name match | |
702 | * @param {RegExp} RegularExpression | |
703 | * @api public | |
704 | */ | |
705 | ||
706 | 1 | Assertion.prototype.match = function (re) { |
707 | 11 | this.assert( |
708 | re.exec(this.obj) | |
709 | , 'expected ' + this.inspect + ' to match ' + re | |
710 | , 'expected ' + this.inspect + ' not to match ' + re); | |
711 | ||
712 | 7 | return this; |
713 | }; | |
714 | ||
715 | /** | |
716 | * # .include(obj) | |
717 | * | |
718 | * Assert the inclusion of an object in an Array or substring in string. | |
719 | * | |
720 | * expect([1,2,3]).to.include(2); | |
721 | * | |
722 | * @name include | |
723 | * @param {Object|String|Number} obj | |
724 | * @api public | |
725 | */ | |
726 | ||
727 | 1 | Assertion.prototype.include = function (obj) { |
728 | 17 | this.assert( |
729 | ~this.obj.indexOf(obj) | |
730 | , 'expected ' + this.inspect + ' to include ' + inspect(obj) | |
731 | , 'expected ' + this.inspect + ' to not include ' + inspect(obj)); | |
732 | ||
733 | 13 | return this; |
734 | }; | |
735 | ||
736 | /** | |
737 | * # .string(string) | |
738 | * | |
739 | * Assert inclusion of string in string. | |
740 | * | |
741 | * expect('foobar').to.have.string('bar'); | |
742 | * | |
743 | * @name string | |
744 | * @param {String} string | |
745 | * @api public | |
746 | */ | |
747 | ||
748 | 1 | Assertion.prototype.string = function (str) { |
749 | 15 | new Assertion(this.obj).is.a('string'); |
750 | ||
751 | 13 | this.assert( |
752 | ~this.obj.indexOf(str) | |
753 | , 'expected ' + this.inspect + ' to contain ' + inspect(str) | |
754 | , 'expected ' + this.inspect + ' to not contain ' + inspect(str)); | |
755 | ||
756 | 8 | return this; |
757 | }; | |
758 | ||
759 | ||
760 | ||
761 | /** | |
762 | * # contain | |
763 | * | |
764 | * Toggles the `contain` flag for the `keys` assertion. | |
765 | * | |
766 | * @name contain | |
767 | * @api public | |
768 | */ | |
769 | ||
770 | 1 | Object.defineProperty(Assertion.prototype, 'contain', |
771 | { get: function () { | |
772 | 37 | this.contains = true; |
773 | 37 | return this; |
774 | }, | |
775 | configurable: true | |
776 | }); | |
777 | ||
778 | /** | |
779 | * # .keys(key1, [key2], [...]) | |
780 | * | |
781 | * Assert exact keys or the inclusing of keys using the `contain` modifier. | |
782 | * | |
783 | * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']); | |
784 | * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar'); | |
785 | * | |
786 | * @name keys | |
787 | * @alias key | |
788 | * @param {String|Array} Keys | |
789 | * @api public | |
790 | */ | |
791 | ||
792 | 1 | Assertion.prototype.keys = function(keys) { |
793 | 56 | var str |
794 | , ok = true; | |
795 | ||
796 | 56 | keys = keys instanceof Array |
797 | ? keys | |
798 | : Array.prototype.slice.call(arguments); | |
799 | ||
800 | 64 | if (!keys.length) throw new Error('keys required'); |
801 | ||
802 | 48 | var actual = Object.keys(this.obj) |
803 | , len = keys.length; | |
804 | ||
805 | // Inclusion | |
806 | 48 | ok = keys.every(function(key){ |
807 | 70 | return ~actual.indexOf(key); |
808 | }); | |
809 | ||
810 | // Strict | |
811 | 48 | if (!this.negate && !this.contains) { |
812 | 12 | ok = ok && keys.length == actual.length; |
813 | } | |
814 | ||
815 | // Key string | |
816 | 48 | if (len > 1) { |
817 | 26 | keys = keys.map(function(key){ |
818 | 54 | return inspect(key); |
819 | }); | |
820 | 26 | var last = keys.pop(); |
821 | 26 | str = keys.join(', ') + ', and ' + last; |
822 | } else { | |
823 | 22 | str = inspect(keys[0]); |
824 | } | |
825 | ||
826 | // Form | |
827 | 48 | str = (len > 1 ? 'keys ' : 'key ') + str; |
828 | ||
829 | // Have / include | |
830 | 48 | str = (this.contains ? 'contain ' : 'have ') + str; |
831 | ||
832 | // Assertion | |
833 | 48 | this.assert( |
834 | ok | |
835 | , 'expected ' + this.inspect + ' to ' + str | |
836 | , 'expected ' + this.inspect + ' to not ' + str | |
837 | , keys | |
838 | , Object.keys(this.obj) | |
839 | ); | |
840 | ||
841 | 32 | return this; |
842 | } | |
843 | ||
844 | /** | |
845 | * # .throw(constructor) | |
846 | * | |
847 | * Assert that a function will throw a specific type of error or that error | |
848 | * thrown will match a RegExp or include a string. | |
849 | * | |
850 | * var fn = function () { throw new ReferenceError('This is a bad function.'); } | |
851 | * expect(fn).to.throw(ReferenceError); | |
852 | * expect(fn).to.throw(/bad function/); | |
853 | * expect(fn).to.not.throw('good function'); | |
854 | * expect(fn).to.throw(ReferenceError, /bad function/); | |
855 | * | |
856 | * Please note that when a throw expectation is negated, it will check each | |
857 | * parameter independently, starting with Error constructor type. The appropriate way | |
858 | * to check for the existence of a type of error but for a message that does not match | |
859 | * is to use `and`. | |
860 | * | |
861 | * expect(fn).to.throw(ReferenceError).and.not.throw(/good function/); | |
862 | * | |
863 | * @name throw | |
864 | * @alias throws | |
865 | * @alias Throw | |
866 | * @param {ErrorConstructor} constructor | |
867 | * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types | |
868 | * @api public | |
869 | */ | |
870 | ||
871 | 1 | Assertion.prototype.throw = function (constructor, msg) { |
872 | 65 | new Assertion(this.obj).is.a('function'); |
873 | ||
874 | 65 | var thrown = false; |
875 | ||
876 | 65 | if (arguments.length === 0) { |
877 | 11 | msg = null; |
878 | 11 | constructor = null; |
879 | 54 | } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) { |
880 | 11 | msg = constructor; |
881 | 11 | constructor = null; |
882 | } | |
883 | ||
884 | 65 | try { |
885 | 65 | this.obj(); |
886 | } catch (err) { | |
887 | // first, check constructor | |
888 | 52 | if (constructor && 'function' === typeof constructor) { |
889 | 31 | this.assert( |
890 | err instanceof constructor && err.name == constructor.name | |
891 | , 'expected ' + this.inspect + ' to throw ' + constructor.name + ' but a ' + err.name + ' was thrown' | |
892 | , 'expected ' + this.inspect + ' to not throw ' + constructor.name ); | |
893 | 36 | if (!msg) return this; |
894 | } | |
895 | // next, check message | |
896 | 31 | if (err.message && msg && msg instanceof RegExp) { |
897 | 13 | this.assert( |
898 | msg.exec(err.message) | |
899 | , 'expected ' + this.inspect + ' to throw error matching ' + msg + ' but got ' + inspect(err.message) | |
900 | , 'expected ' + this.inspect + ' to throw error not matching ' + msg | |
901 | ); | |
902 | 7 | return this; |
903 | 18 | } else if (err.message && msg && 'string' === typeof msg) { |
904 | 8 | this.assert( |
905 | ~err.message.indexOf(msg) | |
906 | , 'expected ' + this.inspect + ' to throw error including ' + inspect(msg) + ' but got ' + inspect(err.message) | |
907 | , 'expected ' + this.inspect + ' to throw error not including ' + inspect(msg) | |
908 | ); | |
909 | 6 | return this; |
910 | } else { | |
911 | 10 | thrown = true; |
912 | } | |
913 | } | |
914 | ||
915 | 23 | var name = (constructor ? constructor.name : 'an error'); |
916 | ||
917 | 23 | this.assert( |
918 | thrown === true | |
919 | , 'expected ' + this.inspect + ' to throw ' + name | |
920 | , 'expected ' + this.inspect + ' to not throw ' + name); | |
921 | ||
922 | 15 | return this; |
923 | }; | |
924 | ||
925 | /** | |
926 | * # .respondTo(method) | |
927 | * | |
928 | * Assert that object/class will respond to a method. | |
929 | * | |
930 | * expect(Klass).to.respondTo('bar'); | |
931 | * expect(obj).to.respondTo('bar'); | |
932 | * | |
933 | * @name respondTo | |
934 | * @param {String} method | |
935 | * @api public | |
936 | */ | |
937 | ||
938 | 1 | Assertion.prototype.respondTo = function (method) { |
939 | 10 | var context = ('function' === typeof this.obj) |
940 | ? this.obj.prototype[method] | |
941 | : this.obj[method]; | |
942 | ||
943 | 10 | this.assert( |
944 | 'function' === typeof context | |
945 | , 'expected ' + this.inspect + ' to respond to ' + inspect(method) | |
946 | , 'expected ' + this.inspect + ' to not respond to ' + inspect(method) | |
947 | , 'function' | |
948 | , typeof context | |
949 | ); | |
950 | ||
951 | 6 | return this; |
952 | }; | |
953 | ||
954 | /** | |
955 | * # .satisfy(method) | |
956 | * | |
957 | * Assert that passes a truth test. | |
958 | * | |
959 | * expect(1).to.satisfy(function(num) { return num > 0; }); | |
960 | * | |
961 | * @name satisfy | |
962 | * @param {Function} matcher | |
963 | * @api public | |
964 | */ | |
965 | ||
966 | 1 | Assertion.prototype.satisfy = function (matcher) { |
967 | 4 | this.assert( |
968 | matcher(this.obj) | |
969 | , 'expected ' + this.inspect + ' to satisfy ' + inspect(matcher) | |
970 | , 'expected ' + this.inspect + ' to not satisfy' + inspect(matcher) | |
971 | , this.negate ? false : true | |
972 | , matcher(this.obj) | |
973 | ); | |
974 | ||
975 | 2 | return this; |
976 | }; | |
977 | ||
978 | /** | |
979 | * # .closeTo(expected, delta) | |
980 | * | |
981 | * Assert that actual is equal to +/- delta. | |
982 | * | |
983 | * expect(1.5).to.be.closeTo(1, 0.5); | |
984 | * | |
985 | * @name closeTo | |
986 | * @param {Number} expected | |
987 | * @param {Number} delta | |
988 | * @api public | |
989 | */ | |
990 | ||
991 | 1 | Assertion.prototype.closeTo = function (expected, delta) { |
992 | 4 | this.assert( |
993 | (this.obj - delta === expected) || (this.obj + delta === expected) | |
994 | , 'expected ' + this.inspect + ' to be close to ' + expected + ' +/- ' + delta | |
995 | , 'expected ' + this.inspect + ' not to be close to ' + expected + ' +/- ' + delta); | |
996 | ||
997 | 2 | return this; |
998 | }; | |
999 | ||
1000 | /*! | |
1001 | * Aliases. | |
1002 | */ | |
1003 | ||
1004 | 1 | (function alias(name, as){ |
1005 | 8 | Assertion.prototype[as] = Assertion.prototype[name]; |
1006 | 8 | return alias; |
1007 | }) | |
1008 | ('length', 'lengthOf') | |
1009 | ('keys', 'key') | |
1010 | ('ownProperty', 'haveOwnProperty') | |
1011 | ('above', 'greaterThan') | |
1012 | ('below', 'lessThan') | |
1013 | ('throw', 'throws') | |
1014 | ('throw', 'Throw') // for troublesome browsers | |
1015 | ('instanceof', 'instanceOf'); |
Line | Hits | Source |
---|---|---|
1 | /*! | |
2 | * chai | |
3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
4 | * MIT Licensed | |
5 | */ | |
6 | ||
7 | 1 | var fail = require('./chai').fail; |
8 | ||
9 | 1 | module.exports = AssertionError; |
10 | ||
11 | /*! | |
12 | * Inspired by node.js assert module | |
13 | * https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js | |
14 | */ | |
15 | 1 | function AssertionError (options) { |
16 | 168 | options = options || {}; |
17 | 168 | this.name = 'AssertionError'; |
18 | 168 | this.message = options.message; |
19 | 168 | this.actual = options.actual; |
20 | 168 | this.expected = options.expected; |
21 | 168 | this.operator = options.operator; |
22 | 168 | var stackStartFunction = options.stackStartFunction || fail; |
23 | ||
24 | 168 | if (Error.captureStackTrace) { |
25 | 168 | Error.captureStackTrace(this, stackStartFunction); |
26 | } | |
27 | } | |
28 | ||
29 | 1 | AssertionError.prototype.__proto__ = Error.prototype; |
30 | ||
31 | 1 | AssertionError.prototype.toString = function() { |
32 | 2 | return this.message; |
33 | }; |
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 | // This is (almost) directly from Node.js utils | |
2 | // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js | |
3 | ||
4 | 1 | module.exports = inspect; |
5 | ||
6 | /** | |
7 | * Echos the value of a value. Trys to print the value out | |
8 | * in the best way possible given the different types. | |
9 | * | |
10 | * @param {Object} obj The object to print out. | |
11 | * @param {Boolean} showHidden Flag that shows hidden (not enumerable) | |
12 | * properties of objects. | |
13 | * @param {Number} depth Depth in which to descend in object. Default is 2. | |
14 | * @param {Boolean} colors Flag to turn on ANSI escape codes to color the | |
15 | * output. Default is false (no coloring). | |
16 | */ | |
17 | 1 | function inspect(obj, showHidden, depth, colors) { |
18 | 2300 | var ctx = { |
19 | showHidden: showHidden, | |
20 | seen: [], | |
21 | 2692 | stylize: function (str) { return str; } |
22 | }; | |
23 | 2300 | return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); |
24 | } | |
25 | ||
26 | 1 | function formatValue(ctx, value, recurseTimes) { |
27 | // Provide a hook for user-specified inspect functions. | |
28 | // Check that value is an object with an inspect function on it | |
29 | 2730 | if (value && typeof value.inspect === 'function' && |
30 | // Filter out the util module, it's inspect function is special | |
31 | value.inspect !== exports.inspect && | |
32 | // Also filter out any prototype objects using the circular check. | |
33 | !(value.constructor && value.constructor.prototype === value)) { | |
34 | 0 | return value.inspect(recurseTimes); |
35 | } | |
36 | ||
37 | // Primitive types cannot have properties | |
38 | 2730 | var primitive = formatPrimitive(ctx, value); |
39 | 2730 | if (primitive) { |
40 | 2098 | return primitive; |
41 | } | |
42 | ||
43 | // Look up the keys of the object. | |
44 | 632 | var visibleKeys = Object.keys(value); |
45 | 632 | var keys = ctx.showHidden ? Object.getOwnPropertyNames(value) : visibleKeys; |
46 | ||
47 | // Some type of object without properties can be shortcutted. | |
48 | 632 | if (keys.length === 0) { |
49 | 392 | if (typeof value === 'function') { |
50 | 328 | var name = value.name ? ': ' + value.name : ''; |
51 | 328 | return ctx.stylize('[Function' + name + ']', 'special'); |
52 | } | |
53 | 64 | if (isRegExp(value)) { |
54 | 0 | return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
55 | } | |
56 | 64 | if (isDate(value)) { |
57 | 0 | return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); |
58 | } | |
59 | 64 | if (isError(value)) { |
60 | 0 | return formatError(value); |
61 | } | |
62 | } | |
63 | ||
64 | 304 | var base = '', array = false, braces = ['{', '}']; |
65 | ||
66 | // Make Array say that they are Array | |
67 | 304 | if (isArray(value)) { |
68 | 96 | array = true; |
69 | 96 | braces = ['[', ']']; |
70 | } | |
71 | ||
72 | // Make functions say that they are functions | |
73 | 304 | if (typeof value === 'function') { |
74 | 0 | var n = value.name ? ': ' + value.name : ''; |
75 | 0 | base = ' [Function' + n + ']'; |
76 | } | |
77 | ||
78 | // Make RegExps say that they are RegExps | |
79 | 304 | if (isRegExp(value)) { |
80 | 0 | base = ' ' + RegExp.prototype.toString.call(value); |
81 | } | |
82 | ||
83 | // Make dates with properties first say the date | |
84 | 304 | if (isDate(value)) { |
85 | 0 | base = ' ' + Date.prototype.toUTCString.call(value); |
86 | } | |
87 | ||
88 | // Make error with message first say the error | |
89 | 304 | if (isError(value)) { |
90 | 0 | base = ' ' + formatError(value); |
91 | } | |
92 | ||
93 | 304 | if (keys.length === 0 && (!array || value.length == 0)) { |
94 | 64 | return braces[0] + base + braces[1]; |
95 | } | |
96 | ||
97 | 240 | if (recurseTimes < 0) { |
98 | 0 | if (isRegExp(value)) { |
99 | 0 | return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
100 | } else { | |
101 | 0 | return ctx.stylize('[Object]', 'special'); |
102 | } | |
103 | } | |
104 | ||
105 | 240 | ctx.seen.push(value); |
106 | ||
107 | 240 | var output; |
108 | 240 | if (array) { |
109 | 72 | output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); |
110 | } else { | |
111 | 168 | output = keys.map(function(key) { |
112 | 266 | return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); |
113 | }); | |
114 | } | |
115 | ||
116 | 240 | ctx.seen.pop(); |
117 | ||
118 | 240 | return reduceToSingleString(output, base, braces); |
119 | } | |
120 | ||
121 | ||
122 | 1 | function formatPrimitive(ctx, value) { |
123 | 2730 | switch (typeof value) { |
124 | case 'undefined': | |
125 | 36 | return ctx.stylize('undefined', 'undefined'); |
126 | ||
127 | case 'string': | |
128 | 1444 | var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') |
129 | .replace(/'/g, "\\'") | |
130 | .replace(/\\"/g, '"') + '\''; | |
131 | 1444 | return ctx.stylize(simple, 'string'); |
132 | ||
133 | case 'number': | |
134 | 546 | return ctx.stylize('' + value, 'number'); |
135 | ||
136 | case 'boolean': | |
137 | 54 | return ctx.stylize('' + value, 'boolean'); |
138 | } | |
139 | // For some reason typeof null is "object", so special case here. | |
140 | 650 | if (value === null) { |
141 | 18 | return ctx.stylize('null', 'null'); |
142 | } | |
143 | } | |
144 | ||
145 | ||
146 | 1 | function formatError(value) { |
147 | 0 | return '[' + Error.prototype.toString.call(value) + ']'; |
148 | } | |
149 | ||
150 | ||
151 | 1 | function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { |
152 | 72 | var output = []; |
153 | 72 | for (var i = 0, l = value.length; i < l; ++i) { |
154 | 164 | if (Object.prototype.hasOwnProperty.call(value, String(i))) { |
155 | 164 | output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
156 | String(i), true)); | |
157 | } else { | |
158 | 0 | output.push(''); |
159 | } | |
160 | } | |
161 | 72 | keys.forEach(function(key) { |
162 | 164 | if (!key.match(/^\d+$/)) { |
163 | 0 | output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
164 | key, true)); | |
165 | } | |
166 | }); | |
167 | 72 | return output; |
168 | } | |
169 | ||
170 | ||
171 | 1 | function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { |
172 | 430 | var name, str; |
173 | 430 | if (value.__lookupGetter__) { |
174 | 430 | if (value.__lookupGetter__(key)) { |
175 | 0 | if (value.__lookupSetter__(key)) { |
176 | 0 | str = ctx.stylize('[Getter/Setter]', 'special'); |
177 | } else { | |
178 | 0 | str = ctx.stylize('[Getter]', 'special'); |
179 | } | |
180 | } else { | |
181 | 430 | if (value.__lookupSetter__(key)) { |
182 | 0 | str = ctx.stylize('[Setter]', 'special'); |
183 | } | |
184 | } | |
185 | } | |
186 | 430 | if (visibleKeys.indexOf(key) < 0) { |
187 | 0 | name = '[' + key + ']'; |
188 | } | |
189 | 430 | if (!str) { |
190 | 430 | if (ctx.seen.indexOf(value[key]) < 0) { |
191 | 430 | if (recurseTimes === null) { |
192 | 0 | str = formatValue(ctx, value[key], null); |
193 | } else { | |
194 | 430 | str = formatValue(ctx, value[key], recurseTimes - 1); |
195 | } | |
196 | 430 | if (str.indexOf('\n') > -1) { |
197 | 0 | if (array) { |
198 | 0 | str = str.split('\n').map(function(line) { |
199 | 0 | return ' ' + line; |
200 | }).join('\n').substr(2); | |
201 | } else { | |
202 | 0 | str = '\n' + str.split('\n').map(function(line) { |
203 | 0 | return ' ' + line; |
204 | }).join('\n'); | |
205 | } | |
206 | } | |
207 | } else { | |
208 | 0 | str = ctx.stylize('[Circular]', 'special'); |
209 | } | |
210 | } | |
211 | 430 | if (typeof name === 'undefined') { |
212 | 430 | if (array && key.match(/^\d+$/)) { |
213 | 164 | return str; |
214 | } | |
215 | 266 | name = JSON.stringify('' + key); |
216 | 266 | if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { |
217 | 248 | name = name.substr(1, name.length - 2); |
218 | 248 | name = ctx.stylize(name, 'name'); |
219 | } else { | |
220 | 18 | name = name.replace(/'/g, "\\'") |
221 | .replace(/\\"/g, '"') | |
222 | .replace(/(^"|"$)/g, "'"); | |
223 | 18 | name = ctx.stylize(name, 'string'); |
224 | } | |
225 | } | |
226 | ||
227 | 266 | return name + ': ' + str; |
228 | } | |
229 | ||
230 | ||
231 | 1 | function reduceToSingleString(output, base, braces) { |
232 | 240 | var numLinesEst = 0; |
233 | 240 | var length = output.reduce(function(prev, cur) { |
234 | 430 | numLinesEst++; |
235 | 430 | if (cur.indexOf('\n') >= 0) numLinesEst++; |
236 | 430 | return prev + cur.length + 1; |
237 | }, 0); | |
238 | ||
239 | 240 | if (length > 60) { |
240 | 0 | return braces[0] + |
241 | (base === '' ? '' : base + '\n ') + | |
242 | ' ' + | |
243 | output.join(',\n ') + | |
244 | ' ' + | |
245 | braces[1]; | |
246 | } | |
247 | ||
248 | 240 | return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; |
249 | } | |
250 | ||
251 | 1 | function isArray(ar) { |
252 | 304 | return Array.isArray(ar) || |
253 | (typeof ar === 'object' && objectToString(ar) === '[object Array]'); | |
254 | } | |
255 | ||
256 | 1 | function isRegExp(re) { |
257 | 368 | return typeof re === 'object' && objectToString(re) === '[object RegExp]'; |
258 | } | |
259 | ||
260 | 1 | function isDate(d) { |
261 | 368 | return typeof d === 'object' && objectToString(d) === '[object Date]'; |
262 | } | |
263 | ||
264 | 1 | function isError(e) { |
265 | 368 | return typeof e === 'object' && objectToString(e) === '[object Error]'; |
266 | } | |
267 | ||
268 | 1 | function objectToString(o) { |
269 | 1312 | return Object.prototype.toString.call(o); |
270 | } |
Line | Hits | Source |
---|---|---|
1 | /*! | |
2 | * chai | |
3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
4 | * MIT Licensed | |
5 | */ | |
6 | ||
7 | 1 | module.exports = function (chai) { |
8 | 1 | chai.expect = function (val, message) { |
9 | 252 | return new chai.Assertion(val, message); |
10 | }; | |
11 | }; | |
12 |
Line | Hits | Source |
---|---|---|
1 | /*! | |
2 | * chai | |
3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
4 | * MIT Licensed | |
5 | */ | |
6 | ||
7 | 1 | module.exports = function (chai) { |
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 | 175 | if (this instanceof String || this instanceof Number) { |
16 | 1 | return new Assertion(this.constructor(this)); |
17 | 174 | } else if (this instanceof Boolean) { |
18 | 0 | return new Assertion(this == true); |
19 | } | |
20 | 174 | return new Assertion(this); |
21 | }, | |
22 | configurable: true | |
23 | }); | |
24 | ||
25 | 1 | var should = {}; |
26 | ||
27 | 1 | should.equal = function (val1, val2) { |
28 | 70 | new Assertion(val1).to.equal(val2); |
29 | }; | |
30 | ||
31 | 1 | should.throw = function (fn, errt, errs) { |
32 | 4 | 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 | 2 | 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 | return should; |
55 | }; | |
56 | }; |
Line | Hits | Source |
---|---|---|
1 | /*! | |
2 | * chai | |
3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
4 | * MIT Licensed | |
5 | */ | |
6 | ||
7 | /** | |
8 | * ### TDD Style Introduction | |
9 | * | |
10 | * The TDD style is exposed through `assert` interfaces. This provides | |
11 | * the classic assert.`test` notation, similiar to that packaged with | |
12 | * node.js. This assert module, however, provides several additional | |
13 | * tests and is browser compatible. | |
14 | * | |
15 | * // assert | |
16 | * var assert = require('chai').assert; | |
17 | * , foo = 'bar'; | |
18 | * | |
19 | * assert.typeOf(foo, 'string'); | |
20 | * assert.equal(foo, 'bar'); | |
21 | * | |
22 | * #### Configuration | |
23 | * | |
24 | * By default, Chai does not show stack traces upon an AssertionError. This can | |
25 | * be changed by modifying the `includeStack` parameter for chai.Assertion. For example: | |
26 | * | |
27 | * var chai = require('chai'); | |
28 | * chai.Assertion.includeStack = true; // defaults to false | |
29 | */ | |
30 | ||
31 | 1 | module.exports = function (chai) { |
32 | /*! | |
33 | * Chai dependencies. | |
34 | */ | |
35 | 1 | var Assertion = chai.Assertion |
36 | , inspect = chai.inspect; | |
37 | ||
38 | /*! | |
39 | * Module export. | |
40 | */ | |
41 | ||
42 | 1 | var assert = chai.assert = {}; |
43 | ||
44 | /** | |
45 | * # .fail(actual, expect, msg, operator) | |
46 | * | |
47 | * Throw a failure. Node.js compatible. | |
48 | * | |
49 | * @name fail | |
50 | * @param {*} actual value | |
51 | * @param {*} expected value | |
52 | * @param {String} message | |
53 | * @param {String} operator | |
54 | * @api public | |
55 | */ | |
56 | ||
57 | 1 | assert.fail = function (actual, expected, message, operator) { |
58 | 1 | throw new chai.AssertionError({ |
59 | actual: actual | |
60 | , expected: expected | |
61 | , message: message | |
62 | , operator: operator | |
63 | , stackStartFunction: assert.fail | |
64 | }); | |
65 | } | |
66 | ||
67 | /** | |
68 | * # .ok(object, [message]) | |
69 | * | |
70 | * Assert object is truthy. | |
71 | * | |
72 | * assert.ok('everthing', 'everything is ok'); | |
73 | * assert.ok(false, 'this will fail'); | |
74 | * | |
75 | * @name ok | |
76 | * @param {*} object to test | |
77 | * @param {String} message | |
78 | * @api public | |
79 | */ | |
80 | ||
81 | 1 | assert.ok = function (val, msg) { |
82 | 7 | new Assertion(val, msg).is.ok; |
83 | }; | |
84 | ||
85 | /** | |
86 | * # .equal(actual, expected, [message]) | |
87 | * | |
88 | * Assert strict equality. | |
89 | * | |
90 | * assert.equal(3, 3, 'these numbers are equal'); | |
91 | * | |
92 | * @name equal | |
93 | * @param {*} actual | |
94 | * @param {*} expected | |
95 | * @param {String} message | |
96 | * @api public | |
97 | */ | |
98 | ||
99 | 1 | assert.equal = function (act, exp, msg) { |
100 | 44 | var test = new Assertion(act, msg); |
101 | ||
102 | 44 | test.assert( |
103 | exp == test.obj | |
104 | , 'expected ' + test.inspect + ' to equal ' + inspect(exp) | |
105 | , 'expected ' + test.inspect + ' to not equal ' + inspect(exp)); | |
106 | }; | |
107 | ||
108 | /** | |
109 | * # .notEqual(actual, expected, [message]) | |
110 | * | |
111 | * Assert not equal. | |
112 | * | |
113 | * assert.notEqual(3, 4, 'these numbers are not equal'); | |
114 | * | |
115 | * @name notEqual | |
116 | * @param {*} actual | |
117 | * @param {*} expected | |
118 | * @param {String} message | |
119 | * @api public | |
120 | */ | |
121 | ||
122 | 1 | assert.notEqual = function (act, exp, msg) { |
123 | 2 | var test = new Assertion(act, msg); |
124 | ||
125 | 2 | test.assert( |
126 | exp != test.obj | |
127 | , 'expected ' + test.inspect + ' to equal ' + inspect(exp) | |
128 | , 'expected ' + test.inspect + ' to not equal ' + inspect(exp)); | |
129 | }; | |
130 | ||
131 | /** | |
132 | * # .strictEqual(actual, expected, [message]) | |
133 | * | |
134 | * Assert strict equality. | |
135 | * | |
136 | * assert.strictEqual(true, true, 'these booleans are strictly equal'); | |
137 | * | |
138 | * @name strictEqual | |
139 | * @param {*} actual | |
140 | * @param {*} expected | |
141 | * @param {String} message | |
142 | * @api public | |
143 | */ | |
144 | ||
145 | 1 | assert.strictEqual = function (act, exp, msg) { |
146 | 2 | new Assertion(act, msg).to.equal(exp); |
147 | }; | |
148 | ||
149 | /** | |
150 | * # .notStrictEqual(actual, expected, [message]) | |
151 | * | |
152 | * Assert strict equality. | |
153 | * | |
154 | * assert.notStrictEqual(1, true, 'these booleans are not strictly equal'); | |
155 | * | |
156 | * @name notStrictEqual | |
157 | * @param {*} actual | |
158 | * @param {*} expected | |
159 | * @param {String} message | |
160 | * @api public | |
161 | */ | |
162 | ||
163 | 1 | assert.notStrictEqual = function (act, exp, msg) { |
164 | 2 | new Assertion(act, msg).to.not.equal(exp); |
165 | }; | |
166 | ||
167 | /** | |
168 | * # .deepEqual(actual, expected, [message]) | |
169 | * | |
170 | * Assert not deep equality. | |
171 | * | |
172 | * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); | |
173 | * | |
174 | * @name deepEqual | |
175 | * @param {*} actual | |
176 | * @param {*} expected | |
177 | * @param {String} message | |
178 | * @api public | |
179 | */ | |
180 | ||
181 | 1 | assert.deepEqual = function (act, exp, msg) { |
182 | 2 | new Assertion(act, msg).to.eql(exp); |
183 | }; | |
184 | ||
185 | /** | |
186 | * # .notDeepEqual(actual, expected, [message]) | |
187 | * | |
188 | * Assert not deep equality. | |
189 | * | |
190 | * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); | |
191 | * | |
192 | * @name notDeepEqual | |
193 | * @param {*} actual | |
194 | * @param {*} expected | |
195 | * @param {String} message | |
196 | * @api public | |
197 | */ | |
198 | ||
199 | 1 | assert.notDeepEqual = function (act, exp, msg) { |
200 | 2 | new Assertion(act, msg).to.not.eql(exp); |
201 | }; | |
202 | ||
203 | /** | |
204 | * # .isTrue(value, [message]) | |
205 | * | |
206 | * Assert `value` is true. | |
207 | * | |
208 | * var tea_served = true; | |
209 | * assert.isTrue(tea_served, 'the tea has been served'); | |
210 | * | |
211 | * @name isTrue | |
212 | * @param {Boolean} value | |
213 | * @param {String} message | |
214 | * @api public | |
215 | */ | |
216 | ||
217 | 1 | assert.isTrue = function (val, msg) { |
218 | 4 | new Assertion(val, msg).is.true; |
219 | }; | |
220 | ||
221 | /** | |
222 | * # .isFalse(value, [message]) | |
223 | * | |
224 | * Assert `value` is false. | |
225 | * | |
226 | * var tea_served = false; | |
227 | * assert.isFalse(tea_served, 'no tea yet? hmm...'); | |
228 | * | |
229 | * @name isFalse | |
230 | * @param {Boolean} value | |
231 | * @param {String} message | |
232 | * @api public | |
233 | */ | |
234 | ||
235 | 1 | assert.isFalse = function (val, msg) { |
236 | 3 | new Assertion(val, msg).is.false; |
237 | }; | |
238 | ||
239 | /** | |
240 | * # .isNull(value, [message]) | |
241 | * | |
242 | * Assert `value` is null. | |
243 | * | |
244 | * assert.isNull(err, 'no errors'); | |
245 | * | |
246 | * @name isNull | |
247 | * @param {*} value | |
248 | * @param {String} message | |
249 | * @api public | |
250 | */ | |
251 | ||
252 | 1 | assert.isNull = function (val, msg) { |
253 | 2 | new Assertion(val, msg).to.equal(null); |
254 | }; | |
255 | ||
256 | /** | |
257 | * # .isNotNull(value, [message]) | |
258 | * | |
259 | * Assert `value` is not null. | |
260 | * | |
261 | * var tea = 'tasty chai'; | |
262 | * assert.isNotNull(tea, 'great, time for tea!'); | |
263 | * | |
264 | * @name isNotNull | |
265 | * @param {*} value | |
266 | * @param {String} message | |
267 | * @api public | |
268 | */ | |
269 | ||
270 | 1 | assert.isNotNull = function (val, msg) { |
271 | 2 | new Assertion(val, msg).to.not.equal(null); |
272 | }; | |
273 | ||
274 | /** | |
275 | * # .isUndefined(value, [message]) | |
276 | * | |
277 | * Assert `value` is undefined. | |
278 | * | |
279 | * assert.isUndefined(tea, 'no tea defined'); | |
280 | * | |
281 | * @name isUndefined | |
282 | * @param {*} value | |
283 | * @param {String} message | |
284 | * @api public | |
285 | */ | |
286 | ||
287 | 1 | assert.isUndefined = function (val, msg) { |
288 | 2 | new Assertion(val, msg).to.equal(undefined); |
289 | }; | |
290 | ||
291 | /** | |
292 | * # .isDefined(value, [message]) | |
293 | * | |
294 | * Assert `value` is not undefined. | |
295 | * | |
296 | * var tea = 'cup of chai'; | |
297 | * assert.isDefined(tea, 'no tea defined'); | |
298 | * | |
299 | * @name isUndefined | |
300 | * @param {*} value | |
301 | * @param {String} message | |
302 | * @api public | |
303 | */ | |
304 | ||
305 | 1 | assert.isDefined = function (val, msg) { |
306 | 2 | new Assertion(val, msg).to.not.equal(undefined); |
307 | }; | |
308 | ||
309 | /** | |
310 | * # .isFunction(value, [message]) | |
311 | * | |
312 | * Assert `value` is a function. | |
313 | * | |
314 | * var serve_tea = function () { return 'cup of tea'; }; | |
315 | * assert.isFunction(serve_tea, 'great, we can have tea now'); | |
316 | * | |
317 | * @name isFunction | |
318 | * @param {Function} value | |
319 | * @param {String} message | |
320 | * @api public | |
321 | */ | |
322 | ||
323 | 1 | assert.isFunction = function (val, msg) { |
324 | 2 | new Assertion(val, msg).to.be.a('function'); |
325 | }; | |
326 | ||
327 | /** | |
328 | * # .isObject(value, [message]) | |
329 | * | |
330 | * Assert `value` is an object. | |
331 | * | |
332 | * var selection = { name: 'Chai', serve: 'with spices' }; | |
333 | * assert.isObject(selection, 'tea selection is an object'); | |
334 | * | |
335 | * @name isObject | |
336 | * @param {Object} value | |
337 | * @param {String} message | |
338 | * @api public | |
339 | */ | |
340 | ||
341 | 1 | assert.isObject = function (val, msg) { |
342 | 5 | new Assertion(val, msg).to.be.a('object'); |
343 | }; | |
344 | ||
345 | /** | |
346 | * # .isArray(value, [message]) | |
347 | * | |
348 | * Assert `value` is an instance of Array. | |
349 | * | |
350 | * var menu = [ 'green', 'chai', 'oolong' ]; | |
351 | * assert.isArray(menu, 'what kind of tea do we want?'); | |
352 | * | |
353 | * @name isArray | |
354 | * @param {*} value | |
355 | * @param {String} message | |
356 | * @api public | |
357 | */ | |
358 | ||
359 | 1 | assert.isArray = function (val, msg) { |
360 | 3 | new Assertion(val, msg).to.be.instanceof(Array); |
361 | }; | |
362 | ||
363 | /** | |
364 | * # .isString(value, [message]) | |
365 | * | |
366 | * Assert `value` is a string. | |
367 | * | |
368 | * var teaorder = 'chai'; | |
369 | * assert.isString(tea_order, 'order placed'); | |
370 | * | |
371 | * @name isString | |
372 | * @param {String} value | |
373 | * @param {String} message | |
374 | * @api public | |
375 | */ | |
376 | ||
377 | 1 | assert.isString = function (val, msg) { |
378 | 3 | new Assertion(val, msg).to.be.a('string'); |
379 | }; | |
380 | ||
381 | /** | |
382 | * # .isNumber(value, [message]) | |
383 | * | |
384 | * Assert `value` is a number | |
385 | * | |
386 | * var cups = 2; | |
387 | * assert.isNumber(cups, 'how many cups'); | |
388 | * | |
389 | * @name isNumber | |
390 | * @param {Number} value | |
391 | * @param {String} message | |
392 | * @api public | |
393 | */ | |
394 | ||
395 | 1 | assert.isNumber = function (val, msg) { |
396 | 3 | new Assertion(val, msg).to.be.a('number'); |
397 | }; | |
398 | ||
399 | /** | |
400 | * # .isBoolean(value, [message]) | |
401 | * | |
402 | * Assert `value` is a boolean | |
403 | * | |
404 | * var teaready = true | |
405 | * , teaserved = false; | |
406 | * | |
407 | * assert.isBoolean(tea_ready, 'is the tea ready'); | |
408 | * assert.isBoolean(tea_served, 'has tea been served'); | |
409 | * | |
410 | * @name isBoolean | |
411 | * @param {*} value | |
412 | * @param {String} message | |
413 | * @api public | |
414 | */ | |
415 | ||
416 | 1 | assert.isBoolean = function (val, msg) { |
417 | 3 | new Assertion(val, msg).to.be.a('boolean'); |
418 | }; | |
419 | ||
420 | /** | |
421 | * # .typeOf(value, name, [message]) | |
422 | * | |
423 | * Assert typeof `value` is `name`. | |
424 | * | |
425 | * assert.typeOf('tea', 'string', 'we have a string'); | |
426 | * | |
427 | * @name typeOf | |
428 | * @param {*} value | |
429 | * @param {String} typeof name | |
430 | * @param {String} message | |
431 | * @api public | |
432 | */ | |
433 | ||
434 | 1 | assert.typeOf = function (val, type, msg) { |
435 | 4 | new Assertion(val, msg).to.be.a(type); |
436 | }; | |
437 | ||
438 | /** | |
439 | * # .instanceOf(object, constructor, [message]) | |
440 | * | |
441 | * Assert `value` is instanceof `constructor`. | |
442 | * | |
443 | * var Tea = function (name) { this.name = name; } | |
444 | * , Chai = new Tea('chai'); | |
445 | * | |
446 | * assert.instanceOf(Chai, Tea, 'chai is an instance of tea'); | |
447 | * | |
448 | * @name instanceOf | |
449 | * @param {Object} object | |
450 | * @param {Constructor} constructor | |
451 | * @param {String} message | |
452 | * @api public | |
453 | */ | |
454 | ||
455 | 1 | assert.instanceOf = function (val, type, msg) { |
456 | 2 | new Assertion(val, msg).to.be.instanceof(type); |
457 | }; | |
458 | ||
459 | /** | |
460 | * # .include(value, includes, [message]) | |
461 | * | |
462 | * Assert the inclusion of an object in another. Works | |
463 | * for strings and arrays. | |
464 | * | |
465 | * assert.include('foobar', 'bar', 'foobar contains string `var`); | |
466 | * assert.include([ 1, 2, 3], 3, 'array contains value); | |
467 | * | |
468 | * @name include | |
469 | * @param {Array|String} value | |
470 | * @param {*} includes | |
471 | * @param {String} message | |
472 | * @api public | |
473 | */ | |
474 | ||
475 | 1 | assert.include = function (exp, inc, msg) { |
476 | 4 | var obj = new Assertion(exp, msg); |
477 | ||
478 | 4 | if (Array.isArray(exp)) { |
479 | 1 | obj.to.include(inc); |
480 | 3 | } else if ('string' === typeof exp) { |
481 | 3 | obj.to.contain.string(inc); |
482 | } | |
483 | }; | |
484 | ||
485 | /** | |
486 | * # .match(value, regex, [message]) | |
487 | * | |
488 | * Assert that `value` matches regular expression. | |
489 | * | |
490 | * assert.match('foobar', /^foo/, 'Regexp matches'); | |
491 | * | |
492 | * @name match | |
493 | * @param {*} value | |
494 | * @param {RegExp} RegularExpression | |
495 | * @param {String} message | |
496 | * @api public | |
497 | */ | |
498 | ||
499 | 1 | assert.match = function (exp, re, msg) { |
500 | 1 | new Assertion(exp, msg).to.match(re); |
501 | }; | |
502 | ||
503 | /** | |
504 | * # .length(value, constructor, [message]) | |
505 | * | |
506 | * Assert that object has expected length. | |
507 | * | |
508 | * assert.length([1,2,3], 3, 'Array has length of 3'); | |
509 | * assert.length('foobar', 5, 'String has length of 6'); | |
510 | * | |
511 | * @name length | |
512 | * @param {*} value | |
513 | * @param {Number} length | |
514 | * @param {String} message | |
515 | * @api public | |
516 | */ | |
517 | ||
518 | 1 | assert.length = function (exp, len, msg) { |
519 | 4 | new Assertion(exp, msg).to.have.length(len); |
520 | }; | |
521 | ||
522 | /** | |
523 | * # .throws(function, [constructor/regexp], [message]) | |
524 | * | |
525 | * Assert that a function will throw a specific | |
526 | * type of error. | |
527 | * | |
528 | * assert.throw(fn, ReferenceError, 'function throw reference error'); | |
529 | * | |
530 | * @name throws | |
531 | * @alias throw | |
532 | * @param {Function} function to test | |
533 | * @param {ErrorConstructor} constructor | |
534 | * @param {String} message | |
535 | * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types | |
536 | * @api public | |
537 | */ | |
538 | ||
539 | 1 | assert.throws = function (fn, type, msg) { |
540 | 3 | if ('string' === typeof type) { |
541 | 1 | msg = type; |
542 | 1 | type = null; |
543 | } | |
544 | ||
545 | 3 | new Assertion(fn, msg).to.throw(type); |
546 | }; | |
547 | ||
548 | /** | |
549 | * # .doesNotThrow(function, [constructor/regexp], [message]) | |
550 | * | |
551 | * Assert that a function will throw a specific | |
552 | * type of error. | |
553 | * | |
554 | * var fn = function (err) { if (err) throw Error(err) }; | |
555 | * assert.doesNotThrow(fn, Error, 'function throw reference error'); | |
556 | * | |
557 | * @name doesNotThrow | |
558 | * @param {Function} function to test | |
559 | * @param {ErrorConstructor} constructor | |
560 | * @param {String} message | |
561 | * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types | |
562 | * @api public | |
563 | */ | |
564 | ||
565 | 1 | assert.doesNotThrow = function (fn, type, msg) { |
566 | 3 | if ('string' === typeof type) { |
567 | 1 | msg = type; |
568 | 1 | type = null; |
569 | } | |
570 | ||
571 | 3 | new Assertion(fn, msg).to.not.throw(type); |
572 | }; | |
573 | ||
574 | /** | |
575 | * # .operator(val, operator, val2, [message]) | |
576 | * | |
577 | * Compare two values using operator. | |
578 | * | |
579 | * assert.operator(1, '<', 2, 'everything is ok'); | |
580 | * assert.operator(1, '>', 2, 'this will fail'); | |
581 | * | |
582 | * @name operator | |
583 | * @param {*} object to test | |
584 | * @param {String} operator | |
585 | * @param {*} second object | |
586 | * @param {String} message | |
587 | * @api public | |
588 | */ | |
589 | ||
590 | 1 | assert.operator = function (val, operator, val2, msg) { |
591 | 15 | if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) { |
592 | 1 | throw new Error('Invalid operator "' + operator + '"'); |
593 | } | |
594 | 14 | var test = new Assertion(eval(val + operator + val2), msg); |
595 | 14 | test.assert( |
596 | true === test.obj | |
597 | , 'expected ' + inspect(val) + ' to be ' + operator + ' ' + inspect(val2) | |
598 | , 'expected ' + inspect(val) + ' to not be ' + operator + ' ' + inspect(val2) ); | |
599 | }; | |
600 | ||
601 | /*! | |
602 | * Undocumented / untested | |
603 | */ | |
604 | ||
605 | 1 | assert.ifError = function (val, msg) { |
606 | 4 | new Assertion(val, msg).to.not.be.ok; |
607 | }; | |
608 | ||
609 | /*! | |
610 | * Aliases. | |
611 | */ | |
612 | ||
613 | 1 | (function alias(name, as){ |
614 | 2 | assert[as] = assert[name]; |
615 | 2 | return alias; |
616 | }) | |
617 | ('length', 'lengthOf') | |
618 | ('throws', 'throw'); | |
619 | }; |