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