Skip to main content

max / quasi

351.4 KB · 11301 lines History Blame Raw
1 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2 module.exports = require('./lib/chai');
3
4 },{"./lib/chai":2}],2:[function(require,module,exports){
5 /*!
6 * chai
7 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
8 * MIT Licensed
9 */
10
11 var used = [];
12
13 /*!
14 * Chai version
15 */
16
17 exports.version = '4.3.8';
18
19 /*!
20 * Assertion Error
21 */
22
23 exports.AssertionError = require('assertion-error');
24
25 /*!
26 * Utils for plugins (not exported)
27 */
28
29 var util = require('./chai/utils');
30
31 /**
32 * # .use(function)
33 *
34 * Provides a way to extend the internals of Chai.
35 *
36 * @param {Function}
37 * @returns {this} for chaining
38 * @api public
39 */
40
41 exports.use = function (fn) {
42 if (!~used.indexOf(fn)) {
43 fn(exports, util);
44 used.push(fn);
45 }
46
47 return exports;
48 };
49
50 /*!
51 * Utility Functions
52 */
53
54 exports.util = util;
55
56 /*!
57 * Configuration
58 */
59
60 var config = require('./chai/config');
61 exports.config = config;
62
63 /*!
64 * Primary `Assertion` prototype
65 */
66
67 var assertion = require('./chai/assertion');
68 exports.use(assertion);
69
70 /*!
71 * Core Assertions
72 */
73
74 var core = require('./chai/core/assertions');
75 exports.use(core);
76
77 /*!
78 * Expect interface
79 */
80
81 var expect = require('./chai/interface/expect');
82 exports.use(expect);
83
84 /*!
85 * Should interface
86 */
87
88 var should = require('./chai/interface/should');
89 exports.use(should);
90
91 /*!
92 * Assert interface
93 */
94
95 var assert = require('./chai/interface/assert');
96 exports.use(assert);
97
98 },{"./chai/assertion":3,"./chai/config":4,"./chai/core/assertions":5,"./chai/interface/assert":6,"./chai/interface/expect":7,"./chai/interface/should":8,"./chai/utils":22,"assertion-error":33}],3:[function(require,module,exports){
99 /*!
100 * chai
101 * http://chaijs.com
102 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
103 * MIT Licensed
104 */
105
106 var config = require('./config');
107
108 module.exports = function (_chai, util) {
109 /*!
110 * Module dependencies.
111 */
112
113 var AssertionError = _chai.AssertionError
114 , flag = util.flag;
115
116 /*!
117 * Module export.
118 */
119
120 _chai.Assertion = Assertion;
121
122 /*!
123 * Assertion Constructor
124 *
125 * Creates object for chaining.
126 *
127 * `Assertion` objects contain metadata in the form of flags. Three flags can
128 * be assigned during instantiation by passing arguments to this constructor:
129 *
130 * - `object`: This flag contains the target of the assertion. For example, in
131 * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will
132 * contain `numKittens` so that the `equal` assertion can reference it when
133 * needed.
134 *
135 * - `message`: This flag contains an optional custom error message to be
136 * prepended to the error message that's generated by the assertion when it
137 * fails.
138 *
139 * - `ssfi`: This flag stands for "start stack function indicator". It
140 * contains a function reference that serves as the starting point for
141 * removing frames from the stack trace of the error that's created by the
142 * assertion when it fails. The goal is to provide a cleaner stack trace to
143 * end users by removing Chai's internal functions. Note that it only works
144 * in environments that support `Error.captureStackTrace`, and only when
145 * `Chai.config.includeStack` hasn't been set to `false`.
146 *
147 * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag
148 * should retain its current value, even as assertions are chained off of
149 * this object. This is usually set to `true` when creating a new assertion
150 * from within another assertion. It's also temporarily set to `true` before
151 * an overwritten assertion gets called by the overwriting assertion.
152 *
153 * - `eql`: This flag contains the deepEqual function to be used by the assertion.
154 *
155 * @param {Mixed} obj target of the assertion
156 * @param {String} msg (optional) custom error message
157 * @param {Function} ssfi (optional) starting point for removing stack frames
158 * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked
159 * @api private
160 */
161
162 function Assertion (obj, msg, ssfi, lockSsfi) {
163 flag(this, 'ssfi', ssfi || Assertion);
164 flag(this, 'lockSsfi', lockSsfi);
165 flag(this, 'object', obj);
166 flag(this, 'message', msg);
167 flag(this, 'eql', config.deepEqual || util.eql);
168
169 return util.proxify(this);
170 }
171
172 Object.defineProperty(Assertion, 'includeStack', {
173 get: function() {
174 console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
175 return config.includeStack;
176 },
177 set: function(value) {
178 console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
179 config.includeStack = value;
180 }
181 });
182
183 Object.defineProperty(Assertion, 'showDiff', {
184 get: function() {
185 console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
186 return config.showDiff;
187 },
188 set: function(value) {
189 console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
190 config.showDiff = value;
191 }
192 });
193
194 Assertion.addProperty = function (name, fn) {
195 util.addProperty(this.prototype, name, fn);
196 };
197
198 Assertion.addMethod = function (name, fn) {
199 util.addMethod(this.prototype, name, fn);
200 };
201
202 Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
203 util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
204 };
205
206 Assertion.overwriteProperty = function (name, fn) {
207 util.overwriteProperty(this.prototype, name, fn);
208 };
209
210 Assertion.overwriteMethod = function (name, fn) {
211 util.overwriteMethod(this.prototype, name, fn);
212 };
213
214 Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {
215 util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
216 };
217
218 /**
219 * ### .assert(expression, message, negateMessage, expected, actual, showDiff)
220 *
221 * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
222 *
223 * @name assert
224 * @param {Philosophical} expression to be tested
225 * @param {String|Function} message or function that returns message to display if expression fails
226 * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails
227 * @param {Mixed} expected value (remember to check for negation)
228 * @param {Mixed} actual (optional) will default to `this.obj`
229 * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails
230 * @api private
231 */
232
233 Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
234 var ok = util.test(this, arguments);
235 if (false !== showDiff) showDiff = true;
236 if (undefined === expected && undefined === _actual) showDiff = false;
237 if (true !== config.showDiff) showDiff = false;
238
239 if (!ok) {
240 msg = util.getMessage(this, arguments);
241 var actual = util.getActual(this, arguments);
242 var assertionErrorObjectProperties = {
243 actual: actual
244 , expected: expected
245 , showDiff: showDiff
246 };
247
248 var operator = util.getOperator(this, arguments);
249 if (operator) {
250 assertionErrorObjectProperties.operator = operator;
251 }
252
253 throw new AssertionError(
254 msg,
255 assertionErrorObjectProperties,
256 (config.includeStack) ? this.assert : flag(this, 'ssfi'));
257 }
258 };
259
260 /*!
261 * ### ._obj
262 *
263 * Quick reference to stored `actual` value for plugin developers.
264 *
265 * @api private
266 */
267
268 Object.defineProperty(Assertion.prototype, '_obj',
269 { get: function () {
270 return flag(this, 'object');
271 }
272 , set: function (val) {
273 flag(this, 'object', val);
274 }
275 });
276 };
277
278 },{"./config":4}],4:[function(require,module,exports){
279 module.exports = {
280
281 /**
282 * ### config.includeStack
283 *
284 * User configurable property, influences whether stack trace
285 * is included in Assertion error message. Default of false
286 * suppresses stack trace in the error message.
287 *
288 * chai.config.includeStack = true; // enable stack on error
289 *
290 * @param {Boolean}
291 * @api public
292 */
293
294 includeStack: false,
295
296 /**
297 * ### config.showDiff
298 *
299 * User configurable property, influences whether or not
300 * the `showDiff` flag should be included in the thrown
301 * AssertionErrors. `false` will always be `false`; `true`
302 * will be true when the assertion has requested a diff
303 * be shown.
304 *
305 * @param {Boolean}
306 * @api public
307 */
308
309 showDiff: true,
310
311 /**
312 * ### config.truncateThreshold
313 *
314 * User configurable property, sets length threshold for actual and
315 * expected values in assertion errors. If this threshold is exceeded, for
316 * example for large data structures, the value is replaced with something
317 * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.
318 *
319 * Set it to zero if you want to disable truncating altogether.
320 *
321 * This is especially userful when doing assertions on arrays: having this
322 * set to a reasonable large value makes the failure messages readily
323 * inspectable.
324 *
325 * chai.config.truncateThreshold = 0; // disable truncating
326 *
327 * @param {Number}
328 * @api public
329 */
330
331 truncateThreshold: 40,
332
333 /**
334 * ### config.useProxy
335 *
336 * User configurable property, defines if chai will use a Proxy to throw
337 * an error when a non-existent property is read, which protects users
338 * from typos when using property-based assertions.
339 *
340 * Set it to false if you want to disable this feature.
341 *
342 * chai.config.useProxy = false; // disable use of Proxy
343 *
344 * This feature is automatically disabled regardless of this config value
345 * in environments that don't support proxies.
346 *
347 * @param {Boolean}
348 * @api public
349 */
350
351 useProxy: true,
352
353 /**
354 * ### config.proxyExcludedKeys
355 *
356 * User configurable property, defines which properties should be ignored
357 * instead of throwing an error if they do not exist on the assertion.
358 * This is only applied if the environment Chai is running in supports proxies and
359 * if the `useProxy` configuration setting is enabled.
360 * By default, `then` and `inspect` will not throw an error if they do not exist on the
361 * assertion object because the `.inspect` property is read by `util.inspect` (for example, when
362 * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking.
363 *
364 * // By default these keys will not throw an error if they do not exist on the assertion object
365 * chai.config.proxyExcludedKeys = ['then', 'inspect'];
366 *
367 * @param {Array}
368 * @api public
369 */
370
371 proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON'],
372
373 /**
374 * ### config.deepEqual
375 *
376 * User configurable property, defines which a custom function to use for deepEqual
377 * comparisons.
378 * By default, the function used is the one from the `deep-eql` package without custom comparator.
379 *
380 * // use a custom comparator
381 * chai.config.deepEqual = (expected, actual) => {
382 * return chai.util.eql(expected, actual, {
383 * comparator: (expected, actual) => {
384 * // for non number comparison, use the default behavior
385 * if(typeof expected !== 'number') return null;
386 * // allow a difference of 10 between compared numbers
387 * return typeof actual === 'number' && Math.abs(actual - expected) < 10
388 * }
389 * })
390 * };
391 *
392 * @param {Function}
393 * @api public
394 */
395
396 deepEqual: null
397
398 };
399
400 },{}],5:[function(require,module,exports){
401 /*!
402 * chai
403 * http://chaijs.com
404 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
405 * MIT Licensed
406 */
407
408 module.exports = function (chai, _) {
409 var Assertion = chai.Assertion
410 , AssertionError = chai.AssertionError
411 , flag = _.flag;
412
413 /**
414 * ### Language Chains
415 *
416 * The following are provided as chainable getters to improve the readability
417 * of your assertions.
418 *
419 * **Chains**
420 *
421 * - to
422 * - be
423 * - been
424 * - is
425 * - that
426 * - which
427 * - and
428 * - has
429 * - have
430 * - with
431 * - at
432 * - of
433 * - same
434 * - but
435 * - does
436 * - still
437 * - also
438 *
439 * @name language chains
440 * @namespace BDD
441 * @api public
442 */
443
444 [ 'to', 'be', 'been', 'is'
445 , 'and', 'has', 'have', 'with'
446 , 'that', 'which', 'at', 'of'
447 , 'same', 'but', 'does', 'still', "also" ].forEach(function (chain) {
448 Assertion.addProperty(chain);
449 });
450
451 /**
452 * ### .not
453 *
454 * Negates all assertions that follow in the chain.
455 *
456 * expect(function () {}).to.not.throw();
457 * expect({a: 1}).to.not.have.property('b');
458 * expect([1, 2]).to.be.an('array').that.does.not.include(3);
459 *
460 * Just because you can negate any assertion with `.not` doesn't mean you
461 * should. With great power comes great responsibility. It's often best to
462 * assert that the one expected output was produced, rather than asserting
463 * that one of countless unexpected outputs wasn't produced. See individual
464 * assertions for specific guidance.
465 *
466 * expect(2).to.equal(2); // Recommended
467 * expect(2).to.not.equal(1); // Not recommended
468 *
469 * @name not
470 * @namespace BDD
471 * @api public
472 */
473
474 Assertion.addProperty('not', function () {
475 flag(this, 'negate', true);
476 });
477
478 /**
479 * ### .deep
480 *
481 * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property`
482 * assertions that follow in the chain to use deep equality instead of strict
483 * (`===`) equality. See the `deep-eql` project page for info on the deep
484 * equality algorithm: https://github.com/chaijs/deep-eql.
485 *
486 * // Target object deeply (but not strictly) equals `{a: 1}`
487 * expect({a: 1}).to.deep.equal({a: 1});
488 * expect({a: 1}).to.not.equal({a: 1});
489 *
490 * // Target array deeply (but not strictly) includes `{a: 1}`
491 * expect([{a: 1}]).to.deep.include({a: 1});
492 * expect([{a: 1}]).to.not.include({a: 1});
493 *
494 * // Target object deeply (but not strictly) includes `x: {a: 1}`
495 * expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
496 * expect({x: {a: 1}}).to.not.include({x: {a: 1}});
497 *
498 * // Target array deeply (but not strictly) has member `{a: 1}`
499 * expect([{a: 1}]).to.have.deep.members([{a: 1}]);
500 * expect([{a: 1}]).to.not.have.members([{a: 1}]);
501 *
502 * // Target set deeply (but not strictly) has key `{a: 1}`
503 * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]);
504 * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]);
505 *
506 * // Target object deeply (but not strictly) has property `x: {a: 1}`
507 * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});
508 * expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
509 *
510 * @name deep
511 * @namespace BDD
512 * @api public
513 */
514
515 Assertion.addProperty('deep', function () {
516 flag(this, 'deep', true);
517 });
518
519 /**
520 * ### .nested
521 *
522 * Enables dot- and bracket-notation in all `.property` and `.include`
523 * assertions that follow in the chain.
524 *
525 * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
526 * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
527 *
528 * If `.` or `[]` are part of an actual property name, they can be escaped by
529 * adding two backslashes before them.
530 *
531 * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
532 * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'});
533 *
534 * `.nested` cannot be combined with `.own`.
535 *
536 * @name nested
537 * @namespace BDD
538 * @api public
539 */
540
541 Assertion.addProperty('nested', function () {
542 flag(this, 'nested', true);
543 });
544
545 /**
546 * ### .own
547 *
548 * Causes all `.property` and `.include` assertions that follow in the chain
549 * to ignore inherited properties.
550 *
551 * Object.prototype.b = 2;
552 *
553 * expect({a: 1}).to.have.own.property('a');
554 * expect({a: 1}).to.have.property('b');
555 * expect({a: 1}).to.not.have.own.property('b');
556 *
557 * expect({a: 1}).to.own.include({a: 1});
558 * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
559 *
560 * `.own` cannot be combined with `.nested`.
561 *
562 * @name own
563 * @namespace BDD
564 * @api public
565 */
566
567 Assertion.addProperty('own', function () {
568 flag(this, 'own', true);
569 });
570
571 /**
572 * ### .ordered
573 *
574 * Causes all `.members` assertions that follow in the chain to require that
575 * members be in the same order.
576 *
577 * expect([1, 2]).to.have.ordered.members([1, 2])
578 * .but.not.have.ordered.members([2, 1]);
579 *
580 * When `.include` and `.ordered` are combined, the ordering begins at the
581 * start of both arrays.
582 *
583 * expect([1, 2, 3]).to.include.ordered.members([1, 2])
584 * .but.not.include.ordered.members([2, 3]);
585 *
586 * @name ordered
587 * @namespace BDD
588 * @api public
589 */
590
591 Assertion.addProperty('ordered', function () {
592 flag(this, 'ordered', true);
593 });
594
595 /**
596 * ### .any
597 *
598 * Causes all `.keys` assertions that follow in the chain to only require that
599 * the target have at least one of the given keys. This is the opposite of
600 * `.all`, which requires that the target have all of the given keys.
601 *
602 * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
603 *
604 * See the `.keys` doc for guidance on when to use `.any` or `.all`.
605 *
606 * @name any
607 * @namespace BDD
608 * @api public
609 */
610
611 Assertion.addProperty('any', function () {
612 flag(this, 'any', true);
613 flag(this, 'all', false);
614 });
615
616 /**
617 * ### .all
618 *
619 * Causes all `.keys` assertions that follow in the chain to require that the
620 * target have all of the given keys. This is the opposite of `.any`, which
621 * only requires that the target have at least one of the given keys.
622 *
623 * expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
624 *
625 * Note that `.all` is used by default when neither `.all` nor `.any` are
626 * added earlier in the chain. However, it's often best to add `.all` anyway
627 * because it improves readability.
628 *
629 * See the `.keys` doc for guidance on when to use `.any` or `.all`.
630 *
631 * @name all
632 * @namespace BDD
633 * @api public
634 */
635
636 Assertion.addProperty('all', function () {
637 flag(this, 'all', true);
638 flag(this, 'any', false);
639 });
640
641 /**
642 * ### .a(type[, msg])
643 *
644 * Asserts that the target's type is equal to the given string `type`. Types
645 * are case insensitive. See the `type-detect` project page for info on the
646 * type detection algorithm: https://github.com/chaijs/type-detect.
647 *
648 * expect('foo').to.be.a('string');
649 * expect({a: 1}).to.be.an('object');
650 * expect(null).to.be.a('null');
651 * expect(undefined).to.be.an('undefined');
652 * expect(new Error).to.be.an('error');
653 * expect(Promise.resolve()).to.be.a('promise');
654 * expect(new Float32Array).to.be.a('float32array');
655 * expect(Symbol()).to.be.a('symbol');
656 *
657 * `.a` supports objects that have a custom type set via `Symbol.toStringTag`.
658 *
659 * var myObj = {
660 * [Symbol.toStringTag]: 'myCustomType'
661 * };
662 *
663 * expect(myObj).to.be.a('myCustomType').but.not.an('object');
664 *
665 * It's often best to use `.a` to check a target's type before making more
666 * assertions on the same target. That way, you avoid unexpected behavior from
667 * any assertion that does different things based on the target's type.
668 *
669 * expect([1, 2, 3]).to.be.an('array').that.includes(2);
670 * expect([]).to.be.an('array').that.is.empty;
671 *
672 * Add `.not` earlier in the chain to negate `.a`. However, it's often best to
673 * assert that the target is the expected type, rather than asserting that it
674 * isn't one of many unexpected types.
675 *
676 * expect('foo').to.be.a('string'); // Recommended
677 * expect('foo').to.not.be.an('array'); // Not recommended
678 *
679 * `.a` accepts an optional `msg` argument which is a custom error message to
680 * show when the assertion fails. The message can also be given as the second
681 * argument to `expect`.
682 *
683 * expect(1).to.be.a('string', 'nooo why fail??');
684 * expect(1, 'nooo why fail??').to.be.a('string');
685 *
686 * `.a` can also be used as a language chain to improve the readability of
687 * your assertions.
688 *
689 * expect({b: 2}).to.have.a.property('b');
690 *
691 * The alias `.an` can be used interchangeably with `.a`.
692 *
693 * @name a
694 * @alias an
695 * @param {String} type
696 * @param {String} msg _optional_
697 * @namespace BDD
698 * @api public
699 */
700
701 function an (type, msg) {
702 if (msg) flag(this, 'message', msg);
703 type = type.toLowerCase();
704 var obj = flag(this, 'object')
705 , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
706
707 this.assert(
708 type === _.type(obj).toLowerCase()
709 , 'expected #{this} to be ' + article + type
710 , 'expected #{this} not to be ' + article + type
711 );
712 }
713
714 Assertion.addChainableMethod('an', an);
715 Assertion.addChainableMethod('a', an);
716
717 /**
718 * ### .include(val[, msg])
719 *
720 * When the target is a string, `.include` asserts that the given string `val`
721 * is a substring of the target.
722 *
723 * expect('foobar').to.include('foo');
724 *
725 * When the target is an array, `.include` asserts that the given `val` is a
726 * member of the target.
727 *
728 * expect([1, 2, 3]).to.include(2);
729 *
730 * When the target is an object, `.include` asserts that the given object
731 * `val`'s properties are a subset of the target's properties.
732 *
733 * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
734 *
735 * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a
736 * member of the target. SameValueZero equality algorithm is used.
737 *
738 * expect(new Set([1, 2])).to.include(2);
739 *
740 * When the target is a Map, `.include` asserts that the given `val` is one of
741 * the values of the target. SameValueZero equality algorithm is used.
742 *
743 * expect(new Map([['a', 1], ['b', 2]])).to.include(2);
744 *
745 * Because `.include` does different things based on the target's type, it's
746 * important to check the target's type before using `.include`. See the `.a`
747 * doc for info on testing a target's type.
748 *
749 * expect([1, 2, 3]).to.be.an('array').that.includes(2);
750 *
751 * By default, strict (`===`) equality is used to compare array members and
752 * object properties. Add `.deep` earlier in the chain to use deep equality
753 * instead (WeakSet targets are not supported). See the `deep-eql` project
754 * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
755 *
756 * // Target array deeply (but not strictly) includes `{a: 1}`
757 * expect([{a: 1}]).to.deep.include({a: 1});
758 * expect([{a: 1}]).to.not.include({a: 1});
759 *
760 * // Target object deeply (but not strictly) includes `x: {a: 1}`
761 * expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
762 * expect({x: {a: 1}}).to.not.include({x: {a: 1}});
763 *
764 * By default, all of the target's properties are searched when working with
765 * objects. This includes properties that are inherited and/or non-enumerable.
766 * Add `.own` earlier in the chain to exclude the target's inherited
767 * properties from the search.
768 *
769 * Object.prototype.b = 2;
770 *
771 * expect({a: 1}).to.own.include({a: 1});
772 * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
773 *
774 * Note that a target object is always only searched for `val`'s own
775 * enumerable properties.
776 *
777 * `.deep` and `.own` can be combined.
778 *
779 * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}});
780 *
781 * Add `.nested` earlier in the chain to enable dot- and bracket-notation when
782 * referencing nested properties.
783 *
784 * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
785 *
786 * If `.` or `[]` are part of an actual property name, they can be escaped by
787 * adding two backslashes before them.
788 *
789 * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2});
790 *
791 * `.deep` and `.nested` can be combined.
792 *
793 * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}});
794 *
795 * `.own` and `.nested` cannot be combined.
796 *
797 * Add `.not` earlier in the chain to negate `.include`.
798 *
799 * expect('foobar').to.not.include('taco');
800 * expect([1, 2, 3]).to.not.include(4);
801 *
802 * However, it's dangerous to negate `.include` when the target is an object.
803 * The problem is that it creates uncertain expectations by asserting that the
804 * target object doesn't have all of `val`'s key/value pairs but may or may
805 * not have some of them. It's often best to identify the exact output that's
806 * expected, and then write an assertion that only accepts that exact output.
807 *
808 * When the target object isn't even expected to have `val`'s keys, it's
809 * often best to assert exactly that.
810 *
811 * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended
812 * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended
813 *
814 * When the target object is expected to have `val`'s keys, it's often best to
815 * assert that each of the properties has its expected value, rather than
816 * asserting that each property doesn't have one of many unexpected values.
817 *
818 * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended
819 * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended
820 *
821 * `.include` accepts an optional `msg` argument which is a custom error
822 * message to show when the assertion fails. The message can also be given as
823 * the second argument to `expect`.
824 *
825 * expect([1, 2, 3]).to.include(4, 'nooo why fail??');
826 * expect([1, 2, 3], 'nooo why fail??').to.include(4);
827 *
828 * `.include` can also be used as a language chain, causing all `.members` and
829 * `.keys` assertions that follow in the chain to require the target to be a
830 * superset of the expected set, rather than an identical set. Note that
831 * `.members` ignores duplicates in the subset when `.include` is added.
832 *
833 * // Target object's keys are a superset of ['a', 'b'] but not identical
834 * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');
835 * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');
836 *
837 * // Target array is a superset of [1, 2] but not identical
838 * expect([1, 2, 3]).to.include.members([1, 2]);
839 * expect([1, 2, 3]).to.not.have.members([1, 2]);
840 *
841 * // Duplicates in the subset are ignored
842 * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
843 *
844 * Note that adding `.any` earlier in the chain causes the `.keys` assertion
845 * to ignore `.include`.
846 *
847 * // Both assertions are identical
848 * expect({a: 1}).to.include.any.keys('a', 'b');
849 * expect({a: 1}).to.have.any.keys('a', 'b');
850 *
851 * The aliases `.includes`, `.contain`, and `.contains` can be used
852 * interchangeably with `.include`.
853 *
854 * @name include
855 * @alias contain
856 * @alias includes
857 * @alias contains
858 * @param {Mixed} val
859 * @param {String} msg _optional_
860 * @namespace BDD
861 * @api public
862 */
863
864 function SameValueZero(a, b) {
865 return (_.isNaN(a) && _.isNaN(b)) || a === b;
866 }
867
868 function includeChainingBehavior () {
869 flag(this, 'contains', true);
870 }
871
872 function include (val, msg) {
873 if (msg) flag(this, 'message', msg);
874
875 var obj = flag(this, 'object')
876 , objType = _.type(obj).toLowerCase()
877 , flagMsg = flag(this, 'message')
878 , negate = flag(this, 'negate')
879 , ssfi = flag(this, 'ssfi')
880 , isDeep = flag(this, 'deep')
881 , descriptor = isDeep ? 'deep ' : ''
882 , isEql = isDeep ? flag(this, 'eql') : SameValueZero;
883
884 flagMsg = flagMsg ? flagMsg + ': ' : '';
885
886 var included = false;
887
888 switch (objType) {
889 case 'string':
890 included = obj.indexOf(val) !== -1;
891 break;
892
893 case 'weakset':
894 if (isDeep) {
895 throw new AssertionError(
896 flagMsg + 'unable to use .deep.include with WeakSet',
897 undefined,
898 ssfi
899 );
900 }
901
902 included = obj.has(val);
903 break;
904
905 case 'map':
906 obj.forEach(function (item) {
907 included = included || isEql(item, val);
908 });
909 break;
910
911 case 'set':
912 if (isDeep) {
913 obj.forEach(function (item) {
914 included = included || isEql(item, val);
915 });
916 } else {
917 included = obj.has(val);
918 }
919 break;
920
921 case 'array':
922 if (isDeep) {
923 included = obj.some(function (item) {
924 return isEql(item, val);
925 })
926 } else {
927 included = obj.indexOf(val) !== -1;
928 }
929 break;
930
931 default:
932 // This block is for asserting a subset of properties in an object.
933 // `_.expectTypes` isn't used here because `.include` should work with
934 // objects with a custom `@@toStringTag`.
935 if (val !== Object(val)) {
936 throw new AssertionError(
937 flagMsg + 'the given combination of arguments ('
938 + objType + ' and '
939 + _.type(val).toLowerCase() + ')'
940 + ' is invalid for this assertion. '
941 + 'You can use an array, a map, an object, a set, a string, '
942 + 'or a weakset instead of a '
943 + _.type(val).toLowerCase(),
944 undefined,
945 ssfi
946 );
947 }
948
949 var props = Object.keys(val)
950 , firstErr = null
951 , numErrs = 0;
952
953 props.forEach(function (prop) {
954 var propAssertion = new Assertion(obj);
955 _.transferFlags(this, propAssertion, true);
956 flag(propAssertion, 'lockSsfi', true);
957
958 if (!negate || props.length === 1) {
959 propAssertion.property(prop, val[prop]);
960 return;
961 }
962
963 try {
964 propAssertion.property(prop, val[prop]);
965 } catch (err) {
966 if (!_.checkError.compatibleConstructor(err, AssertionError)) {
967 throw err;
968 }
969 if (firstErr === null) firstErr = err;
970 numErrs++;
971 }
972 }, this);
973
974 // When validating .not.include with multiple properties, we only want
975 // to throw an assertion error if all of the properties are included,
976 // in which case we throw the first property assertion error that we
977 // encountered.
978 if (negate && props.length > 1 && numErrs === props.length) {
979 throw firstErr;
980 }
981 return;
982 }
983
984 // Assert inclusion in collection or substring in a string.
985 this.assert(
986 included
987 , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val)
988 , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val));
989 }
990
991 Assertion.addChainableMethod('include', include, includeChainingBehavior);
992 Assertion.addChainableMethod('contain', include, includeChainingBehavior);
993 Assertion.addChainableMethod('contains', include, includeChainingBehavior);
994 Assertion.addChainableMethod('includes', include, includeChainingBehavior);
995
996 /**
997 * ### .ok
998 *
999 * Asserts that the target is a truthy value (considered `true` in boolean context).
1000 * However, it's often best to assert that the target is strictly (`===`) or
1001 * deeply equal to its expected value.
1002 *
1003 * expect(1).to.equal(1); // Recommended
1004 * expect(1).to.be.ok; // Not recommended
1005 *
1006 * expect(true).to.be.true; // Recommended
1007 * expect(true).to.be.ok; // Not recommended
1008 *
1009 * Add `.not` earlier in the chain to negate `.ok`.
1010 *
1011 * expect(0).to.equal(0); // Recommended
1012 * expect(0).to.not.be.ok; // Not recommended
1013 *
1014 * expect(false).to.be.false; // Recommended
1015 * expect(false).to.not.be.ok; // Not recommended
1016 *
1017 * expect(null).to.be.null; // Recommended
1018 * expect(null).to.not.be.ok; // Not recommended
1019 *
1020 * expect(undefined).to.be.undefined; // Recommended
1021 * expect(undefined).to.not.be.ok; // Not recommended
1022 *
1023 * A custom error message can be given as the second argument to `expect`.
1024 *
1025 * expect(false, 'nooo why fail??').to.be.ok;
1026 *
1027 * @name ok
1028 * @namespace BDD
1029 * @api public
1030 */
1031
1032 Assertion.addProperty('ok', function () {
1033 this.assert(
1034 flag(this, 'object')
1035 , 'expected #{this} to be truthy'
1036 , 'expected #{this} to be falsy');
1037 });
1038
1039 /**
1040 * ### .true
1041 *
1042 * Asserts that the target is strictly (`===`) equal to `true`.
1043 *
1044 * expect(true).to.be.true;
1045 *
1046 * Add `.not` earlier in the chain to negate `.true`. However, it's often best
1047 * to assert that the target is equal to its expected value, rather than not
1048 * equal to `true`.
1049 *
1050 * expect(false).to.be.false; // Recommended
1051 * expect(false).to.not.be.true; // Not recommended
1052 *
1053 * expect(1).to.equal(1); // Recommended
1054 * expect(1).to.not.be.true; // Not recommended
1055 *
1056 * A custom error message can be given as the second argument to `expect`.
1057 *
1058 * expect(false, 'nooo why fail??').to.be.true;
1059 *
1060 * @name true
1061 * @namespace BDD
1062 * @api public
1063 */
1064
1065 Assertion.addProperty('true', function () {
1066 this.assert(
1067 true === flag(this, 'object')
1068 , 'expected #{this} to be true'
1069 , 'expected #{this} to be false'
1070 , flag(this, 'negate') ? false : true
1071 );
1072 });
1073
1074 /**
1075 * ### .false
1076 *
1077 * Asserts that the target is strictly (`===`) equal to `false`.
1078 *
1079 * expect(false).to.be.false;
1080 *
1081 * Add `.not` earlier in the chain to negate `.false`. However, it's often
1082 * best to assert that the target is equal to its expected value, rather than
1083 * not equal to `false`.
1084 *
1085 * expect(true).to.be.true; // Recommended
1086 * expect(true).to.not.be.false; // Not recommended
1087 *
1088 * expect(1).to.equal(1); // Recommended
1089 * expect(1).to.not.be.false; // Not recommended
1090 *
1091 * A custom error message can be given as the second argument to `expect`.
1092 *
1093 * expect(true, 'nooo why fail??').to.be.false;
1094 *
1095 * @name false
1096 * @namespace BDD
1097 * @api public
1098 */
1099
1100 Assertion.addProperty('false', function () {
1101 this.assert(
1102 false === flag(this, 'object')
1103 , 'expected #{this} to be false'
1104 , 'expected #{this} to be true'
1105 , flag(this, 'negate') ? true : false
1106 );
1107 });
1108
1109 /**
1110 * ### .null
1111 *
1112 * Asserts that the target is strictly (`===`) equal to `null`.
1113 *
1114 * expect(null).to.be.null;
1115 *
1116 * Add `.not` earlier in the chain to negate `.null`. However, it's often best
1117 * to assert that the target is equal to its expected value, rather than not
1118 * equal to `null`.
1119 *
1120 * expect(1).to.equal(1); // Recommended
1121 * expect(1).to.not.be.null; // Not recommended
1122 *
1123 * A custom error message can be given as the second argument to `expect`.
1124 *
1125 * expect(42, 'nooo why fail??').to.be.null;
1126 *
1127 * @name null
1128 * @namespace BDD
1129 * @api public
1130 */
1131
1132 Assertion.addProperty('null', function () {
1133 this.assert(
1134 null === flag(this, 'object')
1135 , 'expected #{this} to be null'
1136 , 'expected #{this} not to be null'
1137 );
1138 });
1139
1140 /**
1141 * ### .undefined
1142 *
1143 * Asserts that the target is strictly (`===`) equal to `undefined`.
1144 *
1145 * expect(undefined).to.be.undefined;
1146 *
1147 * Add `.not` earlier in the chain to negate `.undefined`. However, it's often
1148 * best to assert that the target is equal to its expected value, rather than
1149 * not equal to `undefined`.
1150 *
1151 * expect(1).to.equal(1); // Recommended
1152 * expect(1).to.not.be.undefined; // Not recommended
1153 *
1154 * A custom error message can be given as the second argument to `expect`.
1155 *
1156 * expect(42, 'nooo why fail??').to.be.undefined;
1157 *
1158 * @name undefined
1159 * @namespace BDD
1160 * @api public
1161 */
1162
1163 Assertion.addProperty('undefined', function () {
1164 this.assert(
1165 undefined === flag(this, 'object')
1166 , 'expected #{this} to be undefined'
1167 , 'expected #{this} not to be undefined'
1168 );
1169 });
1170
1171 /**
1172 * ### .NaN
1173 *
1174 * Asserts that the target is exactly `NaN`.
1175 *
1176 * expect(NaN).to.be.NaN;
1177 *
1178 * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best
1179 * to assert that the target is equal to its expected value, rather than not
1180 * equal to `NaN`.
1181 *
1182 * expect('foo').to.equal('foo'); // Recommended
1183 * expect('foo').to.not.be.NaN; // Not recommended
1184 *
1185 * A custom error message can be given as the second argument to `expect`.
1186 *
1187 * expect(42, 'nooo why fail??').to.be.NaN;
1188 *
1189 * @name NaN
1190 * @namespace BDD
1191 * @api public
1192 */
1193
1194 Assertion.addProperty('NaN', function () {
1195 this.assert(
1196 _.isNaN(flag(this, 'object'))
1197 , 'expected #{this} to be NaN'
1198 , 'expected #{this} not to be NaN'
1199 );
1200 });
1201
1202 /**
1203 * ### .exist
1204 *
1205 * Asserts that the target is not strictly (`===`) equal to either `null` or
1206 * `undefined`. However, it's often best to assert that the target is equal to
1207 * its expected value.
1208 *
1209 * expect(1).to.equal(1); // Recommended
1210 * expect(1).to.exist; // Not recommended
1211 *
1212 * expect(0).to.equal(0); // Recommended
1213 * expect(0).to.exist; // Not recommended
1214 *
1215 * Add `.not` earlier in the chain to negate `.exist`.
1216 *
1217 * expect(null).to.be.null; // Recommended
1218 * expect(null).to.not.exist; // Not recommended
1219 *
1220 * expect(undefined).to.be.undefined; // Recommended
1221 * expect(undefined).to.not.exist; // Not recommended
1222 *
1223 * A custom error message can be given as the second argument to `expect`.
1224 *
1225 * expect(null, 'nooo why fail??').to.exist;
1226 *
1227 * The alias `.exists` can be used interchangeably with `.exist`.
1228 *
1229 * @name exist
1230 * @alias exists
1231 * @namespace BDD
1232 * @api public
1233 */
1234
1235 function assertExist () {
1236 var val = flag(this, 'object');
1237 this.assert(
1238 val !== null && val !== undefined
1239 , 'expected #{this} to exist'
1240 , 'expected #{this} to not exist'
1241 );
1242 }
1243
1244 Assertion.addProperty('exist', assertExist);
1245 Assertion.addProperty('exists', assertExist);
1246
1247 /**
1248 * ### .empty
1249 *
1250 * When the target is a string or array, `.empty` asserts that the target's
1251 * `length` property is strictly (`===`) equal to `0`.
1252 *
1253 * expect([]).to.be.empty;
1254 * expect('').to.be.empty;
1255 *
1256 * When the target is a map or set, `.empty` asserts that the target's `size`
1257 * property is strictly equal to `0`.
1258 *
1259 * expect(new Set()).to.be.empty;
1260 * expect(new Map()).to.be.empty;
1261 *
1262 * When the target is a non-function object, `.empty` asserts that the target
1263 * doesn't have any own enumerable properties. Properties with Symbol-based
1264 * keys are excluded from the count.
1265 *
1266 * expect({}).to.be.empty;
1267 *
1268 * Because `.empty` does different things based on the target's type, it's
1269 * important to check the target's type before using `.empty`. See the `.a`
1270 * doc for info on testing a target's type.
1271 *
1272 * expect([]).to.be.an('array').that.is.empty;
1273 *
1274 * Add `.not` earlier in the chain to negate `.empty`. However, it's often
1275 * best to assert that the target contains its expected number of values,
1276 * rather than asserting that it's not empty.
1277 *
1278 * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
1279 * expect([1, 2, 3]).to.not.be.empty; // Not recommended
1280 *
1281 * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended
1282 * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended
1283 *
1284 * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended
1285 * expect({a: 1}).to.not.be.empty; // Not recommended
1286 *
1287 * A custom error message can be given as the second argument to `expect`.
1288 *
1289 * expect([1, 2, 3], 'nooo why fail??').to.be.empty;
1290 *
1291 * @name empty
1292 * @namespace BDD
1293 * @api public
1294 */
1295
1296 Assertion.addProperty('empty', function () {
1297 var val = flag(this, 'object')
1298 , ssfi = flag(this, 'ssfi')
1299 , flagMsg = flag(this, 'message')
1300 , itemsCount;
1301
1302 flagMsg = flagMsg ? flagMsg + ': ' : '';
1303
1304 switch (_.type(val).toLowerCase()) {
1305 case 'array':
1306 case 'string':
1307 itemsCount = val.length;
1308 break;
1309 case 'map':
1310 case 'set':
1311 itemsCount = val.size;
1312 break;
1313 case 'weakmap':
1314 case 'weakset':
1315 throw new AssertionError(
1316 flagMsg + '.empty was passed a weak collection',
1317 undefined,
1318 ssfi
1319 );
1320 case 'function':
1321 var msg = flagMsg + '.empty was passed a function ' + _.getName(val);
1322 throw new AssertionError(msg.trim(), undefined, ssfi);
1323 default:
1324 if (val !== Object(val)) {
1325 throw new AssertionError(
1326 flagMsg + '.empty was passed non-string primitive ' + _.inspect(val),
1327 undefined,
1328 ssfi
1329 );
1330 }
1331 itemsCount = Object.keys(val).length;
1332 }
1333
1334 this.assert(
1335 0 === itemsCount
1336 , 'expected #{this} to be empty'
1337 , 'expected #{this} not to be empty'
1338 );
1339 });
1340
1341 /**
1342 * ### .arguments
1343 *
1344 * Asserts that the target is an `arguments` object.
1345 *
1346 * function test () {
1347 * expect(arguments).to.be.arguments;
1348 * }
1349 *
1350 * test();
1351 *
1352 * Add `.not` earlier in the chain to negate `.arguments`. However, it's often
1353 * best to assert which type the target is expected to be, rather than
1354 * asserting that it’s not an `arguments` object.
1355 *
1356 * expect('foo').to.be.a('string'); // Recommended
1357 * expect('foo').to.not.be.arguments; // Not recommended
1358 *
1359 * A custom error message can be given as the second argument to `expect`.
1360 *
1361 * expect({}, 'nooo why fail??').to.be.arguments;
1362 *
1363 * The alias `.Arguments` can be used interchangeably with `.arguments`.
1364 *
1365 * @name arguments
1366 * @alias Arguments
1367 * @namespace BDD
1368 * @api public
1369 */
1370
1371 function checkArguments () {
1372 var obj = flag(this, 'object')
1373 , type = _.type(obj);
1374 this.assert(
1375 'Arguments' === type
1376 , 'expected #{this} to be arguments but got ' + type
1377 , 'expected #{this} to not be arguments'
1378 );
1379 }
1380
1381 Assertion.addProperty('arguments', checkArguments);
1382 Assertion.addProperty('Arguments', checkArguments);
1383
1384 /**
1385 * ### .equal(val[, msg])
1386 *
1387 * Asserts that the target is strictly (`===`) equal to the given `val`.
1388 *
1389 * expect(1).to.equal(1);
1390 * expect('foo').to.equal('foo');
1391 *
1392 * Add `.deep` earlier in the chain to use deep equality instead. See the
1393 * `deep-eql` project page for info on the deep equality algorithm:
1394 * https://github.com/chaijs/deep-eql.
1395 *
1396 * // Target object deeply (but not strictly) equals `{a: 1}`
1397 * expect({a: 1}).to.deep.equal({a: 1});
1398 * expect({a: 1}).to.not.equal({a: 1});
1399 *
1400 * // Target array deeply (but not strictly) equals `[1, 2]`
1401 * expect([1, 2]).to.deep.equal([1, 2]);
1402 * expect([1, 2]).to.not.equal([1, 2]);
1403 *
1404 * Add `.not` earlier in the chain to negate `.equal`. However, it's often
1405 * best to assert that the target is equal to its expected value, rather than
1406 * not equal to one of countless unexpected values.
1407 *
1408 * expect(1).to.equal(1); // Recommended
1409 * expect(1).to.not.equal(2); // Not recommended
1410 *
1411 * `.equal` accepts an optional `msg` argument which is a custom error message
1412 * to show when the assertion fails. The message can also be given as the
1413 * second argument to `expect`.
1414 *
1415 * expect(1).to.equal(2, 'nooo why fail??');
1416 * expect(1, 'nooo why fail??').to.equal(2);
1417 *
1418 * The aliases `.equals` and `eq` can be used interchangeably with `.equal`.
1419 *
1420 * @name equal
1421 * @alias equals
1422 * @alias eq
1423 * @param {Mixed} val
1424 * @param {String} msg _optional_
1425 * @namespace BDD
1426 * @api public
1427 */
1428
1429 function assertEqual (val, msg) {
1430 if (msg) flag(this, 'message', msg);
1431 var obj = flag(this, 'object');
1432 if (flag(this, 'deep')) {
1433 var prevLockSsfi = flag(this, 'lockSsfi');
1434 flag(this, 'lockSsfi', true);
1435 this.eql(val);
1436 flag(this, 'lockSsfi', prevLockSsfi);
1437 } else {
1438 this.assert(
1439 val === obj
1440 , 'expected #{this} to equal #{exp}'
1441 , 'expected #{this} to not equal #{exp}'
1442 , val
1443 , this._obj
1444 , true
1445 );
1446 }
1447 }
1448
1449 Assertion.addMethod('equal', assertEqual);
1450 Assertion.addMethod('equals', assertEqual);
1451 Assertion.addMethod('eq', assertEqual);
1452
1453 /**
1454 * ### .eql(obj[, msg])
1455 *
1456 * Asserts that the target is deeply equal to the given `obj`. See the
1457 * `deep-eql` project page for info on the deep equality algorithm:
1458 * https://github.com/chaijs/deep-eql.
1459 *
1460 * // Target object is deeply (but not strictly) equal to {a: 1}
1461 * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1});
1462 *
1463 * // Target array is deeply (but not strictly) equal to [1, 2]
1464 * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]);
1465 *
1466 * Add `.not` earlier in the chain to negate `.eql`. However, it's often best
1467 * to assert that the target is deeply equal to its expected value, rather
1468 * than not deeply equal to one of countless unexpected values.
1469 *
1470 * expect({a: 1}).to.eql({a: 1}); // Recommended
1471 * expect({a: 1}).to.not.eql({b: 2}); // Not recommended
1472 *
1473 * `.eql` accepts an optional `msg` argument which is a custom error message
1474 * to show when the assertion fails. The message can also be given as the
1475 * second argument to `expect`.
1476 *
1477 * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??');
1478 * expect({a: 1}, 'nooo why fail??').to.eql({b: 2});
1479 *
1480 * The alias `.eqls` can be used interchangeably with `.eql`.
1481 *
1482 * The `.deep.equal` assertion is almost identical to `.eql` but with one
1483 * difference: `.deep.equal` causes deep equality comparisons to also be used
1484 * for any other assertions that follow in the chain.
1485 *
1486 * @name eql
1487 * @alias eqls
1488 * @param {Mixed} obj
1489 * @param {String} msg _optional_
1490 * @namespace BDD
1491 * @api public
1492 */
1493
1494 function assertEql(obj, msg) {
1495 if (msg) flag(this, 'message', msg);
1496 var eql = flag(this, 'eql');
1497 this.assert(
1498 eql(obj, flag(this, 'object'))
1499 , 'expected #{this} to deeply equal #{exp}'
1500 , 'expected #{this} to not deeply equal #{exp}'
1501 , obj
1502 , this._obj
1503 , true
1504 );
1505 }
1506
1507 Assertion.addMethod('eql', assertEql);
1508 Assertion.addMethod('eqls', assertEql);
1509
1510 /**
1511 * ### .above(n[, msg])
1512 *
1513 * Asserts that the target is a number or a date greater than the given number or date `n` respectively.
1514 * However, it's often best to assert that the target is equal to its expected
1515 * value.
1516 *
1517 * expect(2).to.equal(2); // Recommended
1518 * expect(2).to.be.above(1); // Not recommended
1519 *
1520 * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1521 * or `size` is greater than the given number `n`.
1522 *
1523 * expect('foo').to.have.lengthOf(3); // Recommended
1524 * expect('foo').to.have.lengthOf.above(2); // Not recommended
1525 *
1526 * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
1527 * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended
1528 *
1529 * Add `.not` earlier in the chain to negate `.above`.
1530 *
1531 * expect(2).to.equal(2); // Recommended
1532 * expect(1).to.not.be.above(2); // Not recommended
1533 *
1534 * `.above` accepts an optional `msg` argument which is a custom error message
1535 * to show when the assertion fails. The message can also be given as the
1536 * second argument to `expect`.
1537 *
1538 * expect(1).to.be.above(2, 'nooo why fail??');
1539 * expect(1, 'nooo why fail??').to.be.above(2);
1540 *
1541 * The aliases `.gt` and `.greaterThan` can be used interchangeably with
1542 * `.above`.
1543 *
1544 * @name above
1545 * @alias gt
1546 * @alias greaterThan
1547 * @param {Number} n
1548 * @param {String} msg _optional_
1549 * @namespace BDD
1550 * @api public
1551 */
1552
1553 function assertAbove (n, msg) {
1554 if (msg) flag(this, 'message', msg);
1555 var obj = flag(this, 'object')
1556 , doLength = flag(this, 'doLength')
1557 , flagMsg = flag(this, 'message')
1558 , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1559 , ssfi = flag(this, 'ssfi')
1560 , objType = _.type(obj).toLowerCase()
1561 , nType = _.type(n).toLowerCase()
1562 , errorMessage
1563 , shouldThrow = true;
1564
1565 if (doLength && objType !== 'map' && objType !== 'set') {
1566 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1567 }
1568
1569 if (!doLength && (objType === 'date' && nType !== 'date')) {
1570 errorMessage = msgPrefix + 'the argument to above must be a date';
1571 } else if (nType !== 'number' && (doLength || objType === 'number')) {
1572 errorMessage = msgPrefix + 'the argument to above must be a number';
1573 } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1574 var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1575 errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1576 } else {
1577 shouldThrow = false;
1578 }
1579
1580 if (shouldThrow) {
1581 throw new AssertionError(errorMessage, undefined, ssfi);
1582 }
1583
1584 if (doLength) {
1585 var descriptor = 'length'
1586 , itemsCount;
1587 if (objType === 'map' || objType === 'set') {
1588 descriptor = 'size';
1589 itemsCount = obj.size;
1590 } else {
1591 itemsCount = obj.length;
1592 }
1593 this.assert(
1594 itemsCount > n
1595 , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}'
1596 , 'expected #{this} to not have a ' + descriptor + ' above #{exp}'
1597 , n
1598 , itemsCount
1599 );
1600 } else {
1601 this.assert(
1602 obj > n
1603 , 'expected #{this} to be above #{exp}'
1604 , 'expected #{this} to be at most #{exp}'
1605 , n
1606 );
1607 }
1608 }
1609
1610 Assertion.addMethod('above', assertAbove);
1611 Assertion.addMethod('gt', assertAbove);
1612 Assertion.addMethod('greaterThan', assertAbove);
1613
1614 /**
1615 * ### .least(n[, msg])
1616 *
1617 * Asserts that the target is a number or a date greater than or equal to the given
1618 * number or date `n` respectively. However, it's often best to assert that the target is equal to
1619 * its expected value.
1620 *
1621 * expect(2).to.equal(2); // Recommended
1622 * expect(2).to.be.at.least(1); // Not recommended
1623 * expect(2).to.be.at.least(2); // Not recommended
1624 *
1625 * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1626 * or `size` is greater than or equal to the given number `n`.
1627 *
1628 * expect('foo').to.have.lengthOf(3); // Recommended
1629 * expect('foo').to.have.lengthOf.at.least(2); // Not recommended
1630 *
1631 * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
1632 * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended
1633 *
1634 * Add `.not` earlier in the chain to negate `.least`.
1635 *
1636 * expect(1).to.equal(1); // Recommended
1637 * expect(1).to.not.be.at.least(2); // Not recommended
1638 *
1639 * `.least` accepts an optional `msg` argument which is a custom error message
1640 * to show when the assertion fails. The message can also be given as the
1641 * second argument to `expect`.
1642 *
1643 * expect(1).to.be.at.least(2, 'nooo why fail??');
1644 * expect(1, 'nooo why fail??').to.be.at.least(2);
1645 *
1646 * The aliases `.gte` and `.greaterThanOrEqual` can be used interchangeably with
1647 * `.least`.
1648 *
1649 * @name least
1650 * @alias gte
1651 * @alias greaterThanOrEqual
1652 * @param {Number} n
1653 * @param {String} msg _optional_
1654 * @namespace BDD
1655 * @api public
1656 */
1657
1658 function assertLeast (n, msg) {
1659 if (msg) flag(this, 'message', msg);
1660 var obj = flag(this, 'object')
1661 , doLength = flag(this, 'doLength')
1662 , flagMsg = flag(this, 'message')
1663 , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1664 , ssfi = flag(this, 'ssfi')
1665 , objType = _.type(obj).toLowerCase()
1666 , nType = _.type(n).toLowerCase()
1667 , errorMessage
1668 , shouldThrow = true;
1669
1670 if (doLength && objType !== 'map' && objType !== 'set') {
1671 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1672 }
1673
1674 if (!doLength && (objType === 'date' && nType !== 'date')) {
1675 errorMessage = msgPrefix + 'the argument to least must be a date';
1676 } else if (nType !== 'number' && (doLength || objType === 'number')) {
1677 errorMessage = msgPrefix + 'the argument to least must be a number';
1678 } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1679 var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1680 errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1681 } else {
1682 shouldThrow = false;
1683 }
1684
1685 if (shouldThrow) {
1686 throw new AssertionError(errorMessage, undefined, ssfi);
1687 }
1688
1689 if (doLength) {
1690 var descriptor = 'length'
1691 , itemsCount;
1692 if (objType === 'map' || objType === 'set') {
1693 descriptor = 'size';
1694 itemsCount = obj.size;
1695 } else {
1696 itemsCount = obj.length;
1697 }
1698 this.assert(
1699 itemsCount >= n
1700 , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}'
1701 , 'expected #{this} to have a ' + descriptor + ' below #{exp}'
1702 , n
1703 , itemsCount
1704 );
1705 } else {
1706 this.assert(
1707 obj >= n
1708 , 'expected #{this} to be at least #{exp}'
1709 , 'expected #{this} to be below #{exp}'
1710 , n
1711 );
1712 }
1713 }
1714
1715 Assertion.addMethod('least', assertLeast);
1716 Assertion.addMethod('gte', assertLeast);
1717 Assertion.addMethod('greaterThanOrEqual', assertLeast);
1718
1719 /**
1720 * ### .below(n[, msg])
1721 *
1722 * Asserts that the target is a number or a date less than the given number or date `n` respectively.
1723 * However, it's often best to assert that the target is equal to its expected
1724 * value.
1725 *
1726 * expect(1).to.equal(1); // Recommended
1727 * expect(1).to.be.below(2); // Not recommended
1728 *
1729 * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1730 * or `size` is less than the given number `n`.
1731 *
1732 * expect('foo').to.have.lengthOf(3); // Recommended
1733 * expect('foo').to.have.lengthOf.below(4); // Not recommended
1734 *
1735 * expect([1, 2, 3]).to.have.length(3); // Recommended
1736 * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended
1737 *
1738 * Add `.not` earlier in the chain to negate `.below`.
1739 *
1740 * expect(2).to.equal(2); // Recommended
1741 * expect(2).to.not.be.below(1); // Not recommended
1742 *
1743 * `.below` accepts an optional `msg` argument which is a custom error message
1744 * to show when the assertion fails. The message can also be given as the
1745 * second argument to `expect`.
1746 *
1747 * expect(2).to.be.below(1, 'nooo why fail??');
1748 * expect(2, 'nooo why fail??').to.be.below(1);
1749 *
1750 * The aliases `.lt` and `.lessThan` can be used interchangeably with
1751 * `.below`.
1752 *
1753 * @name below
1754 * @alias lt
1755 * @alias lessThan
1756 * @param {Number} n
1757 * @param {String} msg _optional_
1758 * @namespace BDD
1759 * @api public
1760 */
1761
1762 function assertBelow (n, msg) {
1763 if (msg) flag(this, 'message', msg);
1764 var obj = flag(this, 'object')
1765 , doLength = flag(this, 'doLength')
1766 , flagMsg = flag(this, 'message')
1767 , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1768 , ssfi = flag(this, 'ssfi')
1769 , objType = _.type(obj).toLowerCase()
1770 , nType = _.type(n).toLowerCase()
1771 , errorMessage
1772 , shouldThrow = true;
1773
1774 if (doLength && objType !== 'map' && objType !== 'set') {
1775 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1776 }
1777
1778 if (!doLength && (objType === 'date' && nType !== 'date')) {
1779 errorMessage = msgPrefix + 'the argument to below must be a date';
1780 } else if (nType !== 'number' && (doLength || objType === 'number')) {
1781 errorMessage = msgPrefix + 'the argument to below must be a number';
1782 } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1783 var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1784 errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1785 } else {
1786 shouldThrow = false;
1787 }
1788
1789 if (shouldThrow) {
1790 throw new AssertionError(errorMessage, undefined, ssfi);
1791 }
1792
1793 if (doLength) {
1794 var descriptor = 'length'
1795 , itemsCount;
1796 if (objType === 'map' || objType === 'set') {
1797 descriptor = 'size';
1798 itemsCount = obj.size;
1799 } else {
1800 itemsCount = obj.length;
1801 }
1802 this.assert(
1803 itemsCount < n
1804 , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}'
1805 , 'expected #{this} to not have a ' + descriptor + ' below #{exp}'
1806 , n
1807 , itemsCount
1808 );
1809 } else {
1810 this.assert(
1811 obj < n
1812 , 'expected #{this} to be below #{exp}'
1813 , 'expected #{this} to be at least #{exp}'
1814 , n
1815 );
1816 }
1817 }
1818
1819 Assertion.addMethod('below', assertBelow);
1820 Assertion.addMethod('lt', assertBelow);
1821 Assertion.addMethod('lessThan', assertBelow);
1822
1823 /**
1824 * ### .most(n[, msg])
1825 *
1826 * Asserts that the target is a number or a date less than or equal to the given number
1827 * or date `n` respectively. However, it's often best to assert that the target is equal to its
1828 * expected value.
1829 *
1830 * expect(1).to.equal(1); // Recommended
1831 * expect(1).to.be.at.most(2); // Not recommended
1832 * expect(1).to.be.at.most(1); // Not recommended
1833 *
1834 * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1835 * or `size` is less than or equal to the given number `n`.
1836 *
1837 * expect('foo').to.have.lengthOf(3); // Recommended
1838 * expect('foo').to.have.lengthOf.at.most(4); // Not recommended
1839 *
1840 * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
1841 * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended
1842 *
1843 * Add `.not` earlier in the chain to negate `.most`.
1844 *
1845 * expect(2).to.equal(2); // Recommended
1846 * expect(2).to.not.be.at.most(1); // Not recommended
1847 *
1848 * `.most` accepts an optional `msg` argument which is a custom error message
1849 * to show when the assertion fails. The message can also be given as the
1850 * second argument to `expect`.
1851 *
1852 * expect(2).to.be.at.most(1, 'nooo why fail??');
1853 * expect(2, 'nooo why fail??').to.be.at.most(1);
1854 *
1855 * The aliases `.lte` and `.lessThanOrEqual` can be used interchangeably with
1856 * `.most`.
1857 *
1858 * @name most
1859 * @alias lte
1860 * @alias lessThanOrEqual
1861 * @param {Number} n
1862 * @param {String} msg _optional_
1863 * @namespace BDD
1864 * @api public
1865 */
1866
1867 function assertMost (n, msg) {
1868 if (msg) flag(this, 'message', msg);
1869 var obj = flag(this, 'object')
1870 , doLength = flag(this, 'doLength')
1871 , flagMsg = flag(this, 'message')
1872 , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1873 , ssfi = flag(this, 'ssfi')
1874 , objType = _.type(obj).toLowerCase()
1875 , nType = _.type(n).toLowerCase()
1876 , errorMessage
1877 , shouldThrow = true;
1878
1879 if (doLength && objType !== 'map' && objType !== 'set') {
1880 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1881 }
1882
1883 if (!doLength && (objType === 'date' && nType !== 'date')) {
1884 errorMessage = msgPrefix + 'the argument to most must be a date';
1885 } else if (nType !== 'number' && (doLength || objType === 'number')) {
1886 errorMessage = msgPrefix + 'the argument to most must be a number';
1887 } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1888 var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1889 errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1890 } else {
1891 shouldThrow = false;
1892 }
1893
1894 if (shouldThrow) {
1895 throw new AssertionError(errorMessage, undefined, ssfi);
1896 }
1897
1898 if (doLength) {
1899 var descriptor = 'length'
1900 , itemsCount;
1901 if (objType === 'map' || objType === 'set') {
1902 descriptor = 'size';
1903 itemsCount = obj.size;
1904 } else {
1905 itemsCount = obj.length;
1906 }
1907 this.assert(
1908 itemsCount <= n
1909 , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}'
1910 , 'expected #{this} to have a ' + descriptor + ' above #{exp}'
1911 , n
1912 , itemsCount
1913 );
1914 } else {
1915 this.assert(
1916 obj <= n
1917 , 'expected #{this} to be at most #{exp}'
1918 , 'expected #{this} to be above #{exp}'
1919 , n
1920 );
1921 }
1922 }
1923
1924 Assertion.addMethod('most', assertMost);
1925 Assertion.addMethod('lte', assertMost);
1926 Assertion.addMethod('lessThanOrEqual', assertMost);
1927
1928 /**
1929 * ### .within(start, finish[, msg])
1930 *
1931 * Asserts that the target is a number or a date greater than or equal to the given
1932 * number or date `start`, and less than or equal to the given number or date `finish` respectively.
1933 * However, it's often best to assert that the target is equal to its expected
1934 * value.
1935 *
1936 * expect(2).to.equal(2); // Recommended
1937 * expect(2).to.be.within(1, 3); // Not recommended
1938 * expect(2).to.be.within(2, 3); // Not recommended
1939 * expect(2).to.be.within(1, 2); // Not recommended
1940 *
1941 * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1942 * or `size` is greater than or equal to the given number `start`, and less
1943 * than or equal to the given number `finish`.
1944 *
1945 * expect('foo').to.have.lengthOf(3); // Recommended
1946 * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended
1947 *
1948 * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
1949 * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended
1950 *
1951 * Add `.not` earlier in the chain to negate `.within`.
1952 *
1953 * expect(1).to.equal(1); // Recommended
1954 * expect(1).to.not.be.within(2, 4); // Not recommended
1955 *
1956 * `.within` accepts an optional `msg` argument which is a custom error
1957 * message to show when the assertion fails. The message can also be given as
1958 * the second argument to `expect`.
1959 *
1960 * expect(4).to.be.within(1, 3, 'nooo why fail??');
1961 * expect(4, 'nooo why fail??').to.be.within(1, 3);
1962 *
1963 * @name within
1964 * @param {Number} start lower bound inclusive
1965 * @param {Number} finish upper bound inclusive
1966 * @param {String} msg _optional_
1967 * @namespace BDD
1968 * @api public
1969 */
1970
1971 Assertion.addMethod('within', function (start, finish, msg) {
1972 if (msg) flag(this, 'message', msg);
1973 var obj = flag(this, 'object')
1974 , doLength = flag(this, 'doLength')
1975 , flagMsg = flag(this, 'message')
1976 , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1977 , ssfi = flag(this, 'ssfi')
1978 , objType = _.type(obj).toLowerCase()
1979 , startType = _.type(start).toLowerCase()
1980 , finishType = _.type(finish).toLowerCase()
1981 , errorMessage
1982 , shouldThrow = true
1983 , range = (startType === 'date' && finishType === 'date')
1984 ? start.toISOString() + '..' + finish.toISOString()
1985 : start + '..' + finish;
1986
1987 if (doLength && objType !== 'map' && objType !== 'set') {
1988 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1989 }
1990
1991 if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) {
1992 errorMessage = msgPrefix + 'the arguments to within must be dates';
1993 } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) {
1994 errorMessage = msgPrefix + 'the arguments to within must be numbers';
1995 } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1996 var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1997 errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1998 } else {
1999 shouldThrow = false;
2000 }
2001
2002 if (shouldThrow) {
2003 throw new AssertionError(errorMessage, undefined, ssfi);
2004 }
2005
2006 if (doLength) {
2007 var descriptor = 'length'
2008 , itemsCount;
2009 if (objType === 'map' || objType === 'set') {
2010 descriptor = 'size';
2011 itemsCount = obj.size;
2012 } else {
2013 itemsCount = obj.length;
2014 }
2015 this.assert(
2016 itemsCount >= start && itemsCount <= finish
2017 , 'expected #{this} to have a ' + descriptor + ' within ' + range
2018 , 'expected #{this} to not have a ' + descriptor + ' within ' + range
2019 );
2020 } else {
2021 this.assert(
2022 obj >= start && obj <= finish
2023 , 'expected #{this} to be within ' + range
2024 , 'expected #{this} to not be within ' + range
2025 );
2026 }
2027 });
2028
2029 /**
2030 * ### .instanceof(constructor[, msg])
2031 *
2032 * Asserts that the target is an instance of the given `constructor`.
2033 *
2034 * function Cat () { }
2035 *
2036 * expect(new Cat()).to.be.an.instanceof(Cat);
2037 * expect([1, 2]).to.be.an.instanceof(Array);
2038 *
2039 * Add `.not` earlier in the chain to negate `.instanceof`.
2040 *
2041 * expect({a: 1}).to.not.be.an.instanceof(Array);
2042 *
2043 * `.instanceof` accepts an optional `msg` argument which is a custom error
2044 * message to show when the assertion fails. The message can also be given as
2045 * the second argument to `expect`.
2046 *
2047 * expect(1).to.be.an.instanceof(Array, 'nooo why fail??');
2048 * expect(1, 'nooo why fail??').to.be.an.instanceof(Array);
2049 *
2050 * Due to limitations in ES5, `.instanceof` may not always work as expected
2051 * when using a transpiler such as Babel or TypeScript. In particular, it may
2052 * produce unexpected results when subclassing built-in object such as
2053 * `Array`, `Error`, and `Map`. See your transpiler's docs for details:
2054 *
2055 * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes))
2056 * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work))
2057 *
2058 * The alias `.instanceOf` can be used interchangeably with `.instanceof`.
2059 *
2060 * @name instanceof
2061 * @param {Constructor} constructor
2062 * @param {String} msg _optional_
2063 * @alias instanceOf
2064 * @namespace BDD
2065 * @api public
2066 */
2067
2068 function assertInstanceOf (constructor, msg) {
2069 if (msg) flag(this, 'message', msg);
2070
2071 var target = flag(this, 'object')
2072 var ssfi = flag(this, 'ssfi');
2073 var flagMsg = flag(this, 'message');
2074
2075 try {
2076 var isInstanceOf = target instanceof constructor;
2077 } catch (err) {
2078 if (err instanceof TypeError) {
2079 flagMsg = flagMsg ? flagMsg + ': ' : '';
2080 throw new AssertionError(
2081 flagMsg + 'The instanceof assertion needs a constructor but '
2082 + _.type(constructor) + ' was given.',
2083 undefined,
2084 ssfi
2085 );
2086 }
2087 throw err;
2088 }
2089
2090 var name = _.getName(constructor);
2091 if (name === null) {
2092 name = 'an unnamed constructor';
2093 }
2094
2095 this.assert(
2096 isInstanceOf
2097 , 'expected #{this} to be an instance of ' + name
2098 , 'expected #{this} to not be an instance of ' + name
2099 );
2100 };
2101
2102 Assertion.addMethod('instanceof', assertInstanceOf);
2103 Assertion.addMethod('instanceOf', assertInstanceOf);
2104
2105 /**
2106 * ### .property(name[, val[, msg]])
2107 *
2108 * Asserts that the target has a property with the given key `name`.
2109 *
2110 * expect({a: 1}).to.have.property('a');
2111 *
2112 * When `val` is provided, `.property` also asserts that the property's value
2113 * is equal to the given `val`.
2114 *
2115 * expect({a: 1}).to.have.property('a', 1);
2116 *
2117 * By default, strict (`===`) equality is used. Add `.deep` earlier in the
2118 * chain to use deep equality instead. See the `deep-eql` project page for
2119 * info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
2120 *
2121 * // Target object deeply (but not strictly) has property `x: {a: 1}`
2122 * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});
2123 * expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
2124 *
2125 * The target's enumerable and non-enumerable properties are always included
2126 * in the search. By default, both own and inherited properties are included.
2127 * Add `.own` earlier in the chain to exclude inherited properties from the
2128 * search.
2129 *
2130 * Object.prototype.b = 2;
2131 *
2132 * expect({a: 1}).to.have.own.property('a');
2133 * expect({a: 1}).to.have.own.property('a', 1);
2134 * expect({a: 1}).to.have.property('b');
2135 * expect({a: 1}).to.not.have.own.property('b');
2136 *
2137 * `.deep` and `.own` can be combined.
2138 *
2139 * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1});
2140 *
2141 * Add `.nested` earlier in the chain to enable dot- and bracket-notation when
2142 * referencing nested properties.
2143 *
2144 * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
2145 * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y');
2146 *
2147 * If `.` or `[]` are part of an actual property name, they can be escaped by
2148 * adding two backslashes before them.
2149 *
2150 * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
2151 *
2152 * `.deep` and `.nested` can be combined.
2153 *
2154 * expect({a: {b: [{c: 3}]}})
2155 * .to.have.deep.nested.property('a.b[0]', {c: 3});
2156 *
2157 * `.own` and `.nested` cannot be combined.
2158 *
2159 * Add `.not` earlier in the chain to negate `.property`.
2160 *
2161 * expect({a: 1}).to.not.have.property('b');
2162 *
2163 * However, it's dangerous to negate `.property` when providing `val`. The
2164 * problem is that it creates uncertain expectations by asserting that the
2165 * target either doesn't have a property with the given key `name`, or that it
2166 * does have a property with the given key `name` but its value isn't equal to
2167 * the given `val`. It's often best to identify the exact output that's
2168 * expected, and then write an assertion that only accepts that exact output.
2169 *
2170 * When the target isn't expected to have a property with the given key
2171 * `name`, it's often best to assert exactly that.
2172 *
2173 * expect({b: 2}).to.not.have.property('a'); // Recommended
2174 * expect({b: 2}).to.not.have.property('a', 1); // Not recommended
2175 *
2176 * When the target is expected to have a property with the given key `name`,
2177 * it's often best to assert that the property has its expected value, rather
2178 * than asserting that it doesn't have one of many unexpected values.
2179 *
2180 * expect({a: 3}).to.have.property('a', 3); // Recommended
2181 * expect({a: 3}).to.not.have.property('a', 1); // Not recommended
2182 *
2183 * `.property` changes the target of any assertions that follow in the chain
2184 * to be the value of the property from the original target object.
2185 *
2186 * expect({a: 1}).to.have.property('a').that.is.a('number');
2187 *
2188 * `.property` accepts an optional `msg` argument which is a custom error
2189 * message to show when the assertion fails. The message can also be given as
2190 * the second argument to `expect`. When not providing `val`, only use the
2191 * second form.
2192 *
2193 * // Recommended
2194 * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??');
2195 * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2);
2196 * expect({a: 1}, 'nooo why fail??').to.have.property('b');
2197 *
2198 * // Not recommended
2199 * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??');
2200 *
2201 * The above assertion isn't the same thing as not providing `val`. Instead,
2202 * it's asserting that the target object has a `b` property that's equal to
2203 * `undefined`.
2204 *
2205 * The assertions `.ownProperty` and `.haveOwnProperty` can be used
2206 * interchangeably with `.own.property`.
2207 *
2208 * @name property
2209 * @param {String} name
2210 * @param {Mixed} val (optional)
2211 * @param {String} msg _optional_
2212 * @returns value of property for chaining
2213 * @namespace BDD
2214 * @api public
2215 */
2216
2217 function assertProperty (name, val, msg) {
2218 if (msg) flag(this, 'message', msg);
2219
2220 var isNested = flag(this, 'nested')
2221 , isOwn = flag(this, 'own')
2222 , flagMsg = flag(this, 'message')
2223 , obj = flag(this, 'object')
2224 , ssfi = flag(this, 'ssfi')
2225 , nameType = typeof name;
2226
2227 flagMsg = flagMsg ? flagMsg + ': ' : '';
2228
2229 if (isNested) {
2230 if (nameType !== 'string') {
2231 throw new AssertionError(
2232 flagMsg + 'the argument to property must be a string when using nested syntax',
2233 undefined,
2234 ssfi
2235 );
2236 }
2237 } else {
2238 if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') {
2239 throw new AssertionError(
2240 flagMsg + 'the argument to property must be a string, number, or symbol',
2241 undefined,
2242 ssfi
2243 );
2244 }
2245 }
2246
2247 if (isNested && isOwn) {
2248 throw new AssertionError(
2249 flagMsg + 'The "nested" and "own" flags cannot be combined.',
2250 undefined,
2251 ssfi
2252 );
2253 }
2254
2255 if (obj === null || obj === undefined) {
2256 throw new AssertionError(
2257 flagMsg + 'Target cannot be null or undefined.',
2258 undefined,
2259 ssfi
2260 );
2261 }
2262
2263 var isDeep = flag(this, 'deep')
2264 , negate = flag(this, 'negate')
2265 , pathInfo = isNested ? _.getPathInfo(obj, name) : null
2266 , value = isNested ? pathInfo.value : obj[name]
2267 , isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2;;
2268
2269 var descriptor = '';
2270 if (isDeep) descriptor += 'deep ';
2271 if (isOwn) descriptor += 'own ';
2272 if (isNested) descriptor += 'nested ';
2273 descriptor += 'property ';
2274
2275 var hasProperty;
2276 if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name);
2277 else if (isNested) hasProperty = pathInfo.exists;
2278 else hasProperty = _.hasProperty(obj, name);
2279
2280 // When performing a negated assertion for both name and val, merely having
2281 // a property with the given name isn't enough to cause the assertion to
2282 // fail. It must both have a property with the given name, and the value of
2283 // that property must equal the given val. Therefore, skip this assertion in
2284 // favor of the next.
2285 if (!negate || arguments.length === 1) {
2286 this.assert(
2287 hasProperty
2288 , 'expected #{this} to have ' + descriptor + _.inspect(name)
2289 , 'expected #{this} to not have ' + descriptor + _.inspect(name));
2290 }
2291
2292 if (arguments.length > 1) {
2293 this.assert(
2294 hasProperty && isEql(val, value)
2295 , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
2296 , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}'
2297 , val
2298 , value
2299 );
2300 }
2301
2302 flag(this, 'object', value);
2303 }
2304
2305 Assertion.addMethod('property', assertProperty);
2306
2307 function assertOwnProperty (name, value, msg) {
2308 flag(this, 'own', true);
2309 assertProperty.apply(this, arguments);
2310 }
2311
2312 Assertion.addMethod('ownProperty', assertOwnProperty);
2313 Assertion.addMethod('haveOwnProperty', assertOwnProperty);
2314
2315 /**
2316 * ### .ownPropertyDescriptor(name[, descriptor[, msg]])
2317 *
2318 * Asserts that the target has its own property descriptor with the given key
2319 * `name`. Enumerable and non-enumerable properties are included in the
2320 * search.
2321 *
2322 * expect({a: 1}).to.have.ownPropertyDescriptor('a');
2323 *
2324 * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that
2325 * the property's descriptor is deeply equal to the given `descriptor`. See
2326 * the `deep-eql` project page for info on the deep equality algorithm:
2327 * https://github.com/chaijs/deep-eql.
2328 *
2329 * expect({a: 1}).to.have.ownPropertyDescriptor('a', {
2330 * configurable: true,
2331 * enumerable: true,
2332 * writable: true,
2333 * value: 1,
2334 * });
2335 *
2336 * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`.
2337 *
2338 * expect({a: 1}).to.not.have.ownPropertyDescriptor('b');
2339 *
2340 * However, it's dangerous to negate `.ownPropertyDescriptor` when providing
2341 * a `descriptor`. The problem is that it creates uncertain expectations by
2342 * asserting that the target either doesn't have a property descriptor with
2343 * the given key `name`, or that it does have a property descriptor with the
2344 * given key `name` but it’s not deeply equal to the given `descriptor`. It's
2345 * often best to identify the exact output that's expected, and then write an
2346 * assertion that only accepts that exact output.
2347 *
2348 * When the target isn't expected to have a property descriptor with the given
2349 * key `name`, it's often best to assert exactly that.
2350 *
2351 * // Recommended
2352 * expect({b: 2}).to.not.have.ownPropertyDescriptor('a');
2353 *
2354 * // Not recommended
2355 * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', {
2356 * configurable: true,
2357 * enumerable: true,
2358 * writable: true,
2359 * value: 1,
2360 * });
2361 *
2362 * When the target is expected to have a property descriptor with the given
2363 * key `name`, it's often best to assert that the property has its expected
2364 * descriptor, rather than asserting that it doesn't have one of many
2365 * unexpected descriptors.
2366 *
2367 * // Recommended
2368 * expect({a: 3}).to.have.ownPropertyDescriptor('a', {
2369 * configurable: true,
2370 * enumerable: true,
2371 * writable: true,
2372 * value: 3,
2373 * });
2374 *
2375 * // Not recommended
2376 * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', {
2377 * configurable: true,
2378 * enumerable: true,
2379 * writable: true,
2380 * value: 1,
2381 * });
2382 *
2383 * `.ownPropertyDescriptor` changes the target of any assertions that follow
2384 * in the chain to be the value of the property descriptor from the original
2385 * target object.
2386 *
2387 * expect({a: 1}).to.have.ownPropertyDescriptor('a')
2388 * .that.has.property('enumerable', true);
2389 *
2390 * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a
2391 * custom error message to show when the assertion fails. The message can also
2392 * be given as the second argument to `expect`. When not providing
2393 * `descriptor`, only use the second form.
2394 *
2395 * // Recommended
2396 * expect({a: 1}).to.have.ownPropertyDescriptor('a', {
2397 * configurable: true,
2398 * enumerable: true,
2399 * writable: true,
2400 * value: 2,
2401 * }, 'nooo why fail??');
2402 *
2403 * // Recommended
2404 * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', {
2405 * configurable: true,
2406 * enumerable: true,
2407 * writable: true,
2408 * value: 2,
2409 * });
2410 *
2411 * // Recommended
2412 * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b');
2413 *
2414 * // Not recommended
2415 * expect({a: 1})
2416 * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??');
2417 *
2418 * The above assertion isn't the same thing as not providing `descriptor`.
2419 * Instead, it's asserting that the target object has a `b` property
2420 * descriptor that's deeply equal to `undefined`.
2421 *
2422 * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with
2423 * `.ownPropertyDescriptor`.
2424 *
2425 * @name ownPropertyDescriptor
2426 * @alias haveOwnPropertyDescriptor
2427 * @param {String} name
2428 * @param {Object} descriptor _optional_
2429 * @param {String} msg _optional_
2430 * @namespace BDD
2431 * @api public
2432 */
2433
2434 function assertOwnPropertyDescriptor (name, descriptor, msg) {
2435 if (typeof descriptor === 'string') {
2436 msg = descriptor;
2437 descriptor = null;
2438 }
2439 if (msg) flag(this, 'message', msg);
2440 var obj = flag(this, 'object');
2441 var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);
2442 var eql = flag(this, 'eql');
2443 if (actualDescriptor && descriptor) {
2444 this.assert(
2445 eql(descriptor, actualDescriptor)
2446 , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)
2447 , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)
2448 , descriptor
2449 , actualDescriptor
2450 , true
2451 );
2452 } else {
2453 this.assert(
2454 actualDescriptor
2455 , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)
2456 , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)
2457 );
2458 }
2459 flag(this, 'object', actualDescriptor);
2460 }
2461
2462 Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);
2463 Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);
2464
2465 /**
2466 * ### .lengthOf(n[, msg])
2467 *
2468 * Asserts that the target's `length` or `size` is equal to the given number
2469 * `n`.
2470 *
2471 * expect([1, 2, 3]).to.have.lengthOf(3);
2472 * expect('foo').to.have.lengthOf(3);
2473 * expect(new Set([1, 2, 3])).to.have.lengthOf(3);
2474 * expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3);
2475 *
2476 * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often
2477 * best to assert that the target's `length` property is equal to its expected
2478 * value, rather than not equal to one of many unexpected values.
2479 *
2480 * expect('foo').to.have.lengthOf(3); // Recommended
2481 * expect('foo').to.not.have.lengthOf(4); // Not recommended
2482 *
2483 * `.lengthOf` accepts an optional `msg` argument which is a custom error
2484 * message to show when the assertion fails. The message can also be given as
2485 * the second argument to `expect`.
2486 *
2487 * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??');
2488 * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2);
2489 *
2490 * `.lengthOf` can also be used as a language chain, causing all `.above`,
2491 * `.below`, `.least`, `.most`, and `.within` assertions that follow in the
2492 * chain to use the target's `length` property as the target. However, it's
2493 * often best to assert that the target's `length` property is equal to its
2494 * expected length, rather than asserting that its `length` property falls
2495 * within some range of values.
2496 *
2497 * // Recommended
2498 * expect([1, 2, 3]).to.have.lengthOf(3);
2499 *
2500 * // Not recommended
2501 * expect([1, 2, 3]).to.have.lengthOf.above(2);
2502 * expect([1, 2, 3]).to.have.lengthOf.below(4);
2503 * expect([1, 2, 3]).to.have.lengthOf.at.least(3);
2504 * expect([1, 2, 3]).to.have.lengthOf.at.most(3);
2505 * expect([1, 2, 3]).to.have.lengthOf.within(2,4);
2506 *
2507 * Due to a compatibility issue, the alias `.length` can't be chained directly
2508 * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used
2509 * interchangeably with `.lengthOf` in every situation. It's recommended to
2510 * always use `.lengthOf` instead of `.length`.
2511 *
2512 * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error
2513 * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected
2514 *
2515 * @name lengthOf
2516 * @alias length
2517 * @param {Number} n
2518 * @param {String} msg _optional_
2519 * @namespace BDD
2520 * @api public
2521 */
2522
2523 function assertLengthChain () {
2524 flag(this, 'doLength', true);
2525 }
2526
2527 function assertLength (n, msg) {
2528 if (msg) flag(this, 'message', msg);
2529 var obj = flag(this, 'object')
2530 , objType = _.type(obj).toLowerCase()
2531 , flagMsg = flag(this, 'message')
2532 , ssfi = flag(this, 'ssfi')
2533 , descriptor = 'length'
2534 , itemsCount;
2535
2536 switch (objType) {
2537 case 'map':
2538 case 'set':
2539 descriptor = 'size';
2540 itemsCount = obj.size;
2541 break;
2542 default:
2543 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
2544 itemsCount = obj.length;
2545 }
2546
2547 this.assert(
2548 itemsCount == n
2549 , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}'
2550 , 'expected #{this} to not have a ' + descriptor + ' of #{act}'
2551 , n
2552 , itemsCount
2553 );
2554 }
2555
2556 Assertion.addChainableMethod('length', assertLength, assertLengthChain);
2557 Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain);
2558
2559 /**
2560 * ### .match(re[, msg])
2561 *
2562 * Asserts that the target matches the given regular expression `re`.
2563 *
2564 * expect('foobar').to.match(/^foo/);
2565 *
2566 * Add `.not` earlier in the chain to negate `.match`.
2567 *
2568 * expect('foobar').to.not.match(/taco/);
2569 *
2570 * `.match` accepts an optional `msg` argument which is a custom error message
2571 * to show when the assertion fails. The message can also be given as the
2572 * second argument to `expect`.
2573 *
2574 * expect('foobar').to.match(/taco/, 'nooo why fail??');
2575 * expect('foobar', 'nooo why fail??').to.match(/taco/);
2576 *
2577 * The alias `.matches` can be used interchangeably with `.match`.
2578 *
2579 * @name match
2580 * @alias matches
2581 * @param {RegExp} re
2582 * @param {String} msg _optional_
2583 * @namespace BDD
2584 * @api public
2585 */
2586 function assertMatch(re, msg) {
2587 if (msg) flag(this, 'message', msg);
2588 var obj = flag(this, 'object');
2589 this.assert(
2590 re.exec(obj)
2591 , 'expected #{this} to match ' + re
2592 , 'expected #{this} not to match ' + re
2593 );
2594 }
2595
2596 Assertion.addMethod('match', assertMatch);
2597 Assertion.addMethod('matches', assertMatch);
2598
2599 /**
2600 * ### .string(str[, msg])
2601 *
2602 * Asserts that the target string contains the given substring `str`.
2603 *
2604 * expect('foobar').to.have.string('bar');
2605 *
2606 * Add `.not` earlier in the chain to negate `.string`.
2607 *
2608 * expect('foobar').to.not.have.string('taco');
2609 *
2610 * `.string` accepts an optional `msg` argument which is a custom error
2611 * message to show when the assertion fails. The message can also be given as
2612 * the second argument to `expect`.
2613 *
2614 * expect('foobar').to.have.string('taco', 'nooo why fail??');
2615 * expect('foobar', 'nooo why fail??').to.have.string('taco');
2616 *
2617 * @name string
2618 * @param {String} str
2619 * @param {String} msg _optional_
2620 * @namespace BDD
2621 * @api public
2622 */
2623
2624 Assertion.addMethod('string', function (str, msg) {
2625 if (msg) flag(this, 'message', msg);
2626 var obj = flag(this, 'object')
2627 , flagMsg = flag(this, 'message')
2628 , ssfi = flag(this, 'ssfi');
2629 new Assertion(obj, flagMsg, ssfi, true).is.a('string');
2630
2631 this.assert(
2632 ~obj.indexOf(str)
2633 , 'expected #{this} to contain ' + _.inspect(str)
2634 , 'expected #{this} to not contain ' + _.inspect(str)
2635 );
2636 });
2637
2638 /**
2639 * ### .keys(key1[, key2[, ...]])
2640 *
2641 * Asserts that the target object, array, map, or set has the given keys. Only
2642 * the target's own inherited properties are included in the search.
2643 *
2644 * When the target is an object or array, keys can be provided as one or more
2645 * string arguments, a single array argument, or a single object argument. In
2646 * the latter case, only the keys in the given object matter; the values are
2647 * ignored.
2648 *
2649 * expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
2650 * expect(['x', 'y']).to.have.all.keys(0, 1);
2651 *
2652 * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']);
2653 * expect(['x', 'y']).to.have.all.keys([0, 1]);
2654 *
2655 * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5
2656 * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5
2657 *
2658 * When the target is a map or set, each key must be provided as a separate
2659 * argument.
2660 *
2661 * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b');
2662 * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b');
2663 *
2664 * Because `.keys` does different things based on the target's type, it's
2665 * important to check the target's type before using `.keys`. See the `.a` doc
2666 * for info on testing a target's type.
2667 *
2668 * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b');
2669 *
2670 * By default, strict (`===`) equality is used to compare keys of maps and
2671 * sets. Add `.deep` earlier in the chain to use deep equality instead. See
2672 * the `deep-eql` project page for info on the deep equality algorithm:
2673 * https://github.com/chaijs/deep-eql.
2674 *
2675 * // Target set deeply (but not strictly) has key `{a: 1}`
2676 * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]);
2677 * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]);
2678 *
2679 * By default, the target must have all of the given keys and no more. Add
2680 * `.any` earlier in the chain to only require that the target have at least
2681 * one of the given keys. Also, add `.not` earlier in the chain to negate
2682 * `.keys`. It's often best to add `.any` when negating `.keys`, and to use
2683 * `.all` when asserting `.keys` without negation.
2684 *
2685 * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts
2686 * exactly what's expected of the output, whereas `.not.all.keys` creates
2687 * uncertain expectations.
2688 *
2689 * // Recommended; asserts that target doesn't have any of the given keys
2690 * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
2691 *
2692 * // Not recommended; asserts that target doesn't have all of the given
2693 * // keys but may or may not have some of them
2694 * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd');
2695 *
2696 * When asserting `.keys` without negation, `.all` is preferred because
2697 * `.all.keys` asserts exactly what's expected of the output, whereas
2698 * `.any.keys` creates uncertain expectations.
2699 *
2700 * // Recommended; asserts that target has all the given keys
2701 * expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
2702 *
2703 * // Not recommended; asserts that target has at least one of the given
2704 * // keys but may or may not have more of them
2705 * expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
2706 *
2707 * Note that `.all` is used by default when neither `.all` nor `.any` appear
2708 * earlier in the chain. However, it's often best to add `.all` anyway because
2709 * it improves readability.
2710 *
2711 * // Both assertions are identical
2712 * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended
2713 * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended
2714 *
2715 * Add `.include` earlier in the chain to require that the target's keys be a
2716 * superset of the expected keys, rather than identical sets.
2717 *
2718 * // Target object's keys are a superset of ['a', 'b'] but not identical
2719 * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');
2720 * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');
2721 *
2722 * However, if `.any` and `.include` are combined, only the `.any` takes
2723 * effect. The `.include` is ignored in this case.
2724 *
2725 * // Both assertions are identical
2726 * expect({a: 1}).to.have.any.keys('a', 'b');
2727 * expect({a: 1}).to.include.any.keys('a', 'b');
2728 *
2729 * A custom error message can be given as the second argument to `expect`.
2730 *
2731 * expect({a: 1}, 'nooo why fail??').to.have.key('b');
2732 *
2733 * The alias `.key` can be used interchangeably with `.keys`.
2734 *
2735 * @name keys
2736 * @alias key
2737 * @param {...String|Array|Object} keys
2738 * @namespace BDD
2739 * @api public
2740 */
2741
2742 function assertKeys (keys) {
2743 var obj = flag(this, 'object')
2744 , objType = _.type(obj)
2745 , keysType = _.type(keys)
2746 , ssfi = flag(this, 'ssfi')
2747 , isDeep = flag(this, 'deep')
2748 , str
2749 , deepStr = ''
2750 , actual
2751 , ok = true
2752 , flagMsg = flag(this, 'message');
2753
2754 flagMsg = flagMsg ? flagMsg + ': ' : '';
2755 var mixedArgsMsg = flagMsg + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments';
2756
2757 if (objType === 'Map' || objType === 'Set') {
2758 deepStr = isDeep ? 'deeply ' : '';
2759 actual = [];
2760
2761 // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach.
2762 obj.forEach(function (val, key) { actual.push(key) });
2763
2764 if (keysType !== 'Array') {
2765 keys = Array.prototype.slice.call(arguments);
2766 }
2767 } else {
2768 actual = _.getOwnEnumerableProperties(obj);
2769
2770 switch (keysType) {
2771 case 'Array':
2772 if (arguments.length > 1) {
2773 throw new AssertionError(mixedArgsMsg, undefined, ssfi);
2774 }
2775 break;
2776 case 'Object':
2777 if (arguments.length > 1) {
2778 throw new AssertionError(mixedArgsMsg, undefined, ssfi);
2779 }
2780 keys = Object.keys(keys);
2781 break;
2782 default:
2783 keys = Array.prototype.slice.call(arguments);
2784 }
2785
2786 // Only stringify non-Symbols because Symbols would become "Symbol()"
2787 keys = keys.map(function (val) {
2788 return typeof val === 'symbol' ? val : String(val);
2789 });
2790 }
2791
2792 if (!keys.length) {
2793 throw new AssertionError(flagMsg + 'keys required', undefined, ssfi);
2794 }
2795
2796 var len = keys.length
2797 , any = flag(this, 'any')
2798 , all = flag(this, 'all')
2799 , expected = keys
2800 , isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2;
2801
2802 if (!any && !all) {
2803 all = true;
2804 }
2805
2806 // Has any
2807 if (any) {
2808 ok = expected.some(function(expectedKey) {
2809 return actual.some(function(actualKey) {
2810 return isEql(expectedKey, actualKey);
2811 });
2812 });
2813 }
2814
2815 // Has all
2816 if (all) {
2817 ok = expected.every(function(expectedKey) {
2818 return actual.some(function(actualKey) {
2819 return isEql(expectedKey, actualKey);
2820 });
2821 });
2822
2823 if (!flag(this, 'contains')) {
2824 ok = ok && keys.length == actual.length;
2825 }
2826 }
2827
2828 // Key string
2829 if (len > 1) {
2830 keys = keys.map(function(key) {
2831 return _.inspect(key);
2832 });
2833 var last = keys.pop();
2834 if (all) {
2835 str = keys.join(', ') + ', and ' + last;
2836 }
2837 if (any) {
2838 str = keys.join(', ') + ', or ' + last;
2839 }
2840 } else {
2841 str = _.inspect(keys[0]);
2842 }
2843
2844 // Form
2845 str = (len > 1 ? 'keys ' : 'key ') + str;
2846
2847 // Have / include
2848 str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
2849
2850 // Assertion
2851 this.assert(
2852 ok
2853 , 'expected #{this} to ' + deepStr + str
2854 , 'expected #{this} to not ' + deepStr + str
2855 , expected.slice(0).sort(_.compareByInspect)
2856 , actual.sort(_.compareByInspect)
2857 , true
2858 );
2859 }
2860
2861 Assertion.addMethod('keys', assertKeys);
2862 Assertion.addMethod('key', assertKeys);
2863
2864 /**
2865 * ### .throw([errorLike], [errMsgMatcher], [msg])
2866 *
2867 * When no arguments are provided, `.throw` invokes the target function and
2868 * asserts that an error is thrown.
2869 *
2870 * var badFn = function () { throw new TypeError('Illegal salmon!'); };
2871 *
2872 * expect(badFn).to.throw();
2873 *
2874 * When one argument is provided, and it's an error constructor, `.throw`
2875 * invokes the target function and asserts that an error is thrown that's an
2876 * instance of that error constructor.
2877 *
2878 * var badFn = function () { throw new TypeError('Illegal salmon!'); };
2879 *
2880 * expect(badFn).to.throw(TypeError);
2881 *
2882 * When one argument is provided, and it's an error instance, `.throw` invokes
2883 * the target function and asserts that an error is thrown that's strictly
2884 * (`===`) equal to that error instance.
2885 *
2886 * var err = new TypeError('Illegal salmon!');
2887 * var badFn = function () { throw err; };
2888 *
2889 * expect(badFn).to.throw(err);
2890 *
2891 * When one argument is provided, and it's a string, `.throw` invokes the
2892 * target function and asserts that an error is thrown with a message that
2893 * contains that string.
2894 *
2895 * var badFn = function () { throw new TypeError('Illegal salmon!'); };
2896 *
2897 * expect(badFn).to.throw('salmon');
2898 *
2899 * When one argument is provided, and it's a regular expression, `.throw`
2900 * invokes the target function and asserts that an error is thrown with a
2901 * message that matches that regular expression.
2902 *
2903 * var badFn = function () { throw new TypeError('Illegal salmon!'); };
2904 *
2905 * expect(badFn).to.throw(/salmon/);
2906 *
2907 * When two arguments are provided, and the first is an error instance or
2908 * constructor, and the second is a string or regular expression, `.throw`
2909 * invokes the function and asserts that an error is thrown that fulfills both
2910 * conditions as described above.
2911 *
2912 * var err = new TypeError('Illegal salmon!');
2913 * var badFn = function () { throw err; };
2914 *
2915 * expect(badFn).to.throw(TypeError, 'salmon');
2916 * expect(badFn).to.throw(TypeError, /salmon/);
2917 * expect(badFn).to.throw(err, 'salmon');
2918 * expect(badFn).to.throw(err, /salmon/);
2919 *
2920 * Add `.not` earlier in the chain to negate `.throw`.
2921 *
2922 * var goodFn = function () {};
2923 *
2924 * expect(goodFn).to.not.throw();
2925 *
2926 * However, it's dangerous to negate `.throw` when providing any arguments.
2927 * The problem is that it creates uncertain expectations by asserting that the
2928 * target either doesn't throw an error, or that it throws an error but of a
2929 * different type than the given type, or that it throws an error of the given
2930 * type but with a message that doesn't include the given string. It's often
2931 * best to identify the exact output that's expected, and then write an
2932 * assertion that only accepts that exact output.
2933 *
2934 * When the target isn't expected to throw an error, it's often best to assert
2935 * exactly that.
2936 *
2937 * var goodFn = function () {};
2938 *
2939 * expect(goodFn).to.not.throw(); // Recommended
2940 * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended
2941 *
2942 * When the target is expected to throw an error, it's often best to assert
2943 * that the error is of its expected type, and has a message that includes an
2944 * expected string, rather than asserting that it doesn't have one of many
2945 * unexpected types, and doesn't have a message that includes some string.
2946 *
2947 * var badFn = function () { throw new TypeError('Illegal salmon!'); };
2948 *
2949 * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended
2950 * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended
2951 *
2952 * `.throw` changes the target of any assertions that follow in the chain to
2953 * be the error object that's thrown.
2954 *
2955 * var err = new TypeError('Illegal salmon!');
2956 * err.code = 42;
2957 * var badFn = function () { throw err; };
2958 *
2959 * expect(badFn).to.throw(TypeError).with.property('code', 42);
2960 *
2961 * `.throw` accepts an optional `msg` argument which is a custom error message
2962 * to show when the assertion fails. The message can also be given as the
2963 * second argument to `expect`. When not providing two arguments, always use
2964 * the second form.
2965 *
2966 * var goodFn = function () {};
2967 *
2968 * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??');
2969 * expect(goodFn, 'nooo why fail??').to.throw();
2970 *
2971 * Due to limitations in ES5, `.throw` may not always work as expected when
2972 * using a transpiler such as Babel or TypeScript. In particular, it may
2973 * produce unexpected results when subclassing the built-in `Error` object and
2974 * then passing the subclassed constructor to `.throw`. See your transpiler's
2975 * docs for details:
2976 *
2977 * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes))
2978 * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work))
2979 *
2980 * Beware of some common mistakes when using the `throw` assertion. One common
2981 * mistake is to accidentally invoke the function yourself instead of letting
2982 * the `throw` assertion invoke the function for you. For example, when
2983 * testing if a function named `fn` throws, provide `fn` instead of `fn()` as
2984 * the target for the assertion.
2985 *
2986 * expect(fn).to.throw(); // Good! Tests `fn` as desired
2987 * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn`
2988 *
2989 * If you need to assert that your function `fn` throws when passed certain
2990 * arguments, then wrap a call to `fn` inside of another function.
2991 *
2992 * expect(function () { fn(42); }).to.throw(); // Function expression
2993 * expect(() => fn(42)).to.throw(); // ES6 arrow function
2994 *
2995 * Another common mistake is to provide an object method (or any stand-alone
2996 * function that relies on `this`) as the target of the assertion. Doing so is
2997 * problematic because the `this` context will be lost when the function is
2998 * invoked by `.throw`; there's no way for it to know what `this` is supposed
2999 * to be. There are two ways around this problem. One solution is to wrap the
3000 * method or function call inside of another function. Another solution is to
3001 * use `bind`.
3002 *
3003 * expect(function () { cat.meow(); }).to.throw(); // Function expression
3004 * expect(() => cat.meow()).to.throw(); // ES6 arrow function
3005 * expect(cat.meow.bind(cat)).to.throw(); // Bind
3006 *
3007 * Finally, it's worth mentioning that it's a best practice in JavaScript to
3008 * only throw `Error` and derivatives of `Error` such as `ReferenceError`,
3009 * `TypeError`, and user-defined objects that extend `Error`. No other type of
3010 * value will generate a stack trace when initialized. With that said, the
3011 * `throw` assertion does technically support any type of value being thrown,
3012 * not just `Error` and its derivatives.
3013 *
3014 * The aliases `.throws` and `.Throw` can be used interchangeably with
3015 * `.throw`.
3016 *
3017 * @name throw
3018 * @alias throws
3019 * @alias Throw
3020 * @param {Error|ErrorConstructor} errorLike
3021 * @param {String|RegExp} errMsgMatcher error message
3022 * @param {String} msg _optional_
3023 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
3024 * @returns error for chaining (null if no error)
3025 * @namespace BDD
3026 * @api public
3027 */
3028
3029 function assertThrows (errorLike, errMsgMatcher, msg) {
3030 if (msg) flag(this, 'message', msg);
3031 var obj = flag(this, 'object')
3032 , ssfi = flag(this, 'ssfi')
3033 , flagMsg = flag(this, 'message')
3034 , negate = flag(this, 'negate') || false;
3035 new Assertion(obj, flagMsg, ssfi, true).is.a('function');
3036
3037 if (errorLike instanceof RegExp || typeof errorLike === 'string') {
3038 errMsgMatcher = errorLike;
3039 errorLike = null;
3040 }
3041
3042 var caughtErr;
3043 try {
3044 obj();
3045 } catch (err) {
3046 caughtErr = err;
3047 }
3048
3049 // If we have the negate flag enabled and at least one valid argument it means we do expect an error
3050 // but we want it to match a given set of criteria
3051 var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined;
3052
3053 // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible
3054 // See Issue #551 and PR #683@GitHub
3055 var everyArgIsDefined = Boolean(errorLike && errMsgMatcher);
3056 var errorLikeFail = false;
3057 var errMsgMatcherFail = false;
3058
3059 // Checking if error was thrown
3060 if (everyArgIsUndefined || !everyArgIsUndefined && !negate) {
3061 // We need this to display results correctly according to their types
3062 var errorLikeString = 'an error';
3063 if (errorLike instanceof Error) {
3064 errorLikeString = '#{exp}';
3065 } else if (errorLike) {
3066 errorLikeString = _.checkError.getConstructorName(errorLike);
3067 }
3068
3069 this.assert(
3070 caughtErr
3071 , 'expected #{this} to throw ' + errorLikeString
3072 , 'expected #{this} to not throw an error but #{act} was thrown'
3073 , errorLike && errorLike.toString()
3074 , (caughtErr instanceof Error ?
3075 caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr &&
3076 _.checkError.getConstructorName(caughtErr)))
3077 );
3078 }
3079
3080 if (errorLike && caughtErr) {
3081 // We should compare instances only if `errorLike` is an instance of `Error`
3082 if (errorLike instanceof Error) {
3083 var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike);
3084
3085 if (isCompatibleInstance === negate) {
3086 // These checks were created to ensure we won't fail too soon when we've got both args and a negate
3087 // See Issue #551 and PR #683@GitHub
3088 if (everyArgIsDefined && negate) {
3089 errorLikeFail = true;
3090 } else {
3091 this.assert(
3092 negate
3093 , 'expected #{this} to throw #{exp} but #{act} was thrown'
3094 , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '')
3095 , errorLike.toString()
3096 , caughtErr.toString()
3097 );
3098 }
3099 }
3100 }
3101
3102 var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike);
3103 if (isCompatibleConstructor === negate) {
3104 if (everyArgIsDefined && negate) {
3105 errorLikeFail = true;
3106 } else {
3107 this.assert(
3108 negate
3109 , 'expected #{this} to throw #{exp} but #{act} was thrown'
3110 , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '')
3111 , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike))
3112 , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr))
3113 );
3114 }
3115 }
3116 }
3117
3118 if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) {
3119 // Here we check compatible messages
3120 var placeholder = 'including';
3121 if (errMsgMatcher instanceof RegExp) {
3122 placeholder = 'matching'
3123 }
3124
3125 var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher);
3126 if (isCompatibleMessage === negate) {
3127 if (everyArgIsDefined && negate) {
3128 errMsgMatcherFail = true;
3129 } else {
3130 this.assert(
3131 negate
3132 , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}'
3133 , 'expected #{this} to throw error not ' + placeholder + ' #{exp}'
3134 , errMsgMatcher
3135 , _.checkError.getMessage(caughtErr)
3136 );
3137 }
3138 }
3139 }
3140
3141 // If both assertions failed and both should've matched we throw an error
3142 if (errorLikeFail && errMsgMatcherFail) {
3143 this.assert(
3144 negate
3145 , 'expected #{this} to throw #{exp} but #{act} was thrown'
3146 , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '')
3147 , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike))
3148 , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr))
3149 );
3150 }
3151
3152 flag(this, 'object', caughtErr);
3153 };
3154
3155 Assertion.addMethod('throw', assertThrows);
3156 Assertion.addMethod('throws', assertThrows);
3157 Assertion.addMethod('Throw', assertThrows);
3158
3159 /**
3160 * ### .respondTo(method[, msg])
3161 *
3162 * When the target is a non-function object, `.respondTo` asserts that the
3163 * target has a method with the given name `method`. The method can be own or
3164 * inherited, and it can be enumerable or non-enumerable.
3165 *
3166 * function Cat () {}
3167 * Cat.prototype.meow = function () {};
3168 *
3169 * expect(new Cat()).to.respondTo('meow');
3170 *
3171 * When the target is a function, `.respondTo` asserts that the target's
3172 * `prototype` property has a method with the given name `method`. Again, the
3173 * method can be own or inherited, and it can be enumerable or non-enumerable.
3174 *
3175 * function Cat () {}
3176 * Cat.prototype.meow = function () {};
3177 *
3178 * expect(Cat).to.respondTo('meow');
3179 *
3180 * Add `.itself` earlier in the chain to force `.respondTo` to treat the
3181 * target as a non-function object, even if it's a function. Thus, it asserts
3182 * that the target has a method with the given name `method`, rather than
3183 * asserting that the target's `prototype` property has a method with the
3184 * given name `method`.
3185 *
3186 * function Cat () {}
3187 * Cat.prototype.meow = function () {};
3188 * Cat.hiss = function () {};
3189 *
3190 * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
3191 *
3192 * When not adding `.itself`, it's important to check the target's type before
3193 * using `.respondTo`. See the `.a` doc for info on checking a target's type.
3194 *
3195 * function Cat () {}
3196 * Cat.prototype.meow = function () {};
3197 *
3198 * expect(new Cat()).to.be.an('object').that.respondsTo('meow');
3199 *
3200 * Add `.not` earlier in the chain to negate `.respondTo`.
3201 *
3202 * function Dog () {}
3203 * Dog.prototype.bark = function () {};
3204 *
3205 * expect(new Dog()).to.not.respondTo('meow');
3206 *
3207 * `.respondTo` accepts an optional `msg` argument which is a custom error
3208 * message to show when the assertion fails. The message can also be given as
3209 * the second argument to `expect`.
3210 *
3211 * expect({}).to.respondTo('meow', 'nooo why fail??');
3212 * expect({}, 'nooo why fail??').to.respondTo('meow');
3213 *
3214 * The alias `.respondsTo` can be used interchangeably with `.respondTo`.
3215 *
3216 * @name respondTo
3217 * @alias respondsTo
3218 * @param {String} method
3219 * @param {String} msg _optional_
3220 * @namespace BDD
3221 * @api public
3222 */
3223
3224 function respondTo (method, msg) {
3225 if (msg) flag(this, 'message', msg);
3226 var obj = flag(this, 'object')
3227 , itself = flag(this, 'itself')
3228 , context = ('function' === typeof obj && !itself)
3229 ? obj.prototype[method]
3230 : obj[method];
3231
3232 this.assert(
3233 'function' === typeof context
3234 , 'expected #{this} to respond to ' + _.inspect(method)
3235 , 'expected #{this} to not respond to ' + _.inspect(method)
3236 );
3237 }
3238
3239 Assertion.addMethod('respondTo', respondTo);
3240 Assertion.addMethod('respondsTo', respondTo);
3241
3242 /**
3243 * ### .itself
3244 *
3245 * Forces all `.respondTo` assertions that follow in the chain to behave as if
3246 * the target is a non-function object, even if it's a function. Thus, it
3247 * causes `.respondTo` to assert that the target has a method with the given
3248 * name, rather than asserting that the target's `prototype` property has a
3249 * method with the given name.
3250 *
3251 * function Cat () {}
3252 * Cat.prototype.meow = function () {};
3253 * Cat.hiss = function () {};
3254 *
3255 * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
3256 *
3257 * @name itself
3258 * @namespace BDD
3259 * @api public
3260 */
3261
3262 Assertion.addProperty('itself', function () {
3263 flag(this, 'itself', true);
3264 });
3265
3266 /**
3267 * ### .satisfy(matcher[, msg])
3268 *
3269 * Invokes the given `matcher` function with the target being passed as the
3270 * first argument, and asserts that the value returned is truthy.
3271 *
3272 * expect(1).to.satisfy(function(num) {
3273 * return num > 0;
3274 * });
3275 *
3276 * Add `.not` earlier in the chain to negate `.satisfy`.
3277 *
3278 * expect(1).to.not.satisfy(function(num) {
3279 * return num > 2;
3280 * });
3281 *
3282 * `.satisfy` accepts an optional `msg` argument which is a custom error
3283 * message to show when the assertion fails. The message can also be given as
3284 * the second argument to `expect`.
3285 *
3286 * expect(1).to.satisfy(function(num) {
3287 * return num > 2;
3288 * }, 'nooo why fail??');
3289 *
3290 * expect(1, 'nooo why fail??').to.satisfy(function(num) {
3291 * return num > 2;
3292 * });
3293 *
3294 * The alias `.satisfies` can be used interchangeably with `.satisfy`.
3295 *
3296 * @name satisfy
3297 * @alias satisfies
3298 * @param {Function} matcher
3299 * @param {String} msg _optional_
3300 * @namespace BDD
3301 * @api public
3302 */
3303
3304 function satisfy (matcher, msg) {
3305 if (msg) flag(this, 'message', msg);
3306 var obj = flag(this, 'object');
3307 var result = matcher(obj);
3308 this.assert(
3309 result
3310 , 'expected #{this} to satisfy ' + _.objDisplay(matcher)
3311 , 'expected #{this} to not satisfy' + _.objDisplay(matcher)
3312 , flag(this, 'negate') ? false : true
3313 , result
3314 );
3315 }
3316
3317 Assertion.addMethod('satisfy', satisfy);
3318 Assertion.addMethod('satisfies', satisfy);
3319
3320 /**
3321 * ### .closeTo(expected, delta[, msg])
3322 *
3323 * Asserts that the target is a number that's within a given +/- `delta` range
3324 * of the given number `expected`. However, it's often best to assert that the
3325 * target is equal to its expected value.
3326 *
3327 * // Recommended
3328 * expect(1.5).to.equal(1.5);
3329 *
3330 * // Not recommended
3331 * expect(1.5).to.be.closeTo(1, 0.5);
3332 * expect(1.5).to.be.closeTo(2, 0.5);
3333 * expect(1.5).to.be.closeTo(1, 1);
3334 *
3335 * Add `.not` earlier in the chain to negate `.closeTo`.
3336 *
3337 * expect(1.5).to.equal(1.5); // Recommended
3338 * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended
3339 *
3340 * `.closeTo` accepts an optional `msg` argument which is a custom error
3341 * message to show when the assertion fails. The message can also be given as
3342 * the second argument to `expect`.
3343 *
3344 * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??');
3345 * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1);
3346 *
3347 * The alias `.approximately` can be used interchangeably with `.closeTo`.
3348 *
3349 * @name closeTo
3350 * @alias approximately
3351 * @param {Number} expected
3352 * @param {Number} delta
3353 * @param {String} msg _optional_
3354 * @namespace BDD
3355 * @api public
3356 */
3357
3358 function closeTo(expected, delta, msg) {
3359 if (msg) flag(this, 'message', msg);
3360 var obj = flag(this, 'object')
3361 , flagMsg = flag(this, 'message')
3362 , ssfi = flag(this, 'ssfi');
3363
3364 new Assertion(obj, flagMsg, ssfi, true).is.a('number');
3365 if (typeof expected !== 'number' || typeof delta !== 'number') {
3366 flagMsg = flagMsg ? flagMsg + ': ' : '';
3367 var deltaMessage = delta === undefined ? ", and a delta is required" : "";
3368 throw new AssertionError(
3369 flagMsg + 'the arguments to closeTo or approximately must be numbers' + deltaMessage,
3370 undefined,
3371 ssfi
3372 );
3373 }
3374
3375 this.assert(
3376 Math.abs(obj - expected) <= delta
3377 , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
3378 , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
3379 );
3380 }
3381
3382 Assertion.addMethod('closeTo', closeTo);
3383 Assertion.addMethod('approximately', closeTo);
3384
3385 // Note: Duplicates are ignored if testing for inclusion instead of sameness.
3386 function isSubsetOf(subset, superset, cmp, contains, ordered) {
3387 if (!contains) {
3388 if (subset.length !== superset.length) return false;
3389 superset = superset.slice();
3390 }
3391
3392 return subset.every(function(elem, idx) {
3393 if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx];
3394
3395 if (!cmp) {
3396 var matchIdx = superset.indexOf(elem);
3397 if (matchIdx === -1) return false;
3398
3399 // Remove match from superset so not counted twice if duplicate in subset.
3400 if (!contains) superset.splice(matchIdx, 1);
3401 return true;
3402 }
3403
3404 return superset.some(function(elem2, matchIdx) {
3405 if (!cmp(elem, elem2)) return false;
3406
3407 // Remove match from superset so not counted twice if duplicate in subset.
3408 if (!contains) superset.splice(matchIdx, 1);
3409 return true;
3410 });
3411 });
3412 }
3413
3414 /**
3415 * ### .members(set[, msg])
3416 *
3417 * Asserts that the target array has the same members as the given array
3418 * `set`.
3419 *
3420 * expect([1, 2, 3]).to.have.members([2, 1, 3]);
3421 * expect([1, 2, 2]).to.have.members([2, 1, 2]);
3422 *
3423 * By default, members are compared using strict (`===`) equality. Add `.deep`
3424 * earlier in the chain to use deep equality instead. See the `deep-eql`
3425 * project page for info on the deep equality algorithm:
3426 * https://github.com/chaijs/deep-eql.
3427 *
3428 * // Target array deeply (but not strictly) has member `{a: 1}`
3429 * expect([{a: 1}]).to.have.deep.members([{a: 1}]);
3430 * expect([{a: 1}]).to.not.have.members([{a: 1}]);
3431 *
3432 * By default, order doesn't matter. Add `.ordered` earlier in the chain to
3433 * require that members appear in the same order.
3434 *
3435 * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]);
3436 * expect([1, 2, 3]).to.have.members([2, 1, 3])
3437 * .but.not.ordered.members([2, 1, 3]);
3438 *
3439 * By default, both arrays must be the same size. Add `.include` earlier in
3440 * the chain to require that the target's members be a superset of the
3441 * expected members. Note that duplicates are ignored in the subset when
3442 * `.include` is added.
3443 *
3444 * // Target array is a superset of [1, 2] but not identical
3445 * expect([1, 2, 3]).to.include.members([1, 2]);
3446 * expect([1, 2, 3]).to.not.have.members([1, 2]);
3447 *
3448 * // Duplicates in the subset are ignored
3449 * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
3450 *
3451 * `.deep`, `.ordered`, and `.include` can all be combined. However, if
3452 * `.include` and `.ordered` are combined, the ordering begins at the start of
3453 * both arrays.
3454 *
3455 * expect([{a: 1}, {b: 2}, {c: 3}])
3456 * .to.include.deep.ordered.members([{a: 1}, {b: 2}])
3457 * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]);
3458 *
3459 * Add `.not` earlier in the chain to negate `.members`. However, it's
3460 * dangerous to do so. The problem is that it creates uncertain expectations
3461 * by asserting that the target array doesn't have all of the same members as
3462 * the given array `set` but may or may not have some of them. It's often best
3463 * to identify the exact output that's expected, and then write an assertion
3464 * that only accepts that exact output.
3465 *
3466 * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended
3467 * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended
3468 *
3469 * `.members` accepts an optional `msg` argument which is a custom error
3470 * message to show when the assertion fails. The message can also be given as
3471 * the second argument to `expect`.
3472 *
3473 * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??');
3474 * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]);
3475 *
3476 * @name members
3477 * @param {Array} set
3478 * @param {String} msg _optional_
3479 * @namespace BDD
3480 * @api public
3481 */
3482
3483 Assertion.addMethod('members', function (subset, msg) {
3484 if (msg) flag(this, 'message', msg);
3485 var obj = flag(this, 'object')
3486 , flagMsg = flag(this, 'message')
3487 , ssfi = flag(this, 'ssfi');
3488
3489 new Assertion(obj, flagMsg, ssfi, true).to.be.an('array');
3490 new Assertion(subset, flagMsg, ssfi, true).to.be.an('array');
3491
3492 var contains = flag(this, 'contains');
3493 var ordered = flag(this, 'ordered');
3494
3495 var subject, failMsg, failNegateMsg;
3496
3497 if (contains) {
3498 subject = ordered ? 'an ordered superset' : 'a superset';
3499 failMsg = 'expected #{this} to be ' + subject + ' of #{exp}';
3500 failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}';
3501 } else {
3502 subject = ordered ? 'ordered members' : 'members';
3503 failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}';
3504 failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}';
3505 }
3506
3507 var cmp = flag(this, 'deep') ? flag(this, 'eql') : undefined;
3508
3509 this.assert(
3510 isSubsetOf(subset, obj, cmp, contains, ordered)
3511 , failMsg
3512 , failNegateMsg
3513 , subset
3514 , obj
3515 , true
3516 );
3517 });
3518
3519 /**
3520 * ### .oneOf(list[, msg])
3521 *
3522 * Asserts that the target is a member of the given array `list`. However,
3523 * it's often best to assert that the target is equal to its expected value.
3524 *
3525 * expect(1).to.equal(1); // Recommended
3526 * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended
3527 *
3528 * Comparisons are performed using strict (`===`) equality.
3529 *
3530 * Add `.not` earlier in the chain to negate `.oneOf`.
3531 *
3532 * expect(1).to.equal(1); // Recommended
3533 * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended
3534 *
3535 * It can also be chained with `.contain` or `.include`, which will work with
3536 * both arrays and strings:
3537 *
3538 * expect('Today is sunny').to.contain.oneOf(['sunny', 'cloudy'])
3539 * expect('Today is rainy').to.not.contain.oneOf(['sunny', 'cloudy'])
3540 * expect([1,2,3]).to.contain.oneOf([3,4,5])
3541 * expect([1,2,3]).to.not.contain.oneOf([4,5,6])
3542 *
3543 * `.oneOf` accepts an optional `msg` argument which is a custom error message
3544 * to show when the assertion fails. The message can also be given as the
3545 * second argument to `expect`.
3546 *
3547 * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??');
3548 * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]);
3549 *
3550 * @name oneOf
3551 * @param {Array<*>} list
3552 * @param {String} msg _optional_
3553 * @namespace BDD
3554 * @api public
3555 */
3556
3557 function oneOf (list, msg) {
3558 if (msg) flag(this, 'message', msg);
3559 var expected = flag(this, 'object')
3560 , flagMsg = flag(this, 'message')
3561 , ssfi = flag(this, 'ssfi')
3562 , contains = flag(this, 'contains')
3563 , isDeep = flag(this, 'deep')
3564 , eql = flag(this, 'eql');
3565 new Assertion(list, flagMsg, ssfi, true).to.be.an('array');
3566
3567 if (contains) {
3568 this.assert(
3569 list.some(function(possibility) { return expected.indexOf(possibility) > -1 })
3570 , 'expected #{this} to contain one of #{exp}'
3571 , 'expected #{this} to not contain one of #{exp}'
3572 , list
3573 , expected
3574 );
3575 } else {
3576 if (isDeep) {
3577 this.assert(
3578 list.some(function(possibility) { return eql(expected, possibility) })
3579 , 'expected #{this} to deeply equal one of #{exp}'
3580 , 'expected #{this} to deeply equal one of #{exp}'
3581 , list
3582 , expected
3583 );
3584 } else {
3585 this.assert(
3586 list.indexOf(expected) > -1
3587 , 'expected #{this} to be one of #{exp}'
3588 , 'expected #{this} to not be one of #{exp}'
3589 , list
3590 , expected
3591 );
3592 }
3593 }
3594 }
3595
3596 Assertion.addMethod('oneOf', oneOf);
3597
3598 /**
3599 * ### .change(subject[, prop[, msg]])
3600 *
3601 * When one argument is provided, `.change` asserts that the given function
3602 * `subject` returns a different value when it's invoked before the target
3603 * function compared to when it's invoked afterward. However, it's often best
3604 * to assert that `subject` is equal to its expected value.
3605 *
3606 * var dots = ''
3607 * , addDot = function () { dots += '.'; }
3608 * , getDots = function () { return dots; };
3609 *
3610 * // Recommended
3611 * expect(getDots()).to.equal('');
3612 * addDot();
3613 * expect(getDots()).to.equal('.');
3614 *
3615 * // Not recommended
3616 * expect(addDot).to.change(getDots);
3617 *
3618 * When two arguments are provided, `.change` asserts that the value of the
3619 * given object `subject`'s `prop` property is different before invoking the
3620 * target function compared to afterward.
3621 *
3622 * var myObj = {dots: ''}
3623 * , addDot = function () { myObj.dots += '.'; };
3624 *
3625 * // Recommended
3626 * expect(myObj).to.have.property('dots', '');
3627 * addDot();
3628 * expect(myObj).to.have.property('dots', '.');
3629 *
3630 * // Not recommended
3631 * expect(addDot).to.change(myObj, 'dots');
3632 *
3633 * Strict (`===`) equality is used to compare before and after values.
3634 *
3635 * Add `.not` earlier in the chain to negate `.change`.
3636 *
3637 * var dots = ''
3638 * , noop = function () {}
3639 * , getDots = function () { return dots; };
3640 *
3641 * expect(noop).to.not.change(getDots);
3642 *
3643 * var myObj = {dots: ''}
3644 * , noop = function () {};
3645 *
3646 * expect(noop).to.not.change(myObj, 'dots');
3647 *
3648 * `.change` accepts an optional `msg` argument which is a custom error
3649 * message to show when the assertion fails. The message can also be given as
3650 * the second argument to `expect`. When not providing two arguments, always
3651 * use the second form.
3652 *
3653 * var myObj = {dots: ''}
3654 * , addDot = function () { myObj.dots += '.'; };
3655 *
3656 * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??');
3657 *
3658 * var dots = ''
3659 * , addDot = function () { dots += '.'; }
3660 * , getDots = function () { return dots; };
3661 *
3662 * expect(addDot, 'nooo why fail??').to.not.change(getDots);
3663 *
3664 * `.change` also causes all `.by` assertions that follow in the chain to
3665 * assert how much a numeric subject was increased or decreased by. However,
3666 * it's dangerous to use `.change.by`. The problem is that it creates
3667 * uncertain expectations by asserting that the subject either increases by
3668 * the given delta, or that it decreases by the given delta. It's often best
3669 * to identify the exact output that's expected, and then write an assertion
3670 * that only accepts that exact output.
3671 *
3672 * var myObj = {val: 1}
3673 * , addTwo = function () { myObj.val += 2; }
3674 * , subtractTwo = function () { myObj.val -= 2; };
3675 *
3676 * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
3677 * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended
3678 *
3679 * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
3680 * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended
3681 *
3682 * The alias `.changes` can be used interchangeably with `.change`.
3683 *
3684 * @name change
3685 * @alias changes
3686 * @param {String} subject
3687 * @param {String} prop name _optional_
3688 * @param {String} msg _optional_
3689 * @namespace BDD
3690 * @api public
3691 */
3692
3693 function assertChanges (subject, prop, msg) {
3694 if (msg) flag(this, 'message', msg);
3695 var fn = flag(this, 'object')
3696 , flagMsg = flag(this, 'message')
3697 , ssfi = flag(this, 'ssfi');
3698 new Assertion(fn, flagMsg, ssfi, true).is.a('function');
3699
3700 var initial;
3701 if (!prop) {
3702 new Assertion(subject, flagMsg, ssfi, true).is.a('function');
3703 initial = subject();
3704 } else {
3705 new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
3706 initial = subject[prop];
3707 }
3708
3709 fn();
3710
3711 var final = prop === undefined || prop === null ? subject() : subject[prop];
3712 var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
3713
3714 // This gets flagged because of the .by(delta) assertion
3715 flag(this, 'deltaMsgObj', msgObj);
3716 flag(this, 'initialDeltaValue', initial);
3717 flag(this, 'finalDeltaValue', final);
3718 flag(this, 'deltaBehavior', 'change');
3719 flag(this, 'realDelta', final !== initial);
3720
3721 this.assert(
3722 initial !== final
3723 , 'expected ' + msgObj + ' to change'
3724 , 'expected ' + msgObj + ' to not change'
3725 );
3726 }
3727
3728 Assertion.addMethod('change', assertChanges);
3729 Assertion.addMethod('changes', assertChanges);
3730
3731 /**
3732 * ### .increase(subject[, prop[, msg]])
3733 *
3734 * When one argument is provided, `.increase` asserts that the given function
3735 * `subject` returns a greater number when it's invoked after invoking the
3736 * target function compared to when it's invoked beforehand. `.increase` also
3737 * causes all `.by` assertions that follow in the chain to assert how much
3738 * greater of a number is returned. It's often best to assert that the return
3739 * value increased by the expected amount, rather than asserting it increased
3740 * by any amount.
3741 *
3742 * var val = 1
3743 * , addTwo = function () { val += 2; }
3744 * , getVal = function () { return val; };
3745 *
3746 * expect(addTwo).to.increase(getVal).by(2); // Recommended
3747 * expect(addTwo).to.increase(getVal); // Not recommended
3748 *
3749 * When two arguments are provided, `.increase` asserts that the value of the
3750 * given object `subject`'s `prop` property is greater after invoking the
3751 * target function compared to beforehand.
3752 *
3753 * var myObj = {val: 1}
3754 * , addTwo = function () { myObj.val += 2; };
3755 *
3756 * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
3757 * expect(addTwo).to.increase(myObj, 'val'); // Not recommended
3758 *
3759 * Add `.not` earlier in the chain to negate `.increase`. However, it's
3760 * dangerous to do so. The problem is that it creates uncertain expectations
3761 * by asserting that the subject either decreases, or that it stays the same.
3762 * It's often best to identify the exact output that's expected, and then
3763 * write an assertion that only accepts that exact output.
3764 *
3765 * When the subject is expected to decrease, it's often best to assert that it
3766 * decreased by the expected amount.
3767 *
3768 * var myObj = {val: 1}
3769 * , subtractTwo = function () { myObj.val -= 2; };
3770 *
3771 * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
3772 * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended
3773 *
3774 * When the subject is expected to stay the same, it's often best to assert
3775 * exactly that.
3776 *
3777 * var myObj = {val: 1}
3778 * , noop = function () {};
3779 *
3780 * expect(noop).to.not.change(myObj, 'val'); // Recommended
3781 * expect(noop).to.not.increase(myObj, 'val'); // Not recommended
3782 *
3783 * `.increase` accepts an optional `msg` argument which is a custom error
3784 * message to show when the assertion fails. The message can also be given as
3785 * the second argument to `expect`. When not providing two arguments, always
3786 * use the second form.
3787 *
3788 * var myObj = {val: 1}
3789 * , noop = function () {};
3790 *
3791 * expect(noop).to.increase(myObj, 'val', 'nooo why fail??');
3792 *
3793 * var val = 1
3794 * , noop = function () {}
3795 * , getVal = function () { return val; };
3796 *
3797 * expect(noop, 'nooo why fail??').to.increase(getVal);
3798 *
3799 * The alias `.increases` can be used interchangeably with `.increase`.
3800 *
3801 * @name increase
3802 * @alias increases
3803 * @param {String|Function} subject
3804 * @param {String} prop name _optional_
3805 * @param {String} msg _optional_
3806 * @namespace BDD
3807 * @api public
3808 */
3809
3810 function assertIncreases (subject, prop, msg) {
3811 if (msg) flag(this, 'message', msg);
3812 var fn = flag(this, 'object')
3813 , flagMsg = flag(this, 'message')
3814 , ssfi = flag(this, 'ssfi');
3815 new Assertion(fn, flagMsg, ssfi, true).is.a('function');
3816
3817 var initial;
3818 if (!prop) {
3819 new Assertion(subject, flagMsg, ssfi, true).is.a('function');
3820 initial = subject();
3821 } else {
3822 new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
3823 initial = subject[prop];
3824 }
3825
3826 // Make sure that the target is a number
3827 new Assertion(initial, flagMsg, ssfi, true).is.a('number');
3828
3829 fn();
3830
3831 var final = prop === undefined || prop === null ? subject() : subject[prop];
3832 var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
3833
3834 flag(this, 'deltaMsgObj', msgObj);
3835 flag(this, 'initialDeltaValue', initial);
3836 flag(this, 'finalDeltaValue', final);
3837 flag(this, 'deltaBehavior', 'increase');
3838 flag(this, 'realDelta', final - initial);
3839
3840 this.assert(
3841 final - initial > 0
3842 , 'expected ' + msgObj + ' to increase'
3843 , 'expected ' + msgObj + ' to not increase'
3844 );
3845 }
3846
3847 Assertion.addMethod('increase', assertIncreases);
3848 Assertion.addMethod('increases', assertIncreases);
3849
3850 /**
3851 * ### .decrease(subject[, prop[, msg]])
3852 *
3853 * When one argument is provided, `.decrease` asserts that the given function
3854 * `subject` returns a lesser number when it's invoked after invoking the
3855 * target function compared to when it's invoked beforehand. `.decrease` also
3856 * causes all `.by` assertions that follow in the chain to assert how much
3857 * lesser of a number is returned. It's often best to assert that the return
3858 * value decreased by the expected amount, rather than asserting it decreased
3859 * by any amount.
3860 *
3861 * var val = 1
3862 * , subtractTwo = function () { val -= 2; }
3863 * , getVal = function () { return val; };
3864 *
3865 * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended
3866 * expect(subtractTwo).to.decrease(getVal); // Not recommended
3867 *
3868 * When two arguments are provided, `.decrease` asserts that the value of the
3869 * given object `subject`'s `prop` property is lesser after invoking the
3870 * target function compared to beforehand.
3871 *
3872 * var myObj = {val: 1}
3873 * , subtractTwo = function () { myObj.val -= 2; };
3874 *
3875 * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
3876 * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended
3877 *
3878 * Add `.not` earlier in the chain to negate `.decrease`. However, it's
3879 * dangerous to do so. The problem is that it creates uncertain expectations
3880 * by asserting that the subject either increases, or that it stays the same.
3881 * It's often best to identify the exact output that's expected, and then
3882 * write an assertion that only accepts that exact output.
3883 *
3884 * When the subject is expected to increase, it's often best to assert that it
3885 * increased by the expected amount.
3886 *
3887 * var myObj = {val: 1}
3888 * , addTwo = function () { myObj.val += 2; };
3889 *
3890 * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
3891 * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended
3892 *
3893 * When the subject is expected to stay the same, it's often best to assert
3894 * exactly that.
3895 *
3896 * var myObj = {val: 1}
3897 * , noop = function () {};
3898 *
3899 * expect(noop).to.not.change(myObj, 'val'); // Recommended
3900 * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended
3901 *
3902 * `.decrease` accepts an optional `msg` argument which is a custom error
3903 * message to show when the assertion fails. The message can also be given as
3904 * the second argument to `expect`. When not providing two arguments, always
3905 * use the second form.
3906 *
3907 * var myObj = {val: 1}
3908 * , noop = function () {};
3909 *
3910 * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??');
3911 *
3912 * var val = 1
3913 * , noop = function () {}
3914 * , getVal = function () { return val; };
3915 *
3916 * expect(noop, 'nooo why fail??').to.decrease(getVal);
3917 *
3918 * The alias `.decreases` can be used interchangeably with `.decrease`.
3919 *
3920 * @name decrease
3921 * @alias decreases
3922 * @param {String|Function} subject
3923 * @param {String} prop name _optional_
3924 * @param {String} msg _optional_
3925 * @namespace BDD
3926 * @api public
3927 */
3928
3929 function assertDecreases (subject, prop, msg) {
3930 if (msg) flag(this, 'message', msg);
3931 var fn = flag(this, 'object')
3932 , flagMsg = flag(this, 'message')
3933 , ssfi = flag(this, 'ssfi');
3934 new Assertion(fn, flagMsg, ssfi, true).is.a('function');
3935
3936 var initial;
3937 if (!prop) {
3938 new Assertion(subject, flagMsg, ssfi, true).is.a('function');
3939 initial = subject();
3940 } else {
3941 new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
3942 initial = subject[prop];
3943 }
3944
3945 // Make sure that the target is a number
3946 new Assertion(initial, flagMsg, ssfi, true).is.a('number');
3947
3948 fn();
3949
3950 var final = prop === undefined || prop === null ? subject() : subject[prop];
3951 var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
3952
3953 flag(this, 'deltaMsgObj', msgObj);
3954 flag(this, 'initialDeltaValue', initial);
3955 flag(this, 'finalDeltaValue', final);
3956 flag(this, 'deltaBehavior', 'decrease');
3957 flag(this, 'realDelta', initial - final);
3958
3959 this.assert(
3960 final - initial < 0
3961 , 'expected ' + msgObj + ' to decrease'
3962 , 'expected ' + msgObj + ' to not decrease'
3963 );
3964 }
3965
3966 Assertion.addMethod('decrease', assertDecreases);
3967 Assertion.addMethod('decreases', assertDecreases);
3968
3969 /**
3970 * ### .by(delta[, msg])
3971 *
3972 * When following an `.increase` assertion in the chain, `.by` asserts that
3973 * the subject of the `.increase` assertion increased by the given `delta`.
3974 *
3975 * var myObj = {val: 1}
3976 * , addTwo = function () { myObj.val += 2; };
3977 *
3978 * expect(addTwo).to.increase(myObj, 'val').by(2);
3979 *
3980 * When following a `.decrease` assertion in the chain, `.by` asserts that the
3981 * subject of the `.decrease` assertion decreased by the given `delta`.
3982 *
3983 * var myObj = {val: 1}
3984 * , subtractTwo = function () { myObj.val -= 2; };
3985 *
3986 * expect(subtractTwo).to.decrease(myObj, 'val').by(2);
3987 *
3988 * When following a `.change` assertion in the chain, `.by` asserts that the
3989 * subject of the `.change` assertion either increased or decreased by the
3990 * given `delta`. However, it's dangerous to use `.change.by`. The problem is
3991 * that it creates uncertain expectations. It's often best to identify the
3992 * exact output that's expected, and then write an assertion that only accepts
3993 * that exact output.
3994 *
3995 * var myObj = {val: 1}
3996 * , addTwo = function () { myObj.val += 2; }
3997 * , subtractTwo = function () { myObj.val -= 2; };
3998 *
3999 * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
4000 * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended
4001 *
4002 * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
4003 * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended
4004 *
4005 * Add `.not` earlier in the chain to negate `.by`. However, it's often best
4006 * to assert that the subject changed by its expected delta, rather than
4007 * asserting that it didn't change by one of countless unexpected deltas.
4008 *
4009 * var myObj = {val: 1}
4010 * , addTwo = function () { myObj.val += 2; };
4011 *
4012 * // Recommended
4013 * expect(addTwo).to.increase(myObj, 'val').by(2);
4014 *
4015 * // Not recommended
4016 * expect(addTwo).to.increase(myObj, 'val').but.not.by(3);
4017 *
4018 * `.by` accepts an optional `msg` argument which is a custom error message to
4019 * show when the assertion fails. The message can also be given as the second
4020 * argument to `expect`.
4021 *
4022 * var myObj = {val: 1}
4023 * , addTwo = function () { myObj.val += 2; };
4024 *
4025 * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??');
4026 * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3);
4027 *
4028 * @name by
4029 * @param {Number} delta
4030 * @param {String} msg _optional_
4031 * @namespace BDD
4032 * @api public
4033 */
4034
4035 function assertDelta(delta, msg) {
4036 if (msg) flag(this, 'message', msg);
4037
4038 var msgObj = flag(this, 'deltaMsgObj');
4039 var initial = flag(this, 'initialDeltaValue');
4040 var final = flag(this, 'finalDeltaValue');
4041 var behavior = flag(this, 'deltaBehavior');
4042 var realDelta = flag(this, 'realDelta');
4043
4044 var expression;
4045 if (behavior === 'change') {
4046 expression = Math.abs(final - initial) === Math.abs(delta);
4047 } else {
4048 expression = realDelta === Math.abs(delta);
4049 }
4050
4051 this.assert(
4052 expression
4053 , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta
4054 , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta
4055 );
4056 }
4057
4058 Assertion.addMethod('by', assertDelta);
4059
4060 /**
4061 * ### .extensible
4062 *
4063 * Asserts that the target is extensible, which means that new properties can
4064 * be added to it. Primitives are never extensible.
4065 *
4066 * expect({a: 1}).to.be.extensible;
4067 *
4068 * Add `.not` earlier in the chain to negate `.extensible`.
4069 *
4070 * var nonExtensibleObject = Object.preventExtensions({})
4071 * , sealedObject = Object.seal({})
4072 * , frozenObject = Object.freeze({});
4073 *
4074 * expect(nonExtensibleObject).to.not.be.extensible;
4075 * expect(sealedObject).to.not.be.extensible;
4076 * expect(frozenObject).to.not.be.extensible;
4077 * expect(1).to.not.be.extensible;
4078 *
4079 * A custom error message can be given as the second argument to `expect`.
4080 *
4081 * expect(1, 'nooo why fail??').to.be.extensible;
4082 *
4083 * @name extensible
4084 * @namespace BDD
4085 * @api public
4086 */
4087
4088 Assertion.addProperty('extensible', function() {
4089 var obj = flag(this, 'object');
4090
4091 // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
4092 // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.
4093 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
4094 // The following provides ES6 behavior for ES5 environments.
4095
4096 var isExtensible = obj === Object(obj) && Object.isExtensible(obj);
4097
4098 this.assert(
4099 isExtensible
4100 , 'expected #{this} to be extensible'
4101 , 'expected #{this} to not be extensible'
4102 );
4103 });
4104
4105 /**
4106 * ### .sealed
4107 *
4108 * Asserts that the target is sealed, which means that new properties can't be
4109 * added to it, and its existing properties can't be reconfigured or deleted.
4110 * However, it's possible that its existing properties can still be reassigned
4111 * to different values. Primitives are always sealed.
4112 *
4113 * var sealedObject = Object.seal({});
4114 * var frozenObject = Object.freeze({});
4115 *
4116 * expect(sealedObject).to.be.sealed;
4117 * expect(frozenObject).to.be.sealed;
4118 * expect(1).to.be.sealed;
4119 *
4120 * Add `.not` earlier in the chain to negate `.sealed`.
4121 *
4122 * expect({a: 1}).to.not.be.sealed;
4123 *
4124 * A custom error message can be given as the second argument to `expect`.
4125 *
4126 * expect({a: 1}, 'nooo why fail??').to.be.sealed;
4127 *
4128 * @name sealed
4129 * @namespace BDD
4130 * @api public
4131 */
4132
4133 Assertion.addProperty('sealed', function() {
4134 var obj = flag(this, 'object');
4135
4136 // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
4137 // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.
4138 // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed
4139 // The following provides ES6 behavior for ES5 environments.
4140
4141 var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true;
4142
4143 this.assert(
4144 isSealed
4145 , 'expected #{this} to be sealed'
4146 , 'expected #{this} to not be sealed'
4147 );
4148 });
4149
4150 /**
4151 * ### .frozen
4152 *
4153 * Asserts that the target is frozen, which means that new properties can't be
4154 * added to it, and its existing properties can't be reassigned to different
4155 * values, reconfigured, or deleted. Primitives are always frozen.
4156 *
4157 * var frozenObject = Object.freeze({});
4158 *
4159 * expect(frozenObject).to.be.frozen;
4160 * expect(1).to.be.frozen;
4161 *
4162 * Add `.not` earlier in the chain to negate `.frozen`.
4163 *
4164 * expect({a: 1}).to.not.be.frozen;
4165 *
4166 * A custom error message can be given as the second argument to `expect`.
4167 *
4168 * expect({a: 1}, 'nooo why fail??').to.be.frozen;
4169 *
4170 * @name frozen
4171 * @namespace BDD
4172 * @api public
4173 */
4174
4175 Assertion.addProperty('frozen', function() {
4176 var obj = flag(this, 'object');
4177
4178 // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
4179 // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.
4180 // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen
4181 // The following provides ES6 behavior for ES5 environments.
4182
4183 var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true;
4184
4185 this.assert(
4186 isFrozen
4187 , 'expected #{this} to be frozen'
4188 , 'expected #{this} to not be frozen'
4189 );
4190 });
4191
4192 /**
4193 * ### .finite
4194 *
4195 * Asserts that the target is a number, and isn't `NaN` or positive/negative
4196 * `Infinity`.
4197 *
4198 * expect(1).to.be.finite;
4199 *
4200 * Add `.not` earlier in the chain to negate `.finite`. However, it's
4201 * dangerous to do so. The problem is that it creates uncertain expectations
4202 * by asserting that the subject either isn't a number, or that it's `NaN`, or
4203 * that it's positive `Infinity`, or that it's negative `Infinity`. It's often
4204 * best to identify the exact output that's expected, and then write an
4205 * assertion that only accepts that exact output.
4206 *
4207 * When the target isn't expected to be a number, it's often best to assert
4208 * that it's the expected type, rather than asserting that it isn't one of
4209 * many unexpected types.
4210 *
4211 * expect('foo').to.be.a('string'); // Recommended
4212 * expect('foo').to.not.be.finite; // Not recommended
4213 *
4214 * When the target is expected to be `NaN`, it's often best to assert exactly
4215 * that.
4216 *
4217 * expect(NaN).to.be.NaN; // Recommended
4218 * expect(NaN).to.not.be.finite; // Not recommended
4219 *
4220 * When the target is expected to be positive infinity, it's often best to
4221 * assert exactly that.
4222 *
4223 * expect(Infinity).to.equal(Infinity); // Recommended
4224 * expect(Infinity).to.not.be.finite; // Not recommended
4225 *
4226 * When the target is expected to be negative infinity, it's often best to
4227 * assert exactly that.
4228 *
4229 * expect(-Infinity).to.equal(-Infinity); // Recommended
4230 * expect(-Infinity).to.not.be.finite; // Not recommended
4231 *
4232 * A custom error message can be given as the second argument to `expect`.
4233 *
4234 * expect('foo', 'nooo why fail??').to.be.finite;
4235 *
4236 * @name finite
4237 * @namespace BDD
4238 * @api public
4239 */
4240
4241 Assertion.addProperty('finite', function(msg) {
4242 var obj = flag(this, 'object');
4243
4244 this.assert(
4245 typeof obj === 'number' && isFinite(obj)
4246 , 'expected #{this} to be a finite number'
4247 , 'expected #{this} to not be a finite number'
4248 );
4249 });
4250 };
4251
4252 },{}],6:[function(require,module,exports){
4253 /*!
4254 * chai
4255 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
4256 * MIT Licensed
4257 */
4258
4259 module.exports = function (chai, util) {
4260 /*!
4261 * Chai dependencies.
4262 */
4263
4264 var Assertion = chai.Assertion
4265 , flag = util.flag;
4266
4267 /*!
4268 * Module export.
4269 */
4270
4271 /**
4272 * ### assert(expression, message)
4273 *
4274 * Write your own test expressions.
4275 *
4276 * assert('foo' !== 'bar', 'foo is not bar');
4277 * assert(Array.isArray([]), 'empty arrays are arrays');
4278 *
4279 * @param {Mixed} expression to test for truthiness
4280 * @param {String} message to display on error
4281 * @name assert
4282 * @namespace Assert
4283 * @api public
4284 */
4285
4286 var assert = chai.assert = function (express, errmsg) {
4287 var test = new Assertion(null, null, chai.assert, true);
4288 test.assert(
4289 express
4290 , errmsg
4291 , '[ negation message unavailable ]'
4292 );
4293 };
4294
4295 /**
4296 * ### .fail([message])
4297 * ### .fail(actual, expected, [message], [operator])
4298 *
4299 * Throw a failure. Node.js `assert` module-compatible.
4300 *
4301 * assert.fail();
4302 * assert.fail("custom error message");
4303 * assert.fail(1, 2);
4304 * assert.fail(1, 2, "custom error message");
4305 * assert.fail(1, 2, "custom error message", ">");
4306 * assert.fail(1, 2, undefined, ">");
4307 *
4308 * @name fail
4309 * @param {Mixed} actual
4310 * @param {Mixed} expected
4311 * @param {String} message
4312 * @param {String} operator
4313 * @namespace Assert
4314 * @api public
4315 */
4316
4317 assert.fail = function (actual, expected, message, operator) {
4318 if (arguments.length < 2) {
4319 // Comply with Node's fail([message]) interface
4320
4321 message = actual;
4322 actual = undefined;
4323 }
4324
4325 message = message || 'assert.fail()';
4326 throw new chai.AssertionError(message, {
4327 actual: actual
4328 , expected: expected
4329 , operator: operator
4330 }, assert.fail);
4331 };
4332
4333 /**
4334 * ### .isOk(object, [message])
4335 *
4336 * Asserts that `object` is truthy.
4337 *
4338 * assert.isOk('everything', 'everything is ok');
4339 * assert.isOk(false, 'this will fail');
4340 *
4341 * @name isOk
4342 * @alias ok
4343 * @param {Mixed} object to test
4344 * @param {String} message
4345 * @namespace Assert
4346 * @api public
4347 */
4348
4349 assert.isOk = function (val, msg) {
4350 new Assertion(val, msg, assert.isOk, true).is.ok;
4351 };
4352
4353 /**
4354 * ### .isNotOk(object, [message])
4355 *
4356 * Asserts that `object` is falsy.
4357 *
4358 * assert.isNotOk('everything', 'this will fail');
4359 * assert.isNotOk(false, 'this will pass');
4360 *
4361 * @name isNotOk
4362 * @alias notOk
4363 * @param {Mixed} object to test
4364 * @param {String} message
4365 * @namespace Assert
4366 * @api public
4367 */
4368
4369 assert.isNotOk = function (val, msg) {
4370 new Assertion(val, msg, assert.isNotOk, true).is.not.ok;
4371 };
4372
4373 /**
4374 * ### .equal(actual, expected, [message])
4375 *
4376 * Asserts non-strict equality (`==`) of `actual` and `expected`.
4377 *
4378 * assert.equal(3, '3', '== coerces values to strings');
4379 *
4380 * @name equal
4381 * @param {Mixed} actual
4382 * @param {Mixed} expected
4383 * @param {String} message
4384 * @namespace Assert
4385 * @api public
4386 */
4387
4388 assert.equal = function (act, exp, msg) {
4389 var test = new Assertion(act, msg, assert.equal, true);
4390
4391 test.assert(
4392 exp == flag(test, 'object')
4393 , 'expected #{this} to equal #{exp}'
4394 , 'expected #{this} to not equal #{act}'
4395 , exp
4396 , act
4397 , true
4398 );
4399 };
4400
4401 /**
4402 * ### .notEqual(actual, expected, [message])
4403 *
4404 * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
4405 *
4406 * assert.notEqual(3, 4, 'these numbers are not equal');
4407 *
4408 * @name notEqual
4409 * @param {Mixed} actual
4410 * @param {Mixed} expected
4411 * @param {String} message
4412 * @namespace Assert
4413 * @api public
4414 */
4415
4416 assert.notEqual = function (act, exp, msg) {
4417 var test = new Assertion(act, msg, assert.notEqual, true);
4418
4419 test.assert(
4420 exp != flag(test, 'object')
4421 , 'expected #{this} to not equal #{exp}'
4422 , 'expected #{this} to equal #{act}'
4423 , exp
4424 , act
4425 , true
4426 );
4427 };
4428
4429 /**
4430 * ### .strictEqual(actual, expected, [message])
4431 *
4432 * Asserts strict equality (`===`) of `actual` and `expected`.
4433 *
4434 * assert.strictEqual(true, true, 'these booleans are strictly equal');
4435 *
4436 * @name strictEqual
4437 * @param {Mixed} actual
4438 * @param {Mixed} expected
4439 * @param {String} message
4440 * @namespace Assert
4441 * @api public
4442 */
4443
4444 assert.strictEqual = function (act, exp, msg) {
4445 new Assertion(act, msg, assert.strictEqual, true).to.equal(exp);
4446 };
4447
4448 /**
4449 * ### .notStrictEqual(actual, expected, [message])
4450 *
4451 * Asserts strict inequality (`!==`) of `actual` and `expected`.
4452 *
4453 * assert.notStrictEqual(3, '3', 'no coercion for strict equality');
4454 *
4455 * @name notStrictEqual
4456 * @param {Mixed} actual
4457 * @param {Mixed} expected
4458 * @param {String} message
4459 * @namespace Assert
4460 * @api public
4461 */
4462
4463 assert.notStrictEqual = function (act, exp, msg) {
4464 new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp);
4465 };
4466
4467 /**
4468 * ### .deepEqual(actual, expected, [message])
4469 *
4470 * Asserts that `actual` is deeply equal to `expected`.
4471 *
4472 * assert.deepEqual({ tea: 'green' }, { tea: 'green' });
4473 *
4474 * @name deepEqual
4475 * @param {Mixed} actual
4476 * @param {Mixed} expected
4477 * @param {String} message
4478 * @alias deepStrictEqual
4479 * @namespace Assert
4480 * @api public
4481 */
4482
4483 assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) {
4484 new Assertion(act, msg, assert.deepEqual, true).to.eql(exp);
4485 };
4486
4487 /**
4488 * ### .notDeepEqual(actual, expected, [message])
4489 *
4490 * Assert that `actual` is not deeply equal to `expected`.
4491 *
4492 * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
4493 *
4494 * @name notDeepEqual
4495 * @param {Mixed} actual
4496 * @param {Mixed} expected
4497 * @param {String} message
4498 * @namespace Assert
4499 * @api public
4500 */
4501
4502 assert.notDeepEqual = function (act, exp, msg) {
4503 new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp);
4504 };
4505
4506 /**
4507 * ### .isAbove(valueToCheck, valueToBeAbove, [message])
4508 *
4509 * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`.
4510 *
4511 * assert.isAbove(5, 2, '5 is strictly greater than 2');
4512 *
4513 * @name isAbove
4514 * @param {Mixed} valueToCheck
4515 * @param {Mixed} valueToBeAbove
4516 * @param {String} message
4517 * @namespace Assert
4518 * @api public
4519 */
4520
4521 assert.isAbove = function (val, abv, msg) {
4522 new Assertion(val, msg, assert.isAbove, true).to.be.above(abv);
4523 };
4524
4525 /**
4526 * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])
4527 *
4528 * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`.
4529 *
4530 * assert.isAtLeast(5, 2, '5 is greater or equal to 2');
4531 * assert.isAtLeast(3, 3, '3 is greater or equal to 3');
4532 *
4533 * @name isAtLeast
4534 * @param {Mixed} valueToCheck
4535 * @param {Mixed} valueToBeAtLeast
4536 * @param {String} message
4537 * @namespace Assert
4538 * @api public
4539 */
4540
4541 assert.isAtLeast = function (val, atlst, msg) {
4542 new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst);
4543 };
4544
4545 /**
4546 * ### .isBelow(valueToCheck, valueToBeBelow, [message])
4547 *
4548 * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`.
4549 *
4550 * assert.isBelow(3, 6, '3 is strictly less than 6');
4551 *
4552 * @name isBelow
4553 * @param {Mixed} valueToCheck
4554 * @param {Mixed} valueToBeBelow
4555 * @param {String} message
4556 * @namespace Assert
4557 * @api public
4558 */
4559
4560 assert.isBelow = function (val, blw, msg) {
4561 new Assertion(val, msg, assert.isBelow, true).to.be.below(blw);
4562 };
4563
4564 /**
4565 * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])
4566 *
4567 * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`.
4568 *
4569 * assert.isAtMost(3, 6, '3 is less than or equal to 6');
4570 * assert.isAtMost(4, 4, '4 is less than or equal to 4');
4571 *
4572 * @name isAtMost
4573 * @param {Mixed} valueToCheck
4574 * @param {Mixed} valueToBeAtMost
4575 * @param {String} message
4576 * @namespace Assert
4577 * @api public
4578 */
4579
4580 assert.isAtMost = function (val, atmst, msg) {
4581 new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst);
4582 };
4583
4584 /**
4585 * ### .isTrue(value, [message])
4586 *
4587 * Asserts that `value` is true.
4588 *
4589 * var teaServed = true;
4590 * assert.isTrue(teaServed, 'the tea has been served');
4591 *
4592 * @name isTrue
4593 * @param {Mixed} value
4594 * @param {String} message
4595 * @namespace Assert
4596 * @api public
4597 */
4598
4599 assert.isTrue = function (val, msg) {
4600 new Assertion(val, msg, assert.isTrue, true).is['true'];
4601 };
4602
4603 /**
4604 * ### .isNotTrue(value, [message])
4605 *
4606 * Asserts that `value` is not true.
4607 *
4608 * var tea = 'tasty chai';
4609 * assert.isNotTrue(tea, 'great, time for tea!');
4610 *
4611 * @name isNotTrue
4612 * @param {Mixed} value
4613 * @param {String} message
4614 * @namespace Assert
4615 * @api public
4616 */
4617
4618 assert.isNotTrue = function (val, msg) {
4619 new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true);
4620 };
4621
4622 /**
4623 * ### .isFalse(value, [message])
4624 *
4625 * Asserts that `value` is false.
4626 *
4627 * var teaServed = false;
4628 * assert.isFalse(teaServed, 'no tea yet? hmm...');
4629 *
4630 * @name isFalse
4631 * @param {Mixed} value
4632 * @param {String} message
4633 * @namespace Assert
4634 * @api public
4635 */
4636
4637 assert.isFalse = function (val, msg) {
4638 new Assertion(val, msg, assert.isFalse, true).is['false'];
4639 };
4640
4641 /**
4642 * ### .isNotFalse(value, [message])
4643 *
4644 * Asserts that `value` is not false.
4645 *
4646 * var tea = 'tasty chai';
4647 * assert.isNotFalse(tea, 'great, time for tea!');
4648 *
4649 * @name isNotFalse
4650 * @param {Mixed} value
4651 * @param {String} message
4652 * @namespace Assert
4653 * @api public
4654 */
4655
4656 assert.isNotFalse = function (val, msg) {
4657 new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false);
4658 };
4659
4660 /**
4661 * ### .isNull(value, [message])
4662 *
4663 * Asserts that `value` is null.
4664 *
4665 * assert.isNull(err, 'there was no error');
4666 *
4667 * @name isNull
4668 * @param {Mixed} value
4669 * @param {String} message
4670 * @namespace Assert
4671 * @api public
4672 */
4673
4674 assert.isNull = function (val, msg) {
4675 new Assertion(val, msg, assert.isNull, true).to.equal(null);
4676 };
4677
4678 /**
4679 * ### .isNotNull(value, [message])
4680 *
4681 * Asserts that `value` is not null.
4682 *
4683 * var tea = 'tasty chai';
4684 * assert.isNotNull(tea, 'great, time for tea!');
4685 *
4686 * @name isNotNull
4687 * @param {Mixed} value
4688 * @param {String} message
4689 * @namespace Assert
4690 * @api public
4691 */
4692
4693 assert.isNotNull = function (val, msg) {
4694 new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null);
4695 };
4696
4697 /**
4698 * ### .isNaN
4699 *
4700 * Asserts that value is NaN.
4701 *
4702 * assert.isNaN(NaN, 'NaN is NaN');
4703 *
4704 * @name isNaN
4705 * @param {Mixed} value
4706 * @param {String} message
4707 * @namespace Assert
4708 * @api public
4709 */
4710
4711 assert.isNaN = function (val, msg) {
4712 new Assertion(val, msg, assert.isNaN, true).to.be.NaN;
4713 };
4714
4715 /**
4716 * ### .isNotNaN
4717 *
4718 * Asserts that value is not NaN.
4719 *
4720 * assert.isNotNaN(4, '4 is not NaN');
4721 *
4722 * @name isNotNaN
4723 * @param {Mixed} value
4724 * @param {String} message
4725 * @namespace Assert
4726 * @api public
4727 */
4728 assert.isNotNaN = function (val, msg) {
4729 new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN;
4730 };
4731
4732 /**
4733 * ### .exists
4734 *
4735 * Asserts that the target is neither `null` nor `undefined`.
4736 *
4737 * var foo = 'hi';
4738 *
4739 * assert.exists(foo, 'foo is neither `null` nor `undefined`');
4740 *
4741 * @name exists
4742 * @param {Mixed} value
4743 * @param {String} message
4744 * @namespace Assert
4745 * @api public
4746 */
4747
4748 assert.exists = function (val, msg) {
4749 new Assertion(val, msg, assert.exists, true).to.exist;
4750 };
4751
4752 /**
4753 * ### .notExists
4754 *
4755 * Asserts that the target is either `null` or `undefined`.
4756 *
4757 * var bar = null
4758 * , baz;
4759 *
4760 * assert.notExists(bar);
4761 * assert.notExists(baz, 'baz is either null or undefined');
4762 *
4763 * @name notExists
4764 * @param {Mixed} value
4765 * @param {String} message
4766 * @namespace Assert
4767 * @api public
4768 */
4769
4770 assert.notExists = function (val, msg) {
4771 new Assertion(val, msg, assert.notExists, true).to.not.exist;
4772 };
4773
4774 /**
4775 * ### .isUndefined(value, [message])
4776 *
4777 * Asserts that `value` is `undefined`.
4778 *
4779 * var tea;
4780 * assert.isUndefined(tea, 'no tea defined');
4781 *
4782 * @name isUndefined
4783 * @param {Mixed} value
4784 * @param {String} message
4785 * @namespace Assert
4786 * @api public
4787 */
4788
4789 assert.isUndefined = function (val, msg) {
4790 new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined);
4791 };
4792
4793 /**
4794 * ### .isDefined(value, [message])
4795 *
4796 * Asserts that `value` is not `undefined`.
4797 *
4798 * var tea = 'cup of chai';
4799 * assert.isDefined(tea, 'tea has been defined');
4800 *
4801 * @name isDefined
4802 * @param {Mixed} value
4803 * @param {String} message
4804 * @namespace Assert
4805 * @api public
4806 */
4807
4808 assert.isDefined = function (val, msg) {
4809 new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined);
4810 };
4811
4812 /**
4813 * ### .isFunction(value, [message])
4814 *
4815 * Asserts that `value` is a function.
4816 *
4817 * function serveTea() { return 'cup of tea'; };
4818 * assert.isFunction(serveTea, 'great, we can have tea now');
4819 *
4820 * @name isFunction
4821 * @param {Mixed} value
4822 * @param {String} message
4823 * @namespace Assert
4824 * @api public
4825 */
4826
4827 assert.isFunction = function (val, msg) {
4828 new Assertion(val, msg, assert.isFunction, true).to.be.a('function');
4829 };
4830
4831 /**
4832 * ### .isNotFunction(value, [message])
4833 *
4834 * Asserts that `value` is _not_ a function.
4835 *
4836 * var serveTea = [ 'heat', 'pour', 'sip' ];
4837 * assert.isNotFunction(serveTea, 'great, we have listed the steps');
4838 *
4839 * @name isNotFunction
4840 * @param {Mixed} value
4841 * @param {String} message
4842 * @namespace Assert
4843 * @api public
4844 */
4845
4846 assert.isNotFunction = function (val, msg) {
4847 new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function');
4848 };
4849
4850 /**
4851 * ### .isObject(value, [message])
4852 *
4853 * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).
4854 * _The assertion does not match subclassed objects._
4855 *
4856 * var selection = { name: 'Chai', serve: 'with spices' };
4857 * assert.isObject(selection, 'tea selection is an object');
4858 *
4859 * @name isObject
4860 * @param {Mixed} value
4861 * @param {String} message
4862 * @namespace Assert
4863 * @api public
4864 */
4865
4866 assert.isObject = function (val, msg) {
4867 new Assertion(val, msg, assert.isObject, true).to.be.a('object');
4868 };
4869
4870 /**
4871 * ### .isNotObject(value, [message])
4872 *
4873 * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).
4874 *
4875 * var selection = 'chai'
4876 * assert.isNotObject(selection, 'tea selection is not an object');
4877 * assert.isNotObject(null, 'null is not an object');
4878 *
4879 * @name isNotObject
4880 * @param {Mixed} value
4881 * @param {String} message
4882 * @namespace Assert
4883 * @api public
4884 */
4885
4886 assert.isNotObject = function (val, msg) {
4887 new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object');
4888 };
4889
4890 /**
4891 * ### .isArray(value, [message])
4892 *
4893 * Asserts that `value` is an array.
4894 *
4895 * var menu = [ 'green', 'chai', 'oolong' ];
4896 * assert.isArray(menu, 'what kind of tea do we want?');
4897 *
4898 * @name isArray
4899 * @param {Mixed} value
4900 * @param {String} message
4901 * @namespace Assert
4902 * @api public
4903 */
4904
4905 assert.isArray = function (val, msg) {
4906 new Assertion(val, msg, assert.isArray, true).to.be.an('array');
4907 };
4908
4909 /**
4910 * ### .isNotArray(value, [message])
4911 *
4912 * Asserts that `value` is _not_ an array.
4913 *
4914 * var menu = 'green|chai|oolong';
4915 * assert.isNotArray(menu, 'what kind of tea do we want?');
4916 *
4917 * @name isNotArray
4918 * @param {Mixed} value
4919 * @param {String} message
4920 * @namespace Assert
4921 * @api public
4922 */
4923
4924 assert.isNotArray = function (val, msg) {
4925 new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array');
4926 };
4927
4928 /**
4929 * ### .isString(value, [message])
4930 *
4931 * Asserts that `value` is a string.
4932 *
4933 * var teaOrder = 'chai';
4934 * assert.isString(teaOrder, 'order placed');
4935 *
4936 * @name isString
4937 * @param {Mixed} value
4938 * @param {String} message
4939 * @namespace Assert
4940 * @api public
4941 */
4942
4943 assert.isString = function (val, msg) {
4944 new Assertion(val, msg, assert.isString, true).to.be.a('string');
4945 };
4946
4947 /**
4948 * ### .isNotString(value, [message])
4949 *
4950 * Asserts that `value` is _not_ a string.
4951 *
4952 * var teaOrder = 4;
4953 * assert.isNotString(teaOrder, 'order placed');
4954 *
4955 * @name isNotString
4956 * @param {Mixed} value
4957 * @param {String} message
4958 * @namespace Assert
4959 * @api public
4960 */
4961
4962 assert.isNotString = function (val, msg) {
4963 new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string');
4964 };
4965
4966 /**
4967 * ### .isNumber(value, [message])
4968 *
4969 * Asserts that `value` is a number.
4970 *
4971 * var cups = 2;
4972 * assert.isNumber(cups, 'how many cups');
4973 *
4974 * @name isNumber
4975 * @param {Number} value
4976 * @param {String} message
4977 * @namespace Assert
4978 * @api public
4979 */
4980
4981 assert.isNumber = function (val, msg) {
4982 new Assertion(val, msg, assert.isNumber, true).to.be.a('number');
4983 };
4984
4985 /**
4986 * ### .isNotNumber(value, [message])
4987 *
4988 * Asserts that `value` is _not_ a number.
4989 *
4990 * var cups = '2 cups please';
4991 * assert.isNotNumber(cups, 'how many cups');
4992 *
4993 * @name isNotNumber
4994 * @param {Mixed} value
4995 * @param {String} message
4996 * @namespace Assert
4997 * @api public
4998 */
4999
5000 assert.isNotNumber = function (val, msg) {
5001 new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number');
5002 };
5003
5004 /**
5005 * ### .isFinite(value, [message])
5006 *
5007 * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`.
5008 *
5009 * var cups = 2;
5010 * assert.isFinite(cups, 'how many cups');
5011 *
5012 * assert.isFinite(NaN); // throws
5013 *
5014 * @name isFinite
5015 * @param {Number} value
5016 * @param {String} message
5017 * @namespace Assert
5018 * @api public
5019 */
5020
5021 assert.isFinite = function (val, msg) {
5022 new Assertion(val, msg, assert.isFinite, true).to.be.finite;
5023 };
5024
5025 /**
5026 * ### .isBoolean(value, [message])
5027 *
5028 * Asserts that `value` is a boolean.
5029 *
5030 * var teaReady = true
5031 * , teaServed = false;
5032 *
5033 * assert.isBoolean(teaReady, 'is the tea ready');
5034 * assert.isBoolean(teaServed, 'has tea been served');
5035 *
5036 * @name isBoolean
5037 * @param {Mixed} value
5038 * @param {String} message
5039 * @namespace Assert
5040 * @api public
5041 */
5042
5043 assert.isBoolean = function (val, msg) {
5044 new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean');
5045 };
5046
5047 /**
5048 * ### .isNotBoolean(value, [message])
5049 *
5050 * Asserts that `value` is _not_ a boolean.
5051 *
5052 * var teaReady = 'yep'
5053 * , teaServed = 'nope';
5054 *
5055 * assert.isNotBoolean(teaReady, 'is the tea ready');
5056 * assert.isNotBoolean(teaServed, 'has tea been served');
5057 *
5058 * @name isNotBoolean
5059 * @param {Mixed} value
5060 * @param {String} message
5061 * @namespace Assert
5062 * @api public
5063 */
5064
5065 assert.isNotBoolean = function (val, msg) {
5066 new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean');
5067 };
5068
5069 /**
5070 * ### .typeOf(value, name, [message])
5071 *
5072 * Asserts that `value`'s type is `name`, as determined by
5073 * `Object.prototype.toString`.
5074 *
5075 * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');
5076 * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');
5077 * assert.typeOf('tea', 'string', 'we have a string');
5078 * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');
5079 * assert.typeOf(null, 'null', 'we have a null');
5080 * assert.typeOf(undefined, 'undefined', 'we have an undefined');
5081 *
5082 * @name typeOf
5083 * @param {Mixed} value
5084 * @param {String} name
5085 * @param {String} message
5086 * @namespace Assert
5087 * @api public
5088 */
5089
5090 assert.typeOf = function (val, type, msg) {
5091 new Assertion(val, msg, assert.typeOf, true).to.be.a(type);
5092 };
5093
5094 /**
5095 * ### .notTypeOf(value, name, [message])
5096 *
5097 * Asserts that `value`'s type is _not_ `name`, as determined by
5098 * `Object.prototype.toString`.
5099 *
5100 * assert.notTypeOf('tea', 'number', 'strings are not numbers');
5101 *
5102 * @name notTypeOf
5103 * @param {Mixed} value
5104 * @param {String} typeof name
5105 * @param {String} message
5106 * @namespace Assert
5107 * @api public
5108 */
5109
5110 assert.notTypeOf = function (val, type, msg) {
5111 new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type);
5112 };
5113
5114 /**
5115 * ### .instanceOf(object, constructor, [message])
5116 *
5117 * Asserts that `value` is an instance of `constructor`.
5118 *
5119 * var Tea = function (name) { this.name = name; }
5120 * , chai = new Tea('chai');
5121 *
5122 * assert.instanceOf(chai, Tea, 'chai is an instance of tea');
5123 *
5124 * @name instanceOf
5125 * @param {Object} object
5126 * @param {Constructor} constructor
5127 * @param {String} message
5128 * @namespace Assert
5129 * @api public
5130 */
5131
5132 assert.instanceOf = function (val, type, msg) {
5133 new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type);
5134 };
5135
5136 /**
5137 * ### .notInstanceOf(object, constructor, [message])
5138 *
5139 * Asserts `value` is not an instance of `constructor`.
5140 *
5141 * var Tea = function (name) { this.name = name; }
5142 * , chai = new String('chai');
5143 *
5144 * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');
5145 *
5146 * @name notInstanceOf
5147 * @param {Object} object
5148 * @param {Constructor} constructor
5149 * @param {String} message
5150 * @namespace Assert
5151 * @api public
5152 */
5153
5154 assert.notInstanceOf = function (val, type, msg) {
5155 new Assertion(val, msg, assert.notInstanceOf, true)
5156 .to.not.be.instanceOf(type);
5157 };
5158
5159 /**
5160 * ### .include(haystack, needle, [message])
5161 *
5162 * Asserts that `haystack` includes `needle`. Can be used to assert the
5163 * inclusion of a value in an array, a substring in a string, or a subset of
5164 * properties in an object.
5165 *
5166 * assert.include([1,2,3], 2, 'array contains value');
5167 * assert.include('foobar', 'foo', 'string contains substring');
5168 * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property');
5169 *
5170 * Strict equality (===) is used. When asserting the inclusion of a value in
5171 * an array, the array is searched for an element that's strictly equal to the
5172 * given value. When asserting a subset of properties in an object, the object
5173 * is searched for the given property keys, checking that each one is present
5174 * and strictly equal to the given property value. For instance:
5175 *
5176 * var obj1 = {a: 1}
5177 * , obj2 = {b: 2};
5178 * assert.include([obj1, obj2], obj1);
5179 * assert.include({foo: obj1, bar: obj2}, {foo: obj1});
5180 * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2});
5181 *
5182 * @name include
5183 * @param {Array|String} haystack
5184 * @param {Mixed} needle
5185 * @param {String} message
5186 * @namespace Assert
5187 * @api public
5188 */
5189
5190 assert.include = function (exp, inc, msg) {
5191 new Assertion(exp, msg, assert.include, true).include(inc);
5192 };
5193
5194 /**
5195 * ### .notInclude(haystack, needle, [message])
5196 *
5197 * Asserts that `haystack` does not include `needle`. Can be used to assert
5198 * the absence of a value in an array, a substring in a string, or a subset of
5199 * properties in an object.
5200 *
5201 * assert.notInclude([1,2,3], 4, "array doesn't contain value");
5202 * assert.notInclude('foobar', 'baz', "string doesn't contain substring");
5203 * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property');
5204 *
5205 * Strict equality (===) is used. When asserting the absence of a value in an
5206 * array, the array is searched to confirm the absence of an element that's
5207 * strictly equal to the given value. When asserting a subset of properties in
5208 * an object, the object is searched to confirm that at least one of the given
5209 * property keys is either not present or not strictly equal to the given
5210 * property value. For instance:
5211 *
5212 * var obj1 = {a: 1}
5213 * , obj2 = {b: 2};
5214 * assert.notInclude([obj1, obj2], {a: 1});
5215 * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}});
5216 * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}});
5217 *
5218 * @name notInclude
5219 * @param {Array|String} haystack
5220 * @param {Mixed} needle
5221 * @param {String} message
5222 * @namespace Assert
5223 * @api public
5224 */
5225
5226 assert.notInclude = function (exp, inc, msg) {
5227 new Assertion(exp, msg, assert.notInclude, true).not.include(inc);
5228 };
5229
5230 /**
5231 * ### .deepInclude(haystack, needle, [message])
5232 *
5233 * Asserts that `haystack` includes `needle`. Can be used to assert the
5234 * inclusion of a value in an array or a subset of properties in an object.
5235 * Deep equality is used.
5236 *
5237 * var obj1 = {a: 1}
5238 * , obj2 = {b: 2};
5239 * assert.deepInclude([obj1, obj2], {a: 1});
5240 * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}});
5241 * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}});
5242 *
5243 * @name deepInclude
5244 * @param {Array|String} haystack
5245 * @param {Mixed} needle
5246 * @param {String} message
5247 * @namespace Assert
5248 * @api public
5249 */
5250
5251 assert.deepInclude = function (exp, inc, msg) {
5252 new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc);
5253 };
5254
5255 /**
5256 * ### .notDeepInclude(haystack, needle, [message])
5257 *
5258 * Asserts that `haystack` does not include `needle`. Can be used to assert
5259 * the absence of a value in an array or a subset of properties in an object.
5260 * Deep equality is used.
5261 *
5262 * var obj1 = {a: 1}
5263 * , obj2 = {b: 2};
5264 * assert.notDeepInclude([obj1, obj2], {a: 9});
5265 * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}});
5266 * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}});
5267 *
5268 * @name notDeepInclude
5269 * @param {Array|String} haystack
5270 * @param {Mixed} needle
5271 * @param {String} message
5272 * @namespace Assert
5273 * @api public
5274 */
5275
5276 assert.notDeepInclude = function (exp, inc, msg) {
5277 new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc);
5278 };
5279
5280 /**
5281 * ### .nestedInclude(haystack, needle, [message])
5282 *
5283 * Asserts that 'haystack' includes 'needle'.
5284 * Can be used to assert the inclusion of a subset of properties in an
5285 * object.
5286 * Enables the use of dot- and bracket-notation for referencing nested
5287 * properties.
5288 * '[]' and '.' in property names can be escaped using double backslashes.
5289 *
5290 * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'});
5291 * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'});
5292 *
5293 * @name nestedInclude
5294 * @param {Object} haystack
5295 * @param {Object} needle
5296 * @param {String} message
5297 * @namespace Assert
5298 * @api public
5299 */
5300
5301 assert.nestedInclude = function (exp, inc, msg) {
5302 new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc);
5303 };
5304
5305 /**
5306 * ### .notNestedInclude(haystack, needle, [message])
5307 *
5308 * Asserts that 'haystack' does not include 'needle'.
5309 * Can be used to assert the absence of a subset of properties in an
5310 * object.
5311 * Enables the use of dot- and bracket-notation for referencing nested
5312 * properties.
5313 * '[]' and '.' in property names can be escaped using double backslashes.
5314 *
5315 * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'});
5316 * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'});
5317 *
5318 * @name notNestedInclude
5319 * @param {Object} haystack
5320 * @param {Object} needle
5321 * @param {String} message
5322 * @namespace Assert
5323 * @api public
5324 */
5325
5326 assert.notNestedInclude = function (exp, inc, msg) {
5327 new Assertion(exp, msg, assert.notNestedInclude, true)
5328 .not.nested.include(inc);
5329 };
5330
5331 /**
5332 * ### .deepNestedInclude(haystack, needle, [message])
5333 *
5334 * Asserts that 'haystack' includes 'needle'.
5335 * Can be used to assert the inclusion of a subset of properties in an
5336 * object while checking for deep equality.
5337 * Enables the use of dot- and bracket-notation for referencing nested
5338 * properties.
5339 * '[]' and '.' in property names can be escaped using double backslashes.
5340 *
5341 * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}});
5342 * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}});
5343 *
5344 * @name deepNestedInclude
5345 * @param {Object} haystack
5346 * @param {Object} needle
5347 * @param {String} message
5348 * @namespace Assert
5349 * @api public
5350 */
5351
5352 assert.deepNestedInclude = function(exp, inc, msg) {
5353 new Assertion(exp, msg, assert.deepNestedInclude, true)
5354 .deep.nested.include(inc);
5355 };
5356
5357 /**
5358 * ### .notDeepNestedInclude(haystack, needle, [message])
5359 *
5360 * Asserts that 'haystack' does not include 'needle'.
5361 * Can be used to assert the absence of a subset of properties in an
5362 * object while checking for deep equality.
5363 * Enables the use of dot- and bracket-notation for referencing nested
5364 * properties.
5365 * '[]' and '.' in property names can be escaped using double backslashes.
5366 *
5367 * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}})
5368 * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}});
5369 *
5370 * @name notDeepNestedInclude
5371 * @param {Object} haystack
5372 * @param {Object} needle
5373 * @param {String} message
5374 * @namespace Assert
5375 * @api public
5376 */
5377
5378 assert.notDeepNestedInclude = function(exp, inc, msg) {
5379 new Assertion(exp, msg, assert.notDeepNestedInclude, true)
5380 .not.deep.nested.include(inc);
5381 };
5382
5383 /**
5384 * ### .ownInclude(haystack, needle, [message])
5385 *
5386 * Asserts that 'haystack' includes 'needle'.
5387 * Can be used to assert the inclusion of a subset of properties in an
5388 * object while ignoring inherited properties.
5389 *
5390 * assert.ownInclude({ a: 1 }, { a: 1 });
5391 *
5392 * @name ownInclude
5393 * @param {Object} haystack
5394 * @param {Object} needle
5395 * @param {String} message
5396 * @namespace Assert
5397 * @api public
5398 */
5399
5400 assert.ownInclude = function(exp, inc, msg) {
5401 new Assertion(exp, msg, assert.ownInclude, true).own.include(inc);
5402 };
5403
5404 /**
5405 * ### .notOwnInclude(haystack, needle, [message])
5406 *
5407 * Asserts that 'haystack' includes 'needle'.
5408 * Can be used to assert the absence of a subset of properties in an
5409 * object while ignoring inherited properties.
5410 *
5411 * Object.prototype.b = 2;
5412 *
5413 * assert.notOwnInclude({ a: 1 }, { b: 2 });
5414 *
5415 * @name notOwnInclude
5416 * @param {Object} haystack
5417 * @param {Object} needle
5418 * @param {String} message
5419 * @namespace Assert
5420 * @api public
5421 */
5422
5423 assert.notOwnInclude = function(exp, inc, msg) {
5424 new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc);
5425 };
5426
5427 /**
5428 * ### .deepOwnInclude(haystack, needle, [message])
5429 *
5430 * Asserts that 'haystack' includes 'needle'.
5431 * Can be used to assert the inclusion of a subset of properties in an
5432 * object while ignoring inherited properties and checking for deep equality.
5433 *
5434 * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}});
5435 *
5436 * @name deepOwnInclude
5437 * @param {Object} haystack
5438 * @param {Object} needle
5439 * @param {String} message
5440 * @namespace Assert
5441 * @api public
5442 */
5443
5444 assert.deepOwnInclude = function(exp, inc, msg) {
5445 new Assertion(exp, msg, assert.deepOwnInclude, true)
5446 .deep.own.include(inc);
5447 };
5448
5449 /**
5450 * ### .notDeepOwnInclude(haystack, needle, [message])
5451 *
5452 * Asserts that 'haystack' includes 'needle'.
5453 * Can be used to assert the absence of a subset of properties in an
5454 * object while ignoring inherited properties and checking for deep equality.
5455 *
5456 * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}});
5457 *
5458 * @name notDeepOwnInclude
5459 * @param {Object} haystack
5460 * @param {Object} needle
5461 * @param {String} message
5462 * @namespace Assert
5463 * @api public
5464 */
5465
5466 assert.notDeepOwnInclude = function(exp, inc, msg) {
5467 new Assertion(exp, msg, assert.notDeepOwnInclude, true)
5468 .not.deep.own.include(inc);
5469 };
5470
5471 /**
5472 * ### .match(value, regexp, [message])
5473 *
5474 * Asserts that `value` matches the regular expression `regexp`.
5475 *
5476 * assert.match('foobar', /^foo/, 'regexp matches');
5477 *
5478 * @name match
5479 * @param {Mixed} value
5480 * @param {RegExp} regexp
5481 * @param {String} message
5482 * @namespace Assert
5483 * @api public
5484 */
5485
5486 assert.match = function (exp, re, msg) {
5487 new Assertion(exp, msg, assert.match, true).to.match(re);
5488 };
5489
5490 /**
5491 * ### .notMatch(value, regexp, [message])
5492 *
5493 * Asserts that `value` does not match the regular expression `regexp`.
5494 *
5495 * assert.notMatch('foobar', /^foo/, 'regexp does not match');
5496 *
5497 * @name notMatch
5498 * @param {Mixed} value
5499 * @param {RegExp} regexp
5500 * @param {String} message
5501 * @namespace Assert
5502 * @api public
5503 */
5504
5505 assert.notMatch = function (exp, re, msg) {
5506 new Assertion(exp, msg, assert.notMatch, true).to.not.match(re);
5507 };
5508
5509 /**
5510 * ### .property(object, property, [message])
5511 *
5512 * Asserts that `object` has a direct or inherited property named by
5513 * `property`.
5514 *
5515 * assert.property({ tea: { green: 'matcha' }}, 'tea');
5516 * assert.property({ tea: { green: 'matcha' }}, 'toString');
5517 *
5518 * @name property
5519 * @param {Object} object
5520 * @param {String} property
5521 * @param {String} message
5522 * @namespace Assert
5523 * @api public
5524 */
5525
5526 assert.property = function (obj, prop, msg) {
5527 new Assertion(obj, msg, assert.property, true).to.have.property(prop);
5528 };
5529
5530 /**
5531 * ### .notProperty(object, property, [message])
5532 *
5533 * Asserts that `object` does _not_ have a direct or inherited property named
5534 * by `property`.
5535 *
5536 * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');
5537 *
5538 * @name notProperty
5539 * @param {Object} object
5540 * @param {String} property
5541 * @param {String} message
5542 * @namespace Assert
5543 * @api public
5544 */
5545
5546 assert.notProperty = function (obj, prop, msg) {
5547 new Assertion(obj, msg, assert.notProperty, true)
5548 .to.not.have.property(prop);
5549 };
5550
5551 /**
5552 * ### .propertyVal(object, property, value, [message])
5553 *
5554 * Asserts that `object` has a direct or inherited property named by
5555 * `property` with a value given by `value`. Uses a strict equality check
5556 * (===).
5557 *
5558 * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');
5559 *
5560 * @name propertyVal
5561 * @param {Object} object
5562 * @param {String} property
5563 * @param {Mixed} value
5564 * @param {String} message
5565 * @namespace Assert
5566 * @api public
5567 */
5568
5569 assert.propertyVal = function (obj, prop, val, msg) {
5570 new Assertion(obj, msg, assert.propertyVal, true)
5571 .to.have.property(prop, val);
5572 };
5573
5574 /**
5575 * ### .notPropertyVal(object, property, value, [message])
5576 *
5577 * Asserts that `object` does _not_ have a direct or inherited property named
5578 * by `property` with value given by `value`. Uses a strict equality check
5579 * (===).
5580 *
5581 * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad');
5582 * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good');
5583 *
5584 * @name notPropertyVal
5585 * @param {Object} object
5586 * @param {String} property
5587 * @param {Mixed} value
5588 * @param {String} message
5589 * @namespace Assert
5590 * @api public
5591 */
5592
5593 assert.notPropertyVal = function (obj, prop, val, msg) {
5594 new Assertion(obj, msg, assert.notPropertyVal, true)
5595 .to.not.have.property(prop, val);
5596 };
5597
5598 /**
5599 * ### .deepPropertyVal(object, property, value, [message])
5600 *
5601 * Asserts that `object` has a direct or inherited property named by
5602 * `property` with a value given by `value`. Uses a deep equality check.
5603 *
5604 * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' });
5605 *
5606 * @name deepPropertyVal
5607 * @param {Object} object
5608 * @param {String} property
5609 * @param {Mixed} value
5610 * @param {String} message
5611 * @namespace Assert
5612 * @api public
5613 */
5614
5615 assert.deepPropertyVal = function (obj, prop, val, msg) {
5616 new Assertion(obj, msg, assert.deepPropertyVal, true)
5617 .to.have.deep.property(prop, val);
5618 };
5619
5620 /**
5621 * ### .notDeepPropertyVal(object, property, value, [message])
5622 *
5623 * Asserts that `object` does _not_ have a direct or inherited property named
5624 * by `property` with value given by `value`. Uses a deep equality check.
5625 *
5626 * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' });
5627 * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' });
5628 * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' });
5629 *
5630 * @name notDeepPropertyVal
5631 * @param {Object} object
5632 * @param {String} property
5633 * @param {Mixed} value
5634 * @param {String} message
5635 * @namespace Assert
5636 * @api public
5637 */
5638
5639 assert.notDeepPropertyVal = function (obj, prop, val, msg) {
5640 new Assertion(obj, msg, assert.notDeepPropertyVal, true)
5641 .to.not.have.deep.property(prop, val);
5642 };
5643
5644 /**
5645 * ### .ownProperty(object, property, [message])
5646 *
5647 * Asserts that `object` has a direct property named by `property`. Inherited
5648 * properties aren't checked.
5649 *
5650 * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea');
5651 *
5652 * @name ownProperty
5653 * @param {Object} object
5654 * @param {String} property
5655 * @param {String} message
5656 * @api public
5657 */
5658
5659 assert.ownProperty = function (obj, prop, msg) {
5660 new Assertion(obj, msg, assert.ownProperty, true)
5661 .to.have.own.property(prop);
5662 };
5663
5664 /**
5665 * ### .notOwnProperty(object, property, [message])
5666 *
5667 * Asserts that `object` does _not_ have a direct property named by
5668 * `property`. Inherited properties aren't checked.
5669 *
5670 * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee');
5671 * assert.notOwnProperty({}, 'toString');
5672 *
5673 * @name notOwnProperty
5674 * @param {Object} object
5675 * @param {String} property
5676 * @param {String} message
5677 * @api public
5678 */
5679
5680 assert.notOwnProperty = function (obj, prop, msg) {
5681 new Assertion(obj, msg, assert.notOwnProperty, true)
5682 .to.not.have.own.property(prop);
5683 };
5684
5685 /**
5686 * ### .ownPropertyVal(object, property, value, [message])
5687 *
5688 * Asserts that `object` has a direct property named by `property` and a value
5689 * equal to the provided `value`. Uses a strict equality check (===).
5690 * Inherited properties aren't checked.
5691 *
5692 * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good');
5693 *
5694 * @name ownPropertyVal
5695 * @param {Object} object
5696 * @param {String} property
5697 * @param {Mixed} value
5698 * @param {String} message
5699 * @api public
5700 */
5701
5702 assert.ownPropertyVal = function (obj, prop, value, msg) {
5703 new Assertion(obj, msg, assert.ownPropertyVal, true)
5704 .to.have.own.property(prop, value);
5705 };
5706
5707 /**
5708 * ### .notOwnPropertyVal(object, property, value, [message])
5709 *
5710 * Asserts that `object` does _not_ have a direct property named by `property`
5711 * with a value equal to the provided `value`. Uses a strict equality check
5712 * (===). Inherited properties aren't checked.
5713 *
5714 * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse');
5715 * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString);
5716 *
5717 * @name notOwnPropertyVal
5718 * @param {Object} object
5719 * @param {String} property
5720 * @param {Mixed} value
5721 * @param {String} message
5722 * @api public
5723 */
5724
5725 assert.notOwnPropertyVal = function (obj, prop, value, msg) {
5726 new Assertion(obj, msg, assert.notOwnPropertyVal, true)
5727 .to.not.have.own.property(prop, value);
5728 };
5729
5730 /**
5731 * ### .deepOwnPropertyVal(object, property, value, [message])
5732 *
5733 * Asserts that `object` has a direct property named by `property` and a value
5734 * equal to the provided `value`. Uses a deep equality check. Inherited
5735 * properties aren't checked.
5736 *
5737 * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' });
5738 *
5739 * @name deepOwnPropertyVal
5740 * @param {Object} object
5741 * @param {String} property
5742 * @param {Mixed} value
5743 * @param {String} message
5744 * @api public
5745 */
5746
5747 assert.deepOwnPropertyVal = function (obj, prop, value, msg) {
5748 new Assertion(obj, msg, assert.deepOwnPropertyVal, true)
5749 .to.have.deep.own.property(prop, value);
5750 };
5751
5752 /**
5753 * ### .notDeepOwnPropertyVal(object, property, value, [message])
5754 *
5755 * Asserts that `object` does _not_ have a direct property named by `property`
5756 * with a value equal to the provided `value`. Uses a deep equality check.
5757 * Inherited properties aren't checked.
5758 *
5759 * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' });
5760 * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' });
5761 * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' });
5762 * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString);
5763 *
5764 * @name notDeepOwnPropertyVal
5765 * @param {Object} object
5766 * @param {String} property
5767 * @param {Mixed} value
5768 * @param {String} message
5769 * @api public
5770 */
5771
5772 assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) {
5773 new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true)
5774 .to.not.have.deep.own.property(prop, value);
5775 };
5776
5777 /**
5778 * ### .nestedProperty(object, property, [message])
5779 *
5780 * Asserts that `object` has a direct or inherited property named by
5781 * `property`, which can be a string using dot- and bracket-notation for
5782 * nested reference.
5783 *
5784 * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green');
5785 *
5786 * @name nestedProperty
5787 * @param {Object} object
5788 * @param {String} property
5789 * @param {String} message
5790 * @namespace Assert
5791 * @api public
5792 */
5793
5794 assert.nestedProperty = function (obj, prop, msg) {
5795 new Assertion(obj, msg, assert.nestedProperty, true)
5796 .to.have.nested.property(prop);
5797 };
5798
5799 /**
5800 * ### .notNestedProperty(object, property, [message])
5801 *
5802 * Asserts that `object` does _not_ have a property named by `property`, which
5803 * can be a string using dot- and bracket-notation for nested reference. The
5804 * property cannot exist on the object nor anywhere in its prototype chain.
5805 *
5806 * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong');
5807 *
5808 * @name notNestedProperty
5809 * @param {Object} object
5810 * @param {String} property
5811 * @param {String} message
5812 * @namespace Assert
5813 * @api public
5814 */
5815
5816 assert.notNestedProperty = function (obj, prop, msg) {
5817 new Assertion(obj, msg, assert.notNestedProperty, true)
5818 .to.not.have.nested.property(prop);
5819 };
5820
5821 /**
5822 * ### .nestedPropertyVal(object, property, value, [message])
5823 *
5824 * Asserts that `object` has a property named by `property` with value given
5825 * by `value`. `property` can use dot- and bracket-notation for nested
5826 * reference. Uses a strict equality check (===).
5827 *
5828 * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');
5829 *
5830 * @name nestedPropertyVal
5831 * @param {Object} object
5832 * @param {String} property
5833 * @param {Mixed} value
5834 * @param {String} message
5835 * @namespace Assert
5836 * @api public
5837 */
5838
5839 assert.nestedPropertyVal = function (obj, prop, val, msg) {
5840 new Assertion(obj, msg, assert.nestedPropertyVal, true)
5841 .to.have.nested.property(prop, val);
5842 };
5843
5844 /**
5845 * ### .notNestedPropertyVal(object, property, value, [message])
5846 *
5847 * Asserts that `object` does _not_ have a property named by `property` with
5848 * value given by `value`. `property` can use dot- and bracket-notation for
5849 * nested reference. Uses a strict equality check (===).
5850 *
5851 * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');
5852 * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha');
5853 *
5854 * @name notNestedPropertyVal
5855 * @param {Object} object
5856 * @param {String} property
5857 * @param {Mixed} value
5858 * @param {String} message
5859 * @namespace Assert
5860 * @api public
5861 */
5862
5863 assert.notNestedPropertyVal = function (obj, prop, val, msg) {
5864 new Assertion(obj, msg, assert.notNestedPropertyVal, true)
5865 .to.not.have.nested.property(prop, val);
5866 };
5867
5868 /**
5869 * ### .deepNestedPropertyVal(object, property, value, [message])
5870 *
5871 * Asserts that `object` has a property named by `property` with a value given
5872 * by `value`. `property` can use dot- and bracket-notation for nested
5873 * reference. Uses a deep equality check.
5874 *
5875 * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' });
5876 *
5877 * @name deepNestedPropertyVal
5878 * @param {Object} object
5879 * @param {String} property
5880 * @param {Mixed} value
5881 * @param {String} message
5882 * @namespace Assert
5883 * @api public
5884 */
5885
5886 assert.deepNestedPropertyVal = function (obj, prop, val, msg) {
5887 new Assertion(obj, msg, assert.deepNestedPropertyVal, true)
5888 .to.have.deep.nested.property(prop, val);
5889 };
5890
5891 /**
5892 * ### .notDeepNestedPropertyVal(object, property, value, [message])
5893 *
5894 * Asserts that `object` does _not_ have a property named by `property` with
5895 * value given by `value`. `property` can use dot- and bracket-notation for
5896 * nested reference. Uses a deep equality check.
5897 *
5898 * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' });
5899 * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' });
5900 * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' });
5901 *
5902 * @name notDeepNestedPropertyVal
5903 * @param {Object} object
5904 * @param {String} property
5905 * @param {Mixed} value
5906 * @param {String} message
5907 * @namespace Assert
5908 * @api public
5909 */
5910
5911 assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) {
5912 new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true)
5913 .to.not.have.deep.nested.property(prop, val);
5914 }
5915
5916 /**
5917 * ### .lengthOf(object, length, [message])
5918 *
5919 * Asserts that `object` has a `length` or `size` with the expected value.
5920 *
5921 * assert.lengthOf([1,2,3], 3, 'array has length of 3');
5922 * assert.lengthOf('foobar', 6, 'string has length of 6');
5923 * assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3');
5924 * assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3');
5925 *
5926 * @name lengthOf
5927 * @param {Mixed} object
5928 * @param {Number} length
5929 * @param {String} message
5930 * @namespace Assert
5931 * @api public
5932 */
5933
5934 assert.lengthOf = function (exp, len, msg) {
5935 new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len);
5936 };
5937
5938 /**
5939 * ### .hasAnyKeys(object, [keys], [message])
5940 *
5941 * Asserts that `object` has at least one of the `keys` provided.
5942 * You can also provide a single object instead of a `keys` array and its keys
5943 * will be used as the expected set of keys.
5944 *
5945 * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']);
5946 * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337});
5947 * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
5948 * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']);
5949 *
5950 * @name hasAnyKeys
5951 * @param {Mixed} object
5952 * @param {Array|Object} keys
5953 * @param {String} message
5954 * @namespace Assert
5955 * @api public
5956 */
5957
5958 assert.hasAnyKeys = function (obj, keys, msg) {
5959 new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys);
5960 }
5961
5962 /**
5963 * ### .hasAllKeys(object, [keys], [message])
5964 *
5965 * Asserts that `object` has all and only all of the `keys` provided.
5966 * You can also provide a single object instead of a `keys` array and its keys
5967 * will be used as the expected set of keys.
5968 *
5969 * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']);
5970 * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]);
5971 * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
5972 * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']);
5973 *
5974 * @name hasAllKeys
5975 * @param {Mixed} object
5976 * @param {String[]} keys
5977 * @param {String} message
5978 * @namespace Assert
5979 * @api public
5980 */
5981
5982 assert.hasAllKeys = function (obj, keys, msg) {
5983 new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys);
5984 }
5985
5986 /**
5987 * ### .containsAllKeys(object, [keys], [message])
5988 *
5989 * Asserts that `object` has all of the `keys` provided but may have more keys not listed.
5990 * You can also provide a single object instead of a `keys` array and its keys
5991 * will be used as the expected set of keys.
5992 *
5993 * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']);
5994 * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']);
5995 * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337});
5996 * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337});
5997 * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]);
5998 * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
5999 * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]);
6000 * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']);
6001 *
6002 * @name containsAllKeys
6003 * @param {Mixed} object
6004 * @param {String[]} keys
6005 * @param {String} message
6006 * @namespace Assert
6007 * @api public
6008 */
6009
6010 assert.containsAllKeys = function (obj, keys, msg) {
6011 new Assertion(obj, msg, assert.containsAllKeys, true)
6012 .to.contain.all.keys(keys);
6013 }
6014
6015 /**
6016 * ### .doesNotHaveAnyKeys(object, [keys], [message])
6017 *
6018 * Asserts that `object` has none of the `keys` provided.
6019 * You can also provide a single object instead of a `keys` array and its keys
6020 * will be used as the expected set of keys.
6021 *
6022 * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']);
6023 * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'});
6024 * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']);
6025 * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']);
6026 *
6027 * @name doesNotHaveAnyKeys
6028 * @param {Mixed} object
6029 * @param {String[]} keys
6030 * @param {String} message
6031 * @namespace Assert
6032 * @api public
6033 */
6034
6035 assert.doesNotHaveAnyKeys = function (obj, keys, msg) {
6036 new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true)
6037 .to.not.have.any.keys(keys);
6038 }
6039
6040 /**
6041 * ### .doesNotHaveAllKeys(object, [keys], [message])
6042 *
6043 * Asserts that `object` does not have at least one of the `keys` provided.
6044 * You can also provide a single object instead of a `keys` array and its keys
6045 * will be used as the expected set of keys.
6046 *
6047 * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']);
6048 * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'});
6049 * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']);
6050 * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']);
6051 *
6052 * @name doesNotHaveAllKeys
6053 * @param {Mixed} object
6054 * @param {String[]} keys
6055 * @param {String} message
6056 * @namespace Assert
6057 * @api public
6058 */
6059
6060 assert.doesNotHaveAllKeys = function (obj, keys, msg) {
6061 new Assertion(obj, msg, assert.doesNotHaveAllKeys, true)
6062 .to.not.have.all.keys(keys);
6063 }
6064
6065 /**
6066 * ### .hasAnyDeepKeys(object, [keys], [message])
6067 *
6068 * Asserts that `object` has at least one of the `keys` provided.
6069 * Since Sets and Maps can have objects as keys you can use this assertion to perform
6070 * a deep comparison.
6071 * You can also provide a single object instead of a `keys` array and its keys
6072 * will be used as the expected set of keys.
6073 *
6074 * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'});
6075 * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]);
6076 * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
6077 * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'});
6078 * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]);
6079 * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
6080 *
6081 * @name hasAnyDeepKeys
6082 * @param {Mixed} object
6083 * @param {Array|Object} keys
6084 * @param {String} message
6085 * @namespace Assert
6086 * @api public
6087 */
6088
6089 assert.hasAnyDeepKeys = function (obj, keys, msg) {
6090 new Assertion(obj, msg, assert.hasAnyDeepKeys, true)
6091 .to.have.any.deep.keys(keys);
6092 }
6093
6094 /**
6095 * ### .hasAllDeepKeys(object, [keys], [message])
6096 *
6097 * Asserts that `object` has all and only all of the `keys` provided.
6098 * Since Sets and Maps can have objects as keys you can use this assertion to perform
6099 * a deep comparison.
6100 * You can also provide a single object instead of a `keys` array and its keys
6101 * will be used as the expected set of keys.
6102 *
6103 * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'});
6104 * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
6105 * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'});
6106 * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
6107 *
6108 * @name hasAllDeepKeys
6109 * @param {Mixed} object
6110 * @param {Array|Object} keys
6111 * @param {String} message
6112 * @namespace Assert
6113 * @api public
6114 */
6115
6116 assert.hasAllDeepKeys = function (obj, keys, msg) {
6117 new Assertion(obj, msg, assert.hasAllDeepKeys, true)
6118 .to.have.all.deep.keys(keys);
6119 }
6120
6121 /**
6122 * ### .containsAllDeepKeys(object, [keys], [message])
6123 *
6124 * Asserts that `object` contains all of the `keys` provided.
6125 * Since Sets and Maps can have objects as keys you can use this assertion to perform
6126 * a deep comparison.
6127 * You can also provide a single object instead of a `keys` array and its keys
6128 * will be used as the expected set of keys.
6129 *
6130 * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'});
6131 * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
6132 * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'});
6133 * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
6134 *
6135 * @name containsAllDeepKeys
6136 * @param {Mixed} object
6137 * @param {Array|Object} keys
6138 * @param {String} message
6139 * @namespace Assert
6140 * @api public
6141 */
6142
6143 assert.containsAllDeepKeys = function (obj, keys, msg) {
6144 new Assertion(obj, msg, assert.containsAllDeepKeys, true)
6145 .to.contain.all.deep.keys(keys);
6146 }
6147
6148 /**
6149 * ### .doesNotHaveAnyDeepKeys(object, [keys], [message])
6150 *
6151 * Asserts that `object` has none of the `keys` provided.
6152 * Since Sets and Maps can have objects as keys you can use this assertion to perform
6153 * a deep comparison.
6154 * You can also provide a single object instead of a `keys` array and its keys
6155 * will be used as the expected set of keys.
6156 *
6157 * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'});
6158 * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]);
6159 * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'});
6160 * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]);
6161 *
6162 * @name doesNotHaveAnyDeepKeys
6163 * @param {Mixed} object
6164 * @param {Array|Object} keys
6165 * @param {String} message
6166 * @namespace Assert
6167 * @api public
6168 */
6169
6170 assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) {
6171 new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true)
6172 .to.not.have.any.deep.keys(keys);
6173 }
6174
6175 /**
6176 * ### .doesNotHaveAllDeepKeys(object, [keys], [message])
6177 *
6178 * Asserts that `object` does not have at least one of the `keys` provided.
6179 * Since Sets and Maps can have objects as keys you can use this assertion to perform
6180 * a deep comparison.
6181 * You can also provide a single object instead of a `keys` array and its keys
6182 * will be used as the expected set of keys.
6183 *
6184 * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'});
6185 * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]);
6186 * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'});
6187 * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]);
6188 *
6189 * @name doesNotHaveAllDeepKeys
6190 * @param {Mixed} object
6191 * @param {Array|Object} keys
6192 * @param {String} message
6193 * @namespace Assert
6194 * @api public
6195 */
6196
6197 assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) {
6198 new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true)
6199 .to.not.have.all.deep.keys(keys);
6200 }
6201
6202 /**
6203 * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message])
6204 *
6205 * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an
6206 * instance of `errorLike`.
6207 * If `errorLike` is an `Error` instance, asserts that the error thrown is the same
6208 * instance as `errorLike`.
6209 * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a
6210 * message matching `errMsgMatcher`.
6211 *
6212 * assert.throws(fn, 'Error thrown must have this msg');
6213 * assert.throws(fn, /Error thrown must have a msg that matches this/);
6214 * assert.throws(fn, ReferenceError);
6215 * assert.throws(fn, errorInstance);
6216 * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg');
6217 * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg');
6218 * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/);
6219 * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/);
6220 *
6221 * @name throws
6222 * @alias throw
6223 * @alias Throw
6224 * @param {Function} fn
6225 * @param {ErrorConstructor|Error} errorLike
6226 * @param {RegExp|String} errMsgMatcher
6227 * @param {String} message
6228 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
6229 * @namespace Assert
6230 * @api public
6231 */
6232
6233 assert.throws = function (fn, errorLike, errMsgMatcher, msg) {
6234 if ('string' === typeof errorLike || errorLike instanceof RegExp) {
6235 errMsgMatcher = errorLike;
6236 errorLike = null;
6237 }
6238
6239 var assertErr = new Assertion(fn, msg, assert.throws, true)
6240 .to.throw(errorLike, errMsgMatcher);
6241 return flag(assertErr, 'object');
6242 };
6243
6244 /**
6245 * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message])
6246 *
6247 * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an
6248 * instance of `errorLike`.
6249 * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same
6250 * instance as `errorLike`.
6251 * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a
6252 * message matching `errMsgMatcher`.
6253 *
6254 * assert.doesNotThrow(fn, 'Any Error thrown must not have this message');
6255 * assert.doesNotThrow(fn, /Any Error thrown must not match this/);
6256 * assert.doesNotThrow(fn, Error);
6257 * assert.doesNotThrow(fn, errorInstance);
6258 * assert.doesNotThrow(fn, Error, 'Error must not have this message');
6259 * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message');
6260 * assert.doesNotThrow(fn, Error, /Error must not match this/);
6261 * assert.doesNotThrow(fn, errorInstance, /Error must not match this/);
6262 *
6263 * @name doesNotThrow
6264 * @param {Function} fn
6265 * @param {ErrorConstructor} errorLike
6266 * @param {RegExp|String} errMsgMatcher
6267 * @param {String} message
6268 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
6269 * @namespace Assert
6270 * @api public
6271 */
6272
6273 assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) {
6274 if ('string' === typeof errorLike || errorLike instanceof RegExp) {
6275 errMsgMatcher = errorLike;
6276 errorLike = null;
6277 }
6278
6279 new Assertion(fn, msg, assert.doesNotThrow, true)
6280 .to.not.throw(errorLike, errMsgMatcher);
6281 };
6282
6283 /**
6284 * ### .operator(val1, operator, val2, [message])
6285 *
6286 * Compares two values using `operator`.
6287 *
6288 * assert.operator(1, '<', 2, 'everything is ok');
6289 * assert.operator(1, '>', 2, 'this will fail');
6290 *
6291 * @name operator
6292 * @param {Mixed} val1
6293 * @param {String} operator
6294 * @param {Mixed} val2
6295 * @param {String} message
6296 * @namespace Assert
6297 * @api public
6298 */
6299
6300 assert.operator = function (val, operator, val2, msg) {
6301 var ok;
6302 switch(operator) {
6303 case '==':
6304 ok = val == val2;
6305 break;
6306 case '===':
6307 ok = val === val2;
6308 break;
6309 case '>':
6310 ok = val > val2;
6311 break;
6312 case '>=':
6313 ok = val >= val2;
6314 break;
6315 case '<':
6316 ok = val < val2;
6317 break;
6318 case '<=':
6319 ok = val <= val2;
6320 break;
6321 case '!=':
6322 ok = val != val2;
6323 break;
6324 case '!==':
6325 ok = val !== val2;
6326 break;
6327 default:
6328 msg = msg ? msg + ': ' : msg;
6329 throw new chai.AssertionError(
6330 msg + 'Invalid operator "' + operator + '"',
6331 undefined,
6332 assert.operator
6333 );
6334 }
6335 var test = new Assertion(ok, msg, assert.operator, true);
6336 test.assert(
6337 true === flag(test, 'object')
6338 , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
6339 , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );
6340 };
6341
6342 /**
6343 * ### .closeTo(actual, expected, delta, [message])
6344 *
6345 * Asserts that the target is equal `expected`, to within a +/- `delta` range.
6346 *
6347 * assert.closeTo(1.5, 1, 0.5, 'numbers are close');
6348 *
6349 * @name closeTo
6350 * @param {Number} actual
6351 * @param {Number} expected
6352 * @param {Number} delta
6353 * @param {String} message
6354 * @namespace Assert
6355 * @api public
6356 */
6357
6358 assert.closeTo = function (act, exp, delta, msg) {
6359 new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta);
6360 };
6361
6362 /**
6363 * ### .approximately(actual, expected, delta, [message])
6364 *
6365 * Asserts that the target is equal `expected`, to within a +/- `delta` range.
6366 *
6367 * assert.approximately(1.5, 1, 0.5, 'numbers are close');
6368 *
6369 * @name approximately
6370 * @param {Number} actual
6371 * @param {Number} expected
6372 * @param {Number} delta
6373 * @param {String} message
6374 * @namespace Assert
6375 * @api public
6376 */
6377
6378 assert.approximately = function (act, exp, delta, msg) {
6379 new Assertion(act, msg, assert.approximately, true)
6380 .to.be.approximately(exp, delta);
6381 };
6382
6383 /**
6384 * ### .sameMembers(set1, set2, [message])
6385 *
6386 * Asserts that `set1` and `set2` have the same members in any order. Uses a
6387 * strict equality check (===).
6388 *
6389 * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');
6390 *
6391 * @name sameMembers
6392 * @param {Array} set1
6393 * @param {Array} set2
6394 * @param {String} message
6395 * @namespace Assert
6396 * @api public
6397 */
6398
6399 assert.sameMembers = function (set1, set2, msg) {
6400 new Assertion(set1, msg, assert.sameMembers, true)
6401 .to.have.same.members(set2);
6402 }
6403
6404 /**
6405 * ### .notSameMembers(set1, set2, [message])
6406 *
6407 * Asserts that `set1` and `set2` don't have the same members in any order.
6408 * Uses a strict equality check (===).
6409 *
6410 * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members');
6411 *
6412 * @name notSameMembers
6413 * @param {Array} set1
6414 * @param {Array} set2
6415 * @param {String} message
6416 * @namespace Assert
6417 * @api public
6418 */
6419
6420 assert.notSameMembers = function (set1, set2, msg) {
6421 new Assertion(set1, msg, assert.notSameMembers, true)
6422 .to.not.have.same.members(set2);
6423 }
6424
6425 /**
6426 * ### .sameDeepMembers(set1, set2, [message])
6427 *
6428 * Asserts that `set1` and `set2` have the same members in any order. Uses a
6429 * deep equality check.
6430 *
6431 * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members');
6432 *
6433 * @name sameDeepMembers
6434 * @param {Array} set1
6435 * @param {Array} set2
6436 * @param {String} message
6437 * @namespace Assert
6438 * @api public
6439 */
6440
6441 assert.sameDeepMembers = function (set1, set2, msg) {
6442 new Assertion(set1, msg, assert.sameDeepMembers, true)
6443 .to.have.same.deep.members(set2);
6444 }
6445
6446 /**
6447 * ### .notSameDeepMembers(set1, set2, [message])
6448 *
6449 * Asserts that `set1` and `set2` don't have the same members in any order.
6450 * Uses a deep equality check.
6451 *
6452 * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members');
6453 *
6454 * @name notSameDeepMembers
6455 * @param {Array} set1
6456 * @param {Array} set2
6457 * @param {String} message
6458 * @namespace Assert
6459 * @api public
6460 */
6461
6462 assert.notSameDeepMembers = function (set1, set2, msg) {
6463 new Assertion(set1, msg, assert.notSameDeepMembers, true)
6464 .to.not.have.same.deep.members(set2);
6465 }
6466
6467 /**
6468 * ### .sameOrderedMembers(set1, set2, [message])
6469 *
6470 * Asserts that `set1` and `set2` have the same members in the same order.
6471 * Uses a strict equality check (===).
6472 *
6473 * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members');
6474 *
6475 * @name sameOrderedMembers
6476 * @param {Array} set1
6477 * @param {Array} set2
6478 * @param {String} message
6479 * @namespace Assert
6480 * @api public
6481 */
6482
6483 assert.sameOrderedMembers = function (set1, set2, msg) {
6484 new Assertion(set1, msg, assert.sameOrderedMembers, true)
6485 .to.have.same.ordered.members(set2);
6486 }
6487
6488 /**
6489 * ### .notSameOrderedMembers(set1, set2, [message])
6490 *
6491 * Asserts that `set1` and `set2` don't have the same members in the same
6492 * order. Uses a strict equality check (===).
6493 *
6494 * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members');
6495 *
6496 * @name notSameOrderedMembers
6497 * @param {Array} set1
6498 * @param {Array} set2
6499 * @param {String} message
6500 * @namespace Assert
6501 * @api public
6502 */
6503
6504 assert.notSameOrderedMembers = function (set1, set2, msg) {
6505 new Assertion(set1, msg, assert.notSameOrderedMembers, true)
6506 .to.not.have.same.ordered.members(set2);
6507 }
6508
6509 /**
6510 * ### .sameDeepOrderedMembers(set1, set2, [message])
6511 *
6512 * Asserts that `set1` and `set2` have the same members in the same order.
6513 * Uses a deep equality check.
6514 *
6515 * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members');
6516 *
6517 * @name sameDeepOrderedMembers
6518 * @param {Array} set1
6519 * @param {Array} set2
6520 * @param {String} message
6521 * @namespace Assert
6522 * @api public
6523 */
6524
6525 assert.sameDeepOrderedMembers = function (set1, set2, msg) {
6526 new Assertion(set1, msg, assert.sameDeepOrderedMembers, true)
6527 .to.have.same.deep.ordered.members(set2);
6528 }
6529
6530 /**
6531 * ### .notSameDeepOrderedMembers(set1, set2, [message])
6532 *
6533 * Asserts that `set1` and `set2` don't have the same members in the same
6534 * order. Uses a deep equality check.
6535 *
6536 * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members');
6537 * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members');
6538 *
6539 * @name notSameDeepOrderedMembers
6540 * @param {Array} set1
6541 * @param {Array} set2
6542 * @param {String} message
6543 * @namespace Assert
6544 * @api public
6545 */
6546
6547 assert.notSameDeepOrderedMembers = function (set1, set2, msg) {
6548 new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true)
6549 .to.not.have.same.deep.ordered.members(set2);
6550 }
6551
6552 /**
6553 * ### .includeMembers(superset, subset, [message])
6554 *
6555 * Asserts that `subset` is included in `superset` in any order. Uses a
6556 * strict equality check (===). Duplicates are ignored.
6557 *
6558 * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members');
6559 *
6560 * @name includeMembers
6561 * @param {Array} superset
6562 * @param {Array} subset
6563 * @param {String} message
6564 * @namespace Assert
6565 * @api public
6566 */
6567
6568 assert.includeMembers = function (superset, subset, msg) {
6569 new Assertion(superset, msg, assert.includeMembers, true)
6570 .to.include.members(subset);
6571 }
6572
6573 /**
6574 * ### .notIncludeMembers(superset, subset, [message])
6575 *
6576 * Asserts that `subset` isn't included in `superset` in any order. Uses a
6577 * strict equality check (===). Duplicates are ignored.
6578 *
6579 * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members');
6580 *
6581 * @name notIncludeMembers
6582 * @param {Array} superset
6583 * @param {Array} subset
6584 * @param {String} message
6585 * @namespace Assert
6586 * @api public
6587 */
6588
6589 assert.notIncludeMembers = function (superset, subset, msg) {
6590 new Assertion(superset, msg, assert.notIncludeMembers, true)
6591 .to.not.include.members(subset);
6592 }
6593
6594 /**
6595 * ### .includeDeepMembers(superset, subset, [message])
6596 *
6597 * Asserts that `subset` is included in `superset` in any order. Uses a deep
6598 * equality check. Duplicates are ignored.
6599 *
6600 * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members');
6601 *
6602 * @name includeDeepMembers
6603 * @param {Array} superset
6604 * @param {Array} subset
6605 * @param {String} message
6606 * @namespace Assert
6607 * @api public
6608 */
6609
6610 assert.includeDeepMembers = function (superset, subset, msg) {
6611 new Assertion(superset, msg, assert.includeDeepMembers, true)
6612 .to.include.deep.members(subset);
6613 }
6614
6615 /**
6616 * ### .notIncludeDeepMembers(superset, subset, [message])
6617 *
6618 * Asserts that `subset` isn't included in `superset` in any order. Uses a
6619 * deep equality check. Duplicates are ignored.
6620 *
6621 * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members');
6622 *
6623 * @name notIncludeDeepMembers
6624 * @param {Array} superset
6625 * @param {Array} subset
6626 * @param {String} message
6627 * @namespace Assert
6628 * @api public
6629 */
6630
6631 assert.notIncludeDeepMembers = function (superset, subset, msg) {
6632 new Assertion(superset, msg, assert.notIncludeDeepMembers, true)
6633 .to.not.include.deep.members(subset);
6634 }
6635
6636 /**
6637 * ### .includeOrderedMembers(superset, subset, [message])
6638 *
6639 * Asserts that `subset` is included in `superset` in the same order
6640 * beginning with the first element in `superset`. Uses a strict equality
6641 * check (===).
6642 *
6643 * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members');
6644 *
6645 * @name includeOrderedMembers
6646 * @param {Array} superset
6647 * @param {Array} subset
6648 * @param {String} message
6649 * @namespace Assert
6650 * @api public
6651 */
6652
6653 assert.includeOrderedMembers = function (superset, subset, msg) {
6654 new Assertion(superset, msg, assert.includeOrderedMembers, true)
6655 .to.include.ordered.members(subset);
6656 }
6657
6658 /**
6659 * ### .notIncludeOrderedMembers(superset, subset, [message])
6660 *
6661 * Asserts that `subset` isn't included in `superset` in the same order
6662 * beginning with the first element in `superset`. Uses a strict equality
6663 * check (===).
6664 *
6665 * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members');
6666 * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members');
6667 *
6668 * @name notIncludeOrderedMembers
6669 * @param {Array} superset
6670 * @param {Array} subset
6671 * @param {String} message
6672 * @namespace Assert
6673 * @api public
6674 */
6675
6676 assert.notIncludeOrderedMembers = function (superset, subset, msg) {
6677 new Assertion(superset, msg, assert.notIncludeOrderedMembers, true)
6678 .to.not.include.ordered.members(subset);
6679 }
6680
6681 /**
6682 * ### .includeDeepOrderedMembers(superset, subset, [message])
6683 *
6684 * Asserts that `subset` is included in `superset` in the same order
6685 * beginning with the first element in `superset`. Uses a deep equality
6686 * check.
6687 *
6688 * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members');
6689 *
6690 * @name includeDeepOrderedMembers
6691 * @param {Array} superset
6692 * @param {Array} subset
6693 * @param {String} message
6694 * @namespace Assert
6695 * @api public
6696 */
6697
6698 assert.includeDeepOrderedMembers = function (superset, subset, msg) {
6699 new Assertion(superset, msg, assert.includeDeepOrderedMembers, true)
6700 .to.include.deep.ordered.members(subset);
6701 }
6702
6703 /**
6704 * ### .notIncludeDeepOrderedMembers(superset, subset, [message])
6705 *
6706 * Asserts that `subset` isn't included in `superset` in the same order
6707 * beginning with the first element in `superset`. Uses a deep equality
6708 * check.
6709 *
6710 * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members');
6711 * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members');
6712 * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members');
6713 *
6714 * @name notIncludeDeepOrderedMembers
6715 * @param {Array} superset
6716 * @param {Array} subset
6717 * @param {String} message
6718 * @namespace Assert
6719 * @api public
6720 */
6721
6722 assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) {
6723 new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true)
6724 .to.not.include.deep.ordered.members(subset);
6725 }
6726
6727 /**
6728 * ### .oneOf(inList, list, [message])
6729 *
6730 * Asserts that non-object, non-array value `inList` appears in the flat array `list`.
6731 *
6732 * assert.oneOf(1, [ 2, 1 ], 'Not found in list');
6733 *
6734 * @name oneOf
6735 * @param {*} inList
6736 * @param {Array<*>} list
6737 * @param {String} message
6738 * @namespace Assert
6739 * @api public
6740 */
6741
6742 assert.oneOf = function (inList, list, msg) {
6743 new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list);
6744 }
6745
6746 /**
6747 * ### .changes(function, object, property, [message])
6748 *
6749 * Asserts that a function changes the value of a property.
6750 *
6751 * var obj = { val: 10 };
6752 * var fn = function() { obj.val = 22 };
6753 * assert.changes(fn, obj, 'val');
6754 *
6755 * @name changes
6756 * @param {Function} modifier function
6757 * @param {Object} object or getter function
6758 * @param {String} property name _optional_
6759 * @param {String} message _optional_
6760 * @namespace Assert
6761 * @api public
6762 */
6763
6764 assert.changes = function (fn, obj, prop, msg) {
6765 if (arguments.length === 3 && typeof obj === 'function') {
6766 msg = prop;
6767 prop = null;
6768 }
6769
6770 new Assertion(fn, msg, assert.changes, true).to.change(obj, prop);
6771 }
6772
6773 /**
6774 * ### .changesBy(function, object, property, delta, [message])
6775 *
6776 * Asserts that a function changes the value of a property by an amount (delta).
6777 *
6778 * var obj = { val: 10 };
6779 * var fn = function() { obj.val += 2 };
6780 * assert.changesBy(fn, obj, 'val', 2);
6781 *
6782 * @name changesBy
6783 * @param {Function} modifier function
6784 * @param {Object} object or getter function
6785 * @param {String} property name _optional_
6786 * @param {Number} change amount (delta)
6787 * @param {String} message _optional_
6788 * @namespace Assert
6789 * @api public
6790 */
6791
6792 assert.changesBy = function (fn, obj, prop, delta, msg) {
6793 if (arguments.length === 4 && typeof obj === 'function') {
6794 var tmpMsg = delta;
6795 delta = prop;
6796 msg = tmpMsg;
6797 } else if (arguments.length === 3) {
6798 delta = prop;
6799 prop = null;
6800 }
6801
6802 new Assertion(fn, msg, assert.changesBy, true)
6803 .to.change(obj, prop).by(delta);
6804 }
6805
6806 /**
6807 * ### .doesNotChange(function, object, property, [message])
6808 *
6809 * Asserts that a function does not change the value of a property.
6810 *
6811 * var obj = { val: 10 };
6812 * var fn = function() { console.log('foo'); };
6813 * assert.doesNotChange(fn, obj, 'val');
6814 *
6815 * @name doesNotChange
6816 * @param {Function} modifier function
6817 * @param {Object} object or getter function
6818 * @param {String} property name _optional_
6819 * @param {String} message _optional_
6820 * @namespace Assert
6821 * @api public
6822 */
6823
6824 assert.doesNotChange = function (fn, obj, prop, msg) {
6825 if (arguments.length === 3 && typeof obj === 'function') {
6826 msg = prop;
6827 prop = null;
6828 }
6829
6830 return new Assertion(fn, msg, assert.doesNotChange, true)
6831 .to.not.change(obj, prop);
6832 }
6833
6834 /**
6835 * ### .changesButNotBy(function, object, property, delta, [message])
6836 *
6837 * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta)
6838 *
6839 * var obj = { val: 10 };
6840 * var fn = function() { obj.val += 10 };
6841 * assert.changesButNotBy(fn, obj, 'val', 5);
6842 *
6843 * @name changesButNotBy
6844 * @param {Function} modifier function
6845 * @param {Object} object or getter function
6846 * @param {String} property name _optional_
6847 * @param {Number} change amount (delta)
6848 * @param {String} message _optional_
6849 * @namespace Assert
6850 * @api public
6851 */
6852
6853 assert.changesButNotBy = function (fn, obj, prop, delta, msg) {
6854 if (arguments.length === 4 && typeof obj === 'function') {
6855 var tmpMsg = delta;
6856 delta = prop;
6857 msg = tmpMsg;
6858 } else if (arguments.length === 3) {
6859 delta = prop;
6860 prop = null;
6861 }
6862
6863 new Assertion(fn, msg, assert.changesButNotBy, true)
6864 .to.change(obj, prop).but.not.by(delta);
6865 }
6866
6867 /**
6868 * ### .increases(function, object, property, [message])
6869 *
6870 * Asserts that a function increases a numeric object property.
6871 *
6872 * var obj = { val: 10 };
6873 * var fn = function() { obj.val = 13 };
6874 * assert.increases(fn, obj, 'val');
6875 *
6876 * @name increases
6877 * @param {Function} modifier function
6878 * @param {Object} object or getter function
6879 * @param {String} property name _optional_
6880 * @param {String} message _optional_
6881 * @namespace Assert
6882 * @api public
6883 */
6884
6885 assert.increases = function (fn, obj, prop, msg) {
6886 if (arguments.length === 3 && typeof obj === 'function') {
6887 msg = prop;
6888 prop = null;
6889 }
6890
6891 return new Assertion(fn, msg, assert.increases, true)
6892 .to.increase(obj, prop);
6893 }
6894
6895 /**
6896 * ### .increasesBy(function, object, property, delta, [message])
6897 *
6898 * Asserts that a function increases a numeric object property or a function's return value by an amount (delta).
6899 *
6900 * var obj = { val: 10 };
6901 * var fn = function() { obj.val += 10 };
6902 * assert.increasesBy(fn, obj, 'val', 10);
6903 *
6904 * @name increasesBy
6905 * @param {Function} modifier function
6906 * @param {Object} object or getter function
6907 * @param {String} property name _optional_
6908 * @param {Number} change amount (delta)
6909 * @param {String} message _optional_
6910 * @namespace Assert
6911 * @api public
6912 */
6913
6914 assert.increasesBy = function (fn, obj, prop, delta, msg) {
6915 if (arguments.length === 4 && typeof obj === 'function') {
6916 var tmpMsg = delta;
6917 delta = prop;
6918 msg = tmpMsg;
6919 } else if (arguments.length === 3) {
6920 delta = prop;
6921 prop = null;
6922 }
6923
6924 new Assertion(fn, msg, assert.increasesBy, true)
6925 .to.increase(obj, prop).by(delta);
6926 }
6927
6928 /**
6929 * ### .doesNotIncrease(function, object, property, [message])
6930 *
6931 * Asserts that a function does not increase a numeric object property.
6932 *
6933 * var obj = { val: 10 };
6934 * var fn = function() { obj.val = 8 };
6935 * assert.doesNotIncrease(fn, obj, 'val');
6936 *
6937 * @name doesNotIncrease
6938 * @param {Function} modifier function
6939 * @param {Object} object or getter function
6940 * @param {String} property name _optional_
6941 * @param {String} message _optional_
6942 * @namespace Assert
6943 * @api public
6944 */
6945
6946 assert.doesNotIncrease = function (fn, obj, prop, msg) {
6947 if (arguments.length === 3 && typeof obj === 'function') {
6948 msg = prop;
6949 prop = null;
6950 }
6951
6952 return new Assertion(fn, msg, assert.doesNotIncrease, true)
6953 .to.not.increase(obj, prop);
6954 }
6955
6956 /**
6957 * ### .increasesButNotBy(function, object, property, delta, [message])
6958 *
6959 * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta).
6960 *
6961 * var obj = { val: 10 };
6962 * var fn = function() { obj.val = 15 };
6963 * assert.increasesButNotBy(fn, obj, 'val', 10);
6964 *
6965 * @name increasesButNotBy
6966 * @param {Function} modifier function
6967 * @param {Object} object or getter function
6968 * @param {String} property name _optional_
6969 * @param {Number} change amount (delta)
6970 * @param {String} message _optional_
6971 * @namespace Assert
6972 * @api public
6973 */
6974
6975 assert.increasesButNotBy = function (fn, obj, prop, delta, msg) {
6976 if (arguments.length === 4 && typeof obj === 'function') {
6977 var tmpMsg = delta;
6978 delta = prop;
6979 msg = tmpMsg;
6980 } else if (arguments.length === 3) {
6981 delta = prop;
6982 prop = null;
6983 }
6984
6985 new Assertion(fn, msg, assert.increasesButNotBy, true)
6986 .to.increase(obj, prop).but.not.by(delta);
6987 }
6988
6989 /**
6990 * ### .decreases(function, object, property, [message])
6991 *
6992 * Asserts that a function decreases a numeric object property.
6993 *
6994 * var obj = { val: 10 };
6995 * var fn = function() { obj.val = 5 };
6996 * assert.decreases(fn, obj, 'val');
6997 *
6998 * @name decreases
6999 * @param {Function} modifier function
7000 * @param {Object} object or getter function
7001 * @param {String} property name _optional_
7002 * @param {String} message _optional_
7003 * @namespace Assert
7004 * @api public
7005 */
7006
7007 assert.decreases = function (fn, obj, prop, msg) {
7008 if (arguments.length === 3 && typeof obj === 'function') {
7009 msg = prop;
7010 prop = null;
7011 }
7012
7013 return new Assertion(fn, msg, assert.decreases, true)
7014 .to.decrease(obj, prop);
7015 }
7016
7017 /**
7018 * ### .decreasesBy(function, object, property, delta, [message])
7019 *
7020 * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta)
7021 *
7022 * var obj = { val: 10 };
7023 * var fn = function() { obj.val -= 5 };
7024 * assert.decreasesBy(fn, obj, 'val', 5);
7025 *
7026 * @name decreasesBy
7027 * @param {Function} modifier function
7028 * @param {Object} object or getter function
7029 * @param {String} property name _optional_
7030 * @param {Number} change amount (delta)
7031 * @param {String} message _optional_
7032 * @namespace Assert
7033 * @api public
7034 */
7035
7036 assert.decreasesBy = function (fn, obj, prop, delta, msg) {
7037 if (arguments.length === 4 && typeof obj === 'function') {
7038 var tmpMsg = delta;
7039 delta = prop;
7040 msg = tmpMsg;
7041 } else if (arguments.length === 3) {
7042 delta = prop;
7043 prop = null;
7044 }
7045
7046 new Assertion(fn, msg, assert.decreasesBy, true)
7047 .to.decrease(obj, prop).by(delta);
7048 }
7049
7050 /**
7051 * ### .doesNotDecrease(function, object, property, [message])
7052 *
7053 * Asserts that a function does not decreases a numeric object property.
7054 *
7055 * var obj = { val: 10 };
7056 * var fn = function() { obj.val = 15 };
7057 * assert.doesNotDecrease(fn, obj, 'val');
7058 *
7059 * @name doesNotDecrease
7060 * @param {Function} modifier function
7061 * @param {Object} object or getter function
7062 * @param {String} property name _optional_
7063 * @param {String} message _optional_
7064 * @namespace Assert
7065 * @api public
7066 */
7067
7068 assert.doesNotDecrease = function (fn, obj, prop, msg) {
7069 if (arguments.length === 3 && typeof obj === 'function') {
7070 msg = prop;
7071 prop = null;
7072 }
7073
7074 return new Assertion(fn, msg, assert.doesNotDecrease, true)
7075 .to.not.decrease(obj, prop);
7076 }
7077
7078 /**
7079 * ### .doesNotDecreaseBy(function, object, property, delta, [message])
7080 *
7081 * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta)
7082 *
7083 * var obj = { val: 10 };
7084 * var fn = function() { obj.val = 5 };
7085 * assert.doesNotDecreaseBy(fn, obj, 'val', 1);
7086 *
7087 * @name doesNotDecreaseBy
7088 * @param {Function} modifier function
7089 * @param {Object} object or getter function
7090 * @param {String} property name _optional_
7091 * @param {Number} change amount (delta)
7092 * @param {String} message _optional_
7093 * @namespace Assert
7094 * @api public
7095 */
7096
7097 assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) {
7098 if (arguments.length === 4 && typeof obj === 'function') {
7099 var tmpMsg = delta;
7100 delta = prop;
7101 msg = tmpMsg;
7102 } else if (arguments.length === 3) {
7103 delta = prop;
7104 prop = null;
7105 }
7106
7107 return new Assertion(fn, msg, assert.doesNotDecreaseBy, true)
7108 .to.not.decrease(obj, prop).by(delta);
7109 }
7110
7111 /**
7112 * ### .decreasesButNotBy(function, object, property, delta, [message])
7113 *
7114 * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta)
7115 *
7116 * var obj = { val: 10 };
7117 * var fn = function() { obj.val = 5 };
7118 * assert.decreasesButNotBy(fn, obj, 'val', 1);
7119 *
7120 * @name decreasesButNotBy
7121 * @param {Function} modifier function
7122 * @param {Object} object or getter function
7123 * @param {String} property name _optional_
7124 * @param {Number} change amount (delta)
7125 * @param {String} message _optional_
7126 * @namespace Assert
7127 * @api public
7128 */
7129
7130 assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) {
7131 if (arguments.length === 4 && typeof obj === 'function') {
7132 var tmpMsg = delta;
7133 delta = prop;
7134 msg = tmpMsg;
7135 } else if (arguments.length === 3) {
7136 delta = prop;
7137 prop = null;
7138 }
7139
7140 new Assertion(fn, msg, assert.decreasesButNotBy, true)
7141 .to.decrease(obj, prop).but.not.by(delta);
7142 }
7143
7144 /*!
7145 * ### .ifError(object)
7146 *
7147 * Asserts if value is not a false value, and throws if it is a true value.
7148 * This is added to allow for chai to be a drop-in replacement for Node's
7149 * assert class.
7150 *
7151 * var err = new Error('I am a custom error');
7152 * assert.ifError(err); // Rethrows err!
7153 *
7154 * @name ifError
7155 * @param {Object} object
7156 * @namespace Assert
7157 * @api public
7158 */
7159
7160 assert.ifError = function (val) {
7161 if (val) {
7162 throw(val);
7163 }
7164 };
7165
7166 /**
7167 * ### .isExtensible(object)
7168 *
7169 * Asserts that `object` is extensible (can have new properties added to it).
7170 *
7171 * assert.isExtensible({});
7172 *
7173 * @name isExtensible
7174 * @alias extensible
7175 * @param {Object} object
7176 * @param {String} message _optional_
7177 * @namespace Assert
7178 * @api public
7179 */
7180
7181 assert.isExtensible = function (obj, msg) {
7182 new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible;
7183 };
7184
7185 /**
7186 * ### .isNotExtensible(object)
7187 *
7188 * Asserts that `object` is _not_ extensible.
7189 *
7190 * var nonExtensibleObject = Object.preventExtensions({});
7191 * var sealedObject = Object.seal({});
7192 * var frozenObject = Object.freeze({});
7193 *
7194 * assert.isNotExtensible(nonExtensibleObject);
7195 * assert.isNotExtensible(sealedObject);
7196 * assert.isNotExtensible(frozenObject);
7197 *
7198 * @name isNotExtensible
7199 * @alias notExtensible
7200 * @param {Object} object
7201 * @param {String} message _optional_
7202 * @namespace Assert
7203 * @api public
7204 */
7205
7206 assert.isNotExtensible = function (obj, msg) {
7207 new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible;
7208 };
7209
7210 /**
7211 * ### .isSealed(object)
7212 *
7213 * Asserts that `object` is sealed (cannot have new properties added to it
7214 * and its existing properties cannot be removed).
7215 *
7216 * var sealedObject = Object.seal({});
7217 * var frozenObject = Object.seal({});
7218 *
7219 * assert.isSealed(sealedObject);
7220 * assert.isSealed(frozenObject);
7221 *
7222 * @name isSealed
7223 * @alias sealed
7224 * @param {Object} object
7225 * @param {String} message _optional_
7226 * @namespace Assert
7227 * @api public
7228 */
7229
7230 assert.isSealed = function (obj, msg) {
7231 new Assertion(obj, msg, assert.isSealed, true).to.be.sealed;
7232 };
7233
7234 /**
7235 * ### .isNotSealed(object)
7236 *
7237 * Asserts that `object` is _not_ sealed.
7238 *
7239 * assert.isNotSealed({});
7240 *
7241 * @name isNotSealed
7242 * @alias notSealed
7243 * @param {Object} object
7244 * @param {String} message _optional_
7245 * @namespace Assert
7246 * @api public
7247 */
7248
7249 assert.isNotSealed = function (obj, msg) {
7250 new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed;
7251 };
7252
7253 /**
7254 * ### .isFrozen(object)
7255 *
7256 * Asserts that `object` is frozen (cannot have new properties added to it
7257 * and its existing properties cannot be modified).
7258 *
7259 * var frozenObject = Object.freeze({});
7260 * assert.frozen(frozenObject);
7261 *
7262 * @name isFrozen
7263 * @alias frozen
7264 * @param {Object} object
7265 * @param {String} message _optional_
7266 * @namespace Assert
7267 * @api public
7268 */
7269
7270 assert.isFrozen = function (obj, msg) {
7271 new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen;
7272 };
7273
7274 /**
7275 * ### .isNotFrozen(object)
7276 *
7277 * Asserts that `object` is _not_ frozen.
7278 *
7279 * assert.isNotFrozen({});
7280 *
7281 * @name isNotFrozen
7282 * @alias notFrozen
7283 * @param {Object} object
7284 * @param {String} message _optional_
7285 * @namespace Assert
7286 * @api public
7287 */
7288
7289 assert.isNotFrozen = function (obj, msg) {
7290 new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen;
7291 };
7292
7293 /**
7294 * ### .isEmpty(target)
7295 *
7296 * Asserts that the target does not contain any values.
7297 * For arrays and strings, it checks the `length` property.
7298 * For `Map` and `Set` instances, it checks the `size` property.
7299 * For non-function objects, it gets the count of own
7300 * enumerable string keys.
7301 *
7302 * assert.isEmpty([]);
7303 * assert.isEmpty('');
7304 * assert.isEmpty(new Map);
7305 * assert.isEmpty({});
7306 *
7307 * @name isEmpty
7308 * @alias empty
7309 * @param {Object|Array|String|Map|Set} target
7310 * @param {String} message _optional_
7311 * @namespace Assert
7312 * @api public
7313 */
7314
7315 assert.isEmpty = function(val, msg) {
7316 new Assertion(val, msg, assert.isEmpty, true).to.be.empty;
7317 };
7318
7319 /**
7320 * ### .isNotEmpty(target)
7321 *
7322 * Asserts that the target contains values.
7323 * For arrays and strings, it checks the `length` property.
7324 * For `Map` and `Set` instances, it checks the `size` property.
7325 * For non-function objects, it gets the count of own
7326 * enumerable string keys.
7327 *
7328 * assert.isNotEmpty([1, 2]);
7329 * assert.isNotEmpty('34');
7330 * assert.isNotEmpty(new Set([5, 6]));
7331 * assert.isNotEmpty({ key: 7 });
7332 *
7333 * @name isNotEmpty
7334 * @alias notEmpty
7335 * @param {Object|Array|String|Map|Set} target
7336 * @param {String} message _optional_
7337 * @namespace Assert
7338 * @api public
7339 */
7340
7341 assert.isNotEmpty = function(val, msg) {
7342 new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty;
7343 };
7344
7345 /*!
7346 * Aliases.
7347 */
7348
7349 (function alias(name, as){
7350 assert[as] = assert[name];
7351 return alias;
7352 })
7353 ('isOk', 'ok')
7354 ('isNotOk', 'notOk')
7355 ('throws', 'throw')
7356 ('throws', 'Throw')
7357 ('isExtensible', 'extensible')
7358 ('isNotExtensible', 'notExtensible')
7359 ('isSealed', 'sealed')
7360 ('isNotSealed', 'notSealed')
7361 ('isFrozen', 'frozen')
7362 ('isNotFrozen', 'notFrozen')
7363 ('isEmpty', 'empty')
7364 ('isNotEmpty', 'notEmpty');
7365 };
7366
7367 },{}],7:[function(require,module,exports){
7368 /*!
7369 * chai
7370 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
7371 * MIT Licensed
7372 */
7373
7374 module.exports = function (chai, util) {
7375 chai.expect = function (val, message) {
7376 return new chai.Assertion(val, message);
7377 };
7378
7379 /**
7380 * ### .fail([message])
7381 * ### .fail(actual, expected, [message], [operator])
7382 *
7383 * Throw a failure.
7384 *
7385 * expect.fail();
7386 * expect.fail("custom error message");
7387 * expect.fail(1, 2);
7388 * expect.fail(1, 2, "custom error message");
7389 * expect.fail(1, 2, "custom error message", ">");
7390 * expect.fail(1, 2, undefined, ">");
7391 *
7392 * @name fail
7393 * @param {Mixed} actual
7394 * @param {Mixed} expected
7395 * @param {String} message
7396 * @param {String} operator
7397 * @namespace BDD
7398 * @api public
7399 */
7400
7401 chai.expect.fail = function (actual, expected, message, operator) {
7402 if (arguments.length < 2) {
7403 message = actual;
7404 actual = undefined;
7405 }
7406
7407 message = message || 'expect.fail()';
7408 throw new chai.AssertionError(message, {
7409 actual: actual
7410 , expected: expected
7411 , operator: operator
7412 }, chai.expect.fail);
7413 };
7414 };
7415
7416 },{}],8:[function(require,module,exports){
7417 /*!
7418 * chai
7419 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
7420 * MIT Licensed
7421 */
7422
7423 module.exports = function (chai, util) {
7424 var Assertion = chai.Assertion;
7425
7426 function loadShould () {
7427 // explicitly define this method as function as to have it's name to include as `ssfi`
7428 function shouldGetter() {
7429 if (this instanceof String
7430 || this instanceof Number
7431 || this instanceof Boolean
7432 || typeof Symbol === 'function' && this instanceof Symbol
7433 || typeof BigInt === 'function' && this instanceof BigInt) {
7434 return new Assertion(this.valueOf(), null, shouldGetter);
7435 }
7436 return new Assertion(this, null, shouldGetter);
7437 }
7438 function shouldSetter(value) {
7439 // See https://github.com/chaijs/chai/issues/86: this makes
7440 // `whatever.should = someValue` actually set `someValue`, which is
7441 // especially useful for `global.should = require('chai').should()`.
7442 //
7443 // Note that we have to use [[DefineProperty]] instead of [[Put]]
7444 // since otherwise we would trigger this very setter!
7445 Object.defineProperty(this, 'should', {
7446 value: value,
7447 enumerable: true,
7448 configurable: true,
7449 writable: true
7450 });
7451 }
7452 // modify Object.prototype to have `should`
7453 Object.defineProperty(Object.prototype, 'should', {
7454 set: shouldSetter
7455 , get: shouldGetter
7456 , configurable: true
7457 });
7458
7459 var should = {};
7460
7461 /**
7462 * ### .fail([message])
7463 * ### .fail(actual, expected, [message], [operator])
7464 *
7465 * Throw a failure.
7466 *
7467 * should.fail();
7468 * should.fail("custom error message");
7469 * should.fail(1, 2);
7470 * should.fail(1, 2, "custom error message");
7471 * should.fail(1, 2, "custom error message", ">");
7472 * should.fail(1, 2, undefined, ">");
7473 *
7474 *
7475 * @name fail
7476 * @param {Mixed} actual
7477 * @param {Mixed} expected
7478 * @param {String} message
7479 * @param {String} operator
7480 * @namespace BDD
7481 * @api public
7482 */
7483
7484 should.fail = function (actual, expected, message, operator) {
7485 if (arguments.length < 2) {
7486 message = actual;
7487 actual = undefined;
7488 }
7489
7490 message = message || 'should.fail()';
7491 throw new chai.AssertionError(message, {
7492 actual: actual
7493 , expected: expected
7494 , operator: operator
7495 }, should.fail);
7496 };
7497
7498 /**
7499 * ### .equal(actual, expected, [message])
7500 *
7501 * Asserts non-strict equality (`==`) of `actual` and `expected`.
7502 *
7503 * should.equal(3, '3', '== coerces values to strings');
7504 *
7505 * @name equal
7506 * @param {Mixed} actual
7507 * @param {Mixed} expected
7508 * @param {String} message
7509 * @namespace Should
7510 * @api public
7511 */
7512
7513 should.equal = function (val1, val2, msg) {
7514 new Assertion(val1, msg).to.equal(val2);
7515 };
7516
7517 /**
7518 * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])
7519 *
7520 * Asserts that `function` will throw an error that is an instance of
7521 * `constructor`, or alternately that it will throw an error with message
7522 * matching `regexp`.
7523 *
7524 * should.throw(fn, 'function throws a reference error');
7525 * should.throw(fn, /function throws a reference error/);
7526 * should.throw(fn, ReferenceError);
7527 * should.throw(fn, ReferenceError, 'function throws a reference error');
7528 * should.throw(fn, ReferenceError, /function throws a reference error/);
7529 *
7530 * @name throw
7531 * @alias Throw
7532 * @param {Function} function
7533 * @param {ErrorConstructor} constructor
7534 * @param {RegExp} regexp
7535 * @param {String} message
7536 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
7537 * @namespace Should
7538 * @api public
7539 */
7540
7541 should.Throw = function (fn, errt, errs, msg) {
7542 new Assertion(fn, msg).to.Throw(errt, errs);
7543 };
7544
7545 /**
7546 * ### .exist
7547 *
7548 * Asserts that the target is neither `null` nor `undefined`.
7549 *
7550 * var foo = 'hi';
7551 *
7552 * should.exist(foo, 'foo exists');
7553 *
7554 * @name exist
7555 * @namespace Should
7556 * @api public
7557 */
7558
7559 should.exist = function (val, msg) {
7560 new Assertion(val, msg).to.exist;
7561 }
7562
7563 // negation
7564 should.not = {}
7565
7566 /**
7567 * ### .not.equal(actual, expected, [message])
7568 *
7569 * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
7570 *
7571 * should.not.equal(3, 4, 'these numbers are not equal');
7572 *
7573 * @name not.equal
7574 * @param {Mixed} actual
7575 * @param {Mixed} expected
7576 * @param {String} message
7577 * @namespace Should
7578 * @api public
7579 */
7580
7581 should.not.equal = function (val1, val2, msg) {
7582 new Assertion(val1, msg).to.not.equal(val2);
7583 };
7584
7585 /**
7586 * ### .throw(function, [constructor/regexp], [message])
7587 *
7588 * Asserts that `function` will _not_ throw an error that is an instance of
7589 * `constructor`, or alternately that it will not throw an error with message
7590 * matching `regexp`.
7591 *
7592 * should.not.throw(fn, Error, 'function does not throw');
7593 *
7594 * @name not.throw
7595 * @alias not.Throw
7596 * @param {Function} function
7597 * @param {ErrorConstructor} constructor
7598 * @param {RegExp} regexp
7599 * @param {String} message
7600 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
7601 * @namespace Should
7602 * @api public
7603 */
7604
7605 should.not.Throw = function (fn, errt, errs, msg) {
7606 new Assertion(fn, msg).to.not.Throw(errt, errs);
7607 };
7608
7609 /**
7610 * ### .not.exist
7611 *
7612 * Asserts that the target is neither `null` nor `undefined`.
7613 *
7614 * var bar = null;
7615 *
7616 * should.not.exist(bar, 'bar does not exist');
7617 *
7618 * @name not.exist
7619 * @namespace Should
7620 * @api public
7621 */
7622
7623 should.not.exist = function (val, msg) {
7624 new Assertion(val, msg).to.not.exist;
7625 }
7626
7627 should['throw'] = should['Throw'];
7628 should.not['throw'] = should.not['Throw'];
7629
7630 return should;
7631 };
7632
7633 chai.should = loadShould;
7634 chai.Should = loadShould;
7635 };
7636
7637 },{}],9:[function(require,module,exports){
7638 /*!
7639 * Chai - addChainingMethod utility
7640 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
7641 * MIT Licensed
7642 */
7643
7644 /*!
7645 * Module dependencies
7646 */
7647
7648 var addLengthGuard = require('./addLengthGuard');
7649 var chai = require('../../chai');
7650 var flag = require('./flag');
7651 var proxify = require('./proxify');
7652 var transferFlags = require('./transferFlags');
7653
7654 /*!
7655 * Module variables
7656 */
7657
7658 // Check whether `Object.setPrototypeOf` is supported
7659 var canSetPrototype = typeof Object.setPrototypeOf === 'function';
7660
7661 // Without `Object.setPrototypeOf` support, this module will need to add properties to a function.
7662 // However, some of functions' own props are not configurable and should be skipped.
7663 var testFn = function() {};
7664 var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) {
7665 var propDesc = Object.getOwnPropertyDescriptor(testFn, name);
7666
7667 // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties,
7668 // but then returns `undefined` as the property descriptor for `callee`. As a
7669 // workaround, we perform an otherwise unnecessary type-check for `propDesc`,
7670 // and then filter it out if it's not an object as it should be.
7671 if (typeof propDesc !== 'object')
7672 return true;
7673
7674 return !propDesc.configurable;
7675 });
7676
7677 // Cache `Function` properties
7678 var call = Function.prototype.call,
7679 apply = Function.prototype.apply;
7680
7681 /**
7682 * ### .addChainableMethod(ctx, name, method, chainingBehavior)
7683 *
7684 * Adds a method to an object, such that the method can also be chained.
7685 *
7686 * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {
7687 * var obj = utils.flag(this, 'object');
7688 * new chai.Assertion(obj).to.be.equal(str);
7689 * });
7690 *
7691 * Can also be accessed directly from `chai.Assertion`.
7692 *
7693 * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);
7694 *
7695 * The result can then be used as both a method assertion, executing both `method` and
7696 * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.
7697 *
7698 * expect(fooStr).to.be.foo('bar');
7699 * expect(fooStr).to.be.foo.equal('foo');
7700 *
7701 * @param {Object} ctx object to which the method is added
7702 * @param {String} name of method to add
7703 * @param {Function} method function to be used for `name`, when called
7704 * @param {Function} chainingBehavior function to be called every time the property is accessed
7705 * @namespace Utils
7706 * @name addChainableMethod
7707 * @api public
7708 */
7709
7710 module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) {
7711 if (typeof chainingBehavior !== 'function') {
7712 chainingBehavior = function () { };
7713 }
7714
7715 var chainableBehavior = {
7716 method: method
7717 , chainingBehavior: chainingBehavior
7718 };
7719
7720 // save the methods so we can overwrite them later, if we need to.
7721 if (!ctx.__methods) {
7722 ctx.__methods = {};
7723 }
7724 ctx.__methods[name] = chainableBehavior;
7725
7726 Object.defineProperty(ctx, name,
7727 { get: function chainableMethodGetter() {
7728 chainableBehavior.chainingBehavior.call(this);
7729
7730 var chainableMethodWrapper = function () {
7731 // Setting the `ssfi` flag to `chainableMethodWrapper` causes this
7732 // function to be the starting point for removing implementation
7733 // frames from the stack trace of a failed assertion.
7734 //
7735 // However, we only want to use this function as the starting point if
7736 // the `lockSsfi` flag isn't set.
7737 //
7738 // If the `lockSsfi` flag is set, then this assertion is being
7739 // invoked from inside of another assertion. In this case, the `ssfi`
7740 // flag has already been set by the outer assertion.
7741 //
7742 // Note that overwriting a chainable method merely replaces the saved
7743 // methods in `ctx.__methods` instead of completely replacing the
7744 // overwritten assertion. Therefore, an overwriting assertion won't
7745 // set the `ssfi` or `lockSsfi` flags.
7746 if (!flag(this, 'lockSsfi')) {
7747 flag(this, 'ssfi', chainableMethodWrapper);
7748 }
7749
7750 var result = chainableBehavior.method.apply(this, arguments);
7751 if (result !== undefined) {
7752 return result;
7753 }
7754
7755 var newAssertion = new chai.Assertion();
7756 transferFlags(this, newAssertion);
7757 return newAssertion;
7758 };
7759
7760 addLengthGuard(chainableMethodWrapper, name, true);
7761
7762 // Use `Object.setPrototypeOf` if available
7763 if (canSetPrototype) {
7764 // Inherit all properties from the object by replacing the `Function` prototype
7765 var prototype = Object.create(this);
7766 // Restore the `call` and `apply` methods from `Function`
7767 prototype.call = call;
7768 prototype.apply = apply;
7769 Object.setPrototypeOf(chainableMethodWrapper, prototype);
7770 }
7771 // Otherwise, redefine all properties (slow!)
7772 else {
7773 var asserterNames = Object.getOwnPropertyNames(ctx);
7774 asserterNames.forEach(function (asserterName) {
7775 if (excludeNames.indexOf(asserterName) !== -1) {
7776 return;
7777 }
7778
7779 var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);
7780 Object.defineProperty(chainableMethodWrapper, asserterName, pd);
7781 });
7782 }
7783
7784 transferFlags(this, chainableMethodWrapper);
7785 return proxify(chainableMethodWrapper);
7786 }
7787 , configurable: true
7788 });
7789 };
7790
7791 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],10:[function(require,module,exports){
7792 var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length');
7793
7794 /*!
7795 * Chai - addLengthGuard utility
7796 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
7797 * MIT Licensed
7798 */
7799
7800 /**
7801 * ### .addLengthGuard(fn, assertionName, isChainable)
7802 *
7803 * Define `length` as a getter on the given uninvoked method assertion. The
7804 * getter acts as a guard against chaining `length` directly off of an uninvoked
7805 * method assertion, which is a problem because it references `function`'s
7806 * built-in `length` property instead of Chai's `length` assertion. When the
7807 * getter catches the user making this mistake, it throws an error with a
7808 * helpful message.
7809 *
7810 * There are two ways in which this mistake can be made. The first way is by
7811 * chaining the `length` assertion directly off of an uninvoked chainable
7812 * method. In this case, Chai suggests that the user use `lengthOf` instead. The
7813 * second way is by chaining the `length` assertion directly off of an uninvoked
7814 * non-chainable method. Non-chainable methods must be invoked prior to
7815 * chaining. In this case, Chai suggests that the user consult the docs for the
7816 * given assertion.
7817 *
7818 * If the `length` property of functions is unconfigurable, then return `fn`
7819 * without modification.
7820 *
7821 * Note that in ES6, the function's `length` property is configurable, so once
7822 * support for legacy environments is dropped, Chai's `length` property can
7823 * replace the built-in function's `length` property, and this length guard will
7824 * no longer be necessary. In the mean time, maintaining consistency across all
7825 * environments is the priority.
7826 *
7827 * @param {Function} fn
7828 * @param {String} assertionName
7829 * @param {Boolean} isChainable
7830 * @namespace Utils
7831 * @name addLengthGuard
7832 */
7833
7834 module.exports = function addLengthGuard (fn, assertionName, isChainable) {
7835 if (!fnLengthDesc.configurable) return fn;
7836
7837 Object.defineProperty(fn, 'length', {
7838 get: function () {
7839 if (isChainable) {
7840 throw Error('Invalid Chai property: ' + assertionName + '.length. Due' +
7841 ' to a compatibility issue, "length" cannot directly follow "' +
7842 assertionName + '". Use "' + assertionName + '.lengthOf" instead.');
7843 }
7844
7845 throw Error('Invalid Chai property: ' + assertionName + '.length. See' +
7846 ' docs for proper usage of "' + assertionName + '".');
7847 }
7848 });
7849
7850 return fn;
7851 };
7852
7853 },{}],11:[function(require,module,exports){
7854 /*!
7855 * Chai - addMethod utility
7856 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
7857 * MIT Licensed
7858 */
7859
7860 var addLengthGuard = require('./addLengthGuard');
7861 var chai = require('../../chai');
7862 var flag = require('./flag');
7863 var proxify = require('./proxify');
7864 var transferFlags = require('./transferFlags');
7865
7866 /**
7867 * ### .addMethod(ctx, name, method)
7868 *
7869 * Adds a method to the prototype of an object.
7870 *
7871 * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {
7872 * var obj = utils.flag(this, 'object');
7873 * new chai.Assertion(obj).to.be.equal(str);
7874 * });
7875 *
7876 * Can also be accessed directly from `chai.Assertion`.
7877 *
7878 * chai.Assertion.addMethod('foo', fn);
7879 *
7880 * Then can be used as any other assertion.
7881 *
7882 * expect(fooStr).to.be.foo('bar');
7883 *
7884 * @param {Object} ctx object to which the method is added
7885 * @param {String} name of method to add
7886 * @param {Function} method function to be used for name
7887 * @namespace Utils
7888 * @name addMethod
7889 * @api public
7890 */
7891
7892 module.exports = function addMethod(ctx, name, method) {
7893 var methodWrapper = function () {
7894 // Setting the `ssfi` flag to `methodWrapper` causes this function to be the
7895 // starting point for removing implementation frames from the stack trace of
7896 // a failed assertion.
7897 //
7898 // However, we only want to use this function as the starting point if the
7899 // `lockSsfi` flag isn't set.
7900 //
7901 // If the `lockSsfi` flag is set, then either this assertion has been
7902 // overwritten by another assertion, or this assertion is being invoked from
7903 // inside of another assertion. In the first case, the `ssfi` flag has
7904 // already been set by the overwriting assertion. In the second case, the
7905 // `ssfi` flag has already been set by the outer assertion.
7906 if (!flag(this, 'lockSsfi')) {
7907 flag(this, 'ssfi', methodWrapper);
7908 }
7909
7910 var result = method.apply(this, arguments);
7911 if (result !== undefined)
7912 return result;
7913
7914 var newAssertion = new chai.Assertion();
7915 transferFlags(this, newAssertion);
7916 return newAssertion;
7917 };
7918
7919 addLengthGuard(methodWrapper, name, false);
7920 ctx[name] = proxify(methodWrapper, name);
7921 };
7922
7923 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],12:[function(require,module,exports){
7924 /*!
7925 * Chai - addProperty utility
7926 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
7927 * MIT Licensed
7928 */
7929
7930 var chai = require('../../chai');
7931 var flag = require('./flag');
7932 var isProxyEnabled = require('./isProxyEnabled');
7933 var transferFlags = require('./transferFlags');
7934
7935 /**
7936 * ### .addProperty(ctx, name, getter)
7937 *
7938 * Adds a property to the prototype of an object.
7939 *
7940 * utils.addProperty(chai.Assertion.prototype, 'foo', function () {
7941 * var obj = utils.flag(this, 'object');
7942 * new chai.Assertion(obj).to.be.instanceof(Foo);
7943 * });
7944 *
7945 * Can also be accessed directly from `chai.Assertion`.
7946 *
7947 * chai.Assertion.addProperty('foo', fn);
7948 *
7949 * Then can be used as any other assertion.
7950 *
7951 * expect(myFoo).to.be.foo;
7952 *
7953 * @param {Object} ctx object to which the property is added
7954 * @param {String} name of property to add
7955 * @param {Function} getter function to be used for name
7956 * @namespace Utils
7957 * @name addProperty
7958 * @api public
7959 */
7960
7961 module.exports = function addProperty(ctx, name, getter) {
7962 getter = getter === undefined ? function () {} : getter;
7963
7964 Object.defineProperty(ctx, name,
7965 { get: function propertyGetter() {
7966 // Setting the `ssfi` flag to `propertyGetter` causes this function to
7967 // be the starting point for removing implementation frames from the
7968 // stack trace of a failed assertion.
7969 //
7970 // However, we only want to use this function as the starting point if
7971 // the `lockSsfi` flag isn't set and proxy protection is disabled.
7972 //
7973 // If the `lockSsfi` flag is set, then either this assertion has been
7974 // overwritten by another assertion, or this assertion is being invoked
7975 // from inside of another assertion. In the first case, the `ssfi` flag
7976 // has already been set by the overwriting assertion. In the second
7977 // case, the `ssfi` flag has already been set by the outer assertion.
7978 //
7979 // If proxy protection is enabled, then the `ssfi` flag has already been
7980 // set by the proxy getter.
7981 if (!isProxyEnabled() && !flag(this, 'lockSsfi')) {
7982 flag(this, 'ssfi', propertyGetter);
7983 }
7984
7985 var result = getter.call(this);
7986 if (result !== undefined)
7987 return result;
7988
7989 var newAssertion = new chai.Assertion();
7990 transferFlags(this, newAssertion);
7991 return newAssertion;
7992 }
7993 , configurable: true
7994 });
7995 };
7996
7997 },{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],13:[function(require,module,exports){
7998 /*!
7999 * Chai - compareByInspect utility
8000 * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
8001 * MIT Licensed
8002 */
8003
8004 /*!
8005 * Module dependencies
8006 */
8007
8008 var inspect = require('./inspect');
8009
8010 /**
8011 * ### .compareByInspect(mixed, mixed)
8012 *
8013 * To be used as a compareFunction with Array.prototype.sort. Compares elements
8014 * using inspect instead of default behavior of using toString so that Symbols
8015 * and objects with irregular/missing toString can still be sorted without a
8016 * TypeError.
8017 *
8018 * @param {Mixed} first element to compare
8019 * @param {Mixed} second element to compare
8020 * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1
8021 * @name compareByInspect
8022 * @namespace Utils
8023 * @api public
8024 */
8025
8026 module.exports = function compareByInspect(a, b) {
8027 return inspect(a) < inspect(b) ? -1 : 1;
8028 };
8029
8030 },{"./inspect":23}],14:[function(require,module,exports){
8031 /*!
8032 * Chai - expectTypes utility
8033 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8034 * MIT Licensed
8035 */
8036
8037 /**
8038 * ### .expectTypes(obj, types)
8039 *
8040 * Ensures that the object being tested against is of a valid type.
8041 *
8042 * utils.expectTypes(this, ['array', 'object', 'string']);
8043 *
8044 * @param {Mixed} obj constructed Assertion
8045 * @param {Array} type A list of allowed types for this assertion
8046 * @namespace Utils
8047 * @name expectTypes
8048 * @api public
8049 */
8050
8051 var AssertionError = require('assertion-error');
8052 var flag = require('./flag');
8053 var type = require('type-detect');
8054
8055 module.exports = function expectTypes(obj, types) {
8056 var flagMsg = flag(obj, 'message');
8057 var ssfi = flag(obj, 'ssfi');
8058
8059 flagMsg = flagMsg ? flagMsg + ': ' : '';
8060
8061 obj = flag(obj, 'object');
8062 types = types.map(function (t) { return t.toLowerCase(); });
8063 types.sort();
8064
8065 // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum'
8066 var str = types.map(function (t, index) {
8067 var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';
8068 var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';
8069 return or + art + ' ' + t;
8070 }).join(', ');
8071
8072 var objType = type(obj).toLowerCase();
8073
8074 if (!types.some(function (expected) { return objType === expected; })) {
8075 throw new AssertionError(
8076 flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given',
8077 undefined,
8078 ssfi
8079 );
8080 }
8081 };
8082
8083 },{"./flag":15,"assertion-error":33,"type-detect":39}],15:[function(require,module,exports){
8084 /*!
8085 * Chai - flag utility
8086 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8087 * MIT Licensed
8088 */
8089
8090 /**
8091 * ### .flag(object, key, [value])
8092 *
8093 * Get or set a flag value on an object. If a
8094 * value is provided it will be set, else it will
8095 * return the currently set value or `undefined` if
8096 * the value is not set.
8097 *
8098 * utils.flag(this, 'foo', 'bar'); // setter
8099 * utils.flag(this, 'foo'); // getter, returns `bar`
8100 *
8101 * @param {Object} object constructed Assertion
8102 * @param {String} key
8103 * @param {Mixed} value (optional)
8104 * @namespace Utils
8105 * @name flag
8106 * @api private
8107 */
8108
8109 module.exports = function flag(obj, key, value) {
8110 var flags = obj.__flags || (obj.__flags = Object.create(null));
8111 if (arguments.length === 3) {
8112 flags[key] = value;
8113 } else {
8114 return flags[key];
8115 }
8116 };
8117
8118 },{}],16:[function(require,module,exports){
8119 /*!
8120 * Chai - getActual utility
8121 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8122 * MIT Licensed
8123 */
8124
8125 /**
8126 * ### .getActual(object, [actual])
8127 *
8128 * Returns the `actual` value for an Assertion.
8129 *
8130 * @param {Object} object (constructed Assertion)
8131 * @param {Arguments} chai.Assertion.prototype.assert arguments
8132 * @namespace Utils
8133 * @name getActual
8134 */
8135
8136 module.exports = function getActual(obj, args) {
8137 return args.length > 4 ? args[4] : obj._obj;
8138 };
8139
8140 },{}],17:[function(require,module,exports){
8141 /*!
8142 * Chai - message composition utility
8143 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8144 * MIT Licensed
8145 */
8146
8147 /*!
8148 * Module dependencies
8149 */
8150
8151 var flag = require('./flag')
8152 , getActual = require('./getActual')
8153 , objDisplay = require('./objDisplay');
8154
8155 /**
8156 * ### .getMessage(object, message, negateMessage)
8157 *
8158 * Construct the error message based on flags
8159 * and template tags. Template tags will return
8160 * a stringified inspection of the object referenced.
8161 *
8162 * Message template tags:
8163 * - `#{this}` current asserted object
8164 * - `#{act}` actual value
8165 * - `#{exp}` expected value
8166 *
8167 * @param {Object} object (constructed Assertion)
8168 * @param {Arguments} chai.Assertion.prototype.assert arguments
8169 * @namespace Utils
8170 * @name getMessage
8171 * @api public
8172 */
8173
8174 module.exports = function getMessage(obj, args) {
8175 var negate = flag(obj, 'negate')
8176 , val = flag(obj, 'object')
8177 , expected = args[3]
8178 , actual = getActual(obj, args)
8179 , msg = negate ? args[2] : args[1]
8180 , flagMsg = flag(obj, 'message');
8181
8182 if(typeof msg === "function") msg = msg();
8183 msg = msg || '';
8184 msg = msg
8185 .replace(/#\{this\}/g, function () { return objDisplay(val); })
8186 .replace(/#\{act\}/g, function () { return objDisplay(actual); })
8187 .replace(/#\{exp\}/g, function () { return objDisplay(expected); });
8188
8189 return flagMsg ? flagMsg + ': ' + msg : msg;
8190 };
8191
8192 },{"./flag":15,"./getActual":16,"./objDisplay":26}],18:[function(require,module,exports){
8193 var type = require('type-detect');
8194
8195 var flag = require('./flag');
8196
8197 function isObjectType(obj) {
8198 var objectType = type(obj);
8199 var objectTypes = ['Array', 'Object', 'function'];
8200
8201 return objectTypes.indexOf(objectType) !== -1;
8202 }
8203
8204 /**
8205 * ### .getOperator(message)
8206 *
8207 * Extract the operator from error message.
8208 * Operator defined is based on below link
8209 * https://nodejs.org/api/assert.html#assert_assert.
8210 *
8211 * Returns the `operator` or `undefined` value for an Assertion.
8212 *
8213 * @param {Object} object (constructed Assertion)
8214 * @param {Arguments} chai.Assertion.prototype.assert arguments
8215 * @namespace Utils
8216 * @name getOperator
8217 * @api public
8218 */
8219
8220 module.exports = function getOperator(obj, args) {
8221 var operator = flag(obj, 'operator');
8222 var negate = flag(obj, 'negate');
8223 var expected = args[3];
8224 var msg = negate ? args[2] : args[1];
8225
8226 if (operator) {
8227 return operator;
8228 }
8229
8230 if (typeof msg === 'function') msg = msg();
8231
8232 msg = msg || '';
8233 if (!msg) {
8234 return undefined;
8235 }
8236
8237 if (/\shave\s/.test(msg)) {
8238 return undefined;
8239 }
8240
8241 var isObject = isObjectType(expected);
8242 if (/\snot\s/.test(msg)) {
8243 return isObject ? 'notDeepStrictEqual' : 'notStrictEqual';
8244 }
8245
8246 return isObject ? 'deepStrictEqual' : 'strictEqual';
8247 };
8248
8249 },{"./flag":15,"type-detect":39}],19:[function(require,module,exports){
8250 /*!
8251 * Chai - getOwnEnumerableProperties utility
8252 * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
8253 * MIT Licensed
8254 */
8255
8256 /*!
8257 * Module dependencies
8258 */
8259
8260 var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
8261
8262 /**
8263 * ### .getOwnEnumerableProperties(object)
8264 *
8265 * This allows the retrieval of directly-owned enumerable property names and
8266 * symbols of an object. This function is necessary because Object.keys only
8267 * returns enumerable property names, not enumerable property symbols.
8268 *
8269 * @param {Object} object
8270 * @returns {Array}
8271 * @namespace Utils
8272 * @name getOwnEnumerableProperties
8273 * @api public
8274 */
8275
8276 module.exports = function getOwnEnumerableProperties(obj) {
8277 return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj));
8278 };
8279
8280 },{"./getOwnEnumerablePropertySymbols":20}],20:[function(require,module,exports){
8281 /*!
8282 * Chai - getOwnEnumerablePropertySymbols utility
8283 * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
8284 * MIT Licensed
8285 */
8286
8287 /**
8288 * ### .getOwnEnumerablePropertySymbols(object)
8289 *
8290 * This allows the retrieval of directly-owned enumerable property symbols of an
8291 * object. This function is necessary because Object.getOwnPropertySymbols
8292 * returns both enumerable and non-enumerable property symbols.
8293 *
8294 * @param {Object} object
8295 * @returns {Array}
8296 * @namespace Utils
8297 * @name getOwnEnumerablePropertySymbols
8298 * @api public
8299 */
8300
8301 module.exports = function getOwnEnumerablePropertySymbols(obj) {
8302 if (typeof Object.getOwnPropertySymbols !== 'function') return [];
8303
8304 return Object.getOwnPropertySymbols(obj).filter(function (sym) {
8305 return Object.getOwnPropertyDescriptor(obj, sym).enumerable;
8306 });
8307 };
8308
8309 },{}],21:[function(require,module,exports){
8310 /*!
8311 * Chai - getProperties utility
8312 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8313 * MIT Licensed
8314 */
8315
8316 /**
8317 * ### .getProperties(object)
8318 *
8319 * This allows the retrieval of property names of an object, enumerable or not,
8320 * inherited or not.
8321 *
8322 * @param {Object} object
8323 * @returns {Array}
8324 * @namespace Utils
8325 * @name getProperties
8326 * @api public
8327 */
8328
8329 module.exports = function getProperties(object) {
8330 var result = Object.getOwnPropertyNames(object);
8331
8332 function addProperty(property) {
8333 if (result.indexOf(property) === -1) {
8334 result.push(property);
8335 }
8336 }
8337
8338 var proto = Object.getPrototypeOf(object);
8339 while (proto !== null) {
8340 Object.getOwnPropertyNames(proto).forEach(addProperty);
8341 proto = Object.getPrototypeOf(proto);
8342 }
8343
8344 return result;
8345 };
8346
8347 },{}],22:[function(require,module,exports){
8348 /*!
8349 * chai
8350 * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
8351 * MIT Licensed
8352 */
8353
8354 /*!
8355 * Dependencies that are used for multiple exports are required here only once
8356 */
8357
8358 var pathval = require('pathval');
8359
8360 /*!
8361 * test utility
8362 */
8363
8364 exports.test = require('./test');
8365
8366 /*!
8367 * type utility
8368 */
8369
8370 exports.type = require('type-detect');
8371
8372 /*!
8373 * expectTypes utility
8374 */
8375 exports.expectTypes = require('./expectTypes');
8376
8377 /*!
8378 * message utility
8379 */
8380
8381 exports.getMessage = require('./getMessage');
8382
8383 /*!
8384 * actual utility
8385 */
8386
8387 exports.getActual = require('./getActual');
8388
8389 /*!
8390 * Inspect util
8391 */
8392
8393 exports.inspect = require('./inspect');
8394
8395 /*!
8396 * Object Display util
8397 */
8398
8399 exports.objDisplay = require('./objDisplay');
8400
8401 /*!
8402 * Flag utility
8403 */
8404
8405 exports.flag = require('./flag');
8406
8407 /*!
8408 * Flag transferring utility
8409 */
8410
8411 exports.transferFlags = require('./transferFlags');
8412
8413 /*!
8414 * Deep equal utility
8415 */
8416
8417 exports.eql = require('deep-eql');
8418
8419 /*!
8420 * Deep path info
8421 */
8422
8423 exports.getPathInfo = pathval.getPathInfo;
8424
8425 /*!
8426 * Check if a property exists
8427 */
8428
8429 exports.hasProperty = pathval.hasProperty;
8430
8431 /*!
8432 * Function name
8433 */
8434
8435 exports.getName = require('get-func-name');
8436
8437 /*!
8438 * add Property
8439 */
8440
8441 exports.addProperty = require('./addProperty');
8442
8443 /*!
8444 * add Method
8445 */
8446
8447 exports.addMethod = require('./addMethod');
8448
8449 /*!
8450 * overwrite Property
8451 */
8452
8453 exports.overwriteProperty = require('./overwriteProperty');
8454
8455 /*!
8456 * overwrite Method
8457 */
8458
8459 exports.overwriteMethod = require('./overwriteMethod');
8460
8461 /*!
8462 * Add a chainable method
8463 */
8464
8465 exports.addChainableMethod = require('./addChainableMethod');
8466
8467 /*!
8468 * Overwrite chainable method
8469 */
8470
8471 exports.overwriteChainableMethod = require('./overwriteChainableMethod');
8472
8473 /*!
8474 * Compare by inspect method
8475 */
8476
8477 exports.compareByInspect = require('./compareByInspect');
8478
8479 /*!
8480 * Get own enumerable property symbols method
8481 */
8482
8483 exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
8484
8485 /*!
8486 * Get own enumerable properties method
8487 */
8488
8489 exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties');
8490
8491 /*!
8492 * Checks error against a given set of criteria
8493 */
8494
8495 exports.checkError = require('check-error');
8496
8497 /*!
8498 * Proxify util
8499 */
8500
8501 exports.proxify = require('./proxify');
8502
8503 /*!
8504 * addLengthGuard util
8505 */
8506
8507 exports.addLengthGuard = require('./addLengthGuard');
8508
8509 /*!
8510 * isProxyEnabled helper
8511 */
8512
8513 exports.isProxyEnabled = require('./isProxyEnabled');
8514
8515 /*!
8516 * isNaN method
8517 */
8518
8519 exports.isNaN = require('./isNaN');
8520
8521 /*!
8522 * getOperator method
8523 */
8524
8525 exports.getOperator = require('./getOperator');
8526 },{"./addChainableMethod":9,"./addLengthGuard":10,"./addMethod":11,"./addProperty":12,"./compareByInspect":13,"./expectTypes":14,"./flag":15,"./getActual":16,"./getMessage":17,"./getOperator":18,"./getOwnEnumerableProperties":19,"./getOwnEnumerablePropertySymbols":20,"./inspect":23,"./isNaN":24,"./isProxyEnabled":25,"./objDisplay":26,"./overwriteChainableMethod":27,"./overwriteMethod":28,"./overwriteProperty":29,"./proxify":30,"./test":31,"./transferFlags":32,"check-error":34,"deep-eql":35,"get-func-name":36,"pathval":38,"type-detect":39}],23:[function(require,module,exports){
8527 // This is (almost) directly from Node.js utils
8528 // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
8529
8530 var getName = require('get-func-name');
8531 var loupe = require('loupe');
8532 var config = require('../config');
8533
8534 module.exports = inspect;
8535
8536 /**
8537 * ### .inspect(obj, [showHidden], [depth], [colors])
8538 *
8539 * Echoes the value of a value. Tries to print the value out
8540 * in the best way possible given the different types.
8541 *
8542 * @param {Object} obj The object to print out.
8543 * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
8544 * properties of objects. Default is false.
8545 * @param {Number} depth Depth in which to descend in object. Default is 2.
8546 * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
8547 * output. Default is false (no coloring).
8548 * @namespace Utils
8549 * @name inspect
8550 */
8551 function inspect(obj, showHidden, depth, colors) {
8552 var options = {
8553 colors: colors,
8554 depth: (typeof depth === 'undefined' ? 2 : depth),
8555 showHidden: showHidden,
8556 truncate: config.truncateThreshold ? config.truncateThreshold : Infinity,
8557 };
8558 return loupe.inspect(obj, options);
8559 }
8560
8561 },{"../config":4,"get-func-name":36,"loupe":37}],24:[function(require,module,exports){
8562 /*!
8563 * Chai - isNaN utility
8564 * Copyright(c) 2012-2015 Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
8565 * MIT Licensed
8566 */
8567
8568 /**
8569 * ### .isNaN(value)
8570 *
8571 * Checks if the given value is NaN or not.
8572 *
8573 * utils.isNaN(NaN); // true
8574 *
8575 * @param {Value} The value which has to be checked if it is NaN
8576 * @name isNaN
8577 * @api private
8578 */
8579
8580 function isNaN(value) {
8581 // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number
8582 // section's NOTE.
8583 return value !== value;
8584 }
8585
8586 // If ECMAScript 6's Number.isNaN is present, prefer that.
8587 module.exports = Number.isNaN || isNaN;
8588
8589 },{}],25:[function(require,module,exports){
8590 var config = require('../config');
8591
8592 /*!
8593 * Chai - isProxyEnabled helper
8594 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8595 * MIT Licensed
8596 */
8597
8598 /**
8599 * ### .isProxyEnabled()
8600 *
8601 * Helper function to check if Chai's proxy protection feature is enabled. If
8602 * proxies are unsupported or disabled via the user's Chai config, then return
8603 * false. Otherwise, return true.
8604 *
8605 * @namespace Utils
8606 * @name isProxyEnabled
8607 */
8608
8609 module.exports = function isProxyEnabled() {
8610 return config.useProxy &&
8611 typeof Proxy !== 'undefined' &&
8612 typeof Reflect !== 'undefined';
8613 };
8614
8615 },{"../config":4}],26:[function(require,module,exports){
8616 /*!
8617 * Chai - flag utility
8618 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8619 * MIT Licensed
8620 */
8621
8622 /*!
8623 * Module dependencies
8624 */
8625
8626 var inspect = require('./inspect');
8627 var config = require('../config');
8628
8629 /**
8630 * ### .objDisplay(object)
8631 *
8632 * Determines if an object or an array matches
8633 * criteria to be inspected in-line for error
8634 * messages or should be truncated.
8635 *
8636 * @param {Mixed} javascript object to inspect
8637 * @returns {string} stringified object
8638 * @name objDisplay
8639 * @namespace Utils
8640 * @api public
8641 */
8642
8643 module.exports = function objDisplay(obj) {
8644 var str = inspect(obj)
8645 , type = Object.prototype.toString.call(obj);
8646
8647 if (config.truncateThreshold && str.length >= config.truncateThreshold) {
8648 if (type === '[object Function]') {
8649 return !obj.name || obj.name === ''
8650 ? '[Function]'
8651 : '[Function: ' + obj.name + ']';
8652 } else if (type === '[object Array]') {
8653 return '[ Array(' + obj.length + ') ]';
8654 } else if (type === '[object Object]') {
8655 var keys = Object.keys(obj)
8656 , kstr = keys.length > 2
8657 ? keys.splice(0, 2).join(', ') + ', ...'
8658 : keys.join(', ');
8659 return '{ Object (' + kstr + ') }';
8660 } else {
8661 return str;
8662 }
8663 } else {
8664 return str;
8665 }
8666 };
8667
8668 },{"../config":4,"./inspect":23}],27:[function(require,module,exports){
8669 /*!
8670 * Chai - overwriteChainableMethod utility
8671 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8672 * MIT Licensed
8673 */
8674
8675 var chai = require('../../chai');
8676 var transferFlags = require('./transferFlags');
8677
8678 /**
8679 * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior)
8680 *
8681 * Overwrites an already existing chainable method
8682 * and provides access to the previous function or
8683 * property. Must return functions to be used for
8684 * name.
8685 *
8686 * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf',
8687 * function (_super) {
8688 * }
8689 * , function (_super) {
8690 * }
8691 * );
8692 *
8693 * Can also be accessed directly from `chai.Assertion`.
8694 *
8695 * chai.Assertion.overwriteChainableMethod('foo', fn, fn);
8696 *
8697 * Then can be used as any other assertion.
8698 *
8699 * expect(myFoo).to.have.lengthOf(3);
8700 * expect(myFoo).to.have.lengthOf.above(3);
8701 *
8702 * @param {Object} ctx object whose method / property is to be overwritten
8703 * @param {String} name of method / property to overwrite
8704 * @param {Function} method function that returns a function to be used for name
8705 * @param {Function} chainingBehavior function that returns a function to be used for property
8706 * @namespace Utils
8707 * @name overwriteChainableMethod
8708 * @api public
8709 */
8710
8711 module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) {
8712 var chainableBehavior = ctx.__methods[name];
8713
8714 var _chainingBehavior = chainableBehavior.chainingBehavior;
8715 chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() {
8716 var result = chainingBehavior(_chainingBehavior).call(this);
8717 if (result !== undefined) {
8718 return result;
8719 }
8720
8721 var newAssertion = new chai.Assertion();
8722 transferFlags(this, newAssertion);
8723 return newAssertion;
8724 };
8725
8726 var _method = chainableBehavior.method;
8727 chainableBehavior.method = function overwritingChainableMethodWrapper() {
8728 var result = method(_method).apply(this, arguments);
8729 if (result !== undefined) {
8730 return result;
8731 }
8732
8733 var newAssertion = new chai.Assertion();
8734 transferFlags(this, newAssertion);
8735 return newAssertion;
8736 };
8737 };
8738
8739 },{"../../chai":2,"./transferFlags":32}],28:[function(require,module,exports){
8740 /*!
8741 * Chai - overwriteMethod utility
8742 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8743 * MIT Licensed
8744 */
8745
8746 var addLengthGuard = require('./addLengthGuard');
8747 var chai = require('../../chai');
8748 var flag = require('./flag');
8749 var proxify = require('./proxify');
8750 var transferFlags = require('./transferFlags');
8751
8752 /**
8753 * ### .overwriteMethod(ctx, name, fn)
8754 *
8755 * Overwrites an already existing method and provides
8756 * access to previous function. Must return function
8757 * to be used for name.
8758 *
8759 * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {
8760 * return function (str) {
8761 * var obj = utils.flag(this, 'object');
8762 * if (obj instanceof Foo) {
8763 * new chai.Assertion(obj.value).to.equal(str);
8764 * } else {
8765 * _super.apply(this, arguments);
8766 * }
8767 * }
8768 * });
8769 *
8770 * Can also be accessed directly from `chai.Assertion`.
8771 *
8772 * chai.Assertion.overwriteMethod('foo', fn);
8773 *
8774 * Then can be used as any other assertion.
8775 *
8776 * expect(myFoo).to.equal('bar');
8777 *
8778 * @param {Object} ctx object whose method is to be overwritten
8779 * @param {String} name of method to overwrite
8780 * @param {Function} method function that returns a function to be used for name
8781 * @namespace Utils
8782 * @name overwriteMethod
8783 * @api public
8784 */
8785
8786 module.exports = function overwriteMethod(ctx, name, method) {
8787 var _method = ctx[name]
8788 , _super = function () {
8789 throw new Error(name + ' is not a function');
8790 };
8791
8792 if (_method && 'function' === typeof _method)
8793 _super = _method;
8794
8795 var overwritingMethodWrapper = function () {
8796 // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this
8797 // function to be the starting point for removing implementation frames from
8798 // the stack trace of a failed assertion.
8799 //
8800 // However, we only want to use this function as the starting point if the
8801 // `lockSsfi` flag isn't set.
8802 //
8803 // If the `lockSsfi` flag is set, then either this assertion has been
8804 // overwritten by another assertion, or this assertion is being invoked from
8805 // inside of another assertion. In the first case, the `ssfi` flag has
8806 // already been set by the overwriting assertion. In the second case, the
8807 // `ssfi` flag has already been set by the outer assertion.
8808 if (!flag(this, 'lockSsfi')) {
8809 flag(this, 'ssfi', overwritingMethodWrapper);
8810 }
8811
8812 // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion
8813 // from changing the `ssfi` flag. By this point, the `ssfi` flag is already
8814 // set to the correct starting point for this assertion.
8815 var origLockSsfi = flag(this, 'lockSsfi');
8816 flag(this, 'lockSsfi', true);
8817 var result = method(_super).apply(this, arguments);
8818 flag(this, 'lockSsfi', origLockSsfi);
8819
8820 if (result !== undefined) {
8821 return result;
8822 }
8823
8824 var newAssertion = new chai.Assertion();
8825 transferFlags(this, newAssertion);
8826 return newAssertion;
8827 }
8828
8829 addLengthGuard(overwritingMethodWrapper, name, false);
8830 ctx[name] = proxify(overwritingMethodWrapper, name);
8831 };
8832
8833 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],29:[function(require,module,exports){
8834 /*!
8835 * Chai - overwriteProperty utility
8836 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8837 * MIT Licensed
8838 */
8839
8840 var chai = require('../../chai');
8841 var flag = require('./flag');
8842 var isProxyEnabled = require('./isProxyEnabled');
8843 var transferFlags = require('./transferFlags');
8844
8845 /**
8846 * ### .overwriteProperty(ctx, name, fn)
8847 *
8848 * Overwrites an already existing property getter and provides
8849 * access to previous value. Must return function to use as getter.
8850 *
8851 * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {
8852 * return function () {
8853 * var obj = utils.flag(this, 'object');
8854 * if (obj instanceof Foo) {
8855 * new chai.Assertion(obj.name).to.equal('bar');
8856 * } else {
8857 * _super.call(this);
8858 * }
8859 * }
8860 * });
8861 *
8862 *
8863 * Can also be accessed directly from `chai.Assertion`.
8864 *
8865 * chai.Assertion.overwriteProperty('foo', fn);
8866 *
8867 * Then can be used as any other assertion.
8868 *
8869 * expect(myFoo).to.be.ok;
8870 *
8871 * @param {Object} ctx object whose property is to be overwritten
8872 * @param {String} name of property to overwrite
8873 * @param {Function} getter function that returns a getter function to be used for name
8874 * @namespace Utils
8875 * @name overwriteProperty
8876 * @api public
8877 */
8878
8879 module.exports = function overwriteProperty(ctx, name, getter) {
8880 var _get = Object.getOwnPropertyDescriptor(ctx, name)
8881 , _super = function () {};
8882
8883 if (_get && 'function' === typeof _get.get)
8884 _super = _get.get
8885
8886 Object.defineProperty(ctx, name,
8887 { get: function overwritingPropertyGetter() {
8888 // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this
8889 // function to be the starting point for removing implementation frames
8890 // from the stack trace of a failed assertion.
8891 //
8892 // However, we only want to use this function as the starting point if
8893 // the `lockSsfi` flag isn't set and proxy protection is disabled.
8894 //
8895 // If the `lockSsfi` flag is set, then either this assertion has been
8896 // overwritten by another assertion, or this assertion is being invoked
8897 // from inside of another assertion. In the first case, the `ssfi` flag
8898 // has already been set by the overwriting assertion. In the second
8899 // case, the `ssfi` flag has already been set by the outer assertion.
8900 //
8901 // If proxy protection is enabled, then the `ssfi` flag has already been
8902 // set by the proxy getter.
8903 if (!isProxyEnabled() && !flag(this, 'lockSsfi')) {
8904 flag(this, 'ssfi', overwritingPropertyGetter);
8905 }
8906
8907 // Setting the `lockSsfi` flag to `true` prevents the overwritten
8908 // assertion from changing the `ssfi` flag. By this point, the `ssfi`
8909 // flag is already set to the correct starting point for this assertion.
8910 var origLockSsfi = flag(this, 'lockSsfi');
8911 flag(this, 'lockSsfi', true);
8912 var result = getter(_super).call(this);
8913 flag(this, 'lockSsfi', origLockSsfi);
8914
8915 if (result !== undefined) {
8916 return result;
8917 }
8918
8919 var newAssertion = new chai.Assertion();
8920 transferFlags(this, newAssertion);
8921 return newAssertion;
8922 }
8923 , configurable: true
8924 });
8925 };
8926
8927 },{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],30:[function(require,module,exports){
8928 var config = require('../config');
8929 var flag = require('./flag');
8930 var getProperties = require('./getProperties');
8931 var isProxyEnabled = require('./isProxyEnabled');
8932
8933 /*!
8934 * Chai - proxify utility
8935 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8936 * MIT Licensed
8937 */
8938
8939 /**
8940 * ### .proxify(object)
8941 *
8942 * Return a proxy of given object that throws an error when a non-existent
8943 * property is read. By default, the root cause is assumed to be a misspelled
8944 * property, and thus an attempt is made to offer a reasonable suggestion from
8945 * the list of existing properties. However, if a nonChainableMethodName is
8946 * provided, then the root cause is instead a failure to invoke a non-chainable
8947 * method prior to reading the non-existent property.
8948 *
8949 * If proxies are unsupported or disabled via the user's Chai config, then
8950 * return object without modification.
8951 *
8952 * @param {Object} obj
8953 * @param {String} nonChainableMethodName
8954 * @namespace Utils
8955 * @name proxify
8956 */
8957
8958 var builtins = ['__flags', '__methods', '_obj', 'assert'];
8959
8960 module.exports = function proxify(obj, nonChainableMethodName) {
8961 if (!isProxyEnabled()) return obj;
8962
8963 return new Proxy(obj, {
8964 get: function proxyGetter(target, property) {
8965 // This check is here because we should not throw errors on Symbol properties
8966 // such as `Symbol.toStringTag`.
8967 // The values for which an error should be thrown can be configured using
8968 // the `config.proxyExcludedKeys` setting.
8969 if (typeof property === 'string' &&
8970 config.proxyExcludedKeys.indexOf(property) === -1 &&
8971 !Reflect.has(target, property)) {
8972 // Special message for invalid property access of non-chainable methods.
8973 if (nonChainableMethodName) {
8974 throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' +
8975 property + '. See docs for proper usage of "' +
8976 nonChainableMethodName + '".');
8977 }
8978
8979 // If the property is reasonably close to an existing Chai property,
8980 // suggest that property to the user. Only suggest properties with a
8981 // distance less than 4.
8982 var suggestion = null;
8983 var suggestionDistance = 4;
8984 getProperties(target).forEach(function(prop) {
8985 if (
8986 !Object.prototype.hasOwnProperty(prop) &&
8987 builtins.indexOf(prop) === -1
8988 ) {
8989 var dist = stringDistanceCapped(
8990 property,
8991 prop,
8992 suggestionDistance
8993 );
8994 if (dist < suggestionDistance) {
8995 suggestion = prop;
8996 suggestionDistance = dist;
8997 }
8998 }
8999 });
9000
9001 if (suggestion !== null) {
9002 throw Error('Invalid Chai property: ' + property +
9003 '. Did you mean "' + suggestion + '"?');
9004 } else {
9005 throw Error('Invalid Chai property: ' + property);
9006 }
9007 }
9008
9009 // Use this proxy getter as the starting point for removing implementation
9010 // frames from the stack trace of a failed assertion. For property
9011 // assertions, this prevents the proxy getter from showing up in the stack
9012 // trace since it's invoked before the property getter. For method and
9013 // chainable method assertions, this flag will end up getting changed to
9014 // the method wrapper, which is good since this frame will no longer be in
9015 // the stack once the method is invoked. Note that Chai builtin assertion
9016 // properties such as `__flags` are skipped since this is only meant to
9017 // capture the starting point of an assertion. This step is also skipped
9018 // if the `lockSsfi` flag is set, thus indicating that this assertion is
9019 // being called from within another assertion. In that case, the `ssfi`
9020 // flag is already set to the outer assertion's starting point.
9021 if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) {
9022 flag(target, 'ssfi', proxyGetter);
9023 }
9024
9025 return Reflect.get(target, property);
9026 }
9027 });
9028 };
9029
9030 /**
9031 * # stringDistanceCapped(strA, strB, cap)
9032 * Return the Levenshtein distance between two strings, but no more than cap.
9033 * @param {string} strA
9034 * @param {string} strB
9035 * @param {number} number
9036 * @return {number} min(string distance between strA and strB, cap)
9037 * @api private
9038 */
9039
9040 function stringDistanceCapped(strA, strB, cap) {
9041 if (Math.abs(strA.length - strB.length) >= cap) {
9042 return cap;
9043 }
9044
9045 var memo = [];
9046 // `memo` is a two-dimensional array containing distances.
9047 // memo[i][j] is the distance between strA.slice(0, i) and
9048 // strB.slice(0, j).
9049 for (var i = 0; i <= strA.length; i++) {
9050 memo[i] = Array(strB.length + 1).fill(0);
9051 memo[i][0] = i;
9052 }
9053 for (var j = 0; j < strB.length; j++) {
9054 memo[0][j] = j;
9055 }
9056
9057 for (var i = 1; i <= strA.length; i++) {
9058 var ch = strA.charCodeAt(i - 1);
9059 for (var j = 1; j <= strB.length; j++) {
9060 if (Math.abs(i - j) >= cap) {
9061 memo[i][j] = cap;
9062 continue;
9063 }
9064 memo[i][j] = Math.min(
9065 memo[i - 1][j] + 1,
9066 memo[i][j - 1] + 1,
9067 memo[i - 1][j - 1] +
9068 (ch === strB.charCodeAt(j - 1) ? 0 : 1)
9069 );
9070 }
9071 }
9072
9073 return memo[strA.length][strB.length];
9074 }
9075
9076 },{"../config":4,"./flag":15,"./getProperties":21,"./isProxyEnabled":25}],31:[function(require,module,exports){
9077 /*!
9078 * Chai - test utility
9079 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
9080 * MIT Licensed
9081 */
9082
9083 /*!
9084 * Module dependencies
9085 */
9086
9087 var flag = require('./flag');
9088
9089 /**
9090 * ### .test(object, expression)
9091 *
9092 * Test an object for expression.
9093 *
9094 * @param {Object} object (constructed Assertion)
9095 * @param {Arguments} chai.Assertion.prototype.assert arguments
9096 * @namespace Utils
9097 * @name test
9098 */
9099
9100 module.exports = function test(obj, args) {
9101 var negate = flag(obj, 'negate')
9102 , expr = args[0];
9103 return negate ? !expr : expr;
9104 };
9105
9106 },{"./flag":15}],32:[function(require,module,exports){
9107 /*!
9108 * Chai - transferFlags utility
9109 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
9110 * MIT Licensed
9111 */
9112
9113 /**
9114 * ### .transferFlags(assertion, object, includeAll = true)
9115 *
9116 * Transfer all the flags for `assertion` to `object`. If
9117 * `includeAll` is set to `false`, then the base Chai
9118 * assertion flags (namely `object`, `ssfi`, `lockSsfi`,
9119 * and `message`) will not be transferred.
9120 *
9121 *
9122 * var newAssertion = new Assertion();
9123 * utils.transferFlags(assertion, newAssertion);
9124 *
9125 * var anotherAssertion = new Assertion(myObj);
9126 * utils.transferFlags(assertion, anotherAssertion, false);
9127 *
9128 * @param {Assertion} assertion the assertion to transfer the flags from
9129 * @param {Object} object the object to transfer the flags to; usually a new assertion
9130 * @param {Boolean} includeAll
9131 * @namespace Utils
9132 * @name transferFlags
9133 * @api private
9134 */
9135
9136 module.exports = function transferFlags(assertion, object, includeAll) {
9137 var flags = assertion.__flags || (assertion.__flags = Object.create(null));
9138
9139 if (!object.__flags) {
9140 object.__flags = Object.create(null);
9141 }
9142
9143 includeAll = arguments.length === 3 ? includeAll : true;
9144
9145 for (var flag in flags) {
9146 if (includeAll ||
9147 (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) {
9148 object.__flags[flag] = flags[flag];
9149 }
9150 }
9151 };
9152
9153 },{}],33:[function(require,module,exports){
9154 /*!
9155 * assertion-error
9156 * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>
9157 * MIT Licensed
9158 */
9159
9160 /*!
9161 * Return a function that will copy properties from
9162 * one object to another excluding any originally
9163 * listed. Returned function will create a new `{}`.
9164 *
9165 * @param {String} excluded properties ...
9166 * @return {Function}
9167 */
9168
9169 function exclude () {
9170 var excludes = [].slice.call(arguments);
9171
9172 function excludeProps (res, obj) {
9173 Object.keys(obj).forEach(function (key) {
9174 if (!~excludes.indexOf(key)) res[key] = obj[key];
9175 });
9176 }
9177
9178 return function extendExclude () {
9179 var args = [].slice.call(arguments)
9180 , i = 0
9181 , res = {};
9182
9183 for (; i < args.length; i++) {
9184 excludeProps(res, args[i]);
9185 }
9186
9187 return res;
9188 };
9189 };
9190
9191 /*!
9192 * Primary Exports
9193 */
9194
9195 module.exports = AssertionError;
9196
9197 /**
9198 * ### AssertionError
9199 *
9200 * An extension of the JavaScript `Error` constructor for
9201 * assertion and validation scenarios.
9202 *
9203 * @param {String} message
9204 * @param {Object} properties to include (optional)
9205 * @param {callee} start stack function (optional)
9206 */
9207
9208 function AssertionError (message, _props, ssf) {
9209 var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')
9210 , props = extend(_props || {});
9211
9212 // default values
9213 this.message = message || 'Unspecified AssertionError';
9214 this.showDiff = false;
9215
9216 // copy from properties
9217 for (var key in props) {
9218 this[key] = props[key];
9219 }
9220
9221 // capture stack trace
9222 ssf = ssf || AssertionError;
9223 if (Error.captureStackTrace) {
9224 Error.captureStackTrace(this, ssf);
9225 } else {
9226 try {
9227 throw new Error();
9228 } catch(e) {
9229 this.stack = e.stack;
9230 }
9231 }
9232 }
9233
9234 /*!
9235 * Inherit from Error.prototype
9236 */
9237
9238 AssertionError.prototype = Object.create(Error.prototype);
9239
9240 /*!
9241 * Statically set name
9242 */
9243
9244 AssertionError.prototype.name = 'AssertionError';
9245
9246 /*!
9247 * Ensure correct constructor
9248 */
9249
9250 AssertionError.prototype.constructor = AssertionError;
9251
9252 /**
9253 * Allow errors to be converted to JSON for static transfer.
9254 *
9255 * @param {Boolean} include stack (default: `true`)
9256 * @return {Object} object that can be `JSON.stringify`
9257 */
9258
9259 AssertionError.prototype.toJSON = function (stack) {
9260 var extend = exclude('constructor', 'toJSON', 'stack')
9261 , props = extend({ name: this.name }, this);
9262
9263 // include stack if exists and not turned off
9264 if (false !== stack && this.stack) {
9265 props.stack = this.stack;
9266 }
9267
9268 return props;
9269 };
9270
9271 },{}],34:[function(require,module,exports){
9272 'use strict';
9273
9274 /* !
9275 * Chai - checkError utility
9276 * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
9277 * MIT Licensed
9278 */
9279
9280 var getFunctionName = require('get-func-name');
9281 /**
9282 * ### .checkError
9283 *
9284 * Checks that an error conforms to a given set of criteria and/or retrieves information about it.
9285 *
9286 * @api public
9287 */
9288
9289 /**
9290 * ### .compatibleInstance(thrown, errorLike)
9291 *
9292 * Checks if two instances are compatible (strict equal).
9293 * Returns false if errorLike is not an instance of Error, because instances
9294 * can only be compatible if they're both error instances.
9295 *
9296 * @name compatibleInstance
9297 * @param {Error} thrown error
9298 * @param {Error|ErrorConstructor} errorLike object to compare against
9299 * @namespace Utils
9300 * @api public
9301 */
9302
9303 function compatibleInstance(thrown, errorLike) {
9304 return errorLike instanceof Error && thrown === errorLike;
9305 }
9306
9307 /**
9308 * ### .compatibleConstructor(thrown, errorLike)
9309 *
9310 * Checks if two constructors are compatible.
9311 * This function can receive either an error constructor or
9312 * an error instance as the `errorLike` argument.
9313 * Constructors are compatible if they're the same or if one is
9314 * an instance of another.
9315 *
9316 * @name compatibleConstructor
9317 * @param {Error} thrown error
9318 * @param {Error|ErrorConstructor} errorLike object to compare against
9319 * @namespace Utils
9320 * @api public
9321 */
9322
9323 function compatibleConstructor(thrown, errorLike) {
9324 if (errorLike instanceof Error) {
9325 // If `errorLike` is an instance of any error we compare their constructors
9326 return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor;
9327 } else if (errorLike.prototype instanceof Error || errorLike === Error) {
9328 // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly
9329 return thrown.constructor === errorLike || thrown instanceof errorLike;
9330 }
9331
9332 return false;
9333 }
9334
9335 /**
9336 * ### .compatibleMessage(thrown, errMatcher)
9337 *
9338 * Checks if an error's message is compatible with a matcher (String or RegExp).
9339 * If the message contains the String or passes the RegExp test,
9340 * it is considered compatible.
9341 *
9342 * @name compatibleMessage
9343 * @param {Error} thrown error
9344 * @param {String|RegExp} errMatcher to look for into the message
9345 * @namespace Utils
9346 * @api public
9347 */
9348
9349 function compatibleMessage(thrown, errMatcher) {
9350 var comparisonString = typeof thrown === 'string' ? thrown : thrown.message;
9351 if (errMatcher instanceof RegExp) {
9352 return errMatcher.test(comparisonString);
9353 } else if (typeof errMatcher === 'string') {
9354 return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers
9355 }
9356
9357 return false;
9358 }
9359
9360 /**
9361 * ### .getConstructorName(errorLike)
9362 *
9363 * Gets the constructor name for an Error instance or constructor itself.
9364 *
9365 * @name getConstructorName
9366 * @param {Error|ErrorConstructor} errorLike
9367 * @namespace Utils
9368 * @api public
9369 */
9370
9371 function getConstructorName(errorLike) {
9372 var constructorName = errorLike;
9373 if (errorLike instanceof Error) {
9374 constructorName = getFunctionName(errorLike.constructor);
9375 } else if (typeof errorLike === 'function') {
9376 // If `err` is not an instance of Error it is an error constructor itself or another function.
9377 // If we've got a common function we get its name, otherwise we may need to create a new instance
9378 // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more.
9379 constructorName = getFunctionName(errorLike);
9380 if (constructorName === '') {
9381 var newConstructorName = getFunctionName(new errorLike()); // eslint-disable-line new-cap
9382 constructorName = newConstructorName || constructorName;
9383 }
9384 }
9385
9386 return constructorName;
9387 }
9388
9389 /**
9390 * ### .getMessage(errorLike)
9391 *
9392 * Gets the error message from an error.
9393 * If `err` is a String itself, we return it.
9394 * If the error has no message, we return an empty string.
9395 *
9396 * @name getMessage
9397 * @param {Error|String} errorLike
9398 * @namespace Utils
9399 * @api public
9400 */
9401
9402 function getMessage(errorLike) {
9403 var msg = '';
9404 if (errorLike && errorLike.message) {
9405 msg = errorLike.message;
9406 } else if (typeof errorLike === 'string') {
9407 msg = errorLike;
9408 }
9409
9410 return msg;
9411 }
9412
9413 module.exports = {
9414 compatibleInstance: compatibleInstance,
9415 compatibleConstructor: compatibleConstructor,
9416 compatibleMessage: compatibleMessage,
9417 getMessage: getMessage,
9418 getConstructorName: getConstructorName,
9419 };
9420
9421 },{"get-func-name":36}],35:[function(require,module,exports){
9422 'use strict';
9423 /* globals Symbol: false, Uint8Array: false, WeakMap: false */
9424 /*!
9425 * deep-eql
9426 * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>
9427 * MIT Licensed
9428 */
9429
9430 var type = require('type-detect');
9431 function FakeMap() {
9432 this._key = 'chai/deep-eql__' + Math.random() + Date.now();
9433 }
9434
9435 FakeMap.prototype = {
9436 get: function get(key) {
9437 return key[this._key];
9438 },
9439 set: function set(key, value) {
9440 if (Object.isExtensible(key)) {
9441 Object.defineProperty(key, this._key, {
9442 value: value,
9443 configurable: true,
9444 });
9445 }
9446 },
9447 };
9448
9449 var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap;
9450 /*!
9451 * Check to see if the MemoizeMap has recorded a result of the two operands
9452 *
9453 * @param {Mixed} leftHandOperand
9454 * @param {Mixed} rightHandOperand
9455 * @param {MemoizeMap} memoizeMap
9456 * @returns {Boolean|null} result
9457 */
9458 function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) {
9459 // Technically, WeakMap keys can *only* be objects, not primitives.
9460 if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
9461 return null;
9462 }
9463 var leftHandMap = memoizeMap.get(leftHandOperand);
9464 if (leftHandMap) {
9465 var result = leftHandMap.get(rightHandOperand);
9466 if (typeof result === 'boolean') {
9467 return result;
9468 }
9469 }
9470 return null;
9471 }
9472
9473 /*!
9474 * Set the result of the equality into the MemoizeMap
9475 *
9476 * @param {Mixed} leftHandOperand
9477 * @param {Mixed} rightHandOperand
9478 * @param {MemoizeMap} memoizeMap
9479 * @param {Boolean} result
9480 */
9481 function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) {
9482 // Technically, WeakMap keys can *only* be objects, not primitives.
9483 if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
9484 return;
9485 }
9486 var leftHandMap = memoizeMap.get(leftHandOperand);
9487 if (leftHandMap) {
9488 leftHandMap.set(rightHandOperand, result);
9489 } else {
9490 leftHandMap = new MemoizeMap();
9491 leftHandMap.set(rightHandOperand, result);
9492 memoizeMap.set(leftHandOperand, leftHandMap);
9493 }
9494 }
9495
9496 /*!
9497 * Primary Export
9498 */
9499
9500 module.exports = deepEqual;
9501 module.exports.MemoizeMap = MemoizeMap;
9502
9503 /**
9504 * Assert deeply nested sameValue equality between two objects of any type.
9505 *
9506 * @param {Mixed} leftHandOperand
9507 * @param {Mixed} rightHandOperand
9508 * @param {Object} [options] (optional) Additional options
9509 * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality.
9510 * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of
9511 complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular
9512 references to blow the stack.
9513 * @return {Boolean} equal match
9514 */
9515 function deepEqual(leftHandOperand, rightHandOperand, options) {
9516 // If we have a comparator, we can't assume anything; so bail to its check first.
9517 if (options && options.comparator) {
9518 return extensiveDeepEqual(leftHandOperand, rightHandOperand, options);
9519 }
9520
9521 var simpleResult = simpleEqual(leftHandOperand, rightHandOperand);
9522 if (simpleResult !== null) {
9523 return simpleResult;
9524 }
9525
9526 // Deeper comparisons are pushed through to a larger function
9527 return extensiveDeepEqual(leftHandOperand, rightHandOperand, options);
9528 }
9529
9530 /**
9531 * Many comparisons can be canceled out early via simple equality or primitive checks.
9532 * @param {Mixed} leftHandOperand
9533 * @param {Mixed} rightHandOperand
9534 * @return {Boolean|null} equal match
9535 */
9536 function simpleEqual(leftHandOperand, rightHandOperand) {
9537 // Equal references (except for Numbers) can be returned early
9538 if (leftHandOperand === rightHandOperand) {
9539 // Handle +-0 cases
9540 return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand;
9541 }
9542
9543 // handle NaN cases
9544 if (
9545 leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare
9546 rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare
9547 ) {
9548 return true;
9549 }
9550
9551 // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers,
9552 // strings, and undefined, can be compared by reference.
9553 if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
9554 // Easy out b/c it would have passed the first equality check
9555 return false;
9556 }
9557 return null;
9558 }
9559
9560 /*!
9561 * The main logic of the `deepEqual` function.
9562 *
9563 * @param {Mixed} leftHandOperand
9564 * @param {Mixed} rightHandOperand
9565 * @param {Object} [options] (optional) Additional options
9566 * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality.
9567 * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of
9568 complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular
9569 references to blow the stack.
9570 * @return {Boolean} equal match
9571 */
9572 function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) {
9573 options = options || {};
9574 options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap();
9575 var comparator = options && options.comparator;
9576
9577 // Check if a memoized result exists.
9578 var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize);
9579 if (memoizeResultLeft !== null) {
9580 return memoizeResultLeft;
9581 }
9582 var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize);
9583 if (memoizeResultRight !== null) {
9584 return memoizeResultRight;
9585 }
9586
9587 // If a comparator is present, use it.
9588 if (comparator) {
9589 var comparatorResult = comparator(leftHandOperand, rightHandOperand);
9590 // Comparators may return null, in which case we want to go back to default behavior.
9591 if (comparatorResult === false || comparatorResult === true) {
9592 memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult);
9593 return comparatorResult;
9594 }
9595 // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide
9596 // what to do, we need to make sure to return the basic tests first before we move on.
9597 var simpleResult = simpleEqual(leftHandOperand, rightHandOperand);
9598 if (simpleResult !== null) {
9599 // Don't memoize this, it takes longer to set/retrieve than to just compare.
9600 return simpleResult;
9601 }
9602 }
9603
9604 var leftHandType = type(leftHandOperand);
9605 if (leftHandType !== type(rightHandOperand)) {
9606 memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false);
9607 return false;
9608 }
9609
9610 // Temporarily set the operands in the memoize object to prevent blowing the stack
9611 memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true);
9612
9613 var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options);
9614 memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result);
9615 return result;
9616 }
9617
9618 function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) {
9619 switch (leftHandType) {
9620 case 'String':
9621 case 'Number':
9622 case 'Boolean':
9623 case 'Date':
9624 // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values
9625 return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf());
9626 case 'Promise':
9627 case 'Symbol':
9628 case 'function':
9629 case 'WeakMap':
9630 case 'WeakSet':
9631 return leftHandOperand === rightHandOperand;
9632 case 'Error':
9633 return keysEqual(leftHandOperand, rightHandOperand, [ 'name', 'message', 'code' ], options);
9634 case 'Arguments':
9635 case 'Int8Array':
9636 case 'Uint8Array':
9637 case 'Uint8ClampedArray':
9638 case 'Int16Array':
9639 case 'Uint16Array':
9640 case 'Int32Array':
9641 case 'Uint32Array':
9642 case 'Float32Array':
9643 case 'Float64Array':
9644 case 'Array':
9645 return iterableEqual(leftHandOperand, rightHandOperand, options);
9646 case 'RegExp':
9647 return regexpEqual(leftHandOperand, rightHandOperand);
9648 case 'Generator':
9649 return generatorEqual(leftHandOperand, rightHandOperand, options);
9650 case 'DataView':
9651 return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options);
9652 case 'ArrayBuffer':
9653 return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options);
9654 case 'Set':
9655 return entriesEqual(leftHandOperand, rightHandOperand, options);
9656 case 'Map':
9657 return entriesEqual(leftHandOperand, rightHandOperand, options);
9658 case 'Temporal.PlainDate':
9659 case 'Temporal.PlainTime':
9660 case 'Temporal.PlainDateTime':
9661 case 'Temporal.Instant':
9662 case 'Temporal.ZonedDateTime':
9663 case 'Temporal.PlainYearMonth':
9664 case 'Temporal.PlainMonthDay':
9665 return leftHandOperand.equals(rightHandOperand);
9666 case 'Temporal.Duration':
9667 return leftHandOperand.total('nanoseconds') === rightHandOperand.total('nanoseconds');
9668 case 'Temporal.TimeZone':
9669 case 'Temporal.Calendar':
9670 return leftHandOperand.toString() === rightHandOperand.toString();
9671 default:
9672 return objectEqual(leftHandOperand, rightHandOperand, options);
9673 }
9674 }
9675
9676 /*!
9677 * Compare two Regular Expressions for equality.
9678 *
9679 * @param {RegExp} leftHandOperand
9680 * @param {RegExp} rightHandOperand
9681 * @return {Boolean} result
9682 */
9683
9684 function regexpEqual(leftHandOperand, rightHandOperand) {
9685 return leftHandOperand.toString() === rightHandOperand.toString();
9686 }
9687
9688 /*!
9689 * Compare two Sets/Maps for equality. Faster than other equality functions.
9690 *
9691 * @param {Set} leftHandOperand
9692 * @param {Set} rightHandOperand
9693 * @param {Object} [options] (Optional)
9694 * @return {Boolean} result
9695 */
9696
9697 function entriesEqual(leftHandOperand, rightHandOperand, options) {
9698 // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach
9699 if (leftHandOperand.size !== rightHandOperand.size) {
9700 return false;
9701 }
9702 if (leftHandOperand.size === 0) {
9703 return true;
9704 }
9705 var leftHandItems = [];
9706 var rightHandItems = [];
9707 leftHandOperand.forEach(function gatherEntries(key, value) {
9708 leftHandItems.push([ key, value ]);
9709 });
9710 rightHandOperand.forEach(function gatherEntries(key, value) {
9711 rightHandItems.push([ key, value ]);
9712 });
9713 return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options);
9714 }
9715
9716 /*!
9717 * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers.
9718 *
9719 * @param {Iterable} leftHandOperand
9720 * @param {Iterable} rightHandOperand
9721 * @param {Object} [options] (Optional)
9722 * @return {Boolean} result
9723 */
9724
9725 function iterableEqual(leftHandOperand, rightHandOperand, options) {
9726 var length = leftHandOperand.length;
9727 if (length !== rightHandOperand.length) {
9728 return false;
9729 }
9730 if (length === 0) {
9731 return true;
9732 }
9733 var index = -1;
9734 while (++index < length) {
9735 if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) {
9736 return false;
9737 }
9738 }
9739 return true;
9740 }
9741
9742 /*!
9743 * Simple equality for generator objects such as those returned by generator functions.
9744 *
9745 * @param {Iterable} leftHandOperand
9746 * @param {Iterable} rightHandOperand
9747 * @param {Object} [options] (Optional)
9748 * @return {Boolean} result
9749 */
9750
9751 function generatorEqual(leftHandOperand, rightHandOperand, options) {
9752 return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options);
9753 }
9754
9755 /*!
9756 * Determine if the given object has an @@iterator function.
9757 *
9758 * @param {Object} target
9759 * @return {Boolean} `true` if the object has an @@iterator function.
9760 */
9761 function hasIteratorFunction(target) {
9762 return typeof Symbol !== 'undefined' &&
9763 typeof target === 'object' &&
9764 typeof Symbol.iterator !== 'undefined' &&
9765 typeof target[Symbol.iterator] === 'function';
9766 }
9767
9768 /*!
9769 * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array.
9770 * This will consume the iterator - which could have side effects depending on the @@iterator implementation.
9771 *
9772 * @param {Object} target
9773 * @returns {Array} an array of entries from the @@iterator function
9774 */
9775 function getIteratorEntries(target) {
9776 if (hasIteratorFunction(target)) {
9777 try {
9778 return getGeneratorEntries(target[Symbol.iterator]());
9779 } catch (iteratorError) {
9780 return [];
9781 }
9782 }
9783 return [];
9784 }
9785
9786 /*!
9787 * Gets all entries from a Generator. This will consume the generator - which could have side effects.
9788 *
9789 * @param {Generator} target
9790 * @returns {Array} an array of entries from the Generator.
9791 */
9792 function getGeneratorEntries(generator) {
9793 var generatorResult = generator.next();
9794 var accumulator = [ generatorResult.value ];
9795 while (generatorResult.done === false) {
9796 generatorResult = generator.next();
9797 accumulator.push(generatorResult.value);
9798 }
9799 return accumulator;
9800 }
9801
9802 /*!
9803 * Gets all own and inherited enumerable keys from a target.
9804 *
9805 * @param {Object} target
9806 * @returns {Array} an array of own and inherited enumerable keys from the target.
9807 */
9808 function getEnumerableKeys(target) {
9809 var keys = [];
9810 for (var key in target) {
9811 keys.push(key);
9812 }
9813 return keys;
9814 }
9815
9816 function getEnumerableSymbols(target) {
9817 var keys = [];
9818 var allKeys = Object.getOwnPropertySymbols(target);
9819 for (var i = 0; i < allKeys.length; i += 1) {
9820 var key = allKeys[i];
9821 if (Object.getOwnPropertyDescriptor(target, key).enumerable) {
9822 keys.push(key);
9823 }
9824 }
9825 return keys;
9826 }
9827
9828 /*!
9829 * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of
9830 * each key. If any value of the given key is not equal, the function will return false (early).
9831 *
9832 * @param {Mixed} leftHandOperand
9833 * @param {Mixed} rightHandOperand
9834 * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against
9835 * @param {Object} [options] (Optional)
9836 * @return {Boolean} result
9837 */
9838 function keysEqual(leftHandOperand, rightHandOperand, keys, options) {
9839 var length = keys.length;
9840 if (length === 0) {
9841 return true;
9842 }
9843 for (var i = 0; i < length; i += 1) {
9844 if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) {
9845 return false;
9846 }
9847 }
9848 return true;
9849 }
9850
9851 /*!
9852 * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual`
9853 * for each enumerable key in the object.
9854 *
9855 * @param {Mixed} leftHandOperand
9856 * @param {Mixed} rightHandOperand
9857 * @param {Object} [options] (Optional)
9858 * @return {Boolean} result
9859 */
9860 function objectEqual(leftHandOperand, rightHandOperand, options) {
9861 var leftHandKeys = getEnumerableKeys(leftHandOperand);
9862 var rightHandKeys = getEnumerableKeys(rightHandOperand);
9863 var leftHandSymbols = getEnumerableSymbols(leftHandOperand);
9864 var rightHandSymbols = getEnumerableSymbols(rightHandOperand);
9865 leftHandKeys = leftHandKeys.concat(leftHandSymbols);
9866 rightHandKeys = rightHandKeys.concat(rightHandSymbols);
9867
9868 if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) {
9869 if (iterableEqual(mapSymbols(leftHandKeys).sort(), mapSymbols(rightHandKeys).sort()) === false) {
9870 return false;
9871 }
9872 return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options);
9873 }
9874
9875 var leftHandEntries = getIteratorEntries(leftHandOperand);
9876 var rightHandEntries = getIteratorEntries(rightHandOperand);
9877 if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) {
9878 leftHandEntries.sort();
9879 rightHandEntries.sort();
9880 return iterableEqual(leftHandEntries, rightHandEntries, options);
9881 }
9882
9883 if (leftHandKeys.length === 0 &&
9884 leftHandEntries.length === 0 &&
9885 rightHandKeys.length === 0 &&
9886 rightHandEntries.length === 0) {
9887 return true;
9888 }
9889
9890 return false;
9891 }
9892
9893 /*!
9894 * Returns true if the argument is a primitive.
9895 *
9896 * This intentionally returns true for all objects that can be compared by reference,
9897 * including functions and symbols.
9898 *
9899 * @param {Mixed} value
9900 * @return {Boolean} result
9901 */
9902 function isPrimitive(value) {
9903 return value === null || typeof value !== 'object';
9904 }
9905
9906 function mapSymbols(arr) {
9907 return arr.map(function mapSymbol(entry) {
9908 if (typeof entry === 'symbol') {
9909 return entry.toString();
9910 }
9911
9912 return entry;
9913 });
9914 }
9915
9916 },{"type-detect":39}],36:[function(require,module,exports){
9917 'use strict';
9918
9919 /* !
9920 * Chai - getFuncName utility
9921 * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
9922 * MIT Licensed
9923 */
9924
9925 /**
9926 * ### .getFuncName(constructorFn)
9927 *
9928 * Returns the name of a function.
9929 * When a non-function instance is passed, returns `null`.
9930 * This also includes a polyfill function if `aFunc.name` is not defined.
9931 *
9932 * @name getFuncName
9933 * @param {Function} funct
9934 * @namespace Utils
9935 * @api public
9936 */
9937
9938 var toString = Function.prototype.toString;
9939 var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/;
9940 var maxFunctionSourceLength = 512;
9941 function getFuncName(aFunc) {
9942 if (typeof aFunc !== 'function') {
9943 return null;
9944 }
9945
9946 var name = '';
9947 if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') {
9948 // eslint-disable-next-line prefer-reflect
9949 var functionSource = toString.call(aFunc);
9950 // To avoid unconstrained resource consumption due to pathalogically large function names,
9951 // we limit the available return value to be less than 512 characters.
9952 if (functionSource.indexOf('(') > maxFunctionSourceLength) {
9953 return name;
9954 }
9955 // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined
9956 var match = functionSource.match(functionNameMatch);
9957 if (match) {
9958 name = match[1];
9959 }
9960 } else {
9961 // If we've got a `name` property we just use it
9962 name = aFunc.name;
9963 }
9964
9965 return name;
9966 }
9967
9968 module.exports = getFuncName;
9969
9970 },{}],37:[function(require,module,exports){
9971 (function (global, factory) {
9972 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
9973 typeof define === 'function' && define.amd ? define(['exports'], factory) :
9974 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.loupe = {}));
9975 }(this, (function (exports) { 'use strict';
9976
9977 function _typeof(obj) {
9978 "@babel/helpers - typeof";
9979
9980 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
9981 _typeof = function (obj) {
9982 return typeof obj;
9983 };
9984 } else {
9985 _typeof = function (obj) {
9986 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
9987 };
9988 }
9989
9990 return _typeof(obj);
9991 }
9992
9993 function _slicedToArray(arr, i) {
9994 return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
9995 }
9996
9997 function _arrayWithHoles(arr) {
9998 if (Array.isArray(arr)) return arr;
9999 }
10000
10001 function _iterableToArrayLimit(arr, i) {
10002 if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
10003 var _arr = [];
10004 var _n = true;
10005 var _d = false;
10006 var _e = undefined;
10007
10008 try {
10009 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
10010 _arr.push(_s.value);
10011
10012 if (i && _arr.length === i) break;
10013 }
10014 } catch (err) {
10015 _d = true;
10016 _e = err;
10017 } finally {
10018 try {
10019 if (!_n && _i["return"] != null) _i["return"]();
10020 } finally {
10021 if (_d) throw _e;
10022 }
10023 }
10024
10025 return _arr;
10026 }
10027
10028 function _unsupportedIterableToArray(o, minLen) {
10029 if (!o) return;
10030 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
10031 var n = Object.prototype.toString.call(o).slice(8, -1);
10032 if (n === "Object" && o.constructor) n = o.constructor.name;
10033 if (n === "Map" || n === "Set") return Array.from(o);
10034 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
10035 }
10036
10037 function _arrayLikeToArray(arr, len) {
10038 if (len == null || len > arr.length) len = arr.length;
10039
10040 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
10041
10042 return arr2;
10043 }
10044
10045 function _nonIterableRest() {
10046 throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
10047 }
10048
10049 var ansiColors = {
10050 bold: ['1', '22'],
10051 dim: ['2', '22'],
10052 italic: ['3', '23'],
10053 underline: ['4', '24'],
10054 // 5 & 6 are blinking
10055 inverse: ['7', '27'],
10056 hidden: ['8', '28'],
10057 strike: ['9', '29'],
10058 // 10-20 are fonts
10059 // 21-29 are resets for 1-9
10060 black: ['30', '39'],
10061 red: ['31', '39'],
10062 green: ['32', '39'],
10063 yellow: ['33', '39'],
10064 blue: ['34', '39'],
10065 magenta: ['35', '39'],
10066 cyan: ['36', '39'],
10067 white: ['37', '39'],
10068 brightblack: ['30;1', '39'],
10069 brightred: ['31;1', '39'],
10070 brightgreen: ['32;1', '39'],
10071 brightyellow: ['33;1', '39'],
10072 brightblue: ['34;1', '39'],
10073 brightmagenta: ['35;1', '39'],
10074 brightcyan: ['36;1', '39'],
10075 brightwhite: ['37;1', '39'],
10076 grey: ['90', '39']
10077 };
10078 var styles = {
10079 special: 'cyan',
10080 number: 'yellow',
10081 bigint: 'yellow',
10082 boolean: 'yellow',
10083 undefined: 'grey',
10084 null: 'bold',
10085 string: 'green',
10086 symbol: 'green',
10087 date: 'magenta',
10088 regexp: 'red'
10089 };
10090 var truncator = '…';
10091
10092 function colorise(value, styleType) {
10093 var color = ansiColors[styles[styleType]] || ansiColors[styleType];
10094
10095 if (!color) {
10096 return String(value);
10097 }
10098
10099 return "\x1B[".concat(color[0], "m").concat(String(value), "\x1B[").concat(color[1], "m");
10100 }
10101
10102 function normaliseOptions() {
10103 var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
10104 _ref$showHidden = _ref.showHidden,
10105 showHidden = _ref$showHidden === void 0 ? false : _ref$showHidden,
10106 _ref$depth = _ref.depth,
10107 depth = _ref$depth === void 0 ? 2 : _ref$depth,
10108 _ref$colors = _ref.colors,
10109 colors = _ref$colors === void 0 ? false : _ref$colors,
10110 _ref$customInspect = _ref.customInspect,
10111 customInspect = _ref$customInspect === void 0 ? true : _ref$customInspect,
10112 _ref$showProxy = _ref.showProxy,
10113 showProxy = _ref$showProxy === void 0 ? false : _ref$showProxy,
10114 _ref$maxArrayLength = _ref.maxArrayLength,
10115 maxArrayLength = _ref$maxArrayLength === void 0 ? Infinity : _ref$maxArrayLength,
10116 _ref$breakLength = _ref.breakLength,
10117 breakLength = _ref$breakLength === void 0 ? Infinity : _ref$breakLength,
10118 _ref$seen = _ref.seen,
10119 seen = _ref$seen === void 0 ? [] : _ref$seen,
10120 _ref$truncate = _ref.truncate,
10121 truncate = _ref$truncate === void 0 ? Infinity : _ref$truncate,
10122 _ref$stylize = _ref.stylize,
10123 stylize = _ref$stylize === void 0 ? String : _ref$stylize;
10124
10125 var options = {
10126 showHidden: Boolean(showHidden),
10127 depth: Number(depth),
10128 colors: Boolean(colors),
10129 customInspect: Boolean(customInspect),
10130 showProxy: Boolean(showProxy),
10131 maxArrayLength: Number(maxArrayLength),
10132 breakLength: Number(breakLength),
10133 truncate: Number(truncate),
10134 seen: seen,
10135 stylize: stylize
10136 };
10137
10138 if (options.colors) {
10139 options.stylize = colorise;
10140 }
10141
10142 return options;
10143 }
10144 function truncate(string, length) {
10145 var tail = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : truncator;
10146 string = String(string);
10147 var tailLength = tail.length;
10148 var stringLength = string.length;
10149
10150 if (tailLength > length && stringLength > tailLength) {
10151 return tail;
10152 }
10153
10154 if (stringLength > length && stringLength > tailLength) {
10155 return "".concat(string.slice(0, length - tailLength)).concat(tail);
10156 }
10157
10158 return string;
10159 } // eslint-disable-next-line complexity
10160
10161 function inspectList(list, options, inspectItem) {
10162 var separator = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ', ';
10163 inspectItem = inspectItem || options.inspect;
10164 var size = list.length;
10165 if (size === 0) return '';
10166 var originalLength = options.truncate;
10167 var output = '';
10168 var peek = '';
10169 var truncated = '';
10170
10171 for (var i = 0; i < size; i += 1) {
10172 var last = i + 1 === list.length;
10173 var secondToLast = i + 2 === list.length;
10174 truncated = "".concat(truncator, "(").concat(list.length - i, ")");
10175 var value = list[i]; // If there is more than one remaining we need to account for a separator of `, `
10176
10177 options.truncate = originalLength - output.length - (last ? 0 : separator.length);
10178 var string = peek || inspectItem(value, options) + (last ? '' : separator);
10179 var nextLength = output.length + string.length;
10180 var truncatedLength = nextLength + truncated.length; // If this is the last element, and adding it would
10181 // take us over length, but adding the truncator wouldn't - then break now
10182
10183 if (last && nextLength > originalLength && output.length + truncated.length <= originalLength) {
10184 break;
10185 } // If this isn't the last or second to last element to scan,
10186 // but the string is already over length then break here
10187
10188
10189 if (!last && !secondToLast && truncatedLength > originalLength) {
10190 break;
10191 } // Peek at the next string to determine if we should
10192 // break early before adding this item to the output
10193
10194
10195 peek = last ? '' : inspectItem(list[i + 1], options) + (secondToLast ? '' : separator); // If we have one element left, but this element and
10196 // the next takes over length, the break early
10197
10198 if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) {
10199 break;
10200 }
10201
10202 output += string; // If the next element takes us to length -
10203 // but there are more after that, then we should truncate now
10204
10205 if (!last && !secondToLast && nextLength + peek.length >= originalLength) {
10206 truncated = "".concat(truncator, "(").concat(list.length - i - 1, ")");
10207 break;
10208 }
10209
10210 truncated = '';
10211 }
10212
10213 return "".concat(output).concat(truncated);
10214 }
10215
10216 function quoteComplexKey(key) {
10217 if (key.match(/^[a-zA-Z_][a-zA-Z_0-9]*$/)) {
10218 return key;
10219 }
10220
10221 return JSON.stringify(key).replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'");
10222 }
10223
10224 function inspectProperty(_ref2, options) {
10225 var _ref3 = _slicedToArray(_ref2, 2),
10226 key = _ref3[0],
10227 value = _ref3[1];
10228
10229 options.truncate -= 2;
10230
10231 if (typeof key === 'string') {
10232 key = quoteComplexKey(key);
10233 } else if (typeof key !== 'number') {
10234 key = "[".concat(options.inspect(key, options), "]");
10235 }
10236
10237 options.truncate -= key.length;
10238 value = options.inspect(value, options);
10239 return "".concat(key, ": ").concat(value);
10240 }
10241
10242 function inspectArray(array, options) {
10243 // Object.keys will always output the Array indices first, so we can slice by
10244 // `array.length` to get non-index properties
10245 var nonIndexProperties = Object.keys(array).slice(array.length);
10246 if (!array.length && !nonIndexProperties.length) return '[]';
10247 options.truncate -= 4;
10248 var listContents = inspectList(array, options);
10249 options.truncate -= listContents.length;
10250 var propertyContents = '';
10251
10252 if (nonIndexProperties.length) {
10253 propertyContents = inspectList(nonIndexProperties.map(function (key) {
10254 return [key, array[key]];
10255 }), options, inspectProperty);
10256 }
10257
10258 return "[ ".concat(listContents).concat(propertyContents ? ", ".concat(propertyContents) : '', " ]");
10259 }
10260
10261 /* !
10262 * Chai - getFuncName utility
10263 * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
10264 * MIT Licensed
10265 */
10266
10267 /**
10268 * ### .getFuncName(constructorFn)
10269 *
10270 * Returns the name of a function.
10271 * When a non-function instance is passed, returns `null`.
10272 * This also includes a polyfill function if `aFunc.name` is not defined.
10273 *
10274 * @name getFuncName
10275 * @param {Function} funct
10276 * @namespace Utils
10277 * @api public
10278 */
10279
10280 var toString = Function.prototype.toString;
10281 var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/;
10282 function getFuncName(aFunc) {
10283 if (typeof aFunc !== 'function') {
10284 return null;
10285 }
10286
10287 var name = '';
10288 if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') {
10289 // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined
10290 var match = toString.call(aFunc).match(functionNameMatch);
10291 if (match) {
10292 name = match[1];
10293 }
10294 } else {
10295 // If we've got a `name` property we just use it
10296 name = aFunc.name;
10297 }
10298
10299 return name;
10300 }
10301
10302 var getFuncName_1 = getFuncName;
10303
10304 var getArrayName = function getArrayName(array) {
10305 // We need to special case Node.js' Buffers, which report to be Uint8Array
10306 if (typeof Buffer === 'function' && array instanceof Buffer) {
10307 return 'Buffer';
10308 }
10309
10310 if (array[Symbol.toStringTag]) {
10311 return array[Symbol.toStringTag];
10312 }
10313
10314 return getFuncName_1(array.constructor);
10315 };
10316
10317 function inspectTypedArray(array, options) {
10318 var name = getArrayName(array);
10319 options.truncate -= name.length + 4; // Object.keys will always output the Array indices first, so we can slice by
10320 // `array.length` to get non-index properties
10321
10322 var nonIndexProperties = Object.keys(array).slice(array.length);
10323 if (!array.length && !nonIndexProperties.length) return "".concat(name, "[]"); // As we know TypedArrays only contain Unsigned Integers, we can skip inspecting each one and simply
10324 // stylise the toString() value of them
10325
10326 var output = '';
10327
10328 for (var i = 0; i < array.length; i++) {
10329 var string = "".concat(options.stylize(truncate(array[i], options.truncate), 'number')).concat(i === array.length - 1 ? '' : ', ');
10330 options.truncate -= string.length;
10331
10332 if (array[i] !== array.length && options.truncate <= 3) {
10333 output += "".concat(truncator, "(").concat(array.length - array[i] + 1, ")");
10334 break;
10335 }
10336
10337 output += string;
10338 }
10339
10340 var propertyContents = '';
10341
10342 if (nonIndexProperties.length) {
10343 propertyContents = inspectList(nonIndexProperties.map(function (key) {
10344 return [key, array[key]];
10345 }), options, inspectProperty);
10346 }
10347
10348 return "".concat(name, "[ ").concat(output).concat(propertyContents ? ", ".concat(propertyContents) : '', " ]");
10349 }
10350
10351 function inspectDate(dateObject, options) {
10352 var stringRepresentation = dateObject.toJSON();
10353
10354 if (stringRepresentation === null) {
10355 return 'Invalid Date';
10356 }
10357
10358 var split = stringRepresentation.split('T');
10359 var date = split[0]; // If we need to - truncate the time portion, but never the date
10360
10361 return options.stylize("".concat(date, "T").concat(truncate(split[1], options.truncate - date.length - 1)), 'date');
10362 }
10363
10364 function inspectFunction(func, options) {
10365 var name = getFuncName_1(func);
10366
10367 if (!name) {
10368 return options.stylize('[Function]', 'special');
10369 }
10370
10371 return options.stylize("[Function ".concat(truncate(name, options.truncate - 11), "]"), 'special');
10372 }
10373
10374 function inspectMapEntry(_ref, options) {
10375 var _ref2 = _slicedToArray(_ref, 2),
10376 key = _ref2[0],
10377 value = _ref2[1];
10378
10379 options.truncate -= 4;
10380 key = options.inspect(key, options);
10381 options.truncate -= key.length;
10382 value = options.inspect(value, options);
10383 return "".concat(key, " => ").concat(value);
10384 } // IE11 doesn't support `map.entries()`
10385
10386
10387 function mapToEntries(map) {
10388 var entries = [];
10389 map.forEach(function (value, key) {
10390 entries.push([key, value]);
10391 });
10392 return entries;
10393 }
10394
10395 function inspectMap(map, options) {
10396 var size = map.size - 1;
10397
10398 if (size <= 0) {
10399 return 'Map{}';
10400 }
10401
10402 options.truncate -= 7;
10403 return "Map{ ".concat(inspectList(mapToEntries(map), options, inspectMapEntry), " }");
10404 }
10405
10406 var isNaN = Number.isNaN || function (i) {
10407 return i !== i;
10408 }; // eslint-disable-line no-self-compare
10409
10410
10411 function inspectNumber(number, options) {
10412 if (isNaN(number)) {
10413 return options.stylize('NaN', 'number');
10414 }
10415
10416 if (number === Infinity) {
10417 return options.stylize('Infinity', 'number');
10418 }
10419
10420 if (number === -Infinity) {
10421 return options.stylize('-Infinity', 'number');
10422 }
10423
10424 if (number === 0) {
10425 return options.stylize(1 / number === Infinity ? '+0' : '-0', 'number');
10426 }
10427
10428 return options.stylize(truncate(number, options.truncate), 'number');
10429 }
10430
10431 function inspectBigInt(number, options) {
10432 var nums = truncate(number.toString(), options.truncate - 1);
10433 if (nums !== truncator) nums += 'n';
10434 return options.stylize(nums, 'bigint');
10435 }
10436
10437 function inspectRegExp(value, options) {
10438 var flags = value.toString().split('/')[2];
10439 var sourceLength = options.truncate - (2 + flags.length);
10440 var source = value.source;
10441 return options.stylize("/".concat(truncate(source, sourceLength), "/").concat(flags), 'regexp');
10442 }
10443
10444 function arrayFromSet(set) {
10445 var values = [];
10446 set.forEach(function (value) {
10447 values.push(value);
10448 });
10449 return values;
10450 }
10451
10452 function inspectSet(set, options) {
10453 if (set.size === 0) return 'Set{}';
10454 options.truncate -= 7;
10455 return "Set{ ".concat(inspectList(arrayFromSet(set), options), " }");
10456 }
10457
10458 var stringEscapeChars = new RegExp("['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5" + "\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]", 'g');
10459 var escapeCharacters = {
10460 '\b': '\\b',
10461 '\t': '\\t',
10462 '\n': '\\n',
10463 '\f': '\\f',
10464 '\r': '\\r',
10465 "'": "\\'",
10466 '\\': '\\\\'
10467 };
10468 var hex = 16;
10469 var unicodeLength = 4;
10470
10471 function escape(char) {
10472 return escapeCharacters[char] || "\\u".concat("0000".concat(char.charCodeAt(0).toString(hex)).slice(-unicodeLength));
10473 }
10474
10475 function inspectString(string, options) {
10476 if (stringEscapeChars.test(string)) {
10477 string = string.replace(stringEscapeChars, escape);
10478 }
10479
10480 return options.stylize("'".concat(truncate(string, options.truncate - 2), "'"), 'string');
10481 }
10482
10483 function inspectSymbol(value) {
10484 if ('description' in Symbol.prototype) {
10485 return value.description ? "Symbol(".concat(value.description, ")") : 'Symbol()';
10486 }
10487
10488 return value.toString();
10489 }
10490
10491 var getPromiseValue = function getPromiseValue() {
10492 return 'Promise{…}';
10493 };
10494
10495 try {
10496 var _process$binding = process.binding('util'),
10497 getPromiseDetails = _process$binding.getPromiseDetails,
10498 kPending = _process$binding.kPending,
10499 kRejected = _process$binding.kRejected;
10500
10501 if (Array.isArray(getPromiseDetails(Promise.resolve()))) {
10502 getPromiseValue = function getPromiseValue(value, options) {
10503 var _getPromiseDetails = getPromiseDetails(value),
10504 _getPromiseDetails2 = _slicedToArray(_getPromiseDetails, 2),
10505 state = _getPromiseDetails2[0],
10506 innerValue = _getPromiseDetails2[1];
10507
10508 if (state === kPending) {
10509 return 'Promise{<pending>}';
10510 }
10511
10512 return "Promise".concat(state === kRejected ? '!' : '', "{").concat(options.inspect(innerValue, options), "}");
10513 };
10514 }
10515 } catch (notNode) {
10516 /* ignore */
10517 }
10518
10519 var inspectPromise = getPromiseValue;
10520
10521 function inspectObject(object, options) {
10522 var properties = Object.getOwnPropertyNames(object);
10523 var symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : [];
10524
10525 if (properties.length === 0 && symbols.length === 0) {
10526 return '{}';
10527 }
10528
10529 options.truncate -= 4;
10530 options.seen = options.seen || [];
10531
10532 if (options.seen.indexOf(object) >= 0) {
10533 return '[Circular]';
10534 }
10535
10536 options.seen.push(object);
10537 var propertyContents = inspectList(properties.map(function (key) {
10538 return [key, object[key]];
10539 }), options, inspectProperty);
10540 var symbolContents = inspectList(symbols.map(function (key) {
10541 return [key, object[key]];
10542 }), options, inspectProperty);
10543 options.seen.pop();
10544 var sep = '';
10545
10546 if (propertyContents && symbolContents) {
10547 sep = ', ';
10548 }
10549
10550 return "{ ".concat(propertyContents).concat(sep).concat(symbolContents, " }");
10551 }
10552
10553 var toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag ? Symbol.toStringTag : false;
10554 function inspectClass(value, options) {
10555 var name = '';
10556
10557 if (toStringTag && toStringTag in value) {
10558 name = value[toStringTag];
10559 }
10560
10561 name = name || getFuncName_1(value.constructor); // Babel transforms anonymous classes to the name `_class`
10562
10563 if (!name || name === '_class') {
10564 name = '<Anonymous Class>';
10565 }
10566
10567 options.truncate -= name.length;
10568 return "".concat(name).concat(inspectObject(value, options));
10569 }
10570
10571 function inspectArguments(args, options) {
10572 if (args.length === 0) return 'Arguments[]';
10573 options.truncate -= 13;
10574 return "Arguments[ ".concat(inspectList(args, options), " ]");
10575 }
10576
10577 var errorKeys = ['stack', 'line', 'column', 'name', 'message', 'fileName', 'lineNumber', 'columnNumber', 'number', 'description'];
10578 function inspectObject$1(error, options) {
10579 var properties = Object.getOwnPropertyNames(error).filter(function (key) {
10580 return errorKeys.indexOf(key) === -1;
10581 });
10582 var name = error.name;
10583 options.truncate -= name.length;
10584 var message = '';
10585
10586 if (typeof error.message === 'string') {
10587 message = truncate(error.message, options.truncate);
10588 } else {
10589 properties.unshift('message');
10590 }
10591
10592 message = message ? ": ".concat(message) : '';
10593 options.truncate -= message.length + 5;
10594 var propertyContents = inspectList(properties.map(function (key) {
10595 return [key, error[key]];
10596 }), options, inspectProperty);
10597 return "".concat(name).concat(message).concat(propertyContents ? " { ".concat(propertyContents, " }") : '');
10598 }
10599
10600 function inspectAttribute(_ref, options) {
10601 var _ref2 = _slicedToArray(_ref, 2),
10602 key = _ref2[0],
10603 value = _ref2[1];
10604
10605 options.truncate -= 3;
10606
10607 if (!value) {
10608 return "".concat(options.stylize(key, 'yellow'));
10609 }
10610
10611 return "".concat(options.stylize(key, 'yellow'), "=").concat(options.stylize("\"".concat(value, "\""), 'string'));
10612 }
10613 function inspectHTMLCollection(collection, options) {
10614 // eslint-disable-next-line no-use-before-define
10615 return inspectList(collection, options, inspectHTML, '\n');
10616 }
10617 function inspectHTML(element, options) {
10618 var properties = element.getAttributeNames();
10619 var name = element.tagName.toLowerCase();
10620 var head = options.stylize("<".concat(name), 'special');
10621 var headClose = options.stylize(">", 'special');
10622 var tail = options.stylize("</".concat(name, ">"), 'special');
10623 options.truncate -= name.length * 2 + 5;
10624 var propertyContents = '';
10625
10626 if (properties.length > 0) {
10627 propertyContents += ' ';
10628 propertyContents += inspectList(properties.map(function (key) {
10629 return [key, element.getAttribute(key)];
10630 }), options, inspectAttribute, ' ');
10631 }
10632
10633 options.truncate -= propertyContents.length;
10634 var truncate = options.truncate;
10635 var children = inspectHTMLCollection(element.children, options);
10636
10637 if (children && children.length > truncate) {
10638 children = "".concat(truncator, "(").concat(element.children.length, ")");
10639 }
10640
10641 return "".concat(head).concat(propertyContents).concat(headClose).concat(children).concat(tail);
10642 }
10643
10644 var symbolsSupported = typeof Symbol === 'function' && typeof Symbol.for === 'function';
10645 var chaiInspect = symbolsSupported ? Symbol.for('chai/inspect') : '@@chai/inspect';
10646 var nodeInspect = false;
10647
10648 try {
10649 // eslint-disable-next-line global-require
10650 var nodeUtil = require('util');
10651
10652 nodeInspect = nodeUtil.inspect ? nodeUtil.inspect.custom : false;
10653 } catch (noNodeInspect) {
10654 nodeInspect = false;
10655 }
10656
10657 function FakeMap() {
10658 // eslint-disable-next-line prefer-template
10659 this.key = 'chai/loupe__' + Math.random() + Date.now();
10660 }
10661
10662 FakeMap.prototype = {
10663 // eslint-disable-next-line object-shorthand
10664 get: function get(key) {
10665 return key[this.key];
10666 },
10667 // eslint-disable-next-line object-shorthand
10668 has: function has(key) {
10669 return this.key in key;
10670 },
10671 // eslint-disable-next-line object-shorthand
10672 set: function set(key, value) {
10673 if (Object.isExtensible(key)) {
10674 Object.defineProperty(key, this.key, {
10675 // eslint-disable-next-line object-shorthand
10676 value: value,
10677 configurable: true
10678 });
10679 }
10680 }
10681 };
10682 var constructorMap = new (typeof WeakMap === 'function' ? WeakMap : FakeMap)();
10683 var stringTagMap = {};
10684 var baseTypesMap = {
10685 undefined: function undefined$1(value, options) {
10686 return options.stylize('undefined', 'undefined');
10687 },
10688 null: function _null(value, options) {
10689 return options.stylize(null, 'null');
10690 },
10691 boolean: function boolean(value, options) {
10692 return options.stylize(value, 'boolean');
10693 },
10694 Boolean: function Boolean(value, options) {
10695 return options.stylize(value, 'boolean');
10696 },
10697 number: inspectNumber,
10698 Number: inspectNumber,
10699 bigint: inspectBigInt,
10700 BigInt: inspectBigInt,
10701 string: inspectString,
10702 String: inspectString,
10703 function: inspectFunction,
10704 Function: inspectFunction,
10705 symbol: inspectSymbol,
10706 // A Symbol polyfill will return `Symbol` not `symbol` from typedetect
10707 Symbol: inspectSymbol,
10708 Array: inspectArray,
10709 Date: inspectDate,
10710 Map: inspectMap,
10711 Set: inspectSet,
10712 RegExp: inspectRegExp,
10713 Promise: inspectPromise,
10714 // WeakSet, WeakMap are totally opaque to us
10715 WeakSet: function WeakSet(value, options) {
10716 return options.stylize('WeakSet{…}', 'special');
10717 },
10718 WeakMap: function WeakMap(value, options) {
10719 return options.stylize('WeakMap{…}', 'special');
10720 },
10721 Arguments: inspectArguments,
10722 Int8Array: inspectTypedArray,
10723 Uint8Array: inspectTypedArray,
10724 Uint8ClampedArray: inspectTypedArray,
10725 Int16Array: inspectTypedArray,
10726 Uint16Array: inspectTypedArray,
10727 Int32Array: inspectTypedArray,
10728 Uint32Array: inspectTypedArray,
10729 Float32Array: inspectTypedArray,
10730 Float64Array: inspectTypedArray,
10731 Generator: function Generator() {
10732 return '';
10733 },
10734 DataView: function DataView() {
10735 return '';
10736 },
10737 ArrayBuffer: function ArrayBuffer() {
10738 return '';
10739 },
10740 Error: inspectObject$1,
10741 HTMLCollection: inspectHTMLCollection,
10742 NodeList: inspectHTMLCollection
10743 }; // eslint-disable-next-line complexity
10744
10745 var inspectCustom = function inspectCustom(value, options, type) {
10746 if (chaiInspect in value && typeof value[chaiInspect] === 'function') {
10747 return value[chaiInspect](options);
10748 }
10749
10750 if (nodeInspect && nodeInspect in value && typeof value[nodeInspect] === 'function') {
10751 return value[nodeInspect](options.depth, options);
10752 }
10753
10754 if ('inspect' in value && typeof value.inspect === 'function') {
10755 return value.inspect(options.depth, options);
10756 }
10757
10758 if ('constructor' in value && constructorMap.has(value.constructor)) {
10759 return constructorMap.get(value.constructor)(value, options);
10760 }
10761
10762 if (stringTagMap[type]) {
10763 return stringTagMap[type](value, options);
10764 }
10765
10766 return '';
10767 };
10768
10769 var toString$1 = Object.prototype.toString; // eslint-disable-next-line complexity
10770
10771 function inspect(value, options) {
10772 options = normaliseOptions(options);
10773 options.inspect = inspect;
10774 var _options = options,
10775 customInspect = _options.customInspect;
10776 var type = value === null ? 'null' : _typeof(value);
10777
10778 if (type === 'object') {
10779 type = toString$1.call(value).slice(8, -1);
10780 } // If it is a base value that we already support, then use Loupe's inspector
10781
10782
10783 if (baseTypesMap[type]) {
10784 return baseTypesMap[type](value, options);
10785 } // If `options.customInspect` is set to true then try to use the custom inspector
10786
10787
10788 if (customInspect && value) {
10789 var output = inspectCustom(value, options, type);
10790
10791 if (output) {
10792 if (typeof output === 'string') return output;
10793 return inspect(output, options);
10794 }
10795 }
10796
10797 var proto = value ? Object.getPrototypeOf(value) : false; // If it's a plain Object then use Loupe's inspector
10798
10799 if (proto === Object.prototype || proto === null) {
10800 return inspectObject(value, options);
10801 } // Specifically account for HTMLElements
10802 // eslint-disable-next-line no-undef
10803
10804
10805 if (value && typeof HTMLElement === 'function' && value instanceof HTMLElement) {
10806 return inspectHTML(value, options);
10807 }
10808
10809 if ('constructor' in value) {
10810 // If it is a class, inspect it like an object but add the constructor name
10811 if (value.constructor !== Object) {
10812 return inspectClass(value, options);
10813 } // If it is an object with an anonymous prototype, display it as an object.
10814
10815
10816 return inspectObject(value, options);
10817 } // last chance to check if it's an object
10818
10819
10820 if (value === Object(value)) {
10821 return inspectObject(value, options);
10822 } // We have run out of options! Just stringify the value
10823
10824
10825 return options.stylize(String(value), type);
10826 }
10827 function registerConstructor(constructor, inspector) {
10828 if (constructorMap.has(constructor)) {
10829 return false;
10830 }
10831
10832 constructorMap.set(constructor, inspector);
10833 return true;
10834 }
10835 function registerStringTag(stringTag, inspector) {
10836 if (stringTag in stringTagMap) {
10837 return false;
10838 }
10839
10840 stringTagMap[stringTag] = inspector;
10841 return true;
10842 }
10843 var custom = chaiInspect;
10844
10845 exports.custom = custom;
10846 exports.default = inspect;
10847 exports.inspect = inspect;
10848 exports.registerConstructor = registerConstructor;
10849 exports.registerStringTag = registerStringTag;
10850
10851 Object.defineProperty(exports, '__esModule', { value: true });
10852
10853 })));
10854
10855 },{"util":undefined}],38:[function(require,module,exports){
10856 'use strict';
10857
10858 /* !
10859 * Chai - pathval utility
10860 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
10861 * @see https://github.com/logicalparadox/filtr
10862 * MIT Licensed
10863 */
10864
10865 /**
10866 * ### .hasProperty(object, name)
10867 *
10868 * This allows checking whether an object has own
10869 * or inherited from prototype chain named property.
10870 *
10871 * Basically does the same thing as the `in`
10872 * operator but works properly with null/undefined values
10873 * and other primitives.
10874 *
10875 * var obj = {
10876 * arr: ['a', 'b', 'c']
10877 * , str: 'Hello'
10878 * }
10879 *
10880 * The following would be the results.
10881 *
10882 * hasProperty(obj, 'str'); // true
10883 * hasProperty(obj, 'constructor'); // true
10884 * hasProperty(obj, 'bar'); // false
10885 *
10886 * hasProperty(obj.str, 'length'); // true
10887 * hasProperty(obj.str, 1); // true
10888 * hasProperty(obj.str, 5); // false
10889 *
10890 * hasProperty(obj.arr, 'length'); // true
10891 * hasProperty(obj.arr, 2); // true
10892 * hasProperty(obj.arr, 3); // false
10893 *
10894 * @param {Object} object
10895 * @param {String|Symbol} name
10896 * @returns {Boolean} whether it exists
10897 * @namespace Utils
10898 * @name hasProperty
10899 * @api public
10900 */
10901
10902 function hasProperty(obj, name) {
10903 if (typeof obj === 'undefined' || obj === null) {
10904 return false;
10905 }
10906
10907 // The `in` operator does not work with primitives.
10908 return name in Object(obj);
10909 }
10910
10911 /* !
10912 * ## parsePath(path)
10913 *
10914 * Helper function used to parse string object
10915 * paths. Use in conjunction with `internalGetPathValue`.
10916 *
10917 * var parsed = parsePath('myobject.property.subprop');
10918 *
10919 * ### Paths:
10920 *
10921 * * Can be infinitely deep and nested.
10922 * * Arrays are also valid using the formal `myobject.document[3].property`.
10923 * * Literal dots and brackets (not delimiter) must be backslash-escaped.
10924 *
10925 * @param {String} path
10926 * @returns {Object} parsed
10927 * @api private
10928 */
10929
10930 function parsePath(path) {
10931 var str = path.replace(/([^\\])\[/g, '$1.[');
10932 var parts = str.match(/(\\\.|[^.]+?)+/g);
10933 return parts.map(function mapMatches(value) {
10934 if (
10935 value === 'constructor' ||
10936 value === '__proto__' ||
10937 value === 'prototype'
10938 ) {
10939 return {};
10940 }
10941 var regexp = /^\[(\d+)\]$/;
10942 var mArr = regexp.exec(value);
10943 var parsed = null;
10944 if (mArr) {
10945 parsed = { i: parseFloat(mArr[1]) };
10946 } else {
10947 parsed = { p: value.replace(/\\([.[\]])/g, '$1') };
10948 }
10949
10950 return parsed;
10951 });
10952 }
10953
10954 /* !
10955 * ## internalGetPathValue(obj, parsed[, pathDepth])
10956 *
10957 * Helper companion function for `.parsePath` that returns
10958 * the value located at the parsed address.
10959 *
10960 * var value = getPathValue(obj, parsed);
10961 *
10962 * @param {Object} object to search against
10963 * @param {Object} parsed definition from `parsePath`.
10964 * @param {Number} depth (nesting level) of the property we want to retrieve
10965 * @returns {Object|Undefined} value
10966 * @api private
10967 */
10968
10969 function internalGetPathValue(obj, parsed, pathDepth) {
10970 var temporaryValue = obj;
10971 var res = null;
10972 pathDepth = typeof pathDepth === 'undefined' ? parsed.length : pathDepth;
10973
10974 for (var i = 0; i < pathDepth; i++) {
10975 var part = parsed[i];
10976 if (temporaryValue) {
10977 if (typeof part.p === 'undefined') {
10978 temporaryValue = temporaryValue[part.i];
10979 } else {
10980 temporaryValue = temporaryValue[part.p];
10981 }
10982
10983 if (i === pathDepth - 1) {
10984 res = temporaryValue;
10985 }
10986 }
10987 }
10988
10989 return res;
10990 }
10991
10992 /* !
10993 * ## internalSetPathValue(obj, value, parsed)
10994 *
10995 * Companion function for `parsePath` that sets
10996 * the value located at a parsed address.
10997 *
10998 * internalSetPathValue(obj, 'value', parsed);
10999 *
11000 * @param {Object} object to search and define on
11001 * @param {*} value to use upon set
11002 * @param {Object} parsed definition from `parsePath`
11003 * @api private
11004 */
11005
11006 function internalSetPathValue(obj, val, parsed) {
11007 var tempObj = obj;
11008 var pathDepth = parsed.length;
11009 var part = null;
11010 // Here we iterate through every part of the path
11011 for (var i = 0; i < pathDepth; i++) {
11012 var propName = null;
11013 var propVal = null;
11014 part = parsed[i];
11015
11016 // If it's the last part of the path, we set the 'propName' value with the property name
11017 if (i === pathDepth - 1) {
11018 propName = typeof part.p === 'undefined' ? part.i : part.p;
11019 // Now we set the property with the name held by 'propName' on object with the desired val
11020 tempObj[propName] = val;
11021 } else if (typeof part.p !== 'undefined' && tempObj[part.p]) {
11022 tempObj = tempObj[part.p];
11023 } else if (typeof part.i !== 'undefined' && tempObj[part.i]) {
11024 tempObj = tempObj[part.i];
11025 } else {
11026 // If the obj doesn't have the property we create one with that name to define it
11027 var next = parsed[i + 1];
11028 // Here we set the name of the property which will be defined
11029 propName = typeof part.p === 'undefined' ? part.i : part.p;
11030 // Here we decide if this property will be an array or a new object
11031 propVal = typeof next.p === 'undefined' ? [] : {};
11032 tempObj[propName] = propVal;
11033 tempObj = tempObj[propName];
11034 }
11035 }
11036 }
11037
11038 /**
11039 * ### .getPathInfo(object, path)
11040 *
11041 * This allows the retrieval of property info in an
11042 * object given a string path.
11043 *
11044 * The path info consists of an object with the
11045 * following properties:
11046 *
11047 * * parent - The parent object of the property referenced by `path`
11048 * * name - The name of the final property, a number if it was an array indexer
11049 * * value - The value of the property, if it exists, otherwise `undefined`
11050 * * exists - Whether the property exists or not
11051 *
11052 * @param {Object} object
11053 * @param {String} path
11054 * @returns {Object} info
11055 * @namespace Utils
11056 * @name getPathInfo
11057 * @api public
11058 */
11059
11060 function getPathInfo(obj, path) {
11061 var parsed = parsePath(path);
11062 var last = parsed[parsed.length - 1];
11063 var info = {
11064 parent:
11065 parsed.length > 1 ?
11066 internalGetPathValue(obj, parsed, parsed.length - 1) :
11067 obj,
11068 name: last.p || last.i,
11069 value: internalGetPathValue(obj, parsed),
11070 };
11071 info.exists = hasProperty(info.parent, info.name);
11072
11073 return info;
11074 }
11075
11076 /**
11077 * ### .getPathValue(object, path)
11078 *
11079 * This allows the retrieval of values in an
11080 * object given a string path.
11081 *
11082 * var obj = {
11083 * prop1: {
11084 * arr: ['a', 'b', 'c']
11085 * , str: 'Hello'
11086 * }
11087 * , prop2: {
11088 * arr: [ { nested: 'Universe' } ]
11089 * , str: 'Hello again!'
11090 * }
11091 * }
11092 *
11093 * The following would be the results.
11094 *
11095 * getPathValue(obj, 'prop1.str'); // Hello
11096 * getPathValue(obj, 'prop1.att[2]'); // b
11097 * getPathValue(obj, 'prop2.arr[0].nested'); // Universe
11098 *
11099 * @param {Object} object
11100 * @param {String} path
11101 * @returns {Object} value or `undefined`
11102 * @namespace Utils
11103 * @name getPathValue
11104 * @api public
11105 */
11106
11107 function getPathValue(obj, path) {
11108 var info = getPathInfo(obj, path);
11109 return info.value;
11110 }
11111
11112 /**
11113 * ### .setPathValue(object, path, value)
11114 *
11115 * Define the value in an object at a given string path.
11116 *
11117 * ```js
11118 * var obj = {
11119 * prop1: {
11120 * arr: ['a', 'b', 'c']
11121 * , str: 'Hello'
11122 * }
11123 * , prop2: {
11124 * arr: [ { nested: 'Universe' } ]
11125 * , str: 'Hello again!'
11126 * }
11127 * };
11128 * ```
11129 *
11130 * The following would be acceptable.
11131 *
11132 * ```js
11133 * var properties = require('tea-properties');
11134 * properties.set(obj, 'prop1.str', 'Hello Universe!');
11135 * properties.set(obj, 'prop1.arr[2]', 'B');
11136 * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' });
11137 * ```
11138 *
11139 * @param {Object} object
11140 * @param {String} path
11141 * @param {Mixed} value
11142 * @api private
11143 */
11144
11145 function setPathValue(obj, path, val) {
11146 var parsed = parsePath(path);
11147 internalSetPathValue(obj, val, parsed);
11148 return obj;
11149 }
11150
11151 module.exports = {
11152 hasProperty: hasProperty,
11153 getPathInfo: getPathInfo,
11154 getPathValue: getPathValue,
11155 setPathValue: setPathValue,
11156 };
11157
11158 },{}],39:[function(require,module,exports){
11159 (function (global, factory) {
11160 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
11161 typeof define === 'function' && define.amd ? define(factory) :
11162 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.typeDetect = factory());
11163 })(this, (function () { 'use strict';
11164
11165 var promiseExists = typeof Promise === 'function';
11166 var globalObject = (function (Obj) {
11167 if (typeof globalThis === 'object') {
11168 return globalThis;
11169 }
11170 Object.defineProperty(Obj, 'typeDetectGlobalObject', {
11171 get: function get() {
11172 return this;
11173 },
11174 configurable: true,
11175 });
11176 var global = typeDetectGlobalObject;
11177 delete Obj.typeDetectGlobalObject;
11178 return global;
11179 })(Object.prototype);
11180 var symbolExists = typeof Symbol !== 'undefined';
11181 var mapExists = typeof Map !== 'undefined';
11182 var setExists = typeof Set !== 'undefined';
11183 var weakMapExists = typeof WeakMap !== 'undefined';
11184 var weakSetExists = typeof WeakSet !== 'undefined';
11185 var dataViewExists = typeof DataView !== 'undefined';
11186 var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined';
11187 var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined';
11188 var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';
11189 var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';
11190 var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries());
11191 var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries());
11192 var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
11193 var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
11194 var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function';
11195 var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());
11196 var toStringLeftSliceLength = 8;
11197 var toStringRightSliceLength = -1;
11198 function typeDetect(obj) {
11199 var typeofObj = typeof obj;
11200 if (typeofObj !== 'object') {
11201 return typeofObj;
11202 }
11203 if (obj === null) {
11204 return 'null';
11205 }
11206 if (obj === globalObject) {
11207 return 'global';
11208 }
11209 if (Array.isArray(obj) &&
11210 (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))) {
11211 return 'Array';
11212 }
11213 if (typeof window === 'object' && window !== null) {
11214 if (typeof window.location === 'object' && obj === window.location) {
11215 return 'Location';
11216 }
11217 if (typeof window.document === 'object' && obj === window.document) {
11218 return 'Document';
11219 }
11220 if (typeof window.navigator === 'object') {
11221 if (typeof window.navigator.mimeTypes === 'object' &&
11222 obj === window.navigator.mimeTypes) {
11223 return 'MimeTypeArray';
11224 }
11225 if (typeof window.navigator.plugins === 'object' &&
11226 obj === window.navigator.plugins) {
11227 return 'PluginArray';
11228 }
11229 }
11230 if ((typeof window.HTMLElement === 'function' ||
11231 typeof window.HTMLElement === 'object') &&
11232 obj instanceof window.HTMLElement) {
11233 if (obj.tagName === 'BLOCKQUOTE') {
11234 return 'HTMLQuoteElement';
11235 }
11236 if (obj.tagName === 'TD') {
11237 return 'HTMLTableDataCellElement';
11238 }
11239 if (obj.tagName === 'TH') {
11240 return 'HTMLTableHeaderCellElement';
11241 }
11242 }
11243 }
11244 var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]);
11245 if (typeof stringTag === 'string') {
11246 return stringTag;
11247 }
11248 var objPrototype = Object.getPrototypeOf(obj);
11249 if (objPrototype === RegExp.prototype) {
11250 return 'RegExp';
11251 }
11252 if (objPrototype === Date.prototype) {
11253 return 'Date';
11254 }
11255 if (promiseExists && objPrototype === Promise.prototype) {
11256 return 'Promise';
11257 }
11258 if (setExists && objPrototype === Set.prototype) {
11259 return 'Set';
11260 }
11261 if (mapExists && objPrototype === Map.prototype) {
11262 return 'Map';
11263 }
11264 if (weakSetExists && objPrototype === WeakSet.prototype) {
11265 return 'WeakSet';
11266 }
11267 if (weakMapExists && objPrototype === WeakMap.prototype) {
11268 return 'WeakMap';
11269 }
11270 if (dataViewExists && objPrototype === DataView.prototype) {
11271 return 'DataView';
11272 }
11273 if (mapExists && objPrototype === mapIteratorPrototype) {
11274 return 'Map Iterator';
11275 }
11276 if (setExists && objPrototype === setIteratorPrototype) {
11277 return 'Set Iterator';
11278 }
11279 if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
11280 return 'Array Iterator';
11281 }
11282 if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
11283 return 'String Iterator';
11284 }
11285 if (objPrototype === null) {
11286 return 'Object';
11287 }
11288 return Object
11289 .prototype
11290 .toString
11291 .call(obj)
11292 .slice(toStringLeftSliceLength, toStringRightSliceLength);
11293 }
11294
11295 return typeDetect;
11296
11297 }));
11298
11299 },{}]},{},[1])(1)
11300 });
11301