Only commit raw text after OCR for now.
[redakcja.git] / src / fileupload / static / lib / jQuery-File-Upload-10.32.0 / test / vendor / chai.js
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.2.0';
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    * @param {Mixed} obj target of the assertion
154    * @param {String} msg (optional) custom error message
155    * @param {Function} ssfi (optional) starting point for removing stack frames
156    * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked
157    * @api private
158    */
159
160   function Assertion (obj, msg, ssfi, lockSsfi) {
161     flag(this, 'ssfi', ssfi || Assertion);
162     flag(this, 'lockSsfi', lockSsfi);
163     flag(this, 'object', obj);
164     flag(this, 'message', msg);
165
166     return util.proxify(this);
167   }
168
169   Object.defineProperty(Assertion, 'includeStack', {
170     get: function() {
171       console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
172       return config.includeStack;
173     },
174     set: function(value) {
175       console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
176       config.includeStack = value;
177     }
178   });
179
180   Object.defineProperty(Assertion, 'showDiff', {
181     get: function() {
182       console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
183       return config.showDiff;
184     },
185     set: function(value) {
186       console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
187       config.showDiff = value;
188     }
189   });
190
191   Assertion.addProperty = function (name, fn) {
192     util.addProperty(this.prototype, name, fn);
193   };
194
195   Assertion.addMethod = function (name, fn) {
196     util.addMethod(this.prototype, name, fn);
197   };
198
199   Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
200     util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
201   };
202
203   Assertion.overwriteProperty = function (name, fn) {
204     util.overwriteProperty(this.prototype, name, fn);
205   };
206
207   Assertion.overwriteMethod = function (name, fn) {
208     util.overwriteMethod(this.prototype, name, fn);
209   };
210
211   Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {
212     util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
213   };
214
215   /**
216    * ### .assert(expression, message, negateMessage, expected, actual, showDiff)
217    *
218    * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
219    *
220    * @name assert
221    * @param {Philosophical} expression to be tested
222    * @param {String|Function} message or function that returns message to display if expression fails
223    * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails
224    * @param {Mixed} expected value (remember to check for negation)
225    * @param {Mixed} actual (optional) will default to `this.obj`
226    * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails
227    * @api private
228    */
229
230   Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
231     var ok = util.test(this, arguments);
232     if (false !== showDiff) showDiff = true;
233     if (undefined === expected && undefined === _actual) showDiff = false;
234     if (true !== config.showDiff) showDiff = false;
235
236     if (!ok) {
237       msg = util.getMessage(this, arguments);
238       var actual = util.getActual(this, arguments);
239       throw new AssertionError(msg, {
240           actual: actual
241         , expected: expected
242         , showDiff: showDiff
243       }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));
244     }
245   };
246
247   /*!
248    * ### ._obj
249    *
250    * Quick reference to stored `actual` value for plugin developers.
251    *
252    * @api private
253    */
254
255   Object.defineProperty(Assertion.prototype, '_obj',
256     { get: function () {
257         return flag(this, 'object');
258       }
259     , set: function (val) {
260         flag(this, 'object', val);
261       }
262   });
263 };
264
265 },{"./config":4}],4:[function(require,module,exports){
266 module.exports = {
267
268   /**
269    * ### config.includeStack
270    *
271    * User configurable property, influences whether stack trace
272    * is included in Assertion error message. Default of false
273    * suppresses stack trace in the error message.
274    *
275    *     chai.config.includeStack = true;  // enable stack on error
276    *
277    * @param {Boolean}
278    * @api public
279    */
280
281   includeStack: false,
282
283   /**
284    * ### config.showDiff
285    *
286    * User configurable property, influences whether or not
287    * the `showDiff` flag should be included in the thrown
288    * AssertionErrors. `false` will always be `false`; `true`
289    * will be true when the assertion has requested a diff
290    * be shown.
291    *
292    * @param {Boolean}
293    * @api public
294    */
295
296   showDiff: true,
297
298   /**
299    * ### config.truncateThreshold
300    *
301    * User configurable property, sets length threshold for actual and
302    * expected values in assertion errors. If this threshold is exceeded, for
303    * example for large data structures, the value is replaced with something
304    * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.
305    *
306    * Set it to zero if you want to disable truncating altogether.
307    *
308    * This is especially useful when doing assertions on arrays: having this
309    * set to a reasonable large value makes the failure messages readily
310    * inspectable.
311    *
312    *     chai.config.truncateThreshold = 0;  // disable truncating
313    *
314    * @param {Number}
315    * @api public
316    */
317
318   truncateThreshold: 40,
319
320   /**
321    * ### config.useProxy
322    *
323    * User configurable property, defines if chai will use a Proxy to throw
324    * an error when a non-existent property is read, which protects users
325    * from typos when using property-based assertions.
326    *
327    * Set it to false if you want to disable this feature.
328    *
329    *     chai.config.useProxy = false;  // disable use of Proxy
330    *
331    * This feature is automatically disabled regardless of this config value
332    * in environments that don't support proxies.
333    *
334    * @param {Boolean}
335    * @api public
336    */
337
338   useProxy: true,
339
340   /**
341    * ### config.proxyExcludedKeys
342    *
343    * User configurable property, defines which properties should be ignored
344    * instead of throwing an error if they do not exist on the assertion.
345    * This is only applied if the environment Chai is running in supports proxies and
346    * if the `useProxy` configuration setting is enabled.
347    * By default, `then` and `inspect` will not throw an error if they do not exist on the
348    * assertion object because the `.inspect` property is read by `util.inspect` (for example, when
349    * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking.
350    *
351    *     // By default these keys will not throw an error if they do not exist on the assertion object
352    *     chai.config.proxyExcludedKeys = ['then', 'inspect'];
353    *
354    * @param {Array}
355    * @api public
356    */
357
358   proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON']
359 };
360
361 },{}],5:[function(require,module,exports){
362 /*!
363  * chai
364  * http://chaijs.com
365  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
366  * MIT Licensed
367  */
368
369 module.exports = function (chai, _) {
370   var Assertion = chai.Assertion
371     , AssertionError = chai.AssertionError
372     , flag = _.flag;
373
374   /**
375    * ### Language Chains
376    *
377    * The following are provided as chainable getters to improve the readability
378    * of your assertions.
379    *
380    * **Chains**
381    *
382    * - to
383    * - be
384    * - been
385    * - is
386    * - that
387    * - which
388    * - and
389    * - has
390    * - have
391    * - with
392    * - at
393    * - of
394    * - same
395    * - but
396    * - does
397    * - still
398    *
399    * @name language chains
400    * @namespace BDD
401    * @api public
402    */
403
404   [ 'to', 'be', 'been', 'is'
405   , 'and', 'has', 'have', 'with'
406   , 'that', 'which', 'at', 'of'
407   , 'same', 'but', 'does', 'still' ].forEach(function (chain) {
408     Assertion.addProperty(chain);
409   });
410
411   /**
412    * ### .not
413    *
414    * Negates all assertions that follow in the chain.
415    *
416    *     expect(function () {}).to.not.throw();
417    *     expect({a: 1}).to.not.have.property('b');
418    *     expect([1, 2]).to.be.an('array').that.does.not.include(3);
419    *
420    * Just because you can negate any assertion with `.not` doesn't mean you
421    * should. With great power comes great responsibility. It's often best to
422    * assert that the one expected output was produced, rather than asserting
423    * that one of countless unexpected outputs wasn't produced. See individual
424    * assertions for specific guidance.
425    *
426    *     expect(2).to.equal(2); // Recommended
427    *     expect(2).to.not.equal(1); // Not recommended
428    *
429    * @name not
430    * @namespace BDD
431    * @api public
432    */
433
434   Assertion.addProperty('not', function () {
435     flag(this, 'negate', true);
436   });
437
438   /**
439    * ### .deep
440    *
441    * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property`
442    * assertions that follow in the chain to use deep equality instead of strict
443    * (`===`) equality. See the `deep-eql` project page for info on the deep
444    * equality algorithm: https://github.com/chaijs/deep-eql.
445    *
446    *     // Target object deeply (but not strictly) equals `{a: 1}`
447    *     expect({a: 1}).to.deep.equal({a: 1});
448    *     expect({a: 1}).to.not.equal({a: 1});
449    *
450    *     // Target array deeply (but not strictly) includes `{a: 1}`
451    *     expect([{a: 1}]).to.deep.include({a: 1});
452    *     expect([{a: 1}]).to.not.include({a: 1});
453    *
454    *     // Target object deeply (but not strictly) includes `x: {a: 1}`
455    *     expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
456    *     expect({x: {a: 1}}).to.not.include({x: {a: 1}});
457    *
458    *     // Target array deeply (but not strictly) has member `{a: 1}`
459    *     expect([{a: 1}]).to.have.deep.members([{a: 1}]);
460    *     expect([{a: 1}]).to.not.have.members([{a: 1}]);
461    *
462    *     // Target set deeply (but not strictly) has key `{a: 1}`
463    *     expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]);
464    *     expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]);
465    *
466    *     // Target object deeply (but not strictly) has property `x: {a: 1}`
467    *     expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});
468    *     expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
469    *
470    * @name deep
471    * @namespace BDD
472    * @api public
473    */
474
475   Assertion.addProperty('deep', function () {
476     flag(this, 'deep', true);
477   });
478
479   /**
480    * ### .nested
481    *
482    * Enables dot- and bracket-notation in all `.property` and `.include`
483    * assertions that follow in the chain.
484    *
485    *     expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
486    *     expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
487    *
488    * If `.` or `[]` are part of an actual property name, they can be escaped by
489    * adding two backslashes before them.
490    *
491    *     expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
492    *     expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'});
493    *
494    * `.nested` cannot be combined with `.own`.
495    *
496    * @name nested
497    * @namespace BDD
498    * @api public
499    */
500
501   Assertion.addProperty('nested', function () {
502     flag(this, 'nested', true);
503   });
504
505   /**
506    * ### .own
507    *
508    * Causes all `.property` and `.include` assertions that follow in the chain
509    * to ignore inherited properties.
510    *
511    *     Object.prototype.b = 2;
512    *
513    *     expect({a: 1}).to.have.own.property('a');
514    *     expect({a: 1}).to.have.property('b');
515    *     expect({a: 1}).to.not.have.own.property('b');
516    *
517    *     expect({a: 1}).to.own.include({a: 1});
518    *     expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
519    *
520    * `.own` cannot be combined with `.nested`.
521    *
522    * @name own
523    * @namespace BDD
524    * @api public
525    */
526
527   Assertion.addProperty('own', function () {
528     flag(this, 'own', true);
529   });
530
531   /**
532    * ### .ordered
533    *
534    * Causes all `.members` assertions that follow in the chain to require that
535    * members be in the same order.
536    *
537    *     expect([1, 2]).to.have.ordered.members([1, 2])
538    *       .but.not.have.ordered.members([2, 1]);
539    *
540    * When `.include` and `.ordered` are combined, the ordering begins at the
541    * start of both arrays.
542    *
543    *     expect([1, 2, 3]).to.include.ordered.members([1, 2])
544    *       .but.not.include.ordered.members([2, 3]);
545    *
546    * @name ordered
547    * @namespace BDD
548    * @api public
549    */
550
551   Assertion.addProperty('ordered', function () {
552     flag(this, 'ordered', true);
553   });
554
555   /**
556    * ### .any
557    *
558    * Causes all `.keys` assertions that follow in the chain to only require that
559    * the target have at least one of the given keys. This is the opposite of
560    * `.all`, which requires that the target have all of the given keys.
561    *
562    *     expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
563    *
564    * See the `.keys` doc for guidance on when to use `.any` or `.all`.
565    *
566    * @name any
567    * @namespace BDD
568    * @api public
569    */
570
571   Assertion.addProperty('any', function () {
572     flag(this, 'any', true);
573     flag(this, 'all', false);
574   });
575
576   /**
577    * ### .all
578    *
579    * Causes all `.keys` assertions that follow in the chain to require that the
580    * target have all of the given keys. This is the opposite of `.any`, which
581    * only requires that the target have at least one of the given keys.
582    *
583    *     expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
584    *
585    * Note that `.all` is used by default when neither `.all` nor `.any` are
586    * added earlier in the chain. However, it's often best to add `.all` anyway
587    * because it improves readability.
588    *
589    * See the `.keys` doc for guidance on when to use `.any` or `.all`.
590    *
591    * @name all
592    * @namespace BDD
593    * @api public
594    */
595
596   Assertion.addProperty('all', function () {
597     flag(this, 'all', true);
598     flag(this, 'any', false);
599   });
600
601   /**
602    * ### .a(type[, msg])
603    *
604    * Asserts that the target's type is equal to the given string `type`. Types
605    * are case insensitive. See the `type-detect` project page for info on the
606    * type detection algorithm: https://github.com/chaijs/type-detect.
607    *
608    *     expect('foo').to.be.a('string');
609    *     expect({a: 1}).to.be.an('object');
610    *     expect(null).to.be.a('null');
611    *     expect(undefined).to.be.an('undefined');
612    *     expect(new Error).to.be.an('error');
613    *     expect(Promise.resolve()).to.be.a('promise');
614    *     expect(new Float32Array).to.be.a('float32array');
615    *     expect(Symbol()).to.be.a('symbol');
616    *
617    * `.a` supports objects that have a custom type set via `Symbol.toStringTag`.
618    *
619    *     var myObj = {
620    *       [Symbol.toStringTag]: 'myCustomType'
621    *     };
622    *
623    *     expect(myObj).to.be.a('myCustomType').but.not.an('object');
624    *
625    * It's often best to use `.a` to check a target's type before making more
626    * assertions on the same target. That way, you avoid unexpected behavior from
627    * any assertion that does different things based on the target's type.
628    *
629    *     expect([1, 2, 3]).to.be.an('array').that.includes(2);
630    *     expect([]).to.be.an('array').that.is.empty;
631    *
632    * Add `.not` earlier in the chain to negate `.a`. However, it's often best to
633    * assert that the target is the expected type, rather than asserting that it
634    * isn't one of many unexpected types.
635    *
636    *     expect('foo').to.be.a('string'); // Recommended
637    *     expect('foo').to.not.be.an('array'); // Not recommended
638    *
639    * `.a` accepts an optional `msg` argument which is a custom error message to
640    * show when the assertion fails. The message can also be given as the second
641    * argument to `expect`.
642    *
643    *     expect(1).to.be.a('string', 'nooo why fail??');
644    *     expect(1, 'nooo why fail??').to.be.a('string');
645    *
646    * `.a` can also be used as a language chain to improve the readability of
647    * your assertions.
648    *
649    *     expect({b: 2}).to.have.a.property('b');
650    *
651    * The alias `.an` can be used interchangeably with `.a`.
652    *
653    * @name a
654    * @alias an
655    * @param {String} type
656    * @param {String} msg _optional_
657    * @namespace BDD
658    * @api public
659    */
660
661   function an (type, msg) {
662     if (msg) flag(this, 'message', msg);
663     type = type.toLowerCase();
664     var obj = flag(this, 'object')
665       , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
666
667     this.assert(
668         type === _.type(obj).toLowerCase()
669       , 'expected #{this} to be ' + article + type
670       , 'expected #{this} not to be ' + article + type
671     );
672   }
673
674   Assertion.addChainableMethod('an', an);
675   Assertion.addChainableMethod('a', an);
676
677   /**
678    * ### .include(val[, msg])
679    *
680    * When the target is a string, `.include` asserts that the given string `val`
681    * is a substring of the target.
682    *
683    *     expect('foobar').to.include('foo');
684    *
685    * When the target is an array, `.include` asserts that the given `val` is a
686    * member of the target.
687    *
688    *     expect([1, 2, 3]).to.include(2);
689    *
690    * When the target is an object, `.include` asserts that the given object
691    * `val`'s properties are a subset of the target's properties.
692    *
693    *     expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
694    *
695    * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a
696    * member of the target. SameValueZero equality algorithm is used.
697    *
698    *     expect(new Set([1, 2])).to.include(2);
699    *
700    * When the target is a Map, `.include` asserts that the given `val` is one of
701    * the values of the target. SameValueZero equality algorithm is used.
702    *
703    *     expect(new Map([['a', 1], ['b', 2]])).to.include(2);
704    *
705    * Because `.include` does different things based on the target's type, it's
706    * important to check the target's type before using `.include`. See the `.a`
707    * doc for info on testing a target's type.
708    *
709    *     expect([1, 2, 3]).to.be.an('array').that.includes(2);
710    *
711    * By default, strict (`===`) equality is used to compare array members and
712    * object properties. Add `.deep` earlier in the chain to use deep equality
713    * instead (WeakSet targets are not supported). See the `deep-eql` project
714    * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
715    *
716    *     // Target array deeply (but not strictly) includes `{a: 1}`
717    *     expect([{a: 1}]).to.deep.include({a: 1});
718    *     expect([{a: 1}]).to.not.include({a: 1});
719    *
720    *     // Target object deeply (but not strictly) includes `x: {a: 1}`
721    *     expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
722    *     expect({x: {a: 1}}).to.not.include({x: {a: 1}});
723    *
724    * By default, all of the target's properties are searched when working with
725    * objects. This includes properties that are inherited and/or non-enumerable.
726    * Add `.own` earlier in the chain to exclude the target's inherited
727    * properties from the search.
728    *
729    *     Object.prototype.b = 2;
730    *
731    *     expect({a: 1}).to.own.include({a: 1});
732    *     expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
733    *
734    * Note that a target object is always only searched for `val`'s own
735    * enumerable properties.
736    *
737    * `.deep` and `.own` can be combined.
738    *
739    *     expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}});
740    *
741    * Add `.nested` earlier in the chain to enable dot- and bracket-notation when
742    * referencing nested properties.
743    *
744    *     expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
745    *
746    * If `.` or `[]` are part of an actual property name, they can be escaped by
747    * adding two backslashes before them.
748    *
749    *     expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2});
750    *
751    * `.deep` and `.nested` can be combined.
752    *
753    *     expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}});
754    *
755    * `.own` and `.nested` cannot be combined.
756    *
757    * Add `.not` earlier in the chain to negate `.include`.
758    *
759    *     expect('foobar').to.not.include('taco');
760    *     expect([1, 2, 3]).to.not.include(4);
761    *
762    * However, it's dangerous to negate `.include` when the target is an object.
763    * The problem is that it creates uncertain expectations by asserting that the
764    * target object doesn't have all of `val`'s key/value pairs but may or may
765    * not have some of them. It's often best to identify the exact output that's
766    * expected, and then write an assertion that only accepts that exact output.
767    *
768    * When the target object isn't even expected to have `val`'s keys, it's
769    * often best to assert exactly that.
770    *
771    *     expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended
772    *     expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended
773    *
774    * When the target object is expected to have `val`'s keys, it's often best to
775    * assert that each of the properties has its expected value, rather than
776    * asserting that each property doesn't have one of many unexpected values.
777    *
778    *     expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended
779    *     expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended
780    *
781    * `.include` accepts an optional `msg` argument which is a custom error
782    * message to show when the assertion fails. The message can also be given as
783    * the second argument to `expect`.
784    *
785    *     expect([1, 2, 3]).to.include(4, 'nooo why fail??');
786    *     expect([1, 2, 3], 'nooo why fail??').to.include(4);
787    *
788    * `.include` can also be used as a language chain, causing all `.members` and
789    * `.keys` assertions that follow in the chain to require the target to be a
790    * superset of the expected set, rather than an identical set. Note that
791    * `.members` ignores duplicates in the subset when `.include` is added.
792    *
793    *     // Target object's keys are a superset of ['a', 'b'] but not identical
794    *     expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');
795    *     expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');
796    *
797    *     // Target array is a superset of [1, 2] but not identical
798    *     expect([1, 2, 3]).to.include.members([1, 2]);
799    *     expect([1, 2, 3]).to.not.have.members([1, 2]);
800    *
801    *     // Duplicates in the subset are ignored
802    *     expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
803    *
804    * Note that adding `.any` earlier in the chain causes the `.keys` assertion
805    * to ignore `.include`.
806    *
807    *     // Both assertions are identical
808    *     expect({a: 1}).to.include.any.keys('a', 'b');
809    *     expect({a: 1}).to.have.any.keys('a', 'b');
810    *
811    * The aliases `.includes`, `.contain`, and `.contains` can be used
812    * interchangeably with `.include`.
813    *
814    * @name include
815    * @alias contain
816    * @alias includes
817    * @alias contains
818    * @param {Mixed} val
819    * @param {String} msg _optional_
820    * @namespace BDD
821    * @api public
822    */
823
824   function SameValueZero(a, b) {
825     return (_.isNaN(a) && _.isNaN(b)) || a === b;
826   }
827
828   function includeChainingBehavior () {
829     flag(this, 'contains', true);
830   }
831
832   function include (val, msg) {
833     if (msg) flag(this, 'message', msg);
834
835     var obj = flag(this, 'object')
836       , objType = _.type(obj).toLowerCase()
837       , flagMsg = flag(this, 'message')
838       , negate = flag(this, 'negate')
839       , ssfi = flag(this, 'ssfi')
840       , isDeep = flag(this, 'deep')
841       , descriptor = isDeep ? 'deep ' : '';
842
843     flagMsg = flagMsg ? flagMsg + ': ' : '';
844
845     var included = false;
846
847     switch (objType) {
848       case 'string':
849         included = obj.indexOf(val) !== -1;
850         break;
851
852       case 'weakset':
853         if (isDeep) {
854           throw new AssertionError(
855             flagMsg + 'unable to use .deep.include with WeakSet',
856             undefined,
857             ssfi
858           );
859         }
860
861         included = obj.has(val);
862         break;
863
864       case 'map':
865         var isEql = isDeep ? _.eql : SameValueZero;
866         obj.forEach(function (item) {
867           included = included || isEql(item, val);
868         });
869         break;
870
871       case 'set':
872         if (isDeep) {
873           obj.forEach(function (item) {
874             included = included || _.eql(item, val);
875           });
876         } else {
877           included = obj.has(val);
878         }
879         break;
880
881       case 'array':
882         if (isDeep) {
883           included = obj.some(function (item) {
884             return _.eql(item, val);
885           })
886         } else {
887           included = obj.indexOf(val) !== -1;
888         }
889         break;
890
891       default:
892         // This block is for asserting a subset of properties in an object.
893         // `_.expectTypes` isn't used here because `.include` should work with
894         // objects with a custom `@@toStringTag`.
895         if (val !== Object(val)) {
896           throw new AssertionError(
897             flagMsg + 'object tested must be an array, a map, an object,'
898               + ' a set, a string, or a weakset, but ' + objType + ' given',
899             undefined,
900             ssfi
901           );
902         }
903
904         var props = Object.keys(val)
905           , firstErr = null
906           , numErrs = 0;
907
908         props.forEach(function (prop) {
909           var propAssertion = new Assertion(obj);
910           _.transferFlags(this, propAssertion, true);
911           flag(propAssertion, 'lockSsfi', true);
912
913           if (!negate || props.length === 1) {
914             propAssertion.property(prop, val[prop]);
915             return;
916           }
917
918           try {
919             propAssertion.property(prop, val[prop]);
920           } catch (err) {
921             if (!_.checkError.compatibleConstructor(err, AssertionError)) {
922               throw err;
923             }
924             if (firstErr === null) firstErr = err;
925             numErrs++;
926           }
927         }, this);
928
929         // When validating .not.include with multiple properties, we only want
930         // to throw an assertion error if all of the properties are included,
931         // in which case we throw the first property assertion error that we
932         // encountered.
933         if (negate && props.length > 1 && numErrs === props.length) {
934           throw firstErr;
935         }
936         return;
937     }
938
939     // Assert inclusion in collection or substring in a string.
940     this.assert(
941       included
942       , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val)
943       , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val));
944   }
945
946   Assertion.addChainableMethod('include', include, includeChainingBehavior);
947   Assertion.addChainableMethod('contain', include, includeChainingBehavior);
948   Assertion.addChainableMethod('contains', include, includeChainingBehavior);
949   Assertion.addChainableMethod('includes', include, includeChainingBehavior);
950
951   /**
952    * ### .ok
953    *
954    * Asserts that the target is a truthy value (considered `true` in boolean context).
955    * However, it's often best to assert that the target is strictly (`===`) or
956    * deeply equal to its expected value.
957    *
958    *     expect(1).to.equal(1); // Recommended
959    *     expect(1).to.be.ok; // Not recommended
960    *
961    *     expect(true).to.be.true; // Recommended
962    *     expect(true).to.be.ok; // Not recommended
963    *
964    * Add `.not` earlier in the chain to negate `.ok`.
965    *
966    *     expect(0).to.equal(0); // Recommended
967    *     expect(0).to.not.be.ok; // Not recommended
968    *
969    *     expect(false).to.be.false; // Recommended
970    *     expect(false).to.not.be.ok; // Not recommended
971    *
972    *     expect(null).to.be.null; // Recommended
973    *     expect(null).to.not.be.ok; // Not recommended
974    *
975    *     expect(undefined).to.be.undefined; // Recommended
976    *     expect(undefined).to.not.be.ok; // Not recommended
977    *
978    * A custom error message can be given as the second argument to `expect`.
979    *
980    *     expect(false, 'nooo why fail??').to.be.ok;
981    *
982    * @name ok
983    * @namespace BDD
984    * @api public
985    */
986
987   Assertion.addProperty('ok', function () {
988     this.assert(
989         flag(this, 'object')
990       , 'expected #{this} to be truthy'
991       , 'expected #{this} to be falsy');
992   });
993
994   /**
995    * ### .true
996    *
997    * Asserts that the target is strictly (`===`) equal to `true`.
998    *
999    *     expect(true).to.be.true;
1000    *
1001    * Add `.not` earlier in the chain to negate `.true`. However, it's often best
1002    * to assert that the target is equal to its expected value, rather than not
1003    * equal to `true`.
1004    *
1005    *     expect(false).to.be.false; // Recommended
1006    *     expect(false).to.not.be.true; // Not recommended
1007    *
1008    *     expect(1).to.equal(1); // Recommended
1009    *     expect(1).to.not.be.true; // Not recommended
1010    *
1011    * A custom error message can be given as the second argument to `expect`.
1012    *
1013    *     expect(false, 'nooo why fail??').to.be.true;
1014    *
1015    * @name true
1016    * @namespace BDD
1017    * @api public
1018    */
1019
1020   Assertion.addProperty('true', function () {
1021     this.assert(
1022         true === flag(this, 'object')
1023       , 'expected #{this} to be true'
1024       , 'expected #{this} to be false'
1025       , flag(this, 'negate') ? false : true
1026     );
1027   });
1028
1029   /**
1030    * ### .false
1031    *
1032    * Asserts that the target is strictly (`===`) equal to `false`.
1033    *
1034    *     expect(false).to.be.false;
1035    *
1036    * Add `.not` earlier in the chain to negate `.false`. However, it's often
1037    * best to assert that the target is equal to its expected value, rather than
1038    * not equal to `false`.
1039    *
1040    *     expect(true).to.be.true; // Recommended
1041    *     expect(true).to.not.be.false; // Not recommended
1042    *
1043    *     expect(1).to.equal(1); // Recommended
1044    *     expect(1).to.not.be.false; // Not recommended
1045    *
1046    * A custom error message can be given as the second argument to `expect`.
1047    *
1048    *     expect(true, 'nooo why fail??').to.be.false;
1049    *
1050    * @name false
1051    * @namespace BDD
1052    * @api public
1053    */
1054
1055   Assertion.addProperty('false', function () {
1056     this.assert(
1057         false === flag(this, 'object')
1058       , 'expected #{this} to be false'
1059       , 'expected #{this} to be true'
1060       , flag(this, 'negate') ? true : false
1061     );
1062   });
1063
1064   /**
1065    * ### .null
1066    *
1067    * Asserts that the target is strictly (`===`) equal to `null`.
1068    *
1069    *     expect(null).to.be.null;
1070    *
1071    * Add `.not` earlier in the chain to negate `.null`. However, it's often best
1072    * to assert that the target is equal to its expected value, rather than not
1073    * equal to `null`.
1074    *
1075    *     expect(1).to.equal(1); // Recommended
1076    *     expect(1).to.not.be.null; // Not recommended
1077    *
1078    * A custom error message can be given as the second argument to `expect`.
1079    *
1080    *     expect(42, 'nooo why fail??').to.be.null;
1081    *
1082    * @name null
1083    * @namespace BDD
1084    * @api public
1085    */
1086
1087   Assertion.addProperty('null', function () {
1088     this.assert(
1089         null === flag(this, 'object')
1090       , 'expected #{this} to be null'
1091       , 'expected #{this} not to be null'
1092     );
1093   });
1094
1095   /**
1096    * ### .undefined
1097    *
1098    * Asserts that the target is strictly (`===`) equal to `undefined`.
1099    *
1100    *     expect(undefined).to.be.undefined;
1101    *
1102    * Add `.not` earlier in the chain to negate `.undefined`. However, it's often
1103    * best to assert that the target is equal to its expected value, rather than
1104    * not equal to `undefined`.
1105    *
1106    *     expect(1).to.equal(1); // Recommended
1107    *     expect(1).to.not.be.undefined; // Not recommended
1108    *
1109    * A custom error message can be given as the second argument to `expect`.
1110    *
1111    *     expect(42, 'nooo why fail??').to.be.undefined;
1112    *
1113    * @name undefined
1114    * @namespace BDD
1115    * @api public
1116    */
1117
1118   Assertion.addProperty('undefined', function () {
1119     this.assert(
1120         undefined === flag(this, 'object')
1121       , 'expected #{this} to be undefined'
1122       , 'expected #{this} not to be undefined'
1123     );
1124   });
1125
1126   /**
1127    * ### .NaN
1128    *
1129    * Asserts that the target is exactly `NaN`.
1130    *
1131    *     expect(NaN).to.be.NaN;
1132    *
1133    * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best
1134    * to assert that the target is equal to its expected value, rather than not
1135    * equal to `NaN`.
1136    *
1137    *     expect('foo').to.equal('foo'); // Recommended
1138    *     expect('foo').to.not.be.NaN; // Not recommended
1139    *
1140    * A custom error message can be given as the second argument to `expect`.
1141    *
1142    *     expect(42, 'nooo why fail??').to.be.NaN;
1143    *
1144    * @name NaN
1145    * @namespace BDD
1146    * @api public
1147    */
1148
1149   Assertion.addProperty('NaN', function () {
1150     this.assert(
1151         _.isNaN(flag(this, 'object'))
1152         , 'expected #{this} to be NaN'
1153         , 'expected #{this} not to be NaN'
1154     );
1155   });
1156
1157   /**
1158    * ### .exist
1159    *
1160    * Asserts that the target is not strictly (`===`) equal to either `null` or
1161    * `undefined`. However, it's often best to assert that the target is equal to
1162    * its expected value.
1163    *
1164    *     expect(1).to.equal(1); // Recommended
1165    *     expect(1).to.exist; // Not recommended
1166    *
1167    *     expect(0).to.equal(0); // Recommended
1168    *     expect(0).to.exist; // Not recommended
1169    *
1170    * Add `.not` earlier in the chain to negate `.exist`.
1171    *
1172    *     expect(null).to.be.null; // Recommended
1173    *     expect(null).to.not.exist; // Not recommended
1174    *
1175    *     expect(undefined).to.be.undefined; // Recommended
1176    *     expect(undefined).to.not.exist; // Not recommended
1177    *
1178    * A custom error message can be given as the second argument to `expect`.
1179    *
1180    *     expect(null, 'nooo why fail??').to.exist;
1181    *
1182    * @name exist
1183    * @namespace BDD
1184    * @api public
1185    */
1186
1187   Assertion.addProperty('exist', function () {
1188     var val = flag(this, 'object');
1189     this.assert(
1190         val !== null && val !== undefined
1191       , 'expected #{this} to exist'
1192       , 'expected #{this} to not exist'
1193     );
1194   });
1195
1196   /**
1197    * ### .empty
1198    *
1199    * When the target is a string or array, `.empty` asserts that the target's
1200    * `length` property is strictly (`===`) equal to `0`.
1201    *
1202    *     expect([]).to.be.empty;
1203    *     expect('').to.be.empty;
1204    *
1205    * When the target is a map or set, `.empty` asserts that the target's `size`
1206    * property is strictly equal to `0`.
1207    *
1208    *     expect(new Set()).to.be.empty;
1209    *     expect(new Map()).to.be.empty;
1210    *
1211    * When the target is a non-function object, `.empty` asserts that the target
1212    * doesn't have any own enumerable properties. Properties with Symbol-based
1213    * keys are excluded from the count.
1214    *
1215    *     expect({}).to.be.empty;
1216    *
1217    * Because `.empty` does different things based on the target's type, it's
1218    * important to check the target's type before using `.empty`. See the `.a`
1219    * doc for info on testing a target's type.
1220    *
1221    *     expect([]).to.be.an('array').that.is.empty;
1222    *
1223    * Add `.not` earlier in the chain to negate `.empty`. However, it's often
1224    * best to assert that the target contains its expected number of values,
1225    * rather than asserting that it's not empty.
1226    *
1227    *     expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
1228    *     expect([1, 2, 3]).to.not.be.empty; // Not recommended
1229    *
1230    *     expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended
1231    *     expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended
1232    *
1233    *     expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended
1234    *     expect({a: 1}).to.not.be.empty; // Not recommended
1235    *
1236    * A custom error message can be given as the second argument to `expect`.
1237    *
1238    *     expect([1, 2, 3], 'nooo why fail??').to.be.empty;
1239    *
1240    * @name empty
1241    * @namespace BDD
1242    * @api public
1243    */
1244
1245   Assertion.addProperty('empty', function () {
1246     var val = flag(this, 'object')
1247       , ssfi = flag(this, 'ssfi')
1248       , flagMsg = flag(this, 'message')
1249       , itemsCount;
1250
1251     flagMsg = flagMsg ? flagMsg + ': ' : '';
1252
1253     switch (_.type(val).toLowerCase()) {
1254       case 'array':
1255       case 'string':
1256         itemsCount = val.length;
1257         break;
1258       case 'map':
1259       case 'set':
1260         itemsCount = val.size;
1261         break;
1262       case 'weakmap':
1263       case 'weakset':
1264         throw new AssertionError(
1265           flagMsg + '.empty was passed a weak collection',
1266           undefined,
1267           ssfi
1268         );
1269       case 'function':
1270         var msg = flagMsg + '.empty was passed a function ' + _.getName(val);
1271         throw new AssertionError(msg.trim(), undefined, ssfi);
1272       default:
1273         if (val !== Object(val)) {
1274           throw new AssertionError(
1275             flagMsg + '.empty was passed non-string primitive ' + _.inspect(val),
1276             undefined,
1277             ssfi
1278           );
1279         }
1280         itemsCount = Object.keys(val).length;
1281     }
1282
1283     this.assert(
1284         0 === itemsCount
1285       , 'expected #{this} to be empty'
1286       , 'expected #{this} not to be empty'
1287     );
1288   });
1289
1290   /**
1291    * ### .arguments
1292    *
1293    * Asserts that the target is an `arguments` object.
1294    *
1295    *     function test () {
1296    *       expect(arguments).to.be.arguments;
1297    *     }
1298    *
1299    *     test();
1300    *
1301    * Add `.not` earlier in the chain to negate `.arguments`. However, it's often
1302    * best to assert which type the target is expected to be, rather than
1303    * asserting that its not an `arguments` object.
1304    *
1305    *     expect('foo').to.be.a('string'); // Recommended
1306    *     expect('foo').to.not.be.arguments; // Not recommended
1307    *
1308    * A custom error message can be given as the second argument to `expect`.
1309    *
1310    *     expect({}, 'nooo why fail??').to.be.arguments;
1311    *
1312    * The alias `.Arguments` can be used interchangeably with `.arguments`.
1313    *
1314    * @name arguments
1315    * @alias Arguments
1316    * @namespace BDD
1317    * @api public
1318    */
1319
1320   function checkArguments () {
1321     var obj = flag(this, 'object')
1322       , type = _.type(obj);
1323     this.assert(
1324         'Arguments' === type
1325       , 'expected #{this} to be arguments but got ' + type
1326       , 'expected #{this} to not be arguments'
1327     );
1328   }
1329
1330   Assertion.addProperty('arguments', checkArguments);
1331   Assertion.addProperty('Arguments', checkArguments);
1332
1333   /**
1334    * ### .equal(val[, msg])
1335    *
1336    * Asserts that the target is strictly (`===`) equal to the given `val`.
1337    *
1338    *     expect(1).to.equal(1);
1339    *     expect('foo').to.equal('foo');
1340    *
1341    * Add `.deep` earlier in the chain to use deep equality instead. See the
1342    * `deep-eql` project page for info on the deep equality algorithm:
1343    * https://github.com/chaijs/deep-eql.
1344    *
1345    *     // Target object deeply (but not strictly) equals `{a: 1}`
1346    *     expect({a: 1}).to.deep.equal({a: 1});
1347    *     expect({a: 1}).to.not.equal({a: 1});
1348    *
1349    *     // Target array deeply (but not strictly) equals `[1, 2]`
1350    *     expect([1, 2]).to.deep.equal([1, 2]);
1351    *     expect([1, 2]).to.not.equal([1, 2]);
1352    *
1353    * Add `.not` earlier in the chain to negate `.equal`. However, it's often
1354    * best to assert that the target is equal to its expected value, rather than
1355    * not equal to one of countless unexpected values.
1356    *
1357    *     expect(1).to.equal(1); // Recommended
1358    *     expect(1).to.not.equal(2); // Not recommended
1359    *
1360    * `.equal` accepts an optional `msg` argument which is a custom error message
1361    * to show when the assertion fails. The message can also be given as the
1362    * second argument to `expect`.
1363    *
1364    *     expect(1).to.equal(2, 'nooo why fail??');
1365    *     expect(1, 'nooo why fail??').to.equal(2);
1366    *
1367    * The aliases `.equals` and `eq` can be used interchangeably with `.equal`.
1368    *
1369    * @name equal
1370    * @alias equals
1371    * @alias eq
1372    * @param {Mixed} val
1373    * @param {String} msg _optional_
1374    * @namespace BDD
1375    * @api public
1376    */
1377
1378   function assertEqual (val, msg) {
1379     if (msg) flag(this, 'message', msg);
1380     var obj = flag(this, 'object');
1381     if (flag(this, 'deep')) {
1382       var prevLockSsfi = flag(this, 'lockSsfi');
1383       flag(this, 'lockSsfi', true);
1384       this.eql(val);
1385       flag(this, 'lockSsfi', prevLockSsfi);
1386     } else {
1387       this.assert(
1388           val === obj
1389         , 'expected #{this} to equal #{exp}'
1390         , 'expected #{this} to not equal #{exp}'
1391         , val
1392         , this._obj
1393         , true
1394       );
1395     }
1396   }
1397
1398   Assertion.addMethod('equal', assertEqual);
1399   Assertion.addMethod('equals', assertEqual);
1400   Assertion.addMethod('eq', assertEqual);
1401
1402   /**
1403    * ### .eql(obj[, msg])
1404    *
1405    * Asserts that the target is deeply equal to the given `obj`. See the
1406    * `deep-eql` project page for info on the deep equality algorithm:
1407    * https://github.com/chaijs/deep-eql.
1408    *
1409    *     // Target object is deeply (but not strictly) equal to {a: 1}
1410    *     expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1});
1411    *
1412    *     // Target array is deeply (but not strictly) equal to [1, 2]
1413    *     expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]);
1414    *
1415    * Add `.not` earlier in the chain to negate `.eql`. However, it's often best
1416    * to assert that the target is deeply equal to its expected value, rather
1417    * than not deeply equal to one of countless unexpected values.
1418    *
1419    *     expect({a: 1}).to.eql({a: 1}); // Recommended
1420    *     expect({a: 1}).to.not.eql({b: 2}); // Not recommended
1421    *
1422    * `.eql` accepts an optional `msg` argument which is a custom error message
1423    * to show when the assertion fails. The message can also be given as the
1424    * second argument to `expect`.
1425    *
1426    *     expect({a: 1}).to.eql({b: 2}, 'nooo why fail??');
1427    *     expect({a: 1}, 'nooo why fail??').to.eql({b: 2});
1428    *
1429    * The alias `.eqls` can be used interchangeably with `.eql`.
1430    *
1431    * The `.deep.equal` assertion is almost identical to `.eql` but with one
1432    * difference: `.deep.equal` causes deep equality comparisons to also be used
1433    * for any other assertions that follow in the chain.
1434    *
1435    * @name eql
1436    * @alias eqls
1437    * @param {Mixed} obj
1438    * @param {String} msg _optional_
1439    * @namespace BDD
1440    * @api public
1441    */
1442
1443   function assertEql(obj, msg) {
1444     if (msg) flag(this, 'message', msg);
1445     this.assert(
1446         _.eql(obj, flag(this, 'object'))
1447       , 'expected #{this} to deeply equal #{exp}'
1448       , 'expected #{this} to not deeply equal #{exp}'
1449       , obj
1450       , this._obj
1451       , true
1452     );
1453   }
1454
1455   Assertion.addMethod('eql', assertEql);
1456   Assertion.addMethod('eqls', assertEql);
1457
1458   /**
1459    * ### .above(n[, msg])
1460    *
1461    * Asserts that the target is a number or a date greater than the given number or date `n` respectively.
1462    * However, it's often best to assert that the target is equal to its expected
1463    * value.
1464    *
1465    *     expect(2).to.equal(2); // Recommended
1466    *     expect(2).to.be.above(1); // Not recommended
1467    *
1468    * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1469    * or `size` is greater than the given number `n`.
1470    *
1471    *     expect('foo').to.have.lengthOf(3); // Recommended
1472    *     expect('foo').to.have.lengthOf.above(2); // Not recommended
1473    *
1474    *     expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
1475    *     expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended
1476    *
1477    * Add `.not` earlier in the chain to negate `.above`.
1478    *
1479    *     expect(2).to.equal(2); // Recommended
1480    *     expect(1).to.not.be.above(2); // Not recommended
1481    *
1482    * `.above` accepts an optional `msg` argument which is a custom error message
1483    * to show when the assertion fails. The message can also be given as the
1484    * second argument to `expect`.
1485    *
1486    *     expect(1).to.be.above(2, 'nooo why fail??');
1487    *     expect(1, 'nooo why fail??').to.be.above(2);
1488    *
1489    * The aliases `.gt` and `.greaterThan` can be used interchangeably with
1490    * `.above`.
1491    *
1492    * @name above
1493    * @alias gt
1494    * @alias greaterThan
1495    * @param {Number} n
1496    * @param {String} msg _optional_
1497    * @namespace BDD
1498    * @api public
1499    */
1500
1501   function assertAbove (n, msg) {
1502     if (msg) flag(this, 'message', msg);
1503     var obj = flag(this, 'object')
1504       , doLength = flag(this, 'doLength')
1505       , flagMsg = flag(this, 'message')
1506       , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1507       , ssfi = flag(this, 'ssfi')
1508       , objType = _.type(obj).toLowerCase()
1509       , nType = _.type(n).toLowerCase()
1510       , errorMessage
1511       , shouldThrow = true;
1512
1513     if (doLength && objType !== 'map' && objType !== 'set') {
1514       new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1515     }
1516
1517     if (!doLength && (objType === 'date' && nType !== 'date')) {
1518       errorMessage = msgPrefix + 'the argument to above must be a date';
1519     } else if (nType !== 'number' && (doLength || objType === 'number')) {
1520       errorMessage = msgPrefix + 'the argument to above must be a number';
1521     } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1522       var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1523       errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1524     } else {
1525       shouldThrow = false;
1526     }
1527
1528     if (shouldThrow) {
1529       throw new AssertionError(errorMessage, undefined, ssfi);
1530     }
1531
1532     if (doLength) {
1533       var descriptor = 'length'
1534         , itemsCount;
1535       if (objType === 'map' || objType === 'set') {
1536         descriptor = 'size';
1537         itemsCount = obj.size;
1538       } else {
1539         itemsCount = obj.length;
1540       }
1541       this.assert(
1542           itemsCount > n
1543         , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}'
1544         , 'expected #{this} to not have a ' + descriptor + ' above #{exp}'
1545         , n
1546         , itemsCount
1547       );
1548     } else {
1549       this.assert(
1550           obj > n
1551         , 'expected #{this} to be above #{exp}'
1552         , 'expected #{this} to be at most #{exp}'
1553         , n
1554       );
1555     }
1556   }
1557
1558   Assertion.addMethod('above', assertAbove);
1559   Assertion.addMethod('gt', assertAbove);
1560   Assertion.addMethod('greaterThan', assertAbove);
1561
1562   /**
1563    * ### .least(n[, msg])
1564    *
1565    * Asserts that the target is a number or a date greater than or equal to the given
1566    * number or date `n` respectively. However, it's often best to assert that the target is equal to
1567    * its expected value.
1568    *
1569    *     expect(2).to.equal(2); // Recommended
1570    *     expect(2).to.be.at.least(1); // Not recommended
1571    *     expect(2).to.be.at.least(2); // Not recommended
1572    *
1573    * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1574    * or `size` is greater than or equal to the given number `n`.
1575    *
1576    *     expect('foo').to.have.lengthOf(3); // Recommended
1577    *     expect('foo').to.have.lengthOf.at.least(2); // Not recommended
1578    *
1579    *     expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
1580    *     expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended
1581    *
1582    * Add `.not` earlier in the chain to negate `.least`.
1583    *
1584    *     expect(1).to.equal(1); // Recommended
1585    *     expect(1).to.not.be.at.least(2); // Not recommended
1586    *
1587    * `.least` accepts an optional `msg` argument which is a custom error message
1588    * to show when the assertion fails. The message can also be given as the
1589    * second argument to `expect`.
1590    *
1591    *     expect(1).to.be.at.least(2, 'nooo why fail??');
1592    *     expect(1, 'nooo why fail??').to.be.at.least(2);
1593    *
1594    * The alias `.gte` can be used interchangeably with `.least`.
1595    *
1596    * @name least
1597    * @alias gte
1598    * @param {Number} n
1599    * @param {String} msg _optional_
1600    * @namespace BDD
1601    * @api public
1602    */
1603
1604   function assertLeast (n, msg) {
1605     if (msg) flag(this, 'message', msg);
1606     var obj = flag(this, 'object')
1607       , doLength = flag(this, 'doLength')
1608       , flagMsg = flag(this, 'message')
1609       , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1610       , ssfi = flag(this, 'ssfi')
1611       , objType = _.type(obj).toLowerCase()
1612       , nType = _.type(n).toLowerCase()
1613       , errorMessage
1614       , shouldThrow = true;
1615
1616     if (doLength && objType !== 'map' && objType !== 'set') {
1617       new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1618     }
1619
1620     if (!doLength && (objType === 'date' && nType !== 'date')) {
1621       errorMessage = msgPrefix + 'the argument to least must be a date';
1622     } else if (nType !== 'number' && (doLength || objType === 'number')) {
1623       errorMessage = msgPrefix + 'the argument to least must be a number';
1624     } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1625       var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1626       errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1627     } else {
1628       shouldThrow = false;
1629     }
1630
1631     if (shouldThrow) {
1632       throw new AssertionError(errorMessage, undefined, ssfi);
1633     }
1634
1635     if (doLength) {
1636       var descriptor = 'length'
1637         , itemsCount;
1638       if (objType === 'map' || objType === 'set') {
1639         descriptor = 'size';
1640         itemsCount = obj.size;
1641       } else {
1642         itemsCount = obj.length;
1643       }
1644       this.assert(
1645           itemsCount >= n
1646         , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}'
1647         , 'expected #{this} to have a ' + descriptor + ' below #{exp}'
1648         , n
1649         , itemsCount
1650       );
1651     } else {
1652       this.assert(
1653           obj >= n
1654         , 'expected #{this} to be at least #{exp}'
1655         , 'expected #{this} to be below #{exp}'
1656         , n
1657       );
1658     }
1659   }
1660
1661   Assertion.addMethod('least', assertLeast);
1662   Assertion.addMethod('gte', assertLeast);
1663
1664   /**
1665    * ### .below(n[, msg])
1666    *
1667    * Asserts that the target is a number or a date less than the given number or date `n` respectively.
1668    * However, it's often best to assert that the target is equal to its expected
1669    * value.
1670    *
1671    *     expect(1).to.equal(1); // Recommended
1672    *     expect(1).to.be.below(2); // Not recommended
1673    *
1674    * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1675    * or `size` is less than the given number `n`.
1676    *
1677    *     expect('foo').to.have.lengthOf(3); // Recommended
1678    *     expect('foo').to.have.lengthOf.below(4); // Not recommended
1679    *
1680    *     expect([1, 2, 3]).to.have.length(3); // Recommended
1681    *     expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended
1682    *
1683    * Add `.not` earlier in the chain to negate `.below`.
1684    *
1685    *     expect(2).to.equal(2); // Recommended
1686    *     expect(2).to.not.be.below(1); // Not recommended
1687    *
1688    * `.below` accepts an optional `msg` argument which is a custom error message
1689    * to show when the assertion fails. The message can also be given as the
1690    * second argument to `expect`.
1691    *
1692    *     expect(2).to.be.below(1, 'nooo why fail??');
1693    *     expect(2, 'nooo why fail??').to.be.below(1);
1694    *
1695    * The aliases `.lt` and `.lessThan` can be used interchangeably with
1696    * `.below`.
1697    *
1698    * @name below
1699    * @alias lt
1700    * @alias lessThan
1701    * @param {Number} n
1702    * @param {String} msg _optional_
1703    * @namespace BDD
1704    * @api public
1705    */
1706
1707   function assertBelow (n, msg) {
1708     if (msg) flag(this, 'message', msg);
1709     var obj = flag(this, 'object')
1710       , doLength = flag(this, 'doLength')
1711       , flagMsg = flag(this, 'message')
1712       , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1713       , ssfi = flag(this, 'ssfi')
1714       , objType = _.type(obj).toLowerCase()
1715       , nType = _.type(n).toLowerCase()
1716       , errorMessage
1717       , shouldThrow = true;
1718
1719     if (doLength && objType !== 'map' && objType !== 'set') {
1720       new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1721     }
1722
1723     if (!doLength && (objType === 'date' && nType !== 'date')) {
1724       errorMessage = msgPrefix + 'the argument to below must be a date';
1725     } else if (nType !== 'number' && (doLength || objType === 'number')) {
1726       errorMessage = msgPrefix + 'the argument to below must be a number';
1727     } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1728       var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1729       errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1730     } else {
1731       shouldThrow = false;
1732     }
1733
1734     if (shouldThrow) {
1735       throw new AssertionError(errorMessage, undefined, ssfi);
1736     }
1737
1738     if (doLength) {
1739       var descriptor = 'length'
1740         , itemsCount;
1741       if (objType === 'map' || objType === 'set') {
1742         descriptor = 'size';
1743         itemsCount = obj.size;
1744       } else {
1745         itemsCount = obj.length;
1746       }
1747       this.assert(
1748           itemsCount < n
1749         , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}'
1750         , 'expected #{this} to not have a ' + descriptor + ' below #{exp}'
1751         , n
1752         , itemsCount
1753       );
1754     } else {
1755       this.assert(
1756           obj < n
1757         , 'expected #{this} to be below #{exp}'
1758         , 'expected #{this} to be at least #{exp}'
1759         , n
1760       );
1761     }
1762   }
1763
1764   Assertion.addMethod('below', assertBelow);
1765   Assertion.addMethod('lt', assertBelow);
1766   Assertion.addMethod('lessThan', assertBelow);
1767
1768   /**
1769    * ### .most(n[, msg])
1770    *
1771    * Asserts that the target is a number or a date less than or equal to the given number
1772    * or date `n` respectively. However, it's often best to assert that the target is equal to its
1773    * expected value.
1774    *
1775    *     expect(1).to.equal(1); // Recommended
1776    *     expect(1).to.be.at.most(2); // Not recommended
1777    *     expect(1).to.be.at.most(1); // Not recommended
1778    *
1779    * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1780    * or `size` is less than or equal to the given number `n`.
1781    *
1782    *     expect('foo').to.have.lengthOf(3); // Recommended
1783    *     expect('foo').to.have.lengthOf.at.most(4); // Not recommended
1784    *
1785    *     expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
1786    *     expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended
1787    *
1788    * Add `.not` earlier in the chain to negate `.most`.
1789    *
1790    *     expect(2).to.equal(2); // Recommended
1791    *     expect(2).to.not.be.at.most(1); // Not recommended
1792    *
1793    * `.most` accepts an optional `msg` argument which is a custom error message
1794    * to show when the assertion fails. The message can also be given as the
1795    * second argument to `expect`.
1796    *
1797    *     expect(2).to.be.at.most(1, 'nooo why fail??');
1798    *     expect(2, 'nooo why fail??').to.be.at.most(1);
1799    *
1800    * The alias `.lte` can be used interchangeably with `.most`.
1801    *
1802    * @name most
1803    * @alias lte
1804    * @param {Number} n
1805    * @param {String} msg _optional_
1806    * @namespace BDD
1807    * @api public
1808    */
1809
1810   function assertMost (n, msg) {
1811     if (msg) flag(this, 'message', msg);
1812     var obj = flag(this, 'object')
1813       , doLength = flag(this, 'doLength')
1814       , flagMsg = flag(this, 'message')
1815       , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1816       , ssfi = flag(this, 'ssfi')
1817       , objType = _.type(obj).toLowerCase()
1818       , nType = _.type(n).toLowerCase()
1819       , errorMessage
1820       , shouldThrow = true;
1821
1822     if (doLength && objType !== 'map' && objType !== 'set') {
1823       new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1824     }
1825
1826     if (!doLength && (objType === 'date' && nType !== 'date')) {
1827       errorMessage = msgPrefix + 'the argument to most must be a date';
1828     } else if (nType !== 'number' && (doLength || objType === 'number')) {
1829       errorMessage = msgPrefix + 'the argument to most must be a number';
1830     } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1831       var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1832       errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1833     } else {
1834       shouldThrow = false;
1835     }
1836
1837     if (shouldThrow) {
1838       throw new AssertionError(errorMessage, undefined, ssfi);
1839     }
1840
1841     if (doLength) {
1842       var descriptor = 'length'
1843         , itemsCount;
1844       if (objType === 'map' || objType === 'set') {
1845         descriptor = 'size';
1846         itemsCount = obj.size;
1847       } else {
1848         itemsCount = obj.length;
1849       }
1850       this.assert(
1851           itemsCount <= n
1852         , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}'
1853         , 'expected #{this} to have a ' + descriptor + ' above #{exp}'
1854         , n
1855         , itemsCount
1856       );
1857     } else {
1858       this.assert(
1859           obj <= n
1860         , 'expected #{this} to be at most #{exp}'
1861         , 'expected #{this} to be above #{exp}'
1862         , n
1863       );
1864     }
1865   }
1866
1867   Assertion.addMethod('most', assertMost);
1868   Assertion.addMethod('lte', assertMost);
1869
1870   /**
1871    * ### .within(start, finish[, msg])
1872    *
1873    * Asserts that the target is a number or a date greater than or equal to the given
1874    * number or date `start`, and less than or equal to the given number or date `finish` respectively.
1875    * However, it's often best to assert that the target is equal to its expected
1876    * value.
1877    *
1878    *     expect(2).to.equal(2); // Recommended
1879    *     expect(2).to.be.within(1, 3); // Not recommended
1880    *     expect(2).to.be.within(2, 3); // Not recommended
1881    *     expect(2).to.be.within(1, 2); // Not recommended
1882    *
1883    * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1884    * or `size` is greater than or equal to the given number `start`, and less
1885    * than or equal to the given number `finish`.
1886    *
1887    *     expect('foo').to.have.lengthOf(3); // Recommended
1888    *     expect('foo').to.have.lengthOf.within(2, 4); // Not recommended
1889    *
1890    *     expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
1891    *     expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended
1892    *
1893    * Add `.not` earlier in the chain to negate `.within`.
1894    *
1895    *     expect(1).to.equal(1); // Recommended
1896    *     expect(1).to.not.be.within(2, 4); // Not recommended
1897    *
1898    * `.within` accepts an optional `msg` argument which is a custom error
1899    * message to show when the assertion fails. The message can also be given as
1900    * the second argument to `expect`.
1901    *
1902    *     expect(4).to.be.within(1, 3, 'nooo why fail??');
1903    *     expect(4, 'nooo why fail??').to.be.within(1, 3);
1904    *
1905    * @name within
1906    * @param {Number} start lower bound inclusive
1907    * @param {Number} finish upper bound inclusive
1908    * @param {String} msg _optional_
1909    * @namespace BDD
1910    * @api public
1911    */
1912
1913   Assertion.addMethod('within', function (start, finish, msg) {
1914     if (msg) flag(this, 'message', msg);
1915     var obj = flag(this, 'object')
1916       , doLength = flag(this, 'doLength')
1917       , flagMsg = flag(this, 'message')
1918       , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1919       , ssfi = flag(this, 'ssfi')
1920       , objType = _.type(obj).toLowerCase()
1921       , startType = _.type(start).toLowerCase()
1922       , finishType = _.type(finish).toLowerCase()
1923       , errorMessage
1924       , shouldThrow = true
1925       , range = (startType === 'date' && finishType === 'date')
1926           ? start.toUTCString() + '..' + finish.toUTCString()
1927           : start + '..' + finish;
1928
1929     if (doLength && objType !== 'map' && objType !== 'set') {
1930       new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1931     }
1932
1933     if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) {
1934       errorMessage = msgPrefix + 'the arguments to within must be dates';
1935     } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) {
1936       errorMessage = msgPrefix + 'the arguments to within must be numbers';
1937     } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1938       var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1939       errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1940     } else {
1941       shouldThrow = false;
1942     }
1943
1944     if (shouldThrow) {
1945       throw new AssertionError(errorMessage, undefined, ssfi);
1946     }
1947
1948     if (doLength) {
1949       var descriptor = 'length'
1950         , itemsCount;
1951       if (objType === 'map' || objType === 'set') {
1952         descriptor = 'size';
1953         itemsCount = obj.size;
1954       } else {
1955         itemsCount = obj.length;
1956       }
1957       this.assert(
1958           itemsCount >= start && itemsCount <= finish
1959         , 'expected #{this} to have a ' + descriptor + ' within ' + range
1960         , 'expected #{this} to not have a ' + descriptor + ' within ' + range
1961       );
1962     } else {
1963       this.assert(
1964           obj >= start && obj <= finish
1965         , 'expected #{this} to be within ' + range
1966         , 'expected #{this} to not be within ' + range
1967       );
1968     }
1969   });
1970
1971   /**
1972    * ### .instanceof(constructor[, msg])
1973    *
1974    * Asserts that the target is an instance of the given `constructor`.
1975    *
1976    *     function Cat () { }
1977    *
1978    *     expect(new Cat()).to.be.an.instanceof(Cat);
1979    *     expect([1, 2]).to.be.an.instanceof(Array);
1980    *
1981    * Add `.not` earlier in the chain to negate `.instanceof`.
1982    *
1983    *     expect({a: 1}).to.not.be.an.instanceof(Array);
1984    *
1985    * `.instanceof` accepts an optional `msg` argument which is a custom error
1986    * message to show when the assertion fails. The message can also be given as
1987    * the second argument to `expect`.
1988    *
1989    *     expect(1).to.be.an.instanceof(Array, 'nooo why fail??');
1990    *     expect(1, 'nooo why fail??').to.be.an.instanceof(Array);
1991    *
1992    * Due to limitations in ES5, `.instanceof` may not always work as expected
1993    * when using a transpiler such as Babel or TypeScript. In particular, it may
1994    * produce unexpected results when subclassing built-in object such as
1995    * `Array`, `Error`, and `Map`. See your transpiler's docs for details:
1996    *
1997    * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes))
1998    * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work))
1999    *
2000    * The alias `.instanceOf` can be used interchangeably with `.instanceof`.
2001    *
2002    * @name instanceof
2003    * @param {Constructor} constructor
2004    * @param {String} msg _optional_
2005    * @alias instanceOf
2006    * @namespace BDD
2007    * @api public
2008    */
2009
2010   function assertInstanceOf (constructor, msg) {
2011     if (msg) flag(this, 'message', msg);
2012
2013     var target = flag(this, 'object')
2014     var ssfi = flag(this, 'ssfi');
2015     var flagMsg = flag(this, 'message');
2016
2017     try {
2018       var isInstanceOf = target instanceof constructor;
2019     } catch (err) {
2020       if (err instanceof TypeError) {
2021         flagMsg = flagMsg ? flagMsg + ': ' : '';
2022         throw new AssertionError(
2023           flagMsg + 'The instanceof assertion needs a constructor but '
2024             + _.type(constructor) + ' was given.',
2025           undefined,
2026           ssfi
2027         );
2028       }
2029       throw err;
2030     }
2031
2032     var name = _.getName(constructor);
2033     if (name === null) {
2034       name = 'an unnamed constructor';
2035     }
2036
2037     this.assert(
2038         isInstanceOf
2039       , 'expected #{this} to be an instance of ' + name
2040       , 'expected #{this} to not be an instance of ' + name
2041     );
2042   };
2043
2044   Assertion.addMethod('instanceof', assertInstanceOf);
2045   Assertion.addMethod('instanceOf', assertInstanceOf);
2046
2047   /**
2048    * ### .property(name[, val[, msg]])
2049    *
2050    * Asserts that the target has a property with the given key `name`.
2051    *
2052    *     expect({a: 1}).to.have.property('a');
2053    *
2054    * When `val` is provided, `.property` also asserts that the property's value
2055    * is equal to the given `val`.
2056    *
2057    *     expect({a: 1}).to.have.property('a', 1);
2058    *
2059    * By default, strict (`===`) equality is used. Add `.deep` earlier in the
2060    * chain to use deep equality instead. See the `deep-eql` project page for
2061    * info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
2062    *
2063    *     // Target object deeply (but not strictly) has property `x: {a: 1}`
2064    *     expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});
2065    *     expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
2066    *
2067    * The target's enumerable and non-enumerable properties are always included
2068    * in the search. By default, both own and inherited properties are included.
2069    * Add `.own` earlier in the chain to exclude inherited properties from the
2070    * search.
2071    *
2072    *     Object.prototype.b = 2;
2073    *
2074    *     expect({a: 1}).to.have.own.property('a');
2075    *     expect({a: 1}).to.have.own.property('a', 1);
2076    *     expect({a: 1}).to.have.property('b');
2077    *     expect({a: 1}).to.not.have.own.property('b');
2078    *
2079    * `.deep` and `.own` can be combined.
2080    *
2081    *     expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1});
2082    *
2083    * Add `.nested` earlier in the chain to enable dot- and bracket-notation when
2084    * referencing nested properties.
2085    *
2086    *     expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
2087    *     expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y');
2088    *
2089    * If `.` or `[]` are part of an actual property name, they can be escaped by
2090    * adding two backslashes before them.
2091    *
2092    *     expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
2093    *
2094    * `.deep` and `.nested` can be combined.
2095    *
2096    *     expect({a: {b: [{c: 3}]}})
2097    *       .to.have.deep.nested.property('a.b[0]', {c: 3});
2098    *
2099    * `.own` and `.nested` cannot be combined.
2100    *
2101    * Add `.not` earlier in the chain to negate `.property`.
2102    *
2103    *     expect({a: 1}).to.not.have.property('b');
2104    *
2105    * However, it's dangerous to negate `.property` when providing `val`. The
2106    * problem is that it creates uncertain expectations by asserting that the
2107    * target either doesn't have a property with the given key `name`, or that it
2108    * does have a property with the given key `name` but its value isn't equal to
2109    * the given `val`. It's often best to identify the exact output that's
2110    * expected, and then write an assertion that only accepts that exact output.
2111    *
2112    * When the target isn't expected to have a property with the given key
2113    * `name`, it's often best to assert exactly that.
2114    *
2115    *     expect({b: 2}).to.not.have.property('a'); // Recommended
2116    *     expect({b: 2}).to.not.have.property('a', 1); // Not recommended
2117    *
2118    * When the target is expected to have a property with the given key `name`,
2119    * it's often best to assert that the property has its expected value, rather
2120    * than asserting that it doesn't have one of many unexpected values.
2121    *
2122    *     expect({a: 3}).to.have.property('a', 3); // Recommended
2123    *     expect({a: 3}).to.not.have.property('a', 1); // Not recommended
2124    *
2125    * `.property` changes the target of any assertions that follow in the chain
2126    * to be the value of the property from the original target object.
2127    *
2128    *     expect({a: 1}).to.have.property('a').that.is.a('number');
2129    *
2130    * `.property` accepts an optional `msg` argument which is a custom error
2131    * message to show when the assertion fails. The message can also be given as
2132    * the second argument to `expect`. When not providing `val`, only use the
2133    * second form.
2134    *
2135    *     // Recommended
2136    *     expect({a: 1}).to.have.property('a', 2, 'nooo why fail??');
2137    *     expect({a: 1}, 'nooo why fail??').to.have.property('a', 2);
2138    *     expect({a: 1}, 'nooo why fail??').to.have.property('b');
2139    *
2140    *     // Not recommended
2141    *     expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??');
2142    *
2143    * The above assertion isn't the same thing as not providing `val`. Instead,
2144    * it's asserting that the target object has a `b` property that's equal to
2145    * `undefined`.
2146    *
2147    * The assertions `.ownProperty` and `.haveOwnProperty` can be used
2148    * interchangeably with `.own.property`.
2149    *
2150    * @name property
2151    * @param {String} name
2152    * @param {Mixed} val (optional)
2153    * @param {String} msg _optional_
2154    * @returns value of property for chaining
2155    * @namespace BDD
2156    * @api public
2157    */
2158
2159   function assertProperty (name, val, msg) {
2160     if (msg) flag(this, 'message', msg);
2161
2162     var isNested = flag(this, 'nested')
2163       , isOwn = flag(this, 'own')
2164       , flagMsg = flag(this, 'message')
2165       , obj = flag(this, 'object')
2166       , ssfi = flag(this, 'ssfi')
2167       , nameType = typeof name;
2168
2169     flagMsg = flagMsg ? flagMsg + ': ' : '';
2170
2171     if (isNested) {
2172       if (nameType !== 'string') {
2173         throw new AssertionError(
2174           flagMsg + 'the argument to property must be a string when using nested syntax',
2175           undefined,
2176           ssfi
2177         );
2178       }
2179     } else {
2180       if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') {
2181         throw new AssertionError(
2182           flagMsg + 'the argument to property must be a string, number, or symbol',
2183           undefined,
2184           ssfi
2185         );
2186       }
2187     }
2188
2189     if (isNested && isOwn) {
2190       throw new AssertionError(
2191         flagMsg + 'The "nested" and "own" flags cannot be combined.',
2192         undefined,
2193         ssfi
2194       );
2195     }
2196
2197     if (obj === null || obj === undefined) {
2198       throw new AssertionError(
2199         flagMsg + 'Target cannot be null or undefined.',
2200         undefined,
2201         ssfi
2202       );
2203     }
2204
2205     var isDeep = flag(this, 'deep')
2206       , negate = flag(this, 'negate')
2207       , pathInfo = isNested ? _.getPathInfo(obj, name) : null
2208       , value = isNested ? pathInfo.value : obj[name];
2209
2210     var descriptor = '';
2211     if (isDeep) descriptor += 'deep ';
2212     if (isOwn) descriptor += 'own ';
2213     if (isNested) descriptor += 'nested ';
2214     descriptor += 'property ';
2215
2216     var hasProperty;
2217     if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name);
2218     else if (isNested) hasProperty = pathInfo.exists;
2219     else hasProperty = _.hasProperty(obj, name);
2220
2221     // When performing a negated assertion for both name and val, merely having
2222     // a property with the given name isn't enough to cause the assertion to
2223     // fail. It must both have a property with the given name, and the value of
2224     // that property must equal the given val. Therefore, skip this assertion in
2225     // favor of the next.
2226     if (!negate || arguments.length === 1) {
2227       this.assert(
2228           hasProperty
2229         , 'expected #{this} to have ' + descriptor + _.inspect(name)
2230         , 'expected #{this} to not have ' + descriptor + _.inspect(name));
2231     }
2232
2233     if (arguments.length > 1) {
2234       this.assert(
2235           hasProperty && (isDeep ? _.eql(val, value) : val === value)
2236         , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
2237         , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}'
2238         , val
2239         , value
2240       );
2241     }
2242
2243     flag(this, 'object', value);
2244   }
2245
2246   Assertion.addMethod('property', assertProperty);
2247
2248   function assertOwnProperty (name, value, msg) {
2249     flag(this, 'own', true);
2250     assertProperty.apply(this, arguments);
2251   }
2252
2253   Assertion.addMethod('ownProperty', assertOwnProperty);
2254   Assertion.addMethod('haveOwnProperty', assertOwnProperty);
2255
2256   /**
2257    * ### .ownPropertyDescriptor(name[, descriptor[, msg]])
2258    *
2259    * Asserts that the target has its own property descriptor with the given key
2260    * `name`. Enumerable and non-enumerable properties are included in the
2261    * search.
2262    *
2263    *     expect({a: 1}).to.have.ownPropertyDescriptor('a');
2264    *
2265    * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that
2266    * the property's descriptor is deeply equal to the given `descriptor`. See
2267    * the `deep-eql` project page for info on the deep equality algorithm:
2268    * https://github.com/chaijs/deep-eql.
2269    *
2270    *     expect({a: 1}).to.have.ownPropertyDescriptor('a', {
2271    *       configurable: true,
2272    *       enumerable: true,
2273    *       writable: true,
2274    *       value: 1,
2275    *     });
2276    *
2277    * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`.
2278    *
2279    *     expect({a: 1}).to.not.have.ownPropertyDescriptor('b');
2280    *
2281    * However, it's dangerous to negate `.ownPropertyDescriptor` when providing
2282    * a `descriptor`. The problem is that it creates uncertain expectations by
2283    * asserting that the target either doesn't have a property descriptor with
2284    * the given key `name`, or that it does have a property descriptor with the
2285    * given key `name` but its not deeply equal to the given `descriptor`. It's
2286    * often best to identify the exact output that's expected, and then write an
2287    * assertion that only accepts that exact output.
2288    *
2289    * When the target isn't expected to have a property descriptor with the given
2290    * key `name`, it's often best to assert exactly that.
2291    *
2292    *     // Recommended
2293    *     expect({b: 2}).to.not.have.ownPropertyDescriptor('a');
2294    *
2295    *     // Not recommended
2296    *     expect({b: 2}).to.not.have.ownPropertyDescriptor('a', {
2297    *       configurable: true,
2298    *       enumerable: true,
2299    *       writable: true,
2300    *       value: 1,
2301    *     });
2302    *
2303    * When the target is expected to have a property descriptor with the given
2304    * key `name`, it's often best to assert that the property has its expected
2305    * descriptor, rather than asserting that it doesn't have one of many
2306    * unexpected descriptors.
2307    *
2308    *     // Recommended
2309    *     expect({a: 3}).to.have.ownPropertyDescriptor('a', {
2310    *       configurable: true,
2311    *       enumerable: true,
2312    *       writable: true,
2313    *       value: 3,
2314    *     });
2315    *
2316    *     // Not recommended
2317    *     expect({a: 3}).to.not.have.ownPropertyDescriptor('a', {
2318    *       configurable: true,
2319    *       enumerable: true,
2320    *       writable: true,
2321    *       value: 1,
2322    *     });
2323    *
2324    * `.ownPropertyDescriptor` changes the target of any assertions that follow
2325    * in the chain to be the value of the property descriptor from the original
2326    * target object.
2327    *
2328    *     expect({a: 1}).to.have.ownPropertyDescriptor('a')
2329    *       .that.has.property('enumerable', true);
2330    *
2331    * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a
2332    * custom error message to show when the assertion fails. The message can also
2333    * be given as the second argument to `expect`. When not providing
2334    * `descriptor`, only use the second form.
2335    *
2336    *     // Recommended
2337    *     expect({a: 1}).to.have.ownPropertyDescriptor('a', {
2338    *       configurable: true,
2339    *       enumerable: true,
2340    *       writable: true,
2341    *       value: 2,
2342    *     }, 'nooo why fail??');
2343    *
2344    *     // Recommended
2345    *     expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', {
2346    *       configurable: true,
2347    *       enumerable: true,
2348    *       writable: true,
2349    *       value: 2,
2350    *     });
2351    *
2352    *     // Recommended
2353    *     expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b');
2354    *
2355    *     // Not recommended
2356    *     expect({a: 1})
2357    *       .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??');
2358    *
2359    * The above assertion isn't the same thing as not providing `descriptor`.
2360    * Instead, it's asserting that the target object has a `b` property
2361    * descriptor that's deeply equal to `undefined`.
2362    *
2363    * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with
2364    * `.ownPropertyDescriptor`.
2365    *
2366    * @name ownPropertyDescriptor
2367    * @alias haveOwnPropertyDescriptor
2368    * @param {String} name
2369    * @param {Object} descriptor _optional_
2370    * @param {String} msg _optional_
2371    * @namespace BDD
2372    * @api public
2373    */
2374
2375   function assertOwnPropertyDescriptor (name, descriptor, msg) {
2376     if (typeof descriptor === 'string') {
2377       msg = descriptor;
2378       descriptor = null;
2379     }
2380     if (msg) flag(this, 'message', msg);
2381     var obj = flag(this, 'object');
2382     var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);
2383     if (actualDescriptor && descriptor) {
2384       this.assert(
2385           _.eql(descriptor, actualDescriptor)
2386         , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)
2387         , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)
2388         , descriptor
2389         , actualDescriptor
2390         , true
2391       );
2392     } else {
2393       this.assert(
2394           actualDescriptor
2395         , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)
2396         , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)
2397       );
2398     }
2399     flag(this, 'object', actualDescriptor);
2400   }
2401
2402   Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);
2403   Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);
2404
2405   /**
2406    * ### .lengthOf(n[, msg])
2407    *
2408    * Asserts that the target's `length` or `size` is equal to the given number
2409    * `n`.
2410    *
2411    *     expect([1, 2, 3]).to.have.lengthOf(3);
2412    *     expect('foo').to.have.lengthOf(3);
2413    *     expect(new Set([1, 2, 3])).to.have.lengthOf(3);
2414    *     expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3);
2415    *
2416    * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often
2417    * best to assert that the target's `length` property is equal to its expected
2418    * value, rather than not equal to one of many unexpected values.
2419    *
2420    *     expect('foo').to.have.lengthOf(3); // Recommended
2421    *     expect('foo').to.not.have.lengthOf(4); // Not recommended
2422    *
2423    * `.lengthOf` accepts an optional `msg` argument which is a custom error
2424    * message to show when the assertion fails. The message can also be given as
2425    * the second argument to `expect`.
2426    *
2427    *     expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??');
2428    *     expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2);
2429    *
2430    * `.lengthOf` can also be used as a language chain, causing all `.above`,
2431    * `.below`, `.least`, `.most`, and `.within` assertions that follow in the
2432    * chain to use the target's `length` property as the target. However, it's
2433    * often best to assert that the target's `length` property is equal to its
2434    * expected length, rather than asserting that its `length` property falls
2435    * within some range of values.
2436    *
2437    *     // Recommended
2438    *     expect([1, 2, 3]).to.have.lengthOf(3);
2439    *
2440    *     // Not recommended
2441    *     expect([1, 2, 3]).to.have.lengthOf.above(2);
2442    *     expect([1, 2, 3]).to.have.lengthOf.below(4);
2443    *     expect([1, 2, 3]).to.have.lengthOf.at.least(3);
2444    *     expect([1, 2, 3]).to.have.lengthOf.at.most(3);
2445    *     expect([1, 2, 3]).to.have.lengthOf.within(2,4);
2446    *
2447    * Due to a compatibility issue, the alias `.length` can't be chained directly
2448    * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used
2449    * interchangeably with `.lengthOf` in every situation. It's recommended to
2450    * always use `.lengthOf` instead of `.length`.
2451    *
2452    *     expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error
2453    *     expect([1, 2, 3]).to.have.a.lengthOf(3);  // passes as expected
2454    *
2455    * @name lengthOf
2456    * @alias length
2457    * @param {Number} n
2458    * @param {String} msg _optional_
2459    * @namespace BDD
2460    * @api public
2461    */
2462
2463   function assertLengthChain () {
2464     flag(this, 'doLength', true);
2465   }
2466
2467   function assertLength (n, msg) {
2468     if (msg) flag(this, 'message', msg);
2469     var obj = flag(this, 'object')
2470       , objType = _.type(obj).toLowerCase()
2471       , flagMsg = flag(this, 'message')
2472       , ssfi = flag(this, 'ssfi')
2473       , descriptor = 'length'
2474       , itemsCount;
2475
2476     switch (objType) {
2477       case 'map':
2478       case 'set':
2479         descriptor = 'size';
2480         itemsCount = obj.size;
2481         break;
2482       default:
2483         new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
2484         itemsCount = obj.length;
2485     }
2486
2487     this.assert(
2488         itemsCount == n
2489       , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}'
2490       , 'expected #{this} to not have a ' + descriptor + ' of #{act}'
2491       , n
2492       , itemsCount
2493     );
2494   }
2495
2496   Assertion.addChainableMethod('length', assertLength, assertLengthChain);
2497   Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain);
2498
2499   /**
2500    * ### .match(re[, msg])
2501    *
2502    * Asserts that the target matches the given regular expression `re`.
2503    *
2504    *     expect('foobar').to.match(/^foo/);
2505    *
2506    * Add `.not` earlier in the chain to negate `.match`.
2507    *
2508    *     expect('foobar').to.not.match(/taco/);
2509    *
2510    * `.match` accepts an optional `msg` argument which is a custom error message
2511    * to show when the assertion fails. The message can also be given as the
2512    * second argument to `expect`.
2513    *
2514    *     expect('foobar').to.match(/taco/, 'nooo why fail??');
2515    *     expect('foobar', 'nooo why fail??').to.match(/taco/);
2516    *
2517    * The alias `.matches` can be used interchangeably with `.match`.
2518    *
2519    * @name match
2520    * @alias matches
2521    * @param {RegExp} re
2522    * @param {String} msg _optional_
2523    * @namespace BDD
2524    * @api public
2525    */
2526   function assertMatch(re, msg) {
2527     if (msg) flag(this, 'message', msg);
2528     var obj = flag(this, 'object');
2529     this.assert(
2530         re.exec(obj)
2531       , 'expected #{this} to match ' + re
2532       , 'expected #{this} not to match ' + re
2533     );
2534   }
2535
2536   Assertion.addMethod('match', assertMatch);
2537   Assertion.addMethod('matches', assertMatch);
2538
2539   /**
2540    * ### .string(str[, msg])
2541    *
2542    * Asserts that the target string contains the given substring `str`.
2543    *
2544    *     expect('foobar').to.have.string('bar');
2545    *
2546    * Add `.not` earlier in the chain to negate `.string`.
2547    *
2548    *     expect('foobar').to.not.have.string('taco');
2549    *
2550    * `.string` accepts an optional `msg` argument which is a custom error
2551    * message to show when the assertion fails. The message can also be given as
2552    * the second argument to `expect`.
2553    *
2554    *     expect('foobar').to.have.string('taco', 'nooo why fail??');
2555    *     expect('foobar', 'nooo why fail??').to.have.string('taco');
2556    *
2557    * @name string
2558    * @param {String} str
2559    * @param {String} msg _optional_
2560    * @namespace BDD
2561    * @api public
2562    */
2563
2564   Assertion.addMethod('string', function (str, msg) {
2565     if (msg) flag(this, 'message', msg);
2566     var obj = flag(this, 'object')
2567       , flagMsg = flag(this, 'message')
2568       , ssfi = flag(this, 'ssfi');
2569     new Assertion(obj, flagMsg, ssfi, true).is.a('string');
2570
2571     this.assert(
2572         ~obj.indexOf(str)
2573       , 'expected #{this} to contain ' + _.inspect(str)
2574       , 'expected #{this} to not contain ' + _.inspect(str)
2575     );
2576   });
2577
2578   /**
2579    * ### .keys(key1[, key2[, ...]])
2580    *
2581    * Asserts that the target object, array, map, or set has the given keys. Only
2582    * the target's own inherited properties are included in the search.
2583    *
2584    * When the target is an object or array, keys can be provided as one or more
2585    * string arguments, a single array argument, or a single object argument. In
2586    * the latter case, only the keys in the given object matter; the values are
2587    * ignored.
2588    *
2589    *     expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
2590    *     expect(['x', 'y']).to.have.all.keys(0, 1);
2591    *
2592    *     expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']);
2593    *     expect(['x', 'y']).to.have.all.keys([0, 1]);
2594    *
2595    *     expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5
2596    *     expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5
2597    *
2598    * When the target is a map or set, each key must be provided as a separate
2599    * argument.
2600    *
2601    *     expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b');
2602    *     expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b');
2603    *
2604    * Because `.keys` does different things based on the target's type, it's
2605    * important to check the target's type before using `.keys`. See the `.a` doc
2606    * for info on testing a target's type.
2607    *
2608    *     expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b');
2609    *
2610    * By default, strict (`===`) equality is used to compare keys of maps and
2611    * sets. Add `.deep` earlier in the chain to use deep equality instead. See
2612    * the `deep-eql` project page for info on the deep equality algorithm:
2613    * https://github.com/chaijs/deep-eql.
2614    *
2615    *     // Target set deeply (but not strictly) has key `{a: 1}`
2616    *     expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]);
2617    *     expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]);
2618    *
2619    * By default, the target must have all of the given keys and no more. Add
2620    * `.any` earlier in the chain to only require that the target have at least
2621    * one of the given keys. Also, add `.not` earlier in the chain to negate
2622    * `.keys`. It's often best to add `.any` when negating `.keys`, and to use
2623    * `.all` when asserting `.keys` without negation.
2624    *
2625    * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts
2626    * exactly what's expected of the output, whereas `.not.all.keys` creates
2627    * uncertain expectations.
2628    *
2629    *     // Recommended; asserts that target doesn't have any of the given keys
2630    *     expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
2631    *
2632    *     // Not recommended; asserts that target doesn't have all of the given
2633    *     // keys but may or may not have some of them
2634    *     expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd');
2635    *
2636    * When asserting `.keys` without negation, `.all` is preferred because
2637    * `.all.keys` asserts exactly what's expected of the output, whereas
2638    * `.any.keys` creates uncertain expectations.
2639    *
2640    *     // Recommended; asserts that target has all the given keys
2641    *     expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
2642    *
2643    *     // Not recommended; asserts that target has at least one of the given
2644    *     // keys but may or may not have more of them
2645    *     expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
2646    *
2647    * Note that `.all` is used by default when neither `.all` nor `.any` appear
2648    * earlier in the chain. However, it's often best to add `.all` anyway because
2649    * it improves readability.
2650    *
2651    *     // Both assertions are identical
2652    *     expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended
2653    *     expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended
2654    *
2655    * Add `.include` earlier in the chain to require that the target's keys be a
2656    * superset of the expected keys, rather than identical sets.
2657    *
2658    *     // Target object's keys are a superset of ['a', 'b'] but not identical
2659    *     expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');
2660    *     expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');
2661    *
2662    * However, if `.any` and `.include` are combined, only the `.any` takes
2663    * effect. The `.include` is ignored in this case.
2664    *
2665    *     // Both assertions are identical
2666    *     expect({a: 1}).to.have.any.keys('a', 'b');
2667    *     expect({a: 1}).to.include.any.keys('a', 'b');
2668    *
2669    * A custom error message can be given as the second argument to `expect`.
2670    *
2671    *     expect({a: 1}, 'nooo why fail??').to.have.key('b');
2672    *
2673    * The alias `.key` can be used interchangeably with `.keys`.
2674    *
2675    * @name keys
2676    * @alias key
2677    * @param {...String|Array|Object} keys
2678    * @namespace BDD
2679    * @api public
2680    */
2681
2682   function assertKeys (keys) {
2683     var obj = flag(this, 'object')
2684       , objType = _.type(obj)
2685       , keysType = _.type(keys)
2686       , ssfi = flag(this, 'ssfi')
2687       , isDeep = flag(this, 'deep')
2688       , str
2689       , deepStr = ''
2690       , actual
2691       , ok = true
2692       , flagMsg = flag(this, 'message');
2693
2694     flagMsg = flagMsg ? flagMsg + ': ' : '';
2695     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';
2696
2697     if (objType === 'Map' || objType === 'Set') {
2698       deepStr = isDeep ? 'deeply ' : '';
2699       actual = [];
2700
2701       // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach.
2702       obj.forEach(function (val, key) { actual.push(key) });
2703
2704       if (keysType !== 'Array') {
2705         keys = Array.prototype.slice.call(arguments);
2706       }
2707     } else {
2708       actual = _.getOwnEnumerableProperties(obj);
2709
2710       switch (keysType) {
2711         case 'Array':
2712           if (arguments.length > 1) {
2713             throw new AssertionError(mixedArgsMsg, undefined, ssfi);
2714           }
2715           break;
2716         case 'Object':
2717           if (arguments.length > 1) {
2718             throw new AssertionError(mixedArgsMsg, undefined, ssfi);
2719           }
2720           keys = Object.keys(keys);
2721           break;
2722         default:
2723           keys = Array.prototype.slice.call(arguments);
2724       }
2725
2726       // Only stringify non-Symbols because Symbols would become "Symbol()"
2727       keys = keys.map(function (val) {
2728         return typeof val === 'symbol' ? val : String(val);
2729       });
2730     }
2731
2732     if (!keys.length) {
2733       throw new AssertionError(flagMsg + 'keys required', undefined, ssfi);
2734     }
2735
2736     var len = keys.length
2737       , any = flag(this, 'any')
2738       , all = flag(this, 'all')
2739       , expected = keys;
2740
2741     if (!any && !all) {
2742       all = true;
2743     }
2744
2745     // Has any
2746     if (any) {
2747       ok = expected.some(function(expectedKey) {
2748         return actual.some(function(actualKey) {
2749           if (isDeep) {
2750             return _.eql(expectedKey, actualKey);
2751           } else {
2752             return expectedKey === actualKey;
2753           }
2754         });
2755       });
2756     }
2757
2758     // Has all
2759     if (all) {
2760       ok = expected.every(function(expectedKey) {
2761         return actual.some(function(actualKey) {
2762           if (isDeep) {
2763             return _.eql(expectedKey, actualKey);
2764           } else {
2765             return expectedKey === actualKey;
2766           }
2767         });
2768       });
2769
2770       if (!flag(this, 'contains')) {
2771         ok = ok && keys.length == actual.length;
2772       }
2773     }
2774
2775     // Key string
2776     if (len > 1) {
2777       keys = keys.map(function(key) {
2778         return _.inspect(key);
2779       });
2780       var last = keys.pop();
2781       if (all) {
2782         str = keys.join(', ') + ', and ' + last;
2783       }
2784       if (any) {
2785         str = keys.join(', ') + ', or ' + last;
2786       }
2787     } else {
2788       str = _.inspect(keys[0]);
2789     }
2790
2791     // Form
2792     str = (len > 1 ? 'keys ' : 'key ') + str;
2793
2794     // Have / include
2795     str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
2796
2797     // Assertion
2798     this.assert(
2799         ok
2800       , 'expected #{this} to ' + deepStr + str
2801       , 'expected #{this} to not ' + deepStr + str
2802       , expected.slice(0).sort(_.compareByInspect)
2803       , actual.sort(_.compareByInspect)
2804       , true
2805     );
2806   }
2807
2808   Assertion.addMethod('keys', assertKeys);
2809   Assertion.addMethod('key', assertKeys);
2810
2811   /**
2812    * ### .throw([errorLike], [errMsgMatcher], [msg])
2813    *
2814    * When no arguments are provided, `.throw` invokes the target function and
2815    * asserts that an error is thrown.
2816    *
2817    *     var badFn = function () { throw new TypeError('Illegal salmon!'); };
2818    *
2819    *     expect(badFn).to.throw();
2820    *
2821    * When one argument is provided, and it's an error constructor, `.throw`
2822    * invokes the target function and asserts that an error is thrown that's an
2823    * instance of that error constructor.
2824    *
2825    *     var badFn = function () { throw new TypeError('Illegal salmon!'); };
2826    *
2827    *     expect(badFn).to.throw(TypeError);
2828    *
2829    * When one argument is provided, and it's an error instance, `.throw` invokes
2830    * the target function and asserts that an error is thrown that's strictly
2831    * (`===`) equal to that error instance.
2832    *
2833    *     var err = new TypeError('Illegal salmon!');
2834    *     var badFn = function () { throw err; };
2835    *
2836    *     expect(badFn).to.throw(err);
2837    *
2838    * When one argument is provided, and it's a string, `.throw` invokes the
2839    * target function and asserts that an error is thrown with a message that
2840    * contains that string.
2841    *
2842    *     var badFn = function () { throw new TypeError('Illegal salmon!'); };
2843    *
2844    *     expect(badFn).to.throw('salmon');
2845    *
2846    * When one argument is provided, and it's a regular expression, `.throw`
2847    * invokes the target function and asserts that an error is thrown with a
2848    * message that matches that regular expression.
2849    *
2850    *     var badFn = function () { throw new TypeError('Illegal salmon!'); };
2851    *
2852    *     expect(badFn).to.throw(/salmon/);
2853    *
2854    * When two arguments are provided, and the first is an error instance or
2855    * constructor, and the second is a string or regular expression, `.throw`
2856    * invokes the function and asserts that an error is thrown that fulfills both
2857    * conditions as described above.
2858    *
2859    *     var err = new TypeError('Illegal salmon!');
2860    *     var badFn = function () { throw err; };
2861    *
2862    *     expect(badFn).to.throw(TypeError, 'salmon');
2863    *     expect(badFn).to.throw(TypeError, /salmon/);
2864    *     expect(badFn).to.throw(err, 'salmon');
2865    *     expect(badFn).to.throw(err, /salmon/);
2866    *
2867    * Add `.not` earlier in the chain to negate `.throw`.
2868    *
2869    *     var goodFn = function () {};
2870    *
2871    *     expect(goodFn).to.not.throw();
2872    *
2873    * However, it's dangerous to negate `.throw` when providing any arguments.
2874    * The problem is that it creates uncertain expectations by asserting that the
2875    * target either doesn't throw an error, or that it throws an error but of a
2876    * different type than the given type, or that it throws an error of the given
2877    * type but with a message that doesn't include the given string. It's often
2878    * best to identify the exact output that's expected, and then write an
2879    * assertion that only accepts that exact output.
2880    *
2881    * When the target isn't expected to throw an error, it's often best to assert
2882    * exactly that.
2883    *
2884    *     var goodFn = function () {};
2885    *
2886    *     expect(goodFn).to.not.throw(); // Recommended
2887    *     expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended
2888    *
2889    * When the target is expected to throw an error, it's often best to assert
2890    * that the error is of its expected type, and has a message that includes an
2891    * expected string, rather than asserting that it doesn't have one of many
2892    * unexpected types, and doesn't have a message that includes some string.
2893    *
2894    *     var badFn = function () { throw new TypeError('Illegal salmon!'); };
2895    *
2896    *     expect(badFn).to.throw(TypeError, 'salmon'); // Recommended
2897    *     expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended
2898    *
2899    * `.throw` changes the target of any assertions that follow in the chain to
2900    * be the error object that's thrown.
2901    *
2902    *     var err = new TypeError('Illegal salmon!');
2903    *     err.code = 42;
2904    *     var badFn = function () { throw err; };
2905    *
2906    *     expect(badFn).to.throw(TypeError).with.property('code', 42);
2907    *
2908    * `.throw` accepts an optional `msg` argument which is a custom error message
2909    * to show when the assertion fails. The message can also be given as the
2910    * second argument to `expect`. When not providing two arguments, always use
2911    * the second form.
2912    *
2913    *     var goodFn = function () {};
2914    *
2915    *     expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??');
2916    *     expect(goodFn, 'nooo why fail??').to.throw();
2917    *
2918    * Due to limitations in ES5, `.throw` may not always work as expected when
2919    * using a transpiler such as Babel or TypeScript. In particular, it may
2920    * produce unexpected results when subclassing the built-in `Error` object and
2921    * then passing the subclassed constructor to `.throw`. See your transpiler's
2922    * docs for details:
2923    *
2924    * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes))
2925    * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work))
2926    *
2927    * Beware of some common mistakes when using the `throw` assertion. One common
2928    * mistake is to accidentally invoke the function yourself instead of letting
2929    * the `throw` assertion invoke the function for you. For example, when
2930    * testing if a function named `fn` throws, provide `fn` instead of `fn()` as
2931    * the target for the assertion.
2932    *
2933    *     expect(fn).to.throw();     // Good! Tests `fn` as desired
2934    *     expect(fn()).to.throw();   // Bad! Tests result of `fn()`, not `fn`
2935    *
2936    * If you need to assert that your function `fn` throws when passed certain
2937    * arguments, then wrap a call to `fn` inside of another function.
2938    *
2939    *     expect(function () { fn(42); }).to.throw();  // Function expression
2940    *     expect(() => fn(42)).to.throw();             // ES6 arrow function
2941    *
2942    * Another common mistake is to provide an object method (or any stand-alone
2943    * function that relies on `this`) as the target of the assertion. Doing so is
2944    * problematic because the `this` context will be lost when the function is
2945    * invoked by `.throw`; there's no way for it to know what `this` is supposed
2946    * to be. There are two ways around this problem. One solution is to wrap the
2947    * method or function call inside of another function. Another solution is to
2948    * use `bind`.
2949    *
2950    *     expect(function () { cat.meow(); }).to.throw();  // Function expression
2951    *     expect(() => cat.meow()).to.throw();             // ES6 arrow function
2952    *     expect(cat.meow.bind(cat)).to.throw();           // Bind
2953    *
2954    * Finally, it's worth mentioning that it's a best practice in JavaScript to
2955    * only throw `Error` and derivatives of `Error` such as `ReferenceError`,
2956    * `TypeError`, and user-defined objects that extend `Error`. No other type of
2957    * value will generate a stack trace when initialized. With that said, the
2958    * `throw` assertion does technically support any type of value being thrown,
2959    * not just `Error` and its derivatives.
2960    *
2961    * The aliases `.throws` and `.Throw` can be used interchangeably with
2962    * `.throw`.
2963    *
2964    * @name throw
2965    * @alias throws
2966    * @alias Throw
2967    * @param {Error|ErrorConstructor} errorLike
2968    * @param {String|RegExp} errMsgMatcher error message
2969    * @param {String} msg _optional_
2970    * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
2971    * @returns error for chaining (null if no error)
2972    * @namespace BDD
2973    * @api public
2974    */
2975
2976   function assertThrows (errorLike, errMsgMatcher, msg) {
2977     if (msg) flag(this, 'message', msg);
2978     var obj = flag(this, 'object')
2979       , ssfi = flag(this, 'ssfi')
2980       , flagMsg = flag(this, 'message')
2981       , negate = flag(this, 'negate') || false;
2982     new Assertion(obj, flagMsg, ssfi, true).is.a('function');
2983
2984     if (errorLike instanceof RegExp || typeof errorLike === 'string') {
2985       errMsgMatcher = errorLike;
2986       errorLike = null;
2987     }
2988
2989     var caughtErr;
2990     try {
2991       obj();
2992     } catch (err) {
2993       caughtErr = err;
2994     }
2995
2996     // If we have the negate flag enabled and at least one valid argument it means we do expect an error
2997     // but we want it to match a given set of criteria
2998     var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined;
2999
3000     // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible
3001     // See Issue #551 and PR #683@GitHub
3002     var everyArgIsDefined = Boolean(errorLike && errMsgMatcher);
3003     var errorLikeFail = false;
3004     var errMsgMatcherFail = false;
3005
3006     // Checking if error was thrown
3007     if (everyArgIsUndefined || !everyArgIsUndefined && !negate) {
3008       // We need this to display results correctly according to their types
3009       var errorLikeString = 'an error';
3010       if (errorLike instanceof Error) {
3011         errorLikeString = '#{exp}';
3012       } else if (errorLike) {
3013         errorLikeString = _.checkError.getConstructorName(errorLike);
3014       }
3015
3016       this.assert(
3017           caughtErr
3018         , 'expected #{this} to throw ' + errorLikeString
3019         , 'expected #{this} to not throw an error but #{act} was thrown'
3020         , errorLike && errorLike.toString()
3021         , (caughtErr instanceof Error ?
3022             caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr &&
3023                                     _.checkError.getConstructorName(caughtErr)))
3024       );
3025     }
3026
3027     if (errorLike && caughtErr) {
3028       // We should compare instances only if `errorLike` is an instance of `Error`
3029       if (errorLike instanceof Error) {
3030         var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike);
3031
3032         if (isCompatibleInstance === negate) {
3033           // These checks were created to ensure we won't fail too soon when we've got both args and a negate
3034           // See Issue #551 and PR #683@GitHub
3035           if (everyArgIsDefined && negate) {
3036             errorLikeFail = true;
3037           } else {
3038             this.assert(
3039                 negate
3040               , 'expected #{this} to throw #{exp} but #{act} was thrown'
3041               , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '')
3042               , errorLike.toString()
3043               , caughtErr.toString()
3044             );
3045           }
3046         }
3047       }
3048
3049       var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike);
3050       if (isCompatibleConstructor === negate) {
3051         if (everyArgIsDefined && negate) {
3052             errorLikeFail = true;
3053         } else {
3054           this.assert(
3055               negate
3056             , 'expected #{this} to throw #{exp} but #{act} was thrown'
3057             , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '')
3058             , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike))
3059             , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr))
3060           );
3061         }
3062       }
3063     }
3064
3065     if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) {
3066       // Here we check compatible messages
3067       var placeholder = 'including';
3068       if (errMsgMatcher instanceof RegExp) {
3069         placeholder = 'matching'
3070       }
3071
3072       var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher);
3073       if (isCompatibleMessage === negate) {
3074         if (everyArgIsDefined && negate) {
3075             errMsgMatcherFail = true;
3076         } else {
3077           this.assert(
3078             negate
3079             , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}'
3080             , 'expected #{this} to throw error not ' + placeholder + ' #{exp}'
3081             ,  errMsgMatcher
3082             ,  _.checkError.getMessage(caughtErr)
3083           );
3084         }
3085       }
3086     }
3087
3088     // If both assertions failed and both should've matched we throw an error
3089     if (errorLikeFail && errMsgMatcherFail) {
3090       this.assert(
3091         negate
3092         , 'expected #{this} to throw #{exp} but #{act} was thrown'
3093         , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '')
3094         , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike))
3095         , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr))
3096       );
3097     }
3098
3099     flag(this, 'object', caughtErr);
3100   };
3101
3102   Assertion.addMethod('throw', assertThrows);
3103   Assertion.addMethod('throws', assertThrows);
3104   Assertion.addMethod('Throw', assertThrows);
3105
3106   /**
3107    * ### .respondTo(method[, msg])
3108    *
3109    * When the target is a non-function object, `.respondTo` asserts that the
3110    * target has a method with the given name `method`. The method can be own or
3111    * inherited, and it can be enumerable or non-enumerable.
3112    *
3113    *     function Cat () {}
3114    *     Cat.prototype.meow = function () {};
3115    *
3116    *     expect(new Cat()).to.respondTo('meow');
3117    *
3118    * When the target is a function, `.respondTo` asserts that the target's
3119    * `prototype` property has a method with the given name `method`. Again, the
3120    * method can be own or inherited, and it can be enumerable or non-enumerable.
3121    *
3122    *     function Cat () {}
3123    *     Cat.prototype.meow = function () {};
3124    *
3125    *     expect(Cat).to.respondTo('meow');
3126    *
3127    * Add `.itself` earlier in the chain to force `.respondTo` to treat the
3128    * target as a non-function object, even if it's a function. Thus, it asserts
3129    * that the target has a method with the given name `method`, rather than
3130    * asserting that the target's `prototype` property has a method with the
3131    * given name `method`.
3132    *
3133    *     function Cat () {}
3134    *     Cat.prototype.meow = function () {};
3135    *     Cat.hiss = function () {};
3136    *
3137    *     expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
3138    *
3139    * When not adding `.itself`, it's important to check the target's type before
3140    * using `.respondTo`. See the `.a` doc for info on checking a target's type.
3141    *
3142    *     function Cat () {}
3143    *     Cat.prototype.meow = function () {};
3144    *
3145    *     expect(new Cat()).to.be.an('object').that.respondsTo('meow');
3146    *
3147    * Add `.not` earlier in the chain to negate `.respondTo`.
3148    *
3149    *     function Dog () {}
3150    *     Dog.prototype.bark = function () {};
3151    *
3152    *     expect(new Dog()).to.not.respondTo('meow');
3153    *
3154    * `.respondTo` accepts an optional `msg` argument which is a custom error
3155    * message to show when the assertion fails. The message can also be given as
3156    * the second argument to `expect`.
3157    *
3158    *     expect({}).to.respondTo('meow', 'nooo why fail??');
3159    *     expect({}, 'nooo why fail??').to.respondTo('meow');
3160    *
3161    * The alias `.respondsTo` can be used interchangeably with `.respondTo`.
3162    *
3163    * @name respondTo
3164    * @alias respondsTo
3165    * @param {String} method
3166    * @param {String} msg _optional_
3167    * @namespace BDD
3168    * @api public
3169    */
3170
3171   function respondTo (method, msg) {
3172     if (msg) flag(this, 'message', msg);
3173     var obj = flag(this, 'object')
3174       , itself = flag(this, 'itself')
3175       , context = ('function' === typeof obj && !itself)
3176         ? obj.prototype[method]
3177         : obj[method];
3178
3179     this.assert(
3180         'function' === typeof context
3181       , 'expected #{this} to respond to ' + _.inspect(method)
3182       , 'expected #{this} to not respond to ' + _.inspect(method)
3183     );
3184   }
3185
3186   Assertion.addMethod('respondTo', respondTo);
3187   Assertion.addMethod('respondsTo', respondTo);
3188
3189   /**
3190    * ### .itself
3191    *
3192    * Forces all `.respondTo` assertions that follow in the chain to behave as if
3193    * the target is a non-function object, even if it's a function. Thus, it
3194    * causes `.respondTo` to assert that the target has a method with the given
3195    * name, rather than asserting that the target's `prototype` property has a
3196    * method with the given name.
3197    *
3198    *     function Cat () {}
3199    *     Cat.prototype.meow = function () {};
3200    *     Cat.hiss = function () {};
3201    *
3202    *     expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
3203    *
3204    * @name itself
3205    * @namespace BDD
3206    * @api public
3207    */
3208
3209   Assertion.addProperty('itself', function () {
3210     flag(this, 'itself', true);
3211   });
3212
3213   /**
3214    * ### .satisfy(matcher[, msg])
3215    *
3216    * Invokes the given `matcher` function with the target being passed as the
3217    * first argument, and asserts that the value returned is truthy.
3218    *
3219    *     expect(1).to.satisfy(function(num) {
3220    *       return num > 0;
3221    *     });
3222    *
3223    * Add `.not` earlier in the chain to negate `.satisfy`.
3224    *
3225    *     expect(1).to.not.satisfy(function(num) {
3226    *       return num > 2;
3227    *     });
3228    *
3229    * `.satisfy` accepts an optional `msg` argument which is a custom error
3230    * message to show when the assertion fails. The message can also be given as
3231    * the second argument to `expect`.
3232    *
3233    *     expect(1).to.satisfy(function(num) {
3234    *       return num > 2;
3235    *     }, 'nooo why fail??');
3236    *
3237    *     expect(1, 'nooo why fail??').to.satisfy(function(num) {
3238    *       return num > 2;
3239    *     });
3240    *
3241    * The alias `.satisfies` can be used interchangeably with `.satisfy`.
3242    *
3243    * @name satisfy
3244    * @alias satisfies
3245    * @param {Function} matcher
3246    * @param {String} msg _optional_
3247    * @namespace BDD
3248    * @api public
3249    */
3250
3251   function satisfy (matcher, msg) {
3252     if (msg) flag(this, 'message', msg);
3253     var obj = flag(this, 'object');
3254     var result = matcher(obj);
3255     this.assert(
3256         result
3257       , 'expected #{this} to satisfy ' + _.objDisplay(matcher)
3258       , 'expected #{this} to not satisfy' + _.objDisplay(matcher)
3259       , flag(this, 'negate') ? false : true
3260       , result
3261     );
3262   }
3263
3264   Assertion.addMethod('satisfy', satisfy);
3265   Assertion.addMethod('satisfies', satisfy);
3266
3267   /**
3268    * ### .closeTo(expected, delta[, msg])
3269    *
3270    * Asserts that the target is a number that's within a given +/- `delta` range
3271    * of the given number `expected`. However, it's often best to assert that the
3272    * target is equal to its expected value.
3273    *
3274    *     // Recommended
3275    *     expect(1.5).to.equal(1.5);
3276    *
3277    *     // Not recommended
3278    *     expect(1.5).to.be.closeTo(1, 0.5);
3279    *     expect(1.5).to.be.closeTo(2, 0.5);
3280    *     expect(1.5).to.be.closeTo(1, 1);
3281    *
3282    * Add `.not` earlier in the chain to negate `.closeTo`.
3283    *
3284    *     expect(1.5).to.equal(1.5); // Recommended
3285    *     expect(1.5).to.not.be.closeTo(3, 1); // Not recommended
3286    *
3287    * `.closeTo` accepts an optional `msg` argument which is a custom error
3288    * message to show when the assertion fails. The message can also be given as
3289    * the second argument to `expect`.
3290    *
3291    *     expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??');
3292    *     expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1);
3293    *
3294    * The alias `.approximately` can be used interchangeably with `.closeTo`.
3295    *
3296    * @name closeTo
3297    * @alias approximately
3298    * @param {Number} expected
3299    * @param {Number} delta
3300    * @param {String} msg _optional_
3301    * @namespace BDD
3302    * @api public
3303    */
3304
3305   function closeTo(expected, delta, msg) {
3306     if (msg) flag(this, 'message', msg);
3307     var obj = flag(this, 'object')
3308       , flagMsg = flag(this, 'message')
3309       , ssfi = flag(this, 'ssfi');
3310
3311     new Assertion(obj, flagMsg, ssfi, true).is.a('number');
3312     if (typeof expected !== 'number' || typeof delta !== 'number') {
3313       flagMsg = flagMsg ? flagMsg + ': ' : '';
3314       throw new AssertionError(
3315           flagMsg + 'the arguments to closeTo or approximately must be numbers',
3316           undefined,
3317           ssfi
3318       );
3319     }
3320
3321     this.assert(
3322         Math.abs(obj - expected) <= delta
3323       , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
3324       , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
3325     );
3326   }
3327
3328   Assertion.addMethod('closeTo', closeTo);
3329   Assertion.addMethod('approximately', closeTo);
3330
3331   // Note: Duplicates are ignored if testing for inclusion instead of sameness.
3332   function isSubsetOf(subset, superset, cmp, contains, ordered) {
3333     if (!contains) {
3334       if (subset.length !== superset.length) return false;
3335       superset = superset.slice();
3336     }
3337
3338     return subset.every(function(elem, idx) {
3339       if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx];
3340
3341       if (!cmp) {
3342         var matchIdx = superset.indexOf(elem);
3343         if (matchIdx === -1) return false;
3344
3345         // Remove match from superset so not counted twice if duplicate in subset.
3346         if (!contains) superset.splice(matchIdx, 1);
3347         return true;
3348       }
3349
3350       return superset.some(function(elem2, matchIdx) {
3351         if (!cmp(elem, elem2)) return false;
3352
3353         // Remove match from superset so not counted twice if duplicate in subset.
3354         if (!contains) superset.splice(matchIdx, 1);
3355         return true;
3356       });
3357     });
3358   }
3359
3360   /**
3361    * ### .members(set[, msg])
3362    *
3363    * Asserts that the target array has the same members as the given array
3364    * `set`.
3365    *
3366    *     expect([1, 2, 3]).to.have.members([2, 1, 3]);
3367    *     expect([1, 2, 2]).to.have.members([2, 1, 2]);
3368    *
3369    * By default, members are compared using strict (`===`) equality. Add `.deep`
3370    * earlier in the chain to use deep equality instead. See the `deep-eql`
3371    * project page for info on the deep equality algorithm:
3372    * https://github.com/chaijs/deep-eql.
3373    *
3374    *     // Target array deeply (but not strictly) has member `{a: 1}`
3375    *     expect([{a: 1}]).to.have.deep.members([{a: 1}]);
3376    *     expect([{a: 1}]).to.not.have.members([{a: 1}]);
3377    *
3378    * By default, order doesn't matter. Add `.ordered` earlier in the chain to
3379    * require that members appear in the same order.
3380    *
3381    *     expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]);
3382    *     expect([1, 2, 3]).to.have.members([2, 1, 3])
3383    *       .but.not.ordered.members([2, 1, 3]);
3384    *
3385    * By default, both arrays must be the same size. Add `.include` earlier in
3386    * the chain to require that the target's members be a superset of the
3387    * expected members. Note that duplicates are ignored in the subset when
3388    * `.include` is added.
3389    *
3390    *     // Target array is a superset of [1, 2] but not identical
3391    *     expect([1, 2, 3]).to.include.members([1, 2]);
3392    *     expect([1, 2, 3]).to.not.have.members([1, 2]);
3393    *
3394    *     // Duplicates in the subset are ignored
3395    *     expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
3396    *
3397    * `.deep`, `.ordered`, and `.include` can all be combined. However, if
3398    * `.include` and `.ordered` are combined, the ordering begins at the start of
3399    * both arrays.
3400    *
3401    *     expect([{a: 1}, {b: 2}, {c: 3}])
3402    *       .to.include.deep.ordered.members([{a: 1}, {b: 2}])
3403    *       .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]);
3404    *
3405    * Add `.not` earlier in the chain to negate `.members`. However, it's
3406    * dangerous to do so. The problem is that it creates uncertain expectations
3407    * by asserting that the target array doesn't have all of the same members as
3408    * the given array `set` but may or may not have some of them. It's often best
3409    * to identify the exact output that's expected, and then write an assertion
3410    * that only accepts that exact output.
3411    *
3412    *     expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended
3413    *     expect([1, 2]).to.not.have.members([3, 4]); // Not recommended
3414    *
3415    * `.members` accepts an optional `msg` argument which is a custom error
3416    * message to show when the assertion fails. The message can also be given as
3417    * the second argument to `expect`.
3418    *
3419    *     expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??');
3420    *     expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]);
3421    *
3422    * @name members
3423    * @param {Array} set
3424    * @param {String} msg _optional_
3425    * @namespace BDD
3426    * @api public
3427    */
3428
3429   Assertion.addMethod('members', function (subset, msg) {
3430     if (msg) flag(this, 'message', msg);
3431     var obj = flag(this, 'object')
3432       , flagMsg = flag(this, 'message')
3433       , ssfi = flag(this, 'ssfi');
3434
3435     new Assertion(obj, flagMsg, ssfi, true).to.be.an('array');
3436     new Assertion(subset, flagMsg, ssfi, true).to.be.an('array');
3437
3438     var contains = flag(this, 'contains');
3439     var ordered = flag(this, 'ordered');
3440
3441     var subject, failMsg, failNegateMsg;
3442
3443     if (contains) {
3444       subject = ordered ? 'an ordered superset' : 'a superset';
3445       failMsg = 'expected #{this} to be ' + subject + ' of #{exp}';
3446       failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}';
3447     } else {
3448       subject = ordered ? 'ordered members' : 'members';
3449       failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}';
3450       failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}';
3451     }
3452
3453     var cmp = flag(this, 'deep') ? _.eql : undefined;
3454
3455     this.assert(
3456         isSubsetOf(subset, obj, cmp, contains, ordered)
3457       , failMsg
3458       , failNegateMsg
3459       , subset
3460       , obj
3461       , true
3462     );
3463   });
3464
3465   /**
3466    * ### .oneOf(list[, msg])
3467    *
3468    * Asserts that the target is a member of the given array `list`. However,
3469    * it's often best to assert that the target is equal to its expected value.
3470    *
3471    *     expect(1).to.equal(1); // Recommended
3472    *     expect(1).to.be.oneOf([1, 2, 3]); // Not recommended
3473    *
3474    * Comparisons are performed using strict (`===`) equality.
3475    *
3476    * Add `.not` earlier in the chain to negate `.oneOf`.
3477    *
3478    *     expect(1).to.equal(1); // Recommended
3479    *     expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended
3480    *
3481    * `.oneOf` accepts an optional `msg` argument which is a custom error message
3482    * to show when the assertion fails. The message can also be given as the
3483    * second argument to `expect`.
3484    *
3485    *     expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??');
3486    *     expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]);
3487    *
3488    * @name oneOf
3489    * @param {Array<*>} list
3490    * @param {String} msg _optional_
3491    * @namespace BDD
3492    * @api public
3493    */
3494
3495   function oneOf (list, msg) {
3496     if (msg) flag(this, 'message', msg);
3497     var expected = flag(this, 'object')
3498       , flagMsg = flag(this, 'message')
3499       , ssfi = flag(this, 'ssfi');
3500     new Assertion(list, flagMsg, ssfi, true).to.be.an('array');
3501
3502     this.assert(
3503         list.indexOf(expected) > -1
3504       , 'expected #{this} to be one of #{exp}'
3505       , 'expected #{this} to not be one of #{exp}'
3506       , list
3507       , expected
3508     );
3509   }
3510
3511   Assertion.addMethod('oneOf', oneOf);
3512
3513   /**
3514    * ### .change(subject[, prop[, msg]])
3515    *
3516    * When one argument is provided, `.change` asserts that the given function
3517    * `subject` returns a different value when it's invoked before the target
3518    * function compared to when it's invoked afterward. However, it's often best
3519    * to assert that `subject` is equal to its expected value.
3520    *
3521    *     var dots = ''
3522    *       , addDot = function () { dots += '.'; }
3523    *       , getDots = function () { return dots; };
3524    *
3525    *     // Recommended
3526    *     expect(getDots()).to.equal('');
3527    *     addDot();
3528    *     expect(getDots()).to.equal('.');
3529    *
3530    *     // Not recommended
3531    *     expect(addDot).to.change(getDots);
3532    *
3533    * When two arguments are provided, `.change` asserts that the value of the
3534    * given object `subject`'s `prop` property is different before invoking the
3535    * target function compared to afterward.
3536    *
3537    *     var myObj = {dots: ''}
3538    *       , addDot = function () { myObj.dots += '.'; };
3539    *
3540    *     // Recommended
3541    *     expect(myObj).to.have.property('dots', '');
3542    *     addDot();
3543    *     expect(myObj).to.have.property('dots', '.');
3544    *
3545    *     // Not recommended
3546    *     expect(addDot).to.change(myObj, 'dots');
3547    *
3548    * Strict (`===`) equality is used to compare before and after values.
3549    *
3550    * Add `.not` earlier in the chain to negate `.change`.
3551    *
3552    *     var dots = ''
3553    *       , noop = function () {}
3554    *       , getDots = function () { return dots; };
3555    *
3556    *     expect(noop).to.not.change(getDots);
3557    *
3558    *     var myObj = {dots: ''}
3559    *       , noop = function () {};
3560    *
3561    *     expect(noop).to.not.change(myObj, 'dots');
3562    *
3563    * `.change` accepts an optional `msg` argument which is a custom error
3564    * message to show when the assertion fails. The message can also be given as
3565    * the second argument to `expect`. When not providing two arguments, always
3566    * use the second form.
3567    *
3568    *     var myObj = {dots: ''}
3569    *       , addDot = function () { myObj.dots += '.'; };
3570    *
3571    *     expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??');
3572    *
3573    *     var dots = ''
3574    *       , addDot = function () { dots += '.'; }
3575    *       , getDots = function () { return dots; };
3576    *
3577    *     expect(addDot, 'nooo why fail??').to.not.change(getDots);
3578    *
3579    * `.change` also causes all `.by` assertions that follow in the chain to
3580    * assert how much a numeric subject was increased or decreased by. However,
3581    * it's dangerous to use `.change.by`. The problem is that it creates
3582    * uncertain expectations by asserting that the subject either increases by
3583    * the given delta, or that it decreases by the given delta. It's often best
3584    * to identify the exact output that's expected, and then write an assertion
3585    * that only accepts that exact output.
3586    *
3587    *     var myObj = {val: 1}
3588    *       , addTwo = function () { myObj.val += 2; }
3589    *       , subtractTwo = function () { myObj.val -= 2; };
3590    *
3591    *     expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
3592    *     expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended
3593    *
3594    *     expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
3595    *     expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended
3596    *
3597    * The alias `.changes` can be used interchangeably with `.change`.
3598    *
3599    * @name change
3600    * @alias changes
3601    * @param {String} subject
3602    * @param {String} prop name _optional_
3603    * @param {String} msg _optional_
3604    * @namespace BDD
3605    * @api public
3606    */
3607
3608   function assertChanges (subject, prop, msg) {
3609     if (msg) flag(this, 'message', msg);
3610     var fn = flag(this, 'object')
3611       , flagMsg = flag(this, 'message')
3612       , ssfi = flag(this, 'ssfi');
3613     new Assertion(fn, flagMsg, ssfi, true).is.a('function');
3614
3615     var initial;
3616     if (!prop) {
3617       new Assertion(subject, flagMsg, ssfi, true).is.a('function');
3618       initial = subject();
3619     } else {
3620       new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
3621       initial = subject[prop];
3622     }
3623
3624     fn();
3625
3626     var final = prop === undefined || prop === null ? subject() : subject[prop];
3627     var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
3628
3629     // This gets flagged because of the .by(delta) assertion
3630     flag(this, 'deltaMsgObj', msgObj);
3631     flag(this, 'initialDeltaValue', initial);
3632     flag(this, 'finalDeltaValue', final);
3633     flag(this, 'deltaBehavior', 'change');
3634     flag(this, 'realDelta', final !== initial);
3635
3636     this.assert(
3637       initial !== final
3638       , 'expected ' + msgObj + ' to change'
3639       , 'expected ' + msgObj + ' to not change'
3640     );
3641   }
3642
3643   Assertion.addMethod('change', assertChanges);
3644   Assertion.addMethod('changes', assertChanges);
3645
3646   /**
3647    * ### .increase(subject[, prop[, msg]])
3648    *
3649    * When one argument is provided, `.increase` asserts that the given function
3650    * `subject` returns a greater number when it's invoked after invoking the
3651    * target function compared to when it's invoked beforehand. `.increase` also
3652    * causes all `.by` assertions that follow in the chain to assert how much
3653    * greater of a number is returned. It's often best to assert that the return
3654    * value increased by the expected amount, rather than asserting it increased
3655    * by any amount.
3656    *
3657    *     var val = 1
3658    *       , addTwo = function () { val += 2; }
3659    *       , getVal = function () { return val; };
3660    *
3661    *     expect(addTwo).to.increase(getVal).by(2); // Recommended
3662    *     expect(addTwo).to.increase(getVal); // Not recommended
3663    *
3664    * When two arguments are provided, `.increase` asserts that the value of the
3665    * given object `subject`'s `prop` property is greater after invoking the
3666    * target function compared to beforehand.
3667    *
3668    *     var myObj = {val: 1}
3669    *       , addTwo = function () { myObj.val += 2; };
3670    *
3671    *     expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
3672    *     expect(addTwo).to.increase(myObj, 'val'); // Not recommended
3673    *
3674    * Add `.not` earlier in the chain to negate `.increase`. However, it's
3675    * dangerous to do so. The problem is that it creates uncertain expectations
3676    * by asserting that the subject either decreases, or that it stays the same.
3677    * It's often best to identify the exact output that's expected, and then
3678    * write an assertion that only accepts that exact output.
3679    *
3680    * When the subject is expected to decrease, it's often best to assert that it
3681    * decreased by the expected amount.
3682    *
3683    *     var myObj = {val: 1}
3684    *       , subtractTwo = function () { myObj.val -= 2; };
3685    *
3686    *     expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
3687    *     expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended
3688    *
3689    * When the subject is expected to stay the same, it's often best to assert
3690    * exactly that.
3691    *
3692    *     var myObj = {val: 1}
3693    *       , noop = function () {};
3694    *
3695    *     expect(noop).to.not.change(myObj, 'val'); // Recommended
3696    *     expect(noop).to.not.increase(myObj, 'val'); // Not recommended
3697    *
3698    * `.increase` accepts an optional `msg` argument which is a custom error
3699    * message to show when the assertion fails. The message can also be given as
3700    * the second argument to `expect`. When not providing two arguments, always
3701    * use the second form.
3702    *
3703    *     var myObj = {val: 1}
3704    *       , noop = function () {};
3705    *
3706    *     expect(noop).to.increase(myObj, 'val', 'nooo why fail??');
3707    *
3708    *     var val = 1
3709    *       , noop = function () {}
3710    *       , getVal = function () { return val; };
3711    *
3712    *     expect(noop, 'nooo why fail??').to.increase(getVal);
3713    *
3714    * The alias `.increases` can be used interchangeably with `.increase`.
3715    *
3716    * @name increase
3717    * @alias increases
3718    * @param {String|Function} subject
3719    * @param {String} prop name _optional_
3720    * @param {String} msg _optional_
3721    * @namespace BDD
3722    * @api public
3723    */
3724
3725   function assertIncreases (subject, prop, msg) {
3726     if (msg) flag(this, 'message', msg);
3727     var fn = flag(this, 'object')
3728       , flagMsg = flag(this, 'message')
3729       , ssfi = flag(this, 'ssfi');
3730     new Assertion(fn, flagMsg, ssfi, true).is.a('function');
3731
3732     var initial;
3733     if (!prop) {
3734       new Assertion(subject, flagMsg, ssfi, true).is.a('function');
3735       initial = subject();
3736     } else {
3737       new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
3738       initial = subject[prop];
3739     }
3740
3741     // Make sure that the target is a number
3742     new Assertion(initial, flagMsg, ssfi, true).is.a('number');
3743
3744     fn();
3745
3746     var final = prop === undefined || prop === null ? subject() : subject[prop];
3747     var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
3748
3749     flag(this, 'deltaMsgObj', msgObj);
3750     flag(this, 'initialDeltaValue', initial);
3751     flag(this, 'finalDeltaValue', final);
3752     flag(this, 'deltaBehavior', 'increase');
3753     flag(this, 'realDelta', final - initial);
3754
3755     this.assert(
3756       final - initial > 0
3757       , 'expected ' + msgObj + ' to increase'
3758       , 'expected ' + msgObj + ' to not increase'
3759     );
3760   }
3761
3762   Assertion.addMethod('increase', assertIncreases);
3763   Assertion.addMethod('increases', assertIncreases);
3764
3765   /**
3766    * ### .decrease(subject[, prop[, msg]])
3767    *
3768    * When one argument is provided, `.decrease` asserts that the given function
3769    * `subject` returns a lesser number when it's invoked after invoking the
3770    * target function compared to when it's invoked beforehand. `.decrease` also
3771    * causes all `.by` assertions that follow in the chain to assert how much
3772    * lesser of a number is returned. It's often best to assert that the return
3773    * value decreased by the expected amount, rather than asserting it decreased
3774    * by any amount.
3775    *
3776    *     var val = 1
3777    *       , subtractTwo = function () { val -= 2; }
3778    *       , getVal = function () { return val; };
3779    *
3780    *     expect(subtractTwo).to.decrease(getVal).by(2); // Recommended
3781    *     expect(subtractTwo).to.decrease(getVal); // Not recommended
3782    *
3783    * When two arguments are provided, `.decrease` asserts that the value of the
3784    * given object `subject`'s `prop` property is lesser after invoking the
3785    * target function compared to beforehand.
3786    *
3787    *     var myObj = {val: 1}
3788    *       , subtractTwo = function () { myObj.val -= 2; };
3789    *
3790    *     expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
3791    *     expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended
3792    *
3793    * Add `.not` earlier in the chain to negate `.decrease`. However, it's
3794    * dangerous to do so. The problem is that it creates uncertain expectations
3795    * by asserting that the subject either increases, or that it stays the same.
3796    * It's often best to identify the exact output that's expected, and then
3797    * write an assertion that only accepts that exact output.
3798    *
3799    * When the subject is expected to increase, it's often best to assert that it
3800    * increased by the expected amount.
3801    *
3802    *     var myObj = {val: 1}
3803    *       , addTwo = function () { myObj.val += 2; };
3804    *
3805    *     expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
3806    *     expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended
3807    *
3808    * When the subject is expected to stay the same, it's often best to assert
3809    * exactly that.
3810    *
3811    *     var myObj = {val: 1}
3812    *       , noop = function () {};
3813    *
3814    *     expect(noop).to.not.change(myObj, 'val'); // Recommended
3815    *     expect(noop).to.not.decrease(myObj, 'val'); // Not recommended
3816    *
3817    * `.decrease` accepts an optional `msg` argument which is a custom error
3818    * message to show when the assertion fails. The message can also be given as
3819    * the second argument to `expect`. When not providing two arguments, always
3820    * use the second form.
3821    *
3822    *     var myObj = {val: 1}
3823    *       , noop = function () {};
3824    *
3825    *     expect(noop).to.decrease(myObj, 'val', 'nooo why fail??');
3826    *
3827    *     var val = 1
3828    *       , noop = function () {}
3829    *       , getVal = function () { return val; };
3830    *
3831    *     expect(noop, 'nooo why fail??').to.decrease(getVal);
3832    *
3833    * The alias `.decreases` can be used interchangeably with `.decrease`.
3834    *
3835    * @name decrease
3836    * @alias decreases
3837    * @param {String|Function} subject
3838    * @param {String} prop name _optional_
3839    * @param {String} msg _optional_
3840    * @namespace BDD
3841    * @api public
3842    */
3843
3844   function assertDecreases (subject, prop, msg) {
3845     if (msg) flag(this, 'message', msg);
3846     var fn = flag(this, 'object')
3847       , flagMsg = flag(this, 'message')
3848       , ssfi = flag(this, 'ssfi');
3849     new Assertion(fn, flagMsg, ssfi, true).is.a('function');
3850
3851     var initial;
3852     if (!prop) {
3853       new Assertion(subject, flagMsg, ssfi, true).is.a('function');
3854       initial = subject();
3855     } else {
3856       new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
3857       initial = subject[prop];
3858     }
3859
3860     // Make sure that the target is a number
3861     new Assertion(initial, flagMsg, ssfi, true).is.a('number');
3862
3863     fn();
3864
3865     var final = prop === undefined || prop === null ? subject() : subject[prop];
3866     var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
3867
3868     flag(this, 'deltaMsgObj', msgObj);
3869     flag(this, 'initialDeltaValue', initial);
3870     flag(this, 'finalDeltaValue', final);
3871     flag(this, 'deltaBehavior', 'decrease');
3872     flag(this, 'realDelta', initial - final);
3873
3874     this.assert(
3875       final - initial < 0
3876       , 'expected ' + msgObj + ' to decrease'
3877       , 'expected ' + msgObj + ' to not decrease'
3878     );
3879   }
3880
3881   Assertion.addMethod('decrease', assertDecreases);
3882   Assertion.addMethod('decreases', assertDecreases);
3883
3884   /**
3885    * ### .by(delta[, msg])
3886    *
3887    * When following an `.increase` assertion in the chain, `.by` asserts that
3888    * the subject of the `.increase` assertion increased by the given `delta`.
3889    *
3890    *     var myObj = {val: 1}
3891    *       , addTwo = function () { myObj.val += 2; };
3892    *
3893    *     expect(addTwo).to.increase(myObj, 'val').by(2);
3894    *
3895    * When following a `.decrease` assertion in the chain, `.by` asserts that the
3896    * subject of the `.decrease` assertion decreased by the given `delta`.
3897    *
3898    *     var myObj = {val: 1}
3899    *       , subtractTwo = function () { myObj.val -= 2; };
3900    *
3901    *     expect(subtractTwo).to.decrease(myObj, 'val').by(2);
3902    *
3903    * When following a `.change` assertion in the chain, `.by` asserts that the
3904    * subject of the `.change` assertion either increased or decreased by the
3905    * given `delta`. However, it's dangerous to use `.change.by`. The problem is
3906    * that it creates uncertain expectations. It's often best to identify the
3907    * exact output that's expected, and then write an assertion that only accepts
3908    * that exact output.
3909    *
3910    *     var myObj = {val: 1}
3911    *       , addTwo = function () { myObj.val += 2; }
3912    *       , subtractTwo = function () { myObj.val -= 2; };
3913    *
3914    *     expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
3915    *     expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended
3916    *
3917    *     expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
3918    *     expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended
3919    *
3920    * Add `.not` earlier in the chain to negate `.by`. However, it's often best
3921    * to assert that the subject changed by its expected delta, rather than
3922    * asserting that it didn't change by one of countless unexpected deltas.
3923    *
3924    *     var myObj = {val: 1}
3925    *       , addTwo = function () { myObj.val += 2; };
3926    *
3927    *     // Recommended
3928    *     expect(addTwo).to.increase(myObj, 'val').by(2);
3929    *
3930    *     // Not recommended
3931    *     expect(addTwo).to.increase(myObj, 'val').but.not.by(3);
3932    *
3933    * `.by` accepts an optional `msg` argument which is a custom error message to
3934    * show when the assertion fails. The message can also be given as the second
3935    * argument to `expect`.
3936    *
3937    *     var myObj = {val: 1}
3938    *       , addTwo = function () { myObj.val += 2; };
3939    *
3940    *     expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??');
3941    *     expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3);
3942    *
3943    * @name by
3944    * @param {Number} delta
3945    * @param {String} msg _optional_
3946    * @namespace BDD
3947    * @api public
3948    */
3949
3950   function assertDelta(delta, msg) {
3951     if (msg) flag(this, 'message', msg);
3952
3953     var msgObj = flag(this, 'deltaMsgObj');
3954     var initial = flag(this, 'initialDeltaValue');
3955     var final = flag(this, 'finalDeltaValue');
3956     var behavior = flag(this, 'deltaBehavior');
3957     var realDelta = flag(this, 'realDelta');
3958
3959     var expression;
3960     if (behavior === 'change') {
3961       expression = Math.abs(final - initial) === Math.abs(delta);
3962     } else {
3963       expression = realDelta === Math.abs(delta);
3964     }
3965
3966     this.assert(
3967       expression
3968       , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta
3969       , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta
3970     );
3971   }
3972
3973   Assertion.addMethod('by', assertDelta);
3974
3975   /**
3976    * ### .extensible
3977    *
3978    * Asserts that the target is extensible, which means that new properties can
3979    * be added to it. Primitives are never extensible.
3980    *
3981    *     expect({a: 1}).to.be.extensible;
3982    *
3983    * Add `.not` earlier in the chain to negate `.extensible`.
3984    *
3985    *     var nonExtensibleObject = Object.preventExtensions({})
3986    *       , sealedObject = Object.seal({})
3987    *       , frozenObject = Object.freeze({});
3988    *
3989    *     expect(nonExtensibleObject).to.not.be.extensible;
3990    *     expect(sealedObject).to.not.be.extensible;
3991    *     expect(frozenObject).to.not.be.extensible;
3992    *     expect(1).to.not.be.extensible;
3993    *
3994    * A custom error message can be given as the second argument to `expect`.
3995    *
3996    *     expect(1, 'nooo why fail??').to.be.extensible;
3997    *
3998    * @name extensible
3999    * @namespace BDD
4000    * @api public
4001    */
4002
4003   Assertion.addProperty('extensible', function() {
4004     var obj = flag(this, 'object');
4005
4006     // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
4007     // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.
4008     // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
4009     // The following provides ES6 behavior for ES5 environments.
4010
4011     var isExtensible = obj === Object(obj) && Object.isExtensible(obj);
4012
4013     this.assert(
4014       isExtensible
4015       , 'expected #{this} to be extensible'
4016       , 'expected #{this} to not be extensible'
4017     );
4018   });
4019
4020   /**
4021    * ### .sealed
4022    *
4023    * Asserts that the target is sealed, which means that new properties can't be
4024    * added to it, and its existing properties can't be reconfigured or deleted.
4025    * However, it's possible that its existing properties can still be reassigned
4026    * to different values. Primitives are always sealed.
4027    *
4028    *     var sealedObject = Object.seal({});
4029    *     var frozenObject = Object.freeze({});
4030    *
4031    *     expect(sealedObject).to.be.sealed;
4032    *     expect(frozenObject).to.be.sealed;
4033    *     expect(1).to.be.sealed;
4034    *
4035    * Add `.not` earlier in the chain to negate `.sealed`.
4036    *
4037    *     expect({a: 1}).to.not.be.sealed;
4038    *
4039    * A custom error message can be given as the second argument to `expect`.
4040    *
4041    *     expect({a: 1}, 'nooo why fail??').to.be.sealed;
4042    *
4043    * @name sealed
4044    * @namespace BDD
4045    * @api public
4046    */
4047
4048   Assertion.addProperty('sealed', function() {
4049     var obj = flag(this, 'object');
4050
4051     // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
4052     // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.
4053     // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed
4054     // The following provides ES6 behavior for ES5 environments.
4055
4056     var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true;
4057
4058     this.assert(
4059       isSealed
4060       , 'expected #{this} to be sealed'
4061       , 'expected #{this} to not be sealed'
4062     );
4063   });
4064
4065   /**
4066    * ### .frozen
4067    *
4068    * Asserts that the target is frozen, which means that new properties can't be
4069    * added to it, and its existing properties can't be reassigned to different
4070    * values, reconfigured, or deleted. Primitives are always frozen.
4071    *
4072    *     var frozenObject = Object.freeze({});
4073    *
4074    *     expect(frozenObject).to.be.frozen;
4075    *     expect(1).to.be.frozen;
4076    *
4077    * Add `.not` earlier in the chain to negate `.frozen`.
4078    *
4079    *     expect({a: 1}).to.not.be.frozen;
4080    *
4081    * A custom error message can be given as the second argument to `expect`.
4082    *
4083    *     expect({a: 1}, 'nooo why fail??').to.be.frozen;
4084    *
4085    * @name frozen
4086    * @namespace BDD
4087    * @api public
4088    */
4089
4090   Assertion.addProperty('frozen', function() {
4091     var obj = flag(this, 'object');
4092
4093     // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
4094     // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.
4095     // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen
4096     // The following provides ES6 behavior for ES5 environments.
4097
4098     var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true;
4099
4100     this.assert(
4101       isFrozen
4102       , 'expected #{this} to be frozen'
4103       , 'expected #{this} to not be frozen'
4104     );
4105   });
4106
4107   /**
4108    * ### .finite
4109    *
4110    * Asserts that the target is a number, and isn't `NaN` or positive/negative
4111    * `Infinity`.
4112    *
4113    *     expect(1).to.be.finite;
4114    *
4115    * Add `.not` earlier in the chain to negate `.finite`. However, it's
4116    * dangerous to do so. The problem is that it creates uncertain expectations
4117    * by asserting that the subject either isn't a number, or that it's `NaN`, or
4118    * that it's positive `Infinity`, or that it's negative `Infinity`. It's often
4119    * best to identify the exact output that's expected, and then write an
4120    * assertion that only accepts that exact output.
4121    *
4122    * When the target isn't expected to be a number, it's often best to assert
4123    * that it's the expected type, rather than asserting that it isn't one of
4124    * many unexpected types.
4125    *
4126    *     expect('foo').to.be.a('string'); // Recommended
4127    *     expect('foo').to.not.be.finite; // Not recommended
4128    *
4129    * When the target is expected to be `NaN`, it's often best to assert exactly
4130    * that.
4131    *
4132    *     expect(NaN).to.be.NaN; // Recommended
4133    *     expect(NaN).to.not.be.finite; // Not recommended
4134    *
4135    * When the target is expected to be positive infinity, it's often best to
4136    * assert exactly that.
4137    *
4138    *     expect(Infinity).to.equal(Infinity); // Recommended
4139    *     expect(Infinity).to.not.be.finite; // Not recommended
4140    *
4141    * When the target is expected to be negative infinity, it's often best to
4142    * assert exactly that.
4143    *
4144    *     expect(-Infinity).to.equal(-Infinity); // Recommended
4145    *     expect(-Infinity).to.not.be.finite; // Not recommended
4146    *
4147    * A custom error message can be given as the second argument to `expect`.
4148    *
4149    *     expect('foo', 'nooo why fail??').to.be.finite;
4150    *
4151    * @name finite
4152    * @namespace BDD
4153    * @api public
4154    */
4155
4156   Assertion.addProperty('finite', function(msg) {
4157     var obj = flag(this, 'object');
4158
4159     this.assert(
4160         typeof obj === 'number' && isFinite(obj)
4161       , 'expected #{this} to be a finite number'
4162       , 'expected #{this} to not be a finite number'
4163     );
4164   });
4165 };
4166
4167 },{}],6:[function(require,module,exports){
4168 /*!
4169  * chai
4170  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
4171  * MIT Licensed
4172  */
4173
4174 module.exports = function (chai, util) {
4175   /*!
4176    * Chai dependencies.
4177    */
4178
4179   var Assertion = chai.Assertion
4180     , flag = util.flag;
4181
4182   /*!
4183    * Module export.
4184    */
4185
4186   /**
4187    * ### assert(expression, message)
4188    *
4189    * Write your own test expressions.
4190    *
4191    *     assert('foo' !== 'bar', 'foo is not bar');
4192    *     assert(Array.isArray([]), 'empty arrays are arrays');
4193    *
4194    * @param {Mixed} expression to test for truthiness
4195    * @param {String} message to display on error
4196    * @name assert
4197    * @namespace Assert
4198    * @api public
4199    */
4200
4201   var assert = chai.assert = function (express, errmsg) {
4202     var test = new Assertion(null, null, chai.assert, true);
4203     test.assert(
4204         express
4205       , errmsg
4206       , '[ negation message unavailable ]'
4207     );
4208   };
4209
4210   /**
4211    * ### .fail([message])
4212    * ### .fail(actual, expected, [message], [operator])
4213    *
4214    * Throw a failure. Node.js `assert` module-compatible.
4215    *
4216    *     assert.fail();
4217    *     assert.fail("custom error message");
4218    *     assert.fail(1, 2);
4219    *     assert.fail(1, 2, "custom error message");
4220    *     assert.fail(1, 2, "custom error message", ">");
4221    *     assert.fail(1, 2, undefined, ">");
4222    *
4223    * @name fail
4224    * @param {Mixed} actual
4225    * @param {Mixed} expected
4226    * @param {String} message
4227    * @param {String} operator
4228    * @namespace Assert
4229    * @api public
4230    */
4231
4232   assert.fail = function (actual, expected, message, operator) {
4233     if (arguments.length < 2) {
4234         // Comply with Node's fail([message]) interface
4235
4236         message = actual;
4237         actual = undefined;
4238     }
4239
4240     message = message || 'assert.fail()';
4241     throw new chai.AssertionError(message, {
4242         actual: actual
4243       , expected: expected
4244       , operator: operator
4245     }, assert.fail);
4246   };
4247
4248   /**
4249    * ### .isOk(object, [message])
4250    *
4251    * Asserts that `object` is truthy.
4252    *
4253    *     assert.isOk('everything', 'everything is ok');
4254    *     assert.isOk(false, 'this will fail');
4255    *
4256    * @name isOk
4257    * @alias ok
4258    * @param {Mixed} object to test
4259    * @param {String} message
4260    * @namespace Assert
4261    * @api public
4262    */
4263
4264   assert.isOk = function (val, msg) {
4265     new Assertion(val, msg, assert.isOk, true).is.ok;
4266   };
4267
4268   /**
4269    * ### .isNotOk(object, [message])
4270    *
4271    * Asserts that `object` is falsy.
4272    *
4273    *     assert.isNotOk('everything', 'this will fail');
4274    *     assert.isNotOk(false, 'this will pass');
4275    *
4276    * @name isNotOk
4277    * @alias notOk
4278    * @param {Mixed} object to test
4279    * @param {String} message
4280    * @namespace Assert
4281    * @api public
4282    */
4283
4284   assert.isNotOk = function (val, msg) {
4285     new Assertion(val, msg, assert.isNotOk, true).is.not.ok;
4286   };
4287
4288   /**
4289    * ### .equal(actual, expected, [message])
4290    *
4291    * Asserts non-strict equality (`==`) of `actual` and `expected`.
4292    *
4293    *     assert.equal(3, '3', '== coerces values to strings');
4294    *
4295    * @name equal
4296    * @param {Mixed} actual
4297    * @param {Mixed} expected
4298    * @param {String} message
4299    * @namespace Assert
4300    * @api public
4301    */
4302
4303   assert.equal = function (act, exp, msg) {
4304     var test = new Assertion(act, msg, assert.equal, true);
4305
4306     test.assert(
4307         exp == flag(test, 'object')
4308       , 'expected #{this} to equal #{exp}'
4309       , 'expected #{this} to not equal #{act}'
4310       , exp
4311       , act
4312       , true
4313     );
4314   };
4315
4316   /**
4317    * ### .notEqual(actual, expected, [message])
4318    *
4319    * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
4320    *
4321    *     assert.notEqual(3, 4, 'these numbers are not equal');
4322    *
4323    * @name notEqual
4324    * @param {Mixed} actual
4325    * @param {Mixed} expected
4326    * @param {String} message
4327    * @namespace Assert
4328    * @api public
4329    */
4330
4331   assert.notEqual = function (act, exp, msg) {
4332     var test = new Assertion(act, msg, assert.notEqual, true);
4333
4334     test.assert(
4335         exp != flag(test, 'object')
4336       , 'expected #{this} to not equal #{exp}'
4337       , 'expected #{this} to equal #{act}'
4338       , exp
4339       , act
4340       , true
4341     );
4342   };
4343
4344   /**
4345    * ### .strictEqual(actual, expected, [message])
4346    *
4347    * Asserts strict equality (`===`) of `actual` and `expected`.
4348    *
4349    *     assert.strictEqual(true, true, 'these booleans are strictly equal');
4350    *
4351    * @name strictEqual
4352    * @param {Mixed} actual
4353    * @param {Mixed} expected
4354    * @param {String} message
4355    * @namespace Assert
4356    * @api public
4357    */
4358
4359   assert.strictEqual = function (act, exp, msg) {
4360     new Assertion(act, msg, assert.strictEqual, true).to.equal(exp);
4361   };
4362
4363   /**
4364    * ### .notStrictEqual(actual, expected, [message])
4365    *
4366    * Asserts strict inequality (`!==`) of `actual` and `expected`.
4367    *
4368    *     assert.notStrictEqual(3, '3', 'no coercion for strict equality');
4369    *
4370    * @name notStrictEqual
4371    * @param {Mixed} actual
4372    * @param {Mixed} expected
4373    * @param {String} message
4374    * @namespace Assert
4375    * @api public
4376    */
4377
4378   assert.notStrictEqual = function (act, exp, msg) {
4379     new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp);
4380   };
4381
4382   /**
4383    * ### .deepEqual(actual, expected, [message])
4384    *
4385    * Asserts that `actual` is deeply equal to `expected`.
4386    *
4387    *     assert.deepEqual({ tea: 'green' }, { tea: 'green' });
4388    *
4389    * @name deepEqual
4390    * @param {Mixed} actual
4391    * @param {Mixed} expected
4392    * @param {String} message
4393    * @alias deepStrictEqual
4394    * @namespace Assert
4395    * @api public
4396    */
4397
4398   assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) {
4399     new Assertion(act, msg, assert.deepEqual, true).to.eql(exp);
4400   };
4401
4402   /**
4403    * ### .notDeepEqual(actual, expected, [message])
4404    *
4405    * Assert that `actual` is not deeply equal to `expected`.
4406    *
4407    *     assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
4408    *
4409    * @name notDeepEqual
4410    * @param {Mixed} actual
4411    * @param {Mixed} expected
4412    * @param {String} message
4413    * @namespace Assert
4414    * @api public
4415    */
4416
4417   assert.notDeepEqual = function (act, exp, msg) {
4418     new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp);
4419   };
4420
4421    /**
4422    * ### .isAbove(valueToCheck, valueToBeAbove, [message])
4423    *
4424    * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`.
4425    *
4426    *     assert.isAbove(5, 2, '5 is strictly greater than 2');
4427    *
4428    * @name isAbove
4429    * @param {Mixed} valueToCheck
4430    * @param {Mixed} valueToBeAbove
4431    * @param {String} message
4432    * @namespace Assert
4433    * @api public
4434    */
4435
4436   assert.isAbove = function (val, abv, msg) {
4437     new Assertion(val, msg, assert.isAbove, true).to.be.above(abv);
4438   };
4439
4440    /**
4441    * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])
4442    *
4443    * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`.
4444    *
4445    *     assert.isAtLeast(5, 2, '5 is greater or equal to 2');
4446    *     assert.isAtLeast(3, 3, '3 is greater or equal to 3');
4447    *
4448    * @name isAtLeast
4449    * @param {Mixed} valueToCheck
4450    * @param {Mixed} valueToBeAtLeast
4451    * @param {String} message
4452    * @namespace Assert
4453    * @api public
4454    */
4455
4456   assert.isAtLeast = function (val, atlst, msg) {
4457     new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst);
4458   };
4459
4460    /**
4461    * ### .isBelow(valueToCheck, valueToBeBelow, [message])
4462    *
4463    * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`.
4464    *
4465    *     assert.isBelow(3, 6, '3 is strictly less than 6');
4466    *
4467    * @name isBelow
4468    * @param {Mixed} valueToCheck
4469    * @param {Mixed} valueToBeBelow
4470    * @param {String} message
4471    * @namespace Assert
4472    * @api public
4473    */
4474
4475   assert.isBelow = function (val, blw, msg) {
4476     new Assertion(val, msg, assert.isBelow, true).to.be.below(blw);
4477   };
4478
4479    /**
4480    * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])
4481    *
4482    * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`.
4483    *
4484    *     assert.isAtMost(3, 6, '3 is less than or equal to 6');
4485    *     assert.isAtMost(4, 4, '4 is less than or equal to 4');
4486    *
4487    * @name isAtMost
4488    * @param {Mixed} valueToCheck
4489    * @param {Mixed} valueToBeAtMost
4490    * @param {String} message
4491    * @namespace Assert
4492    * @api public
4493    */
4494
4495   assert.isAtMost = function (val, atmst, msg) {
4496     new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst);
4497   };
4498
4499   /**
4500    * ### .isTrue(value, [message])
4501    *
4502    * Asserts that `value` is true.
4503    *
4504    *     var teaServed = true;
4505    *     assert.isTrue(teaServed, 'the tea has been served');
4506    *
4507    * @name isTrue
4508    * @param {Mixed} value
4509    * @param {String} message
4510    * @namespace Assert
4511    * @api public
4512    */
4513
4514   assert.isTrue = function (val, msg) {
4515     new Assertion(val, msg, assert.isTrue, true).is['true'];
4516   };
4517
4518   /**
4519    * ### .isNotTrue(value, [message])
4520    *
4521    * Asserts that `value` is not true.
4522    *
4523    *     var tea = 'tasty chai';
4524    *     assert.isNotTrue(tea, 'great, time for tea!');
4525    *
4526    * @name isNotTrue
4527    * @param {Mixed} value
4528    * @param {String} message
4529    * @namespace Assert
4530    * @api public
4531    */
4532
4533   assert.isNotTrue = function (val, msg) {
4534     new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true);
4535   };
4536
4537   /**
4538    * ### .isFalse(value, [message])
4539    *
4540    * Asserts that `value` is false.
4541    *
4542    *     var teaServed = false;
4543    *     assert.isFalse(teaServed, 'no tea yet? hmm...');
4544    *
4545    * @name isFalse
4546    * @param {Mixed} value
4547    * @param {String} message
4548    * @namespace Assert
4549    * @api public
4550    */
4551
4552   assert.isFalse = function (val, msg) {
4553     new Assertion(val, msg, assert.isFalse, true).is['false'];
4554   };
4555
4556   /**
4557    * ### .isNotFalse(value, [message])
4558    *
4559    * Asserts that `value` is not false.
4560    *
4561    *     var tea = 'tasty chai';
4562    *     assert.isNotFalse(tea, 'great, time for tea!');
4563    *
4564    * @name isNotFalse
4565    * @param {Mixed} value
4566    * @param {String} message
4567    * @namespace Assert
4568    * @api public
4569    */
4570
4571   assert.isNotFalse = function (val, msg) {
4572     new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false);
4573   };
4574
4575   /**
4576    * ### .isNull(value, [message])
4577    *
4578    * Asserts that `value` is null.
4579    *
4580    *     assert.isNull(err, 'there was no error');
4581    *
4582    * @name isNull
4583    * @param {Mixed} value
4584    * @param {String} message
4585    * @namespace Assert
4586    * @api public
4587    */
4588
4589   assert.isNull = function (val, msg) {
4590     new Assertion(val, msg, assert.isNull, true).to.equal(null);
4591   };
4592
4593   /**
4594    * ### .isNotNull(value, [message])
4595    *
4596    * Asserts that `value` is not null.
4597    *
4598    *     var tea = 'tasty chai';
4599    *     assert.isNotNull(tea, 'great, time for tea!');
4600    *
4601    * @name isNotNull
4602    * @param {Mixed} value
4603    * @param {String} message
4604    * @namespace Assert
4605    * @api public
4606    */
4607
4608   assert.isNotNull = function (val, msg) {
4609     new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null);
4610   };
4611
4612   /**
4613    * ### .isNaN
4614    *
4615    * Asserts that value is NaN.
4616    *
4617    *     assert.isNaN(NaN, 'NaN is NaN');
4618    *
4619    * @name isNaN
4620    * @param {Mixed} value
4621    * @param {String} message
4622    * @namespace Assert
4623    * @api public
4624    */
4625
4626   assert.isNaN = function (val, msg) {
4627     new Assertion(val, msg, assert.isNaN, true).to.be.NaN;
4628   };
4629
4630   /**
4631    * ### .isNotNaN
4632    *
4633    * Asserts that value is not NaN.
4634    *
4635    *     assert.isNotNaN(4, '4 is not NaN');
4636    *
4637    * @name isNotNaN
4638    * @param {Mixed} value
4639    * @param {String} message
4640    * @namespace Assert
4641    * @api public
4642    */
4643   assert.isNotNaN = function (val, msg) {
4644     new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN;
4645   };
4646
4647   /**
4648    * ### .exists
4649    *
4650    * Asserts that the target is neither `null` nor `undefined`.
4651    *
4652    *     var foo = 'hi';
4653    *
4654    *     assert.exists(foo, 'foo is neither `null` nor `undefined`');
4655    *
4656    * @name exists
4657    * @param {Mixed} value
4658    * @param {String} message
4659    * @namespace Assert
4660    * @api public
4661    */
4662
4663   assert.exists = function (val, msg) {
4664     new Assertion(val, msg, assert.exists, true).to.exist;
4665   };
4666
4667   /**
4668    * ### .notExists
4669    *
4670    * Asserts that the target is either `null` or `undefined`.
4671    *
4672    *     var bar = null
4673    *       , baz;
4674    *
4675    *     assert.notExists(bar);
4676    *     assert.notExists(baz, 'baz is either null or undefined');
4677    *
4678    * @name notExists
4679    * @param {Mixed} value
4680    * @param {String} message
4681    * @namespace Assert
4682    * @api public
4683    */
4684
4685   assert.notExists = function (val, msg) {
4686     new Assertion(val, msg, assert.notExists, true).to.not.exist;
4687   };
4688
4689   /**
4690    * ### .isUndefined(value, [message])
4691    *
4692    * Asserts that `value` is `undefined`.
4693    *
4694    *     var tea;
4695    *     assert.isUndefined(tea, 'no tea defined');
4696    *
4697    * @name isUndefined
4698    * @param {Mixed} value
4699    * @param {String} message
4700    * @namespace Assert
4701    * @api public
4702    */
4703
4704   assert.isUndefined = function (val, msg) {
4705     new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined);
4706   };
4707
4708   /**
4709    * ### .isDefined(value, [message])
4710    *
4711    * Asserts that `value` is not `undefined`.
4712    *
4713    *     var tea = 'cup of chai';
4714    *     assert.isDefined(tea, 'tea has been defined');
4715    *
4716    * @name isDefined
4717    * @param {Mixed} value
4718    * @param {String} message
4719    * @namespace Assert
4720    * @api public
4721    */
4722
4723   assert.isDefined = function (val, msg) {
4724     new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined);
4725   };
4726
4727   /**
4728    * ### .isFunction(value, [message])
4729    *
4730    * Asserts that `value` is a function.
4731    *
4732    *     function serveTea() { return 'cup of tea'; };
4733    *     assert.isFunction(serveTea, 'great, we can have tea now');
4734    *
4735    * @name isFunction
4736    * @param {Mixed} value
4737    * @param {String} message
4738    * @namespace Assert
4739    * @api public
4740    */
4741
4742   assert.isFunction = function (val, msg) {
4743     new Assertion(val, msg, assert.isFunction, true).to.be.a('function');
4744   };
4745
4746   /**
4747    * ### .isNotFunction(value, [message])
4748    *
4749    * Asserts that `value` is _not_ a function.
4750    *
4751    *     var serveTea = [ 'heat', 'pour', 'sip' ];
4752    *     assert.isNotFunction(serveTea, 'great, we have listed the steps');
4753    *
4754    * @name isNotFunction
4755    * @param {Mixed} value
4756    * @param {String} message
4757    * @namespace Assert
4758    * @api public
4759    */
4760
4761   assert.isNotFunction = function (val, msg) {
4762     new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function');
4763   };
4764
4765   /**
4766    * ### .isObject(value, [message])
4767    *
4768    * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).
4769    * _The assertion does not match subclassed objects._
4770    *
4771    *     var selection = { name: 'Chai', serve: 'with spices' };
4772    *     assert.isObject(selection, 'tea selection is an object');
4773    *
4774    * @name isObject
4775    * @param {Mixed} value
4776    * @param {String} message
4777    * @namespace Assert
4778    * @api public
4779    */
4780
4781   assert.isObject = function (val, msg) {
4782     new Assertion(val, msg, assert.isObject, true).to.be.a('object');
4783   };
4784
4785   /**
4786    * ### .isNotObject(value, [message])
4787    *
4788    * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).
4789    *
4790    *     var selection = 'chai'
4791    *     assert.isNotObject(selection, 'tea selection is not an object');
4792    *     assert.isNotObject(null, 'null is not an object');
4793    *
4794    * @name isNotObject
4795    * @param {Mixed} value
4796    * @param {String} message
4797    * @namespace Assert
4798    * @api public
4799    */
4800
4801   assert.isNotObject = function (val, msg) {
4802     new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object');
4803   };
4804
4805   /**
4806    * ### .isArray(value, [message])
4807    *
4808    * Asserts that `value` is an array.
4809    *
4810    *     var menu = [ 'green', 'chai', 'oolong' ];
4811    *     assert.isArray(menu, 'what kind of tea do we want?');
4812    *
4813    * @name isArray
4814    * @param {Mixed} value
4815    * @param {String} message
4816    * @namespace Assert
4817    * @api public
4818    */
4819
4820   assert.isArray = function (val, msg) {
4821     new Assertion(val, msg, assert.isArray, true).to.be.an('array');
4822   };
4823
4824   /**
4825    * ### .isNotArray(value, [message])
4826    *
4827    * Asserts that `value` is _not_ an array.
4828    *
4829    *     var menu = 'green|chai|oolong';
4830    *     assert.isNotArray(menu, 'what kind of tea do we want?');
4831    *
4832    * @name isNotArray
4833    * @param {Mixed} value
4834    * @param {String} message
4835    * @namespace Assert
4836    * @api public
4837    */
4838
4839   assert.isNotArray = function (val, msg) {
4840     new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array');
4841   };
4842
4843   /**
4844    * ### .isString(value, [message])
4845    *
4846    * Asserts that `value` is a string.
4847    *
4848    *     var teaOrder = 'chai';
4849    *     assert.isString(teaOrder, 'order placed');
4850    *
4851    * @name isString
4852    * @param {Mixed} value
4853    * @param {String} message
4854    * @namespace Assert
4855    * @api public
4856    */
4857
4858   assert.isString = function (val, msg) {
4859     new Assertion(val, msg, assert.isString, true).to.be.a('string');
4860   };
4861
4862   /**
4863    * ### .isNotString(value, [message])
4864    *
4865    * Asserts that `value` is _not_ a string.
4866    *
4867    *     var teaOrder = 4;
4868    *     assert.isNotString(teaOrder, 'order placed');
4869    *
4870    * @name isNotString
4871    * @param {Mixed} value
4872    * @param {String} message
4873    * @namespace Assert
4874    * @api public
4875    */
4876
4877   assert.isNotString = function (val, msg) {
4878     new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string');
4879   };
4880
4881   /**
4882    * ### .isNumber(value, [message])
4883    *
4884    * Asserts that `value` is a number.
4885    *
4886    *     var cups = 2;
4887    *     assert.isNumber(cups, 'how many cups');
4888    *
4889    * @name isNumber
4890    * @param {Number} value
4891    * @param {String} message
4892    * @namespace Assert
4893    * @api public
4894    */
4895
4896   assert.isNumber = function (val, msg) {
4897     new Assertion(val, msg, assert.isNumber, true).to.be.a('number');
4898   };
4899
4900   /**
4901    * ### .isNotNumber(value, [message])
4902    *
4903    * Asserts that `value` is _not_ a number.
4904    *
4905    *     var cups = '2 cups please';
4906    *     assert.isNotNumber(cups, 'how many cups');
4907    *
4908    * @name isNotNumber
4909    * @param {Mixed} value
4910    * @param {String} message
4911    * @namespace Assert
4912    * @api public
4913    */
4914
4915   assert.isNotNumber = function (val, msg) {
4916     new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number');
4917   };
4918
4919    /**
4920    * ### .isFinite(value, [message])
4921    *
4922    * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`.
4923    *
4924    *     var cups = 2;
4925    *     assert.isFinite(cups, 'how many cups');
4926    *
4927    *     assert.isFinite(NaN); // throws
4928    *
4929    * @name isFinite
4930    * @param {Number} value
4931    * @param {String} message
4932    * @namespace Assert
4933    * @api public
4934    */
4935
4936   assert.isFinite = function (val, msg) {
4937     new Assertion(val, msg, assert.isFinite, true).to.be.finite;
4938   };
4939
4940   /**
4941    * ### .isBoolean(value, [message])
4942    *
4943    * Asserts that `value` is a boolean.
4944    *
4945    *     var teaReady = true
4946    *       , teaServed = false;
4947    *
4948    *     assert.isBoolean(teaReady, 'is the tea ready');
4949    *     assert.isBoolean(teaServed, 'has tea been served');
4950    *
4951    * @name isBoolean
4952    * @param {Mixed} value
4953    * @param {String} message
4954    * @namespace Assert
4955    * @api public
4956    */
4957
4958   assert.isBoolean = function (val, msg) {
4959     new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean');
4960   };
4961
4962   /**
4963    * ### .isNotBoolean(value, [message])
4964    *
4965    * Asserts that `value` is _not_ a boolean.
4966    *
4967    *     var teaReady = 'yep'
4968    *       , teaServed = 'nope';
4969    *
4970    *     assert.isNotBoolean(teaReady, 'is the tea ready');
4971    *     assert.isNotBoolean(teaServed, 'has tea been served');
4972    *
4973    * @name isNotBoolean
4974    * @param {Mixed} value
4975    * @param {String} message
4976    * @namespace Assert
4977    * @api public
4978    */
4979
4980   assert.isNotBoolean = function (val, msg) {
4981     new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean');
4982   };
4983
4984   /**
4985    * ### .typeOf(value, name, [message])
4986    *
4987    * Asserts that `value`'s type is `name`, as determined by
4988    * `Object.prototype.toString`.
4989    *
4990    *     assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');
4991    *     assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');
4992    *     assert.typeOf('tea', 'string', 'we have a string');
4993    *     assert.typeOf(/tea/, 'regexp', 'we have a regular expression');
4994    *     assert.typeOf(null, 'null', 'we have a null');
4995    *     assert.typeOf(undefined, 'undefined', 'we have an undefined');
4996    *
4997    * @name typeOf
4998    * @param {Mixed} value
4999    * @param {String} name
5000    * @param {String} message
5001    * @namespace Assert
5002    * @api public
5003    */
5004
5005   assert.typeOf = function (val, type, msg) {
5006     new Assertion(val, msg, assert.typeOf, true).to.be.a(type);
5007   };
5008
5009   /**
5010    * ### .notTypeOf(value, name, [message])
5011    *
5012    * Asserts that `value`'s type is _not_ `name`, as determined by
5013    * `Object.prototype.toString`.
5014    *
5015    *     assert.notTypeOf('tea', 'number', 'strings are not numbers');
5016    *
5017    * @name notTypeOf
5018    * @param {Mixed} value
5019    * @param {String} typeof name
5020    * @param {String} message
5021    * @namespace Assert
5022    * @api public
5023    */
5024
5025   assert.notTypeOf = function (val, type, msg) {
5026     new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type);
5027   };
5028
5029   /**
5030    * ### .instanceOf(object, constructor, [message])
5031    *
5032    * Asserts that `value` is an instance of `constructor`.
5033    *
5034    *     var Tea = function (name) { this.name = name; }
5035    *       , chai = new Tea('chai');
5036    *
5037    *     assert.instanceOf(chai, Tea, 'chai is an instance of tea');
5038    *
5039    * @name instanceOf
5040    * @param {Object} object
5041    * @param {Constructor} constructor
5042    * @param {String} message
5043    * @namespace Assert
5044    * @api public
5045    */
5046
5047   assert.instanceOf = function (val, type, msg) {
5048     new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type);
5049   };
5050
5051   /**
5052    * ### .notInstanceOf(object, constructor, [message])
5053    *
5054    * Asserts `value` is not an instance of `constructor`.
5055    *
5056    *     var Tea = function (name) { this.name = name; }
5057    *       , chai = new String('chai');
5058    *
5059    *     assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');
5060    *
5061    * @name notInstanceOf
5062    * @param {Object} object
5063    * @param {Constructor} constructor
5064    * @param {String} message
5065    * @namespace Assert
5066    * @api public
5067    */
5068
5069   assert.notInstanceOf = function (val, type, msg) {
5070     new Assertion(val, msg, assert.notInstanceOf, true)
5071       .to.not.be.instanceOf(type);
5072   };
5073
5074   /**
5075    * ### .include(haystack, needle, [message])
5076    *
5077    * Asserts that `haystack` includes `needle`. Can be used to assert the
5078    * inclusion of a value in an array, a substring in a string, or a subset of
5079    * properties in an object.
5080    *
5081    *     assert.include([1,2,3], 2, 'array contains value');
5082    *     assert.include('foobar', 'foo', 'string contains substring');
5083    *     assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property');
5084    *
5085    * Strict equality (===) is used. When asserting the inclusion of a value in
5086    * an array, the array is searched for an element that's strictly equal to the
5087    * given value. When asserting a subset of properties in an object, the object
5088    * is searched for the given property keys, checking that each one is present
5089    * and strictly equal to the given property value. For instance:
5090    *
5091    *     var obj1 = {a: 1}
5092    *       , obj2 = {b: 2};
5093    *     assert.include([obj1, obj2], obj1);
5094    *     assert.include({foo: obj1, bar: obj2}, {foo: obj1});
5095    *     assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2});
5096    *
5097    * @name include
5098    * @param {Array|String} haystack
5099    * @param {Mixed} needle
5100    * @param {String} message
5101    * @namespace Assert
5102    * @api public
5103    */
5104
5105   assert.include = function (exp, inc, msg) {
5106     new Assertion(exp, msg, assert.include, true).include(inc);
5107   };
5108
5109   /**
5110    * ### .notInclude(haystack, needle, [message])
5111    *
5112    * Asserts that `haystack` does not include `needle`. Can be used to assert
5113    * the absence of a value in an array, a substring in a string, or a subset of
5114    * properties in an object.
5115    *
5116    *     assert.notInclude([1,2,3], 4, "array doesn't contain value");
5117    *     assert.notInclude('foobar', 'baz', "string doesn't contain substring");
5118    *     assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property');
5119    *
5120    * Strict equality (===) is used. When asserting the absence of a value in an
5121    * array, the array is searched to confirm the absence of an element that's
5122    * strictly equal to the given value. When asserting a subset of properties in
5123    * an object, the object is searched to confirm that at least one of the given
5124    * property keys is either not present or not strictly equal to the given
5125    * property value. For instance:
5126    *
5127    *     var obj1 = {a: 1}
5128    *       , obj2 = {b: 2};
5129    *     assert.notInclude([obj1, obj2], {a: 1});
5130    *     assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}});
5131    *     assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}});
5132    *
5133    * @name notInclude
5134    * @param {Array|String} haystack
5135    * @param {Mixed} needle
5136    * @param {String} message
5137    * @namespace Assert
5138    * @api public
5139    */
5140
5141   assert.notInclude = function (exp, inc, msg) {
5142     new Assertion(exp, msg, assert.notInclude, true).not.include(inc);
5143   };
5144
5145   /**
5146    * ### .deepInclude(haystack, needle, [message])
5147    *
5148    * Asserts that `haystack` includes `needle`. Can be used to assert the
5149    * inclusion of a value in an array or a subset of properties in an object.
5150    * Deep equality is used.
5151    *
5152    *     var obj1 = {a: 1}
5153    *       , obj2 = {b: 2};
5154    *     assert.deepInclude([obj1, obj2], {a: 1});
5155    *     assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}});
5156    *     assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}});
5157    *
5158    * @name deepInclude
5159    * @param {Array|String} haystack
5160    * @param {Mixed} needle
5161    * @param {String} message
5162    * @namespace Assert
5163    * @api public
5164    */
5165
5166   assert.deepInclude = function (exp, inc, msg) {
5167     new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc);
5168   };
5169
5170   /**
5171    * ### .notDeepInclude(haystack, needle, [message])
5172    *
5173    * Asserts that `haystack` does not include `needle`. Can be used to assert
5174    * the absence of a value in an array or a subset of properties in an object.
5175    * Deep equality is used.
5176    *
5177    *     var obj1 = {a: 1}
5178    *       , obj2 = {b: 2};
5179    *     assert.notDeepInclude([obj1, obj2], {a: 9});
5180    *     assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}});
5181    *     assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}});
5182    *
5183    * @name notDeepInclude
5184    * @param {Array|String} haystack
5185    * @param {Mixed} needle
5186    * @param {String} message
5187    * @namespace Assert
5188    * @api public
5189    */
5190
5191   assert.notDeepInclude = function (exp, inc, msg) {
5192     new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc);
5193   };
5194
5195   /**
5196    * ### .nestedInclude(haystack, needle, [message])
5197    *
5198    * Asserts that 'haystack' includes 'needle'.
5199    * Can be used to assert the inclusion of a subset of properties in an
5200    * object.
5201    * Enables the use of dot- and bracket-notation for referencing nested
5202    * properties.
5203    * '[]' and '.' in property names can be escaped using double backslashes.
5204    *
5205    *     assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'});
5206    *     assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'});
5207    *
5208    * @name nestedInclude
5209    * @param {Object} haystack
5210    * @param {Object} needle
5211    * @param {String} message
5212    * @namespace Assert
5213    * @api public
5214    */
5215
5216   assert.nestedInclude = function (exp, inc, msg) {
5217     new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc);
5218   };
5219
5220   /**
5221    * ### .notNestedInclude(haystack, needle, [message])
5222    *
5223    * Asserts that 'haystack' does not include 'needle'.
5224    * Can be used to assert the absence of a subset of properties in an
5225    * object.
5226    * Enables the use of dot- and bracket-notation for referencing nested
5227    * properties.
5228    * '[]' and '.' in property names can be escaped using double backslashes.
5229    *
5230    *     assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'});
5231    *     assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'});
5232    *
5233    * @name notNestedInclude
5234    * @param {Object} haystack
5235    * @param {Object} needle
5236    * @param {String} message
5237    * @namespace Assert
5238    * @api public
5239    */
5240
5241   assert.notNestedInclude = function (exp, inc, msg) {
5242     new Assertion(exp, msg, assert.notNestedInclude, true)
5243       .not.nested.include(inc);
5244   };
5245
5246   /**
5247    * ### .deepNestedInclude(haystack, needle, [message])
5248    *
5249    * Asserts that 'haystack' includes 'needle'.
5250    * Can be used to assert the inclusion of a subset of properties in an
5251    * object while checking for deep equality.
5252    * Enables the use of dot- and bracket-notation for referencing nested
5253    * properties.
5254    * '[]' and '.' in property names can be escaped using double backslashes.
5255    *
5256    *     assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}});
5257    *     assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}});
5258    *
5259    * @name deepNestedInclude
5260    * @param {Object} haystack
5261    * @param {Object} needle
5262    * @param {String} message
5263    * @namespace Assert
5264    * @api public
5265    */
5266
5267   assert.deepNestedInclude = function(exp, inc, msg) {
5268     new Assertion(exp, msg, assert.deepNestedInclude, true)
5269       .deep.nested.include(inc);
5270   };
5271
5272   /**
5273    * ### .notDeepNestedInclude(haystack, needle, [message])
5274    *
5275    * Asserts that 'haystack' does not include 'needle'.
5276    * Can be used to assert the absence of a subset of properties in an
5277    * object while checking for deep equality.
5278    * Enables the use of dot- and bracket-notation for referencing nested
5279    * properties.
5280    * '[]' and '.' in property names can be escaped using double backslashes.
5281    *
5282    *     assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}})
5283    *     assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}});
5284    *
5285    * @name notDeepNestedInclude
5286    * @param {Object} haystack
5287    * @param {Object} needle
5288    * @param {String} message
5289    * @namespace Assert
5290    * @api public
5291    */
5292
5293   assert.notDeepNestedInclude = function(exp, inc, msg) {
5294     new Assertion(exp, msg, assert.notDeepNestedInclude, true)
5295       .not.deep.nested.include(inc);
5296   };
5297
5298   /**
5299    * ### .ownInclude(haystack, needle, [message])
5300    *
5301    * Asserts that 'haystack' includes 'needle'.
5302    * Can be used to assert the inclusion of a subset of properties in an
5303    * object while ignoring inherited properties.
5304    *
5305    *     assert.ownInclude({ a: 1 }, { a: 1 });
5306    *
5307    * @name ownInclude
5308    * @param {Object} haystack
5309    * @param {Object} needle
5310    * @param {String} message
5311    * @namespace Assert
5312    * @api public
5313    */
5314
5315   assert.ownInclude = function(exp, inc, msg) {
5316     new Assertion(exp, msg, assert.ownInclude, true).own.include(inc);
5317   };
5318
5319   /**
5320    * ### .notOwnInclude(haystack, needle, [message])
5321    *
5322    * Asserts that 'haystack' includes 'needle'.
5323    * Can be used to assert the absence of a subset of properties in an
5324    * object while ignoring inherited properties.
5325    *
5326    *     Object.prototype.b = 2;
5327    *
5328    *     assert.notOwnInclude({ a: 1 }, { b: 2 });
5329    *
5330    * @name notOwnInclude
5331    * @param {Object} haystack
5332    * @param {Object} needle
5333    * @param {String} message
5334    * @namespace Assert
5335    * @api public
5336    */
5337
5338   assert.notOwnInclude = function(exp, inc, msg) {
5339     new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc);
5340   };
5341
5342   /**
5343    * ### .deepOwnInclude(haystack, needle, [message])
5344    *
5345    * Asserts that 'haystack' includes 'needle'.
5346    * Can be used to assert the inclusion of a subset of properties in an
5347    * object while ignoring inherited properties and checking for deep equality.
5348    *
5349    *      assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}});
5350    *
5351    * @name deepOwnInclude
5352    * @param {Object} haystack
5353    * @param {Object} needle
5354    * @param {String} message
5355    * @namespace Assert
5356    * @api public
5357    */
5358
5359   assert.deepOwnInclude = function(exp, inc, msg) {
5360     new Assertion(exp, msg, assert.deepOwnInclude, true)
5361       .deep.own.include(inc);
5362   };
5363
5364    /**
5365    * ### .notDeepOwnInclude(haystack, needle, [message])
5366    *
5367    * Asserts that 'haystack' includes 'needle'.
5368    * Can be used to assert the absence of a subset of properties in an
5369    * object while ignoring inherited properties and checking for deep equality.
5370    *
5371    *      assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}});
5372    *
5373    * @name notDeepOwnInclude
5374    * @param {Object} haystack
5375    * @param {Object} needle
5376    * @param {String} message
5377    * @namespace Assert
5378    * @api public
5379    */
5380
5381   assert.notDeepOwnInclude = function(exp, inc, msg) {
5382     new Assertion(exp, msg, assert.notDeepOwnInclude, true)
5383       .not.deep.own.include(inc);
5384   };
5385
5386   /**
5387    * ### .match(value, regexp, [message])
5388    *
5389    * Asserts that `value` matches the regular expression `regexp`.
5390    *
5391    *     assert.match('foobar', /^foo/, 'regexp matches');
5392    *
5393    * @name match
5394    * @param {Mixed} value
5395    * @param {RegExp} regexp
5396    * @param {String} message
5397    * @namespace Assert
5398    * @api public
5399    */
5400
5401   assert.match = function (exp, re, msg) {
5402     new Assertion(exp, msg, assert.match, true).to.match(re);
5403   };
5404
5405   /**
5406    * ### .notMatch(value, regexp, [message])
5407    *
5408    * Asserts that `value` does not match the regular expression `regexp`.
5409    *
5410    *     assert.notMatch('foobar', /^foo/, 'regexp does not match');
5411    *
5412    * @name notMatch
5413    * @param {Mixed} value
5414    * @param {RegExp} regexp
5415    * @param {String} message
5416    * @namespace Assert
5417    * @api public
5418    */
5419
5420   assert.notMatch = function (exp, re, msg) {
5421     new Assertion(exp, msg, assert.notMatch, true).to.not.match(re);
5422   };
5423
5424   /**
5425    * ### .property(object, property, [message])
5426    *
5427    * Asserts that `object` has a direct or inherited property named by
5428    * `property`.
5429    *
5430    *     assert.property({ tea: { green: 'matcha' }}, 'tea');
5431    *     assert.property({ tea: { green: 'matcha' }}, 'toString');
5432    *
5433    * @name property
5434    * @param {Object} object
5435    * @param {String} property
5436    * @param {String} message
5437    * @namespace Assert
5438    * @api public
5439    */
5440
5441   assert.property = function (obj, prop, msg) {
5442     new Assertion(obj, msg, assert.property, true).to.have.property(prop);
5443   };
5444
5445   /**
5446    * ### .notProperty(object, property, [message])
5447    *
5448    * Asserts that `object` does _not_ have a direct or inherited property named
5449    * by `property`.
5450    *
5451    *     assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');
5452    *
5453    * @name notProperty
5454    * @param {Object} object
5455    * @param {String} property
5456    * @param {String} message
5457    * @namespace Assert
5458    * @api public
5459    */
5460
5461   assert.notProperty = function (obj, prop, msg) {
5462     new Assertion(obj, msg, assert.notProperty, true)
5463       .to.not.have.property(prop);
5464   };
5465
5466   /**
5467    * ### .propertyVal(object, property, value, [message])
5468    *
5469    * Asserts that `object` has a direct or inherited property named by
5470    * `property` with a value given by `value`. Uses a strict equality check
5471    * (===).
5472    *
5473    *     assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');
5474    *
5475    * @name propertyVal
5476    * @param {Object} object
5477    * @param {String} property
5478    * @param {Mixed} value
5479    * @param {String} message
5480    * @namespace Assert
5481    * @api public
5482    */
5483
5484   assert.propertyVal = function (obj, prop, val, msg) {
5485     new Assertion(obj, msg, assert.propertyVal, true)
5486       .to.have.property(prop, val);
5487   };
5488
5489   /**
5490    * ### .notPropertyVal(object, property, value, [message])
5491    *
5492    * Asserts that `object` does _not_ have a direct or inherited property named
5493    * by `property` with value given by `value`. Uses a strict equality check
5494    * (===).
5495    *
5496    *     assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad');
5497    *     assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good');
5498    *
5499    * @name notPropertyVal
5500    * @param {Object} object
5501    * @param {String} property
5502    * @param {Mixed} value
5503    * @param {String} message
5504    * @namespace Assert
5505    * @api public
5506    */
5507
5508   assert.notPropertyVal = function (obj, prop, val, msg) {
5509     new Assertion(obj, msg, assert.notPropertyVal, true)
5510       .to.not.have.property(prop, val);
5511   };
5512
5513   /**
5514    * ### .deepPropertyVal(object, property, value, [message])
5515    *
5516    * Asserts that `object` has a direct or inherited property named by
5517    * `property` with a value given by `value`. Uses a deep equality check.
5518    *
5519    *     assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' });
5520    *
5521    * @name deepPropertyVal
5522    * @param {Object} object
5523    * @param {String} property
5524    * @param {Mixed} value
5525    * @param {String} message
5526    * @namespace Assert
5527    * @api public
5528    */
5529
5530   assert.deepPropertyVal = function (obj, prop, val, msg) {
5531     new Assertion(obj, msg, assert.deepPropertyVal, true)
5532       .to.have.deep.property(prop, val);
5533   };
5534
5535   /**
5536    * ### .notDeepPropertyVal(object, property, value, [message])
5537    *
5538    * Asserts that `object` does _not_ have a direct or inherited property named
5539    * by `property` with value given by `value`. Uses a deep equality check.
5540    *
5541    *     assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' });
5542    *     assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' });
5543    *     assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' });
5544    *
5545    * @name notDeepPropertyVal
5546    * @param {Object} object
5547    * @param {String} property
5548    * @param {Mixed} value
5549    * @param {String} message
5550    * @namespace Assert
5551    * @api public
5552    */
5553
5554   assert.notDeepPropertyVal = function (obj, prop, val, msg) {
5555     new Assertion(obj, msg, assert.notDeepPropertyVal, true)
5556       .to.not.have.deep.property(prop, val);
5557   };
5558
5559   /**
5560    * ### .ownProperty(object, property, [message])
5561    *
5562    * Asserts that `object` has a direct property named by `property`. Inherited
5563    * properties aren't checked.
5564    *
5565    *     assert.ownProperty({ tea: { green: 'matcha' }}, 'tea');
5566    *
5567    * @name ownProperty
5568    * @param {Object} object
5569    * @param {String} property
5570    * @param {String} message
5571    * @api public
5572    */
5573
5574   assert.ownProperty = function (obj, prop, msg) {
5575     new Assertion(obj, msg, assert.ownProperty, true)
5576       .to.have.own.property(prop);
5577   };
5578
5579   /**
5580    * ### .notOwnProperty(object, property, [message])
5581    *
5582    * Asserts that `object` does _not_ have a direct property named by
5583    * `property`. Inherited properties aren't checked.
5584    *
5585    *     assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee');
5586    *     assert.notOwnProperty({}, 'toString');
5587    *
5588    * @name notOwnProperty
5589    * @param {Object} object
5590    * @param {String} property
5591    * @param {String} message
5592    * @api public
5593    */
5594
5595   assert.notOwnProperty = function (obj, prop, msg) {
5596     new Assertion(obj, msg, assert.notOwnProperty, true)
5597       .to.not.have.own.property(prop);
5598   };
5599
5600   /**
5601    * ### .ownPropertyVal(object, property, value, [message])
5602    *
5603    * Asserts that `object` has a direct property named by `property` and a value
5604    * equal to the provided `value`. Uses a strict equality check (===).
5605    * Inherited properties aren't checked.
5606    *
5607    *     assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good');
5608    *
5609    * @name ownPropertyVal
5610    * @param {Object} object
5611    * @param {String} property
5612    * @param {Mixed} value
5613    * @param {String} message
5614    * @api public
5615    */
5616
5617   assert.ownPropertyVal = function (obj, prop, value, msg) {
5618     new Assertion(obj, msg, assert.ownPropertyVal, true)
5619       .to.have.own.property(prop, value);
5620   };
5621
5622   /**
5623    * ### .notOwnPropertyVal(object, property, value, [message])
5624    *
5625    * Asserts that `object` does _not_ have a direct property named by `property`
5626    * with a value equal to the provided `value`. Uses a strict equality check
5627    * (===). Inherited properties aren't checked.
5628    *
5629    *     assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse');
5630    *     assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString);
5631    *
5632    * @name notOwnPropertyVal
5633    * @param {Object} object
5634    * @param {String} property
5635    * @param {Mixed} value
5636    * @param {String} message
5637    * @api public
5638    */
5639
5640   assert.notOwnPropertyVal = function (obj, prop, value, msg) {
5641     new Assertion(obj, msg, assert.notOwnPropertyVal, true)
5642       .to.not.have.own.property(prop, value);
5643   };
5644
5645   /**
5646    * ### .deepOwnPropertyVal(object, property, value, [message])
5647    *
5648    * Asserts that `object` has a direct property named by `property` and a value
5649    * equal to the provided `value`. Uses a deep equality check. Inherited
5650    * properties aren't checked.
5651    *
5652    *     assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' });
5653    *
5654    * @name deepOwnPropertyVal
5655    * @param {Object} object
5656    * @param {String} property
5657    * @param {Mixed} value
5658    * @param {String} message
5659    * @api public
5660    */
5661
5662   assert.deepOwnPropertyVal = function (obj, prop, value, msg) {
5663     new Assertion(obj, msg, assert.deepOwnPropertyVal, true)
5664       .to.have.deep.own.property(prop, value);
5665   };
5666
5667   /**
5668    * ### .notDeepOwnPropertyVal(object, property, value, [message])
5669    *
5670    * Asserts that `object` does _not_ have a direct property named by `property`
5671    * with a value equal to the provided `value`. Uses a deep equality check.
5672    * Inherited properties aren't checked.
5673    *
5674    *     assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' });
5675    *     assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' });
5676    *     assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' });
5677    *     assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString);
5678    *
5679    * @name notDeepOwnPropertyVal
5680    * @param {Object} object
5681    * @param {String} property
5682    * @param {Mixed} value
5683    * @param {String} message
5684    * @api public
5685    */
5686
5687   assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) {
5688     new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true)
5689       .to.not.have.deep.own.property(prop, value);
5690   };
5691
5692   /**
5693    * ### .nestedProperty(object, property, [message])
5694    *
5695    * Asserts that `object` has a direct or inherited property named by
5696    * `property`, which can be a string using dot- and bracket-notation for
5697    * nested reference.
5698    *
5699    *     assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green');
5700    *
5701    * @name nestedProperty
5702    * @param {Object} object
5703    * @param {String} property
5704    * @param {String} message
5705    * @namespace Assert
5706    * @api public
5707    */
5708
5709   assert.nestedProperty = function (obj, prop, msg) {
5710     new Assertion(obj, msg, assert.nestedProperty, true)
5711       .to.have.nested.property(prop);
5712   };
5713
5714   /**
5715    * ### .notNestedProperty(object, property, [message])
5716    *
5717    * Asserts that `object` does _not_ have a property named by `property`, which
5718    * can be a string using dot- and bracket-notation for nested reference. The
5719    * property cannot exist on the object nor anywhere in its prototype chain.
5720    *
5721    *     assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong');
5722    *
5723    * @name notNestedProperty
5724    * @param {Object} object
5725    * @param {String} property
5726    * @param {String} message
5727    * @namespace Assert
5728    * @api public
5729    */
5730
5731   assert.notNestedProperty = function (obj, prop, msg) {
5732     new Assertion(obj, msg, assert.notNestedProperty, true)
5733       .to.not.have.nested.property(prop);
5734   };
5735
5736   /**
5737    * ### .nestedPropertyVal(object, property, value, [message])
5738    *
5739    * Asserts that `object` has a property named by `property` with value given
5740    * by `value`. `property` can use dot- and bracket-notation for nested
5741    * reference. Uses a strict equality check (===).
5742    *
5743    *     assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');
5744    *
5745    * @name nestedPropertyVal
5746    * @param {Object} object
5747    * @param {String} property
5748    * @param {Mixed} value
5749    * @param {String} message
5750    * @namespace Assert
5751    * @api public
5752    */
5753
5754   assert.nestedPropertyVal = function (obj, prop, val, msg) {
5755     new Assertion(obj, msg, assert.nestedPropertyVal, true)
5756       .to.have.nested.property(prop, val);
5757   };
5758
5759   /**
5760    * ### .notNestedPropertyVal(object, property, value, [message])
5761    *
5762    * Asserts that `object` does _not_ have a property named by `property` with
5763    * value given by `value`. `property` can use dot- and bracket-notation for
5764    * nested reference. Uses a strict equality check (===).
5765    *
5766    *     assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');
5767    *     assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha');
5768    *
5769    * @name notNestedPropertyVal
5770    * @param {Object} object
5771    * @param {String} property
5772    * @param {Mixed} value
5773    * @param {String} message
5774    * @namespace Assert
5775    * @api public
5776    */
5777
5778   assert.notNestedPropertyVal = function (obj, prop, val, msg) {
5779     new Assertion(obj, msg, assert.notNestedPropertyVal, true)
5780       .to.not.have.nested.property(prop, val);
5781   };
5782
5783   /**
5784    * ### .deepNestedPropertyVal(object, property, value, [message])
5785    *
5786    * Asserts that `object` has a property named by `property` with a value given
5787    * by `value`. `property` can use dot- and bracket-notation for nested
5788    * reference. Uses a deep equality check.
5789    *
5790    *     assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' });
5791    *
5792    * @name deepNestedPropertyVal
5793    * @param {Object} object
5794    * @param {String} property
5795    * @param {Mixed} value
5796    * @param {String} message
5797    * @namespace Assert
5798    * @api public
5799    */
5800
5801   assert.deepNestedPropertyVal = function (obj, prop, val, msg) {
5802     new Assertion(obj, msg, assert.deepNestedPropertyVal, true)
5803       .to.have.deep.nested.property(prop, val);
5804   };
5805
5806   /**
5807    * ### .notDeepNestedPropertyVal(object, property, value, [message])
5808    *
5809    * Asserts that `object` does _not_ have a property named by `property` with
5810    * value given by `value`. `property` can use dot- and bracket-notation for
5811    * nested reference. Uses a deep equality check.
5812    *
5813    *     assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' });
5814    *     assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' });
5815    *     assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' });
5816    *
5817    * @name notDeepNestedPropertyVal
5818    * @param {Object} object
5819    * @param {String} property
5820    * @param {Mixed} value
5821    * @param {String} message
5822    * @namespace Assert
5823    * @api public
5824    */
5825
5826   assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) {
5827     new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true)
5828       .to.not.have.deep.nested.property(prop, val);
5829   }
5830
5831   /**
5832    * ### .lengthOf(object, length, [message])
5833    *
5834    * Asserts that `object` has a `length` or `size` with the expected value.
5835    *
5836    *     assert.lengthOf([1,2,3], 3, 'array has length of 3');
5837    *     assert.lengthOf('foobar', 6, 'string has length of 6');
5838    *     assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3');
5839    *     assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3');
5840    *
5841    * @name lengthOf
5842    * @param {Mixed} object
5843    * @param {Number} length
5844    * @param {String} message
5845    * @namespace Assert
5846    * @api public
5847    */
5848
5849   assert.lengthOf = function (exp, len, msg) {
5850     new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len);
5851   };
5852
5853   /**
5854    * ### .hasAnyKeys(object, [keys], [message])
5855    *
5856    * Asserts that `object` has at least one of the `keys` provided.
5857    * You can also provide a single object instead of a `keys` array and its keys
5858    * will be used as the expected set of keys.
5859    *
5860    *     assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']);
5861    *     assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337});
5862    *     assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
5863    *     assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']);
5864    *
5865    * @name hasAnyKeys
5866    * @param {Mixed} object
5867    * @param {Array|Object} keys
5868    * @param {String} message
5869    * @namespace Assert
5870    * @api public
5871    */
5872
5873   assert.hasAnyKeys = function (obj, keys, msg) {
5874     new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys);
5875   }
5876
5877   /**
5878    * ### .hasAllKeys(object, [keys], [message])
5879    *
5880    * Asserts that `object` has all and only all of the `keys` provided.
5881    * You can also provide a single object instead of a `keys` array and its keys
5882    * will be used as the expected set of keys.
5883    *
5884    *     assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']);
5885    *     assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]);
5886    *     assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
5887    *     assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']);
5888    *
5889    * @name hasAllKeys
5890    * @param {Mixed} object
5891    * @param {String[]} keys
5892    * @param {String} message
5893    * @namespace Assert
5894    * @api public
5895    */
5896
5897   assert.hasAllKeys = function (obj, keys, msg) {
5898     new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys);
5899   }
5900
5901   /**
5902    * ### .containsAllKeys(object, [keys], [message])
5903    *
5904    * Asserts that `object` has all of the `keys` provided but may have more keys not listed.
5905    * You can also provide a single object instead of a `keys` array and its keys
5906    * will be used as the expected set of keys.
5907    *
5908    *     assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']);
5909    *     assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']);
5910    *     assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337});
5911    *     assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337});
5912    *     assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]);
5913    *     assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
5914    *     assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]);
5915    *     assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']);
5916    *
5917    * @name containsAllKeys
5918    * @param {Mixed} object
5919    * @param {String[]} keys
5920    * @param {String} message
5921    * @namespace Assert
5922    * @api public
5923    */
5924
5925   assert.containsAllKeys = function (obj, keys, msg) {
5926     new Assertion(obj, msg, assert.containsAllKeys, true)
5927       .to.contain.all.keys(keys);
5928   }
5929
5930   /**
5931    * ### .doesNotHaveAnyKeys(object, [keys], [message])
5932    *
5933    * Asserts that `object` has none of the `keys` provided.
5934    * You can also provide a single object instead of a `keys` array and its keys
5935    * will be used as the expected set of keys.
5936    *
5937    *     assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']);
5938    *     assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'});
5939    *     assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']);
5940    *     assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']);
5941    *
5942    * @name doesNotHaveAnyKeys
5943    * @param {Mixed} object
5944    * @param {String[]} keys
5945    * @param {String} message
5946    * @namespace Assert
5947    * @api public
5948    */
5949
5950   assert.doesNotHaveAnyKeys = function (obj, keys, msg) {
5951     new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true)
5952       .to.not.have.any.keys(keys);
5953   }
5954
5955   /**
5956    * ### .doesNotHaveAllKeys(object, [keys], [message])
5957    *
5958    * Asserts that `object` does not have at least one of the `keys` provided.
5959    * You can also provide a single object instead of a `keys` array and its keys
5960    * will be used as the expected set of keys.
5961    *
5962    *     assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']);
5963    *     assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'});
5964    *     assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']);
5965    *     assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']);
5966    *
5967    * @name doesNotHaveAllKeys
5968    * @param {Mixed} object
5969    * @param {String[]} keys
5970    * @param {String} message
5971    * @namespace Assert
5972    * @api public
5973    */
5974
5975   assert.doesNotHaveAllKeys = function (obj, keys, msg) {
5976     new Assertion(obj, msg, assert.doesNotHaveAllKeys, true)
5977       .to.not.have.all.keys(keys);
5978   }
5979
5980   /**
5981    * ### .hasAnyDeepKeys(object, [keys], [message])
5982    *
5983    * Asserts that `object` has at least one of the `keys` provided.
5984    * Since Sets and Maps can have objects as keys you can use this assertion to perform
5985    * a deep comparison.
5986    * You can also provide a single object instead of a `keys` array and its keys
5987    * will be used as the expected set of keys.
5988    *
5989    *     assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'});
5990    *     assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]);
5991    *     assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
5992    *     assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'});
5993    *     assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]);
5994    *     assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
5995    *
5996    * @name doesNotHaveAllKeys
5997    * @param {Mixed} object
5998    * @param {Array|Object} keys
5999    * @param {String} message
6000    * @namespace Assert
6001    * @api public
6002    */
6003
6004   assert.hasAnyDeepKeys = function (obj, keys, msg) {
6005     new Assertion(obj, msg, assert.hasAnyDeepKeys, true)
6006       .to.have.any.deep.keys(keys);
6007   }
6008
6009  /**
6010    * ### .hasAllDeepKeys(object, [keys], [message])
6011    *
6012    * Asserts that `object` has all and only all of the `keys` provided.
6013    * Since Sets and Maps can have objects as keys you can use this assertion to perform
6014    * a deep comparison.
6015    * You can also provide a single object instead of a `keys` array and its keys
6016    * will be used as the expected set of keys.
6017    *
6018    *     assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'});
6019    *     assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
6020    *     assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'});
6021    *     assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
6022    *
6023    * @name hasAllDeepKeys
6024    * @param {Mixed} object
6025    * @param {Array|Object} keys
6026    * @param {String} message
6027    * @namespace Assert
6028    * @api public
6029    */
6030
6031   assert.hasAllDeepKeys = function (obj, keys, msg) {
6032     new Assertion(obj, msg, assert.hasAllDeepKeys, true)
6033       .to.have.all.deep.keys(keys);
6034   }
6035
6036  /**
6037    * ### .containsAllDeepKeys(object, [keys], [message])
6038    *
6039    * Asserts that `object` contains all of the `keys` provided.
6040    * Since Sets and Maps can have objects as keys you can use this assertion to perform
6041    * a deep comparison.
6042    * You can also provide a single object instead of a `keys` array and its keys
6043    * will be used as the expected set of keys.
6044    *
6045    *     assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'});
6046    *     assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
6047    *     assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'});
6048    *     assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
6049    *
6050    * @name containsAllDeepKeys
6051    * @param {Mixed} object
6052    * @param {Array|Object} keys
6053    * @param {String} message
6054    * @namespace Assert
6055    * @api public
6056    */
6057
6058   assert.containsAllDeepKeys = function (obj, keys, msg) {
6059     new Assertion(obj, msg, assert.containsAllDeepKeys, true)
6060       .to.contain.all.deep.keys(keys);
6061   }
6062
6063  /**
6064    * ### .doesNotHaveAnyDeepKeys(object, [keys], [message])
6065    *
6066    * Asserts that `object` has none of the `keys` provided.
6067    * Since Sets and Maps can have objects as keys you can use this assertion to perform
6068    * a deep comparison.
6069    * You can also provide a single object instead of a `keys` array and its keys
6070    * will be used as the expected set of keys.
6071    *
6072    *     assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'});
6073    *     assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]);
6074    *     assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'});
6075    *     assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]);
6076    *
6077    * @name doesNotHaveAnyDeepKeys
6078    * @param {Mixed} object
6079    * @param {Array|Object} keys
6080    * @param {String} message
6081    * @namespace Assert
6082    * @api public
6083    */
6084
6085   assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) {
6086     new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true)
6087       .to.not.have.any.deep.keys(keys);
6088   }
6089
6090  /**
6091    * ### .doesNotHaveAllDeepKeys(object, [keys], [message])
6092    *
6093    * Asserts that `object` does not have at least one of the `keys` provided.
6094    * Since Sets and Maps can have objects as keys you can use this assertion to perform
6095    * a deep comparison.
6096    * You can also provide a single object instead of a `keys` array and its keys
6097    * will be used as the expected set of keys.
6098    *
6099    *     assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'});
6100    *     assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]);
6101    *     assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'});
6102    *     assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]);
6103    *
6104    * @name doesNotHaveAllDeepKeys
6105    * @param {Mixed} object
6106    * @param {Array|Object} keys
6107    * @param {String} message
6108    * @namespace Assert
6109    * @api public
6110    */
6111
6112   assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) {
6113     new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true)
6114       .to.not.have.all.deep.keys(keys);
6115   }
6116
6117  /**
6118    * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message])
6119    *
6120    * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an
6121    * instance of `errorLike`.
6122    * If `errorLike` is an `Error` instance, asserts that the error thrown is the same
6123    * instance as `errorLike`.
6124    * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a
6125    * message matching `errMsgMatcher`.
6126    *
6127    *     assert.throws(fn, 'Error thrown must have this msg');
6128    *     assert.throws(fn, /Error thrown must have a msg that matches this/);
6129    *     assert.throws(fn, ReferenceError);
6130    *     assert.throws(fn, errorInstance);
6131    *     assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg');
6132    *     assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg');
6133    *     assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/);
6134    *     assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/);
6135    *
6136    * @name throws
6137    * @alias throw
6138    * @alias Throw
6139    * @param {Function} fn
6140    * @param {ErrorConstructor|Error} errorLike
6141    * @param {RegExp|String} errMsgMatcher
6142    * @param {String} message
6143    * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
6144    * @namespace Assert
6145    * @api public
6146    */
6147
6148   assert.throws = function (fn, errorLike, errMsgMatcher, msg) {
6149     if ('string' === typeof errorLike || errorLike instanceof RegExp) {
6150       errMsgMatcher = errorLike;
6151       errorLike = null;
6152     }
6153
6154     var assertErr = new Assertion(fn, msg, assert.throws, true)
6155       .to.throw(errorLike, errMsgMatcher);
6156     return flag(assertErr, 'object');
6157   };
6158
6159   /**
6160    * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message])
6161    *
6162    * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an
6163    * instance of `errorLike`.
6164    * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same
6165    * instance as `errorLike`.
6166    * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a
6167    * message matching `errMsgMatcher`.
6168    *
6169    *     assert.doesNotThrow(fn, 'Any Error thrown must not have this message');
6170    *     assert.doesNotThrow(fn, /Any Error thrown must not match this/);
6171    *     assert.doesNotThrow(fn, Error);
6172    *     assert.doesNotThrow(fn, errorInstance);
6173    *     assert.doesNotThrow(fn, Error, 'Error must not have this message');
6174    *     assert.doesNotThrow(fn, errorInstance, 'Error must not have this message');
6175    *     assert.doesNotThrow(fn, Error, /Error must not match this/);
6176    *     assert.doesNotThrow(fn, errorInstance, /Error must not match this/);
6177    *
6178    * @name doesNotThrow
6179    * @param {Function} fn
6180    * @param {ErrorConstructor} errorLike
6181    * @param {RegExp|String} errMsgMatcher
6182    * @param {String} message
6183    * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
6184    * @namespace Assert
6185    * @api public
6186    */
6187
6188   assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) {
6189     if ('string' === typeof errorLike || errorLike instanceof RegExp) {
6190       errMsgMatcher = errorLike;
6191       errorLike = null;
6192     }
6193
6194     new Assertion(fn, msg, assert.doesNotThrow, true)
6195       .to.not.throw(errorLike, errMsgMatcher);
6196   };
6197
6198   /**
6199    * ### .operator(val1, operator, val2, [message])
6200    *
6201    * Compares two values using `operator`.
6202    *
6203    *     assert.operator(1, '<', 2, 'everything is ok');
6204    *     assert.operator(1, '>', 2, 'this will fail');
6205    *
6206    * @name operator
6207    * @param {Mixed} val1
6208    * @param {String} operator
6209    * @param {Mixed} val2
6210    * @param {String} message
6211    * @namespace Assert
6212    * @api public
6213    */
6214
6215   assert.operator = function (val, operator, val2, msg) {
6216     var ok;
6217     switch(operator) {
6218       case '==':
6219         ok = val == val2;
6220         break;
6221       case '===':
6222         ok = val === val2;
6223         break;
6224       case '>':
6225         ok = val > val2;
6226         break;
6227       case '>=':
6228         ok = val >= val2;
6229         break;
6230       case '<':
6231         ok = val < val2;
6232         break;
6233       case '<=':
6234         ok = val <= val2;
6235         break;
6236       case '!=':
6237         ok = val != val2;
6238         break;
6239       case '!==':
6240         ok = val !== val2;
6241         break;
6242       default:
6243         msg = msg ? msg + ': ' : msg;
6244         throw new chai.AssertionError(
6245           msg + 'Invalid operator "' + operator + '"',
6246           undefined,
6247           assert.operator
6248         );
6249     }
6250     var test = new Assertion(ok, msg, assert.operator, true);
6251     test.assert(
6252         true === flag(test, 'object')
6253       , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
6254       , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );
6255   };
6256
6257   /**
6258    * ### .closeTo(actual, expected, delta, [message])
6259    *
6260    * Asserts that the target is equal `expected`, to within a +/- `delta` range.
6261    *
6262    *     assert.closeTo(1.5, 1, 0.5, 'numbers are close');
6263    *
6264    * @name closeTo
6265    * @param {Number} actual
6266    * @param {Number} expected
6267    * @param {Number} delta
6268    * @param {String} message
6269    * @namespace Assert
6270    * @api public
6271    */
6272
6273   assert.closeTo = function (act, exp, delta, msg) {
6274     new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta);
6275   };
6276
6277   /**
6278    * ### .approximately(actual, expected, delta, [message])
6279    *
6280    * Asserts that the target is equal `expected`, to within a +/- `delta` range.
6281    *
6282    *     assert.approximately(1.5, 1, 0.5, 'numbers are close');
6283    *
6284    * @name approximately
6285    * @param {Number} actual
6286    * @param {Number} expected
6287    * @param {Number} delta
6288    * @param {String} message
6289    * @namespace Assert
6290    * @api public
6291    */
6292
6293   assert.approximately = function (act, exp, delta, msg) {
6294     new Assertion(act, msg, assert.approximately, true)
6295       .to.be.approximately(exp, delta);
6296   };
6297
6298   /**
6299    * ### .sameMembers(set1, set2, [message])
6300    *
6301    * Asserts that `set1` and `set2` have the same members in any order. Uses a
6302    * strict equality check (===).
6303    *
6304    *     assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');
6305    *
6306    * @name sameMembers
6307    * @param {Array} set1
6308    * @param {Array} set2
6309    * @param {String} message
6310    * @namespace Assert
6311    * @api public
6312    */
6313
6314   assert.sameMembers = function (set1, set2, msg) {
6315     new Assertion(set1, msg, assert.sameMembers, true)
6316       .to.have.same.members(set2);
6317   }
6318
6319   /**
6320    * ### .notSameMembers(set1, set2, [message])
6321    *
6322    * Asserts that `set1` and `set2` don't have the same members in any order.
6323    * Uses a strict equality check (===).
6324    *
6325    *     assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members');
6326    *
6327    * @name notSameMembers
6328    * @param {Array} set1
6329    * @param {Array} set2
6330    * @param {String} message
6331    * @namespace Assert
6332    * @api public
6333    */
6334
6335   assert.notSameMembers = function (set1, set2, msg) {
6336     new Assertion(set1, msg, assert.notSameMembers, true)
6337       .to.not.have.same.members(set2);
6338   }
6339
6340   /**
6341    * ### .sameDeepMembers(set1, set2, [message])
6342    *
6343    * Asserts that `set1` and `set2` have the same members in any order. Uses a
6344    * deep equality check.
6345    *
6346    *     assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members');
6347    *
6348    * @name sameDeepMembers
6349    * @param {Array} set1
6350    * @param {Array} set2
6351    * @param {String} message
6352    * @namespace Assert
6353    * @api public
6354    */
6355
6356   assert.sameDeepMembers = function (set1, set2, msg) {
6357     new Assertion(set1, msg, assert.sameDeepMembers, true)
6358       .to.have.same.deep.members(set2);
6359   }
6360
6361   /**
6362    * ### .notSameDeepMembers(set1, set2, [message])
6363    *
6364    * Asserts that `set1` and `set2` don't have the same members in any order.
6365    * Uses a deep equality check.
6366    *
6367    *     assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members');
6368    *
6369    * @name notSameDeepMembers
6370    * @param {Array} set1
6371    * @param {Array} set2
6372    * @param {String} message
6373    * @namespace Assert
6374    * @api public
6375    */
6376
6377   assert.notSameDeepMembers = function (set1, set2, msg) {
6378     new Assertion(set1, msg, assert.notSameDeepMembers, true)
6379       .to.not.have.same.deep.members(set2);
6380   }
6381
6382   /**
6383    * ### .sameOrderedMembers(set1, set2, [message])
6384    *
6385    * Asserts that `set1` and `set2` have the same members in the same order.
6386    * Uses a strict equality check (===).
6387    *
6388    *     assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members');
6389    *
6390    * @name sameOrderedMembers
6391    * @param {Array} set1
6392    * @param {Array} set2
6393    * @param {String} message
6394    * @namespace Assert
6395    * @api public
6396    */
6397
6398   assert.sameOrderedMembers = function (set1, set2, msg) {
6399     new Assertion(set1, msg, assert.sameOrderedMembers, true)
6400       .to.have.same.ordered.members(set2);
6401   }
6402
6403   /**
6404    * ### .notSameOrderedMembers(set1, set2, [message])
6405    *
6406    * Asserts that `set1` and `set2` don't have the same members in the same
6407    * order. Uses a strict equality check (===).
6408    *
6409    *     assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members');
6410    *
6411    * @name notSameOrderedMembers
6412    * @param {Array} set1
6413    * @param {Array} set2
6414    * @param {String} message
6415    * @namespace Assert
6416    * @api public
6417    */
6418
6419   assert.notSameOrderedMembers = function (set1, set2, msg) {
6420     new Assertion(set1, msg, assert.notSameOrderedMembers, true)
6421       .to.not.have.same.ordered.members(set2);
6422   }
6423
6424   /**
6425    * ### .sameDeepOrderedMembers(set1, set2, [message])
6426    *
6427    * Asserts that `set1` and `set2` have the same members in the same order.
6428    * Uses a deep equality check.
6429    *
6430    * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members');
6431    *
6432    * @name sameDeepOrderedMembers
6433    * @param {Array} set1
6434    * @param {Array} set2
6435    * @param {String} message
6436    * @namespace Assert
6437    * @api public
6438    */
6439
6440   assert.sameDeepOrderedMembers = function (set1, set2, msg) {
6441     new Assertion(set1, msg, assert.sameDeepOrderedMembers, true)
6442       .to.have.same.deep.ordered.members(set2);
6443   }
6444
6445   /**
6446    * ### .notSameDeepOrderedMembers(set1, set2, [message])
6447    *
6448    * Asserts that `set1` and `set2` don't have the same members in the same
6449    * order. Uses a deep equality check.
6450    *
6451    * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members');
6452    * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members');
6453    *
6454    * @name notSameDeepOrderedMembers
6455    * @param {Array} set1
6456    * @param {Array} set2
6457    * @param {String} message
6458    * @namespace Assert
6459    * @api public
6460    */
6461
6462   assert.notSameDeepOrderedMembers = function (set1, set2, msg) {
6463     new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true)
6464       .to.not.have.same.deep.ordered.members(set2);
6465   }
6466
6467   /**
6468    * ### .includeMembers(superset, subset, [message])
6469    *
6470    * Asserts that `subset` is included in `superset` in any order. Uses a
6471    * strict equality check (===). Duplicates are ignored.
6472    *
6473    *     assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members');
6474    *
6475    * @name includeMembers
6476    * @param {Array} superset
6477    * @param {Array} subset
6478    * @param {String} message
6479    * @namespace Assert
6480    * @api public
6481    */
6482
6483   assert.includeMembers = function (superset, subset, msg) {
6484     new Assertion(superset, msg, assert.includeMembers, true)
6485       .to.include.members(subset);
6486   }
6487
6488   /**
6489    * ### .notIncludeMembers(superset, subset, [message])
6490    *
6491    * Asserts that `subset` isn't included in `superset` in any order. Uses a
6492    * strict equality check (===). Duplicates are ignored.
6493    *
6494    *     assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members');
6495    *
6496    * @name notIncludeMembers
6497    * @param {Array} superset
6498    * @param {Array} subset
6499    * @param {String} message
6500    * @namespace Assert
6501    * @api public
6502    */
6503
6504   assert.notIncludeMembers = function (superset, subset, msg) {
6505     new Assertion(superset, msg, assert.notIncludeMembers, true)
6506       .to.not.include.members(subset);
6507   }
6508
6509   /**
6510    * ### .includeDeepMembers(superset, subset, [message])
6511    *
6512    * Asserts that `subset` is included in `superset` in any order. Uses a deep
6513    * equality check. Duplicates are ignored.
6514    *
6515    *     assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members');
6516    *
6517    * @name includeDeepMembers
6518    * @param {Array} superset
6519    * @param {Array} subset
6520    * @param {String} message
6521    * @namespace Assert
6522    * @api public
6523    */
6524
6525   assert.includeDeepMembers = function (superset, subset, msg) {
6526     new Assertion(superset, msg, assert.includeDeepMembers, true)
6527       .to.include.deep.members(subset);
6528   }
6529
6530   /**
6531    * ### .notIncludeDeepMembers(superset, subset, [message])
6532    *
6533    * Asserts that `subset` isn't included in `superset` in any order. Uses a
6534    * deep equality check. Duplicates are ignored.
6535    *
6536    *     assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members');
6537    *
6538    * @name notIncludeDeepMembers
6539    * @param {Array} superset
6540    * @param {Array} subset
6541    * @param {String} message
6542    * @namespace Assert
6543    * @api public
6544    */
6545
6546   assert.notIncludeDeepMembers = function (superset, subset, msg) {
6547     new Assertion(superset, msg, assert.notIncludeDeepMembers, true)
6548       .to.not.include.deep.members(subset);
6549   }
6550
6551   /**
6552    * ### .includeOrderedMembers(superset, subset, [message])
6553    *
6554    * Asserts that `subset` is included in `superset` in the same order
6555    * beginning with the first element in `superset`. Uses a strict equality
6556    * check (===).
6557    *
6558    *     assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members');
6559    *
6560    * @name includeOrderedMembers
6561    * @param {Array} superset
6562    * @param {Array} subset
6563    * @param {String} message
6564    * @namespace Assert
6565    * @api public
6566    */
6567
6568   assert.includeOrderedMembers = function (superset, subset, msg) {
6569     new Assertion(superset, msg, assert.includeOrderedMembers, true)
6570       .to.include.ordered.members(subset);
6571   }
6572
6573   /**
6574    * ### .notIncludeOrderedMembers(superset, subset, [message])
6575    *
6576    * Asserts that `subset` isn't included in `superset` in the same order
6577    * beginning with the first element in `superset`. Uses a strict equality
6578    * check (===).
6579    *
6580    *     assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members');
6581    *     assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members');
6582    *
6583    * @name notIncludeOrderedMembers
6584    * @param {Array} superset
6585    * @param {Array} subset
6586    * @param {String} message
6587    * @namespace Assert
6588    * @api public
6589    */
6590
6591   assert.notIncludeOrderedMembers = function (superset, subset, msg) {
6592     new Assertion(superset, msg, assert.notIncludeOrderedMembers, true)
6593       .to.not.include.ordered.members(subset);
6594   }
6595
6596   /**
6597    * ### .includeDeepOrderedMembers(superset, subset, [message])
6598    *
6599    * Asserts that `subset` is included in `superset` in the same order
6600    * beginning with the first element in `superset`. Uses a deep equality
6601    * check.
6602    *
6603    *     assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members');
6604    *
6605    * @name includeDeepOrderedMembers
6606    * @param {Array} superset
6607    * @param {Array} subset
6608    * @param {String} message
6609    * @namespace Assert
6610    * @api public
6611    */
6612
6613   assert.includeDeepOrderedMembers = function (superset, subset, msg) {
6614     new Assertion(superset, msg, assert.includeDeepOrderedMembers, true)
6615       .to.include.deep.ordered.members(subset);
6616   }
6617
6618   /**
6619    * ### .notIncludeDeepOrderedMembers(superset, subset, [message])
6620    *
6621    * Asserts that `subset` isn't included in `superset` in the same order
6622    * beginning with the first element in `superset`. Uses a deep equality
6623    * check.
6624    *
6625    *     assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members');
6626    *     assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members');
6627    *     assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members');
6628    *
6629    * @name notIncludeDeepOrderedMembers
6630    * @param {Array} superset
6631    * @param {Array} subset
6632    * @param {String} message
6633    * @namespace Assert
6634    * @api public
6635    */
6636
6637   assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) {
6638     new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true)
6639       .to.not.include.deep.ordered.members(subset);
6640   }
6641
6642   /**
6643    * ### .oneOf(inList, list, [message])
6644    *
6645    * Asserts that non-object, non-array value `inList` appears in the flat array `list`.
6646    *
6647    *     assert.oneOf(1, [ 2, 1 ], 'Not found in list');
6648    *
6649    * @name oneOf
6650    * @param {*} inList
6651    * @param {Array<*>} list
6652    * @param {String} message
6653    * @namespace Assert
6654    * @api public
6655    */
6656
6657   assert.oneOf = function (inList, list, msg) {
6658     new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list);
6659   }
6660
6661   /**
6662    * ### .changes(function, object, property, [message])
6663    *
6664    * Asserts that a function changes the value of a property.
6665    *
6666    *     var obj = { val: 10 };
6667    *     var fn = function() { obj.val = 22 };
6668    *     assert.changes(fn, obj, 'val');
6669    *
6670    * @name changes
6671    * @param {Function} modifier function
6672    * @param {Object} object or getter function
6673    * @param {String} property name _optional_
6674    * @param {String} message _optional_
6675    * @namespace Assert
6676    * @api public
6677    */
6678
6679   assert.changes = function (fn, obj, prop, msg) {
6680     if (arguments.length === 3 && typeof obj === 'function') {
6681       msg = prop;
6682       prop = null;
6683     }
6684
6685     new Assertion(fn, msg, assert.changes, true).to.change(obj, prop);
6686   }
6687
6688    /**
6689    * ### .changesBy(function, object, property, delta, [message])
6690    *
6691    * Asserts that a function changes the value of a property by an amount (delta).
6692    *
6693    *     var obj = { val: 10 };
6694    *     var fn = function() { obj.val += 2 };
6695    *     assert.changesBy(fn, obj, 'val', 2);
6696    *
6697    * @name changesBy
6698    * @param {Function} modifier function
6699    * @param {Object} object or getter function
6700    * @param {String} property name _optional_
6701    * @param {Number} change amount (delta)
6702    * @param {String} message _optional_
6703    * @namespace Assert
6704    * @api public
6705    */
6706
6707   assert.changesBy = function (fn, obj, prop, delta, msg) {
6708     if (arguments.length === 4 && typeof obj === 'function') {
6709       var tmpMsg = delta;
6710       delta = prop;
6711       msg = tmpMsg;
6712     } else if (arguments.length === 3) {
6713       delta = prop;
6714       prop = null;
6715     }
6716
6717     new Assertion(fn, msg, assert.changesBy, true)
6718       .to.change(obj, prop).by(delta);
6719   }
6720
6721    /**
6722    * ### .doesNotChange(function, object, property, [message])
6723    *
6724    * Asserts that a function does not change the value of a property.
6725    *
6726    *     var obj = { val: 10 };
6727    *     var fn = function() { console.log('foo'); };
6728    *     assert.doesNotChange(fn, obj, 'val');
6729    *
6730    * @name doesNotChange
6731    * @param {Function} modifier function
6732    * @param {Object} object or getter function
6733    * @param {String} property name _optional_
6734    * @param {String} message _optional_
6735    * @namespace Assert
6736    * @api public
6737    */
6738
6739   assert.doesNotChange = function (fn, obj, prop, msg) {
6740     if (arguments.length === 3 && typeof obj === 'function') {
6741       msg = prop;
6742       prop = null;
6743     }
6744
6745     return new Assertion(fn, msg, assert.doesNotChange, true)
6746       .to.not.change(obj, prop);
6747   }
6748
6749   /**
6750    * ### .changesButNotBy(function, object, property, delta, [message])
6751    *
6752    * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta)
6753    *
6754    *     var obj = { val: 10 };
6755    *     var fn = function() { obj.val += 10 };
6756    *     assert.changesButNotBy(fn, obj, 'val', 5);
6757    *
6758    * @name changesButNotBy
6759    * @param {Function} modifier function
6760    * @param {Object} object or getter function
6761    * @param {String} property name _optional_
6762    * @param {Number} change amount (delta)
6763    * @param {String} message _optional_
6764    * @namespace Assert
6765    * @api public
6766    */
6767
6768   assert.changesButNotBy = function (fn, obj, prop, delta, msg) {
6769     if (arguments.length === 4 && typeof obj === 'function') {
6770       var tmpMsg = delta;
6771       delta = prop;
6772       msg = tmpMsg;
6773     } else if (arguments.length === 3) {
6774       delta = prop;
6775       prop = null;
6776     }
6777
6778     new Assertion(fn, msg, assert.changesButNotBy, true)
6779       .to.change(obj, prop).but.not.by(delta);
6780   }
6781
6782   /**
6783    * ### .increases(function, object, property, [message])
6784    *
6785    * Asserts that a function increases a numeric object property.
6786    *
6787    *     var obj = { val: 10 };
6788    *     var fn = function() { obj.val = 13 };
6789    *     assert.increases(fn, obj, 'val');
6790    *
6791    * @name increases
6792    * @param {Function} modifier function
6793    * @param {Object} object or getter function
6794    * @param {String} property name _optional_
6795    * @param {String} message _optional_
6796    * @namespace Assert
6797    * @api public
6798    */
6799
6800   assert.increases = function (fn, obj, prop, msg) {
6801     if (arguments.length === 3 && typeof obj === 'function') {
6802       msg = prop;
6803       prop = null;
6804     }
6805
6806     return new Assertion(fn, msg, assert.increases, true)
6807       .to.increase(obj, prop);
6808   }
6809
6810   /**
6811    * ### .increasesBy(function, object, property, delta, [message])
6812    *
6813    * Asserts that a function increases a numeric object property or a function's return value by an amount (delta).
6814    *
6815    *     var obj = { val: 10 };
6816    *     var fn = function() { obj.val += 10 };
6817    *     assert.increasesBy(fn, obj, 'val', 10);
6818    *
6819    * @name increasesBy
6820    * @param {Function} modifier function
6821    * @param {Object} object or getter function
6822    * @param {String} property name _optional_
6823    * @param {Number} change amount (delta)
6824    * @param {String} message _optional_
6825    * @namespace Assert
6826    * @api public
6827    */
6828
6829   assert.increasesBy = function (fn, obj, prop, delta, msg) {
6830     if (arguments.length === 4 && typeof obj === 'function') {
6831       var tmpMsg = delta;
6832       delta = prop;
6833       msg = tmpMsg;
6834     } else if (arguments.length === 3) {
6835       delta = prop;
6836       prop = null;
6837     }
6838
6839     new Assertion(fn, msg, assert.increasesBy, true)
6840       .to.increase(obj, prop).by(delta);
6841   }
6842
6843   /**
6844    * ### .doesNotIncrease(function, object, property, [message])
6845    *
6846    * Asserts that a function does not increase a numeric object property.
6847    *
6848    *     var obj = { val: 10 };
6849    *     var fn = function() { obj.val = 8 };
6850    *     assert.doesNotIncrease(fn, obj, 'val');
6851    *
6852    * @name doesNotIncrease
6853    * @param {Function} modifier function
6854    * @param {Object} object or getter function
6855    * @param {String} property name _optional_
6856    * @param {String} message _optional_
6857    * @namespace Assert
6858    * @api public
6859    */
6860
6861   assert.doesNotIncrease = function (fn, obj, prop, msg) {
6862     if (arguments.length === 3 && typeof obj === 'function') {
6863       msg = prop;
6864       prop = null;
6865     }
6866
6867     return new Assertion(fn, msg, assert.doesNotIncrease, true)
6868       .to.not.increase(obj, prop);
6869   }
6870
6871   /**
6872    * ### .increasesButNotBy(function, object, property, [message])
6873    *
6874    * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta).
6875    *
6876    *     var obj = { val: 10 };
6877    *     var fn = function() { obj.val = 15 };
6878    *     assert.increasesButNotBy(fn, obj, 'val', 10);
6879    *
6880    * @name increasesButNotBy
6881    * @param {Function} modifier function
6882    * @param {Object} object or getter function
6883    * @param {String} property name _optional_
6884    * @param {Number} change amount (delta)
6885    * @param {String} message _optional_
6886    * @namespace Assert
6887    * @api public
6888    */
6889
6890   assert.increasesButNotBy = function (fn, obj, prop, delta, msg) {
6891     if (arguments.length === 4 && typeof obj === 'function') {
6892       var tmpMsg = delta;
6893       delta = prop;
6894       msg = tmpMsg;
6895     } else if (arguments.length === 3) {
6896       delta = prop;
6897       prop = null;
6898     }
6899
6900     new Assertion(fn, msg, assert.increasesButNotBy, true)
6901       .to.increase(obj, prop).but.not.by(delta);
6902   }
6903
6904   /**
6905    * ### .decreases(function, object, property, [message])
6906    *
6907    * Asserts that a function decreases a numeric object property.
6908    *
6909    *     var obj = { val: 10 };
6910    *     var fn = function() { obj.val = 5 };
6911    *     assert.decreases(fn, obj, 'val');
6912    *
6913    * @name decreases
6914    * @param {Function} modifier function
6915    * @param {Object} object or getter function
6916    * @param {String} property name _optional_
6917    * @param {String} message _optional_
6918    * @namespace Assert
6919    * @api public
6920    */
6921
6922   assert.decreases = function (fn, obj, prop, msg) {
6923     if (arguments.length === 3 && typeof obj === 'function') {
6924       msg = prop;
6925       prop = null;
6926     }
6927
6928     return new Assertion(fn, msg, assert.decreases, true)
6929       .to.decrease(obj, prop);
6930   }
6931
6932   /**
6933    * ### .decreasesBy(function, object, property, delta, [message])
6934    *
6935    * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta)
6936    *
6937    *     var obj = { val: 10 };
6938    *     var fn = function() { obj.val -= 5 };
6939    *     assert.decreasesBy(fn, obj, 'val', 5);
6940    *
6941    * @name decreasesBy
6942    * @param {Function} modifier function
6943    * @param {Object} object or getter function
6944    * @param {String} property name _optional_
6945    * @param {Number} change amount (delta)
6946    * @param {String} message _optional_
6947    * @namespace Assert
6948    * @api public
6949    */
6950
6951   assert.decreasesBy = function (fn, obj, prop, delta, msg) {
6952     if (arguments.length === 4 && typeof obj === 'function') {
6953       var tmpMsg = delta;
6954       delta = prop;
6955       msg = tmpMsg;
6956     } else if (arguments.length === 3) {
6957       delta = prop;
6958       prop = null;
6959     }
6960
6961     new Assertion(fn, msg, assert.decreasesBy, true)
6962       .to.decrease(obj, prop).by(delta);
6963   }
6964
6965   /**
6966    * ### .doesNotDecrease(function, object, property, [message])
6967    *
6968    * Asserts that a function does not decreases a numeric object property.
6969    *
6970    *     var obj = { val: 10 };
6971    *     var fn = function() { obj.val = 15 };
6972    *     assert.doesNotDecrease(fn, obj, 'val');
6973    *
6974    * @name doesNotDecrease
6975    * @param {Function} modifier function
6976    * @param {Object} object or getter function
6977    * @param {String} property name _optional_
6978    * @param {String} message _optional_
6979    * @namespace Assert
6980    * @api public
6981    */
6982
6983   assert.doesNotDecrease = function (fn, obj, prop, msg) {
6984     if (arguments.length === 3 && typeof obj === 'function') {
6985       msg = prop;
6986       prop = null;
6987     }
6988
6989     return new Assertion(fn, msg, assert.doesNotDecrease, true)
6990       .to.not.decrease(obj, prop);
6991   }
6992
6993   /**
6994    * ### .doesNotDecreaseBy(function, object, property, delta, [message])
6995    *
6996    * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta)
6997    *
6998    *     var obj = { val: 10 };
6999    *     var fn = function() { obj.val = 5 };
7000    *     assert.doesNotDecreaseBy(fn, obj, 'val', 1);
7001    *
7002    * @name doesNotDecrease
7003    * @param {Function} modifier function
7004    * @param {Object} object or getter function
7005    * @param {String} property name _optional_
7006    * @param {Number} change amount (delta)
7007    * @param {String} message _optional_
7008    * @namespace Assert
7009    * @api public
7010    */
7011
7012   assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) {
7013     if (arguments.length === 4 && typeof obj === 'function') {
7014       var tmpMsg = delta;
7015       delta = prop;
7016       msg = tmpMsg;
7017     } else if (arguments.length === 3) {
7018       delta = prop;
7019       prop = null;
7020     }
7021
7022     return new Assertion(fn, msg, assert.doesNotDecreaseBy, true)
7023       .to.not.decrease(obj, prop).by(delta);
7024   }
7025
7026   /**
7027    * ### .decreasesButNotBy(function, object, property, delta, [message])
7028    *
7029    * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta)
7030    *
7031    *     var obj = { val: 10 };
7032    *     var fn = function() { obj.val = 5 };
7033    *     assert.decreasesButNotBy(fn, obj, 'val', 1);
7034    *
7035    * @name decreasesButNotBy
7036    * @param {Function} modifier function
7037    * @param {Object} object or getter function
7038    * @param {String} property name _optional_
7039    * @param {Number} change amount (delta)
7040    * @param {String} message _optional_
7041    * @namespace Assert
7042    * @api public
7043    */
7044
7045   assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) {
7046     if (arguments.length === 4 && typeof obj === 'function') {
7047       var tmpMsg = delta;
7048       delta = prop;
7049       msg = tmpMsg;
7050     } else if (arguments.length === 3) {
7051       delta = prop;
7052       prop = null;
7053     }
7054
7055     new Assertion(fn, msg, assert.decreasesButNotBy, true)
7056       .to.decrease(obj, prop).but.not.by(delta);
7057   }
7058
7059   /*!
7060    * ### .ifError(object)
7061    *
7062    * Asserts if value is not a false value, and throws if it is a true value.
7063    * This is added to allow for chai to be a drop-in replacement for Node's
7064    * assert class.
7065    *
7066    *     var err = new Error('I am a custom error');
7067    *     assert.ifError(err); // Rethrows err!
7068    *
7069    * @name ifError
7070    * @param {Object} object
7071    * @namespace Assert
7072    * @api public
7073    */
7074
7075   assert.ifError = function (val) {
7076     if (val) {
7077       throw(val);
7078     }
7079   };
7080
7081   /**
7082    * ### .isExtensible(object)
7083    *
7084    * Asserts that `object` is extensible (can have new properties added to it).
7085    *
7086    *     assert.isExtensible({});
7087    *
7088    * @name isExtensible
7089    * @alias extensible
7090    * @param {Object} object
7091    * @param {String} message _optional_
7092    * @namespace Assert
7093    * @api public
7094    */
7095
7096   assert.isExtensible = function (obj, msg) {
7097     new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible;
7098   };
7099
7100   /**
7101    * ### .isNotExtensible(object)
7102    *
7103    * Asserts that `object` is _not_ extensible.
7104    *
7105    *     var nonExtensibleObject = Object.preventExtensions({});
7106    *     var sealedObject = Object.seal({});
7107    *     var frozenObject = Object.freeze({});
7108    *
7109    *     assert.isNotExtensible(nonExtensibleObject);
7110    *     assert.isNotExtensible(sealedObject);
7111    *     assert.isNotExtensible(frozenObject);
7112    *
7113    * @name isNotExtensible
7114    * @alias notExtensible
7115    * @param {Object} object
7116    * @param {String} message _optional_
7117    * @namespace Assert
7118    * @api public
7119    */
7120
7121   assert.isNotExtensible = function (obj, msg) {
7122     new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible;
7123   };
7124
7125   /**
7126    * ### .isSealed(object)
7127    *
7128    * Asserts that `object` is sealed (cannot have new properties added to it
7129    * and its existing properties cannot be removed).
7130    *
7131    *     var sealedObject = Object.seal({});
7132    *     var frozenObject = Object.seal({});
7133    *
7134    *     assert.isSealed(sealedObject);
7135    *     assert.isSealed(frozenObject);
7136    *
7137    * @name isSealed
7138    * @alias sealed
7139    * @param {Object} object
7140    * @param {String} message _optional_
7141    * @namespace Assert
7142    * @api public
7143    */
7144
7145   assert.isSealed = function (obj, msg) {
7146     new Assertion(obj, msg, assert.isSealed, true).to.be.sealed;
7147   };
7148
7149   /**
7150    * ### .isNotSealed(object)
7151    *
7152    * Asserts that `object` is _not_ sealed.
7153    *
7154    *     assert.isNotSealed({});
7155    *
7156    * @name isNotSealed
7157    * @alias notSealed
7158    * @param {Object} object
7159    * @param {String} message _optional_
7160    * @namespace Assert
7161    * @api public
7162    */
7163
7164   assert.isNotSealed = function (obj, msg) {
7165     new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed;
7166   };
7167
7168   /**
7169    * ### .isFrozen(object)
7170    *
7171    * Asserts that `object` is frozen (cannot have new properties added to it
7172    * and its existing properties cannot be modified).
7173    *
7174    *     var frozenObject = Object.freeze({});
7175    *     assert.frozen(frozenObject);
7176    *
7177    * @name isFrozen
7178    * @alias frozen
7179    * @param {Object} object
7180    * @param {String} message _optional_
7181    * @namespace Assert
7182    * @api public
7183    */
7184
7185   assert.isFrozen = function (obj, msg) {
7186     new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen;
7187   };
7188
7189   /**
7190    * ### .isNotFrozen(object)
7191    *
7192    * Asserts that `object` is _not_ frozen.
7193    *
7194    *     assert.isNotFrozen({});
7195    *
7196    * @name isNotFrozen
7197    * @alias notFrozen
7198    * @param {Object} object
7199    * @param {String} message _optional_
7200    * @namespace Assert
7201    * @api public
7202    */
7203
7204   assert.isNotFrozen = function (obj, msg) {
7205     new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen;
7206   };
7207
7208   /**
7209    * ### .isEmpty(target)
7210    *
7211    * Asserts that the target does not contain any values.
7212    * For arrays and strings, it checks the `length` property.
7213    * For `Map` and `Set` instances, it checks the `size` property.
7214    * For non-function objects, it gets the count of own
7215    * enumerable string keys.
7216    *
7217    *     assert.isEmpty([]);
7218    *     assert.isEmpty('');
7219    *     assert.isEmpty(new Map);
7220    *     assert.isEmpty({});
7221    *
7222    * @name isEmpty
7223    * @alias empty
7224    * @param {Object|Array|String|Map|Set} target
7225    * @param {String} message _optional_
7226    * @namespace Assert
7227    * @api public
7228    */
7229
7230   assert.isEmpty = function(val, msg) {
7231     new Assertion(val, msg, assert.isEmpty, true).to.be.empty;
7232   };
7233
7234   /**
7235    * ### .isNotEmpty(target)
7236    *
7237    * Asserts that the target contains values.
7238    * For arrays and strings, it checks the `length` property.
7239    * For `Map` and `Set` instances, it checks the `size` property.
7240    * For non-function objects, it gets the count of own
7241    * enumerable string keys.
7242    *
7243    *     assert.isNotEmpty([1, 2]);
7244    *     assert.isNotEmpty('34');
7245    *     assert.isNotEmpty(new Set([5, 6]));
7246    *     assert.isNotEmpty({ key: 7 });
7247    *
7248    * @name isNotEmpty
7249    * @alias notEmpty
7250    * @param {Object|Array|String|Map|Set} target
7251    * @param {String} message _optional_
7252    * @namespace Assert
7253    * @api public
7254    */
7255
7256   assert.isNotEmpty = function(val, msg) {
7257     new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty;
7258   };
7259
7260   /*!
7261    * Aliases.
7262    */
7263
7264   (function alias(name, as){
7265     assert[as] = assert[name];
7266     return alias;
7267   })
7268   ('isOk', 'ok')
7269   ('isNotOk', 'notOk')
7270   ('throws', 'throw')
7271   ('throws', 'Throw')
7272   ('isExtensible', 'extensible')
7273   ('isNotExtensible', 'notExtensible')
7274   ('isSealed', 'sealed')
7275   ('isNotSealed', 'notSealed')
7276   ('isFrozen', 'frozen')
7277   ('isNotFrozen', 'notFrozen')
7278   ('isEmpty', 'empty')
7279   ('isNotEmpty', 'notEmpty');
7280 };
7281
7282 },{}],7:[function(require,module,exports){
7283 /*!
7284  * chai
7285  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
7286  * MIT Licensed
7287  */
7288
7289 module.exports = function (chai, util) {
7290   chai.expect = function (val, message) {
7291     return new chai.Assertion(val, message);
7292   };
7293
7294   /**
7295    * ### .fail([message])
7296    * ### .fail(actual, expected, [message], [operator])
7297    *
7298    * Throw a failure.
7299    *
7300    *     expect.fail();
7301    *     expect.fail("custom error message");
7302    *     expect.fail(1, 2);
7303    *     expect.fail(1, 2, "custom error message");
7304    *     expect.fail(1, 2, "custom error message", ">");
7305    *     expect.fail(1, 2, undefined, ">");
7306    *
7307    * @name fail
7308    * @param {Mixed} actual
7309    * @param {Mixed} expected
7310    * @param {String} message
7311    * @param {String} operator
7312    * @namespace BDD
7313    * @api public
7314    */
7315
7316   chai.expect.fail = function (actual, expected, message, operator) {
7317     if (arguments.length < 2) {
7318         message = actual;
7319         actual = undefined;
7320     }
7321
7322     message = message || 'expect.fail()';
7323     throw new chai.AssertionError(message, {
7324         actual: actual
7325       , expected: expected
7326       , operator: operator
7327     }, chai.expect.fail);
7328   };
7329 };
7330
7331 },{}],8:[function(require,module,exports){
7332 /*!
7333  * chai
7334  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
7335  * MIT Licensed
7336  */
7337
7338 module.exports = function (chai, util) {
7339   var Assertion = chai.Assertion;
7340
7341   function loadShould () {
7342     // explicitly define this method as function as to have it's name to include as `ssfi`
7343     function shouldGetter() {
7344       if (this instanceof String
7345           || this instanceof Number
7346           || this instanceof Boolean
7347           || typeof Symbol === 'function' && this instanceof Symbol) {
7348         return new Assertion(this.valueOf(), null, shouldGetter);
7349       }
7350       return new Assertion(this, null, shouldGetter);
7351     }
7352     function shouldSetter(value) {
7353       // See https://github.com/chaijs/chai/issues/86: this makes
7354       // `whatever.should = someValue` actually set `someValue`, which is
7355       // especially useful for `global.should = require('chai').should()`.
7356       //
7357       // Note that we have to use [[DefineProperty]] instead of [[Put]]
7358       // since otherwise we would trigger this very setter!
7359       Object.defineProperty(this, 'should', {
7360         value: value,
7361         enumerable: true,
7362         configurable: true,
7363         writable: true
7364       });
7365     }
7366     // modify Object.prototype to have `should`
7367     Object.defineProperty(Object.prototype, 'should', {
7368       set: shouldSetter
7369       , get: shouldGetter
7370       , configurable: true
7371     });
7372
7373     var should = {};
7374
7375     /**
7376      * ### .fail([message])
7377      * ### .fail(actual, expected, [message], [operator])
7378      *
7379      * Throw a failure.
7380      *
7381      *     should.fail();
7382      *     should.fail("custom error message");
7383      *     should.fail(1, 2);
7384      *     should.fail(1, 2, "custom error message");
7385      *     should.fail(1, 2, "custom error message", ">");
7386      *     should.fail(1, 2, undefined, ">");
7387      *
7388      *
7389      * @name fail
7390      * @param {Mixed} actual
7391      * @param {Mixed} expected
7392      * @param {String} message
7393      * @param {String} operator
7394      * @namespace BDD
7395      * @api public
7396      */
7397
7398     should.fail = function (actual, expected, message, operator) {
7399       if (arguments.length < 2) {
7400           message = actual;
7401           actual = undefined;
7402       }
7403
7404       message = message || 'should.fail()';
7405       throw new chai.AssertionError(message, {
7406           actual: actual
7407         , expected: expected
7408         , operator: operator
7409       }, should.fail);
7410     };
7411
7412     /**
7413      * ### .equal(actual, expected, [message])
7414      *
7415      * Asserts non-strict equality (`==`) of `actual` and `expected`.
7416      *
7417      *     should.equal(3, '3', '== coerces values to strings');
7418      *
7419      * @name equal
7420      * @param {Mixed} actual
7421      * @param {Mixed} expected
7422      * @param {String} message
7423      * @namespace Should
7424      * @api public
7425      */
7426
7427     should.equal = function (val1, val2, msg) {
7428       new Assertion(val1, msg).to.equal(val2);
7429     };
7430
7431     /**
7432      * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])
7433      *
7434      * Asserts that `function` will throw an error that is an instance of
7435      * `constructor`, or alternately that it will throw an error with message
7436      * matching `regexp`.
7437      *
7438      *     should.throw(fn, 'function throws a reference error');
7439      *     should.throw(fn, /function throws a reference error/);
7440      *     should.throw(fn, ReferenceError);
7441      *     should.throw(fn, ReferenceError, 'function throws a reference error');
7442      *     should.throw(fn, ReferenceError, /function throws a reference error/);
7443      *
7444      * @name throw
7445      * @alias Throw
7446      * @param {Function} function
7447      * @param {ErrorConstructor} constructor
7448      * @param {RegExp} regexp
7449      * @param {String} message
7450      * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
7451      * @namespace Should
7452      * @api public
7453      */
7454
7455     should.Throw = function (fn, errt, errs, msg) {
7456       new Assertion(fn, msg).to.Throw(errt, errs);
7457     };
7458
7459     /**
7460      * ### .exist
7461      *
7462      * Asserts that the target is neither `null` nor `undefined`.
7463      *
7464      *     var foo = 'hi';
7465      *
7466      *     should.exist(foo, 'foo exists');
7467      *
7468      * @name exist
7469      * @namespace Should
7470      * @api public
7471      */
7472
7473     should.exist = function (val, msg) {
7474       new Assertion(val, msg).to.exist;
7475     }
7476
7477     // negation
7478     should.not = {}
7479
7480     /**
7481      * ### .not.equal(actual, expected, [message])
7482      *
7483      * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
7484      *
7485      *     should.not.equal(3, 4, 'these numbers are not equal');
7486      *
7487      * @name not.equal
7488      * @param {Mixed} actual
7489      * @param {Mixed} expected
7490      * @param {String} message
7491      * @namespace Should
7492      * @api public
7493      */
7494
7495     should.not.equal = function (val1, val2, msg) {
7496       new Assertion(val1, msg).to.not.equal(val2);
7497     };
7498
7499     /**
7500      * ### .throw(function, [constructor/regexp], [message])
7501      *
7502      * Asserts that `function` will _not_ throw an error that is an instance of
7503      * `constructor`, or alternately that it will not throw an error with message
7504      * matching `regexp`.
7505      *
7506      *     should.not.throw(fn, Error, 'function does not throw');
7507      *
7508      * @name not.throw
7509      * @alias not.Throw
7510      * @param {Function} function
7511      * @param {ErrorConstructor} constructor
7512      * @param {RegExp} regexp
7513      * @param {String} message
7514      * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
7515      * @namespace Should
7516      * @api public
7517      */
7518
7519     should.not.Throw = function (fn, errt, errs, msg) {
7520       new Assertion(fn, msg).to.not.Throw(errt, errs);
7521     };
7522
7523     /**
7524      * ### .not.exist
7525      *
7526      * Asserts that the target is neither `null` nor `undefined`.
7527      *
7528      *     var bar = null;
7529      *
7530      *     should.not.exist(bar, 'bar does not exist');
7531      *
7532      * @name not.exist
7533      * @namespace Should
7534      * @api public
7535      */
7536
7537     should.not.exist = function (val, msg) {
7538       new Assertion(val, msg).to.not.exist;
7539     }
7540
7541     should['throw'] = should['Throw'];
7542     should.not['throw'] = should.not['Throw'];
7543
7544     return should;
7545   };
7546
7547   chai.should = loadShould;
7548   chai.Should = loadShould;
7549 };
7550
7551 },{}],9:[function(require,module,exports){
7552 /*!
7553  * Chai - addChainingMethod utility
7554  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
7555  * MIT Licensed
7556  */
7557
7558 /*!
7559  * Module dependencies
7560  */
7561
7562 var addLengthGuard = require('./addLengthGuard');
7563 var chai = require('../../chai');
7564 var flag = require('./flag');
7565 var proxify = require('./proxify');
7566 var transferFlags = require('./transferFlags');
7567
7568 /*!
7569  * Module variables
7570  */
7571
7572 // Check whether `Object.setPrototypeOf` is supported
7573 var canSetPrototype = typeof Object.setPrototypeOf === 'function';
7574
7575 // Without `Object.setPrototypeOf` support, this module will need to add properties to a function.
7576 // However, some of functions' own props are not configurable and should be skipped.
7577 var testFn = function() {};
7578 var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) {
7579   var propDesc = Object.getOwnPropertyDescriptor(testFn, name);
7580
7581   // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties,
7582   // but then returns `undefined` as the property descriptor for `callee`. As a
7583   // workaround, we perform an otherwise unnecessary type-check for `propDesc`,
7584   // and then filter it out if it's not an object as it should be.
7585   if (typeof propDesc !== 'object')
7586     return true;
7587
7588   return !propDesc.configurable;
7589 });
7590
7591 // Cache `Function` properties
7592 var call  = Function.prototype.call,
7593     apply = Function.prototype.apply;
7594
7595 /**
7596  * ### .addChainableMethod(ctx, name, method, chainingBehavior)
7597  *
7598  * Adds a method to an object, such that the method can also be chained.
7599  *
7600  *     utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {
7601  *       var obj = utils.flag(this, 'object');
7602  *       new chai.Assertion(obj).to.be.equal(str);
7603  *     });
7604  *
7605  * Can also be accessed directly from `chai.Assertion`.
7606  *
7607  *     chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);
7608  *
7609  * The result can then be used as both a method assertion, executing both `method` and
7610  * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.
7611  *
7612  *     expect(fooStr).to.be.foo('bar');
7613  *     expect(fooStr).to.be.foo.equal('foo');
7614  *
7615  * @param {Object} ctx object to which the method is added
7616  * @param {String} name of method to add
7617  * @param {Function} method function to be used for `name`, when called
7618  * @param {Function} chainingBehavior function to be called every time the property is accessed
7619  * @namespace Utils
7620  * @name addChainableMethod
7621  * @api public
7622  */
7623
7624 module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) {
7625   if (typeof chainingBehavior !== 'function') {
7626     chainingBehavior = function () { };
7627   }
7628
7629   var chainableBehavior = {
7630       method: method
7631     , chainingBehavior: chainingBehavior
7632   };
7633
7634   // save the methods so we can overwrite them later, if we need to.
7635   if (!ctx.__methods) {
7636     ctx.__methods = {};
7637   }
7638   ctx.__methods[name] = chainableBehavior;
7639
7640   Object.defineProperty(ctx, name,
7641     { get: function chainableMethodGetter() {
7642         chainableBehavior.chainingBehavior.call(this);
7643
7644         var chainableMethodWrapper = function () {
7645           // Setting the `ssfi` flag to `chainableMethodWrapper` causes this
7646           // function to be the starting point for removing implementation
7647           // frames from the stack trace of a failed assertion.
7648           //
7649           // However, we only want to use this function as the starting point if
7650           // the `lockSsfi` flag isn't set.
7651           //
7652           // If the `lockSsfi` flag is set, then this assertion is being
7653           // invoked from inside of another assertion. In this case, the `ssfi`
7654           // flag has already been set by the outer assertion.
7655           //
7656           // Note that overwriting a chainable method merely replaces the saved
7657           // methods in `ctx.__methods` instead of completely replacing the
7658           // overwritten assertion. Therefore, an overwriting assertion won't
7659           // set the `ssfi` or `lockSsfi` flags.
7660           if (!flag(this, 'lockSsfi')) {
7661             flag(this, 'ssfi', chainableMethodWrapper);
7662           }
7663
7664           var result = chainableBehavior.method.apply(this, arguments);
7665           if (result !== undefined) {
7666             return result;
7667           }
7668
7669           var newAssertion = new chai.Assertion();
7670           transferFlags(this, newAssertion);
7671           return newAssertion;
7672         };
7673
7674         addLengthGuard(chainableMethodWrapper, name, true);
7675
7676         // Use `Object.setPrototypeOf` if available
7677         if (canSetPrototype) {
7678           // Inherit all properties from the object by replacing the `Function` prototype
7679           var prototype = Object.create(this);
7680           // Restore the `call` and `apply` methods from `Function`
7681           prototype.call = call;
7682           prototype.apply = apply;
7683           Object.setPrototypeOf(chainableMethodWrapper, prototype);
7684         }
7685         // Otherwise, redefine all properties (slow!)
7686         else {
7687           var asserterNames = Object.getOwnPropertyNames(ctx);
7688           asserterNames.forEach(function (asserterName) {
7689             if (excludeNames.indexOf(asserterName) !== -1) {
7690               return;
7691             }
7692
7693             var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);
7694             Object.defineProperty(chainableMethodWrapper, asserterName, pd);
7695           });
7696         }
7697
7698         transferFlags(this, chainableMethodWrapper);
7699         return proxify(chainableMethodWrapper);
7700       }
7701     , configurable: true
7702   });
7703 };
7704
7705 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],10:[function(require,module,exports){
7706 var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length');
7707
7708 /*!
7709  * Chai - addLengthGuard utility
7710  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
7711  * MIT Licensed
7712  */
7713
7714 /**
7715  * ### .addLengthGuard(fn, assertionName, isChainable)
7716  *
7717  * Define `length` as a getter on the given uninvoked method assertion. The
7718  * getter acts as a guard against chaining `length` directly off of an uninvoked
7719  * method assertion, which is a problem because it references `function`'s
7720  * built-in `length` property instead of Chai's `length` assertion. When the
7721  * getter catches the user making this mistake, it throws an error with a
7722  * helpful message.
7723  *
7724  * There are two ways in which this mistake can be made. The first way is by
7725  * chaining the `length` assertion directly off of an uninvoked chainable
7726  * method. In this case, Chai suggests that the user use `lengthOf` instead. The
7727  * second way is by chaining the `length` assertion directly off of an uninvoked
7728  * non-chainable method. Non-chainable methods must be invoked prior to
7729  * chaining. In this case, Chai suggests that the user consult the docs for the
7730  * given assertion.
7731  *
7732  * If the `length` property of functions is unconfigurable, then return `fn`
7733  * without modification.
7734  *
7735  * Note that in ES6, the function's `length` property is configurable, so once
7736  * support for legacy environments is dropped, Chai's `length` property can
7737  * replace the built-in function's `length` property, and this length guard will
7738  * no longer be necessary. In the mean time, maintaining consistency across all
7739  * environments is the priority.
7740  *
7741  * @param {Function} fn
7742  * @param {String} assertionName
7743  * @param {Boolean} isChainable
7744  * @namespace Utils
7745  * @name addLengthGuard
7746  */
7747
7748 module.exports = function addLengthGuard (fn, assertionName, isChainable) {
7749   if (!fnLengthDesc.configurable) return fn;
7750
7751   Object.defineProperty(fn, 'length', {
7752     get: function () {
7753       if (isChainable) {
7754         throw Error('Invalid Chai property: ' + assertionName + '.length. Due' +
7755           ' to a compatibility issue, "length" cannot directly follow "' +
7756           assertionName + '". Use "' + assertionName + '.lengthOf" instead.');
7757       }
7758
7759       throw Error('Invalid Chai property: ' + assertionName + '.length. See' +
7760         ' docs for proper usage of "' + assertionName + '".');
7761     }
7762   });
7763
7764   return fn;
7765 };
7766
7767 },{}],11:[function(require,module,exports){
7768 /*!
7769  * Chai - addMethod utility
7770  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
7771  * MIT Licensed
7772  */
7773
7774 var addLengthGuard = require('./addLengthGuard');
7775 var chai = require('../../chai');
7776 var flag = require('./flag');
7777 var proxify = require('./proxify');
7778 var transferFlags = require('./transferFlags');
7779
7780 /**
7781  * ### .addMethod(ctx, name, method)
7782  *
7783  * Adds a method to the prototype of an object.
7784  *
7785  *     utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {
7786  *       var obj = utils.flag(this, 'object');
7787  *       new chai.Assertion(obj).to.be.equal(str);
7788  *     });
7789  *
7790  * Can also be accessed directly from `chai.Assertion`.
7791  *
7792  *     chai.Assertion.addMethod('foo', fn);
7793  *
7794  * Then can be used as any other assertion.
7795  *
7796  *     expect(fooStr).to.be.foo('bar');
7797  *
7798  * @param {Object} ctx object to which the method is added
7799  * @param {String} name of method to add
7800  * @param {Function} method function to be used for name
7801  * @namespace Utils
7802  * @name addMethod
7803  * @api public
7804  */
7805
7806 module.exports = function addMethod(ctx, name, method) {
7807   var methodWrapper = function () {
7808     // Setting the `ssfi` flag to `methodWrapper` causes this function to be the
7809     // starting point for removing implementation frames from the stack trace of
7810     // a failed assertion.
7811     //
7812     // However, we only want to use this function as the starting point if the
7813     // `lockSsfi` flag isn't set.
7814     //
7815     // If the `lockSsfi` flag is set, then either this assertion has been
7816     // overwritten by another assertion, or this assertion is being invoked from
7817     // inside of another assertion. In the first case, the `ssfi` flag has
7818     // already been set by the overwriting assertion. In the second case, the
7819     // `ssfi` flag has already been set by the outer assertion.
7820     if (!flag(this, 'lockSsfi')) {
7821       flag(this, 'ssfi', methodWrapper);
7822     }
7823
7824     var result = method.apply(this, arguments);
7825     if (result !== undefined)
7826       return result;
7827
7828     var newAssertion = new chai.Assertion();
7829     transferFlags(this, newAssertion);
7830     return newAssertion;
7831   };
7832
7833   addLengthGuard(methodWrapper, name, false);
7834   ctx[name] = proxify(methodWrapper, name);
7835 };
7836
7837 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],12:[function(require,module,exports){
7838 /*!
7839  * Chai - addProperty utility
7840  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
7841  * MIT Licensed
7842  */
7843
7844 var chai = require('../../chai');
7845 var flag = require('./flag');
7846 var isProxyEnabled = require('./isProxyEnabled');
7847 var transferFlags = require('./transferFlags');
7848
7849 /**
7850  * ### .addProperty(ctx, name, getter)
7851  *
7852  * Adds a property to the prototype of an object.
7853  *
7854  *     utils.addProperty(chai.Assertion.prototype, 'foo', function () {
7855  *       var obj = utils.flag(this, 'object');
7856  *       new chai.Assertion(obj).to.be.instanceof(Foo);
7857  *     });
7858  *
7859  * Can also be accessed directly from `chai.Assertion`.
7860  *
7861  *     chai.Assertion.addProperty('foo', fn);
7862  *
7863  * Then can be used as any other assertion.
7864  *
7865  *     expect(myFoo).to.be.foo;
7866  *
7867  * @param {Object} ctx object to which the property is added
7868  * @param {String} name of property to add
7869  * @param {Function} getter function to be used for name
7870  * @namespace Utils
7871  * @name addProperty
7872  * @api public
7873  */
7874
7875 module.exports = function addProperty(ctx, name, getter) {
7876   getter = getter === undefined ? function () {} : getter;
7877
7878   Object.defineProperty(ctx, name,
7879     { get: function propertyGetter() {
7880         // Setting the `ssfi` flag to `propertyGetter` causes this function to
7881         // be the starting point for removing implementation frames from the
7882         // stack trace of a failed assertion.
7883         //
7884         // However, we only want to use this function as the starting point if
7885         // the `lockSsfi` flag isn't set and proxy protection is disabled.
7886         //
7887         // If the `lockSsfi` flag is set, then either this assertion has been
7888         // overwritten by another assertion, or this assertion is being invoked
7889         // from inside of another assertion. In the first case, the `ssfi` flag
7890         // has already been set by the overwriting assertion. In the second
7891         // case, the `ssfi` flag has already been set by the outer assertion.
7892         //
7893         // If proxy protection is enabled, then the `ssfi` flag has already been
7894         // set by the proxy getter.
7895         if (!isProxyEnabled() && !flag(this, 'lockSsfi')) {
7896           flag(this, 'ssfi', propertyGetter);
7897         }
7898
7899         var result = getter.call(this);
7900         if (result !== undefined)
7901           return result;
7902
7903         var newAssertion = new chai.Assertion();
7904         transferFlags(this, newAssertion);
7905         return newAssertion;
7906       }
7907     , configurable: true
7908   });
7909 };
7910
7911 },{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],13:[function(require,module,exports){
7912 /*!
7913  * Chai - compareByInspect utility
7914  * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
7915  * MIT Licensed
7916  */
7917
7918 /*!
7919  * Module dependencies
7920  */
7921
7922 var inspect = require('./inspect');
7923
7924 /**
7925  * ### .compareByInspect(mixed, mixed)
7926  *
7927  * To be used as a compareFunction with Array.prototype.sort. Compares elements
7928  * using inspect instead of default behavior of using toString so that Symbols
7929  * and objects with irregular/missing toString can still be sorted without a
7930  * TypeError.
7931  *
7932  * @param {Mixed} first element to compare
7933  * @param {Mixed} second element to compare
7934  * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1
7935  * @name compareByInspect
7936  * @namespace Utils
7937  * @api public
7938  */
7939
7940 module.exports = function compareByInspect(a, b) {
7941   return inspect(a) < inspect(b) ? -1 : 1;
7942 };
7943
7944 },{"./inspect":23}],14:[function(require,module,exports){
7945 /*!
7946  * Chai - expectTypes utility
7947  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
7948  * MIT Licensed
7949  */
7950
7951 /**
7952  * ### .expectTypes(obj, types)
7953  *
7954  * Ensures that the object being tested against is of a valid type.
7955  *
7956  *     utils.expectTypes(this, ['array', 'object', 'string']);
7957  *
7958  * @param {Mixed} obj constructed Assertion
7959  * @param {Array} type A list of allowed types for this assertion
7960  * @namespace Utils
7961  * @name expectTypes
7962  * @api public
7963  */
7964
7965 var AssertionError = require('assertion-error');
7966 var flag = require('./flag');
7967 var type = require('type-detect');
7968
7969 module.exports = function expectTypes(obj, types) {
7970   var flagMsg = flag(obj, 'message');
7971   var ssfi = flag(obj, 'ssfi');
7972
7973   flagMsg = flagMsg ? flagMsg + ': ' : '';
7974
7975   obj = flag(obj, 'object');
7976   types = types.map(function (t) { return t.toLowerCase(); });
7977   types.sort();
7978
7979   // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum'
7980   var str = types.map(function (t, index) {
7981     var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';
7982     var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';
7983     return or + art + ' ' + t;
7984   }).join(', ');
7985
7986   var objType = type(obj).toLowerCase();
7987
7988   if (!types.some(function (expected) { return objType === expected; })) {
7989     throw new AssertionError(
7990       flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given',
7991       undefined,
7992       ssfi
7993     );
7994   }
7995 };
7996
7997 },{"./flag":15,"assertion-error":33,"type-detect":38}],15:[function(require,module,exports){
7998 /*!
7999  * Chai - flag utility
8000  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8001  * MIT Licensed
8002  */
8003
8004 /**
8005  * ### .flag(object, key, [value])
8006  *
8007  * Get or set a flag value on an object. If a
8008  * value is provided it will be set, else it will
8009  * return the currently set value or `undefined` if
8010  * the value is not set.
8011  *
8012  *     utils.flag(this, 'foo', 'bar'); // setter
8013  *     utils.flag(this, 'foo'); // getter, returns `bar`
8014  *
8015  * @param {Object} object constructed Assertion
8016  * @param {String} key
8017  * @param {Mixed} value (optional)
8018  * @namespace Utils
8019  * @name flag
8020  * @api private
8021  */
8022
8023 module.exports = function flag(obj, key, value) {
8024   var flags = obj.__flags || (obj.__flags = Object.create(null));
8025   if (arguments.length === 3) {
8026     flags[key] = value;
8027   } else {
8028     return flags[key];
8029   }
8030 };
8031
8032 },{}],16:[function(require,module,exports){
8033 /*!
8034  * Chai - getActual utility
8035  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8036  * MIT Licensed
8037  */
8038
8039 /**
8040  * ### .getActual(object, [actual])
8041  *
8042  * Returns the `actual` value for an Assertion.
8043  *
8044  * @param {Object} object (constructed Assertion)
8045  * @param {Arguments} chai.Assertion.prototype.assert arguments
8046  * @namespace Utils
8047  * @name getActual
8048  */
8049
8050 module.exports = function getActual(obj, args) {
8051   return args.length > 4 ? args[4] : obj._obj;
8052 };
8053
8054 },{}],17:[function(require,module,exports){
8055 /*!
8056  * Chai - getEnumerableProperties utility
8057  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8058  * MIT Licensed
8059  */
8060
8061 /**
8062  * ### .getEnumerableProperties(object)
8063  *
8064  * This allows the retrieval of enumerable property names of an object,
8065  * inherited or not.
8066  *
8067  * @param {Object} object
8068  * @returns {Array}
8069  * @namespace Utils
8070  * @name getEnumerableProperties
8071  * @api public
8072  */
8073
8074 module.exports = function getEnumerableProperties(object) {
8075   var result = [];
8076   for (var name in object) {
8077     result.push(name);
8078   }
8079   return result;
8080 };
8081
8082 },{}],18:[function(require,module,exports){
8083 /*!
8084  * Chai - message composition utility
8085  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8086  * MIT Licensed
8087  */
8088
8089 /*!
8090  * Module dependencies
8091  */
8092
8093 var flag = require('./flag')
8094   , getActual = require('./getActual')
8095   , objDisplay = require('./objDisplay');
8096
8097 /**
8098  * ### .getMessage(object, message, negateMessage)
8099  *
8100  * Construct the error message based on flags
8101  * and template tags. Template tags will return
8102  * a stringified inspection of the object referenced.
8103  *
8104  * Message template tags:
8105  * - `#{this}` current asserted object
8106  * - `#{act}` actual value
8107  * - `#{exp}` expected value
8108  *
8109  * @param {Object} object (constructed Assertion)
8110  * @param {Arguments} chai.Assertion.prototype.assert arguments
8111  * @namespace Utils
8112  * @name getMessage
8113  * @api public
8114  */
8115
8116 module.exports = function getMessage(obj, args) {
8117   var negate = flag(obj, 'negate')
8118     , val = flag(obj, 'object')
8119     , expected = args[3]
8120     , actual = getActual(obj, args)
8121     , msg = negate ? args[2] : args[1]
8122     , flagMsg = flag(obj, 'message');
8123
8124   if(typeof msg === "function") msg = msg();
8125   msg = msg || '';
8126   msg = msg
8127     .replace(/#\{this\}/g, function () { return objDisplay(val); })
8128     .replace(/#\{act\}/g, function () { return objDisplay(actual); })
8129     .replace(/#\{exp\}/g, function () { return objDisplay(expected); });
8130
8131   return flagMsg ? flagMsg + ': ' + msg : msg;
8132 };
8133
8134 },{"./flag":15,"./getActual":16,"./objDisplay":26}],19:[function(require,module,exports){
8135 /*!
8136  * Chai - getOwnEnumerableProperties utility
8137  * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
8138  * MIT Licensed
8139  */
8140
8141 /*!
8142  * Module dependencies
8143  */
8144
8145 var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
8146
8147 /**
8148  * ### .getOwnEnumerableProperties(object)
8149  *
8150  * This allows the retrieval of directly-owned enumerable property names and
8151  * symbols of an object. This function is necessary because Object.keys only
8152  * returns enumerable property names, not enumerable property symbols.
8153  *
8154  * @param {Object} object
8155  * @returns {Array}
8156  * @namespace Utils
8157  * @name getOwnEnumerableProperties
8158  * @api public
8159  */
8160
8161 module.exports = function getOwnEnumerableProperties(obj) {
8162   return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj));
8163 };
8164
8165 },{"./getOwnEnumerablePropertySymbols":20}],20:[function(require,module,exports){
8166 /*!
8167  * Chai - getOwnEnumerablePropertySymbols utility
8168  * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
8169  * MIT Licensed
8170  */
8171
8172 /**
8173  * ### .getOwnEnumerablePropertySymbols(object)
8174  *
8175  * This allows the retrieval of directly-owned enumerable property symbols of an
8176  * object. This function is necessary because Object.getOwnPropertySymbols
8177  * returns both enumerable and non-enumerable property symbols.
8178  *
8179  * @param {Object} object
8180  * @returns {Array}
8181  * @namespace Utils
8182  * @name getOwnEnumerablePropertySymbols
8183  * @api public
8184  */
8185
8186 module.exports = function getOwnEnumerablePropertySymbols(obj) {
8187   if (typeof Object.getOwnPropertySymbols !== 'function') return [];
8188
8189   return Object.getOwnPropertySymbols(obj).filter(function (sym) {
8190     return Object.getOwnPropertyDescriptor(obj, sym).enumerable;
8191   });
8192 };
8193
8194 },{}],21:[function(require,module,exports){
8195 /*!
8196  * Chai - getProperties utility
8197  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8198  * MIT Licensed
8199  */
8200
8201 /**
8202  * ### .getProperties(object)
8203  *
8204  * This allows the retrieval of property names of an object, enumerable or not,
8205  * inherited or not.
8206  *
8207  * @param {Object} object
8208  * @returns {Array}
8209  * @namespace Utils
8210  * @name getProperties
8211  * @api public
8212  */
8213
8214 module.exports = function getProperties(object) {
8215   var result = Object.getOwnPropertyNames(object);
8216
8217   function addProperty(property) {
8218     if (result.indexOf(property) === -1) {
8219       result.push(property);
8220     }
8221   }
8222
8223   var proto = Object.getPrototypeOf(object);
8224   while (proto !== null) {
8225     Object.getOwnPropertyNames(proto).forEach(addProperty);
8226     proto = Object.getPrototypeOf(proto);
8227   }
8228
8229   return result;
8230 };
8231
8232 },{}],22:[function(require,module,exports){
8233 /*!
8234  * chai
8235  * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
8236  * MIT Licensed
8237  */
8238
8239 /*!
8240  * Dependencies that are used for multiple exports are required here only once
8241  */
8242
8243 var pathval = require('pathval');
8244
8245 /*!
8246  * test utility
8247  */
8248
8249 exports.test = require('./test');
8250
8251 /*!
8252  * type utility
8253  */
8254
8255 exports.type = require('type-detect');
8256
8257 /*!
8258  * expectTypes utility
8259  */
8260 exports.expectTypes = require('./expectTypes');
8261
8262 /*!
8263  * message utility
8264  */
8265
8266 exports.getMessage = require('./getMessage');
8267
8268 /*!
8269  * actual utility
8270  */
8271
8272 exports.getActual = require('./getActual');
8273
8274 /*!
8275  * Inspect util
8276  */
8277
8278 exports.inspect = require('./inspect');
8279
8280 /*!
8281  * Object Display util
8282  */
8283
8284 exports.objDisplay = require('./objDisplay');
8285
8286 /*!
8287  * Flag utility
8288  */
8289
8290 exports.flag = require('./flag');
8291
8292 /*!
8293  * Flag transferring utility
8294  */
8295
8296 exports.transferFlags = require('./transferFlags');
8297
8298 /*!
8299  * Deep equal utility
8300  */
8301
8302 exports.eql = require('deep-eql');
8303
8304 /*!
8305  * Deep path info
8306  */
8307
8308 exports.getPathInfo = pathval.getPathInfo;
8309
8310 /*!
8311  * Check if a property exists
8312  */
8313
8314 exports.hasProperty = pathval.hasProperty;
8315
8316 /*!
8317  * Function name
8318  */
8319
8320 exports.getName = require('get-func-name');
8321
8322 /*!
8323  * add Property
8324  */
8325
8326 exports.addProperty = require('./addProperty');
8327
8328 /*!
8329  * add Method
8330  */
8331
8332 exports.addMethod = require('./addMethod');
8333
8334 /*!
8335  * overwrite Property
8336  */
8337
8338 exports.overwriteProperty = require('./overwriteProperty');
8339
8340 /*!
8341  * overwrite Method
8342  */
8343
8344 exports.overwriteMethod = require('./overwriteMethod');
8345
8346 /*!
8347  * Add a chainable method
8348  */
8349
8350 exports.addChainableMethod = require('./addChainableMethod');
8351
8352 /*!
8353  * Overwrite chainable method
8354  */
8355
8356 exports.overwriteChainableMethod = require('./overwriteChainableMethod');
8357
8358 /*!
8359  * Compare by inspect method
8360  */
8361
8362 exports.compareByInspect = require('./compareByInspect');
8363
8364 /*!
8365  * Get own enumerable property symbols method
8366  */
8367
8368 exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
8369
8370 /*!
8371  * Get own enumerable properties method
8372  */
8373
8374 exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties');
8375
8376 /*!
8377  * Checks error against a given set of criteria
8378  */
8379
8380 exports.checkError = require('check-error');
8381
8382 /*!
8383  * Proxify util
8384  */
8385
8386 exports.proxify = require('./proxify');
8387
8388 /*!
8389  * addLengthGuard util
8390  */
8391
8392 exports.addLengthGuard = require('./addLengthGuard');
8393
8394 /*!
8395  * isProxyEnabled helper
8396  */
8397
8398 exports.isProxyEnabled = require('./isProxyEnabled');
8399
8400 /*!
8401  * isNaN method
8402  */
8403
8404 exports.isNaN = require('./isNaN');
8405
8406 },{"./addChainableMethod":9,"./addLengthGuard":10,"./addMethod":11,"./addProperty":12,"./compareByInspect":13,"./expectTypes":14,"./flag":15,"./getActual":16,"./getMessage":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":37,"type-detect":38}],23:[function(require,module,exports){
8407 // This is (almost) directly from Node.js utils
8408 // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
8409
8410 var getName = require('get-func-name');
8411 var getProperties = require('./getProperties');
8412 var getEnumerableProperties = require('./getEnumerableProperties');
8413 var config = require('../config');
8414
8415 module.exports = inspect;
8416
8417 /**
8418  * ### .inspect(obj, [showHidden], [depth], [colors])
8419  *
8420  * Echoes the value of a value. Tries to print the value out
8421  * in the best way possible given the different types.
8422  *
8423  * @param {Object} obj The object to print out.
8424  * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
8425  *    properties of objects. Default is false.
8426  * @param {Number} depth Depth in which to descend in object. Default is 2.
8427  * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
8428  *    output. Default is false (no coloring).
8429  * @namespace Utils
8430  * @name inspect
8431  */
8432 function inspect(obj, showHidden, depth, colors) {
8433   var ctx = {
8434     showHidden: showHidden,
8435     seen: [],
8436     stylize: function (str) { return str; }
8437   };
8438   return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
8439 }
8440
8441 // Returns true if object is a DOM element.
8442 var isDOMElement = function (object) {
8443   if (typeof HTMLElement === 'object') {
8444     return object instanceof HTMLElement;
8445   } else {
8446     return object &&
8447       typeof object === 'object' &&
8448       'nodeType' in object &&
8449       object.nodeType === 1 &&
8450       typeof object.nodeName === 'string';
8451   }
8452 };
8453
8454 function formatValue(ctx, value, recurseTimes) {
8455   // Provide a hook for user-specified inspect functions.
8456   // Check that value is an object with an inspect function on it
8457   if (value && typeof value.inspect === 'function' &&
8458       // Filter out the util module, it's inspect function is special
8459       value.inspect !== exports.inspect &&
8460       // Also filter out any prototype objects using the circular check.
8461       !(value.constructor && value.constructor.prototype === value)) {
8462     var ret = value.inspect(recurseTimes, ctx);
8463     if (typeof ret !== 'string') {
8464       ret = formatValue(ctx, ret, recurseTimes);
8465     }
8466     return ret;
8467   }
8468
8469   // Primitive types cannot have properties
8470   var primitive = formatPrimitive(ctx, value);
8471   if (primitive) {
8472     return primitive;
8473   }
8474
8475   // If this is a DOM element, try to get the outer HTML.
8476   if (isDOMElement(value)) {
8477     if ('outerHTML' in value) {
8478       return value.outerHTML;
8479       // This value does not have an outerHTML attribute,
8480       //   it could still be an XML element
8481     } else {
8482       // Attempt to serialize it
8483       try {
8484         if (document.xmlVersion) {
8485           var xmlSerializer = new XMLSerializer();
8486           return xmlSerializer.serializeToString(value);
8487         } else {
8488           // Firefox 11- do not support outerHTML
8489           //   It does, however, support innerHTML
8490           //   Use the following to render the element
8491           var ns = "http://www.w3.org/1999/xhtml";
8492           var container = document.createElementNS(ns, '_');
8493
8494           container.appendChild(value.cloneNode(false));
8495           var html = container.innerHTML
8496             .replace('><', '>' + value.innerHTML + '<');
8497           container.innerHTML = '';
8498           return html;
8499         }
8500       } catch (err) {
8501         // This could be a non-native DOM implementation,
8502         //   continue with the normal flow:
8503         //   printing the element as if it is an object.
8504       }
8505     }
8506   }
8507
8508   // Look up the keys of the object.
8509   var visibleKeys = getEnumerableProperties(value);
8510   var keys = ctx.showHidden ? getProperties(value) : visibleKeys;
8511
8512   var name, nameSuffix;
8513
8514   // Some type of object without properties can be shortcut.
8515   // In IE, errors have a single `stack` property, or if they are vanilla `Error`,
8516   // a `stack` plus `description` property; ignore those for consistency.
8517   if (keys.length === 0 || (isError(value) && (
8518       (keys.length === 1 && keys[0] === 'stack') ||
8519       (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')
8520      ))) {
8521     if (typeof value === 'function') {
8522       name = getName(value);
8523       nameSuffix = name ? ': ' + name : '';
8524       return ctx.stylize('[Function' + nameSuffix + ']', 'special');
8525     }
8526     if (isRegExp(value)) {
8527       return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
8528     }
8529     if (isDate(value)) {
8530       return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
8531     }
8532     if (isError(value)) {
8533       return formatError(value);
8534     }
8535   }
8536
8537   var base = ''
8538     , array = false
8539     , typedArray = false
8540     , braces = ['{', '}'];
8541
8542   if (isTypedArray(value)) {
8543     typedArray = true;
8544     braces = ['[', ']'];
8545   }
8546
8547   // Make Array say that they are Array
8548   if (isArray(value)) {
8549     array = true;
8550     braces = ['[', ']'];
8551   }
8552
8553   // Make functions say that they are functions
8554   if (typeof value === 'function') {
8555     name = getName(value);
8556     nameSuffix = name ? ': ' + name : '';
8557     base = ' [Function' + nameSuffix + ']';
8558   }
8559
8560   // Make RegExps say that they are RegExps
8561   if (isRegExp(value)) {
8562     base = ' ' + RegExp.prototype.toString.call(value);
8563   }
8564
8565   // Make dates with properties first say the date
8566   if (isDate(value)) {
8567     base = ' ' + Date.prototype.toUTCString.call(value);
8568   }
8569
8570   // Make error with message first say the error
8571   if (isError(value)) {
8572     return formatError(value);
8573   }
8574
8575   if (keys.length === 0 && (!array || value.length == 0)) {
8576     return braces[0] + base + braces[1];
8577   }
8578
8579   if (recurseTimes < 0) {
8580     if (isRegExp(value)) {
8581       return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
8582     } else {
8583       return ctx.stylize('[Object]', 'special');
8584     }
8585   }
8586
8587   ctx.seen.push(value);
8588
8589   var output;
8590   if (array) {
8591     output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
8592   } else if (typedArray) {
8593     return formatTypedArray(value);
8594   } else {
8595     output = keys.map(function(key) {
8596       return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
8597     });
8598   }
8599
8600   ctx.seen.pop();
8601
8602   return reduceToSingleString(output, base, braces);
8603 }
8604
8605 function formatPrimitive(ctx, value) {
8606   switch (typeof value) {
8607     case 'undefined':
8608       return ctx.stylize('undefined', 'undefined');
8609
8610     case 'string':
8611       var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
8612                                                .replace(/'/g, "\\'")
8613                                                .replace(/\\"/g, '"') + '\'';
8614       return ctx.stylize(simple, 'string');
8615
8616     case 'number':
8617       if (value === 0 && (1/value) === -Infinity) {
8618         return ctx.stylize('-0', 'number');
8619       }
8620       return ctx.stylize('' + value, 'number');
8621
8622     case 'boolean':
8623       return ctx.stylize('' + value, 'boolean');
8624
8625     case 'symbol':
8626       return ctx.stylize(value.toString(), 'symbol');
8627   }
8628   // For some reason typeof null is "object", so special case here.
8629   if (value === null) {
8630     return ctx.stylize('null', 'null');
8631   }
8632 }
8633
8634 function formatError(value) {
8635   return '[' + Error.prototype.toString.call(value) + ']';
8636 }
8637
8638 function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
8639   var output = [];
8640   for (var i = 0, l = value.length; i < l; ++i) {
8641     if (Object.prototype.hasOwnProperty.call(value, String(i))) {
8642       output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
8643           String(i), true));
8644     } else {
8645       output.push('');
8646     }
8647   }
8648
8649   keys.forEach(function(key) {
8650     if (!key.match(/^\d+$/)) {
8651       output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
8652           key, true));
8653     }
8654   });
8655   return output;
8656 }
8657
8658 function formatTypedArray(value) {
8659   var str = '[ ';
8660
8661   for (var i = 0; i < value.length; ++i) {
8662     if (str.length >= config.truncateThreshold - 7) {
8663       str += '...';
8664       break;
8665     }
8666     str += value[i] + ', ';
8667   }
8668   str += ' ]';
8669
8670   // Removing trailing `, ` if the array was not truncated
8671   if (str.indexOf(',  ]') !== -1) {
8672     str = str.replace(',  ]', ' ]');
8673   }
8674
8675   return str;
8676 }
8677
8678 function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
8679   var name;
8680   var propDescriptor = Object.getOwnPropertyDescriptor(value, key);
8681   var str;
8682
8683   if (propDescriptor) {
8684     if (propDescriptor.get) {
8685       if (propDescriptor.set) {
8686         str = ctx.stylize('[Getter/Setter]', 'special');
8687       } else {
8688         str = ctx.stylize('[Getter]', 'special');
8689       }
8690     } else {
8691       if (propDescriptor.set) {
8692         str = ctx.stylize('[Setter]', 'special');
8693       }
8694     }
8695   }
8696   if (visibleKeys.indexOf(key) < 0) {
8697     name = '[' + key + ']';
8698   }
8699   if (!str) {
8700     if (ctx.seen.indexOf(value[key]) < 0) {
8701       if (recurseTimes === null) {
8702         str = formatValue(ctx, value[key], null);
8703       } else {
8704         str = formatValue(ctx, value[key], recurseTimes - 1);
8705       }
8706       if (str.indexOf('\n') > -1) {
8707         if (array) {
8708           str = str.split('\n').map(function(line) {
8709             return '  ' + line;
8710           }).join('\n').substr(2);
8711         } else {
8712           str = '\n' + str.split('\n').map(function(line) {
8713             return '   ' + line;
8714           }).join('\n');
8715         }
8716       }
8717     } else {
8718       str = ctx.stylize('[Circular]', 'special');
8719     }
8720   }
8721   if (typeof name === 'undefined') {
8722     if (array && key.match(/^\d+$/)) {
8723       return str;
8724     }
8725     name = JSON.stringify('' + key);
8726     if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
8727       name = name.substr(1, name.length - 2);
8728       name = ctx.stylize(name, 'name');
8729     } else {
8730       name = name.replace(/'/g, "\\'")
8731                  .replace(/\\"/g, '"')
8732                  .replace(/(^"|"$)/g, "'");
8733       name = ctx.stylize(name, 'string');
8734     }
8735   }
8736
8737   return name + ': ' + str;
8738 }
8739
8740 function reduceToSingleString(output, base, braces) {
8741   var length = output.reduce(function(prev, cur) {
8742     return prev + cur.length + 1;
8743   }, 0);
8744
8745   if (length > 60) {
8746     return braces[0] +
8747            (base === '' ? '' : base + '\n ') +
8748            ' ' +
8749            output.join(',\n  ') +
8750            ' ' +
8751            braces[1];
8752   }
8753
8754   return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
8755 }
8756
8757 function isTypedArray(ar) {
8758   // Unfortunately there's no way to check if an object is a TypedArray
8759   // We have to check if it's one of these types
8760   return (typeof ar === 'object' && /\w+Array]$/.test(objectToString(ar)));
8761 }
8762
8763 function isArray(ar) {
8764   return Array.isArray(ar) ||
8765          (typeof ar === 'object' && objectToString(ar) === '[object Array]');
8766 }
8767
8768 function isRegExp(re) {
8769   return typeof re === 'object' && objectToString(re) === '[object RegExp]';
8770 }
8771
8772 function isDate(d) {
8773   return typeof d === 'object' && objectToString(d) === '[object Date]';
8774 }
8775
8776 function isError(e) {
8777   return typeof e === 'object' && objectToString(e) === '[object Error]';
8778 }
8779
8780 function objectToString(o) {
8781   return Object.prototype.toString.call(o);
8782 }
8783
8784 },{"../config":4,"./getEnumerableProperties":17,"./getProperties":21,"get-func-name":36}],24:[function(require,module,exports){
8785 /*!
8786  * Chai - isNaN utility
8787  * Copyright(c) 2012-2015 Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
8788  * MIT Licensed
8789  */
8790
8791 /**
8792  * ### .isNaN(value)
8793  *
8794  * Checks if the given value is NaN or not.
8795  *
8796  *     utils.isNaN(NaN); // true
8797  *
8798  * @param {Value} The value which has to be checked if it is NaN
8799  * @name isNaN
8800  * @api private
8801  */
8802
8803 function isNaN(value) {
8804   // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number
8805   // section's NOTE.
8806   return value !== value;
8807 }
8808
8809 // If ECMAScript 6's Number.isNaN is present, prefer that.
8810 module.exports = Number.isNaN || isNaN;
8811
8812 },{}],25:[function(require,module,exports){
8813 var config = require('../config');
8814
8815 /*!
8816  * Chai - isProxyEnabled helper
8817  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8818  * MIT Licensed
8819  */
8820
8821 /**
8822  * ### .isProxyEnabled()
8823  *
8824  * Helper function to check if Chai's proxy protection feature is enabled. If
8825  * proxies are unsupported or disabled via the user's Chai config, then return
8826  * false. Otherwise, return true.
8827  *
8828  * @namespace Utils
8829  * @name isProxyEnabled
8830  */
8831
8832 module.exports = function isProxyEnabled() {
8833   return config.useProxy &&
8834     typeof Proxy !== 'undefined' &&
8835     typeof Reflect !== 'undefined';
8836 };
8837
8838 },{"../config":4}],26:[function(require,module,exports){
8839 /*!
8840  * Chai - flag utility
8841  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8842  * MIT Licensed
8843  */
8844
8845 /*!
8846  * Module dependencies
8847  */
8848
8849 var inspect = require('./inspect');
8850 var config = require('../config');
8851
8852 /**
8853  * ### .objDisplay(object)
8854  *
8855  * Determines if an object or an array matches
8856  * criteria to be inspected in-line for error
8857  * messages or should be truncated.
8858  *
8859  * @param {Mixed} javascript object to inspect
8860  * @name objDisplay
8861  * @namespace Utils
8862  * @api public
8863  */
8864
8865 module.exports = function objDisplay(obj) {
8866   var str = inspect(obj)
8867     , type = Object.prototype.toString.call(obj);
8868
8869   if (config.truncateThreshold && str.length >= config.truncateThreshold) {
8870     if (type === '[object Function]') {
8871       return !obj.name || obj.name === ''
8872         ? '[Function]'
8873         : '[Function: ' + obj.name + ']';
8874     } else if (type === '[object Array]') {
8875       return '[ Array(' + obj.length + ') ]';
8876     } else if (type === '[object Object]') {
8877       var keys = Object.keys(obj)
8878         , kstr = keys.length > 2
8879           ? keys.splice(0, 2).join(', ') + ', ...'
8880           : keys.join(', ');
8881       return '{ Object (' + kstr + ') }';
8882     } else {
8883       return str;
8884     }
8885   } else {
8886     return str;
8887   }
8888 };
8889
8890 },{"../config":4,"./inspect":23}],27:[function(require,module,exports){
8891 /*!
8892  * Chai - overwriteChainableMethod utility
8893  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8894  * MIT Licensed
8895  */
8896
8897 var chai = require('../../chai');
8898 var transferFlags = require('./transferFlags');
8899
8900 /**
8901  * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior)
8902  *
8903  * Overwrites an already existing chainable method
8904  * and provides access to the previous function or
8905  * property.  Must return functions to be used for
8906  * name.
8907  *
8908  *     utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf',
8909  *       function (_super) {
8910  *       }
8911  *     , function (_super) {
8912  *       }
8913  *     );
8914  *
8915  * Can also be accessed directly from `chai.Assertion`.
8916  *
8917  *     chai.Assertion.overwriteChainableMethod('foo', fn, fn);
8918  *
8919  * Then can be used as any other assertion.
8920  *
8921  *     expect(myFoo).to.have.lengthOf(3);
8922  *     expect(myFoo).to.have.lengthOf.above(3);
8923  *
8924  * @param {Object} ctx object whose method / property is to be overwritten
8925  * @param {String} name of method / property to overwrite
8926  * @param {Function} method function that returns a function to be used for name
8927  * @param {Function} chainingBehavior function that returns a function to be used for property
8928  * @namespace Utils
8929  * @name overwriteChainableMethod
8930  * @api public
8931  */
8932
8933 module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) {
8934   var chainableBehavior = ctx.__methods[name];
8935
8936   var _chainingBehavior = chainableBehavior.chainingBehavior;
8937   chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() {
8938     var result = chainingBehavior(_chainingBehavior).call(this);
8939     if (result !== undefined) {
8940       return result;
8941     }
8942
8943     var newAssertion = new chai.Assertion();
8944     transferFlags(this, newAssertion);
8945     return newAssertion;
8946   };
8947
8948   var _method = chainableBehavior.method;
8949   chainableBehavior.method = function overwritingChainableMethodWrapper() {
8950     var result = method(_method).apply(this, arguments);
8951     if (result !== undefined) {
8952       return result;
8953     }
8954
8955     var newAssertion = new chai.Assertion();
8956     transferFlags(this, newAssertion);
8957     return newAssertion;
8958   };
8959 };
8960
8961 },{"../../chai":2,"./transferFlags":32}],28:[function(require,module,exports){
8962 /*!
8963  * Chai - overwriteMethod utility
8964  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
8965  * MIT Licensed
8966  */
8967
8968 var addLengthGuard = require('./addLengthGuard');
8969 var chai = require('../../chai');
8970 var flag = require('./flag');
8971 var proxify = require('./proxify');
8972 var transferFlags = require('./transferFlags');
8973
8974 /**
8975  * ### .overwriteMethod(ctx, name, fn)
8976  *
8977  * Overwrites an already existing method and provides
8978  * access to previous function. Must return function
8979  * to be used for name.
8980  *
8981  *     utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {
8982  *       return function (str) {
8983  *         var obj = utils.flag(this, 'object');
8984  *         if (obj instanceof Foo) {
8985  *           new chai.Assertion(obj.value).to.equal(str);
8986  *         } else {
8987  *           _super.apply(this, arguments);
8988  *         }
8989  *       }
8990  *     });
8991  *
8992  * Can also be accessed directly from `chai.Assertion`.
8993  *
8994  *     chai.Assertion.overwriteMethod('foo', fn);
8995  *
8996  * Then can be used as any other assertion.
8997  *
8998  *     expect(myFoo).to.equal('bar');
8999  *
9000  * @param {Object} ctx object whose method is to be overwritten
9001  * @param {String} name of method to overwrite
9002  * @param {Function} method function that returns a function to be used for name
9003  * @namespace Utils
9004  * @name overwriteMethod
9005  * @api public
9006  */
9007
9008 module.exports = function overwriteMethod(ctx, name, method) {
9009   var _method = ctx[name]
9010     , _super = function () {
9011       throw new Error(name + ' is not a function');
9012     };
9013
9014   if (_method && 'function' === typeof _method)
9015     _super = _method;
9016
9017   var overwritingMethodWrapper = function () {
9018     // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this
9019     // function to be the starting point for removing implementation frames from
9020     // the stack trace of a failed assertion.
9021     //
9022     // However, we only want to use this function as the starting point if the
9023     // `lockSsfi` flag isn't set.
9024     //
9025     // If the `lockSsfi` flag is set, then either this assertion has been
9026     // overwritten by another assertion, or this assertion is being invoked from
9027     // inside of another assertion. In the first case, the `ssfi` flag has
9028     // already been set by the overwriting assertion. In the second case, the
9029     // `ssfi` flag has already been set by the outer assertion.
9030     if (!flag(this, 'lockSsfi')) {
9031       flag(this, 'ssfi', overwritingMethodWrapper);
9032     }
9033
9034     // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion
9035     // from changing the `ssfi` flag. By this point, the `ssfi` flag is already
9036     // set to the correct starting point for this assertion.
9037     var origLockSsfi = flag(this, 'lockSsfi');
9038     flag(this, 'lockSsfi', true);
9039     var result = method(_super).apply(this, arguments);
9040     flag(this, 'lockSsfi', origLockSsfi);
9041
9042     if (result !== undefined) {
9043       return result;
9044     }
9045
9046     var newAssertion = new chai.Assertion();
9047     transferFlags(this, newAssertion);
9048     return newAssertion;
9049   }
9050
9051   addLengthGuard(overwritingMethodWrapper, name, false);
9052   ctx[name] = proxify(overwritingMethodWrapper, name);
9053 };
9054
9055 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],29:[function(require,module,exports){
9056 /*!
9057  * Chai - overwriteProperty utility
9058  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
9059  * MIT Licensed
9060  */
9061
9062 var chai = require('../../chai');
9063 var flag = require('./flag');
9064 var isProxyEnabled = require('./isProxyEnabled');
9065 var transferFlags = require('./transferFlags');
9066
9067 /**
9068  * ### .overwriteProperty(ctx, name, fn)
9069  *
9070  * Overwrites an already existing property getter and provides
9071  * access to previous value. Must return function to use as getter.
9072  *
9073  *     utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {
9074  *       return function () {
9075  *         var obj = utils.flag(this, 'object');
9076  *         if (obj instanceof Foo) {
9077  *           new chai.Assertion(obj.name).to.equal('bar');
9078  *         } else {
9079  *           _super.call(this);
9080  *         }
9081  *       }
9082  *     });
9083  *
9084  *
9085  * Can also be accessed directly from `chai.Assertion`.
9086  *
9087  *     chai.Assertion.overwriteProperty('foo', fn);
9088  *
9089  * Then can be used as any other assertion.
9090  *
9091  *     expect(myFoo).to.be.ok;
9092  *
9093  * @param {Object} ctx object whose property is to be overwritten
9094  * @param {String} name of property to overwrite
9095  * @param {Function} getter function that returns a getter function to be used for name
9096  * @namespace Utils
9097  * @name overwriteProperty
9098  * @api public
9099  */
9100
9101 module.exports = function overwriteProperty(ctx, name, getter) {
9102   var _get = Object.getOwnPropertyDescriptor(ctx, name)
9103     , _super = function () {};
9104
9105   if (_get && 'function' === typeof _get.get)
9106     _super = _get.get
9107
9108   Object.defineProperty(ctx, name,
9109     { get: function overwritingPropertyGetter() {
9110         // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this
9111         // function to be the starting point for removing implementation frames
9112         // from the stack trace of a failed assertion.
9113         //
9114         // However, we only want to use this function as the starting point if
9115         // the `lockSsfi` flag isn't set and proxy protection is disabled.
9116         //
9117         // If the `lockSsfi` flag is set, then either this assertion has been
9118         // overwritten by another assertion, or this assertion is being invoked
9119         // from inside of another assertion. In the first case, the `ssfi` flag
9120         // has already been set by the overwriting assertion. In the second
9121         // case, the `ssfi` flag has already been set by the outer assertion.
9122         //
9123         // If proxy protection is enabled, then the `ssfi` flag has already been
9124         // set by the proxy getter.
9125         if (!isProxyEnabled() && !flag(this, 'lockSsfi')) {
9126           flag(this, 'ssfi', overwritingPropertyGetter);
9127         }
9128
9129         // Setting the `lockSsfi` flag to `true` prevents the overwritten
9130         // assertion from changing the `ssfi` flag. By this point, the `ssfi`
9131         // flag is already set to the correct starting point for this assertion.
9132         var origLockSsfi = flag(this, 'lockSsfi');
9133         flag(this, 'lockSsfi', true);
9134         var result = getter(_super).call(this);
9135         flag(this, 'lockSsfi', origLockSsfi);
9136
9137         if (result !== undefined) {
9138           return result;
9139         }
9140
9141         var newAssertion = new chai.Assertion();
9142         transferFlags(this, newAssertion);
9143         return newAssertion;
9144       }
9145     , configurable: true
9146   });
9147 };
9148
9149 },{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],30:[function(require,module,exports){
9150 var config = require('../config');
9151 var flag = require('./flag');
9152 var getProperties = require('./getProperties');
9153 var isProxyEnabled = require('./isProxyEnabled');
9154
9155 /*!
9156  * Chai - proxify utility
9157  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
9158  * MIT Licensed
9159  */
9160
9161 /**
9162  * ### .proxify(object)
9163  *
9164  * Return a proxy of given object that throws an error when a non-existent
9165  * property is read. By default, the root cause is assumed to be a misspelled
9166  * property, and thus an attempt is made to offer a reasonable suggestion from
9167  * the list of existing properties. However, if a nonChainableMethodName is
9168  * provided, then the root cause is instead a failure to invoke a non-chainable
9169  * method prior to reading the non-existent property.
9170  *
9171  * If proxies are unsupported or disabled via the user's Chai config, then
9172  * return object without modification.
9173  *
9174  * @param {Object} obj
9175  * @param {String} nonChainableMethodName
9176  * @namespace Utils
9177  * @name proxify
9178  */
9179
9180 var builtins = ['__flags', '__methods', '_obj', 'assert'];
9181
9182 module.exports = function proxify(obj, nonChainableMethodName) {
9183   if (!isProxyEnabled()) return obj;
9184
9185   return new Proxy(obj, {
9186     get: function proxyGetter(target, property) {
9187       // This check is here because we should not throw errors on Symbol properties
9188       // such as `Symbol.toStringTag`.
9189       // The values for which an error should be thrown can be configured using
9190       // the `config.proxyExcludedKeys` setting.
9191       if (typeof property === 'string' &&
9192           config.proxyExcludedKeys.indexOf(property) === -1 &&
9193           !Reflect.has(target, property)) {
9194         // Special message for invalid property access of non-chainable methods.
9195         if (nonChainableMethodName) {
9196           throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' +
9197             property + '. See docs for proper usage of "' +
9198             nonChainableMethodName + '".');
9199         }
9200
9201         // If the property is reasonably close to an existing Chai property,
9202         // suggest that property to the user. Only suggest properties with a
9203         // distance less than 4.
9204         var suggestion = null;
9205         var suggestionDistance = 4;
9206         getProperties(target).forEach(function(prop) {
9207           if (
9208             !Object.prototype.hasOwnProperty(prop) &&
9209             builtins.indexOf(prop) === -1
9210           ) {
9211             var dist = stringDistanceCapped(
9212               property,
9213               prop,
9214               suggestionDistance
9215             );
9216             if (dist < suggestionDistance) {
9217               suggestion = prop;
9218               suggestionDistance = dist;
9219             }
9220           }
9221         });
9222
9223         if (suggestion !== null) {
9224           throw Error('Invalid Chai property: ' + property +
9225             '. Did you mean "' + suggestion + '"?');
9226         } else {
9227           throw Error('Invalid Chai property: ' + property);
9228         }
9229       }
9230
9231       // Use this proxy getter as the starting point for removing implementation
9232       // frames from the stack trace of a failed assertion. For property
9233       // assertions, this prevents the proxy getter from showing up in the stack
9234       // trace since it's invoked before the property getter. For method and
9235       // chainable method assertions, this flag will end up getting changed to
9236       // the method wrapper, which is good since this frame will no longer be in
9237       // the stack once the method is invoked. Note that Chai builtin assertion
9238       // properties such as `__flags` are skipped since this is only meant to
9239       // capture the starting point of an assertion. This step is also skipped
9240       // if the `lockSsfi` flag is set, thus indicating that this assertion is
9241       // being called from within another assertion. In that case, the `ssfi`
9242       // flag is already set to the outer assertion's starting point.
9243       if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) {
9244         flag(target, 'ssfi', proxyGetter);
9245       }
9246
9247       return Reflect.get(target, property);
9248     }
9249   });
9250 };
9251
9252 /**
9253  * # stringDistanceCapped(strA, strB, cap)
9254  * Return the Levenshtein distance between two strings, but no more than cap.
9255  * @param {string} strA
9256  * @param {string} strB
9257  * @param {number} number
9258  * @return {number} min(string distance between strA and strB, cap)
9259  * @api private
9260  */
9261
9262 function stringDistanceCapped(strA, strB, cap) {
9263   if (Math.abs(strA.length - strB.length) >= cap) {
9264     return cap;
9265   }
9266
9267   var memo = [];
9268   // `memo` is a two-dimensional array containing distances.
9269   // memo[i][j] is the distance between strA.slice(0, i) and
9270   // strB.slice(0, j).
9271   for (var i = 0; i <= strA.length; i++) {
9272     memo[i] = Array(strB.length + 1).fill(0);
9273     memo[i][0] = i;
9274   }
9275   for (var j = 0; j < strB.length; j++) {
9276     memo[0][j] = j;
9277   }
9278
9279   for (var i = 1; i <= strA.length; i++) {
9280     var ch = strA.charCodeAt(i - 1);
9281     for (var j = 1; j <= strB.length; j++) {
9282       if (Math.abs(i - j) >= cap) {
9283         memo[i][j] = cap;
9284         continue;
9285       }
9286       memo[i][j] = Math.min(
9287         memo[i - 1][j] + 1,
9288         memo[i][j - 1] + 1,
9289         memo[i - 1][j - 1] +
9290           (ch === strB.charCodeAt(j - 1) ? 0 : 1)
9291       );
9292     }
9293   }
9294
9295   return memo[strA.length][strB.length];
9296 }
9297
9298 },{"../config":4,"./flag":15,"./getProperties":21,"./isProxyEnabled":25}],31:[function(require,module,exports){
9299 /*!
9300  * Chai - test utility
9301  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
9302  * MIT Licensed
9303  */
9304
9305 /*!
9306  * Module dependencies
9307  */
9308
9309 var flag = require('./flag');
9310
9311 /**
9312  * ### .test(object, expression)
9313  *
9314  * Test and object for expression.
9315  *
9316  * @param {Object} object (constructed Assertion)
9317  * @param {Arguments} chai.Assertion.prototype.assert arguments
9318  * @namespace Utils
9319  * @name test
9320  */
9321
9322 module.exports = function test(obj, args) {
9323   var negate = flag(obj, 'negate')
9324     , expr = args[0];
9325   return negate ? !expr : expr;
9326 };
9327
9328 },{"./flag":15}],32:[function(require,module,exports){
9329 /*!
9330  * Chai - transferFlags utility
9331  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
9332  * MIT Licensed
9333  */
9334
9335 /**
9336  * ### .transferFlags(assertion, object, includeAll = true)
9337  *
9338  * Transfer all the flags for `assertion` to `object`. If
9339  * `includeAll` is set to `false`, then the base Chai
9340  * assertion flags (namely `object`, `ssfi`, `lockSsfi`,
9341  * and `message`) will not be transferred.
9342  *
9343  *
9344  *     var newAssertion = new Assertion();
9345  *     utils.transferFlags(assertion, newAssertion);
9346  *
9347  *     var anotherAssertion = new Assertion(myObj);
9348  *     utils.transferFlags(assertion, anotherAssertion, false);
9349  *
9350  * @param {Assertion} assertion the assertion to transfer the flags from
9351  * @param {Object} object the object to transfer the flags to; usually a new assertion
9352  * @param {Boolean} includeAll
9353  * @namespace Utils
9354  * @name transferFlags
9355  * @api private
9356  */
9357
9358 module.exports = function transferFlags(assertion, object, includeAll) {
9359   var flags = assertion.__flags || (assertion.__flags = Object.create(null));
9360
9361   if (!object.__flags) {
9362     object.__flags = Object.create(null);
9363   }
9364
9365   includeAll = arguments.length === 3 ? includeAll : true;
9366
9367   for (var flag in flags) {
9368     if (includeAll ||
9369         (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) {
9370       object.__flags[flag] = flags[flag];
9371     }
9372   }
9373 };
9374
9375 },{}],33:[function(require,module,exports){
9376 /*!
9377  * assertion-error
9378  * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>
9379  * MIT Licensed
9380  */
9381
9382 /*!
9383  * Return a function that will copy properties from
9384  * one object to another excluding any originally
9385  * listed. Returned function will create a new `{}`.
9386  *
9387  * @param {String} excluded properties ...
9388  * @return {Function}
9389  */
9390
9391 function exclude () {
9392   var excludes = [].slice.call(arguments);
9393
9394   function excludeProps (res, obj) {
9395     Object.keys(obj).forEach(function (key) {
9396       if (!~excludes.indexOf(key)) res[key] = obj[key];
9397     });
9398   }
9399
9400   return function extendExclude () {
9401     var args = [].slice.call(arguments)
9402       , i = 0
9403       , res = {};
9404
9405     for (; i < args.length; i++) {
9406       excludeProps(res, args[i]);
9407     }
9408
9409     return res;
9410   };
9411 };
9412
9413 /*!
9414  * Primary Exports
9415  */
9416
9417 module.exports = AssertionError;
9418
9419 /**
9420  * ### AssertionError
9421  *
9422  * An extension of the JavaScript `Error` constructor for
9423  * assertion and validation scenarios.
9424  *
9425  * @param {String} message
9426  * @param {Object} properties to include (optional)
9427  * @param {callee} start stack function (optional)
9428  */
9429
9430 function AssertionError (message, _props, ssf) {
9431   var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')
9432     , props = extend(_props || {});
9433
9434   // default values
9435   this.message = message || 'Unspecified AssertionError';
9436   this.showDiff = false;
9437
9438   // copy from properties
9439   for (var key in props) {
9440     this[key] = props[key];
9441   }
9442
9443   // capture stack trace
9444   ssf = ssf || AssertionError;
9445   if (Error.captureStackTrace) {
9446     Error.captureStackTrace(this, ssf);
9447   } else {
9448     try {
9449       throw new Error();
9450     } catch(e) {
9451       this.stack = e.stack;
9452     }
9453   }
9454 }
9455
9456 /*!
9457  * Inherit from Error.prototype
9458  */
9459
9460 AssertionError.prototype = Object.create(Error.prototype);
9461
9462 /*!
9463  * Statically set name
9464  */
9465
9466 AssertionError.prototype.name = 'AssertionError';
9467
9468 /*!
9469  * Ensure correct constructor
9470  */
9471
9472 AssertionError.prototype.constructor = AssertionError;
9473
9474 /**
9475  * Allow errors to be converted to JSON for static transfer.
9476  *
9477  * @param {Boolean} include stack (default: `true`)
9478  * @return {Object} object that can be `JSON.stringify`
9479  */
9480
9481 AssertionError.prototype.toJSON = function (stack) {
9482   var extend = exclude('constructor', 'toJSON', 'stack')
9483     , props = extend({ name: this.name }, this);
9484
9485   // include stack if exists and not turned off
9486   if (false !== stack && this.stack) {
9487     props.stack = this.stack;
9488   }
9489
9490   return props;
9491 };
9492
9493 },{}],34:[function(require,module,exports){
9494 'use strict';
9495
9496 /* !
9497  * Chai - checkError utility
9498  * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
9499  * MIT Licensed
9500  */
9501
9502 /**
9503  * ### .checkError
9504  *
9505  * Checks that an error conforms to a given set of criteria and/or retrieves information about it.
9506  *
9507  * @api public
9508  */
9509
9510 /**
9511  * ### .compatibleInstance(thrown, errorLike)
9512  *
9513  * Checks if two instances are compatible (strict equal).
9514  * Returns false if errorLike is not an instance of Error, because instances
9515  * can only be compatible if they're both error instances.
9516  *
9517  * @name compatibleInstance
9518  * @param {Error} thrown error
9519  * @param {Error|ErrorConstructor} errorLike object to compare against
9520  * @namespace Utils
9521  * @api public
9522  */
9523
9524 function compatibleInstance(thrown, errorLike) {
9525   return errorLike instanceof Error && thrown === errorLike;
9526 }
9527
9528 /**
9529  * ### .compatibleConstructor(thrown, errorLike)
9530  *
9531  * Checks if two constructors are compatible.
9532  * This function can receive either an error constructor or
9533  * an error instance as the `errorLike` argument.
9534  * Constructors are compatible if they're the same or if one is
9535  * an instance of another.
9536  *
9537  * @name compatibleConstructor
9538  * @param {Error} thrown error
9539  * @param {Error|ErrorConstructor} errorLike object to compare against
9540  * @namespace Utils
9541  * @api public
9542  */
9543
9544 function compatibleConstructor(thrown, errorLike) {
9545   if (errorLike instanceof Error) {
9546     // If `errorLike` is an instance of any error we compare their constructors
9547     return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor;
9548   } else if (errorLike.prototype instanceof Error || errorLike === Error) {
9549     // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly
9550     return thrown.constructor === errorLike || thrown instanceof errorLike;
9551   }
9552
9553   return false;
9554 }
9555
9556 /**
9557  * ### .compatibleMessage(thrown, errMatcher)
9558  *
9559  * Checks if an error's message is compatible with a matcher (String or RegExp).
9560  * If the message contains the String or passes the RegExp test,
9561  * it is considered compatible.
9562  *
9563  * @name compatibleMessage
9564  * @param {Error} thrown error
9565  * @param {String|RegExp} errMatcher to look for into the message
9566  * @namespace Utils
9567  * @api public
9568  */
9569
9570 function compatibleMessage(thrown, errMatcher) {
9571   var comparisonString = typeof thrown === 'string' ? thrown : thrown.message;
9572   if (errMatcher instanceof RegExp) {
9573     return errMatcher.test(comparisonString);
9574   } else if (typeof errMatcher === 'string') {
9575     return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers
9576   }
9577
9578   return false;
9579 }
9580
9581 /**
9582  * ### .getFunctionName(constructorFn)
9583  *
9584  * Returns the name of a function.
9585  * This also includes a polyfill function if `constructorFn.name` is not defined.
9586  *
9587  * @name getFunctionName
9588  * @param {Function} constructorFn
9589  * @namespace Utils
9590  * @api private
9591  */
9592
9593 var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\(\/]+)/;
9594 function getFunctionName(constructorFn) {
9595   var name = '';
9596   if (typeof constructorFn.name === 'undefined') {
9597     // Here we run a polyfill if constructorFn.name is not defined
9598     var match = String(constructorFn).match(functionNameMatch);
9599     if (match) {
9600       name = match[1];
9601     }
9602   } else {
9603     name = constructorFn.name;
9604   }
9605
9606   return name;
9607 }
9608
9609 /**
9610  * ### .getConstructorName(errorLike)
9611  *
9612  * Gets the constructor name for an Error instance or constructor itself.
9613  *
9614  * @name getConstructorName
9615  * @param {Error|ErrorConstructor} errorLike
9616  * @namespace Utils
9617  * @api public
9618  */
9619
9620 function getConstructorName(errorLike) {
9621   var constructorName = errorLike;
9622   if (errorLike instanceof Error) {
9623     constructorName = getFunctionName(errorLike.constructor);
9624   } else if (typeof errorLike === 'function') {
9625     // If `err` is not an instance of Error it is an error constructor itself or another function.
9626     // If we've got a common function we get its name, otherwise we may need to create a new instance
9627     // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more.
9628     constructorName = getFunctionName(errorLike).trim() ||
9629         getFunctionName(new errorLike()); // eslint-disable-line new-cap
9630   }
9631
9632   return constructorName;
9633 }
9634
9635 /**
9636  * ### .getMessage(errorLike)
9637  *
9638  * Gets the error message from an error.
9639  * If `err` is a String itself, we return it.
9640  * If the error has no message, we return an empty string.
9641  *
9642  * @name getMessage
9643  * @param {Error|String} errorLike
9644  * @namespace Utils
9645  * @api public
9646  */
9647
9648 function getMessage(errorLike) {
9649   var msg = '';
9650   if (errorLike && errorLike.message) {
9651     msg = errorLike.message;
9652   } else if (typeof errorLike === 'string') {
9653     msg = errorLike;
9654   }
9655
9656   return msg;
9657 }
9658
9659 module.exports = {
9660   compatibleInstance: compatibleInstance,
9661   compatibleConstructor: compatibleConstructor,
9662   compatibleMessage: compatibleMessage,
9663   getMessage: getMessage,
9664   getConstructorName: getConstructorName,
9665 };
9666
9667 },{}],35:[function(require,module,exports){
9668 'use strict';
9669 /* globals Symbol: false, Uint8Array: false, WeakMap: false */
9670 /*!
9671  * deep-eql
9672  * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>
9673  * MIT Licensed
9674  */
9675
9676 var type = require('type-detect');
9677 function FakeMap() {
9678   this._key = 'chai/deep-eql__' + Math.random() + Date.now();
9679 }
9680
9681 FakeMap.prototype = {
9682   get: function getMap(key) {
9683     return key[this._key];
9684   },
9685   set: function setMap(key, value) {
9686     if (Object.isExtensible(key)) {
9687       Object.defineProperty(key, this._key, {
9688         value: value,
9689         configurable: true,
9690       });
9691     }
9692   },
9693 };
9694
9695 var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap;
9696 /*!
9697  * Check to see if the MemoizeMap has recorded a result of the two operands
9698  *
9699  * @param {Mixed} leftHandOperand
9700  * @param {Mixed} rightHandOperand
9701  * @param {MemoizeMap} memoizeMap
9702  * @returns {Boolean|null} result
9703 */
9704 function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) {
9705   // Technically, WeakMap keys can *only* be objects, not primitives.
9706   if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
9707     return null;
9708   }
9709   var leftHandMap = memoizeMap.get(leftHandOperand);
9710   if (leftHandMap) {
9711     var result = leftHandMap.get(rightHandOperand);
9712     if (typeof result === 'boolean') {
9713       return result;
9714     }
9715   }
9716   return null;
9717 }
9718
9719 /*!
9720  * Set the result of the equality into the MemoizeMap
9721  *
9722  * @param {Mixed} leftHandOperand
9723  * @param {Mixed} rightHandOperand
9724  * @param {MemoizeMap} memoizeMap
9725  * @param {Boolean} result
9726 */
9727 function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) {
9728   // Technically, WeakMap keys can *only* be objects, not primitives.
9729   if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
9730     return;
9731   }
9732   var leftHandMap = memoizeMap.get(leftHandOperand);
9733   if (leftHandMap) {
9734     leftHandMap.set(rightHandOperand, result);
9735   } else {
9736     leftHandMap = new MemoizeMap();
9737     leftHandMap.set(rightHandOperand, result);
9738     memoizeMap.set(leftHandOperand, leftHandMap);
9739   }
9740 }
9741
9742 /*!
9743  * Primary Export
9744  */
9745
9746 module.exports = deepEqual;
9747 module.exports.MemoizeMap = MemoizeMap;
9748
9749 /**
9750  * Assert deeply nested sameValue equality between two objects of any type.
9751  *
9752  * @param {Mixed} leftHandOperand
9753  * @param {Mixed} rightHandOperand
9754  * @param {Object} [options] (optional) Additional options
9755  * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality.
9756  * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of
9757     complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular
9758     references to blow the stack.
9759  * @return {Boolean} equal match
9760  */
9761 function deepEqual(leftHandOperand, rightHandOperand, options) {
9762   // If we have a comparator, we can't assume anything; so bail to its check first.
9763   if (options && options.comparator) {
9764     return extensiveDeepEqual(leftHandOperand, rightHandOperand, options);
9765   }
9766
9767   var simpleResult = simpleEqual(leftHandOperand, rightHandOperand);
9768   if (simpleResult !== null) {
9769     return simpleResult;
9770   }
9771
9772   // Deeper comparisons are pushed through to a larger function
9773   return extensiveDeepEqual(leftHandOperand, rightHandOperand, options);
9774 }
9775
9776 /**
9777  * Many comparisons can be canceled out early via simple equality or primitive checks.
9778  * @param {Mixed} leftHandOperand
9779  * @param {Mixed} rightHandOperand
9780  * @return {Boolean|null} equal match
9781  */
9782 function simpleEqual(leftHandOperand, rightHandOperand) {
9783   // Equal references (except for Numbers) can be returned early
9784   if (leftHandOperand === rightHandOperand) {
9785     // Handle +-0 cases
9786     return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand;
9787   }
9788
9789   // handle NaN cases
9790   if (
9791     leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare
9792     rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare
9793   ) {
9794     return true;
9795   }
9796
9797   // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers,
9798   // strings, and undefined, can be compared by reference.
9799   if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
9800     // Easy out b/c it would have passed the first equality check
9801     return false;
9802   }
9803   return null;
9804 }
9805
9806 /*!
9807  * The main logic of the `deepEqual` function.
9808  *
9809  * @param {Mixed} leftHandOperand
9810  * @param {Mixed} rightHandOperand
9811  * @param {Object} [options] (optional) Additional options
9812  * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality.
9813  * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of
9814     complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular
9815     references to blow the stack.
9816  * @return {Boolean} equal match
9817 */
9818 function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) {
9819   options = options || {};
9820   options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap();
9821   var comparator = options && options.comparator;
9822
9823   // Check if a memoized result exists.
9824   var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize);
9825   if (memoizeResultLeft !== null) {
9826     return memoizeResultLeft;
9827   }
9828   var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize);
9829   if (memoizeResultRight !== null) {
9830     return memoizeResultRight;
9831   }
9832
9833   // If a comparator is present, use it.
9834   if (comparator) {
9835     var comparatorResult = comparator(leftHandOperand, rightHandOperand);
9836     // Comparators may return null, in which case we want to go back to default behavior.
9837     if (comparatorResult === false || comparatorResult === true) {
9838       memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult);
9839       return comparatorResult;
9840     }
9841     // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide
9842     // what to do, we need to make sure to return the basic tests first before we move on.
9843     var simpleResult = simpleEqual(leftHandOperand, rightHandOperand);
9844     if (simpleResult !== null) {
9845       // Don't memoize this, it takes longer to set/retrieve than to just compare.
9846       return simpleResult;
9847     }
9848   }
9849
9850   var leftHandType = type(leftHandOperand);
9851   if (leftHandType !== type(rightHandOperand)) {
9852     memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false);
9853     return false;
9854   }
9855
9856   // Temporarily set the operands in the memoize object to prevent blowing the stack
9857   memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true);
9858
9859   var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options);
9860   memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result);
9861   return result;
9862 }
9863
9864 function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) {
9865   switch (leftHandType) {
9866     case 'String':
9867     case 'Number':
9868     case 'Boolean':
9869     case 'Date':
9870       // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values
9871       return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf());
9872     case 'Promise':
9873     case 'Symbol':
9874     case 'function':
9875     case 'WeakMap':
9876     case 'WeakSet':
9877     case 'Error':
9878       return leftHandOperand === rightHandOperand;
9879     case 'Arguments':
9880     case 'Int8Array':
9881     case 'Uint8Array':
9882     case 'Uint8ClampedArray':
9883     case 'Int16Array':
9884     case 'Uint16Array':
9885     case 'Int32Array':
9886     case 'Uint32Array':
9887     case 'Float32Array':
9888     case 'Float64Array':
9889     case 'Array':
9890       return iterableEqual(leftHandOperand, rightHandOperand, options);
9891     case 'RegExp':
9892       return regexpEqual(leftHandOperand, rightHandOperand);
9893     case 'Generator':
9894       return generatorEqual(leftHandOperand, rightHandOperand, options);
9895     case 'DataView':
9896       return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options);
9897     case 'ArrayBuffer':
9898       return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options);
9899     case 'Set':
9900       return entriesEqual(leftHandOperand, rightHandOperand, options);
9901     case 'Map':
9902       return entriesEqual(leftHandOperand, rightHandOperand, options);
9903     default:
9904       return objectEqual(leftHandOperand, rightHandOperand, options);
9905   }
9906 }
9907
9908 /*!
9909  * Compare two Regular Expressions for equality.
9910  *
9911  * @param {RegExp} leftHandOperand
9912  * @param {RegExp} rightHandOperand
9913  * @return {Boolean} result
9914  */
9915
9916 function regexpEqual(leftHandOperand, rightHandOperand) {
9917   return leftHandOperand.toString() === rightHandOperand.toString();
9918 }
9919
9920 /*!
9921  * Compare two Sets/Maps for equality. Faster than other equality functions.
9922  *
9923  * @param {Set} leftHandOperand
9924  * @param {Set} rightHandOperand
9925  * @param {Object} [options] (Optional)
9926  * @return {Boolean} result
9927  */
9928
9929 function entriesEqual(leftHandOperand, rightHandOperand, options) {
9930   // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach
9931   if (leftHandOperand.size !== rightHandOperand.size) {
9932     return false;
9933   }
9934   if (leftHandOperand.size === 0) {
9935     return true;
9936   }
9937   var leftHandItems = [];
9938   var rightHandItems = [];
9939   leftHandOperand.forEach(function gatherEntries(key, value) {
9940     leftHandItems.push([ key, value ]);
9941   });
9942   rightHandOperand.forEach(function gatherEntries(key, value) {
9943     rightHandItems.push([ key, value ]);
9944   });
9945   return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options);
9946 }
9947
9948 /*!
9949  * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers.
9950  *
9951  * @param {Iterable} leftHandOperand
9952  * @param {Iterable} rightHandOperand
9953  * @param {Object} [options] (Optional)
9954  * @return {Boolean} result
9955  */
9956
9957 function iterableEqual(leftHandOperand, rightHandOperand, options) {
9958   var length = leftHandOperand.length;
9959   if (length !== rightHandOperand.length) {
9960     return false;
9961   }
9962   if (length === 0) {
9963     return true;
9964   }
9965   var index = -1;
9966   while (++index < length) {
9967     if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) {
9968       return false;
9969     }
9970   }
9971   return true;
9972 }
9973
9974 /*!
9975  * Simple equality for generator objects such as those returned by generator functions.
9976  *
9977  * @param {Iterable} leftHandOperand
9978  * @param {Iterable} rightHandOperand
9979  * @param {Object} [options] (Optional)
9980  * @return {Boolean} result
9981  */
9982
9983 function generatorEqual(leftHandOperand, rightHandOperand, options) {
9984   return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options);
9985 }
9986
9987 /*!
9988  * Determine if the given object has an @@iterator function.
9989  *
9990  * @param {Object} target
9991  * @return {Boolean} `true` if the object has an @@iterator function.
9992  */
9993 function hasIteratorFunction(target) {
9994   return typeof Symbol !== 'undefined' &&
9995     typeof target === 'object' &&
9996     typeof Symbol.iterator !== 'undefined' &&
9997     typeof target[Symbol.iterator] === 'function';
9998 }
9999
10000 /*!
10001  * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array.
10002  * This will consume the iterator - which could have side effects depending on the @@iterator implementation.
10003  *
10004  * @param {Object} target
10005  * @returns {Array} an array of entries from the @@iterator function
10006  */
10007 function getIteratorEntries(target) {
10008   if (hasIteratorFunction(target)) {
10009     try {
10010       return getGeneratorEntries(target[Symbol.iterator]());
10011     } catch (iteratorError) {
10012       return [];
10013     }
10014   }
10015   return [];
10016 }
10017
10018 /*!
10019  * Gets all entries from a Generator. This will consume the generator - which could have side effects.
10020  *
10021  * @param {Generator} target
10022  * @returns {Array} an array of entries from the Generator.
10023  */
10024 function getGeneratorEntries(generator) {
10025   var generatorResult = generator.next();
10026   var accumulator = [ generatorResult.value ];
10027   while (generatorResult.done === false) {
10028     generatorResult = generator.next();
10029     accumulator.push(generatorResult.value);
10030   }
10031   return accumulator;
10032 }
10033
10034 /*!
10035  * Gets all own and inherited enumerable keys from a target.
10036  *
10037  * @param {Object} target
10038  * @returns {Array} an array of own and inherited enumerable keys from the target.
10039  */
10040 function getEnumerableKeys(target) {
10041   var keys = [];
10042   for (var key in target) {
10043     keys.push(key);
10044   }
10045   return keys;
10046 }
10047
10048 /*!
10049  * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of
10050  * each key. If any value of the given key is not equal, the function will return false (early).
10051  *
10052  * @param {Mixed} leftHandOperand
10053  * @param {Mixed} rightHandOperand
10054  * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against
10055  * @param {Object} [options] (Optional)
10056  * @return {Boolean} result
10057  */
10058 function keysEqual(leftHandOperand, rightHandOperand, keys, options) {
10059   var length = keys.length;
10060   if (length === 0) {
10061     return true;
10062   }
10063   for (var i = 0; i < length; i += 1) {
10064     if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) {
10065       return false;
10066     }
10067   }
10068   return true;
10069 }
10070
10071 /*!
10072  * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual`
10073  * for each enumerable key in the object.
10074  *
10075  * @param {Mixed} leftHandOperand
10076  * @param {Mixed} rightHandOperand
10077  * @param {Object} [options] (Optional)
10078  * @return {Boolean} result
10079  */
10080
10081 function objectEqual(leftHandOperand, rightHandOperand, options) {
10082   var leftHandKeys = getEnumerableKeys(leftHandOperand);
10083   var rightHandKeys = getEnumerableKeys(rightHandOperand);
10084   if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) {
10085     leftHandKeys.sort();
10086     rightHandKeys.sort();
10087     if (iterableEqual(leftHandKeys, rightHandKeys) === false) {
10088       return false;
10089     }
10090     return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options);
10091   }
10092
10093   var leftHandEntries = getIteratorEntries(leftHandOperand);
10094   var rightHandEntries = getIteratorEntries(rightHandOperand);
10095   if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) {
10096     leftHandEntries.sort();
10097     rightHandEntries.sort();
10098     return iterableEqual(leftHandEntries, rightHandEntries, options);
10099   }
10100
10101   if (leftHandKeys.length === 0 &&
10102       leftHandEntries.length === 0 &&
10103       rightHandKeys.length === 0 &&
10104       rightHandEntries.length === 0) {
10105     return true;
10106   }
10107
10108   return false;
10109 }
10110
10111 /*!
10112  * Returns true if the argument is a primitive.
10113  *
10114  * This intentionally returns true for all objects that can be compared by reference,
10115  * including functions and symbols.
10116  *
10117  * @param {Mixed} value
10118  * @return {Boolean} result
10119  */
10120 function isPrimitive(value) {
10121   return value === null || typeof value !== 'object';
10122 }
10123
10124 },{"type-detect":38}],36:[function(require,module,exports){
10125 'use strict';
10126
10127 /* !
10128  * Chai - getFuncName utility
10129  * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
10130  * MIT Licensed
10131  */
10132
10133 /**
10134  * ### .getFuncName(constructorFn)
10135  *
10136  * Returns the name of a function.
10137  * When a non-function instance is passed, returns `null`.
10138  * This also includes a polyfill function if `aFunc.name` is not defined.
10139  *
10140  * @name getFuncName
10141  * @param {Function} funct
10142  * @namespace Utils
10143  * @api public
10144  */
10145
10146 var toString = Function.prototype.toString;
10147 var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/;
10148 function getFuncName(aFunc) {
10149   if (typeof aFunc !== 'function') {
10150     return null;
10151   }
10152
10153   var name = '';
10154   if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') {
10155     // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined
10156     var match = toString.call(aFunc).match(functionNameMatch);
10157     if (match) {
10158       name = match[1];
10159     }
10160   } else {
10161     // If we've got a `name` property we just use it
10162     name = aFunc.name;
10163   }
10164
10165   return name;
10166 }
10167
10168 module.exports = getFuncName;
10169
10170 },{}],37:[function(require,module,exports){
10171 'use strict';
10172
10173 /* !
10174  * Chai - pathval utility
10175  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
10176  * @see https://github.com/logicalparadox/filtr
10177  * MIT Licensed
10178  */
10179
10180 /**
10181  * ### .hasProperty(object, name)
10182  *
10183  * This allows checking whether an object has own
10184  * or inherited from prototype chain named property.
10185  *
10186  * Basically does the same thing as the `in`
10187  * operator but works properly with null/undefined values
10188  * and other primitives.
10189  *
10190  *     var obj = {
10191  *         arr: ['a', 'b', 'c']
10192  *       , str: 'Hello'
10193  *     }
10194  *
10195  * The following would be the results.
10196  *
10197  *     hasProperty(obj, 'str');  // true
10198  *     hasProperty(obj, 'constructor');  // true
10199  *     hasProperty(obj, 'bar');  // false
10200  *
10201  *     hasProperty(obj.str, 'length'); // true
10202  *     hasProperty(obj.str, 1);  // true
10203  *     hasProperty(obj.str, 5);  // false
10204  *
10205  *     hasProperty(obj.arr, 'length');  // true
10206  *     hasProperty(obj.arr, 2);  // true
10207  *     hasProperty(obj.arr, 3);  // false
10208  *
10209  * @param {Object} object
10210  * @param {String|Symbol} name
10211  * @returns {Boolean} whether it exists
10212  * @namespace Utils
10213  * @name hasProperty
10214  * @api public
10215  */
10216
10217 function hasProperty(obj, name) {
10218   if (typeof obj === 'undefined' || obj === null) {
10219     return false;
10220   }
10221
10222   // The `in` operator does not work with primitives.
10223   return name in Object(obj);
10224 }
10225
10226 /* !
10227  * ## parsePath(path)
10228  *
10229  * Helper function used to parse string object
10230  * paths. Use in conjunction with `internalGetPathValue`.
10231  *
10232  *      var parsed = parsePath('myobject.property.subprop');
10233  *
10234  * ### Paths:
10235  *
10236  * * Can be infinitely deep and nested.
10237  * * Arrays are also valid using the formal `myobject.document[3].property`.
10238  * * Literal dots and brackets (not delimiter) must be backslash-escaped.
10239  *
10240  * @param {String} path
10241  * @returns {Object} parsed
10242  * @api private
10243  */
10244
10245 function parsePath(path) {
10246   var str = path.replace(/([^\\])\[/g, '$1.[');
10247   var parts = str.match(/(\\\.|[^.]+?)+/g);
10248   return parts.map(function mapMatches(value) {
10249     var regexp = /^\[(\d+)\]$/;
10250     var mArr = regexp.exec(value);
10251     var parsed = null;
10252     if (mArr) {
10253       parsed = { i: parseFloat(mArr[1]) };
10254     } else {
10255       parsed = { p: value.replace(/\\([.\[\]])/g, '$1') };
10256     }
10257
10258     return parsed;
10259   });
10260 }
10261
10262 /* !
10263  * ## internalGetPathValue(obj, parsed[, pathDepth])
10264  *
10265  * Helper companion function for `.parsePath` that returns
10266  * the value located at the parsed address.
10267  *
10268  *      var value = getPathValue(obj, parsed);
10269  *
10270  * @param {Object} object to search against
10271  * @param {Object} parsed definition from `parsePath`.
10272  * @param {Number} depth (nesting level) of the property we want to retrieve
10273  * @returns {Object|Undefined} value
10274  * @api private
10275  */
10276
10277 function internalGetPathValue(obj, parsed, pathDepth) {
10278   var temporaryValue = obj;
10279   var res = null;
10280   pathDepth = (typeof pathDepth === 'undefined' ? parsed.length : pathDepth);
10281
10282   for (var i = 0; i < pathDepth; i++) {
10283     var part = parsed[i];
10284     if (temporaryValue) {
10285       if (typeof part.p === 'undefined') {
10286         temporaryValue = temporaryValue[part.i];
10287       } else {
10288         temporaryValue = temporaryValue[part.p];
10289       }
10290
10291       if (i === (pathDepth - 1)) {
10292         res = temporaryValue;
10293       }
10294     }
10295   }
10296
10297   return res;
10298 }
10299
10300 /* !
10301  * ## internalSetPathValue(obj, value, parsed)
10302  *
10303  * Companion function for `parsePath` that sets
10304  * the value located at a parsed address.
10305  *
10306  *  internalSetPathValue(obj, 'value', parsed);
10307  *
10308  * @param {Object} object to search and define on
10309  * @param {*} value to use upon set
10310  * @param {Object} parsed definition from `parsePath`
10311  * @api private
10312  */
10313
10314 function internalSetPathValue(obj, val, parsed) {
10315   var tempObj = obj;
10316   var pathDepth = parsed.length;
10317   var part = null;
10318   // Here we iterate through every part of the path
10319   for (var i = 0; i < pathDepth; i++) {
10320     var propName = null;
10321     var propVal = null;
10322     part = parsed[i];
10323
10324     // If it's the last part of the path, we set the 'propName' value with the property name
10325     if (i === (pathDepth - 1)) {
10326       propName = typeof part.p === 'undefined' ? part.i : part.p;
10327       // Now we set the property with the name held by 'propName' on object with the desired val
10328       tempObj[propName] = val;
10329     } else if (typeof part.p !== 'undefined' && tempObj[part.p]) {
10330       tempObj = tempObj[part.p];
10331     } else if (typeof part.i !== 'undefined' && tempObj[part.i]) {
10332       tempObj = tempObj[part.i];
10333     } else {
10334       // If the obj doesn't have the property we create one with that name to define it
10335       var next = parsed[i + 1];
10336       // Here we set the name of the property which will be defined
10337       propName = typeof part.p === 'undefined' ? part.i : part.p;
10338       // Here we decide if this property will be an array or a new object
10339       propVal = typeof next.p === 'undefined' ? [] : {};
10340       tempObj[propName] = propVal;
10341       tempObj = tempObj[propName];
10342     }
10343   }
10344 }
10345
10346 /**
10347  * ### .getPathInfo(object, path)
10348  *
10349  * This allows the retrieval of property info in an
10350  * object given a string path.
10351  *
10352  * The path info consists of an object with the
10353  * following properties:
10354  *
10355  * * parent - The parent object of the property referenced by `path`
10356  * * name - The name of the final property, a number if it was an array indexer
10357  * * value - The value of the property, if it exists, otherwise `undefined`
10358  * * exists - Whether the property exists or not
10359  *
10360  * @param {Object} object
10361  * @param {String} path
10362  * @returns {Object} info
10363  * @namespace Utils
10364  * @name getPathInfo
10365  * @api public
10366  */
10367
10368 function getPathInfo(obj, path) {
10369   var parsed = parsePath(path);
10370   var last = parsed[parsed.length - 1];
10371   var info = {
10372     parent: parsed.length > 1 ? internalGetPathValue(obj, parsed, parsed.length - 1) : obj,
10373     name: last.p || last.i,
10374     value: internalGetPathValue(obj, parsed),
10375   };
10376   info.exists = hasProperty(info.parent, info.name);
10377
10378   return info;
10379 }
10380
10381 /**
10382  * ### .getPathValue(object, path)
10383  *
10384  * This allows the retrieval of values in an
10385  * object given a string path.
10386  *
10387  *     var obj = {
10388  *         prop1: {
10389  *             arr: ['a', 'b', 'c']
10390  *           , str: 'Hello'
10391  *         }
10392  *       , prop2: {
10393  *             arr: [ { nested: 'Universe' } ]
10394  *           , str: 'Hello again!'
10395  *         }
10396  *     }
10397  *
10398  * The following would be the results.
10399  *
10400  *     getPathValue(obj, 'prop1.str'); // Hello
10401  *     getPathValue(obj, 'prop1.att[2]'); // b
10402  *     getPathValue(obj, 'prop2.arr[0].nested'); // Universe
10403  *
10404  * @param {Object} object
10405  * @param {String} path
10406  * @returns {Object} value or `undefined`
10407  * @namespace Utils
10408  * @name getPathValue
10409  * @api public
10410  */
10411
10412 function getPathValue(obj, path) {
10413   var info = getPathInfo(obj, path);
10414   return info.value;
10415 }
10416
10417 /**
10418  * ### .setPathValue(object, path, value)
10419  *
10420  * Define the value in an object at a given string path.
10421  *
10422  * ```js
10423  * var obj = {
10424  *     prop1: {
10425  *         arr: ['a', 'b', 'c']
10426  *       , str: 'Hello'
10427  *     }
10428  *   , prop2: {
10429  *         arr: [ { nested: 'Universe' } ]
10430  *       , str: 'Hello again!'
10431  *     }
10432  * };
10433  * ```
10434  *
10435  * The following would be acceptable.
10436  *
10437  * ```js
10438  * var properties = require('tea-properties');
10439  * properties.set(obj, 'prop1.str', 'Hello Universe!');
10440  * properties.set(obj, 'prop1.arr[2]', 'B');
10441  * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' });
10442  * ```
10443  *
10444  * @param {Object} object
10445  * @param {String} path
10446  * @param {Mixed} value
10447  * @api private
10448  */
10449
10450 function setPathValue(obj, path, val) {
10451   var parsed = parsePath(path);
10452   internalSetPathValue(obj, val, parsed);
10453   return obj;
10454 }
10455
10456 module.exports = {
10457   hasProperty: hasProperty,
10458   getPathInfo: getPathInfo,
10459   getPathValue: getPathValue,
10460   setPathValue: setPathValue,
10461 };
10462
10463 },{}],38:[function(require,module,exports){
10464 (function (global, factory) {
10465         typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
10466         typeof define === 'function' && define.amd ? define(factory) :
10467         (global.typeDetect = factory());
10468 }(this, (function () { 'use strict';
10469
10470 /* !
10471  * type-detect
10472  * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
10473  * MIT Licensed
10474  */
10475 var promiseExists = typeof Promise === 'function';
10476
10477 /* eslint-disable no-undef */
10478 var globalObject = typeof self === 'object' ? self : global; // eslint-disable-line id-blacklist
10479
10480 var symbolExists = typeof Symbol !== 'undefined';
10481 var mapExists = typeof Map !== 'undefined';
10482 var setExists = typeof Set !== 'undefined';
10483 var weakMapExists = typeof WeakMap !== 'undefined';
10484 var weakSetExists = typeof WeakSet !== 'undefined';
10485 var dataViewExists = typeof DataView !== 'undefined';
10486 var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined';
10487 var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined';
10488 var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';
10489 var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';
10490 var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries());
10491 var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries());
10492 var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
10493 var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
10494 var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function';
10495 var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());
10496 var toStringLeftSliceLength = 8;
10497 var toStringRightSliceLength = -1;
10498 /**
10499  * ### typeOf (obj)
10500  *
10501  * Uses `Object.prototype.toString` to determine the type of an object,
10502  * normalising behaviour across engine versions & well optimised.
10503  *
10504  * @param {Mixed} object
10505  * @return {String} object type
10506  * @api public
10507  */
10508 function typeDetect(obj) {
10509   /* ! Speed optimisation
10510    * Pre:
10511    *   string literal     x 3,039,035 ops/sec ±1.62% (78 runs sampled)
10512    *   boolean literal    x 1,424,138 ops/sec ±4.54% (75 runs sampled)
10513    *   number literal     x 1,653,153 ops/sec ±1.91% (82 runs sampled)
10514    *   undefined          x 9,978,660 ops/sec ±1.92% (75 runs sampled)
10515    *   function           x 2,556,769 ops/sec ±1.73% (77 runs sampled)
10516    * Post:
10517    *   string literal     x 38,564,796 ops/sec ±1.15% (79 runs sampled)
10518    *   boolean literal    x 31,148,940 ops/sec ±1.10% (79 runs sampled)
10519    *   number literal     x 32,679,330 ops/sec ±1.90% (78 runs sampled)
10520    *   undefined          x 32,363,368 ops/sec ±1.07% (82 runs sampled)
10521    *   function           x 31,296,870 ops/sec ±0.96% (83 runs sampled)
10522    */
10523   var typeofObj = typeof obj;
10524   if (typeofObj !== 'object') {
10525     return typeofObj;
10526   }
10527
10528   /* ! Speed optimisation
10529    * Pre:
10530    *   null               x 28,645,765 ops/sec ±1.17% (82 runs sampled)
10531    * Post:
10532    *   null               x 36,428,962 ops/sec ±1.37% (84 runs sampled)
10533    */
10534   if (obj === null) {
10535     return 'null';
10536   }
10537
10538   /* ! Spec Conformance
10539    * Test: `Object.prototype.toString.call(window)``
10540    *  - Node === "[object global]"
10541    *  - Chrome === "[object global]"
10542    *  - Firefox === "[object Window]"
10543    *  - PhantomJS === "[object Window]"
10544    *  - Safari === "[object Window]"
10545    *  - IE 11 === "[object Window]"
10546    *  - IE Edge === "[object Window]"
10547    * Test: `Object.prototype.toString.call(this)``
10548    *  - Chrome Worker === "[object global]"
10549    *  - Firefox Worker === "[object DedicatedWorkerGlobalScope]"
10550    *  - Safari Worker === "[object DedicatedWorkerGlobalScope]"
10551    *  - IE 11 Worker === "[object WorkerGlobalScope]"
10552    *  - IE Edge Worker === "[object WorkerGlobalScope]"
10553    */
10554   if (obj === globalObject) {
10555     return 'global';
10556   }
10557
10558   /* ! Speed optimisation
10559    * Pre:
10560    *   array literal      x 2,888,352 ops/sec ±0.67% (82 runs sampled)
10561    * Post:
10562    *   array literal      x 22,479,650 ops/sec ±0.96% (81 runs sampled)
10563    */
10564   if (
10565     Array.isArray(obj) &&
10566     (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))
10567   ) {
10568     return 'Array';
10569   }
10570
10571   // Not caching existence of `window` and related properties due to potential
10572   // for `window` to be unset before tests in quasi-browser environments.
10573   if (typeof window === 'object' && window !== null) {
10574     /* ! Spec Conformance
10575      * (https://html.spec.whatwg.org/multipage/browsers.html#location)
10576      * WhatWG HTML$7.7.3 - The `Location` interface
10577      * Test: `Object.prototype.toString.call(window.location)``
10578      *  - IE <=11 === "[object Object]"
10579      *  - IE Edge <=13 === "[object Object]"
10580      */
10581     if (typeof window.location === 'object' && obj === window.location) {
10582       return 'Location';
10583     }
10584
10585     /* ! Spec Conformance
10586      * (https://html.spec.whatwg.org/#document)
10587      * WhatWG HTML$3.1.1 - The `Document` object
10588      * Note: Most browsers currently adher to the W3C DOM Level 2 spec
10589      *       (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268)
10590      *       which suggests that browsers should use HTMLTableCellElement for
10591      *       both TD and TH elements. WhatWG separates these.
10592      *       WhatWG HTML states:
10593      *         > For historical reasons, Window objects must also have a
10594      *         > writable, configurable, non-enumerable property named
10595      *         > HTMLDocument whose value is the Document interface object.
10596      * Test: `Object.prototype.toString.call(document)``
10597      *  - Chrome === "[object HTMLDocument]"
10598      *  - Firefox === "[object HTMLDocument]"
10599      *  - Safari === "[object HTMLDocument]"
10600      *  - IE <=10 === "[object Document]"
10601      *  - IE 11 === "[object HTMLDocument]"
10602      *  - IE Edge <=13 === "[object HTMLDocument]"
10603      */
10604     if (typeof window.document === 'object' && obj === window.document) {
10605       return 'Document';
10606     }
10607
10608     if (typeof window.navigator === 'object') {
10609       /* ! Spec Conformance
10610        * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
10611        * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
10612        * Test: `Object.prototype.toString.call(navigator.mimeTypes)``
10613        *  - IE <=10 === "[object MSMimeTypesCollection]"
10614        */
10615       if (typeof window.navigator.mimeTypes === 'object' &&
10616           obj === window.navigator.mimeTypes) {
10617         return 'MimeTypeArray';
10618       }
10619
10620       /* ! Spec Conformance
10621        * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
10622        * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
10623        * Test: `Object.prototype.toString.call(navigator.plugins)``
10624        *  - IE <=10 === "[object MSPluginsCollection]"
10625        */
10626       if (typeof window.navigator.plugins === 'object' &&
10627           obj === window.navigator.plugins) {
10628         return 'PluginArray';
10629       }
10630     }
10631
10632     if ((typeof window.HTMLElement === 'function' ||
10633         typeof window.HTMLElement === 'object') &&
10634         obj instanceof window.HTMLElement) {
10635       /* ! Spec Conformance
10636       * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
10637       * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
10638       * Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
10639       *  - IE <=10 === "[object HTMLBlockElement]"
10640       */
10641       if (obj.tagName === 'BLOCKQUOTE') {
10642         return 'HTMLQuoteElement';
10643       }
10644
10645       /* ! Spec Conformance
10646        * (https://html.spec.whatwg.org/#htmltabledatacellelement)
10647        * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
10648        * Note: Most browsers currently adher to the W3C DOM Level 2 spec
10649        *       (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
10650        *       which suggests that browsers should use HTMLTableCellElement for
10651        *       both TD and TH elements. WhatWG separates these.
10652        * Test: Object.prototype.toString.call(document.createElement('td'))
10653        *  - Chrome === "[object HTMLTableCellElement]"
10654        *  - Firefox === "[object HTMLTableCellElement]"
10655        *  - Safari === "[object HTMLTableCellElement]"
10656        */
10657       if (obj.tagName === 'TD') {
10658         return 'HTMLTableDataCellElement';
10659       }
10660
10661       /* ! Spec Conformance
10662        * (https://html.spec.whatwg.org/#htmltableheadercellelement)
10663        * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
10664        * Note: Most browsers currently adher to the W3C DOM Level 2 spec
10665        *       (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
10666        *       which suggests that browsers should use HTMLTableCellElement for
10667        *       both TD and TH elements. WhatWG separates these.
10668        * Test: Object.prototype.toString.call(document.createElement('th'))
10669        *  - Chrome === "[object HTMLTableCellElement]"
10670        *  - Firefox === "[object HTMLTableCellElement]"
10671        *  - Safari === "[object HTMLTableCellElement]"
10672        */
10673       if (obj.tagName === 'TH') {
10674         return 'HTMLTableHeaderCellElement';
10675       }
10676     }
10677   }
10678
10679   /* ! Speed optimisation
10680   * Pre:
10681   *   Float64Array       x 625,644 ops/sec ±1.58% (80 runs sampled)
10682   *   Float32Array       x 1,279,852 ops/sec ±2.91% (77 runs sampled)
10683   *   Uint32Array        x 1,178,185 ops/sec ±1.95% (83 runs sampled)
10684   *   Uint16Array        x 1,008,380 ops/sec ±2.25% (80 runs sampled)
10685   *   Uint8Array         x 1,128,040 ops/sec ±2.11% (81 runs sampled)
10686   *   Int32Array         x 1,170,119 ops/sec ±2.88% (80 runs sampled)
10687   *   Int16Array         x 1,176,348 ops/sec ±5.79% (86 runs sampled)
10688   *   Int8Array          x 1,058,707 ops/sec ±4.94% (77 runs sampled)
10689   *   Uint8ClampedArray  x 1,110,633 ops/sec ±4.20% (80 runs sampled)
10690   * Post:
10691   *   Float64Array       x 7,105,671 ops/sec ±13.47% (64 runs sampled)
10692   *   Float32Array       x 5,887,912 ops/sec ±1.46% (82 runs sampled)
10693   *   Uint32Array        x 6,491,661 ops/sec ±1.76% (79 runs sampled)
10694   *   Uint16Array        x 6,559,795 ops/sec ±1.67% (82 runs sampled)
10695   *   Uint8Array         x 6,463,966 ops/sec ±1.43% (85 runs sampled)
10696   *   Int32Array         x 5,641,841 ops/sec ±3.49% (81 runs sampled)
10697   *   Int16Array         x 6,583,511 ops/sec ±1.98% (80 runs sampled)
10698   *   Int8Array          x 6,606,078 ops/sec ±1.74% (81 runs sampled)
10699   *   Uint8ClampedArray  x 6,602,224 ops/sec ±1.77% (83 runs sampled)
10700   */
10701   var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]);
10702   if (typeof stringTag === 'string') {
10703     return stringTag;
10704   }
10705
10706   var objPrototype = Object.getPrototypeOf(obj);
10707   /* ! Speed optimisation
10708   * Pre:
10709   *   regex literal      x 1,772,385 ops/sec ±1.85% (77 runs sampled)
10710   *   regex constructor  x 2,143,634 ops/sec ±2.46% (78 runs sampled)
10711   * Post:
10712   *   regex literal      x 3,928,009 ops/sec ±0.65% (78 runs sampled)
10713   *   regex constructor  x 3,931,108 ops/sec ±0.58% (84 runs sampled)
10714   */
10715   if (objPrototype === RegExp.prototype) {
10716     return 'RegExp';
10717   }
10718
10719   /* ! Speed optimisation
10720   * Pre:
10721   *   date               x 2,130,074 ops/sec ±4.42% (68 runs sampled)
10722   * Post:
10723   *   date               x 3,953,779 ops/sec ±1.35% (77 runs sampled)
10724   */
10725   if (objPrototype === Date.prototype) {
10726     return 'Date';
10727   }
10728
10729   /* ! Spec Conformance
10730    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag)
10731    * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise":
10732    * Test: `Object.prototype.toString.call(Promise.resolve())``
10733    *  - Chrome <=47 === "[object Object]"
10734    *  - Edge <=20 === "[object Object]"
10735    *  - Firefox 29-Latest === "[object Promise]"
10736    *  - Safari 7.1-Latest === "[object Promise]"
10737    */
10738   if (promiseExists && objPrototype === Promise.prototype) {
10739     return 'Promise';
10740   }
10741
10742   /* ! Speed optimisation
10743   * Pre:
10744   *   set                x 2,222,186 ops/sec ±1.31% (82 runs sampled)
10745   * Post:
10746   *   set                x 4,545,879 ops/sec ±1.13% (83 runs sampled)
10747   */
10748   if (setExists && objPrototype === Set.prototype) {
10749     return 'Set';
10750   }
10751
10752   /* ! Speed optimisation
10753   * Pre:
10754   *   map                x 2,396,842 ops/sec ±1.59% (81 runs sampled)
10755   * Post:
10756   *   map                x 4,183,945 ops/sec ±6.59% (82 runs sampled)
10757   */
10758   if (mapExists && objPrototype === Map.prototype) {
10759     return 'Map';
10760   }
10761
10762   /* ! Speed optimisation
10763   * Pre:
10764   *   weakset            x 1,323,220 ops/sec ±2.17% (76 runs sampled)
10765   * Post:
10766   *   weakset            x 4,237,510 ops/sec ±2.01% (77 runs sampled)
10767   */
10768   if (weakSetExists && objPrototype === WeakSet.prototype) {
10769     return 'WeakSet';
10770   }
10771
10772   /* ! Speed optimisation
10773   * Pre:
10774   *   weakmap            x 1,500,260 ops/sec ±2.02% (78 runs sampled)
10775   * Post:
10776   *   weakmap            x 3,881,384 ops/sec ±1.45% (82 runs sampled)
10777   */
10778   if (weakMapExists && objPrototype === WeakMap.prototype) {
10779     return 'WeakMap';
10780   }
10781
10782   /* ! Spec Conformance
10783    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag)
10784    * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView":
10785    * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))``
10786    *  - Edge <=13 === "[object Object]"
10787    */
10788   if (dataViewExists && objPrototype === DataView.prototype) {
10789     return 'DataView';
10790   }
10791
10792   /* ! Spec Conformance
10793    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag)
10794    * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator":
10795    * Test: `Object.prototype.toString.call(new Map().entries())``
10796    *  - Edge <=13 === "[object Object]"
10797    */
10798   if (mapExists && objPrototype === mapIteratorPrototype) {
10799     return 'Map Iterator';
10800   }
10801
10802   /* ! Spec Conformance
10803    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag)
10804    * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator":
10805    * Test: `Object.prototype.toString.call(new Set().entries())``
10806    *  - Edge <=13 === "[object Object]"
10807    */
10808   if (setExists && objPrototype === setIteratorPrototype) {
10809     return 'Set Iterator';
10810   }
10811
10812   /* ! Spec Conformance
10813    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag)
10814    * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator":
10815    * Test: `Object.prototype.toString.call([][Symbol.iterator]())``
10816    *  - Edge <=13 === "[object Object]"
10817    */
10818   if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
10819     return 'Array Iterator';
10820   }
10821
10822   /* ! Spec Conformance
10823    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag)
10824    * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator":
10825    * Test: `Object.prototype.toString.call(''[Symbol.iterator]())``
10826    *  - Edge <=13 === "[object Object]"
10827    */
10828   if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
10829     return 'String Iterator';
10830   }
10831
10832   /* ! Speed optimisation
10833   * Pre:
10834   *   object from null   x 2,424,320 ops/sec ±1.67% (76 runs sampled)
10835   * Post:
10836   *   object from null   x 5,838,000 ops/sec ±0.99% (84 runs sampled)
10837   */
10838   if (objPrototype === null) {
10839     return 'Object';
10840   }
10841
10842   return Object
10843     .prototype
10844     .toString
10845     .call(obj)
10846     .slice(toStringLeftSliceLength, toStringRightSliceLength);
10847 }
10848
10849 return typeDetect;
10850
10851 })));
10852
10853 },{}]},{},[1])(1)
10854 });