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