spanish-quizzer

An app to quiz you on Spanish vocabulary and verb conjugations
git clone https://git.ashermorgan.net/spanish-quizzer/
Log | Files | Refs | README

chai.js (349596B)


      1 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
      2 module.exports = require('./lib/chai');
      3 
      4 },{"./lib/chai":2}],2:[function(require,module,exports){
      5 /*!
      6  * chai
      7  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
      8  * MIT Licensed
      9  */
     10 
     11 var used = [];
     12 
     13 /*!
     14  * Chai version
     15  */
     16 
     17 exports.version = '4.3.3';
     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":23,"assertion-error":34}],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       var assertionErrorObjectProperties = {
    240           actual: actual
    241         , expected: expected
    242         , showDiff: showDiff
    243       };
    244 
    245       var operator = util.getOperator(this, arguments);
    246       if (operator) {
    247         assertionErrorObjectProperties.operator = operator;
    248       }
    249 
    250       throw new AssertionError(
    251         msg,
    252         assertionErrorObjectProperties,
    253         (config.includeStack) ? this.assert : flag(this, 'ssfi'));
    254     }
    255   };
    256 
    257   /*!
    258    * ### ._obj
    259    *
    260    * Quick reference to stored `actual` value for plugin developers.
    261    *
    262    * @api private
    263    */
    264 
    265   Object.defineProperty(Assertion.prototype, '_obj',
    266     { get: function () {
    267         return flag(this, 'object');
    268       }
    269     , set: function (val) {
    270         flag(this, 'object', val);
    271       }
    272   });
    273 };
    274 
    275 },{"./config":4}],4:[function(require,module,exports){
    276 module.exports = {
    277 
    278   /**
    279    * ### config.includeStack
    280    *
    281    * User configurable property, influences whether stack trace
    282    * is included in Assertion error message. Default of false
    283    * suppresses stack trace in the error message.
    284    *
    285    *     chai.config.includeStack = true;  // enable stack on error
    286    *
    287    * @param {Boolean}
    288    * @api public
    289    */
    290 
    291   includeStack: false,
    292 
    293   /**
    294    * ### config.showDiff
    295    *
    296    * User configurable property, influences whether or not
    297    * the `showDiff` flag should be included in the thrown
    298    * AssertionErrors. `false` will always be `false`; `true`
    299    * will be true when the assertion has requested a diff
    300    * be shown.
    301    *
    302    * @param {Boolean}
    303    * @api public
    304    */
    305 
    306   showDiff: true,
    307 
    308   /**
    309    * ### config.truncateThreshold
    310    *
    311    * User configurable property, sets length threshold for actual and
    312    * expected values in assertion errors. If this threshold is exceeded, for
    313    * example for large data structures, the value is replaced with something
    314    * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.
    315    *
    316    * Set it to zero if you want to disable truncating altogether.
    317    *
    318    * This is especially userful when doing assertions on arrays: having this
    319    * set to a reasonable large value makes the failure messages readily
    320    * inspectable.
    321    *
    322    *     chai.config.truncateThreshold = 0;  // disable truncating
    323    *
    324    * @param {Number}
    325    * @api public
    326    */
    327 
    328   truncateThreshold: 40,
    329 
    330   /**
    331    * ### config.useProxy
    332    *
    333    * User configurable property, defines if chai will use a Proxy to throw
    334    * an error when a non-existent property is read, which protects users
    335    * from typos when using property-based assertions.
    336    *
    337    * Set it to false if you want to disable this feature.
    338    *
    339    *     chai.config.useProxy = false;  // disable use of Proxy
    340    *
    341    * This feature is automatically disabled regardless of this config value
    342    * in environments that don't support proxies.
    343    *
    344    * @param {Boolean}
    345    * @api public
    346    */
    347 
    348   useProxy: true,
    349 
    350   /**
    351    * ### config.proxyExcludedKeys
    352    *
    353    * User configurable property, defines which properties should be ignored
    354    * instead of throwing an error if they do not exist on the assertion.
    355    * This is only applied if the environment Chai is running in supports proxies and
    356    * if the `useProxy` configuration setting is enabled.
    357    * By default, `then` and `inspect` will not throw an error if they do not exist on the
    358    * assertion object because the `.inspect` property is read by `util.inspect` (for example, when
    359    * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking.
    360    *
    361    *     // By default these keys will not throw an error if they do not exist on the assertion object
    362    *     chai.config.proxyExcludedKeys = ['then', 'inspect'];
    363    *
    364    * @param {Array}
    365    * @api public
    366    */
    367 
    368   proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON']
    369 };
    370 
    371 },{}],5:[function(require,module,exports){
    372 /*!
    373  * chai
    374  * http://chaijs.com
    375  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
    376  * MIT Licensed
    377  */
    378 
    379 module.exports = function (chai, _) {
    380   var Assertion = chai.Assertion
    381     , AssertionError = chai.AssertionError
    382     , flag = _.flag;
    383 
    384   /**
    385    * ### Language Chains
    386    *
    387    * The following are provided as chainable getters to improve the readability
    388    * of your assertions.
    389    *
    390    * **Chains**
    391    *
    392    * - to
    393    * - be
    394    * - been
    395    * - is
    396    * - that
    397    * - which
    398    * - and
    399    * - has
    400    * - have
    401    * - with
    402    * - at
    403    * - of
    404    * - same
    405    * - but
    406    * - does
    407    * - still
    408    * - also
    409    *
    410    * @name language chains
    411    * @namespace BDD
    412    * @api public
    413    */
    414 
    415   [ 'to', 'be', 'been', 'is'
    416   , 'and', 'has', 'have', 'with'
    417   , 'that', 'which', 'at', 'of'
    418   , 'same', 'but', 'does', 'still', "also" ].forEach(function (chain) {
    419     Assertion.addProperty(chain);
    420   });
    421 
    422   /**
    423    * ### .not
    424    *
    425    * Negates all assertions that follow in the chain.
    426    *
    427    *     expect(function () {}).to.not.throw();
    428    *     expect({a: 1}).to.not.have.property('b');
    429    *     expect([1, 2]).to.be.an('array').that.does.not.include(3);
    430    *
    431    * Just because you can negate any assertion with `.not` doesn't mean you
    432    * should. With great power comes great responsibility. It's often best to
    433    * assert that the one expected output was produced, rather than asserting
    434    * that one of countless unexpected outputs wasn't produced. See individual
    435    * assertions for specific guidance.
    436    *
    437    *     expect(2).to.equal(2); // Recommended
    438    *     expect(2).to.not.equal(1); // Not recommended
    439    *
    440    * @name not
    441    * @namespace BDD
    442    * @api public
    443    */
    444 
    445   Assertion.addProperty('not', function () {
    446     flag(this, 'negate', true);
    447   });
    448 
    449   /**
    450    * ### .deep
    451    *
    452    * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property`
    453    * assertions that follow in the chain to use deep equality instead of strict
    454    * (`===`) equality. See the `deep-eql` project page for info on the deep
    455    * equality algorithm: https://github.com/chaijs/deep-eql.
    456    *
    457    *     // Target object deeply (but not strictly) equals `{a: 1}`
    458    *     expect({a: 1}).to.deep.equal({a: 1});
    459    *     expect({a: 1}).to.not.equal({a: 1});
    460    *
    461    *     // Target array deeply (but not strictly) includes `{a: 1}`
    462    *     expect([{a: 1}]).to.deep.include({a: 1});
    463    *     expect([{a: 1}]).to.not.include({a: 1});
    464    *
    465    *     // Target object deeply (but not strictly) includes `x: {a: 1}`
    466    *     expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
    467    *     expect({x: {a: 1}}).to.not.include({x: {a: 1}});
    468    *
    469    *     // Target array deeply (but not strictly) has member `{a: 1}`
    470    *     expect([{a: 1}]).to.have.deep.members([{a: 1}]);
    471    *     expect([{a: 1}]).to.not.have.members([{a: 1}]);
    472    *
    473    *     // Target set deeply (but not strictly) has key `{a: 1}`
    474    *     expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]);
    475    *     expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]);
    476    *
    477    *     // Target object deeply (but not strictly) has property `x: {a: 1}`
    478    *     expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});
    479    *     expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
    480    *
    481    * @name deep
    482    * @namespace BDD
    483    * @api public
    484    */
    485 
    486   Assertion.addProperty('deep', function () {
    487     flag(this, 'deep', true);
    488   });
    489 
    490   /**
    491    * ### .nested
    492    *
    493    * Enables dot- and bracket-notation in all `.property` and `.include`
    494    * assertions that follow in the chain.
    495    *
    496    *     expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
    497    *     expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
    498    *
    499    * If `.` or `[]` are part of an actual property name, they can be escaped by
    500    * adding two backslashes before them.
    501    *
    502    *     expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
    503    *     expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'});
    504    *
    505    * `.nested` cannot be combined with `.own`.
    506    *
    507    * @name nested
    508    * @namespace BDD
    509    * @api public
    510    */
    511 
    512   Assertion.addProperty('nested', function () {
    513     flag(this, 'nested', true);
    514   });
    515 
    516   /**
    517    * ### .own
    518    *
    519    * Causes all `.property` and `.include` assertions that follow in the chain
    520    * to ignore inherited properties.
    521    *
    522    *     Object.prototype.b = 2;
    523    *
    524    *     expect({a: 1}).to.have.own.property('a');
    525    *     expect({a: 1}).to.have.property('b');
    526    *     expect({a: 1}).to.not.have.own.property('b');
    527    *
    528    *     expect({a: 1}).to.own.include({a: 1});
    529    *     expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
    530    *
    531    * `.own` cannot be combined with `.nested`.
    532    *
    533    * @name own
    534    * @namespace BDD
    535    * @api public
    536    */
    537 
    538   Assertion.addProperty('own', function () {
    539     flag(this, 'own', true);
    540   });
    541 
    542   /**
    543    * ### .ordered
    544    *
    545    * Causes all `.members` assertions that follow in the chain to require that
    546    * members be in the same order.
    547    *
    548    *     expect([1, 2]).to.have.ordered.members([1, 2])
    549    *       .but.not.have.ordered.members([2, 1]);
    550    *
    551    * When `.include` and `.ordered` are combined, the ordering begins at the
    552    * start of both arrays.
    553    *
    554    *     expect([1, 2, 3]).to.include.ordered.members([1, 2])
    555    *       .but.not.include.ordered.members([2, 3]);
    556    *
    557    * @name ordered
    558    * @namespace BDD
    559    * @api public
    560    */
    561 
    562   Assertion.addProperty('ordered', function () {
    563     flag(this, 'ordered', true);
    564   });
    565 
    566   /**
    567    * ### .any
    568    *
    569    * Causes all `.keys` assertions that follow in the chain to only require that
    570    * the target have at least one of the given keys. This is the opposite of
    571    * `.all`, which requires that the target have all of the given keys.
    572    *
    573    *     expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
    574    *
    575    * See the `.keys` doc for guidance on when to use `.any` or `.all`.
    576    *
    577    * @name any
    578    * @namespace BDD
    579    * @api public
    580    */
    581 
    582   Assertion.addProperty('any', function () {
    583     flag(this, 'any', true);
    584     flag(this, 'all', false);
    585   });
    586 
    587   /**
    588    * ### .all
    589    *
    590    * Causes all `.keys` assertions that follow in the chain to require that the
    591    * target have all of the given keys. This is the opposite of `.any`, which
    592    * only requires that the target have at least one of the given keys.
    593    *
    594    *     expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
    595    *
    596    * Note that `.all` is used by default when neither `.all` nor `.any` are
    597    * added earlier in the chain. However, it's often best to add `.all` anyway
    598    * because it improves readability.
    599    *
    600    * See the `.keys` doc for guidance on when to use `.any` or `.all`.
    601    *
    602    * @name all
    603    * @namespace BDD
    604    * @api public
    605    */
    606 
    607   Assertion.addProperty('all', function () {
    608     flag(this, 'all', true);
    609     flag(this, 'any', false);
    610   });
    611 
    612   /**
    613    * ### .a(type[, msg])
    614    *
    615    * Asserts that the target's type is equal to the given string `type`. Types
    616    * are case insensitive. See the `type-detect` project page for info on the
    617    * type detection algorithm: https://github.com/chaijs/type-detect.
    618    *
    619    *     expect('foo').to.be.a('string');
    620    *     expect({a: 1}).to.be.an('object');
    621    *     expect(null).to.be.a('null');
    622    *     expect(undefined).to.be.an('undefined');
    623    *     expect(new Error).to.be.an('error');
    624    *     expect(Promise.resolve()).to.be.a('promise');
    625    *     expect(new Float32Array).to.be.a('float32array');
    626    *     expect(Symbol()).to.be.a('symbol');
    627    *
    628    * `.a` supports objects that have a custom type set via `Symbol.toStringTag`.
    629    *
    630    *     var myObj = {
    631    *       [Symbol.toStringTag]: 'myCustomType'
    632    *     };
    633    *
    634    *     expect(myObj).to.be.a('myCustomType').but.not.an('object');
    635    *
    636    * It's often best to use `.a` to check a target's type before making more
    637    * assertions on the same target. That way, you avoid unexpected behavior from
    638    * any assertion that does different things based on the target's type.
    639    *
    640    *     expect([1, 2, 3]).to.be.an('array').that.includes(2);
    641    *     expect([]).to.be.an('array').that.is.empty;
    642    *
    643    * Add `.not` earlier in the chain to negate `.a`. However, it's often best to
    644    * assert that the target is the expected type, rather than asserting that it
    645    * isn't one of many unexpected types.
    646    *
    647    *     expect('foo').to.be.a('string'); // Recommended
    648    *     expect('foo').to.not.be.an('array'); // Not recommended
    649    *
    650    * `.a` accepts an optional `msg` argument which is a custom error message to
    651    * show when the assertion fails. The message can also be given as the second
    652    * argument to `expect`.
    653    *
    654    *     expect(1).to.be.a('string', 'nooo why fail??');
    655    *     expect(1, 'nooo why fail??').to.be.a('string');
    656    *
    657    * `.a` can also be used as a language chain to improve the readability of
    658    * your assertions.
    659    *
    660    *     expect({b: 2}).to.have.a.property('b');
    661    *
    662    * The alias `.an` can be used interchangeably with `.a`.
    663    *
    664    * @name a
    665    * @alias an
    666    * @param {String} type
    667    * @param {String} msg _optional_
    668    * @namespace BDD
    669    * @api public
    670    */
    671 
    672   function an (type, msg) {
    673     if (msg) flag(this, 'message', msg);
    674     type = type.toLowerCase();
    675     var obj = flag(this, 'object')
    676       , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
    677 
    678     this.assert(
    679         type === _.type(obj).toLowerCase()
    680       , 'expected #{this} to be ' + article + type
    681       , 'expected #{this} not to be ' + article + type
    682     );
    683   }
    684 
    685   Assertion.addChainableMethod('an', an);
    686   Assertion.addChainableMethod('a', an);
    687 
    688   /**
    689    * ### .include(val[, msg])
    690    *
    691    * When the target is a string, `.include` asserts that the given string `val`
    692    * is a substring of the target.
    693    *
    694    *     expect('foobar').to.include('foo');
    695    *
    696    * When the target is an array, `.include` asserts that the given `val` is a
    697    * member of the target.
    698    *
    699    *     expect([1, 2, 3]).to.include(2);
    700    *
    701    * When the target is an object, `.include` asserts that the given object
    702    * `val`'s properties are a subset of the target's properties.
    703    *
    704    *     expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
    705    *
    706    * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a
    707    * member of the target. SameValueZero equality algorithm is used.
    708    *
    709    *     expect(new Set([1, 2])).to.include(2);
    710    *
    711    * When the target is a Map, `.include` asserts that the given `val` is one of
    712    * the values of the target. SameValueZero equality algorithm is used.
    713    *
    714    *     expect(new Map([['a', 1], ['b', 2]])).to.include(2);
    715    *
    716    * Because `.include` does different things based on the target's type, it's
    717    * important to check the target's type before using `.include`. See the `.a`
    718    * doc for info on testing a target's type.
    719    *
    720    *     expect([1, 2, 3]).to.be.an('array').that.includes(2);
    721    *
    722    * By default, strict (`===`) equality is used to compare array members and
    723    * object properties. Add `.deep` earlier in the chain to use deep equality
    724    * instead (WeakSet targets are not supported). See the `deep-eql` project
    725    * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
    726    *
    727    *     // Target array deeply (but not strictly) includes `{a: 1}`
    728    *     expect([{a: 1}]).to.deep.include({a: 1});
    729    *     expect([{a: 1}]).to.not.include({a: 1});
    730    *
    731    *     // Target object deeply (but not strictly) includes `x: {a: 1}`
    732    *     expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
    733    *     expect({x: {a: 1}}).to.not.include({x: {a: 1}});
    734    *
    735    * By default, all of the target's properties are searched when working with
    736    * objects. This includes properties that are inherited and/or non-enumerable.
    737    * Add `.own` earlier in the chain to exclude the target's inherited
    738    * properties from the search.
    739    *
    740    *     Object.prototype.b = 2;
    741    *
    742    *     expect({a: 1}).to.own.include({a: 1});
    743    *     expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
    744    *
    745    * Note that a target object is always only searched for `val`'s own
    746    * enumerable properties.
    747    *
    748    * `.deep` and `.own` can be combined.
    749    *
    750    *     expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}});
    751    *
    752    * Add `.nested` earlier in the chain to enable dot- and bracket-notation when
    753    * referencing nested properties.
    754    *
    755    *     expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
    756    *
    757    * If `.` or `[]` are part of an actual property name, they can be escaped by
    758    * adding two backslashes before them.
    759    *
    760    *     expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2});
    761    *
    762    * `.deep` and `.nested` can be combined.
    763    *
    764    *     expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}});
    765    *
    766    * `.own` and `.nested` cannot be combined.
    767    *
    768    * Add `.not` earlier in the chain to negate `.include`.
    769    *
    770    *     expect('foobar').to.not.include('taco');
    771    *     expect([1, 2, 3]).to.not.include(4);
    772    *
    773    * However, it's dangerous to negate `.include` when the target is an object.
    774    * The problem is that it creates uncertain expectations by asserting that the
    775    * target object doesn't have all of `val`'s key/value pairs but may or may
    776    * not have some of them. It's often best to identify the exact output that's
    777    * expected, and then write an assertion that only accepts that exact output.
    778    *
    779    * When the target object isn't even expected to have `val`'s keys, it's
    780    * often best to assert exactly that.
    781    *
    782    *     expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended
    783    *     expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended
    784    *
    785    * When the target object is expected to have `val`'s keys, it's often best to
    786    * assert that each of the properties has its expected value, rather than
    787    * asserting that each property doesn't have one of many unexpected values.
    788    *
    789    *     expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended
    790    *     expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended
    791    *
    792    * `.include` accepts an optional `msg` argument which is a custom error
    793    * message to show when the assertion fails. The message can also be given as
    794    * the second argument to `expect`.
    795    *
    796    *     expect([1, 2, 3]).to.include(4, 'nooo why fail??');
    797    *     expect([1, 2, 3], 'nooo why fail??').to.include(4);
    798    *
    799    * `.include` can also be used as a language chain, causing all `.members` and
    800    * `.keys` assertions that follow in the chain to require the target to be a
    801    * superset of the expected set, rather than an identical set. Note that
    802    * `.members` ignores duplicates in the subset when `.include` is added.
    803    *
    804    *     // Target object's keys are a superset of ['a', 'b'] but not identical
    805    *     expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');
    806    *     expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');
    807    *
    808    *     // Target array is a superset of [1, 2] but not identical
    809    *     expect([1, 2, 3]).to.include.members([1, 2]);
    810    *     expect([1, 2, 3]).to.not.have.members([1, 2]);
    811    *
    812    *     // Duplicates in the subset are ignored
    813    *     expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
    814    *
    815    * Note that adding `.any` earlier in the chain causes the `.keys` assertion
    816    * to ignore `.include`.
    817    *
    818    *     // Both assertions are identical
    819    *     expect({a: 1}).to.include.any.keys('a', 'b');
    820    *     expect({a: 1}).to.have.any.keys('a', 'b');
    821    *
    822    * The aliases `.includes`, `.contain`, and `.contains` can be used
    823    * interchangeably with `.include`.
    824    *
    825    * @name include
    826    * @alias contain
    827    * @alias includes
    828    * @alias contains
    829    * @param {Mixed} val
    830    * @param {String} msg _optional_
    831    * @namespace BDD
    832    * @api public
    833    */
    834 
    835   function SameValueZero(a, b) {
    836     return (_.isNaN(a) && _.isNaN(b)) || a === b;
    837   }
    838 
    839   function includeChainingBehavior () {
    840     flag(this, 'contains', true);
    841   }
    842 
    843   function include (val, msg) {
    844     if (msg) flag(this, 'message', msg);
    845 
    846     var obj = flag(this, 'object')
    847       , objType = _.type(obj).toLowerCase()
    848       , flagMsg = flag(this, 'message')
    849       , negate = flag(this, 'negate')
    850       , ssfi = flag(this, 'ssfi')
    851       , isDeep = flag(this, 'deep')
    852       , descriptor = isDeep ? 'deep ' : '';
    853 
    854     flagMsg = flagMsg ? flagMsg + ': ' : '';
    855 
    856     var included = false;
    857 
    858     switch (objType) {
    859       case 'string':
    860         included = obj.indexOf(val) !== -1;
    861         break;
    862 
    863       case 'weakset':
    864         if (isDeep) {
    865           throw new AssertionError(
    866             flagMsg + 'unable to use .deep.include with WeakSet',
    867             undefined,
    868             ssfi
    869           );
    870         }
    871 
    872         included = obj.has(val);
    873         break;
    874 
    875       case 'map':
    876         var isEql = isDeep ? _.eql : SameValueZero;
    877         obj.forEach(function (item) {
    878           included = included || isEql(item, val);
    879         });
    880         break;
    881 
    882       case 'set':
    883         if (isDeep) {
    884           obj.forEach(function (item) {
    885             included = included || _.eql(item, val);
    886           });
    887         } else {
    888           included = obj.has(val);
    889         }
    890         break;
    891 
    892       case 'array':
    893         if (isDeep) {
    894           included = obj.some(function (item) {
    895             return _.eql(item, val);
    896           })
    897         } else {
    898           included = obj.indexOf(val) !== -1;
    899         }
    900         break;
    901 
    902       default:
    903         // This block is for asserting a subset of properties in an object.
    904         // `_.expectTypes` isn't used here because `.include` should work with
    905         // objects with a custom `@@toStringTag`.
    906         if (val !== Object(val)) {
    907           throw new AssertionError(
    908             flagMsg + 'the given combination of arguments ('
    909             + objType + ' and '
    910             + _.type(val).toLowerCase() + ')'
    911             + ' is invalid for this assertion. '
    912             + 'You can use an array, a map, an object, a set, a string, '
    913             + 'or a weakset instead of a '
    914             + _.type(val).toLowerCase(),
    915             undefined,
    916             ssfi
    917           );
    918         }
    919 
    920         var props = Object.keys(val)
    921           , firstErr = null
    922           , numErrs = 0;
    923 
    924         props.forEach(function (prop) {
    925           var propAssertion = new Assertion(obj);
    926           _.transferFlags(this, propAssertion, true);
    927           flag(propAssertion, 'lockSsfi', true);
    928 
    929           if (!negate || props.length === 1) {
    930             propAssertion.property(prop, val[prop]);
    931             return;
    932           }
    933 
    934           try {
    935             propAssertion.property(prop, val[prop]);
    936           } catch (err) {
    937             if (!_.checkError.compatibleConstructor(err, AssertionError)) {
    938               throw err;
    939             }
    940             if (firstErr === null) firstErr = err;
    941             numErrs++;
    942           }
    943         }, this);
    944 
    945         // When validating .not.include with multiple properties, we only want
    946         // to throw an assertion error if all of the properties are included,
    947         // in which case we throw the first property assertion error that we
    948         // encountered.
    949         if (negate && props.length > 1 && numErrs === props.length) {
    950           throw firstErr;
    951         }
    952         return;
    953     }
    954 
    955     // Assert inclusion in collection or substring in a string.
    956     this.assert(
    957       included
    958       , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val)
    959       , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val));
    960   }
    961 
    962   Assertion.addChainableMethod('include', include, includeChainingBehavior);
    963   Assertion.addChainableMethod('contain', include, includeChainingBehavior);
    964   Assertion.addChainableMethod('contains', include, includeChainingBehavior);
    965   Assertion.addChainableMethod('includes', include, includeChainingBehavior);
    966 
    967   /**
    968    * ### .ok
    969    *
    970    * Asserts that the target is a truthy value (considered `true` in boolean context).
    971    * However, it's often best to assert that the target is strictly (`===`) or
    972    * deeply equal to its expected value.
    973    *
    974    *     expect(1).to.equal(1); // Recommended
    975    *     expect(1).to.be.ok; // Not recommended
    976    *
    977    *     expect(true).to.be.true; // Recommended
    978    *     expect(true).to.be.ok; // Not recommended
    979    *
    980    * Add `.not` earlier in the chain to negate `.ok`.
    981    *
    982    *     expect(0).to.equal(0); // Recommended
    983    *     expect(0).to.not.be.ok; // Not recommended
    984    *
    985    *     expect(false).to.be.false; // Recommended
    986    *     expect(false).to.not.be.ok; // Not recommended
    987    *
    988    *     expect(null).to.be.null; // Recommended
    989    *     expect(null).to.not.be.ok; // Not recommended
    990    *
    991    *     expect(undefined).to.be.undefined; // Recommended
    992    *     expect(undefined).to.not.be.ok; // Not recommended
    993    *
    994    * A custom error message can be given as the second argument to `expect`.
    995    *
    996    *     expect(false, 'nooo why fail??').to.be.ok;
    997    *
    998    * @name ok
    999    * @namespace BDD
   1000    * @api public
   1001    */
   1002 
   1003   Assertion.addProperty('ok', function () {
   1004     this.assert(
   1005         flag(this, 'object')
   1006       , 'expected #{this} to be truthy'
   1007       , 'expected #{this} to be falsy');
   1008   });
   1009 
   1010   /**
   1011    * ### .true
   1012    *
   1013    * Asserts that the target is strictly (`===`) equal to `true`.
   1014    *
   1015    *     expect(true).to.be.true;
   1016    *
   1017    * Add `.not` earlier in the chain to negate `.true`. However, it's often best
   1018    * to assert that the target is equal to its expected value, rather than not
   1019    * equal to `true`.
   1020    *
   1021    *     expect(false).to.be.false; // Recommended
   1022    *     expect(false).to.not.be.true; // Not recommended
   1023    *
   1024    *     expect(1).to.equal(1); // Recommended
   1025    *     expect(1).to.not.be.true; // Not recommended
   1026    *
   1027    * A custom error message can be given as the second argument to `expect`.
   1028    *
   1029    *     expect(false, 'nooo why fail??').to.be.true;
   1030    *
   1031    * @name true
   1032    * @namespace BDD
   1033    * @api public
   1034    */
   1035 
   1036   Assertion.addProperty('true', function () {
   1037     this.assert(
   1038         true === flag(this, 'object')
   1039       , 'expected #{this} to be true'
   1040       , 'expected #{this} to be false'
   1041       , flag(this, 'negate') ? false : true
   1042     );
   1043   });
   1044 
   1045   /**
   1046    * ### .false
   1047    *
   1048    * Asserts that the target is strictly (`===`) equal to `false`.
   1049    *
   1050    *     expect(false).to.be.false;
   1051    *
   1052    * Add `.not` earlier in the chain to negate `.false`. However, it's often
   1053    * best to assert that the target is equal to its expected value, rather than
   1054    * not equal to `false`.
   1055    *
   1056    *     expect(true).to.be.true; // Recommended
   1057    *     expect(true).to.not.be.false; // Not recommended
   1058    *
   1059    *     expect(1).to.equal(1); // Recommended
   1060    *     expect(1).to.not.be.false; // Not recommended
   1061    *
   1062    * A custom error message can be given as the second argument to `expect`.
   1063    *
   1064    *     expect(true, 'nooo why fail??').to.be.false;
   1065    *
   1066    * @name false
   1067    * @namespace BDD
   1068    * @api public
   1069    */
   1070 
   1071   Assertion.addProperty('false', function () {
   1072     this.assert(
   1073         false === flag(this, 'object')
   1074       , 'expected #{this} to be false'
   1075       , 'expected #{this} to be true'
   1076       , flag(this, 'negate') ? true : false
   1077     );
   1078   });
   1079 
   1080   /**
   1081    * ### .null
   1082    *
   1083    * Asserts that the target is strictly (`===`) equal to `null`.
   1084    *
   1085    *     expect(null).to.be.null;
   1086    *
   1087    * Add `.not` earlier in the chain to negate `.null`. However, it's often best
   1088    * to assert that the target is equal to its expected value, rather than not
   1089    * equal to `null`.
   1090    *
   1091    *     expect(1).to.equal(1); // Recommended
   1092    *     expect(1).to.not.be.null; // Not recommended
   1093    *
   1094    * A custom error message can be given as the second argument to `expect`.
   1095    *
   1096    *     expect(42, 'nooo why fail??').to.be.null;
   1097    *
   1098    * @name null
   1099    * @namespace BDD
   1100    * @api public
   1101    */
   1102 
   1103   Assertion.addProperty('null', function () {
   1104     this.assert(
   1105         null === flag(this, 'object')
   1106       , 'expected #{this} to be null'
   1107       , 'expected #{this} not to be null'
   1108     );
   1109   });
   1110 
   1111   /**
   1112    * ### .undefined
   1113    *
   1114    * Asserts that the target is strictly (`===`) equal to `undefined`.
   1115    *
   1116    *     expect(undefined).to.be.undefined;
   1117    *
   1118    * Add `.not` earlier in the chain to negate `.undefined`. However, it's often
   1119    * best to assert that the target is equal to its expected value, rather than
   1120    * not equal to `undefined`.
   1121    *
   1122    *     expect(1).to.equal(1); // Recommended
   1123    *     expect(1).to.not.be.undefined; // Not recommended
   1124    *
   1125    * A custom error message can be given as the second argument to `expect`.
   1126    *
   1127    *     expect(42, 'nooo why fail??').to.be.undefined;
   1128    *
   1129    * @name undefined
   1130    * @namespace BDD
   1131    * @api public
   1132    */
   1133 
   1134   Assertion.addProperty('undefined', function () {
   1135     this.assert(
   1136         undefined === flag(this, 'object')
   1137       , 'expected #{this} to be undefined'
   1138       , 'expected #{this} not to be undefined'
   1139     );
   1140   });
   1141 
   1142   /**
   1143    * ### .NaN
   1144    *
   1145    * Asserts that the target is exactly `NaN`.
   1146    *
   1147    *     expect(NaN).to.be.NaN;
   1148    *
   1149    * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best
   1150    * to assert that the target is equal to its expected value, rather than not
   1151    * equal to `NaN`.
   1152    *
   1153    *     expect('foo').to.equal('foo'); // Recommended
   1154    *     expect('foo').to.not.be.NaN; // Not recommended
   1155    *
   1156    * A custom error message can be given as the second argument to `expect`.
   1157    *
   1158    *     expect(42, 'nooo why fail??').to.be.NaN;
   1159    *
   1160    * @name NaN
   1161    * @namespace BDD
   1162    * @api public
   1163    */
   1164 
   1165   Assertion.addProperty('NaN', function () {
   1166     this.assert(
   1167         _.isNaN(flag(this, 'object'))
   1168         , 'expected #{this} to be NaN'
   1169         , 'expected #{this} not to be NaN'
   1170     );
   1171   });
   1172 
   1173   /**
   1174    * ### .exist
   1175    *
   1176    * Asserts that the target is not strictly (`===`) equal to either `null` or
   1177    * `undefined`. However, it's often best to assert that the target is equal to
   1178    * its expected value.
   1179    *
   1180    *     expect(1).to.equal(1); // Recommended
   1181    *     expect(1).to.exist; // Not recommended
   1182    *
   1183    *     expect(0).to.equal(0); // Recommended
   1184    *     expect(0).to.exist; // Not recommended
   1185    *
   1186    * Add `.not` earlier in the chain to negate `.exist`.
   1187    *
   1188    *     expect(null).to.be.null; // Recommended
   1189    *     expect(null).to.not.exist; // Not recommended
   1190    *
   1191    *     expect(undefined).to.be.undefined; // Recommended
   1192    *     expect(undefined).to.not.exist; // Not recommended
   1193    *
   1194    * A custom error message can be given as the second argument to `expect`.
   1195    *
   1196    *     expect(null, 'nooo why fail??').to.exist;
   1197    *
   1198    * The alias `.exists` can be used interchangeably with `.exist`.
   1199    *
   1200    * @name exist
   1201    * @alias exists
   1202    * @namespace BDD
   1203    * @api public
   1204    */
   1205 
   1206   function assertExist () {
   1207     var val = flag(this, 'object');
   1208     this.assert(
   1209         val !== null && val !== undefined
   1210       , 'expected #{this} to exist'
   1211       , 'expected #{this} to not exist'
   1212     );
   1213   }
   1214 
   1215   Assertion.addProperty('exist', assertExist);
   1216   Assertion.addProperty('exists', assertExist);
   1217 
   1218   /**
   1219    * ### .empty
   1220    *
   1221    * When the target is a string or array, `.empty` asserts that the target's
   1222    * `length` property is strictly (`===`) equal to `0`.
   1223    *
   1224    *     expect([]).to.be.empty;
   1225    *     expect('').to.be.empty;
   1226    *
   1227    * When the target is a map or set, `.empty` asserts that the target's `size`
   1228    * property is strictly equal to `0`.
   1229    *
   1230    *     expect(new Set()).to.be.empty;
   1231    *     expect(new Map()).to.be.empty;
   1232    *
   1233    * When the target is a non-function object, `.empty` asserts that the target
   1234    * doesn't have any own enumerable properties. Properties with Symbol-based
   1235    * keys are excluded from the count.
   1236    *
   1237    *     expect({}).to.be.empty;
   1238    *
   1239    * Because `.empty` does different things based on the target's type, it's
   1240    * important to check the target's type before using `.empty`. See the `.a`
   1241    * doc for info on testing a target's type.
   1242    *
   1243    *     expect([]).to.be.an('array').that.is.empty;
   1244    *
   1245    * Add `.not` earlier in the chain to negate `.empty`. However, it's often
   1246    * best to assert that the target contains its expected number of values,
   1247    * rather than asserting that it's not empty.
   1248    *
   1249    *     expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
   1250    *     expect([1, 2, 3]).to.not.be.empty; // Not recommended
   1251    *
   1252    *     expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended
   1253    *     expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended
   1254    *
   1255    *     expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended
   1256    *     expect({a: 1}).to.not.be.empty; // Not recommended
   1257    *
   1258    * A custom error message can be given as the second argument to `expect`.
   1259    *
   1260    *     expect([1, 2, 3], 'nooo why fail??').to.be.empty;
   1261    *
   1262    * @name empty
   1263    * @namespace BDD
   1264    * @api public
   1265    */
   1266 
   1267   Assertion.addProperty('empty', function () {
   1268     var val = flag(this, 'object')
   1269       , ssfi = flag(this, 'ssfi')
   1270       , flagMsg = flag(this, 'message')
   1271       , itemsCount;
   1272 
   1273     flagMsg = flagMsg ? flagMsg + ': ' : '';
   1274 
   1275     switch (_.type(val).toLowerCase()) {
   1276       case 'array':
   1277       case 'string':
   1278         itemsCount = val.length;
   1279         break;
   1280       case 'map':
   1281       case 'set':
   1282         itemsCount = val.size;
   1283         break;
   1284       case 'weakmap':
   1285       case 'weakset':
   1286         throw new AssertionError(
   1287           flagMsg + '.empty was passed a weak collection',
   1288           undefined,
   1289           ssfi
   1290         );
   1291       case 'function':
   1292         var msg = flagMsg + '.empty was passed a function ' + _.getName(val);
   1293         throw new AssertionError(msg.trim(), undefined, ssfi);
   1294       default:
   1295         if (val !== Object(val)) {
   1296           throw new AssertionError(
   1297             flagMsg + '.empty was passed non-string primitive ' + _.inspect(val),
   1298             undefined,
   1299             ssfi
   1300           );
   1301         }
   1302         itemsCount = Object.keys(val).length;
   1303     }
   1304 
   1305     this.assert(
   1306         0 === itemsCount
   1307       , 'expected #{this} to be empty'
   1308       , 'expected #{this} not to be empty'
   1309     );
   1310   });
   1311 
   1312   /**
   1313    * ### .arguments
   1314    *
   1315    * Asserts that the target is an `arguments` object.
   1316    *
   1317    *     function test () {
   1318    *       expect(arguments).to.be.arguments;
   1319    *     }
   1320    *
   1321    *     test();
   1322    *
   1323    * Add `.not` earlier in the chain to negate `.arguments`. However, it's often
   1324    * best to assert which type the target is expected to be, rather than
   1325    * asserting that it’s not an `arguments` object.
   1326    *
   1327    *     expect('foo').to.be.a('string'); // Recommended
   1328    *     expect('foo').to.not.be.arguments; // Not recommended
   1329    *
   1330    * A custom error message can be given as the second argument to `expect`.
   1331    *
   1332    *     expect({}, 'nooo why fail??').to.be.arguments;
   1333    *
   1334    * The alias `.Arguments` can be used interchangeably with `.arguments`.
   1335    *
   1336    * @name arguments
   1337    * @alias Arguments
   1338    * @namespace BDD
   1339    * @api public
   1340    */
   1341 
   1342   function checkArguments () {
   1343     var obj = flag(this, 'object')
   1344       , type = _.type(obj);
   1345     this.assert(
   1346         'Arguments' === type
   1347       , 'expected #{this} to be arguments but got ' + type
   1348       , 'expected #{this} to not be arguments'
   1349     );
   1350   }
   1351 
   1352   Assertion.addProperty('arguments', checkArguments);
   1353   Assertion.addProperty('Arguments', checkArguments);
   1354 
   1355   /**
   1356    * ### .equal(val[, msg])
   1357    *
   1358    * Asserts that the target is strictly (`===`) equal to the given `val`.
   1359    *
   1360    *     expect(1).to.equal(1);
   1361    *     expect('foo').to.equal('foo');
   1362    *
   1363    * Add `.deep` earlier in the chain to use deep equality instead. See the
   1364    * `deep-eql` project page for info on the deep equality algorithm:
   1365    * https://github.com/chaijs/deep-eql.
   1366    *
   1367    *     // Target object deeply (but not strictly) equals `{a: 1}`
   1368    *     expect({a: 1}).to.deep.equal({a: 1});
   1369    *     expect({a: 1}).to.not.equal({a: 1});
   1370    *
   1371    *     // Target array deeply (but not strictly) equals `[1, 2]`
   1372    *     expect([1, 2]).to.deep.equal([1, 2]);
   1373    *     expect([1, 2]).to.not.equal([1, 2]);
   1374    *
   1375    * Add `.not` earlier in the chain to negate `.equal`. However, it's often
   1376    * best to assert that the target is equal to its expected value, rather than
   1377    * not equal to one of countless unexpected values.
   1378    *
   1379    *     expect(1).to.equal(1); // Recommended
   1380    *     expect(1).to.not.equal(2); // Not recommended
   1381    *
   1382    * `.equal` accepts an optional `msg` argument which is a custom error message
   1383    * to show when the assertion fails. The message can also be given as the
   1384    * second argument to `expect`.
   1385    *
   1386    *     expect(1).to.equal(2, 'nooo why fail??');
   1387    *     expect(1, 'nooo why fail??').to.equal(2);
   1388    *
   1389    * The aliases `.equals` and `eq` can be used interchangeably with `.equal`.
   1390    *
   1391    * @name equal
   1392    * @alias equals
   1393    * @alias eq
   1394    * @param {Mixed} val
   1395    * @param {String} msg _optional_
   1396    * @namespace BDD
   1397    * @api public
   1398    */
   1399 
   1400   function assertEqual (val, msg) {
   1401     if (msg) flag(this, 'message', msg);
   1402     var obj = flag(this, 'object');
   1403     if (flag(this, 'deep')) {
   1404       var prevLockSsfi = flag(this, 'lockSsfi');
   1405       flag(this, 'lockSsfi', true);
   1406       this.eql(val);
   1407       flag(this, 'lockSsfi', prevLockSsfi);
   1408     } else {
   1409       this.assert(
   1410           val === obj
   1411         , 'expected #{this} to equal #{exp}'
   1412         , 'expected #{this} to not equal #{exp}'
   1413         , val
   1414         , this._obj
   1415         , true
   1416       );
   1417     }
   1418   }
   1419 
   1420   Assertion.addMethod('equal', assertEqual);
   1421   Assertion.addMethod('equals', assertEqual);
   1422   Assertion.addMethod('eq', assertEqual);
   1423 
   1424   /**
   1425    * ### .eql(obj[, msg])
   1426    *
   1427    * Asserts that the target is deeply equal to the given `obj`. See the
   1428    * `deep-eql` project page for info on the deep equality algorithm:
   1429    * https://github.com/chaijs/deep-eql.
   1430    *
   1431    *     // Target object is deeply (but not strictly) equal to {a: 1}
   1432    *     expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1});
   1433    *
   1434    *     // Target array is deeply (but not strictly) equal to [1, 2]
   1435    *     expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]);
   1436    *
   1437    * Add `.not` earlier in the chain to negate `.eql`. However, it's often best
   1438    * to assert that the target is deeply equal to its expected value, rather
   1439    * than not deeply equal to one of countless unexpected values.
   1440    *
   1441    *     expect({a: 1}).to.eql({a: 1}); // Recommended
   1442    *     expect({a: 1}).to.not.eql({b: 2}); // Not recommended
   1443    *
   1444    * `.eql` accepts an optional `msg` argument which is a custom error message
   1445    * to show when the assertion fails. The message can also be given as the
   1446    * second argument to `expect`.
   1447    *
   1448    *     expect({a: 1}).to.eql({b: 2}, 'nooo why fail??');
   1449    *     expect({a: 1}, 'nooo why fail??').to.eql({b: 2});
   1450    *
   1451    * The alias `.eqls` can be used interchangeably with `.eql`.
   1452    *
   1453    * The `.deep.equal` assertion is almost identical to `.eql` but with one
   1454    * difference: `.deep.equal` causes deep equality comparisons to also be used
   1455    * for any other assertions that follow in the chain.
   1456    *
   1457    * @name eql
   1458    * @alias eqls
   1459    * @param {Mixed} obj
   1460    * @param {String} msg _optional_
   1461    * @namespace BDD
   1462    * @api public
   1463    */
   1464 
   1465   function assertEql(obj, msg) {
   1466     if (msg) flag(this, 'message', msg);
   1467     this.assert(
   1468         _.eql(obj, flag(this, 'object'))
   1469       , 'expected #{this} to deeply equal #{exp}'
   1470       , 'expected #{this} to not deeply equal #{exp}'
   1471       , obj
   1472       , this._obj
   1473       , true
   1474     );
   1475   }
   1476 
   1477   Assertion.addMethod('eql', assertEql);
   1478   Assertion.addMethod('eqls', assertEql);
   1479 
   1480   /**
   1481    * ### .above(n[, msg])
   1482    *
   1483    * Asserts that the target is a number or a date greater than the given number or date `n` respectively.
   1484    * However, it's often best to assert that the target is equal to its expected
   1485    * value.
   1486    *
   1487    *     expect(2).to.equal(2); // Recommended
   1488    *     expect(2).to.be.above(1); // Not recommended
   1489    *
   1490    * Add `.lengthOf` earlier in the chain to assert that the target's `length`
   1491    * or `size` is greater than the given number `n`.
   1492    *
   1493    *     expect('foo').to.have.lengthOf(3); // Recommended
   1494    *     expect('foo').to.have.lengthOf.above(2); // Not recommended
   1495    *
   1496    *     expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
   1497    *     expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended
   1498    *
   1499    * Add `.not` earlier in the chain to negate `.above`.
   1500    *
   1501    *     expect(2).to.equal(2); // Recommended
   1502    *     expect(1).to.not.be.above(2); // Not recommended
   1503    *
   1504    * `.above` accepts an optional `msg` argument which is a custom error message
   1505    * to show when the assertion fails. The message can also be given as the
   1506    * second argument to `expect`.
   1507    *
   1508    *     expect(1).to.be.above(2, 'nooo why fail??');
   1509    *     expect(1, 'nooo why fail??').to.be.above(2);
   1510    *
   1511    * The aliases `.gt` and `.greaterThan` can be used interchangeably with
   1512    * `.above`.
   1513    *
   1514    * @name above
   1515    * @alias gt
   1516    * @alias greaterThan
   1517    * @param {Number} n
   1518    * @param {String} msg _optional_
   1519    * @namespace BDD
   1520    * @api public
   1521    */
   1522 
   1523   function assertAbove (n, msg) {
   1524     if (msg) flag(this, 'message', msg);
   1525     var obj = flag(this, 'object')
   1526       , doLength = flag(this, 'doLength')
   1527       , flagMsg = flag(this, 'message')
   1528       , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
   1529       , ssfi = flag(this, 'ssfi')
   1530       , objType = _.type(obj).toLowerCase()
   1531       , nType = _.type(n).toLowerCase()
   1532       , errorMessage
   1533       , shouldThrow = true;
   1534 
   1535     if (doLength && objType !== 'map' && objType !== 'set') {
   1536       new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
   1537     }
   1538 
   1539     if (!doLength && (objType === 'date' && nType !== 'date')) {
   1540       errorMessage = msgPrefix + 'the argument to above must be a date';
   1541     } else if (nType !== 'number' && (doLength || objType === 'number')) {
   1542       errorMessage = msgPrefix + 'the argument to above must be a number';
   1543     } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
   1544       var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
   1545       errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
   1546     } else {
   1547       shouldThrow = false;
   1548     }
   1549 
   1550     if (shouldThrow) {
   1551       throw new AssertionError(errorMessage, undefined, ssfi);
   1552     }
   1553 
   1554     if (doLength) {
   1555       var descriptor = 'length'
   1556         , itemsCount;
   1557       if (objType === 'map' || objType === 'set') {
   1558         descriptor = 'size';
   1559         itemsCount = obj.size;
   1560       } else {
   1561         itemsCount = obj.length;
   1562       }
   1563       this.assert(
   1564           itemsCount > n
   1565         , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}'
   1566         , 'expected #{this} to not have a ' + descriptor + ' above #{exp}'
   1567         , n
   1568         , itemsCount
   1569       );
   1570     } else {
   1571       this.assert(
   1572           obj > n
   1573         , 'expected #{this} to be above #{exp}'
   1574         , 'expected #{this} to be at most #{exp}'
   1575         , n
   1576       );
   1577     }
   1578   }
   1579 
   1580   Assertion.addMethod('above', assertAbove);
   1581   Assertion.addMethod('gt', assertAbove);
   1582   Assertion.addMethod('greaterThan', assertAbove);
   1583 
   1584   /**
   1585    * ### .least(n[, msg])
   1586    *
   1587    * Asserts that the target is a number or a date greater than or equal to the given
   1588    * number or date `n` respectively. However, it's often best to assert that the target is equal to
   1589    * its expected value.
   1590    *
   1591    *     expect(2).to.equal(2); // Recommended
   1592    *     expect(2).to.be.at.least(1); // Not recommended
   1593    *     expect(2).to.be.at.least(2); // Not recommended
   1594    *
   1595    * Add `.lengthOf` earlier in the chain to assert that the target's `length`
   1596    * or `size` is greater than or equal to the given number `n`.
   1597    *
   1598    *     expect('foo').to.have.lengthOf(3); // Recommended
   1599    *     expect('foo').to.have.lengthOf.at.least(2); // Not recommended
   1600    *
   1601    *     expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
   1602    *     expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended
   1603    *
   1604    * Add `.not` earlier in the chain to negate `.least`.
   1605    *
   1606    *     expect(1).to.equal(1); // Recommended
   1607    *     expect(1).to.not.be.at.least(2); // Not recommended
   1608    *
   1609    * `.least` accepts an optional `msg` argument which is a custom error message
   1610    * to show when the assertion fails. The message can also be given as the
   1611    * second argument to `expect`.
   1612    *
   1613    *     expect(1).to.be.at.least(2, 'nooo why fail??');
   1614    *     expect(1, 'nooo why fail??').to.be.at.least(2);
   1615    *
   1616    * The aliases `.gte` and `.greaterThanOrEqual` can be used interchangeably with
   1617    * `.least`.
   1618    *
   1619    * @name least
   1620    * @alias gte
   1621    * @alias greaterThanOrEqual
   1622    * @param {Number} n
   1623    * @param {String} msg _optional_
   1624    * @namespace BDD
   1625    * @api public
   1626    */
   1627 
   1628   function assertLeast (n, msg) {
   1629     if (msg) flag(this, 'message', msg);
   1630     var obj = flag(this, 'object')
   1631       , doLength = flag(this, 'doLength')
   1632       , flagMsg = flag(this, 'message')
   1633       , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
   1634       , ssfi = flag(this, 'ssfi')
   1635       , objType = _.type(obj).toLowerCase()
   1636       , nType = _.type(n).toLowerCase()
   1637       , errorMessage
   1638       , shouldThrow = true;
   1639 
   1640     if (doLength && objType !== 'map' && objType !== 'set') {
   1641       new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
   1642     }
   1643 
   1644     if (!doLength && (objType === 'date' && nType !== 'date')) {
   1645       errorMessage = msgPrefix + 'the argument to least must be a date';
   1646     } else if (nType !== 'number' && (doLength || objType === 'number')) {
   1647       errorMessage = msgPrefix + 'the argument to least must be a number';
   1648     } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
   1649       var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
   1650       errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
   1651     } else {
   1652       shouldThrow = false;
   1653     }
   1654 
   1655     if (shouldThrow) {
   1656       throw new AssertionError(errorMessage, undefined, ssfi);
   1657     }
   1658 
   1659     if (doLength) {
   1660       var descriptor = 'length'
   1661         , itemsCount;
   1662       if (objType === 'map' || objType === 'set') {
   1663         descriptor = 'size';
   1664         itemsCount = obj.size;
   1665       } else {
   1666         itemsCount = obj.length;
   1667       }
   1668       this.assert(
   1669           itemsCount >= n
   1670         , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}'
   1671         , 'expected #{this} to have a ' + descriptor + ' below #{exp}'
   1672         , n
   1673         , itemsCount
   1674       );
   1675     } else {
   1676       this.assert(
   1677           obj >= n
   1678         , 'expected #{this} to be at least #{exp}'
   1679         , 'expected #{this} to be below #{exp}'
   1680         , n
   1681       );
   1682     }
   1683   }
   1684 
   1685   Assertion.addMethod('least', assertLeast);
   1686   Assertion.addMethod('gte', assertLeast);
   1687   Assertion.addMethod('greaterThanOrEqual', assertLeast);
   1688 
   1689   /**
   1690    * ### .below(n[, msg])
   1691    *
   1692    * Asserts that the target is a number or a date less than the given number or date `n` respectively.
   1693    * However, it's often best to assert that the target is equal to its expected
   1694    * value.
   1695    *
   1696    *     expect(1).to.equal(1); // Recommended
   1697    *     expect(1).to.be.below(2); // Not recommended
   1698    *
   1699    * Add `.lengthOf` earlier in the chain to assert that the target's `length`
   1700    * or `size` is less than the given number `n`.
   1701    *
   1702    *     expect('foo').to.have.lengthOf(3); // Recommended
   1703    *     expect('foo').to.have.lengthOf.below(4); // Not recommended
   1704    *
   1705    *     expect([1, 2, 3]).to.have.length(3); // Recommended
   1706    *     expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended
   1707    *
   1708    * Add `.not` earlier in the chain to negate `.below`.
   1709    *
   1710    *     expect(2).to.equal(2); // Recommended
   1711    *     expect(2).to.not.be.below(1); // Not recommended
   1712    *
   1713    * `.below` accepts an optional `msg` argument which is a custom error message
   1714    * to show when the assertion fails. The message can also be given as the
   1715    * second argument to `expect`.
   1716    *
   1717    *     expect(2).to.be.below(1, 'nooo why fail??');
   1718    *     expect(2, 'nooo why fail??').to.be.below(1);
   1719    *
   1720    * The aliases `.lt` and `.lessThan` can be used interchangeably with
   1721    * `.below`.
   1722    *
   1723    * @name below
   1724    * @alias lt
   1725    * @alias lessThan
   1726    * @param {Number} n
   1727    * @param {String} msg _optional_
   1728    * @namespace BDD
   1729    * @api public
   1730    */
   1731 
   1732   function assertBelow (n, msg) {
   1733     if (msg) flag(this, 'message', msg);
   1734     var obj = flag(this, 'object')
   1735       , doLength = flag(this, 'doLength')
   1736       , flagMsg = flag(this, 'message')
   1737       , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
   1738       , ssfi = flag(this, 'ssfi')
   1739       , objType = _.type(obj).toLowerCase()
   1740       , nType = _.type(n).toLowerCase()
   1741       , errorMessage
   1742       , shouldThrow = true;
   1743 
   1744     if (doLength && objType !== 'map' && objType !== 'set') {
   1745       new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
   1746     }
   1747 
   1748     if (!doLength && (objType === 'date' && nType !== 'date')) {
   1749       errorMessage = msgPrefix + 'the argument to below must be a date';
   1750     } else if (nType !== 'number' && (doLength || objType === 'number')) {
   1751       errorMessage = msgPrefix + 'the argument to below must be a number';
   1752     } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
   1753       var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
   1754       errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
   1755     } else {
   1756       shouldThrow = false;
   1757     }
   1758 
   1759     if (shouldThrow) {
   1760       throw new AssertionError(errorMessage, undefined, ssfi);
   1761     }
   1762 
   1763     if (doLength) {
   1764       var descriptor = 'length'
   1765         , itemsCount;
   1766       if (objType === 'map' || objType === 'set') {
   1767         descriptor = 'size';
   1768         itemsCount = obj.size;
   1769       } else {
   1770         itemsCount = obj.length;
   1771       }
   1772       this.assert(
   1773           itemsCount < n
   1774         , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}'
   1775         , 'expected #{this} to not have a ' + descriptor + ' below #{exp}'
   1776         , n
   1777         , itemsCount
   1778       );
   1779     } else {
   1780       this.assert(
   1781           obj < n
   1782         , 'expected #{this} to be below #{exp}'
   1783         , 'expected #{this} to be at least #{exp}'
   1784         , n
   1785       );
   1786     }
   1787   }
   1788 
   1789   Assertion.addMethod('below', assertBelow);
   1790   Assertion.addMethod('lt', assertBelow);
   1791   Assertion.addMethod('lessThan', assertBelow);
   1792 
   1793   /**
   1794    * ### .most(n[, msg])
   1795    *
   1796    * Asserts that the target is a number or a date less than or equal to the given number
   1797    * or date `n` respectively. However, it's often best to assert that the target is equal to its
   1798    * expected value.
   1799    *
   1800    *     expect(1).to.equal(1); // Recommended
   1801    *     expect(1).to.be.at.most(2); // Not recommended
   1802    *     expect(1).to.be.at.most(1); // Not recommended
   1803    *
   1804    * Add `.lengthOf` earlier in the chain to assert that the target's `length`
   1805    * or `size` is less than or equal to the given number `n`.
   1806    *
   1807    *     expect('foo').to.have.lengthOf(3); // Recommended
   1808    *     expect('foo').to.have.lengthOf.at.most(4); // Not recommended
   1809    *
   1810    *     expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
   1811    *     expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended
   1812    *
   1813    * Add `.not` earlier in the chain to negate `.most`.
   1814    *
   1815    *     expect(2).to.equal(2); // Recommended
   1816    *     expect(2).to.not.be.at.most(1); // Not recommended
   1817    *
   1818    * `.most` accepts an optional `msg` argument which is a custom error message
   1819    * to show when the assertion fails. The message can also be given as the
   1820    * second argument to `expect`.
   1821    *
   1822    *     expect(2).to.be.at.most(1, 'nooo why fail??');
   1823    *     expect(2, 'nooo why fail??').to.be.at.most(1);
   1824    *
   1825    * The aliases `.lte` and `.lessThanOrEqual` can be used interchangeably with
   1826    * `.most`.
   1827    *
   1828    * @name most
   1829    * @alias lte
   1830    * @alias lessThanOrEqual
   1831    * @param {Number} n
   1832    * @param {String} msg _optional_
   1833    * @namespace BDD
   1834    * @api public
   1835    */
   1836 
   1837   function assertMost (n, msg) {
   1838     if (msg) flag(this, 'message', msg);
   1839     var obj = flag(this, 'object')
   1840       , doLength = flag(this, 'doLength')
   1841       , flagMsg = flag(this, 'message')
   1842       , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
   1843       , ssfi = flag(this, 'ssfi')
   1844       , objType = _.type(obj).toLowerCase()
   1845       , nType = _.type(n).toLowerCase()
   1846       , errorMessage
   1847       , shouldThrow = true;
   1848 
   1849     if (doLength && objType !== 'map' && objType !== 'set') {
   1850       new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
   1851     }
   1852 
   1853     if (!doLength && (objType === 'date' && nType !== 'date')) {
   1854       errorMessage = msgPrefix + 'the argument to most must be a date';
   1855     } else if (nType !== 'number' && (doLength || objType === 'number')) {
   1856       errorMessage = msgPrefix + 'the argument to most must be a number';
   1857     } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
   1858       var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
   1859       errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
   1860     } else {
   1861       shouldThrow = false;
   1862     }
   1863 
   1864     if (shouldThrow) {
   1865       throw new AssertionError(errorMessage, undefined, ssfi);
   1866     }
   1867 
   1868     if (doLength) {
   1869       var descriptor = 'length'
   1870         , itemsCount;
   1871       if (objType === 'map' || objType === 'set') {
   1872         descriptor = 'size';
   1873         itemsCount = obj.size;
   1874       } else {
   1875         itemsCount = obj.length;
   1876       }
   1877       this.assert(
   1878           itemsCount <= n
   1879         , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}'
   1880         , 'expected #{this} to have a ' + descriptor + ' above #{exp}'
   1881         , n
   1882         , itemsCount
   1883       );
   1884     } else {
   1885       this.assert(
   1886           obj <= n
   1887         , 'expected #{this} to be at most #{exp}'
   1888         , 'expected #{this} to be above #{exp}'
   1889         , n
   1890       );
   1891     }
   1892   }
   1893 
   1894   Assertion.addMethod('most', assertMost);
   1895   Assertion.addMethod('lte', assertMost);
   1896   Assertion.addMethod('lessThanOrEqual', assertMost);
   1897 
   1898   /**
   1899    * ### .within(start, finish[, msg])
   1900    *
   1901    * Asserts that the target is a number or a date greater than or equal to the given
   1902    * number or date `start`, and less than or equal to the given number or date `finish` respectively.
   1903    * However, it's often best to assert that the target is equal to its expected
   1904    * value.
   1905    *
   1906    *     expect(2).to.equal(2); // Recommended
   1907    *     expect(2).to.be.within(1, 3); // Not recommended
   1908    *     expect(2).to.be.within(2, 3); // Not recommended
   1909    *     expect(2).to.be.within(1, 2); // Not recommended
   1910    *
   1911    * Add `.lengthOf` earlier in the chain to assert that the target's `length`
   1912    * or `size` is greater than or equal to the given number `start`, and less
   1913    * than or equal to the given number `finish`.
   1914    *
   1915    *     expect('foo').to.have.lengthOf(3); // Recommended
   1916    *     expect('foo').to.have.lengthOf.within(2, 4); // Not recommended
   1917    *
   1918    *     expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
   1919    *     expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended
   1920    *
   1921    * Add `.not` earlier in the chain to negate `.within`.
   1922    *
   1923    *     expect(1).to.equal(1); // Recommended
   1924    *     expect(1).to.not.be.within(2, 4); // Not recommended
   1925    *
   1926    * `.within` accepts an optional `msg` argument which is a custom error
   1927    * message to show when the assertion fails. The message can also be given as
   1928    * the second argument to `expect`.
   1929    *
   1930    *     expect(4).to.be.within(1, 3, 'nooo why fail??');
   1931    *     expect(4, 'nooo why fail??').to.be.within(1, 3);
   1932    *
   1933    * @name within
   1934    * @param {Number} start lower bound inclusive
   1935    * @param {Number} finish upper bound inclusive
   1936    * @param {String} msg _optional_
   1937    * @namespace BDD
   1938    * @api public
   1939    */
   1940 
   1941   Assertion.addMethod('within', function (start, finish, msg) {
   1942     if (msg) flag(this, 'message', msg);
   1943     var obj = flag(this, 'object')
   1944       , doLength = flag(this, 'doLength')
   1945       , flagMsg = flag(this, 'message')
   1946       , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
   1947       , ssfi = flag(this, 'ssfi')
   1948       , objType = _.type(obj).toLowerCase()
   1949       , startType = _.type(start).toLowerCase()
   1950       , finishType = _.type(finish).toLowerCase()
   1951       , errorMessage
   1952       , shouldThrow = true
   1953       , range = (startType === 'date' && finishType === 'date')
   1954           ? start.toUTCString() + '..' + finish.toUTCString()
   1955           : start + '..' + finish;
   1956 
   1957     if (doLength && objType !== 'map' && objType !== 'set') {
   1958       new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
   1959     }
   1960 
   1961     if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) {
   1962       errorMessage = msgPrefix + 'the arguments to within must be dates';
   1963     } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) {
   1964       errorMessage = msgPrefix + 'the arguments to within must be numbers';
   1965     } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
   1966       var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
   1967       errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
   1968     } else {
   1969       shouldThrow = false;
   1970     }
   1971 
   1972     if (shouldThrow) {
   1973       throw new AssertionError(errorMessage, undefined, ssfi);
   1974     }
   1975 
   1976     if (doLength) {
   1977       var descriptor = 'length'
   1978         , itemsCount;
   1979       if (objType === 'map' || objType === 'set') {
   1980         descriptor = 'size';
   1981         itemsCount = obj.size;
   1982       } else {
   1983         itemsCount = obj.length;
   1984       }
   1985       this.assert(
   1986           itemsCount >= start && itemsCount <= finish
   1987         , 'expected #{this} to have a ' + descriptor + ' within ' + range
   1988         , 'expected #{this} to not have a ' + descriptor + ' within ' + range
   1989       );
   1990     } else {
   1991       this.assert(
   1992           obj >= start && obj <= finish
   1993         , 'expected #{this} to be within ' + range
   1994         , 'expected #{this} to not be within ' + range
   1995       );
   1996     }
   1997   });
   1998 
   1999   /**
   2000    * ### .instanceof(constructor[, msg])
   2001    *
   2002    * Asserts that the target is an instance of the given `constructor`.
   2003    *
   2004    *     function Cat () { }
   2005    *
   2006    *     expect(new Cat()).to.be.an.instanceof(Cat);
   2007    *     expect([1, 2]).to.be.an.instanceof(Array);
   2008    *
   2009    * Add `.not` earlier in the chain to negate `.instanceof`.
   2010    *
   2011    *     expect({a: 1}).to.not.be.an.instanceof(Array);
   2012    *
   2013    * `.instanceof` accepts an optional `msg` argument which is a custom error
   2014    * message to show when the assertion fails. The message can also be given as
   2015    * the second argument to `expect`.
   2016    *
   2017    *     expect(1).to.be.an.instanceof(Array, 'nooo why fail??');
   2018    *     expect(1, 'nooo why fail??').to.be.an.instanceof(Array);
   2019    *
   2020    * Due to limitations in ES5, `.instanceof` may not always work as expected
   2021    * when using a transpiler such as Babel or TypeScript. In particular, it may
   2022    * produce unexpected results when subclassing built-in object such as
   2023    * `Array`, `Error`, and `Map`. See your transpiler's docs for details:
   2024    *
   2025    * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes))
   2026    * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work))
   2027    *
   2028    * The alias `.instanceOf` can be used interchangeably with `.instanceof`.
   2029    *
   2030    * @name instanceof
   2031    * @param {Constructor} constructor
   2032    * @param {String} msg _optional_
   2033    * @alias instanceOf
   2034    * @namespace BDD
   2035    * @api public
   2036    */
   2037 
   2038   function assertInstanceOf (constructor, msg) {
   2039     if (msg) flag(this, 'message', msg);
   2040 
   2041     var target = flag(this, 'object')
   2042     var ssfi = flag(this, 'ssfi');
   2043     var flagMsg = flag(this, 'message');
   2044 
   2045     try {
   2046       var isInstanceOf = target instanceof constructor;
   2047     } catch (err) {
   2048       if (err instanceof TypeError) {
   2049         flagMsg = flagMsg ? flagMsg + ': ' : '';
   2050         throw new AssertionError(
   2051           flagMsg + 'The instanceof assertion needs a constructor but '
   2052             + _.type(constructor) + ' was given.',
   2053           undefined,
   2054           ssfi
   2055         );
   2056       }
   2057       throw err;
   2058     }
   2059 
   2060     var name = _.getName(constructor);
   2061     if (name === null) {
   2062       name = 'an unnamed constructor';
   2063     }
   2064 
   2065     this.assert(
   2066         isInstanceOf
   2067       , 'expected #{this} to be an instance of ' + name
   2068       , 'expected #{this} to not be an instance of ' + name
   2069     );
   2070   };
   2071 
   2072   Assertion.addMethod('instanceof', assertInstanceOf);
   2073   Assertion.addMethod('instanceOf', assertInstanceOf);
   2074 
   2075   /**
   2076    * ### .property(name[, val[, msg]])
   2077    *
   2078    * Asserts that the target has a property with the given key `name`.
   2079    *
   2080    *     expect({a: 1}).to.have.property('a');
   2081    *
   2082    * When `val` is provided, `.property` also asserts that the property's value
   2083    * is equal to the given `val`.
   2084    *
   2085    *     expect({a: 1}).to.have.property('a', 1);
   2086    *
   2087    * By default, strict (`===`) equality is used. Add `.deep` earlier in the
   2088    * chain to use deep equality instead. See the `deep-eql` project page for
   2089    * info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
   2090    *
   2091    *     // Target object deeply (but not strictly) has property `x: {a: 1}`
   2092    *     expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});
   2093    *     expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
   2094    *
   2095    * The target's enumerable and non-enumerable properties are always included
   2096    * in the search. By default, both own and inherited properties are included.
   2097    * Add `.own` earlier in the chain to exclude inherited properties from the
   2098    * search.
   2099    *
   2100    *     Object.prototype.b = 2;
   2101    *
   2102    *     expect({a: 1}).to.have.own.property('a');
   2103    *     expect({a: 1}).to.have.own.property('a', 1);
   2104    *     expect({a: 1}).to.have.property('b');
   2105    *     expect({a: 1}).to.not.have.own.property('b');
   2106    *
   2107    * `.deep` and `.own` can be combined.
   2108    *
   2109    *     expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1});
   2110    *
   2111    * Add `.nested` earlier in the chain to enable dot- and bracket-notation when
   2112    * referencing nested properties.
   2113    *
   2114    *     expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
   2115    *     expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y');
   2116    *
   2117    * If `.` or `[]` are part of an actual property name, they can be escaped by
   2118    * adding two backslashes before them.
   2119    *
   2120    *     expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
   2121    *
   2122    * `.deep` and `.nested` can be combined.
   2123    *
   2124    *     expect({a: {b: [{c: 3}]}})
   2125    *       .to.have.deep.nested.property('a.b[0]', {c: 3});
   2126    *
   2127    * `.own` and `.nested` cannot be combined.
   2128    *
   2129    * Add `.not` earlier in the chain to negate `.property`.
   2130    *
   2131    *     expect({a: 1}).to.not.have.property('b');
   2132    *
   2133    * However, it's dangerous to negate `.property` when providing `val`. The
   2134    * problem is that it creates uncertain expectations by asserting that the
   2135    * target either doesn't have a property with the given key `name`, or that it
   2136    * does have a property with the given key `name` but its value isn't equal to
   2137    * the given `val`. It's often best to identify the exact output that's
   2138    * expected, and then write an assertion that only accepts that exact output.
   2139    *
   2140    * When the target isn't expected to have a property with the given key
   2141    * `name`, it's often best to assert exactly that.
   2142    *
   2143    *     expect({b: 2}).to.not.have.property('a'); // Recommended
   2144    *     expect({b: 2}).to.not.have.property('a', 1); // Not recommended
   2145    *
   2146    * When the target is expected to have a property with the given key `name`,
   2147    * it's often best to assert that the property has its expected value, rather
   2148    * than asserting that it doesn't have one of many unexpected values.
   2149    *
   2150    *     expect({a: 3}).to.have.property('a', 3); // Recommended
   2151    *     expect({a: 3}).to.not.have.property('a', 1); // Not recommended
   2152    *
   2153    * `.property` changes the target of any assertions that follow in the chain
   2154    * to be the value of the property from the original target object.
   2155    *
   2156    *     expect({a: 1}).to.have.property('a').that.is.a('number');
   2157    *
   2158    * `.property` accepts an optional `msg` argument which is a custom error
   2159    * message to show when the assertion fails. The message can also be given as
   2160    * the second argument to `expect`. When not providing `val`, only use the
   2161    * second form.
   2162    *
   2163    *     // Recommended
   2164    *     expect({a: 1}).to.have.property('a', 2, 'nooo why fail??');
   2165    *     expect({a: 1}, 'nooo why fail??').to.have.property('a', 2);
   2166    *     expect({a: 1}, 'nooo why fail??').to.have.property('b');
   2167    *
   2168    *     // Not recommended
   2169    *     expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??');
   2170    *
   2171    * The above assertion isn't the same thing as not providing `val`. Instead,
   2172    * it's asserting that the target object has a `b` property that's equal to
   2173    * `undefined`.
   2174    *
   2175    * The assertions `.ownProperty` and `.haveOwnProperty` can be used
   2176    * interchangeably with `.own.property`.
   2177    *
   2178    * @name property
   2179    * @param {String} name
   2180    * @param {Mixed} val (optional)
   2181    * @param {String} msg _optional_
   2182    * @returns value of property for chaining
   2183    * @namespace BDD
   2184    * @api public
   2185    */
   2186 
   2187   function assertProperty (name, val, msg) {
   2188     if (msg) flag(this, 'message', msg);
   2189 
   2190     var isNested = flag(this, 'nested')
   2191       , isOwn = flag(this, 'own')
   2192       , flagMsg = flag(this, 'message')
   2193       , obj = flag(this, 'object')
   2194       , ssfi = flag(this, 'ssfi')
   2195       , nameType = typeof name;
   2196 
   2197     flagMsg = flagMsg ? flagMsg + ': ' : '';
   2198 
   2199     if (isNested) {
   2200       if (nameType !== 'string') {
   2201         throw new AssertionError(
   2202           flagMsg + 'the argument to property must be a string when using nested syntax',
   2203           undefined,
   2204           ssfi
   2205         );
   2206       }
   2207     } else {
   2208       if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') {
   2209         throw new AssertionError(
   2210           flagMsg + 'the argument to property must be a string, number, or symbol',
   2211           undefined,
   2212           ssfi
   2213         );
   2214       }
   2215     }
   2216 
   2217     if (isNested && isOwn) {
   2218       throw new AssertionError(
   2219         flagMsg + 'The "nested" and "own" flags cannot be combined.',
   2220         undefined,
   2221         ssfi
   2222       );
   2223     }
   2224 
   2225     if (obj === null || obj === undefined) {
   2226       throw new AssertionError(
   2227         flagMsg + 'Target cannot be null or undefined.',
   2228         undefined,
   2229         ssfi
   2230       );
   2231     }
   2232 
   2233     var isDeep = flag(this, 'deep')
   2234       , negate = flag(this, 'negate')
   2235       , pathInfo = isNested ? _.getPathInfo(obj, name) : null
   2236       , value = isNested ? pathInfo.value : obj[name];
   2237 
   2238     var descriptor = '';
   2239     if (isDeep) descriptor += 'deep ';
   2240     if (isOwn) descriptor += 'own ';
   2241     if (isNested) descriptor += 'nested ';
   2242     descriptor += 'property ';
   2243 
   2244     var hasProperty;
   2245     if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name);
   2246     else if (isNested) hasProperty = pathInfo.exists;
   2247     else hasProperty = _.hasProperty(obj, name);
   2248 
   2249     // When performing a negated assertion for both name and val, merely having
   2250     // a property with the given name isn't enough to cause the assertion to
   2251     // fail. It must both have a property with the given name, and the value of
   2252     // that property must equal the given val. Therefore, skip this assertion in
   2253     // favor of the next.
   2254     if (!negate || arguments.length === 1) {
   2255       this.assert(
   2256           hasProperty
   2257         , 'expected #{this} to have ' + descriptor + _.inspect(name)
   2258         , 'expected #{this} to not have ' + descriptor + _.inspect(name));
   2259     }
   2260 
   2261     if (arguments.length > 1) {
   2262       this.assert(
   2263           hasProperty && (isDeep ? _.eql(val, value) : val === value)
   2264         , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
   2265         , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}'
   2266         , val
   2267         , value
   2268       );
   2269     }
   2270 
   2271     flag(this, 'object', value);
   2272   }
   2273 
   2274   Assertion.addMethod('property', assertProperty);
   2275 
   2276   function assertOwnProperty (name, value, msg) {
   2277     flag(this, 'own', true);
   2278     assertProperty.apply(this, arguments);
   2279   }
   2280 
   2281   Assertion.addMethod('ownProperty', assertOwnProperty);
   2282   Assertion.addMethod('haveOwnProperty', assertOwnProperty);
   2283 
   2284   /**
   2285    * ### .ownPropertyDescriptor(name[, descriptor[, msg]])
   2286    *
   2287    * Asserts that the target has its own property descriptor with the given key
   2288    * `name`. Enumerable and non-enumerable properties are included in the
   2289    * search.
   2290    *
   2291    *     expect({a: 1}).to.have.ownPropertyDescriptor('a');
   2292    *
   2293    * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that
   2294    * the property's descriptor is deeply equal to the given `descriptor`. See
   2295    * the `deep-eql` project page for info on the deep equality algorithm:
   2296    * https://github.com/chaijs/deep-eql.
   2297    *
   2298    *     expect({a: 1}).to.have.ownPropertyDescriptor('a', {
   2299    *       configurable: true,
   2300    *       enumerable: true,
   2301    *       writable: true,
   2302    *       value: 1,
   2303    *     });
   2304    *
   2305    * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`.
   2306    *
   2307    *     expect({a: 1}).to.not.have.ownPropertyDescriptor('b');
   2308    *
   2309    * However, it's dangerous to negate `.ownPropertyDescriptor` when providing
   2310    * a `descriptor`. The problem is that it creates uncertain expectations by
   2311    * asserting that the target either doesn't have a property descriptor with
   2312    * the given key `name`, or that it does have a property descriptor with the
   2313    * given key `name` but it’s not deeply equal to the given `descriptor`. It's
   2314    * often best to identify the exact output that's expected, and then write an
   2315    * assertion that only accepts that exact output.
   2316    *
   2317    * When the target isn't expected to have a property descriptor with the given
   2318    * key `name`, it's often best to assert exactly that.
   2319    *
   2320    *     // Recommended
   2321    *     expect({b: 2}).to.not.have.ownPropertyDescriptor('a');
   2322    *
   2323    *     // Not recommended
   2324    *     expect({b: 2}).to.not.have.ownPropertyDescriptor('a', {
   2325    *       configurable: true,
   2326    *       enumerable: true,
   2327    *       writable: true,
   2328    *       value: 1,
   2329    *     });
   2330    *
   2331    * When the target is expected to have a property descriptor with the given
   2332    * key `name`, it's often best to assert that the property has its expected
   2333    * descriptor, rather than asserting that it doesn't have one of many
   2334    * unexpected descriptors.
   2335    *
   2336    *     // Recommended
   2337    *     expect({a: 3}).to.have.ownPropertyDescriptor('a', {
   2338    *       configurable: true,
   2339    *       enumerable: true,
   2340    *       writable: true,
   2341    *       value: 3,
   2342    *     });
   2343    *
   2344    *     // Not recommended
   2345    *     expect({a: 3}).to.not.have.ownPropertyDescriptor('a', {
   2346    *       configurable: true,
   2347    *       enumerable: true,
   2348    *       writable: true,
   2349    *       value: 1,
   2350    *     });
   2351    *
   2352    * `.ownPropertyDescriptor` changes the target of any assertions that follow
   2353    * in the chain to be the value of the property descriptor from the original
   2354    * target object.
   2355    *
   2356    *     expect({a: 1}).to.have.ownPropertyDescriptor('a')
   2357    *       .that.has.property('enumerable', true);
   2358    *
   2359    * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a
   2360    * custom error message to show when the assertion fails. The message can also
   2361    * be given as the second argument to `expect`. When not providing
   2362    * `descriptor`, only use the second form.
   2363    *
   2364    *     // Recommended
   2365    *     expect({a: 1}).to.have.ownPropertyDescriptor('a', {
   2366    *       configurable: true,
   2367    *       enumerable: true,
   2368    *       writable: true,
   2369    *       value: 2,
   2370    *     }, 'nooo why fail??');
   2371    *
   2372    *     // Recommended
   2373    *     expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', {
   2374    *       configurable: true,
   2375    *       enumerable: true,
   2376    *       writable: true,
   2377    *       value: 2,
   2378    *     });
   2379    *
   2380    *     // Recommended
   2381    *     expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b');
   2382    *
   2383    *     // Not recommended
   2384    *     expect({a: 1})
   2385    *       .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??');
   2386    *
   2387    * The above assertion isn't the same thing as not providing `descriptor`.
   2388    * Instead, it's asserting that the target object has a `b` property
   2389    * descriptor that's deeply equal to `undefined`.
   2390    *
   2391    * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with
   2392    * `.ownPropertyDescriptor`.
   2393    *
   2394    * @name ownPropertyDescriptor
   2395    * @alias haveOwnPropertyDescriptor
   2396    * @param {String} name
   2397    * @param {Object} descriptor _optional_
   2398    * @param {String} msg _optional_
   2399    * @namespace BDD
   2400    * @api public
   2401    */
   2402 
   2403   function assertOwnPropertyDescriptor (name, descriptor, msg) {
   2404     if (typeof descriptor === 'string') {
   2405       msg = descriptor;
   2406       descriptor = null;
   2407     }
   2408     if (msg) flag(this, 'message', msg);
   2409     var obj = flag(this, 'object');
   2410     var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);
   2411     if (actualDescriptor && descriptor) {
   2412       this.assert(
   2413           _.eql(descriptor, actualDescriptor)
   2414         , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)
   2415         , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)
   2416         , descriptor
   2417         , actualDescriptor
   2418         , true
   2419       );
   2420     } else {
   2421       this.assert(
   2422           actualDescriptor
   2423         , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)
   2424         , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)
   2425       );
   2426     }
   2427     flag(this, 'object', actualDescriptor);
   2428   }
   2429 
   2430   Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);
   2431   Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);
   2432 
   2433   /**
   2434    * ### .lengthOf(n[, msg])
   2435    *
   2436    * Asserts that the target's `length` or `size` is equal to the given number
   2437    * `n`.
   2438    *
   2439    *     expect([1, 2, 3]).to.have.lengthOf(3);
   2440    *     expect('foo').to.have.lengthOf(3);
   2441    *     expect(new Set([1, 2, 3])).to.have.lengthOf(3);
   2442    *     expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3);
   2443    *
   2444    * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often
   2445    * best to assert that the target's `length` property is equal to its expected
   2446    * value, rather than not equal to one of many unexpected values.
   2447    *
   2448    *     expect('foo').to.have.lengthOf(3); // Recommended
   2449    *     expect('foo').to.not.have.lengthOf(4); // Not recommended
   2450    *
   2451    * `.lengthOf` accepts an optional `msg` argument which is a custom error
   2452    * message to show when the assertion fails. The message can also be given as
   2453    * the second argument to `expect`.
   2454    *
   2455    *     expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??');
   2456    *     expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2);
   2457    *
   2458    * `.lengthOf` can also be used as a language chain, causing all `.above`,
   2459    * `.below`, `.least`, `.most`, and `.within` assertions that follow in the
   2460    * chain to use the target's `length` property as the target. However, it's
   2461    * often best to assert that the target's `length` property is equal to its
   2462    * expected length, rather than asserting that its `length` property falls
   2463    * within some range of values.
   2464    *
   2465    *     // Recommended
   2466    *     expect([1, 2, 3]).to.have.lengthOf(3);
   2467    *
   2468    *     // Not recommended
   2469    *     expect([1, 2, 3]).to.have.lengthOf.above(2);
   2470    *     expect([1, 2, 3]).to.have.lengthOf.below(4);
   2471    *     expect([1, 2, 3]).to.have.lengthOf.at.least(3);
   2472    *     expect([1, 2, 3]).to.have.lengthOf.at.most(3);
   2473    *     expect([1, 2, 3]).to.have.lengthOf.within(2,4);
   2474    *
   2475    * Due to a compatibility issue, the alias `.length` can't be chained directly
   2476    * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used
   2477    * interchangeably with `.lengthOf` in every situation. It's recommended to
   2478    * always use `.lengthOf` instead of `.length`.
   2479    *
   2480    *     expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error
   2481    *     expect([1, 2, 3]).to.have.a.lengthOf(3);  // passes as expected
   2482    *
   2483    * @name lengthOf
   2484    * @alias length
   2485    * @param {Number} n
   2486    * @param {String} msg _optional_
   2487    * @namespace BDD
   2488    * @api public
   2489    */
   2490 
   2491   function assertLengthChain () {
   2492     flag(this, 'doLength', true);
   2493   }
   2494 
   2495   function assertLength (n, msg) {
   2496     if (msg) flag(this, 'message', msg);
   2497     var obj = flag(this, 'object')
   2498       , objType = _.type(obj).toLowerCase()
   2499       , flagMsg = flag(this, 'message')
   2500       , ssfi = flag(this, 'ssfi')
   2501       , descriptor = 'length'
   2502       , itemsCount;
   2503 
   2504     switch (objType) {
   2505       case 'map':
   2506       case 'set':
   2507         descriptor = 'size';
   2508         itemsCount = obj.size;
   2509         break;
   2510       default:
   2511         new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
   2512         itemsCount = obj.length;
   2513     }
   2514 
   2515     this.assert(
   2516         itemsCount == n
   2517       , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}'
   2518       , 'expected #{this} to not have a ' + descriptor + ' of #{act}'
   2519       , n
   2520       , itemsCount
   2521     );
   2522   }
   2523 
   2524   Assertion.addChainableMethod('length', assertLength, assertLengthChain);
   2525   Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain);
   2526 
   2527   /**
   2528    * ### .match(re[, msg])
   2529    *
   2530    * Asserts that the target matches the given regular expression `re`.
   2531    *
   2532    *     expect('foobar').to.match(/^foo/);
   2533    *
   2534    * Add `.not` earlier in the chain to negate `.match`.
   2535    *
   2536    *     expect('foobar').to.not.match(/taco/);
   2537    *
   2538    * `.match` accepts an optional `msg` argument which is a custom error message
   2539    * to show when the assertion fails. The message can also be given as the
   2540    * second argument to `expect`.
   2541    *
   2542    *     expect('foobar').to.match(/taco/, 'nooo why fail??');
   2543    *     expect('foobar', 'nooo why fail??').to.match(/taco/);
   2544    *
   2545    * The alias `.matches` can be used interchangeably with `.match`.
   2546    *
   2547    * @name match
   2548    * @alias matches
   2549    * @param {RegExp} re
   2550    * @param {String} msg _optional_
   2551    * @namespace BDD
   2552    * @api public
   2553    */
   2554   function assertMatch(re, msg) {
   2555     if (msg) flag(this, 'message', msg);
   2556     var obj = flag(this, 'object');
   2557     this.assert(
   2558         re.exec(obj)
   2559       , 'expected #{this} to match ' + re
   2560       , 'expected #{this} not to match ' + re
   2561     );
   2562   }
   2563 
   2564   Assertion.addMethod('match', assertMatch);
   2565   Assertion.addMethod('matches', assertMatch);
   2566 
   2567   /**
   2568    * ### .string(str[, msg])
   2569    *
   2570    * Asserts that the target string contains the given substring `str`.
   2571    *
   2572    *     expect('foobar').to.have.string('bar');
   2573    *
   2574    * Add `.not` earlier in the chain to negate `.string`.
   2575    *
   2576    *     expect('foobar').to.not.have.string('taco');
   2577    *
   2578    * `.string` accepts an optional `msg` argument which is a custom error
   2579    * message to show when the assertion fails. The message can also be given as
   2580    * the second argument to `expect`.
   2581    *
   2582    *     expect('foobar').to.have.string('taco', 'nooo why fail??');
   2583    *     expect('foobar', 'nooo why fail??').to.have.string('taco');
   2584    *
   2585    * @name string
   2586    * @param {String} str
   2587    * @param {String} msg _optional_
   2588    * @namespace BDD
   2589    * @api public
   2590    */
   2591 
   2592   Assertion.addMethod('string', function (str, msg) {
   2593     if (msg) flag(this, 'message', msg);
   2594     var obj = flag(this, 'object')
   2595       , flagMsg = flag(this, 'message')
   2596       , ssfi = flag(this, 'ssfi');
   2597     new Assertion(obj, flagMsg, ssfi, true).is.a('string');
   2598 
   2599     this.assert(
   2600         ~obj.indexOf(str)
   2601       , 'expected #{this} to contain ' + _.inspect(str)
   2602       , 'expected #{this} to not contain ' + _.inspect(str)
   2603     );
   2604   });
   2605 
   2606   /**
   2607    * ### .keys(key1[, key2[, ...]])
   2608    *
   2609    * Asserts that the target object, array, map, or set has the given keys. Only
   2610    * the target's own inherited properties are included in the search.
   2611    *
   2612    * When the target is an object or array, keys can be provided as one or more
   2613    * string arguments, a single array argument, or a single object argument. In
   2614    * the latter case, only the keys in the given object matter; the values are
   2615    * ignored.
   2616    *
   2617    *     expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
   2618    *     expect(['x', 'y']).to.have.all.keys(0, 1);
   2619    *
   2620    *     expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']);
   2621    *     expect(['x', 'y']).to.have.all.keys([0, 1]);
   2622    *
   2623    *     expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5
   2624    *     expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5
   2625    *
   2626    * When the target is a map or set, each key must be provided as a separate
   2627    * argument.
   2628    *
   2629    *     expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b');
   2630    *     expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b');
   2631    *
   2632    * Because `.keys` does different things based on the target's type, it's
   2633    * important to check the target's type before using `.keys`. See the `.a` doc
   2634    * for info on testing a target's type.
   2635    *
   2636    *     expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b');
   2637    *
   2638    * By default, strict (`===`) equality is used to compare keys of maps and
   2639    * sets. Add `.deep` earlier in the chain to use deep equality instead. See
   2640    * the `deep-eql` project page for info on the deep equality algorithm:
   2641    * https://github.com/chaijs/deep-eql.
   2642    *
   2643    *     // Target set deeply (but not strictly) has key `{a: 1}`
   2644    *     expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]);
   2645    *     expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]);
   2646    *
   2647    * By default, the target must have all of the given keys and no more. Add
   2648    * `.any` earlier in the chain to only require that the target have at least
   2649    * one of the given keys. Also, add `.not` earlier in the chain to negate
   2650    * `.keys`. It's often best to add `.any` when negating `.keys`, and to use
   2651    * `.all` when asserting `.keys` without negation.
   2652    *
   2653    * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts
   2654    * exactly what's expected of the output, whereas `.not.all.keys` creates
   2655    * uncertain expectations.
   2656    *
   2657    *     // Recommended; asserts that target doesn't have any of the given keys
   2658    *     expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
   2659    *
   2660    *     // Not recommended; asserts that target doesn't have all of the given
   2661    *     // keys but may or may not have some of them
   2662    *     expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd');
   2663    *
   2664    * When asserting `.keys` without negation, `.all` is preferred because
   2665    * `.all.keys` asserts exactly what's expected of the output, whereas
   2666    * `.any.keys` creates uncertain expectations.
   2667    *
   2668    *     // Recommended; asserts that target has all the given keys
   2669    *     expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
   2670    *
   2671    *     // Not recommended; asserts that target has at least one of the given
   2672    *     // keys but may or may not have more of them
   2673    *     expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
   2674    *
   2675    * Note that `.all` is used by default when neither `.all` nor `.any` appear
   2676    * earlier in the chain. However, it's often best to add `.all` anyway because
   2677    * it improves readability.
   2678    *
   2679    *     // Both assertions are identical
   2680    *     expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended
   2681    *     expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended
   2682    *
   2683    * Add `.include` earlier in the chain to require that the target's keys be a
   2684    * superset of the expected keys, rather than identical sets.
   2685    *
   2686    *     // Target object's keys are a superset of ['a', 'b'] but not identical
   2687    *     expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');
   2688    *     expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');
   2689    *
   2690    * However, if `.any` and `.include` are combined, only the `.any` takes
   2691    * effect. The `.include` is ignored in this case.
   2692    *
   2693    *     // Both assertions are identical
   2694    *     expect({a: 1}).to.have.any.keys('a', 'b');
   2695    *     expect({a: 1}).to.include.any.keys('a', 'b');
   2696    *
   2697    * A custom error message can be given as the second argument to `expect`.
   2698    *
   2699    *     expect({a: 1}, 'nooo why fail??').to.have.key('b');
   2700    *
   2701    * The alias `.key` can be used interchangeably with `.keys`.
   2702    *
   2703    * @name keys
   2704    * @alias key
   2705    * @param {...String|Array|Object} keys
   2706    * @namespace BDD
   2707    * @api public
   2708    */
   2709 
   2710   function assertKeys (keys) {
   2711     var obj = flag(this, 'object')
   2712       , objType = _.type(obj)
   2713       , keysType = _.type(keys)
   2714       , ssfi = flag(this, 'ssfi')
   2715       , isDeep = flag(this, 'deep')
   2716       , str
   2717       , deepStr = ''
   2718       , actual
   2719       , ok = true
   2720       , flagMsg = flag(this, 'message');
   2721 
   2722     flagMsg = flagMsg ? flagMsg + ': ' : '';
   2723     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';
   2724 
   2725     if (objType === 'Map' || objType === 'Set') {
   2726       deepStr = isDeep ? 'deeply ' : '';
   2727       actual = [];
   2728 
   2729       // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach.
   2730       obj.forEach(function (val, key) { actual.push(key) });
   2731 
   2732       if (keysType !== 'Array') {
   2733         keys = Array.prototype.slice.call(arguments);
   2734       }
   2735     } else {
   2736       actual = _.getOwnEnumerableProperties(obj);
   2737 
   2738       switch (keysType) {
   2739         case 'Array':
   2740           if (arguments.length > 1) {
   2741             throw new AssertionError(mixedArgsMsg, undefined, ssfi);
   2742           }
   2743           break;
   2744         case 'Object':
   2745           if (arguments.length > 1) {
   2746             throw new AssertionError(mixedArgsMsg, undefined, ssfi);
   2747           }
   2748           keys = Object.keys(keys);
   2749           break;
   2750         default:
   2751           keys = Array.prototype.slice.call(arguments);
   2752       }
   2753 
   2754       // Only stringify non-Symbols because Symbols would become "Symbol()"
   2755       keys = keys.map(function (val) {
   2756         return typeof val === 'symbol' ? val : String(val);
   2757       });
   2758     }
   2759 
   2760     if (!keys.length) {
   2761       throw new AssertionError(flagMsg + 'keys required', undefined, ssfi);
   2762     }
   2763 
   2764     var len = keys.length
   2765       , any = flag(this, 'any')
   2766       , all = flag(this, 'all')
   2767       , expected = keys;
   2768 
   2769     if (!any && !all) {
   2770       all = true;
   2771     }
   2772 
   2773     // Has any
   2774     if (any) {
   2775       ok = expected.some(function(expectedKey) {
   2776         return actual.some(function(actualKey) {
   2777           if (isDeep) {
   2778             return _.eql(expectedKey, actualKey);
   2779           } else {
   2780             return expectedKey === actualKey;
   2781           }
   2782         });
   2783       });
   2784     }
   2785 
   2786     // Has all
   2787     if (all) {
   2788       ok = expected.every(function(expectedKey) {
   2789         return actual.some(function(actualKey) {
   2790           if (isDeep) {
   2791             return _.eql(expectedKey, actualKey);
   2792           } else {
   2793             return expectedKey === actualKey;
   2794           }
   2795         });
   2796       });
   2797 
   2798       if (!flag(this, 'contains')) {
   2799         ok = ok && keys.length == actual.length;
   2800       }
   2801     }
   2802 
   2803     // Key string
   2804     if (len > 1) {
   2805       keys = keys.map(function(key) {
   2806         return _.inspect(key);
   2807       });
   2808       var last = keys.pop();
   2809       if (all) {
   2810         str = keys.join(', ') + ', and ' + last;
   2811       }
   2812       if (any) {
   2813         str = keys.join(', ') + ', or ' + last;
   2814       }
   2815     } else {
   2816       str = _.inspect(keys[0]);
   2817     }
   2818 
   2819     // Form
   2820     str = (len > 1 ? 'keys ' : 'key ') + str;
   2821 
   2822     // Have / include
   2823     str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
   2824 
   2825     // Assertion
   2826     this.assert(
   2827         ok
   2828       , 'expected #{this} to ' + deepStr + str
   2829       , 'expected #{this} to not ' + deepStr + str
   2830       , expected.slice(0).sort(_.compareByInspect)
   2831       , actual.sort(_.compareByInspect)
   2832       , true
   2833     );
   2834   }
   2835 
   2836   Assertion.addMethod('keys', assertKeys);
   2837   Assertion.addMethod('key', assertKeys);
   2838 
   2839   /**
   2840    * ### .throw([errorLike], [errMsgMatcher], [msg])
   2841    *
   2842    * When no arguments are provided, `.throw` invokes the target function and
   2843    * asserts that an error is thrown.
   2844    *
   2845    *     var badFn = function () { throw new TypeError('Illegal salmon!'); };
   2846    *
   2847    *     expect(badFn).to.throw();
   2848    *
   2849    * When one argument is provided, and it's an error constructor, `.throw`
   2850    * invokes the target function and asserts that an error is thrown that's an
   2851    * instance of that error constructor.
   2852    *
   2853    *     var badFn = function () { throw new TypeError('Illegal salmon!'); };
   2854    *
   2855    *     expect(badFn).to.throw(TypeError);
   2856    *
   2857    * When one argument is provided, and it's an error instance, `.throw` invokes
   2858    * the target function and asserts that an error is thrown that's strictly
   2859    * (`===`) equal to that error instance.
   2860    *
   2861    *     var err = new TypeError('Illegal salmon!');
   2862    *     var badFn = function () { throw err; };
   2863    *
   2864    *     expect(badFn).to.throw(err);
   2865    *
   2866    * When one argument is provided, and it's a string, `.throw` invokes the
   2867    * target function and asserts that an error is thrown with a message that
   2868    * contains that string.
   2869    *
   2870    *     var badFn = function () { throw new TypeError('Illegal salmon!'); };
   2871    *
   2872    *     expect(badFn).to.throw('salmon');
   2873    *
   2874    * When one argument is provided, and it's a regular expression, `.throw`
   2875    * invokes the target function and asserts that an error is thrown with a
   2876    * message that matches that regular expression.
   2877    *
   2878    *     var badFn = function () { throw new TypeError('Illegal salmon!'); };
   2879    *
   2880    *     expect(badFn).to.throw(/salmon/);
   2881    *
   2882    * When two arguments are provided, and the first is an error instance or
   2883    * constructor, and the second is a string or regular expression, `.throw`
   2884    * invokes the function and asserts that an error is thrown that fulfills both
   2885    * conditions as described above.
   2886    *
   2887    *     var err = new TypeError('Illegal salmon!');
   2888    *     var badFn = function () { throw err; };
   2889    *
   2890    *     expect(badFn).to.throw(TypeError, 'salmon');
   2891    *     expect(badFn).to.throw(TypeError, /salmon/);
   2892    *     expect(badFn).to.throw(err, 'salmon');
   2893    *     expect(badFn).to.throw(err, /salmon/);
   2894    *
   2895    * Add `.not` earlier in the chain to negate `.throw`.
   2896    *
   2897    *     var goodFn = function () {};
   2898    *
   2899    *     expect(goodFn).to.not.throw();
   2900    *
   2901    * However, it's dangerous to negate `.throw` when providing any arguments.
   2902    * The problem is that it creates uncertain expectations by asserting that the
   2903    * target either doesn't throw an error, or that it throws an error but of a
   2904    * different type than the given type, or that it throws an error of the given
   2905    * type but with a message that doesn't include the given string. It's often
   2906    * best to identify the exact output that's expected, and then write an
   2907    * assertion that only accepts that exact output.
   2908    *
   2909    * When the target isn't expected to throw an error, it's often best to assert
   2910    * exactly that.
   2911    *
   2912    *     var goodFn = function () {};
   2913    *
   2914    *     expect(goodFn).to.not.throw(); // Recommended
   2915    *     expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended
   2916    *
   2917    * When the target is expected to throw an error, it's often best to assert
   2918    * that the error is of its expected type, and has a message that includes an
   2919    * expected string, rather than asserting that it doesn't have one of many
   2920    * unexpected types, and doesn't have a message that includes some string.
   2921    *
   2922    *     var badFn = function () { throw new TypeError('Illegal salmon!'); };
   2923    *
   2924    *     expect(badFn).to.throw(TypeError, 'salmon'); // Recommended
   2925    *     expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended
   2926    *
   2927    * `.throw` changes the target of any assertions that follow in the chain to
   2928    * be the error object that's thrown.
   2929    *
   2930    *     var err = new TypeError('Illegal salmon!');
   2931    *     err.code = 42;
   2932    *     var badFn = function () { throw err; };
   2933    *
   2934    *     expect(badFn).to.throw(TypeError).with.property('code', 42);
   2935    *
   2936    * `.throw` accepts an optional `msg` argument which is a custom error message
   2937    * to show when the assertion fails. The message can also be given as the
   2938    * second argument to `expect`. When not providing two arguments, always use
   2939    * the second form.
   2940    *
   2941    *     var goodFn = function () {};
   2942    *
   2943    *     expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??');
   2944    *     expect(goodFn, 'nooo why fail??').to.throw();
   2945    *
   2946    * Due to limitations in ES5, `.throw` may not always work as expected when
   2947    * using a transpiler such as Babel or TypeScript. In particular, it may
   2948    * produce unexpected results when subclassing the built-in `Error` object and
   2949    * then passing the subclassed constructor to `.throw`. See your transpiler's
   2950    * docs for details:
   2951    *
   2952    * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes))
   2953    * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work))
   2954    *
   2955    * Beware of some common mistakes when using the `throw` assertion. One common
   2956    * mistake is to accidentally invoke the function yourself instead of letting
   2957    * the `throw` assertion invoke the function for you. For example, when
   2958    * testing if a function named `fn` throws, provide `fn` instead of `fn()` as
   2959    * the target for the assertion.
   2960    *
   2961    *     expect(fn).to.throw();     // Good! Tests `fn` as desired
   2962    *     expect(fn()).to.throw();   // Bad! Tests result of `fn()`, not `fn`
   2963    *
   2964    * If you need to assert that your function `fn` throws when passed certain
   2965    * arguments, then wrap a call to `fn` inside of another function.
   2966    *
   2967    *     expect(function () { fn(42); }).to.throw();  // Function expression
   2968    *     expect(() => fn(42)).to.throw();             // ES6 arrow function
   2969    *
   2970    * Another common mistake is to provide an object method (or any stand-alone
   2971    * function that relies on `this`) as the target of the assertion. Doing so is
   2972    * problematic because the `this` context will be lost when the function is
   2973    * invoked by `.throw`; there's no way for it to know what `this` is supposed
   2974    * to be. There are two ways around this problem. One solution is to wrap the
   2975    * method or function call inside of another function. Another solution is to
   2976    * use `bind`.
   2977    *
   2978    *     expect(function () { cat.meow(); }).to.throw();  // Function expression
   2979    *     expect(() => cat.meow()).to.throw();             // ES6 arrow function
   2980    *     expect(cat.meow.bind(cat)).to.throw();           // Bind
   2981    *
   2982    * Finally, it's worth mentioning that it's a best practice in JavaScript to
   2983    * only throw `Error` and derivatives of `Error` such as `ReferenceError`,
   2984    * `TypeError`, and user-defined objects that extend `Error`. No other type of
   2985    * value will generate a stack trace when initialized. With that said, the
   2986    * `throw` assertion does technically support any type of value being thrown,
   2987    * not just `Error` and its derivatives.
   2988    *
   2989    * The aliases `.throws` and `.Throw` can be used interchangeably with
   2990    * `.throw`.
   2991    *
   2992    * @name throw
   2993    * @alias throws
   2994    * @alias Throw
   2995    * @param {Error|ErrorConstructor} errorLike
   2996    * @param {String|RegExp} errMsgMatcher error message
   2997    * @param {String} msg _optional_
   2998    * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
   2999    * @returns error for chaining (null if no error)
   3000    * @namespace BDD
   3001    * @api public
   3002    */
   3003 
   3004   function assertThrows (errorLike, errMsgMatcher, msg) {
   3005     if (msg) flag(this, 'message', msg);
   3006     var obj = flag(this, 'object')
   3007       , ssfi = flag(this, 'ssfi')
   3008       , flagMsg = flag(this, 'message')
   3009       , negate = flag(this, 'negate') || false;
   3010     new Assertion(obj, flagMsg, ssfi, true).is.a('function');
   3011 
   3012     if (errorLike instanceof RegExp || typeof errorLike === 'string') {
   3013       errMsgMatcher = errorLike;
   3014       errorLike = null;
   3015     }
   3016 
   3017     var caughtErr;
   3018     try {
   3019       obj();
   3020     } catch (err) {
   3021       caughtErr = err;
   3022     }
   3023 
   3024     // If we have the negate flag enabled and at least one valid argument it means we do expect an error
   3025     // but we want it to match a given set of criteria
   3026     var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined;
   3027 
   3028     // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible
   3029     // See Issue #551 and PR #683@GitHub
   3030     var everyArgIsDefined = Boolean(errorLike && errMsgMatcher);
   3031     var errorLikeFail = false;
   3032     var errMsgMatcherFail = false;
   3033 
   3034     // Checking if error was thrown
   3035     if (everyArgIsUndefined || !everyArgIsUndefined && !negate) {
   3036       // We need this to display results correctly according to their types
   3037       var errorLikeString = 'an error';
   3038       if (errorLike instanceof Error) {
   3039         errorLikeString = '#{exp}';
   3040       } else if (errorLike) {
   3041         errorLikeString = _.checkError.getConstructorName(errorLike);
   3042       }
   3043 
   3044       this.assert(
   3045           caughtErr
   3046         , 'expected #{this} to throw ' + errorLikeString
   3047         , 'expected #{this} to not throw an error but #{act} was thrown'
   3048         , errorLike && errorLike.toString()
   3049         , (caughtErr instanceof Error ?
   3050             caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr &&
   3051                                     _.checkError.getConstructorName(caughtErr)))
   3052       );
   3053     }
   3054 
   3055     if (errorLike && caughtErr) {
   3056       // We should compare instances only if `errorLike` is an instance of `Error`
   3057       if (errorLike instanceof Error) {
   3058         var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike);
   3059 
   3060         if (isCompatibleInstance === negate) {
   3061           // These checks were created to ensure we won't fail too soon when we've got both args and a negate
   3062           // See Issue #551 and PR #683@GitHub
   3063           if (everyArgIsDefined && negate) {
   3064             errorLikeFail = true;
   3065           } else {
   3066             this.assert(
   3067                 negate
   3068               , 'expected #{this} to throw #{exp} but #{act} was thrown'
   3069               , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '')
   3070               , errorLike.toString()
   3071               , caughtErr.toString()
   3072             );
   3073           }
   3074         }
   3075       }
   3076 
   3077       var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike);
   3078       if (isCompatibleConstructor === negate) {
   3079         if (everyArgIsDefined && negate) {
   3080             errorLikeFail = true;
   3081         } else {
   3082           this.assert(
   3083               negate
   3084             , 'expected #{this} to throw #{exp} but #{act} was thrown'
   3085             , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '')
   3086             , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike))
   3087             , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr))
   3088           );
   3089         }
   3090       }
   3091     }
   3092 
   3093     if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) {
   3094       // Here we check compatible messages
   3095       var placeholder = 'including';
   3096       if (errMsgMatcher instanceof RegExp) {
   3097         placeholder = 'matching'
   3098       }
   3099 
   3100       var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher);
   3101       if (isCompatibleMessage === negate) {
   3102         if (everyArgIsDefined && negate) {
   3103             errMsgMatcherFail = true;
   3104         } else {
   3105           this.assert(
   3106             negate
   3107             , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}'
   3108             , 'expected #{this} to throw error not ' + placeholder + ' #{exp}'
   3109             ,  errMsgMatcher
   3110             ,  _.checkError.getMessage(caughtErr)
   3111           );
   3112         }
   3113       }
   3114     }
   3115 
   3116     // If both assertions failed and both should've matched we throw an error
   3117     if (errorLikeFail && errMsgMatcherFail) {
   3118       this.assert(
   3119         negate
   3120         , 'expected #{this} to throw #{exp} but #{act} was thrown'
   3121         , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '')
   3122         , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike))
   3123         , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr))
   3124       );
   3125     }
   3126 
   3127     flag(this, 'object', caughtErr);
   3128   };
   3129 
   3130   Assertion.addMethod('throw', assertThrows);
   3131   Assertion.addMethod('throws', assertThrows);
   3132   Assertion.addMethod('Throw', assertThrows);
   3133 
   3134   /**
   3135    * ### .respondTo(method[, msg])
   3136    *
   3137    * When the target is a non-function object, `.respondTo` asserts that the
   3138    * target has a method with the given name `method`. The method can be own or
   3139    * inherited, and it can be enumerable or non-enumerable.
   3140    *
   3141    *     function Cat () {}
   3142    *     Cat.prototype.meow = function () {};
   3143    *
   3144    *     expect(new Cat()).to.respondTo('meow');
   3145    *
   3146    * When the target is a function, `.respondTo` asserts that the target's
   3147    * `prototype` property has a method with the given name `method`. Again, the
   3148    * method can be own or inherited, and it can be enumerable or non-enumerable.
   3149    *
   3150    *     function Cat () {}
   3151    *     Cat.prototype.meow = function () {};
   3152    *
   3153    *     expect(Cat).to.respondTo('meow');
   3154    *
   3155    * Add `.itself` earlier in the chain to force `.respondTo` to treat the
   3156    * target as a non-function object, even if it's a function. Thus, it asserts
   3157    * that the target has a method with the given name `method`, rather than
   3158    * asserting that the target's `prototype` property has a method with the
   3159    * given name `method`.
   3160    *
   3161    *     function Cat () {}
   3162    *     Cat.prototype.meow = function () {};
   3163    *     Cat.hiss = function () {};
   3164    *
   3165    *     expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
   3166    *
   3167    * When not adding `.itself`, it's important to check the target's type before
   3168    * using `.respondTo`. See the `.a` doc for info on checking a target's type.
   3169    *
   3170    *     function Cat () {}
   3171    *     Cat.prototype.meow = function () {};
   3172    *
   3173    *     expect(new Cat()).to.be.an('object').that.respondsTo('meow');
   3174    *
   3175    * Add `.not` earlier in the chain to negate `.respondTo`.
   3176    *
   3177    *     function Dog () {}
   3178    *     Dog.prototype.bark = function () {};
   3179    *
   3180    *     expect(new Dog()).to.not.respondTo('meow');
   3181    *
   3182    * `.respondTo` accepts an optional `msg` argument which is a custom error
   3183    * message to show when the assertion fails. The message can also be given as
   3184    * the second argument to `expect`.
   3185    *
   3186    *     expect({}).to.respondTo('meow', 'nooo why fail??');
   3187    *     expect({}, 'nooo why fail??').to.respondTo('meow');
   3188    *
   3189    * The alias `.respondsTo` can be used interchangeably with `.respondTo`.
   3190    *
   3191    * @name respondTo
   3192    * @alias respondsTo
   3193    * @param {String} method
   3194    * @param {String} msg _optional_
   3195    * @namespace BDD
   3196    * @api public
   3197    */
   3198 
   3199   function respondTo (method, msg) {
   3200     if (msg) flag(this, 'message', msg);
   3201     var obj = flag(this, 'object')
   3202       , itself = flag(this, 'itself')
   3203       , context = ('function' === typeof obj && !itself)
   3204         ? obj.prototype[method]
   3205         : obj[method];
   3206 
   3207     this.assert(
   3208         'function' === typeof context
   3209       , 'expected #{this} to respond to ' + _.inspect(method)
   3210       , 'expected #{this} to not respond to ' + _.inspect(method)
   3211     );
   3212   }
   3213 
   3214   Assertion.addMethod('respondTo', respondTo);
   3215   Assertion.addMethod('respondsTo', respondTo);
   3216 
   3217   /**
   3218    * ### .itself
   3219    *
   3220    * Forces all `.respondTo` assertions that follow in the chain to behave as if
   3221    * the target is a non-function object, even if it's a function. Thus, it
   3222    * causes `.respondTo` to assert that the target has a method with the given
   3223    * name, rather than asserting that the target's `prototype` property has a
   3224    * method with the given name.
   3225    *
   3226    *     function Cat () {}
   3227    *     Cat.prototype.meow = function () {};
   3228    *     Cat.hiss = function () {};
   3229    *
   3230    *     expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
   3231    *
   3232    * @name itself
   3233    * @namespace BDD
   3234    * @api public
   3235    */
   3236 
   3237   Assertion.addProperty('itself', function () {
   3238     flag(this, 'itself', true);
   3239   });
   3240 
   3241   /**
   3242    * ### .satisfy(matcher[, msg])
   3243    *
   3244    * Invokes the given `matcher` function with the target being passed as the
   3245    * first argument, and asserts that the value returned is truthy.
   3246    *
   3247    *     expect(1).to.satisfy(function(num) {
   3248    *       return num > 0;
   3249    *     });
   3250    *
   3251    * Add `.not` earlier in the chain to negate `.satisfy`.
   3252    *
   3253    *     expect(1).to.not.satisfy(function(num) {
   3254    *       return num > 2;
   3255    *     });
   3256    *
   3257    * `.satisfy` accepts an optional `msg` argument which is a custom error
   3258    * message to show when the assertion fails. The message can also be given as
   3259    * the second argument to `expect`.
   3260    *
   3261    *     expect(1).to.satisfy(function(num) {
   3262    *       return num > 2;
   3263    *     }, 'nooo why fail??');
   3264    *
   3265    *     expect(1, 'nooo why fail??').to.satisfy(function(num) {
   3266    *       return num > 2;
   3267    *     });
   3268    *
   3269    * The alias `.satisfies` can be used interchangeably with `.satisfy`.
   3270    *
   3271    * @name satisfy
   3272    * @alias satisfies
   3273    * @param {Function} matcher
   3274    * @param {String} msg _optional_
   3275    * @namespace BDD
   3276    * @api public
   3277    */
   3278 
   3279   function satisfy (matcher, msg) {
   3280     if (msg) flag(this, 'message', msg);
   3281     var obj = flag(this, 'object');
   3282     var result = matcher(obj);
   3283     this.assert(
   3284         result
   3285       , 'expected #{this} to satisfy ' + _.objDisplay(matcher)
   3286       , 'expected #{this} to not satisfy' + _.objDisplay(matcher)
   3287       , flag(this, 'negate') ? false : true
   3288       , result
   3289     );
   3290   }
   3291 
   3292   Assertion.addMethod('satisfy', satisfy);
   3293   Assertion.addMethod('satisfies', satisfy);
   3294 
   3295   /**
   3296    * ### .closeTo(expected, delta[, msg])
   3297    *
   3298    * Asserts that the target is a number that's within a given +/- `delta` range
   3299    * of the given number `expected`. However, it's often best to assert that the
   3300    * target is equal to its expected value.
   3301    *
   3302    *     // Recommended
   3303    *     expect(1.5).to.equal(1.5);
   3304    *
   3305    *     // Not recommended
   3306    *     expect(1.5).to.be.closeTo(1, 0.5);
   3307    *     expect(1.5).to.be.closeTo(2, 0.5);
   3308    *     expect(1.5).to.be.closeTo(1, 1);
   3309    *
   3310    * Add `.not` earlier in the chain to negate `.closeTo`.
   3311    *
   3312    *     expect(1.5).to.equal(1.5); // Recommended
   3313    *     expect(1.5).to.not.be.closeTo(3, 1); // Not recommended
   3314    *
   3315    * `.closeTo` accepts an optional `msg` argument which is a custom error
   3316    * message to show when the assertion fails. The message can also be given as
   3317    * the second argument to `expect`.
   3318    *
   3319    *     expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??');
   3320    *     expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1);
   3321    *
   3322    * The alias `.approximately` can be used interchangeably with `.closeTo`.
   3323    *
   3324    * @name closeTo
   3325    * @alias approximately
   3326    * @param {Number} expected
   3327    * @param {Number} delta
   3328    * @param {String} msg _optional_
   3329    * @namespace BDD
   3330    * @api public
   3331    */
   3332 
   3333   function closeTo(expected, delta, msg) {
   3334     if (msg) flag(this, 'message', msg);
   3335     var obj = flag(this, 'object')
   3336       , flagMsg = flag(this, 'message')
   3337       , ssfi = flag(this, 'ssfi');
   3338 
   3339     new Assertion(obj, flagMsg, ssfi, true).is.a('number');
   3340     if (typeof expected !== 'number' || typeof delta !== 'number') {
   3341       flagMsg = flagMsg ? flagMsg + ': ' : '';
   3342       var deltaMessage = delta === undefined ? ", and a delta is required" : "";
   3343       throw new AssertionError(
   3344           flagMsg + 'the arguments to closeTo or approximately must be numbers' + deltaMessage,
   3345           undefined,
   3346           ssfi
   3347       );
   3348     }
   3349 
   3350     this.assert(
   3351         Math.abs(obj - expected) <= delta
   3352       , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
   3353       , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
   3354     );
   3355   }
   3356 
   3357   Assertion.addMethod('closeTo', closeTo);
   3358   Assertion.addMethod('approximately', closeTo);
   3359 
   3360   // Note: Duplicates are ignored if testing for inclusion instead of sameness.
   3361   function isSubsetOf(subset, superset, cmp, contains, ordered) {
   3362     if (!contains) {
   3363       if (subset.length !== superset.length) return false;
   3364       superset = superset.slice();
   3365     }
   3366 
   3367     return subset.every(function(elem, idx) {
   3368       if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx];
   3369 
   3370       if (!cmp) {
   3371         var matchIdx = superset.indexOf(elem);
   3372         if (matchIdx === -1) return false;
   3373 
   3374         // Remove match from superset so not counted twice if duplicate in subset.
   3375         if (!contains) superset.splice(matchIdx, 1);
   3376         return true;
   3377       }
   3378 
   3379       return superset.some(function(elem2, matchIdx) {
   3380         if (!cmp(elem, elem2)) return false;
   3381 
   3382         // Remove match from superset so not counted twice if duplicate in subset.
   3383         if (!contains) superset.splice(matchIdx, 1);
   3384         return true;
   3385       });
   3386     });
   3387   }
   3388 
   3389   /**
   3390    * ### .members(set[, msg])
   3391    *
   3392    * Asserts that the target array has the same members as the given array
   3393    * `set`.
   3394    *
   3395    *     expect([1, 2, 3]).to.have.members([2, 1, 3]);
   3396    *     expect([1, 2, 2]).to.have.members([2, 1, 2]);
   3397    *
   3398    * By default, members are compared using strict (`===`) equality. Add `.deep`
   3399    * earlier in the chain to use deep equality instead. See the `deep-eql`
   3400    * project page for info on the deep equality algorithm:
   3401    * https://github.com/chaijs/deep-eql.
   3402    *
   3403    *     // Target array deeply (but not strictly) has member `{a: 1}`
   3404    *     expect([{a: 1}]).to.have.deep.members([{a: 1}]);
   3405    *     expect([{a: 1}]).to.not.have.members([{a: 1}]);
   3406    *
   3407    * By default, order doesn't matter. Add `.ordered` earlier in the chain to
   3408    * require that members appear in the same order.
   3409    *
   3410    *     expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]);
   3411    *     expect([1, 2, 3]).to.have.members([2, 1, 3])
   3412    *       .but.not.ordered.members([2, 1, 3]);
   3413    *
   3414    * By default, both arrays must be the same size. Add `.include` earlier in
   3415    * the chain to require that the target's members be a superset of the
   3416    * expected members. Note that duplicates are ignored in the subset when
   3417    * `.include` is added.
   3418    *
   3419    *     // Target array is a superset of [1, 2] but not identical
   3420    *     expect([1, 2, 3]).to.include.members([1, 2]);
   3421    *     expect([1, 2, 3]).to.not.have.members([1, 2]);
   3422    *
   3423    *     // Duplicates in the subset are ignored
   3424    *     expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
   3425    *
   3426    * `.deep`, `.ordered`, and `.include` can all be combined. However, if
   3427    * `.include` and `.ordered` are combined, the ordering begins at the start of
   3428    * both arrays.
   3429    *
   3430    *     expect([{a: 1}, {b: 2}, {c: 3}])
   3431    *       .to.include.deep.ordered.members([{a: 1}, {b: 2}])
   3432    *       .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]);
   3433    *
   3434    * Add `.not` earlier in the chain to negate `.members`. However, it's
   3435    * dangerous to do so. The problem is that it creates uncertain expectations
   3436    * by asserting that the target array doesn't have all of the same members as
   3437    * the given array `set` but may or may not have some of them. It's often best
   3438    * to identify the exact output that's expected, and then write an assertion
   3439    * that only accepts that exact output.
   3440    *
   3441    *     expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended
   3442    *     expect([1, 2]).to.not.have.members([3, 4]); // Not recommended
   3443    *
   3444    * `.members` accepts an optional `msg` argument which is a custom error
   3445    * message to show when the assertion fails. The message can also be given as
   3446    * the second argument to `expect`.
   3447    *
   3448    *     expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??');
   3449    *     expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]);
   3450    *
   3451    * @name members
   3452    * @param {Array} set
   3453    * @param {String} msg _optional_
   3454    * @namespace BDD
   3455    * @api public
   3456    */
   3457 
   3458   Assertion.addMethod('members', function (subset, msg) {
   3459     if (msg) flag(this, 'message', msg);
   3460     var obj = flag(this, 'object')
   3461       , flagMsg = flag(this, 'message')
   3462       , ssfi = flag(this, 'ssfi');
   3463 
   3464     new Assertion(obj, flagMsg, ssfi, true).to.be.an('array');
   3465     new Assertion(subset, flagMsg, ssfi, true).to.be.an('array');
   3466 
   3467     var contains = flag(this, 'contains');
   3468     var ordered = flag(this, 'ordered');
   3469 
   3470     var subject, failMsg, failNegateMsg;
   3471 
   3472     if (contains) {
   3473       subject = ordered ? 'an ordered superset' : 'a superset';
   3474       failMsg = 'expected #{this} to be ' + subject + ' of #{exp}';
   3475       failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}';
   3476     } else {
   3477       subject = ordered ? 'ordered members' : 'members';
   3478       failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}';
   3479       failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}';
   3480     }
   3481 
   3482     var cmp = flag(this, 'deep') ? _.eql : undefined;
   3483 
   3484     this.assert(
   3485         isSubsetOf(subset, obj, cmp, contains, ordered)
   3486       , failMsg
   3487       , failNegateMsg
   3488       , subset
   3489       , obj
   3490       , true
   3491     );
   3492   });
   3493 
   3494   /**
   3495    * ### .oneOf(list[, msg])
   3496    *
   3497    * Asserts that the target is a member of the given array `list`. However,
   3498    * it's often best to assert that the target is equal to its expected value.
   3499    *
   3500    *     expect(1).to.equal(1); // Recommended
   3501    *     expect(1).to.be.oneOf([1, 2, 3]); // Not recommended
   3502    *
   3503    * Comparisons are performed using strict (`===`) equality.
   3504    *
   3505    * Add `.not` earlier in the chain to negate `.oneOf`.
   3506    *
   3507    *     expect(1).to.equal(1); // Recommended
   3508    *     expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended
   3509    *
   3510    * It can also be chained with `.contain` or `.include`, which will work with
   3511    * both arrays and strings:
   3512    *
   3513    *     expect('Today is sunny').to.contain.oneOf(['sunny', 'cloudy'])
   3514    *     expect('Today is rainy').to.not.contain.oneOf(['sunny', 'cloudy'])
   3515    *     expect([1,2,3]).to.contain.oneOf([3,4,5])
   3516    *     expect([1,2,3]).to.not.contain.oneOf([4,5,6])
   3517    *
   3518    * `.oneOf` accepts an optional `msg` argument which is a custom error message
   3519    * to show when the assertion fails. The message can also be given as the
   3520    * second argument to `expect`.
   3521    *
   3522    *     expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??');
   3523    *     expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]);
   3524    *
   3525    * @name oneOf
   3526    * @param {Array<*>} list
   3527    * @param {String} msg _optional_
   3528    * @namespace BDD
   3529    * @api public
   3530    */
   3531 
   3532   function oneOf (list, msg) {
   3533     if (msg) flag(this, 'message', msg);
   3534     var expected = flag(this, 'object')
   3535       , flagMsg = flag(this, 'message')
   3536       , ssfi = flag(this, 'ssfi')
   3537       , contains = flag(this, 'contains')
   3538       , isDeep = flag(this, 'deep');
   3539     new Assertion(list, flagMsg, ssfi, true).to.be.an('array');
   3540 
   3541     if (contains) {
   3542       this.assert(
   3543         list.some(function(possibility) { return expected.indexOf(possibility) > -1 })
   3544         , 'expected #{this} to contain one of #{exp}'
   3545         , 'expected #{this} to not contain one of #{exp}'
   3546         , list
   3547         , expected
   3548       );
   3549     } else {
   3550       if (isDeep) {
   3551         this.assert(
   3552           list.some(function(possibility) { return _.eql(expected, possibility) })
   3553           , 'expected #{this} to deeply equal one of #{exp}'
   3554           , 'expected #{this} to deeply equal one of #{exp}'
   3555           , list
   3556           , expected
   3557         );
   3558       } else {
   3559         this.assert(
   3560           list.indexOf(expected) > -1
   3561           , 'expected #{this} to be one of #{exp}'
   3562           , 'expected #{this} to not be one of #{exp}'
   3563           , list
   3564           , expected
   3565         );
   3566       }
   3567     }
   3568   }
   3569 
   3570   Assertion.addMethod('oneOf', oneOf);
   3571 
   3572   /**
   3573    * ### .change(subject[, prop[, msg]])
   3574    *
   3575    * When one argument is provided, `.change` asserts that the given function
   3576    * `subject` returns a different value when it's invoked before the target
   3577    * function compared to when it's invoked afterward. However, it's often best
   3578    * to assert that `subject` is equal to its expected value.
   3579    *
   3580    *     var dots = ''
   3581    *       , addDot = function () { dots += '.'; }
   3582    *       , getDots = function () { return dots; };
   3583    *
   3584    *     // Recommended
   3585    *     expect(getDots()).to.equal('');
   3586    *     addDot();
   3587    *     expect(getDots()).to.equal('.');
   3588    *
   3589    *     // Not recommended
   3590    *     expect(addDot).to.change(getDots);
   3591    *
   3592    * When two arguments are provided, `.change` asserts that the value of the
   3593    * given object `subject`'s `prop` property is different before invoking the
   3594    * target function compared to afterward.
   3595    *
   3596    *     var myObj = {dots: ''}
   3597    *       , addDot = function () { myObj.dots += '.'; };
   3598    *
   3599    *     // Recommended
   3600    *     expect(myObj).to.have.property('dots', '');
   3601    *     addDot();
   3602    *     expect(myObj).to.have.property('dots', '.');
   3603    *
   3604    *     // Not recommended
   3605    *     expect(addDot).to.change(myObj, 'dots');
   3606    *
   3607    * Strict (`===`) equality is used to compare before and after values.
   3608    *
   3609    * Add `.not` earlier in the chain to negate `.change`.
   3610    *
   3611    *     var dots = ''
   3612    *       , noop = function () {}
   3613    *       , getDots = function () { return dots; };
   3614    *
   3615    *     expect(noop).to.not.change(getDots);
   3616    *
   3617    *     var myObj = {dots: ''}
   3618    *       , noop = function () {};
   3619    *
   3620    *     expect(noop).to.not.change(myObj, 'dots');
   3621    *
   3622    * `.change` accepts an optional `msg` argument which is a custom error
   3623    * message to show when the assertion fails. The message can also be given as
   3624    * the second argument to `expect`. When not providing two arguments, always
   3625    * use the second form.
   3626    *
   3627    *     var myObj = {dots: ''}
   3628    *       , addDot = function () { myObj.dots += '.'; };
   3629    *
   3630    *     expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??');
   3631    *
   3632    *     var dots = ''
   3633    *       , addDot = function () { dots += '.'; }
   3634    *       , getDots = function () { return dots; };
   3635    *
   3636    *     expect(addDot, 'nooo why fail??').to.not.change(getDots);
   3637    *
   3638    * `.change` also causes all `.by` assertions that follow in the chain to
   3639    * assert how much a numeric subject was increased or decreased by. However,
   3640    * it's dangerous to use `.change.by`. The problem is that it creates
   3641    * uncertain expectations by asserting that the subject either increases by
   3642    * the given delta, or that it decreases by the given delta. It's often best
   3643    * to identify the exact output that's expected, and then write an assertion
   3644    * that only accepts that exact output.
   3645    *
   3646    *     var myObj = {val: 1}
   3647    *       , addTwo = function () { myObj.val += 2; }
   3648    *       , subtractTwo = function () { myObj.val -= 2; };
   3649    *
   3650    *     expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
   3651    *     expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended
   3652    *
   3653    *     expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
   3654    *     expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended
   3655    *
   3656    * The alias `.changes` can be used interchangeably with `.change`.
   3657    *
   3658    * @name change
   3659    * @alias changes
   3660    * @param {String} subject
   3661    * @param {String} prop name _optional_
   3662    * @param {String} msg _optional_
   3663    * @namespace BDD
   3664    * @api public
   3665    */
   3666 
   3667   function assertChanges (subject, prop, msg) {
   3668     if (msg) flag(this, 'message', msg);
   3669     var fn = flag(this, 'object')
   3670       , flagMsg = flag(this, 'message')
   3671       , ssfi = flag(this, 'ssfi');
   3672     new Assertion(fn, flagMsg, ssfi, true).is.a('function');
   3673 
   3674     var initial;
   3675     if (!prop) {
   3676       new Assertion(subject, flagMsg, ssfi, true).is.a('function');
   3677       initial = subject();
   3678     } else {
   3679       new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
   3680       initial = subject[prop];
   3681     }
   3682 
   3683     fn();
   3684 
   3685     var final = prop === undefined || prop === null ? subject() : subject[prop];
   3686     var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
   3687 
   3688     // This gets flagged because of the .by(delta) assertion
   3689     flag(this, 'deltaMsgObj', msgObj);
   3690     flag(this, 'initialDeltaValue', initial);
   3691     flag(this, 'finalDeltaValue', final);
   3692     flag(this, 'deltaBehavior', 'change');
   3693     flag(this, 'realDelta', final !== initial);
   3694 
   3695     this.assert(
   3696       initial !== final
   3697       , 'expected ' + msgObj + ' to change'
   3698       , 'expected ' + msgObj + ' to not change'
   3699     );
   3700   }
   3701 
   3702   Assertion.addMethod('change', assertChanges);
   3703   Assertion.addMethod('changes', assertChanges);
   3704 
   3705   /**
   3706    * ### .increase(subject[, prop[, msg]])
   3707    *
   3708    * When one argument is provided, `.increase` asserts that the given function
   3709    * `subject` returns a greater number when it's invoked after invoking the
   3710    * target function compared to when it's invoked beforehand. `.increase` also
   3711    * causes all `.by` assertions that follow in the chain to assert how much
   3712    * greater of a number is returned. It's often best to assert that the return
   3713    * value increased by the expected amount, rather than asserting it increased
   3714    * by any amount.
   3715    *
   3716    *     var val = 1
   3717    *       , addTwo = function () { val += 2; }
   3718    *       , getVal = function () { return val; };
   3719    *
   3720    *     expect(addTwo).to.increase(getVal).by(2); // Recommended
   3721    *     expect(addTwo).to.increase(getVal); // Not recommended
   3722    *
   3723    * When two arguments are provided, `.increase` asserts that the value of the
   3724    * given object `subject`'s `prop` property is greater after invoking the
   3725    * target function compared to beforehand.
   3726    *
   3727    *     var myObj = {val: 1}
   3728    *       , addTwo = function () { myObj.val += 2; };
   3729    *
   3730    *     expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
   3731    *     expect(addTwo).to.increase(myObj, 'val'); // Not recommended
   3732    *
   3733    * Add `.not` earlier in the chain to negate `.increase`. However, it's
   3734    * dangerous to do so. The problem is that it creates uncertain expectations
   3735    * by asserting that the subject either decreases, or that it stays the same.
   3736    * It's often best to identify the exact output that's expected, and then
   3737    * write an assertion that only accepts that exact output.
   3738    *
   3739    * When the subject is expected to decrease, it's often best to assert that it
   3740    * decreased by the expected amount.
   3741    *
   3742    *     var myObj = {val: 1}
   3743    *       , subtractTwo = function () { myObj.val -= 2; };
   3744    *
   3745    *     expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
   3746    *     expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended
   3747    *
   3748    * When the subject is expected to stay the same, it's often best to assert
   3749    * exactly that.
   3750    *
   3751    *     var myObj = {val: 1}
   3752    *       , noop = function () {};
   3753    *
   3754    *     expect(noop).to.not.change(myObj, 'val'); // Recommended
   3755    *     expect(noop).to.not.increase(myObj, 'val'); // Not recommended
   3756    *
   3757    * `.increase` accepts an optional `msg` argument which is a custom error
   3758    * message to show when the assertion fails. The message can also be given as
   3759    * the second argument to `expect`. When not providing two arguments, always
   3760    * use the second form.
   3761    *
   3762    *     var myObj = {val: 1}
   3763    *       , noop = function () {};
   3764    *
   3765    *     expect(noop).to.increase(myObj, 'val', 'nooo why fail??');
   3766    *
   3767    *     var val = 1
   3768    *       , noop = function () {}
   3769    *       , getVal = function () { return val; };
   3770    *
   3771    *     expect(noop, 'nooo why fail??').to.increase(getVal);
   3772    *
   3773    * The alias `.increases` can be used interchangeably with `.increase`.
   3774    *
   3775    * @name increase
   3776    * @alias increases
   3777    * @param {String|Function} subject
   3778    * @param {String} prop name _optional_
   3779    * @param {String} msg _optional_
   3780    * @namespace BDD
   3781    * @api public
   3782    */
   3783 
   3784   function assertIncreases (subject, prop, msg) {
   3785     if (msg) flag(this, 'message', msg);
   3786     var fn = flag(this, 'object')
   3787       , flagMsg = flag(this, 'message')
   3788       , ssfi = flag(this, 'ssfi');
   3789     new Assertion(fn, flagMsg, ssfi, true).is.a('function');
   3790 
   3791     var initial;
   3792     if (!prop) {
   3793       new Assertion(subject, flagMsg, ssfi, true).is.a('function');
   3794       initial = subject();
   3795     } else {
   3796       new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
   3797       initial = subject[prop];
   3798     }
   3799 
   3800     // Make sure that the target is a number
   3801     new Assertion(initial, flagMsg, ssfi, true).is.a('number');
   3802 
   3803     fn();
   3804 
   3805     var final = prop === undefined || prop === null ? subject() : subject[prop];
   3806     var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
   3807 
   3808     flag(this, 'deltaMsgObj', msgObj);
   3809     flag(this, 'initialDeltaValue', initial);
   3810     flag(this, 'finalDeltaValue', final);
   3811     flag(this, 'deltaBehavior', 'increase');
   3812     flag(this, 'realDelta', final - initial);
   3813 
   3814     this.assert(
   3815       final - initial > 0
   3816       , 'expected ' + msgObj + ' to increase'
   3817       , 'expected ' + msgObj + ' to not increase'
   3818     );
   3819   }
   3820 
   3821   Assertion.addMethod('increase', assertIncreases);
   3822   Assertion.addMethod('increases', assertIncreases);
   3823 
   3824   /**
   3825    * ### .decrease(subject[, prop[, msg]])
   3826    *
   3827    * When one argument is provided, `.decrease` asserts that the given function
   3828    * `subject` returns a lesser number when it's invoked after invoking the
   3829    * target function compared to when it's invoked beforehand. `.decrease` also
   3830    * causes all `.by` assertions that follow in the chain to assert how much
   3831    * lesser of a number is returned. It's often best to assert that the return
   3832    * value decreased by the expected amount, rather than asserting it decreased
   3833    * by any amount.
   3834    *
   3835    *     var val = 1
   3836    *       , subtractTwo = function () { val -= 2; }
   3837    *       , getVal = function () { return val; };
   3838    *
   3839    *     expect(subtractTwo).to.decrease(getVal).by(2); // Recommended
   3840    *     expect(subtractTwo).to.decrease(getVal); // Not recommended
   3841    *
   3842    * When two arguments are provided, `.decrease` asserts that the value of the
   3843    * given object `subject`'s `prop` property is lesser after invoking the
   3844    * target function compared to beforehand.
   3845    *
   3846    *     var myObj = {val: 1}
   3847    *       , subtractTwo = function () { myObj.val -= 2; };
   3848    *
   3849    *     expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
   3850    *     expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended
   3851    *
   3852    * Add `.not` earlier in the chain to negate `.decrease`. However, it's
   3853    * dangerous to do so. The problem is that it creates uncertain expectations
   3854    * by asserting that the subject either increases, or that it stays the same.
   3855    * It's often best to identify the exact output that's expected, and then
   3856    * write an assertion that only accepts that exact output.
   3857    *
   3858    * When the subject is expected to increase, it's often best to assert that it
   3859    * increased by the expected amount.
   3860    *
   3861    *     var myObj = {val: 1}
   3862    *       , addTwo = function () { myObj.val += 2; };
   3863    *
   3864    *     expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
   3865    *     expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended
   3866    *
   3867    * When the subject is expected to stay the same, it's often best to assert
   3868    * exactly that.
   3869    *
   3870    *     var myObj = {val: 1}
   3871    *       , noop = function () {};
   3872    *
   3873    *     expect(noop).to.not.change(myObj, 'val'); // Recommended
   3874    *     expect(noop).to.not.decrease(myObj, 'val'); // Not recommended
   3875    *
   3876    * `.decrease` accepts an optional `msg` argument which is a custom error
   3877    * message to show when the assertion fails. The message can also be given as
   3878    * the second argument to `expect`. When not providing two arguments, always
   3879    * use the second form.
   3880    *
   3881    *     var myObj = {val: 1}
   3882    *       , noop = function () {};
   3883    *
   3884    *     expect(noop).to.decrease(myObj, 'val', 'nooo why fail??');
   3885    *
   3886    *     var val = 1
   3887    *       , noop = function () {}
   3888    *       , getVal = function () { return val; };
   3889    *
   3890    *     expect(noop, 'nooo why fail??').to.decrease(getVal);
   3891    *
   3892    * The alias `.decreases` can be used interchangeably with `.decrease`.
   3893    *
   3894    * @name decrease
   3895    * @alias decreases
   3896    * @param {String|Function} subject
   3897    * @param {String} prop name _optional_
   3898    * @param {String} msg _optional_
   3899    * @namespace BDD
   3900    * @api public
   3901    */
   3902 
   3903   function assertDecreases (subject, prop, msg) {
   3904     if (msg) flag(this, 'message', msg);
   3905     var fn = flag(this, 'object')
   3906       , flagMsg = flag(this, 'message')
   3907       , ssfi = flag(this, 'ssfi');
   3908     new Assertion(fn, flagMsg, ssfi, true).is.a('function');
   3909 
   3910     var initial;
   3911     if (!prop) {
   3912       new Assertion(subject, flagMsg, ssfi, true).is.a('function');
   3913       initial = subject();
   3914     } else {
   3915       new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
   3916       initial = subject[prop];
   3917     }
   3918 
   3919     // Make sure that the target is a number
   3920     new Assertion(initial, flagMsg, ssfi, true).is.a('number');
   3921 
   3922     fn();
   3923 
   3924     var final = prop === undefined || prop === null ? subject() : subject[prop];
   3925     var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
   3926 
   3927     flag(this, 'deltaMsgObj', msgObj);
   3928     flag(this, 'initialDeltaValue', initial);
   3929     flag(this, 'finalDeltaValue', final);
   3930     flag(this, 'deltaBehavior', 'decrease');
   3931     flag(this, 'realDelta', initial - final);
   3932 
   3933     this.assert(
   3934       final - initial < 0
   3935       , 'expected ' + msgObj + ' to decrease'
   3936       , 'expected ' + msgObj + ' to not decrease'
   3937     );
   3938   }
   3939 
   3940   Assertion.addMethod('decrease', assertDecreases);
   3941   Assertion.addMethod('decreases', assertDecreases);
   3942 
   3943   /**
   3944    * ### .by(delta[, msg])
   3945    *
   3946    * When following an `.increase` assertion in the chain, `.by` asserts that
   3947    * the subject of the `.increase` assertion increased by the given `delta`.
   3948    *
   3949    *     var myObj = {val: 1}
   3950    *       , addTwo = function () { myObj.val += 2; };
   3951    *
   3952    *     expect(addTwo).to.increase(myObj, 'val').by(2);
   3953    *
   3954    * When following a `.decrease` assertion in the chain, `.by` asserts that the
   3955    * subject of the `.decrease` assertion decreased by the given `delta`.
   3956    *
   3957    *     var myObj = {val: 1}
   3958    *       , subtractTwo = function () { myObj.val -= 2; };
   3959    *
   3960    *     expect(subtractTwo).to.decrease(myObj, 'val').by(2);
   3961    *
   3962    * When following a `.change` assertion in the chain, `.by` asserts that the
   3963    * subject of the `.change` assertion either increased or decreased by the
   3964    * given `delta`. However, it's dangerous to use `.change.by`. The problem is
   3965    * that it creates uncertain expectations. It's often best to identify the
   3966    * exact output that's expected, and then write an assertion that only accepts
   3967    * that exact output.
   3968    *
   3969    *     var myObj = {val: 1}
   3970    *       , addTwo = function () { myObj.val += 2; }
   3971    *       , subtractTwo = function () { myObj.val -= 2; };
   3972    *
   3973    *     expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
   3974    *     expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended
   3975    *
   3976    *     expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
   3977    *     expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended
   3978    *
   3979    * Add `.not` earlier in the chain to negate `.by`. However, it's often best
   3980    * to assert that the subject changed by its expected delta, rather than
   3981    * asserting that it didn't change by one of countless unexpected deltas.
   3982    *
   3983    *     var myObj = {val: 1}
   3984    *       , addTwo = function () { myObj.val += 2; };
   3985    *
   3986    *     // Recommended
   3987    *     expect(addTwo).to.increase(myObj, 'val').by(2);
   3988    *
   3989    *     // Not recommended
   3990    *     expect(addTwo).to.increase(myObj, 'val').but.not.by(3);
   3991    *
   3992    * `.by` accepts an optional `msg` argument which is a custom error message to
   3993    * show when the assertion fails. The message can also be given as the second
   3994    * argument to `expect`.
   3995    *
   3996    *     var myObj = {val: 1}
   3997    *       , addTwo = function () { myObj.val += 2; };
   3998    *
   3999    *     expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??');
   4000    *     expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3);
   4001    *
   4002    * @name by
   4003    * @param {Number} delta
   4004    * @param {String} msg _optional_
   4005    * @namespace BDD
   4006    * @api public
   4007    */
   4008 
   4009   function assertDelta(delta, msg) {
   4010     if (msg) flag(this, 'message', msg);
   4011 
   4012     var msgObj = flag(this, 'deltaMsgObj');
   4013     var initial = flag(this, 'initialDeltaValue');
   4014     var final = flag(this, 'finalDeltaValue');
   4015     var behavior = flag(this, 'deltaBehavior');
   4016     var realDelta = flag(this, 'realDelta');
   4017 
   4018     var expression;
   4019     if (behavior === 'change') {
   4020       expression = Math.abs(final - initial) === Math.abs(delta);
   4021     } else {
   4022       expression = realDelta === Math.abs(delta);
   4023     }
   4024 
   4025     this.assert(
   4026       expression
   4027       , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta
   4028       , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta
   4029     );
   4030   }
   4031 
   4032   Assertion.addMethod('by', assertDelta);
   4033 
   4034   /**
   4035    * ### .extensible
   4036    *
   4037    * Asserts that the target is extensible, which means that new properties can
   4038    * be added to it. Primitives are never extensible.
   4039    *
   4040    *     expect({a: 1}).to.be.extensible;
   4041    *
   4042    * Add `.not` earlier in the chain to negate `.extensible`.
   4043    *
   4044    *     var nonExtensibleObject = Object.preventExtensions({})
   4045    *       , sealedObject = Object.seal({})
   4046    *       , frozenObject = Object.freeze({});
   4047    *
   4048    *     expect(nonExtensibleObject).to.not.be.extensible;
   4049    *     expect(sealedObject).to.not.be.extensible;
   4050    *     expect(frozenObject).to.not.be.extensible;
   4051    *     expect(1).to.not.be.extensible;
   4052    *
   4053    * A custom error message can be given as the second argument to `expect`.
   4054    *
   4055    *     expect(1, 'nooo why fail??').to.be.extensible;
   4056    *
   4057    * @name extensible
   4058    * @namespace BDD
   4059    * @api public
   4060    */
   4061 
   4062   Assertion.addProperty('extensible', function() {
   4063     var obj = flag(this, 'object');
   4064 
   4065     // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
   4066     // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.
   4067     // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
   4068     // The following provides ES6 behavior for ES5 environments.
   4069 
   4070     var isExtensible = obj === Object(obj) && Object.isExtensible(obj);
   4071 
   4072     this.assert(
   4073       isExtensible
   4074       , 'expected #{this} to be extensible'
   4075       , 'expected #{this} to not be extensible'
   4076     );
   4077   });
   4078 
   4079   /**
   4080    * ### .sealed
   4081    *
   4082    * Asserts that the target is sealed, which means that new properties can't be
   4083    * added to it, and its existing properties can't be reconfigured or deleted.
   4084    * However, it's possible that its existing properties can still be reassigned
   4085    * to different values. Primitives are always sealed.
   4086    *
   4087    *     var sealedObject = Object.seal({});
   4088    *     var frozenObject = Object.freeze({});
   4089    *
   4090    *     expect(sealedObject).to.be.sealed;
   4091    *     expect(frozenObject).to.be.sealed;
   4092    *     expect(1).to.be.sealed;
   4093    *
   4094    * Add `.not` earlier in the chain to negate `.sealed`.
   4095    *
   4096    *     expect({a: 1}).to.not.be.sealed;
   4097    *
   4098    * A custom error message can be given as the second argument to `expect`.
   4099    *
   4100    *     expect({a: 1}, 'nooo why fail??').to.be.sealed;
   4101    *
   4102    * @name sealed
   4103    * @namespace BDD
   4104    * @api public
   4105    */
   4106 
   4107   Assertion.addProperty('sealed', function() {
   4108     var obj = flag(this, 'object');
   4109 
   4110     // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
   4111     // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.
   4112     // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed
   4113     // The following provides ES6 behavior for ES5 environments.
   4114 
   4115     var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true;
   4116 
   4117     this.assert(
   4118       isSealed
   4119       , 'expected #{this} to be sealed'
   4120       , 'expected #{this} to not be sealed'
   4121     );
   4122   });
   4123 
   4124   /**
   4125    * ### .frozen
   4126    *
   4127    * Asserts that the target is frozen, which means that new properties can't be
   4128    * added to it, and its existing properties can't be reassigned to different
   4129    * values, reconfigured, or deleted. Primitives are always frozen.
   4130    *
   4131    *     var frozenObject = Object.freeze({});
   4132    *
   4133    *     expect(frozenObject).to.be.frozen;
   4134    *     expect(1).to.be.frozen;
   4135    *
   4136    * Add `.not` earlier in the chain to negate `.frozen`.
   4137    *
   4138    *     expect({a: 1}).to.not.be.frozen;
   4139    *
   4140    * A custom error message can be given as the second argument to `expect`.
   4141    *
   4142    *     expect({a: 1}, 'nooo why fail??').to.be.frozen;
   4143    *
   4144    * @name frozen
   4145    * @namespace BDD
   4146    * @api public
   4147    */
   4148 
   4149   Assertion.addProperty('frozen', function() {
   4150     var obj = flag(this, 'object');
   4151 
   4152     // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
   4153     // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.
   4154     // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen
   4155     // The following provides ES6 behavior for ES5 environments.
   4156 
   4157     var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true;
   4158 
   4159     this.assert(
   4160       isFrozen
   4161       , 'expected #{this} to be frozen'
   4162       , 'expected #{this} to not be frozen'
   4163     );
   4164   });
   4165 
   4166   /**
   4167    * ### .finite
   4168    *
   4169    * Asserts that the target is a number, and isn't `NaN` or positive/negative
   4170    * `Infinity`.
   4171    *
   4172    *     expect(1).to.be.finite;
   4173    *
   4174    * Add `.not` earlier in the chain to negate `.finite`. However, it's
   4175    * dangerous to do so. The problem is that it creates uncertain expectations
   4176    * by asserting that the subject either isn't a number, or that it's `NaN`, or
   4177    * that it's positive `Infinity`, or that it's negative `Infinity`. It's often
   4178    * best to identify the exact output that's expected, and then write an
   4179    * assertion that only accepts that exact output.
   4180    *
   4181    * When the target isn't expected to be a number, it's often best to assert
   4182    * that it's the expected type, rather than asserting that it isn't one of
   4183    * many unexpected types.
   4184    *
   4185    *     expect('foo').to.be.a('string'); // Recommended
   4186    *     expect('foo').to.not.be.finite; // Not recommended
   4187    *
   4188    * When the target is expected to be `NaN`, it's often best to assert exactly
   4189    * that.
   4190    *
   4191    *     expect(NaN).to.be.NaN; // Recommended
   4192    *     expect(NaN).to.not.be.finite; // Not recommended
   4193    *
   4194    * When the target is expected to be positive infinity, it's often best to
   4195    * assert exactly that.
   4196    *
   4197    *     expect(Infinity).to.equal(Infinity); // Recommended
   4198    *     expect(Infinity).to.not.be.finite; // Not recommended
   4199    *
   4200    * When the target is expected to be negative infinity, it's often best to
   4201    * assert exactly that.
   4202    *
   4203    *     expect(-Infinity).to.equal(-Infinity); // Recommended
   4204    *     expect(-Infinity).to.not.be.finite; // Not recommended
   4205    *
   4206    * A custom error message can be given as the second argument to `expect`.
   4207    *
   4208    *     expect('foo', 'nooo why fail??').to.be.finite;
   4209    *
   4210    * @name finite
   4211    * @namespace BDD
   4212    * @api public
   4213    */
   4214 
   4215   Assertion.addProperty('finite', function(msg) {
   4216     var obj = flag(this, 'object');
   4217 
   4218     this.assert(
   4219         typeof obj === 'number' && isFinite(obj)
   4220       , 'expected #{this} to be a finite number'
   4221       , 'expected #{this} to not be a finite number'
   4222     );
   4223   });
   4224 };
   4225 
   4226 },{}],6:[function(require,module,exports){
   4227 /*!
   4228  * chai
   4229  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
   4230  * MIT Licensed
   4231  */
   4232 
   4233 module.exports = function (chai, util) {
   4234   /*!
   4235    * Chai dependencies.
   4236    */
   4237 
   4238   var Assertion = chai.Assertion
   4239     , flag = util.flag;
   4240 
   4241   /*!
   4242    * Module export.
   4243    */
   4244 
   4245   /**
   4246    * ### assert(expression, message)
   4247    *
   4248    * Write your own test expressions.
   4249    *
   4250    *     assert('foo' !== 'bar', 'foo is not bar');
   4251    *     assert(Array.isArray([]), 'empty arrays are arrays');
   4252    *
   4253    * @param {Mixed} expression to test for truthiness
   4254    * @param {String} message to display on error
   4255    * @name assert
   4256    * @namespace Assert
   4257    * @api public
   4258    */
   4259 
   4260   var assert = chai.assert = function (express, errmsg) {
   4261     var test = new Assertion(null, null, chai.assert, true);
   4262     test.assert(
   4263         express
   4264       , errmsg
   4265       , '[ negation message unavailable ]'
   4266     );
   4267   };
   4268 
   4269   /**
   4270    * ### .fail([message])
   4271    * ### .fail(actual, expected, [message], [operator])
   4272    *
   4273    * Throw a failure. Node.js `assert` module-compatible.
   4274    *
   4275    *     assert.fail();
   4276    *     assert.fail("custom error message");
   4277    *     assert.fail(1, 2);
   4278    *     assert.fail(1, 2, "custom error message");
   4279    *     assert.fail(1, 2, "custom error message", ">");
   4280    *     assert.fail(1, 2, undefined, ">");
   4281    *
   4282    * @name fail
   4283    * @param {Mixed} actual
   4284    * @param {Mixed} expected
   4285    * @param {String} message
   4286    * @param {String} operator
   4287    * @namespace Assert
   4288    * @api public
   4289    */
   4290 
   4291   assert.fail = function (actual, expected, message, operator) {
   4292     if (arguments.length < 2) {
   4293         // Comply with Node's fail([message]) interface
   4294 
   4295         message = actual;
   4296         actual = undefined;
   4297     }
   4298 
   4299     message = message || 'assert.fail()';
   4300     throw new chai.AssertionError(message, {
   4301         actual: actual
   4302       , expected: expected
   4303       , operator: operator
   4304     }, assert.fail);
   4305   };
   4306 
   4307   /**
   4308    * ### .isOk(object, [message])
   4309    *
   4310    * Asserts that `object` is truthy.
   4311    *
   4312    *     assert.isOk('everything', 'everything is ok');
   4313    *     assert.isOk(false, 'this will fail');
   4314    *
   4315    * @name isOk
   4316    * @alias ok
   4317    * @param {Mixed} object to test
   4318    * @param {String} message
   4319    * @namespace Assert
   4320    * @api public
   4321    */
   4322 
   4323   assert.isOk = function (val, msg) {
   4324     new Assertion(val, msg, assert.isOk, true).is.ok;
   4325   };
   4326 
   4327   /**
   4328    * ### .isNotOk(object, [message])
   4329    *
   4330    * Asserts that `object` is falsy.
   4331    *
   4332    *     assert.isNotOk('everything', 'this will fail');
   4333    *     assert.isNotOk(false, 'this will pass');
   4334    *
   4335    * @name isNotOk
   4336    * @alias notOk
   4337    * @param {Mixed} object to test
   4338    * @param {String} message
   4339    * @namespace Assert
   4340    * @api public
   4341    */
   4342 
   4343   assert.isNotOk = function (val, msg) {
   4344     new Assertion(val, msg, assert.isNotOk, true).is.not.ok;
   4345   };
   4346 
   4347   /**
   4348    * ### .equal(actual, expected, [message])
   4349    *
   4350    * Asserts non-strict equality (`==`) of `actual` and `expected`.
   4351    *
   4352    *     assert.equal(3, '3', '== coerces values to strings');
   4353    *
   4354    * @name equal
   4355    * @param {Mixed} actual
   4356    * @param {Mixed} expected
   4357    * @param {String} message
   4358    * @namespace Assert
   4359    * @api public
   4360    */
   4361 
   4362   assert.equal = function (act, exp, msg) {
   4363     var test = new Assertion(act, msg, assert.equal, true);
   4364 
   4365     test.assert(
   4366         exp == flag(test, 'object')
   4367       , 'expected #{this} to equal #{exp}'
   4368       , 'expected #{this} to not equal #{act}'
   4369       , exp
   4370       , act
   4371       , true
   4372     );
   4373   };
   4374 
   4375   /**
   4376    * ### .notEqual(actual, expected, [message])
   4377    *
   4378    * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
   4379    *
   4380    *     assert.notEqual(3, 4, 'these numbers are not equal');
   4381    *
   4382    * @name notEqual
   4383    * @param {Mixed} actual
   4384    * @param {Mixed} expected
   4385    * @param {String} message
   4386    * @namespace Assert
   4387    * @api public
   4388    */
   4389 
   4390   assert.notEqual = function (act, exp, msg) {
   4391     var test = new Assertion(act, msg, assert.notEqual, true);
   4392 
   4393     test.assert(
   4394         exp != flag(test, 'object')
   4395       , 'expected #{this} to not equal #{exp}'
   4396       , 'expected #{this} to equal #{act}'
   4397       , exp
   4398       , act
   4399       , true
   4400     );
   4401   };
   4402 
   4403   /**
   4404    * ### .strictEqual(actual, expected, [message])
   4405    *
   4406    * Asserts strict equality (`===`) of `actual` and `expected`.
   4407    *
   4408    *     assert.strictEqual(true, true, 'these booleans are strictly equal');
   4409    *
   4410    * @name strictEqual
   4411    * @param {Mixed} actual
   4412    * @param {Mixed} expected
   4413    * @param {String} message
   4414    * @namespace Assert
   4415    * @api public
   4416    */
   4417 
   4418   assert.strictEqual = function (act, exp, msg) {
   4419     new Assertion(act, msg, assert.strictEqual, true).to.equal(exp);
   4420   };
   4421 
   4422   /**
   4423    * ### .notStrictEqual(actual, expected, [message])
   4424    *
   4425    * Asserts strict inequality (`!==`) of `actual` and `expected`.
   4426    *
   4427    *     assert.notStrictEqual(3, '3', 'no coercion for strict equality');
   4428    *
   4429    * @name notStrictEqual
   4430    * @param {Mixed} actual
   4431    * @param {Mixed} expected
   4432    * @param {String} message
   4433    * @namespace Assert
   4434    * @api public
   4435    */
   4436 
   4437   assert.notStrictEqual = function (act, exp, msg) {
   4438     new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp);
   4439   };
   4440 
   4441   /**
   4442    * ### .deepEqual(actual, expected, [message])
   4443    *
   4444    * Asserts that `actual` is deeply equal to `expected`.
   4445    *
   4446    *     assert.deepEqual({ tea: 'green' }, { tea: 'green' });
   4447    *
   4448    * @name deepEqual
   4449    * @param {Mixed} actual
   4450    * @param {Mixed} expected
   4451    * @param {String} message
   4452    * @alias deepStrictEqual
   4453    * @namespace Assert
   4454    * @api public
   4455    */
   4456 
   4457   assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) {
   4458     new Assertion(act, msg, assert.deepEqual, true).to.eql(exp);
   4459   };
   4460 
   4461   /**
   4462    * ### .notDeepEqual(actual, expected, [message])
   4463    *
   4464    * Assert that `actual` is not deeply equal to `expected`.
   4465    *
   4466    *     assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
   4467    *
   4468    * @name notDeepEqual
   4469    * @param {Mixed} actual
   4470    * @param {Mixed} expected
   4471    * @param {String} message
   4472    * @namespace Assert
   4473    * @api public
   4474    */
   4475 
   4476   assert.notDeepEqual = function (act, exp, msg) {
   4477     new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp);
   4478   };
   4479 
   4480    /**
   4481    * ### .isAbove(valueToCheck, valueToBeAbove, [message])
   4482    *
   4483    * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`.
   4484    *
   4485    *     assert.isAbove(5, 2, '5 is strictly greater than 2');
   4486    *
   4487    * @name isAbove
   4488    * @param {Mixed} valueToCheck
   4489    * @param {Mixed} valueToBeAbove
   4490    * @param {String} message
   4491    * @namespace Assert
   4492    * @api public
   4493    */
   4494 
   4495   assert.isAbove = function (val, abv, msg) {
   4496     new Assertion(val, msg, assert.isAbove, true).to.be.above(abv);
   4497   };
   4498 
   4499    /**
   4500    * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])
   4501    *
   4502    * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`.
   4503    *
   4504    *     assert.isAtLeast(5, 2, '5 is greater or equal to 2');
   4505    *     assert.isAtLeast(3, 3, '3 is greater or equal to 3');
   4506    *
   4507    * @name isAtLeast
   4508    * @param {Mixed} valueToCheck
   4509    * @param {Mixed} valueToBeAtLeast
   4510    * @param {String} message
   4511    * @namespace Assert
   4512    * @api public
   4513    */
   4514 
   4515   assert.isAtLeast = function (val, atlst, msg) {
   4516     new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst);
   4517   };
   4518 
   4519    /**
   4520    * ### .isBelow(valueToCheck, valueToBeBelow, [message])
   4521    *
   4522    * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`.
   4523    *
   4524    *     assert.isBelow(3, 6, '3 is strictly less than 6');
   4525    *
   4526    * @name isBelow
   4527    * @param {Mixed} valueToCheck
   4528    * @param {Mixed} valueToBeBelow
   4529    * @param {String} message
   4530    * @namespace Assert
   4531    * @api public
   4532    */
   4533 
   4534   assert.isBelow = function (val, blw, msg) {
   4535     new Assertion(val, msg, assert.isBelow, true).to.be.below(blw);
   4536   };
   4537 
   4538    /**
   4539    * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])
   4540    *
   4541    * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`.
   4542    *
   4543    *     assert.isAtMost(3, 6, '3 is less than or equal to 6');
   4544    *     assert.isAtMost(4, 4, '4 is less than or equal to 4');
   4545    *
   4546    * @name isAtMost
   4547    * @param {Mixed} valueToCheck
   4548    * @param {Mixed} valueToBeAtMost
   4549    * @param {String} message
   4550    * @namespace Assert
   4551    * @api public
   4552    */
   4553 
   4554   assert.isAtMost = function (val, atmst, msg) {
   4555     new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst);
   4556   };
   4557 
   4558   /**
   4559    * ### .isTrue(value, [message])
   4560    *
   4561    * Asserts that `value` is true.
   4562    *
   4563    *     var teaServed = true;
   4564    *     assert.isTrue(teaServed, 'the tea has been served');
   4565    *
   4566    * @name isTrue
   4567    * @param {Mixed} value
   4568    * @param {String} message
   4569    * @namespace Assert
   4570    * @api public
   4571    */
   4572 
   4573   assert.isTrue = function (val, msg) {
   4574     new Assertion(val, msg, assert.isTrue, true).is['true'];
   4575   };
   4576 
   4577   /**
   4578    * ### .isNotTrue(value, [message])
   4579    *
   4580    * Asserts that `value` is not true.
   4581    *
   4582    *     var tea = 'tasty chai';
   4583    *     assert.isNotTrue(tea, 'great, time for tea!');
   4584    *
   4585    * @name isNotTrue
   4586    * @param {Mixed} value
   4587    * @param {String} message
   4588    * @namespace Assert
   4589    * @api public
   4590    */
   4591 
   4592   assert.isNotTrue = function (val, msg) {
   4593     new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true);
   4594   };
   4595 
   4596   /**
   4597    * ### .isFalse(value, [message])
   4598    *
   4599    * Asserts that `value` is false.
   4600    *
   4601    *     var teaServed = false;
   4602    *     assert.isFalse(teaServed, 'no tea yet? hmm...');
   4603    *
   4604    * @name isFalse
   4605    * @param {Mixed} value
   4606    * @param {String} message
   4607    * @namespace Assert
   4608    * @api public
   4609    */
   4610 
   4611   assert.isFalse = function (val, msg) {
   4612     new Assertion(val, msg, assert.isFalse, true).is['false'];
   4613   };
   4614 
   4615   /**
   4616    * ### .isNotFalse(value, [message])
   4617    *
   4618    * Asserts that `value` is not false.
   4619    *
   4620    *     var tea = 'tasty chai';
   4621    *     assert.isNotFalse(tea, 'great, time for tea!');
   4622    *
   4623    * @name isNotFalse
   4624    * @param {Mixed} value
   4625    * @param {String} message
   4626    * @namespace Assert
   4627    * @api public
   4628    */
   4629 
   4630   assert.isNotFalse = function (val, msg) {
   4631     new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false);
   4632   };
   4633 
   4634   /**
   4635    * ### .isNull(value, [message])
   4636    *
   4637    * Asserts that `value` is null.
   4638    *
   4639    *     assert.isNull(err, 'there was no error');
   4640    *
   4641    * @name isNull
   4642    * @param {Mixed} value
   4643    * @param {String} message
   4644    * @namespace Assert
   4645    * @api public
   4646    */
   4647 
   4648   assert.isNull = function (val, msg) {
   4649     new Assertion(val, msg, assert.isNull, true).to.equal(null);
   4650   };
   4651 
   4652   /**
   4653    * ### .isNotNull(value, [message])
   4654    *
   4655    * Asserts that `value` is not null.
   4656    *
   4657    *     var tea = 'tasty chai';
   4658    *     assert.isNotNull(tea, 'great, time for tea!');
   4659    *
   4660    * @name isNotNull
   4661    * @param {Mixed} value
   4662    * @param {String} message
   4663    * @namespace Assert
   4664    * @api public
   4665    */
   4666 
   4667   assert.isNotNull = function (val, msg) {
   4668     new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null);
   4669   };
   4670 
   4671   /**
   4672    * ### .isNaN
   4673    *
   4674    * Asserts that value is NaN.
   4675    *
   4676    *     assert.isNaN(NaN, 'NaN is NaN');
   4677    *
   4678    * @name isNaN
   4679    * @param {Mixed} value
   4680    * @param {String} message
   4681    * @namespace Assert
   4682    * @api public
   4683    */
   4684 
   4685   assert.isNaN = function (val, msg) {
   4686     new Assertion(val, msg, assert.isNaN, true).to.be.NaN;
   4687   };
   4688 
   4689   /**
   4690    * ### .isNotNaN
   4691    *
   4692    * Asserts that value is not NaN.
   4693    *
   4694    *     assert.isNotNaN(4, '4 is not NaN');
   4695    *
   4696    * @name isNotNaN
   4697    * @param {Mixed} value
   4698    * @param {String} message
   4699    * @namespace Assert
   4700    * @api public
   4701    */
   4702   assert.isNotNaN = function (val, msg) {
   4703     new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN;
   4704   };
   4705 
   4706   /**
   4707    * ### .exists
   4708    *
   4709    * Asserts that the target is neither `null` nor `undefined`.
   4710    *
   4711    *     var foo = 'hi';
   4712    *
   4713    *     assert.exists(foo, 'foo is neither `null` nor `undefined`');
   4714    *
   4715    * @name exists
   4716    * @param {Mixed} value
   4717    * @param {String} message
   4718    * @namespace Assert
   4719    * @api public
   4720    */
   4721 
   4722   assert.exists = function (val, msg) {
   4723     new Assertion(val, msg, assert.exists, true).to.exist;
   4724   };
   4725 
   4726   /**
   4727    * ### .notExists
   4728    *
   4729    * Asserts that the target is either `null` or `undefined`.
   4730    *
   4731    *     var bar = null
   4732    *       , baz;
   4733    *
   4734    *     assert.notExists(bar);
   4735    *     assert.notExists(baz, 'baz is either null or undefined');
   4736    *
   4737    * @name notExists
   4738    * @param {Mixed} value
   4739    * @param {String} message
   4740    * @namespace Assert
   4741    * @api public
   4742    */
   4743 
   4744   assert.notExists = function (val, msg) {
   4745     new Assertion(val, msg, assert.notExists, true).to.not.exist;
   4746   };
   4747 
   4748   /**
   4749    * ### .isUndefined(value, [message])
   4750    *
   4751    * Asserts that `value` is `undefined`.
   4752    *
   4753    *     var tea;
   4754    *     assert.isUndefined(tea, 'no tea defined');
   4755    *
   4756    * @name isUndefined
   4757    * @param {Mixed} value
   4758    * @param {String} message
   4759    * @namespace Assert
   4760    * @api public
   4761    */
   4762 
   4763   assert.isUndefined = function (val, msg) {
   4764     new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined);
   4765   };
   4766 
   4767   /**
   4768    * ### .isDefined(value, [message])
   4769    *
   4770    * Asserts that `value` is not `undefined`.
   4771    *
   4772    *     var tea = 'cup of chai';
   4773    *     assert.isDefined(tea, 'tea has been defined');
   4774    *
   4775    * @name isDefined
   4776    * @param {Mixed} value
   4777    * @param {String} message
   4778    * @namespace Assert
   4779    * @api public
   4780    */
   4781 
   4782   assert.isDefined = function (val, msg) {
   4783     new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined);
   4784   };
   4785 
   4786   /**
   4787    * ### .isFunction(value, [message])
   4788    *
   4789    * Asserts that `value` is a function.
   4790    *
   4791    *     function serveTea() { return 'cup of tea'; };
   4792    *     assert.isFunction(serveTea, 'great, we can have tea now');
   4793    *
   4794    * @name isFunction
   4795    * @param {Mixed} value
   4796    * @param {String} message
   4797    * @namespace Assert
   4798    * @api public
   4799    */
   4800 
   4801   assert.isFunction = function (val, msg) {
   4802     new Assertion(val, msg, assert.isFunction, true).to.be.a('function');
   4803   };
   4804 
   4805   /**
   4806    * ### .isNotFunction(value, [message])
   4807    *
   4808    * Asserts that `value` is _not_ a function.
   4809    *
   4810    *     var serveTea = [ 'heat', 'pour', 'sip' ];
   4811    *     assert.isNotFunction(serveTea, 'great, we have listed the steps');
   4812    *
   4813    * @name isNotFunction
   4814    * @param {Mixed} value
   4815    * @param {String} message
   4816    * @namespace Assert
   4817    * @api public
   4818    */
   4819 
   4820   assert.isNotFunction = function (val, msg) {
   4821     new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function');
   4822   };
   4823 
   4824   /**
   4825    * ### .isObject(value, [message])
   4826    *
   4827    * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).
   4828    * _The assertion does not match subclassed objects._
   4829    *
   4830    *     var selection = { name: 'Chai', serve: 'with spices' };
   4831    *     assert.isObject(selection, 'tea selection is an object');
   4832    *
   4833    * @name isObject
   4834    * @param {Mixed} value
   4835    * @param {String} message
   4836    * @namespace Assert
   4837    * @api public
   4838    */
   4839 
   4840   assert.isObject = function (val, msg) {
   4841     new Assertion(val, msg, assert.isObject, true).to.be.a('object');
   4842   };
   4843 
   4844   /**
   4845    * ### .isNotObject(value, [message])
   4846    *
   4847    * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).
   4848    *
   4849    *     var selection = 'chai'
   4850    *     assert.isNotObject(selection, 'tea selection is not an object');
   4851    *     assert.isNotObject(null, 'null is not an object');
   4852    *
   4853    * @name isNotObject
   4854    * @param {Mixed} value
   4855    * @param {String} message
   4856    * @namespace Assert
   4857    * @api public
   4858    */
   4859 
   4860   assert.isNotObject = function (val, msg) {
   4861     new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object');
   4862   };
   4863 
   4864   /**
   4865    * ### .isArray(value, [message])
   4866    *
   4867    * Asserts that `value` is an array.
   4868    *
   4869    *     var menu = [ 'green', 'chai', 'oolong' ];
   4870    *     assert.isArray(menu, 'what kind of tea do we want?');
   4871    *
   4872    * @name isArray
   4873    * @param {Mixed} value
   4874    * @param {String} message
   4875    * @namespace Assert
   4876    * @api public
   4877    */
   4878 
   4879   assert.isArray = function (val, msg) {
   4880     new Assertion(val, msg, assert.isArray, true).to.be.an('array');
   4881   };
   4882 
   4883   /**
   4884    * ### .isNotArray(value, [message])
   4885    *
   4886    * Asserts that `value` is _not_ an array.
   4887    *
   4888    *     var menu = 'green|chai|oolong';
   4889    *     assert.isNotArray(menu, 'what kind of tea do we want?');
   4890    *
   4891    * @name isNotArray
   4892    * @param {Mixed} value
   4893    * @param {String} message
   4894    * @namespace Assert
   4895    * @api public
   4896    */
   4897 
   4898   assert.isNotArray = function (val, msg) {
   4899     new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array');
   4900   };
   4901 
   4902   /**
   4903    * ### .isString(value, [message])
   4904    *
   4905    * Asserts that `value` is a string.
   4906    *
   4907    *     var teaOrder = 'chai';
   4908    *     assert.isString(teaOrder, 'order placed');
   4909    *
   4910    * @name isString
   4911    * @param {Mixed} value
   4912    * @param {String} message
   4913    * @namespace Assert
   4914    * @api public
   4915    */
   4916 
   4917   assert.isString = function (val, msg) {
   4918     new Assertion(val, msg, assert.isString, true).to.be.a('string');
   4919   };
   4920 
   4921   /**
   4922    * ### .isNotString(value, [message])
   4923    *
   4924    * Asserts that `value` is _not_ a string.
   4925    *
   4926    *     var teaOrder = 4;
   4927    *     assert.isNotString(teaOrder, 'order placed');
   4928    *
   4929    * @name isNotString
   4930    * @param {Mixed} value
   4931    * @param {String} message
   4932    * @namespace Assert
   4933    * @api public
   4934    */
   4935 
   4936   assert.isNotString = function (val, msg) {
   4937     new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string');
   4938   };
   4939 
   4940   /**
   4941    * ### .isNumber(value, [message])
   4942    *
   4943    * Asserts that `value` is a number.
   4944    *
   4945    *     var cups = 2;
   4946    *     assert.isNumber(cups, 'how many cups');
   4947    *
   4948    * @name isNumber
   4949    * @param {Number} value
   4950    * @param {String} message
   4951    * @namespace Assert
   4952    * @api public
   4953    */
   4954 
   4955   assert.isNumber = function (val, msg) {
   4956     new Assertion(val, msg, assert.isNumber, true).to.be.a('number');
   4957   };
   4958 
   4959   /**
   4960    * ### .isNotNumber(value, [message])
   4961    *
   4962    * Asserts that `value` is _not_ a number.
   4963    *
   4964    *     var cups = '2 cups please';
   4965    *     assert.isNotNumber(cups, 'how many cups');
   4966    *
   4967    * @name isNotNumber
   4968    * @param {Mixed} value
   4969    * @param {String} message
   4970    * @namespace Assert
   4971    * @api public
   4972    */
   4973 
   4974   assert.isNotNumber = function (val, msg) {
   4975     new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number');
   4976   };
   4977 
   4978    /**
   4979    * ### .isFinite(value, [message])
   4980    *
   4981    * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`.
   4982    *
   4983    *     var cups = 2;
   4984    *     assert.isFinite(cups, 'how many cups');
   4985    *
   4986    *     assert.isFinite(NaN); // throws
   4987    *
   4988    * @name isFinite
   4989    * @param {Number} value
   4990    * @param {String} message
   4991    * @namespace Assert
   4992    * @api public
   4993    */
   4994 
   4995   assert.isFinite = function (val, msg) {
   4996     new Assertion(val, msg, assert.isFinite, true).to.be.finite;
   4997   };
   4998 
   4999   /**
   5000    * ### .isBoolean(value, [message])
   5001    *
   5002    * Asserts that `value` is a boolean.
   5003    *
   5004    *     var teaReady = true
   5005    *       , teaServed = false;
   5006    *
   5007    *     assert.isBoolean(teaReady, 'is the tea ready');
   5008    *     assert.isBoolean(teaServed, 'has tea been served');
   5009    *
   5010    * @name isBoolean
   5011    * @param {Mixed} value
   5012    * @param {String} message
   5013    * @namespace Assert
   5014    * @api public
   5015    */
   5016 
   5017   assert.isBoolean = function (val, msg) {
   5018     new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean');
   5019   };
   5020 
   5021   /**
   5022    * ### .isNotBoolean(value, [message])
   5023    *
   5024    * Asserts that `value` is _not_ a boolean.
   5025    *
   5026    *     var teaReady = 'yep'
   5027    *       , teaServed = 'nope';
   5028    *
   5029    *     assert.isNotBoolean(teaReady, 'is the tea ready');
   5030    *     assert.isNotBoolean(teaServed, 'has tea been served');
   5031    *
   5032    * @name isNotBoolean
   5033    * @param {Mixed} value
   5034    * @param {String} message
   5035    * @namespace Assert
   5036    * @api public
   5037    */
   5038 
   5039   assert.isNotBoolean = function (val, msg) {
   5040     new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean');
   5041   };
   5042 
   5043   /**
   5044    * ### .typeOf(value, name, [message])
   5045    *
   5046    * Asserts that `value`'s type is `name`, as determined by
   5047    * `Object.prototype.toString`.
   5048    *
   5049    *     assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');
   5050    *     assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');
   5051    *     assert.typeOf('tea', 'string', 'we have a string');
   5052    *     assert.typeOf(/tea/, 'regexp', 'we have a regular expression');
   5053    *     assert.typeOf(null, 'null', 'we have a null');
   5054    *     assert.typeOf(undefined, 'undefined', 'we have an undefined');
   5055    *
   5056    * @name typeOf
   5057    * @param {Mixed} value
   5058    * @param {String} name
   5059    * @param {String} message
   5060    * @namespace Assert
   5061    * @api public
   5062    */
   5063 
   5064   assert.typeOf = function (val, type, msg) {
   5065     new Assertion(val, msg, assert.typeOf, true).to.be.a(type);
   5066   };
   5067 
   5068   /**
   5069    * ### .notTypeOf(value, name, [message])
   5070    *
   5071    * Asserts that `value`'s type is _not_ `name`, as determined by
   5072    * `Object.prototype.toString`.
   5073    *
   5074    *     assert.notTypeOf('tea', 'number', 'strings are not numbers');
   5075    *
   5076    * @name notTypeOf
   5077    * @param {Mixed} value
   5078    * @param {String} typeof name
   5079    * @param {String} message
   5080    * @namespace Assert
   5081    * @api public
   5082    */
   5083 
   5084   assert.notTypeOf = function (val, type, msg) {
   5085     new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type);
   5086   };
   5087 
   5088   /**
   5089    * ### .instanceOf(object, constructor, [message])
   5090    *
   5091    * Asserts that `value` is an instance of `constructor`.
   5092    *
   5093    *     var Tea = function (name) { this.name = name; }
   5094    *       , chai = new Tea('chai');
   5095    *
   5096    *     assert.instanceOf(chai, Tea, 'chai is an instance of tea');
   5097    *
   5098    * @name instanceOf
   5099    * @param {Object} object
   5100    * @param {Constructor} constructor
   5101    * @param {String} message
   5102    * @namespace Assert
   5103    * @api public
   5104    */
   5105 
   5106   assert.instanceOf = function (val, type, msg) {
   5107     new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type);
   5108   };
   5109 
   5110   /**
   5111    * ### .notInstanceOf(object, constructor, [message])
   5112    *
   5113    * Asserts `value` is not an instance of `constructor`.
   5114    *
   5115    *     var Tea = function (name) { this.name = name; }
   5116    *       , chai = new String('chai');
   5117    *
   5118    *     assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');
   5119    *
   5120    * @name notInstanceOf
   5121    * @param {Object} object
   5122    * @param {Constructor} constructor
   5123    * @param {String} message
   5124    * @namespace Assert
   5125    * @api public
   5126    */
   5127 
   5128   assert.notInstanceOf = function (val, type, msg) {
   5129     new Assertion(val, msg, assert.notInstanceOf, true)
   5130       .to.not.be.instanceOf(type);
   5131   };
   5132 
   5133   /**
   5134    * ### .include(haystack, needle, [message])
   5135    *
   5136    * Asserts that `haystack` includes `needle`. Can be used to assert the
   5137    * inclusion of a value in an array, a substring in a string, or a subset of
   5138    * properties in an object.
   5139    *
   5140    *     assert.include([1,2,3], 2, 'array contains value');
   5141    *     assert.include('foobar', 'foo', 'string contains substring');
   5142    *     assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property');
   5143    *
   5144    * Strict equality (===) is used. When asserting the inclusion of a value in
   5145    * an array, the array is searched for an element that's strictly equal to the
   5146    * given value. When asserting a subset of properties in an object, the object
   5147    * is searched for the given property keys, checking that each one is present
   5148    * and strictly equal to the given property value. For instance:
   5149    *
   5150    *     var obj1 = {a: 1}
   5151    *       , obj2 = {b: 2};
   5152    *     assert.include([obj1, obj2], obj1);
   5153    *     assert.include({foo: obj1, bar: obj2}, {foo: obj1});
   5154    *     assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2});
   5155    *
   5156    * @name include
   5157    * @param {Array|String} haystack
   5158    * @param {Mixed} needle
   5159    * @param {String} message
   5160    * @namespace Assert
   5161    * @api public
   5162    */
   5163 
   5164   assert.include = function (exp, inc, msg) {
   5165     new Assertion(exp, msg, assert.include, true).include(inc);
   5166   };
   5167 
   5168   /**
   5169    * ### .notInclude(haystack, needle, [message])
   5170    *
   5171    * Asserts that `haystack` does not include `needle`. Can be used to assert
   5172    * the absence of a value in an array, a substring in a string, or a subset of
   5173    * properties in an object.
   5174    *
   5175    *     assert.notInclude([1,2,3], 4, "array doesn't contain value");
   5176    *     assert.notInclude('foobar', 'baz', "string doesn't contain substring");
   5177    *     assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property');
   5178    *
   5179    * Strict equality (===) is used. When asserting the absence of a value in an
   5180    * array, the array is searched to confirm the absence of an element that's
   5181    * strictly equal to the given value. When asserting a subset of properties in
   5182    * an object, the object is searched to confirm that at least one of the given
   5183    * property keys is either not present or not strictly equal to the given
   5184    * property value. For instance:
   5185    *
   5186    *     var obj1 = {a: 1}
   5187    *       , obj2 = {b: 2};
   5188    *     assert.notInclude([obj1, obj2], {a: 1});
   5189    *     assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}});
   5190    *     assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}});
   5191    *
   5192    * @name notInclude
   5193    * @param {Array|String} haystack
   5194    * @param {Mixed} needle
   5195    * @param {String} message
   5196    * @namespace Assert
   5197    * @api public
   5198    */
   5199 
   5200   assert.notInclude = function (exp, inc, msg) {
   5201     new Assertion(exp, msg, assert.notInclude, true).not.include(inc);
   5202   };
   5203 
   5204   /**
   5205    * ### .deepInclude(haystack, needle, [message])
   5206    *
   5207    * Asserts that `haystack` includes `needle`. Can be used to assert the
   5208    * inclusion of a value in an array or a subset of properties in an object.
   5209    * Deep equality is used.
   5210    *
   5211    *     var obj1 = {a: 1}
   5212    *       , obj2 = {b: 2};
   5213    *     assert.deepInclude([obj1, obj2], {a: 1});
   5214    *     assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}});
   5215    *     assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}});
   5216    *
   5217    * @name deepInclude
   5218    * @param {Array|String} haystack
   5219    * @param {Mixed} needle
   5220    * @param {String} message
   5221    * @namespace Assert
   5222    * @api public
   5223    */
   5224 
   5225   assert.deepInclude = function (exp, inc, msg) {
   5226     new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc);
   5227   };
   5228 
   5229   /**
   5230    * ### .notDeepInclude(haystack, needle, [message])
   5231    *
   5232    * Asserts that `haystack` does not include `needle`. Can be used to assert
   5233    * the absence of a value in an array or a subset of properties in an object.
   5234    * Deep equality is used.
   5235    *
   5236    *     var obj1 = {a: 1}
   5237    *       , obj2 = {b: 2};
   5238    *     assert.notDeepInclude([obj1, obj2], {a: 9});
   5239    *     assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}});
   5240    *     assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}});
   5241    *
   5242    * @name notDeepInclude
   5243    * @param {Array|String} haystack
   5244    * @param {Mixed} needle
   5245    * @param {String} message
   5246    * @namespace Assert
   5247    * @api public
   5248    */
   5249 
   5250   assert.notDeepInclude = function (exp, inc, msg) {
   5251     new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc);
   5252   };
   5253 
   5254   /**
   5255    * ### .nestedInclude(haystack, needle, [message])
   5256    *
   5257    * Asserts that 'haystack' includes 'needle'.
   5258    * Can be used to assert the inclusion of a subset of properties in an
   5259    * object.
   5260    * Enables the use of dot- and bracket-notation for referencing nested
   5261    * properties.
   5262    * '[]' and '.' in property names can be escaped using double backslashes.
   5263    *
   5264    *     assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'});
   5265    *     assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'});
   5266    *
   5267    * @name nestedInclude
   5268    * @param {Object} haystack
   5269    * @param {Object} needle
   5270    * @param {String} message
   5271    * @namespace Assert
   5272    * @api public
   5273    */
   5274 
   5275   assert.nestedInclude = function (exp, inc, msg) {
   5276     new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc);
   5277   };
   5278 
   5279   /**
   5280    * ### .notNestedInclude(haystack, needle, [message])
   5281    *
   5282    * Asserts that 'haystack' does not include 'needle'.
   5283    * Can be used to assert the absence of a subset of properties in an
   5284    * object.
   5285    * Enables the use of dot- and bracket-notation for referencing nested
   5286    * properties.
   5287    * '[]' and '.' in property names can be escaped using double backslashes.
   5288    *
   5289    *     assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'});
   5290    *     assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'});
   5291    *
   5292    * @name notNestedInclude
   5293    * @param {Object} haystack
   5294    * @param {Object} needle
   5295    * @param {String} message
   5296    * @namespace Assert
   5297    * @api public
   5298    */
   5299 
   5300   assert.notNestedInclude = function (exp, inc, msg) {
   5301     new Assertion(exp, msg, assert.notNestedInclude, true)
   5302       .not.nested.include(inc);
   5303   };
   5304 
   5305   /**
   5306    * ### .deepNestedInclude(haystack, needle, [message])
   5307    *
   5308    * Asserts that 'haystack' includes 'needle'.
   5309    * Can be used to assert the inclusion of a subset of properties in an
   5310    * object while checking for deep equality.
   5311    * Enables the use of dot- and bracket-notation for referencing nested
   5312    * properties.
   5313    * '[]' and '.' in property names can be escaped using double backslashes.
   5314    *
   5315    *     assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}});
   5316    *     assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}});
   5317    *
   5318    * @name deepNestedInclude
   5319    * @param {Object} haystack
   5320    * @param {Object} needle
   5321    * @param {String} message
   5322    * @namespace Assert
   5323    * @api public
   5324    */
   5325 
   5326   assert.deepNestedInclude = function(exp, inc, msg) {
   5327     new Assertion(exp, msg, assert.deepNestedInclude, true)
   5328       .deep.nested.include(inc);
   5329   };
   5330 
   5331   /**
   5332    * ### .notDeepNestedInclude(haystack, needle, [message])
   5333    *
   5334    * Asserts that 'haystack' does not include 'needle'.
   5335    * Can be used to assert the absence of a subset of properties in an
   5336    * object while checking for deep equality.
   5337    * Enables the use of dot- and bracket-notation for referencing nested
   5338    * properties.
   5339    * '[]' and '.' in property names can be escaped using double backslashes.
   5340    *
   5341    *     assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}})
   5342    *     assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}});
   5343    *
   5344    * @name notDeepNestedInclude
   5345    * @param {Object} haystack
   5346    * @param {Object} needle
   5347    * @param {String} message
   5348    * @namespace Assert
   5349    * @api public
   5350    */
   5351 
   5352   assert.notDeepNestedInclude = function(exp, inc, msg) {
   5353     new Assertion(exp, msg, assert.notDeepNestedInclude, true)
   5354       .not.deep.nested.include(inc);
   5355   };
   5356 
   5357   /**
   5358    * ### .ownInclude(haystack, needle, [message])
   5359    *
   5360    * Asserts that 'haystack' includes 'needle'.
   5361    * Can be used to assert the inclusion of a subset of properties in an
   5362    * object while ignoring inherited properties.
   5363    *
   5364    *     assert.ownInclude({ a: 1 }, { a: 1 });
   5365    *
   5366    * @name ownInclude
   5367    * @param {Object} haystack
   5368    * @param {Object} needle
   5369    * @param {String} message
   5370    * @namespace Assert
   5371    * @api public
   5372    */
   5373 
   5374   assert.ownInclude = function(exp, inc, msg) {
   5375     new Assertion(exp, msg, assert.ownInclude, true).own.include(inc);
   5376   };
   5377 
   5378   /**
   5379    * ### .notOwnInclude(haystack, needle, [message])
   5380    *
   5381    * Asserts that 'haystack' includes 'needle'.
   5382    * Can be used to assert the absence of a subset of properties in an
   5383    * object while ignoring inherited properties.
   5384    *
   5385    *     Object.prototype.b = 2;
   5386    *
   5387    *     assert.notOwnInclude({ a: 1 }, { b: 2 });
   5388    *
   5389    * @name notOwnInclude
   5390    * @param {Object} haystack
   5391    * @param {Object} needle
   5392    * @param {String} message
   5393    * @namespace Assert
   5394    * @api public
   5395    */
   5396 
   5397   assert.notOwnInclude = function(exp, inc, msg) {
   5398     new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc);
   5399   };
   5400 
   5401   /**
   5402    * ### .deepOwnInclude(haystack, needle, [message])
   5403    *
   5404    * Asserts that 'haystack' includes 'needle'.
   5405    * Can be used to assert the inclusion of a subset of properties in an
   5406    * object while ignoring inherited properties and checking for deep equality.
   5407    *
   5408    *      assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}});
   5409    *
   5410    * @name deepOwnInclude
   5411    * @param {Object} haystack
   5412    * @param {Object} needle
   5413    * @param {String} message
   5414    * @namespace Assert
   5415    * @api public
   5416    */
   5417 
   5418   assert.deepOwnInclude = function(exp, inc, msg) {
   5419     new Assertion(exp, msg, assert.deepOwnInclude, true)
   5420       .deep.own.include(inc);
   5421   };
   5422 
   5423    /**
   5424    * ### .notDeepOwnInclude(haystack, needle, [message])
   5425    *
   5426    * Asserts that 'haystack' includes 'needle'.
   5427    * Can be used to assert the absence of a subset of properties in an
   5428    * object while ignoring inherited properties and checking for deep equality.
   5429    *
   5430    *      assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}});
   5431    *
   5432    * @name notDeepOwnInclude
   5433    * @param {Object} haystack
   5434    * @param {Object} needle
   5435    * @param {String} message
   5436    * @namespace Assert
   5437    * @api public
   5438    */
   5439 
   5440   assert.notDeepOwnInclude = function(exp, inc, msg) {
   5441     new Assertion(exp, msg, assert.notDeepOwnInclude, true)
   5442       .not.deep.own.include(inc);
   5443   };
   5444 
   5445   /**
   5446    * ### .match(value, regexp, [message])
   5447    *
   5448    * Asserts that `value` matches the regular expression `regexp`.
   5449    *
   5450    *     assert.match('foobar', /^foo/, 'regexp matches');
   5451    *
   5452    * @name match
   5453    * @param {Mixed} value
   5454    * @param {RegExp} regexp
   5455    * @param {String} message
   5456    * @namespace Assert
   5457    * @api public
   5458    */
   5459 
   5460   assert.match = function (exp, re, msg) {
   5461     new Assertion(exp, msg, assert.match, true).to.match(re);
   5462   };
   5463 
   5464   /**
   5465    * ### .notMatch(value, regexp, [message])
   5466    *
   5467    * Asserts that `value` does not match the regular expression `regexp`.
   5468    *
   5469    *     assert.notMatch('foobar', /^foo/, 'regexp does not match');
   5470    *
   5471    * @name notMatch
   5472    * @param {Mixed} value
   5473    * @param {RegExp} regexp
   5474    * @param {String} message
   5475    * @namespace Assert
   5476    * @api public
   5477    */
   5478 
   5479   assert.notMatch = function (exp, re, msg) {
   5480     new Assertion(exp, msg, assert.notMatch, true).to.not.match(re);
   5481   };
   5482 
   5483   /**
   5484    * ### .property(object, property, [message])
   5485    *
   5486    * Asserts that `object` has a direct or inherited property named by
   5487    * `property`.
   5488    *
   5489    *     assert.property({ tea: { green: 'matcha' }}, 'tea');
   5490    *     assert.property({ tea: { green: 'matcha' }}, 'toString');
   5491    *
   5492    * @name property
   5493    * @param {Object} object
   5494    * @param {String} property
   5495    * @param {String} message
   5496    * @namespace Assert
   5497    * @api public
   5498    */
   5499 
   5500   assert.property = function (obj, prop, msg) {
   5501     new Assertion(obj, msg, assert.property, true).to.have.property(prop);
   5502   };
   5503 
   5504   /**
   5505    * ### .notProperty(object, property, [message])
   5506    *
   5507    * Asserts that `object` does _not_ have a direct or inherited property named
   5508    * by `property`.
   5509    *
   5510    *     assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');
   5511    *
   5512    * @name notProperty
   5513    * @param {Object} object
   5514    * @param {String} property
   5515    * @param {String} message
   5516    * @namespace Assert
   5517    * @api public
   5518    */
   5519 
   5520   assert.notProperty = function (obj, prop, msg) {
   5521     new Assertion(obj, msg, assert.notProperty, true)
   5522       .to.not.have.property(prop);
   5523   };
   5524 
   5525   /**
   5526    * ### .propertyVal(object, property, value, [message])
   5527    *
   5528    * Asserts that `object` has a direct or inherited property named by
   5529    * `property` with a value given by `value`. Uses a strict equality check
   5530    * (===).
   5531    *
   5532    *     assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');
   5533    *
   5534    * @name propertyVal
   5535    * @param {Object} object
   5536    * @param {String} property
   5537    * @param {Mixed} value
   5538    * @param {String} message
   5539    * @namespace Assert
   5540    * @api public
   5541    */
   5542 
   5543   assert.propertyVal = function (obj, prop, val, msg) {
   5544     new Assertion(obj, msg, assert.propertyVal, true)
   5545       .to.have.property(prop, val);
   5546   };
   5547 
   5548   /**
   5549    * ### .notPropertyVal(object, property, value, [message])
   5550    *
   5551    * Asserts that `object` does _not_ have a direct or inherited property named
   5552    * by `property` with value given by `value`. Uses a strict equality check
   5553    * (===).
   5554    *
   5555    *     assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad');
   5556    *     assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good');
   5557    *
   5558    * @name notPropertyVal
   5559    * @param {Object} object
   5560    * @param {String} property
   5561    * @param {Mixed} value
   5562    * @param {String} message
   5563    * @namespace Assert
   5564    * @api public
   5565    */
   5566 
   5567   assert.notPropertyVal = function (obj, prop, val, msg) {
   5568     new Assertion(obj, msg, assert.notPropertyVal, true)
   5569       .to.not.have.property(prop, val);
   5570   };
   5571 
   5572   /**
   5573    * ### .deepPropertyVal(object, property, value, [message])
   5574    *
   5575    * Asserts that `object` has a direct or inherited property named by
   5576    * `property` with a value given by `value`. Uses a deep equality check.
   5577    *
   5578    *     assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' });
   5579    *
   5580    * @name deepPropertyVal
   5581    * @param {Object} object
   5582    * @param {String} property
   5583    * @param {Mixed} value
   5584    * @param {String} message
   5585    * @namespace Assert
   5586    * @api public
   5587    */
   5588 
   5589   assert.deepPropertyVal = function (obj, prop, val, msg) {
   5590     new Assertion(obj, msg, assert.deepPropertyVal, true)
   5591       .to.have.deep.property(prop, val);
   5592   };
   5593 
   5594   /**
   5595    * ### .notDeepPropertyVal(object, property, value, [message])
   5596    *
   5597    * Asserts that `object` does _not_ have a direct or inherited property named
   5598    * by `property` with value given by `value`. Uses a deep equality check.
   5599    *
   5600    *     assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' });
   5601    *     assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' });
   5602    *     assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' });
   5603    *
   5604    * @name notDeepPropertyVal
   5605    * @param {Object} object
   5606    * @param {String} property
   5607    * @param {Mixed} value
   5608    * @param {String} message
   5609    * @namespace Assert
   5610    * @api public
   5611    */
   5612 
   5613   assert.notDeepPropertyVal = function (obj, prop, val, msg) {
   5614     new Assertion(obj, msg, assert.notDeepPropertyVal, true)
   5615       .to.not.have.deep.property(prop, val);
   5616   };
   5617 
   5618   /**
   5619    * ### .ownProperty(object, property, [message])
   5620    *
   5621    * Asserts that `object` has a direct property named by `property`. Inherited
   5622    * properties aren't checked.
   5623    *
   5624    *     assert.ownProperty({ tea: { green: 'matcha' }}, 'tea');
   5625    *
   5626    * @name ownProperty
   5627    * @param {Object} object
   5628    * @param {String} property
   5629    * @param {String} message
   5630    * @api public
   5631    */
   5632 
   5633   assert.ownProperty = function (obj, prop, msg) {
   5634     new Assertion(obj, msg, assert.ownProperty, true)
   5635       .to.have.own.property(prop);
   5636   };
   5637 
   5638   /**
   5639    * ### .notOwnProperty(object, property, [message])
   5640    *
   5641    * Asserts that `object` does _not_ have a direct property named by
   5642    * `property`. Inherited properties aren't checked.
   5643    *
   5644    *     assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee');
   5645    *     assert.notOwnProperty({}, 'toString');
   5646    *
   5647    * @name notOwnProperty
   5648    * @param {Object} object
   5649    * @param {String} property
   5650    * @param {String} message
   5651    * @api public
   5652    */
   5653 
   5654   assert.notOwnProperty = function (obj, prop, msg) {
   5655     new Assertion(obj, msg, assert.notOwnProperty, true)
   5656       .to.not.have.own.property(prop);
   5657   };
   5658 
   5659   /**
   5660    * ### .ownPropertyVal(object, property, value, [message])
   5661    *
   5662    * Asserts that `object` has a direct property named by `property` and a value
   5663    * equal to the provided `value`. Uses a strict equality check (===).
   5664    * Inherited properties aren't checked.
   5665    *
   5666    *     assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good');
   5667    *
   5668    * @name ownPropertyVal
   5669    * @param {Object} object
   5670    * @param {String} property
   5671    * @param {Mixed} value
   5672    * @param {String} message
   5673    * @api public
   5674    */
   5675 
   5676   assert.ownPropertyVal = function (obj, prop, value, msg) {
   5677     new Assertion(obj, msg, assert.ownPropertyVal, true)
   5678       .to.have.own.property(prop, value);
   5679   };
   5680 
   5681   /**
   5682    * ### .notOwnPropertyVal(object, property, value, [message])
   5683    *
   5684    * Asserts that `object` does _not_ have a direct property named by `property`
   5685    * with a value equal to the provided `value`. Uses a strict equality check
   5686    * (===). Inherited properties aren't checked.
   5687    *
   5688    *     assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse');
   5689    *     assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString);
   5690    *
   5691    * @name notOwnPropertyVal
   5692    * @param {Object} object
   5693    * @param {String} property
   5694    * @param {Mixed} value
   5695    * @param {String} message
   5696    * @api public
   5697    */
   5698 
   5699   assert.notOwnPropertyVal = function (obj, prop, value, msg) {
   5700     new Assertion(obj, msg, assert.notOwnPropertyVal, true)
   5701       .to.not.have.own.property(prop, value);
   5702   };
   5703 
   5704   /**
   5705    * ### .deepOwnPropertyVal(object, property, value, [message])
   5706    *
   5707    * Asserts that `object` has a direct property named by `property` and a value
   5708    * equal to the provided `value`. Uses a deep equality check. Inherited
   5709    * properties aren't checked.
   5710    *
   5711    *     assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' });
   5712    *
   5713    * @name deepOwnPropertyVal
   5714    * @param {Object} object
   5715    * @param {String} property
   5716    * @param {Mixed} value
   5717    * @param {String} message
   5718    * @api public
   5719    */
   5720 
   5721   assert.deepOwnPropertyVal = function (obj, prop, value, msg) {
   5722     new Assertion(obj, msg, assert.deepOwnPropertyVal, true)
   5723       .to.have.deep.own.property(prop, value);
   5724   };
   5725 
   5726   /**
   5727    * ### .notDeepOwnPropertyVal(object, property, value, [message])
   5728    *
   5729    * Asserts that `object` does _not_ have a direct property named by `property`
   5730    * with a value equal to the provided `value`. Uses a deep equality check.
   5731    * Inherited properties aren't checked.
   5732    *
   5733    *     assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' });
   5734    *     assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' });
   5735    *     assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' });
   5736    *     assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString);
   5737    *
   5738    * @name notDeepOwnPropertyVal
   5739    * @param {Object} object
   5740    * @param {String} property
   5741    * @param {Mixed} value
   5742    * @param {String} message
   5743    * @api public
   5744    */
   5745 
   5746   assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) {
   5747     new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true)
   5748       .to.not.have.deep.own.property(prop, value);
   5749   };
   5750 
   5751   /**
   5752    * ### .nestedProperty(object, property, [message])
   5753    *
   5754    * Asserts that `object` has a direct or inherited property named by
   5755    * `property`, which can be a string using dot- and bracket-notation for
   5756    * nested reference.
   5757    *
   5758    *     assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green');
   5759    *
   5760    * @name nestedProperty
   5761    * @param {Object} object
   5762    * @param {String} property
   5763    * @param {String} message
   5764    * @namespace Assert
   5765    * @api public
   5766    */
   5767 
   5768   assert.nestedProperty = function (obj, prop, msg) {
   5769     new Assertion(obj, msg, assert.nestedProperty, true)
   5770       .to.have.nested.property(prop);
   5771   };
   5772 
   5773   /**
   5774    * ### .notNestedProperty(object, property, [message])
   5775    *
   5776    * Asserts that `object` does _not_ have a property named by `property`, which
   5777    * can be a string using dot- and bracket-notation for nested reference. The
   5778    * property cannot exist on the object nor anywhere in its prototype chain.
   5779    *
   5780    *     assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong');
   5781    *
   5782    * @name notNestedProperty
   5783    * @param {Object} object
   5784    * @param {String} property
   5785    * @param {String} message
   5786    * @namespace Assert
   5787    * @api public
   5788    */
   5789 
   5790   assert.notNestedProperty = function (obj, prop, msg) {
   5791     new Assertion(obj, msg, assert.notNestedProperty, true)
   5792       .to.not.have.nested.property(prop);
   5793   };
   5794 
   5795   /**
   5796    * ### .nestedPropertyVal(object, property, value, [message])
   5797    *
   5798    * Asserts that `object` has a property named by `property` with value given
   5799    * by `value`. `property` can use dot- and bracket-notation for nested
   5800    * reference. Uses a strict equality check (===).
   5801    *
   5802    *     assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');
   5803    *
   5804    * @name nestedPropertyVal
   5805    * @param {Object} object
   5806    * @param {String} property
   5807    * @param {Mixed} value
   5808    * @param {String} message
   5809    * @namespace Assert
   5810    * @api public
   5811    */
   5812 
   5813   assert.nestedPropertyVal = function (obj, prop, val, msg) {
   5814     new Assertion(obj, msg, assert.nestedPropertyVal, true)
   5815       .to.have.nested.property(prop, val);
   5816   };
   5817 
   5818   /**
   5819    * ### .notNestedPropertyVal(object, property, value, [message])
   5820    *
   5821    * Asserts that `object` does _not_ have a property named by `property` with
   5822    * value given by `value`. `property` can use dot- and bracket-notation for
   5823    * nested reference. Uses a strict equality check (===).
   5824    *
   5825    *     assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');
   5826    *     assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha');
   5827    *
   5828    * @name notNestedPropertyVal
   5829    * @param {Object} object
   5830    * @param {String} property
   5831    * @param {Mixed} value
   5832    * @param {String} message
   5833    * @namespace Assert
   5834    * @api public
   5835    */
   5836 
   5837   assert.notNestedPropertyVal = function (obj, prop, val, msg) {
   5838     new Assertion(obj, msg, assert.notNestedPropertyVal, true)
   5839       .to.not.have.nested.property(prop, val);
   5840   };
   5841 
   5842   /**
   5843    * ### .deepNestedPropertyVal(object, property, value, [message])
   5844    *
   5845    * Asserts that `object` has a property named by `property` with a value given
   5846    * by `value`. `property` can use dot- and bracket-notation for nested
   5847    * reference. Uses a deep equality check.
   5848    *
   5849    *     assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' });
   5850    *
   5851    * @name deepNestedPropertyVal
   5852    * @param {Object} object
   5853    * @param {String} property
   5854    * @param {Mixed} value
   5855    * @param {String} message
   5856    * @namespace Assert
   5857    * @api public
   5858    */
   5859 
   5860   assert.deepNestedPropertyVal = function (obj, prop, val, msg) {
   5861     new Assertion(obj, msg, assert.deepNestedPropertyVal, true)
   5862       .to.have.deep.nested.property(prop, val);
   5863   };
   5864 
   5865   /**
   5866    * ### .notDeepNestedPropertyVal(object, property, value, [message])
   5867    *
   5868    * Asserts that `object` does _not_ have a property named by `property` with
   5869    * value given by `value`. `property` can use dot- and bracket-notation for
   5870    * nested reference. Uses a deep equality check.
   5871    *
   5872    *     assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' });
   5873    *     assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' });
   5874    *     assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' });
   5875    *
   5876    * @name notDeepNestedPropertyVal
   5877    * @param {Object} object
   5878    * @param {String} property
   5879    * @param {Mixed} value
   5880    * @param {String} message
   5881    * @namespace Assert
   5882    * @api public
   5883    */
   5884 
   5885   assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) {
   5886     new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true)
   5887       .to.not.have.deep.nested.property(prop, val);
   5888   }
   5889 
   5890   /**
   5891    * ### .lengthOf(object, length, [message])
   5892    *
   5893    * Asserts that `object` has a `length` or `size` with the expected value.
   5894    *
   5895    *     assert.lengthOf([1,2,3], 3, 'array has length of 3');
   5896    *     assert.lengthOf('foobar', 6, 'string has length of 6');
   5897    *     assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3');
   5898    *     assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3');
   5899    *
   5900    * @name lengthOf
   5901    * @param {Mixed} object
   5902    * @param {Number} length
   5903    * @param {String} message
   5904    * @namespace Assert
   5905    * @api public
   5906    */
   5907 
   5908   assert.lengthOf = function (exp, len, msg) {
   5909     new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len);
   5910   };
   5911 
   5912   /**
   5913    * ### .hasAnyKeys(object, [keys], [message])
   5914    *
   5915    * Asserts that `object` has at least one of the `keys` provided.
   5916    * You can also provide a single object instead of a `keys` array and its keys
   5917    * will be used as the expected set of keys.
   5918    *
   5919    *     assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']);
   5920    *     assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337});
   5921    *     assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
   5922    *     assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']);
   5923    *
   5924    * @name hasAnyKeys
   5925    * @param {Mixed} object
   5926    * @param {Array|Object} keys
   5927    * @param {String} message
   5928    * @namespace Assert
   5929    * @api public
   5930    */
   5931 
   5932   assert.hasAnyKeys = function (obj, keys, msg) {
   5933     new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys);
   5934   }
   5935 
   5936   /**
   5937    * ### .hasAllKeys(object, [keys], [message])
   5938    *
   5939    * Asserts that `object` has all and only all of the `keys` provided.
   5940    * You can also provide a single object instead of a `keys` array and its keys
   5941    * will be used as the expected set of keys.
   5942    *
   5943    *     assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']);
   5944    *     assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]);
   5945    *     assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
   5946    *     assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']);
   5947    *
   5948    * @name hasAllKeys
   5949    * @param {Mixed} object
   5950    * @param {String[]} keys
   5951    * @param {String} message
   5952    * @namespace Assert
   5953    * @api public
   5954    */
   5955 
   5956   assert.hasAllKeys = function (obj, keys, msg) {
   5957     new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys);
   5958   }
   5959 
   5960   /**
   5961    * ### .containsAllKeys(object, [keys], [message])
   5962    *
   5963    * Asserts that `object` has all of the `keys` provided but may have more keys not listed.
   5964    * You can also provide a single object instead of a `keys` array and its keys
   5965    * will be used as the expected set of keys.
   5966    *
   5967    *     assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']);
   5968    *     assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']);
   5969    *     assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337});
   5970    *     assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337});
   5971    *     assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]);
   5972    *     assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
   5973    *     assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]);
   5974    *     assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']);
   5975    *
   5976    * @name containsAllKeys
   5977    * @param {Mixed} object
   5978    * @param {String[]} keys
   5979    * @param {String} message
   5980    * @namespace Assert
   5981    * @api public
   5982    */
   5983 
   5984   assert.containsAllKeys = function (obj, keys, msg) {
   5985     new Assertion(obj, msg, assert.containsAllKeys, true)
   5986       .to.contain.all.keys(keys);
   5987   }
   5988 
   5989   /**
   5990    * ### .doesNotHaveAnyKeys(object, [keys], [message])
   5991    *
   5992    * Asserts that `object` has none of the `keys` provided.
   5993    * You can also provide a single object instead of a `keys` array and its keys
   5994    * will be used as the expected set of keys.
   5995    *
   5996    *     assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']);
   5997    *     assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'});
   5998    *     assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']);
   5999    *     assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']);
   6000    *
   6001    * @name doesNotHaveAnyKeys
   6002    * @param {Mixed} object
   6003    * @param {String[]} keys
   6004    * @param {String} message
   6005    * @namespace Assert
   6006    * @api public
   6007    */
   6008 
   6009   assert.doesNotHaveAnyKeys = function (obj, keys, msg) {
   6010     new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true)
   6011       .to.not.have.any.keys(keys);
   6012   }
   6013 
   6014   /**
   6015    * ### .doesNotHaveAllKeys(object, [keys], [message])
   6016    *
   6017    * Asserts that `object` does not have at least one of the `keys` provided.
   6018    * You can also provide a single object instead of a `keys` array and its keys
   6019    * will be used as the expected set of keys.
   6020    *
   6021    *     assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']);
   6022    *     assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'});
   6023    *     assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']);
   6024    *     assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']);
   6025    *
   6026    * @name doesNotHaveAllKeys
   6027    * @param {Mixed} object
   6028    * @param {String[]} keys
   6029    * @param {String} message
   6030    * @namespace Assert
   6031    * @api public
   6032    */
   6033 
   6034   assert.doesNotHaveAllKeys = function (obj, keys, msg) {
   6035     new Assertion(obj, msg, assert.doesNotHaveAllKeys, true)
   6036       .to.not.have.all.keys(keys);
   6037   }
   6038 
   6039   /**
   6040    * ### .hasAnyDeepKeys(object, [keys], [message])
   6041    *
   6042    * Asserts that `object` has at least one of the `keys` provided.
   6043    * Since Sets and Maps can have objects as keys you can use this assertion to perform
   6044    * a deep comparison.
   6045    * You can also provide a single object instead of a `keys` array and its keys
   6046    * will be used as the expected set of keys.
   6047    *
   6048    *     assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'});
   6049    *     assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]);
   6050    *     assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
   6051    *     assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'});
   6052    *     assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]);
   6053    *     assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
   6054    *
   6055    * @name hasAnyDeepKeys
   6056    * @param {Mixed} object
   6057    * @param {Array|Object} keys
   6058    * @param {String} message
   6059    * @namespace Assert
   6060    * @api public
   6061    */
   6062 
   6063   assert.hasAnyDeepKeys = function (obj, keys, msg) {
   6064     new Assertion(obj, msg, assert.hasAnyDeepKeys, true)
   6065       .to.have.any.deep.keys(keys);
   6066   }
   6067 
   6068  /**
   6069    * ### .hasAllDeepKeys(object, [keys], [message])
   6070    *
   6071    * Asserts that `object` has all and only all of the `keys` provided.
   6072    * Since Sets and Maps can have objects as keys you can use this assertion to perform
   6073    * a deep comparison.
   6074    * You can also provide a single object instead of a `keys` array and its keys
   6075    * will be used as the expected set of keys.
   6076    *
   6077    *     assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'});
   6078    *     assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
   6079    *     assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'});
   6080    *     assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
   6081    *
   6082    * @name hasAllDeepKeys
   6083    * @param {Mixed} object
   6084    * @param {Array|Object} keys
   6085    * @param {String} message
   6086    * @namespace Assert
   6087    * @api public
   6088    */
   6089 
   6090   assert.hasAllDeepKeys = function (obj, keys, msg) {
   6091     new Assertion(obj, msg, assert.hasAllDeepKeys, true)
   6092       .to.have.all.deep.keys(keys);
   6093   }
   6094 
   6095  /**
   6096    * ### .containsAllDeepKeys(object, [keys], [message])
   6097    *
   6098    * Asserts that `object` contains all of the `keys` provided.
   6099    * Since Sets and Maps can have objects as keys you can use this assertion to perform
   6100    * a deep comparison.
   6101    * You can also provide a single object instead of a `keys` array and its keys
   6102    * will be used as the expected set of keys.
   6103    *
   6104    *     assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'});
   6105    *     assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
   6106    *     assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'});
   6107    *     assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
   6108    *
   6109    * @name containsAllDeepKeys
   6110    * @param {Mixed} object
   6111    * @param {Array|Object} keys
   6112    * @param {String} message
   6113    * @namespace Assert
   6114    * @api public
   6115    */
   6116 
   6117   assert.containsAllDeepKeys = function (obj, keys, msg) {
   6118     new Assertion(obj, msg, assert.containsAllDeepKeys, true)
   6119       .to.contain.all.deep.keys(keys);
   6120   }
   6121 
   6122  /**
   6123    * ### .doesNotHaveAnyDeepKeys(object, [keys], [message])
   6124    *
   6125    * Asserts that `object` has none of the `keys` provided.
   6126    * Since Sets and Maps can have objects as keys you can use this assertion to perform
   6127    * a deep comparison.
   6128    * You can also provide a single object instead of a `keys` array and its keys
   6129    * will be used as the expected set of keys.
   6130    *
   6131    *     assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'});
   6132    *     assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]);
   6133    *     assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'});
   6134    *     assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]);
   6135    *
   6136    * @name doesNotHaveAnyDeepKeys
   6137    * @param {Mixed} object
   6138    * @param {Array|Object} keys
   6139    * @param {String} message
   6140    * @namespace Assert
   6141    * @api public
   6142    */
   6143 
   6144   assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) {
   6145     new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true)
   6146       .to.not.have.any.deep.keys(keys);
   6147   }
   6148 
   6149  /**
   6150    * ### .doesNotHaveAllDeepKeys(object, [keys], [message])
   6151    *
   6152    * Asserts that `object` does not have at least one of the `keys` provided.
   6153    * Since Sets and Maps can have objects as keys you can use this assertion to perform
   6154    * a deep comparison.
   6155    * You can also provide a single object instead of a `keys` array and its keys
   6156    * will be used as the expected set of keys.
   6157    *
   6158    *     assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'});
   6159    *     assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]);
   6160    *     assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'});
   6161    *     assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]);
   6162    *
   6163    * @name doesNotHaveAllDeepKeys
   6164    * @param {Mixed} object
   6165    * @param {Array|Object} keys
   6166    * @param {String} message
   6167    * @namespace Assert
   6168    * @api public
   6169    */
   6170 
   6171   assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) {
   6172     new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true)
   6173       .to.not.have.all.deep.keys(keys);
   6174   }
   6175 
   6176  /**
   6177    * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message])
   6178    *
   6179    * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an
   6180    * instance of `errorLike`.
   6181    * If `errorLike` is an `Error` instance, asserts that the error thrown is the same
   6182    * instance as `errorLike`.
   6183    * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a
   6184    * message matching `errMsgMatcher`.
   6185    *
   6186    *     assert.throws(fn, 'Error thrown must have this msg');
   6187    *     assert.throws(fn, /Error thrown must have a msg that matches this/);
   6188    *     assert.throws(fn, ReferenceError);
   6189    *     assert.throws(fn, errorInstance);
   6190    *     assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg');
   6191    *     assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg');
   6192    *     assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/);
   6193    *     assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/);
   6194    *
   6195    * @name throws
   6196    * @alias throw
   6197    * @alias Throw
   6198    * @param {Function} fn
   6199    * @param {ErrorConstructor|Error} errorLike
   6200    * @param {RegExp|String} errMsgMatcher
   6201    * @param {String} message
   6202    * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
   6203    * @namespace Assert
   6204    * @api public
   6205    */
   6206 
   6207   assert.throws = function (fn, errorLike, errMsgMatcher, msg) {
   6208     if ('string' === typeof errorLike || errorLike instanceof RegExp) {
   6209       errMsgMatcher = errorLike;
   6210       errorLike = null;
   6211     }
   6212 
   6213     var assertErr = new Assertion(fn, msg, assert.throws, true)
   6214       .to.throw(errorLike, errMsgMatcher);
   6215     return flag(assertErr, 'object');
   6216   };
   6217 
   6218   /**
   6219    * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message])
   6220    *
   6221    * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an
   6222    * instance of `errorLike`.
   6223    * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same
   6224    * instance as `errorLike`.
   6225    * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a
   6226    * message matching `errMsgMatcher`.
   6227    *
   6228    *     assert.doesNotThrow(fn, 'Any Error thrown must not have this message');
   6229    *     assert.doesNotThrow(fn, /Any Error thrown must not match this/);
   6230    *     assert.doesNotThrow(fn, Error);
   6231    *     assert.doesNotThrow(fn, errorInstance);
   6232    *     assert.doesNotThrow(fn, Error, 'Error must not have this message');
   6233    *     assert.doesNotThrow(fn, errorInstance, 'Error must not have this message');
   6234    *     assert.doesNotThrow(fn, Error, /Error must not match this/);
   6235    *     assert.doesNotThrow(fn, errorInstance, /Error must not match this/);
   6236    *
   6237    * @name doesNotThrow
   6238    * @param {Function} fn
   6239    * @param {ErrorConstructor} errorLike
   6240    * @param {RegExp|String} errMsgMatcher
   6241    * @param {String} message
   6242    * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
   6243    * @namespace Assert
   6244    * @api public
   6245    */
   6246 
   6247   assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) {
   6248     if ('string' === typeof errorLike || errorLike instanceof RegExp) {
   6249       errMsgMatcher = errorLike;
   6250       errorLike = null;
   6251     }
   6252 
   6253     new Assertion(fn, msg, assert.doesNotThrow, true)
   6254       .to.not.throw(errorLike, errMsgMatcher);
   6255   };
   6256 
   6257   /**
   6258    * ### .operator(val1, operator, val2, [message])
   6259    *
   6260    * Compares two values using `operator`.
   6261    *
   6262    *     assert.operator(1, '<', 2, 'everything is ok');
   6263    *     assert.operator(1, '>', 2, 'this will fail');
   6264    *
   6265    * @name operator
   6266    * @param {Mixed} val1
   6267    * @param {String} operator
   6268    * @param {Mixed} val2
   6269    * @param {String} message
   6270    * @namespace Assert
   6271    * @api public
   6272    */
   6273 
   6274   assert.operator = function (val, operator, val2, msg) {
   6275     var ok;
   6276     switch(operator) {
   6277       case '==':
   6278         ok = val == val2;
   6279         break;
   6280       case '===':
   6281         ok = val === val2;
   6282         break;
   6283       case '>':
   6284         ok = val > val2;
   6285         break;
   6286       case '>=':
   6287         ok = val >= val2;
   6288         break;
   6289       case '<':
   6290         ok = val < val2;
   6291         break;
   6292       case '<=':
   6293         ok = val <= val2;
   6294         break;
   6295       case '!=':
   6296         ok = val != val2;
   6297         break;
   6298       case '!==':
   6299         ok = val !== val2;
   6300         break;
   6301       default:
   6302         msg = msg ? msg + ': ' : msg;
   6303         throw new chai.AssertionError(
   6304           msg + 'Invalid operator "' + operator + '"',
   6305           undefined,
   6306           assert.operator
   6307         );
   6308     }
   6309     var test = new Assertion(ok, msg, assert.operator, true);
   6310     test.assert(
   6311         true === flag(test, 'object')
   6312       , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
   6313       , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );
   6314   };
   6315 
   6316   /**
   6317    * ### .closeTo(actual, expected, delta, [message])
   6318    *
   6319    * Asserts that the target is equal `expected`, to within a +/- `delta` range.
   6320    *
   6321    *     assert.closeTo(1.5, 1, 0.5, 'numbers are close');
   6322    *
   6323    * @name closeTo
   6324    * @param {Number} actual
   6325    * @param {Number} expected
   6326    * @param {Number} delta
   6327    * @param {String} message
   6328    * @namespace Assert
   6329    * @api public
   6330    */
   6331 
   6332   assert.closeTo = function (act, exp, delta, msg) {
   6333     new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta);
   6334   };
   6335 
   6336   /**
   6337    * ### .approximately(actual, expected, delta, [message])
   6338    *
   6339    * Asserts that the target is equal `expected`, to within a +/- `delta` range.
   6340    *
   6341    *     assert.approximately(1.5, 1, 0.5, 'numbers are close');
   6342    *
   6343    * @name approximately
   6344    * @param {Number} actual
   6345    * @param {Number} expected
   6346    * @param {Number} delta
   6347    * @param {String} message
   6348    * @namespace Assert
   6349    * @api public
   6350    */
   6351 
   6352   assert.approximately = function (act, exp, delta, msg) {
   6353     new Assertion(act, msg, assert.approximately, true)
   6354       .to.be.approximately(exp, delta);
   6355   };
   6356 
   6357   /**
   6358    * ### .sameMembers(set1, set2, [message])
   6359    *
   6360    * Asserts that `set1` and `set2` have the same members in any order. Uses a
   6361    * strict equality check (===).
   6362    *
   6363    *     assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');
   6364    *
   6365    * @name sameMembers
   6366    * @param {Array} set1
   6367    * @param {Array} set2
   6368    * @param {String} message
   6369    * @namespace Assert
   6370    * @api public
   6371    */
   6372 
   6373   assert.sameMembers = function (set1, set2, msg) {
   6374     new Assertion(set1, msg, assert.sameMembers, true)
   6375       .to.have.same.members(set2);
   6376   }
   6377 
   6378   /**
   6379    * ### .notSameMembers(set1, set2, [message])
   6380    *
   6381    * Asserts that `set1` and `set2` don't have the same members in any order.
   6382    * Uses a strict equality check (===).
   6383    *
   6384    *     assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members');
   6385    *
   6386    * @name notSameMembers
   6387    * @param {Array} set1
   6388    * @param {Array} set2
   6389    * @param {String} message
   6390    * @namespace Assert
   6391    * @api public
   6392    */
   6393 
   6394   assert.notSameMembers = function (set1, set2, msg) {
   6395     new Assertion(set1, msg, assert.notSameMembers, true)
   6396       .to.not.have.same.members(set2);
   6397   }
   6398 
   6399   /**
   6400    * ### .sameDeepMembers(set1, set2, [message])
   6401    *
   6402    * Asserts that `set1` and `set2` have the same members in any order. Uses a
   6403    * deep equality check.
   6404    *
   6405    *     assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members');
   6406    *
   6407    * @name sameDeepMembers
   6408    * @param {Array} set1
   6409    * @param {Array} set2
   6410    * @param {String} message
   6411    * @namespace Assert
   6412    * @api public
   6413    */
   6414 
   6415   assert.sameDeepMembers = function (set1, set2, msg) {
   6416     new Assertion(set1, msg, assert.sameDeepMembers, true)
   6417       .to.have.same.deep.members(set2);
   6418   }
   6419 
   6420   /**
   6421    * ### .notSameDeepMembers(set1, set2, [message])
   6422    *
   6423    * Asserts that `set1` and `set2` don't have the same members in any order.
   6424    * Uses a deep equality check.
   6425    *
   6426    *     assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members');
   6427    *
   6428    * @name notSameDeepMembers
   6429    * @param {Array} set1
   6430    * @param {Array} set2
   6431    * @param {String} message
   6432    * @namespace Assert
   6433    * @api public
   6434    */
   6435 
   6436   assert.notSameDeepMembers = function (set1, set2, msg) {
   6437     new Assertion(set1, msg, assert.notSameDeepMembers, true)
   6438       .to.not.have.same.deep.members(set2);
   6439   }
   6440 
   6441   /**
   6442    * ### .sameOrderedMembers(set1, set2, [message])
   6443    *
   6444    * Asserts that `set1` and `set2` have the same members in the same order.
   6445    * Uses a strict equality check (===).
   6446    *
   6447    *     assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members');
   6448    *
   6449    * @name sameOrderedMembers
   6450    * @param {Array} set1
   6451    * @param {Array} set2
   6452    * @param {String} message
   6453    * @namespace Assert
   6454    * @api public
   6455    */
   6456 
   6457   assert.sameOrderedMembers = function (set1, set2, msg) {
   6458     new Assertion(set1, msg, assert.sameOrderedMembers, true)
   6459       .to.have.same.ordered.members(set2);
   6460   }
   6461 
   6462   /**
   6463    * ### .notSameOrderedMembers(set1, set2, [message])
   6464    *
   6465    * Asserts that `set1` and `set2` don't have the same members in the same
   6466    * order. Uses a strict equality check (===).
   6467    *
   6468    *     assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members');
   6469    *
   6470    * @name notSameOrderedMembers
   6471    * @param {Array} set1
   6472    * @param {Array} set2
   6473    * @param {String} message
   6474    * @namespace Assert
   6475    * @api public
   6476    */
   6477 
   6478   assert.notSameOrderedMembers = function (set1, set2, msg) {
   6479     new Assertion(set1, msg, assert.notSameOrderedMembers, true)
   6480       .to.not.have.same.ordered.members(set2);
   6481   }
   6482 
   6483   /**
   6484    * ### .sameDeepOrderedMembers(set1, set2, [message])
   6485    *
   6486    * Asserts that `set1` and `set2` have the same members in the same order.
   6487    * Uses a deep equality check.
   6488    *
   6489    *     assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members');
   6490    *
   6491    * @name sameDeepOrderedMembers
   6492    * @param {Array} set1
   6493    * @param {Array} set2
   6494    * @param {String} message
   6495    * @namespace Assert
   6496    * @api public
   6497    */
   6498 
   6499   assert.sameDeepOrderedMembers = function (set1, set2, msg) {
   6500     new Assertion(set1, msg, assert.sameDeepOrderedMembers, true)
   6501       .to.have.same.deep.ordered.members(set2);
   6502   }
   6503 
   6504   /**
   6505    * ### .notSameDeepOrderedMembers(set1, set2, [message])
   6506    *
   6507    * Asserts that `set1` and `set2` don't have the same members in the same
   6508    * order. Uses a deep equality check.
   6509    *
   6510    *     assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members');
   6511    *     assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members');
   6512    *
   6513    * @name notSameDeepOrderedMembers
   6514    * @param {Array} set1
   6515    * @param {Array} set2
   6516    * @param {String} message
   6517    * @namespace Assert
   6518    * @api public
   6519    */
   6520 
   6521   assert.notSameDeepOrderedMembers = function (set1, set2, msg) {
   6522     new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true)
   6523       .to.not.have.same.deep.ordered.members(set2);
   6524   }
   6525 
   6526   /**
   6527    * ### .includeMembers(superset, subset, [message])
   6528    *
   6529    * Asserts that `subset` is included in `superset` in any order. Uses a
   6530    * strict equality check (===). Duplicates are ignored.
   6531    *
   6532    *     assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members');
   6533    *
   6534    * @name includeMembers
   6535    * @param {Array} superset
   6536    * @param {Array} subset
   6537    * @param {String} message
   6538    * @namespace Assert
   6539    * @api public
   6540    */
   6541 
   6542   assert.includeMembers = function (superset, subset, msg) {
   6543     new Assertion(superset, msg, assert.includeMembers, true)
   6544       .to.include.members(subset);
   6545   }
   6546 
   6547   /**
   6548    * ### .notIncludeMembers(superset, subset, [message])
   6549    *
   6550    * Asserts that `subset` isn't included in `superset` in any order. Uses a
   6551    * strict equality check (===). Duplicates are ignored.
   6552    *
   6553    *     assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members');
   6554    *
   6555    * @name notIncludeMembers
   6556    * @param {Array} superset
   6557    * @param {Array} subset
   6558    * @param {String} message
   6559    * @namespace Assert
   6560    * @api public
   6561    */
   6562 
   6563   assert.notIncludeMembers = function (superset, subset, msg) {
   6564     new Assertion(superset, msg, assert.notIncludeMembers, true)
   6565       .to.not.include.members(subset);
   6566   }
   6567 
   6568   /**
   6569    * ### .includeDeepMembers(superset, subset, [message])
   6570    *
   6571    * Asserts that `subset` is included in `superset` in any order. Uses a deep
   6572    * equality check. Duplicates are ignored.
   6573    *
   6574    *     assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members');
   6575    *
   6576    * @name includeDeepMembers
   6577    * @param {Array} superset
   6578    * @param {Array} subset
   6579    * @param {String} message
   6580    * @namespace Assert
   6581    * @api public
   6582    */
   6583 
   6584   assert.includeDeepMembers = function (superset, subset, msg) {
   6585     new Assertion(superset, msg, assert.includeDeepMembers, true)
   6586       .to.include.deep.members(subset);
   6587   }
   6588 
   6589   /**
   6590    * ### .notIncludeDeepMembers(superset, subset, [message])
   6591    *
   6592    * Asserts that `subset` isn't included in `superset` in any order. Uses a
   6593    * deep equality check. Duplicates are ignored.
   6594    *
   6595    *     assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members');
   6596    *
   6597    * @name notIncludeDeepMembers
   6598    * @param {Array} superset
   6599    * @param {Array} subset
   6600    * @param {String} message
   6601    * @namespace Assert
   6602    * @api public
   6603    */
   6604 
   6605   assert.notIncludeDeepMembers = function (superset, subset, msg) {
   6606     new Assertion(superset, msg, assert.notIncludeDeepMembers, true)
   6607       .to.not.include.deep.members(subset);
   6608   }
   6609 
   6610   /**
   6611    * ### .includeOrderedMembers(superset, subset, [message])
   6612    *
   6613    * Asserts that `subset` is included in `superset` in the same order
   6614    * beginning with the first element in `superset`. Uses a strict equality
   6615    * check (===).
   6616    *
   6617    *     assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members');
   6618    *
   6619    * @name includeOrderedMembers
   6620    * @param {Array} superset
   6621    * @param {Array} subset
   6622    * @param {String} message
   6623    * @namespace Assert
   6624    * @api public
   6625    */
   6626 
   6627   assert.includeOrderedMembers = function (superset, subset, msg) {
   6628     new Assertion(superset, msg, assert.includeOrderedMembers, true)
   6629       .to.include.ordered.members(subset);
   6630   }
   6631 
   6632   /**
   6633    * ### .notIncludeOrderedMembers(superset, subset, [message])
   6634    *
   6635    * Asserts that `subset` isn't included in `superset` in the same order
   6636    * beginning with the first element in `superset`. Uses a strict equality
   6637    * check (===).
   6638    *
   6639    *     assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members');
   6640    *     assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members');
   6641    *
   6642    * @name notIncludeOrderedMembers
   6643    * @param {Array} superset
   6644    * @param {Array} subset
   6645    * @param {String} message
   6646    * @namespace Assert
   6647    * @api public
   6648    */
   6649 
   6650   assert.notIncludeOrderedMembers = function (superset, subset, msg) {
   6651     new Assertion(superset, msg, assert.notIncludeOrderedMembers, true)
   6652       .to.not.include.ordered.members(subset);
   6653   }
   6654 
   6655   /**
   6656    * ### .includeDeepOrderedMembers(superset, subset, [message])
   6657    *
   6658    * Asserts that `subset` is included in `superset` in the same order
   6659    * beginning with the first element in `superset`. Uses a deep equality
   6660    * check.
   6661    *
   6662    *     assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members');
   6663    *
   6664    * @name includeDeepOrderedMembers
   6665    * @param {Array} superset
   6666    * @param {Array} subset
   6667    * @param {String} message
   6668    * @namespace Assert
   6669    * @api public
   6670    */
   6671 
   6672   assert.includeDeepOrderedMembers = function (superset, subset, msg) {
   6673     new Assertion(superset, msg, assert.includeDeepOrderedMembers, true)
   6674       .to.include.deep.ordered.members(subset);
   6675   }
   6676 
   6677   /**
   6678    * ### .notIncludeDeepOrderedMembers(superset, subset, [message])
   6679    *
   6680    * Asserts that `subset` isn't included in `superset` in the same order
   6681    * beginning with the first element in `superset`. Uses a deep equality
   6682    * check.
   6683    *
   6684    *     assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members');
   6685    *     assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members');
   6686    *     assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members');
   6687    *
   6688    * @name notIncludeDeepOrderedMembers
   6689    * @param {Array} superset
   6690    * @param {Array} subset
   6691    * @param {String} message
   6692    * @namespace Assert
   6693    * @api public
   6694    */
   6695 
   6696   assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) {
   6697     new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true)
   6698       .to.not.include.deep.ordered.members(subset);
   6699   }
   6700 
   6701   /**
   6702    * ### .oneOf(inList, list, [message])
   6703    *
   6704    * Asserts that non-object, non-array value `inList` appears in the flat array `list`.
   6705    *
   6706    *     assert.oneOf(1, [ 2, 1 ], 'Not found in list');
   6707    *
   6708    * @name oneOf
   6709    * @param {*} inList
   6710    * @param {Array<*>} list
   6711    * @param {String} message
   6712    * @namespace Assert
   6713    * @api public
   6714    */
   6715 
   6716   assert.oneOf = function (inList, list, msg) {
   6717     new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list);
   6718   }
   6719 
   6720   /**
   6721    * ### .changes(function, object, property, [message])
   6722    *
   6723    * Asserts that a function changes the value of a property.
   6724    *
   6725    *     var obj = { val: 10 };
   6726    *     var fn = function() { obj.val = 22 };
   6727    *     assert.changes(fn, obj, 'val');
   6728    *
   6729    * @name changes
   6730    * @param {Function} modifier function
   6731    * @param {Object} object or getter function
   6732    * @param {String} property name _optional_
   6733    * @param {String} message _optional_
   6734    * @namespace Assert
   6735    * @api public
   6736    */
   6737 
   6738   assert.changes = function (fn, obj, prop, msg) {
   6739     if (arguments.length === 3 && typeof obj === 'function') {
   6740       msg = prop;
   6741       prop = null;
   6742     }
   6743 
   6744     new Assertion(fn, msg, assert.changes, true).to.change(obj, prop);
   6745   }
   6746 
   6747    /**
   6748    * ### .changesBy(function, object, property, delta, [message])
   6749    *
   6750    * Asserts that a function changes the value of a property by an amount (delta).
   6751    *
   6752    *     var obj = { val: 10 };
   6753    *     var fn = function() { obj.val += 2 };
   6754    *     assert.changesBy(fn, obj, 'val', 2);
   6755    *
   6756    * @name changesBy
   6757    * @param {Function} modifier function
   6758    * @param {Object} object or getter function
   6759    * @param {String} property name _optional_
   6760    * @param {Number} change amount (delta)
   6761    * @param {String} message _optional_
   6762    * @namespace Assert
   6763    * @api public
   6764    */
   6765 
   6766   assert.changesBy = function (fn, obj, prop, delta, msg) {
   6767     if (arguments.length === 4 && typeof obj === 'function') {
   6768       var tmpMsg = delta;
   6769       delta = prop;
   6770       msg = tmpMsg;
   6771     } else if (arguments.length === 3) {
   6772       delta = prop;
   6773       prop = null;
   6774     }
   6775 
   6776     new Assertion(fn, msg, assert.changesBy, true)
   6777       .to.change(obj, prop).by(delta);
   6778   }
   6779 
   6780    /**
   6781    * ### .doesNotChange(function, object, property, [message])
   6782    *
   6783    * Asserts that a function does not change the value of a property.
   6784    *
   6785    *     var obj = { val: 10 };
   6786    *     var fn = function() { console.log('foo'); };
   6787    *     assert.doesNotChange(fn, obj, 'val');
   6788    *
   6789    * @name doesNotChange
   6790    * @param {Function} modifier function
   6791    * @param {Object} object or getter function
   6792    * @param {String} property name _optional_
   6793    * @param {String} message _optional_
   6794    * @namespace Assert
   6795    * @api public
   6796    */
   6797 
   6798   assert.doesNotChange = function (fn, obj, prop, msg) {
   6799     if (arguments.length === 3 && typeof obj === 'function') {
   6800       msg = prop;
   6801       prop = null;
   6802     }
   6803 
   6804     return new Assertion(fn, msg, assert.doesNotChange, true)
   6805       .to.not.change(obj, prop);
   6806   }
   6807 
   6808   /**
   6809    * ### .changesButNotBy(function, object, property, delta, [message])
   6810    *
   6811    * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta)
   6812    *
   6813    *     var obj = { val: 10 };
   6814    *     var fn = function() { obj.val += 10 };
   6815    *     assert.changesButNotBy(fn, obj, 'val', 5);
   6816    *
   6817    * @name changesButNotBy
   6818    * @param {Function} modifier function
   6819    * @param {Object} object or getter function
   6820    * @param {String} property name _optional_
   6821    * @param {Number} change amount (delta)
   6822    * @param {String} message _optional_
   6823    * @namespace Assert
   6824    * @api public
   6825    */
   6826 
   6827   assert.changesButNotBy = function (fn, obj, prop, delta, msg) {
   6828     if (arguments.length === 4 && typeof obj === 'function') {
   6829       var tmpMsg = delta;
   6830       delta = prop;
   6831       msg = tmpMsg;
   6832     } else if (arguments.length === 3) {
   6833       delta = prop;
   6834       prop = null;
   6835     }
   6836 
   6837     new Assertion(fn, msg, assert.changesButNotBy, true)
   6838       .to.change(obj, prop).but.not.by(delta);
   6839   }
   6840 
   6841   /**
   6842    * ### .increases(function, object, property, [message])
   6843    *
   6844    * Asserts that a function increases a numeric object property.
   6845    *
   6846    *     var obj = { val: 10 };
   6847    *     var fn = function() { obj.val = 13 };
   6848    *     assert.increases(fn, obj, 'val');
   6849    *
   6850    * @name increases
   6851    * @param {Function} modifier function
   6852    * @param {Object} object or getter function
   6853    * @param {String} property name _optional_
   6854    * @param {String} message _optional_
   6855    * @namespace Assert
   6856    * @api public
   6857    */
   6858 
   6859   assert.increases = function (fn, obj, prop, msg) {
   6860     if (arguments.length === 3 && typeof obj === 'function') {
   6861       msg = prop;
   6862       prop = null;
   6863     }
   6864 
   6865     return new Assertion(fn, msg, assert.increases, true)
   6866       .to.increase(obj, prop);
   6867   }
   6868 
   6869   /**
   6870    * ### .increasesBy(function, object, property, delta, [message])
   6871    *
   6872    * Asserts that a function increases a numeric object property or a function's return value by an amount (delta).
   6873    *
   6874    *     var obj = { val: 10 };
   6875    *     var fn = function() { obj.val += 10 };
   6876    *     assert.increasesBy(fn, obj, 'val', 10);
   6877    *
   6878    * @name increasesBy
   6879    * @param {Function} modifier function
   6880    * @param {Object} object or getter function
   6881    * @param {String} property name _optional_
   6882    * @param {Number} change amount (delta)
   6883    * @param {String} message _optional_
   6884    * @namespace Assert
   6885    * @api public
   6886    */
   6887 
   6888   assert.increasesBy = function (fn, obj, prop, delta, msg) {
   6889     if (arguments.length === 4 && typeof obj === 'function') {
   6890       var tmpMsg = delta;
   6891       delta = prop;
   6892       msg = tmpMsg;
   6893     } else if (arguments.length === 3) {
   6894       delta = prop;
   6895       prop = null;
   6896     }
   6897 
   6898     new Assertion(fn, msg, assert.increasesBy, true)
   6899       .to.increase(obj, prop).by(delta);
   6900   }
   6901 
   6902   /**
   6903    * ### .doesNotIncrease(function, object, property, [message])
   6904    *
   6905    * Asserts that a function does not increase a numeric object property.
   6906    *
   6907    *     var obj = { val: 10 };
   6908    *     var fn = function() { obj.val = 8 };
   6909    *     assert.doesNotIncrease(fn, obj, 'val');
   6910    *
   6911    * @name doesNotIncrease
   6912    * @param {Function} modifier function
   6913    * @param {Object} object or getter function
   6914    * @param {String} property name _optional_
   6915    * @param {String} message _optional_
   6916    * @namespace Assert
   6917    * @api public
   6918    */
   6919 
   6920   assert.doesNotIncrease = function (fn, obj, prop, msg) {
   6921     if (arguments.length === 3 && typeof obj === 'function') {
   6922       msg = prop;
   6923       prop = null;
   6924     }
   6925 
   6926     return new Assertion(fn, msg, assert.doesNotIncrease, true)
   6927       .to.not.increase(obj, prop);
   6928   }
   6929 
   6930   /**
   6931    * ### .increasesButNotBy(function, object, property, delta, [message])
   6932    *
   6933    * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta).
   6934    *
   6935    *     var obj = { val: 10 };
   6936    *     var fn = function() { obj.val = 15 };
   6937    *     assert.increasesButNotBy(fn, obj, 'val', 10);
   6938    *
   6939    * @name increasesButNotBy
   6940    * @param {Function} modifier function
   6941    * @param {Object} object or getter function
   6942    * @param {String} property name _optional_
   6943    * @param {Number} change amount (delta)
   6944    * @param {String} message _optional_
   6945    * @namespace Assert
   6946    * @api public
   6947    */
   6948 
   6949   assert.increasesButNotBy = function (fn, obj, prop, delta, msg) {
   6950     if (arguments.length === 4 && typeof obj === 'function') {
   6951       var tmpMsg = delta;
   6952       delta = prop;
   6953       msg = tmpMsg;
   6954     } else if (arguments.length === 3) {
   6955       delta = prop;
   6956       prop = null;
   6957     }
   6958 
   6959     new Assertion(fn, msg, assert.increasesButNotBy, true)
   6960       .to.increase(obj, prop).but.not.by(delta);
   6961   }
   6962 
   6963   /**
   6964    * ### .decreases(function, object, property, [message])
   6965    *
   6966    * Asserts that a function decreases a numeric object property.
   6967    *
   6968    *     var obj = { val: 10 };
   6969    *     var fn = function() { obj.val = 5 };
   6970    *     assert.decreases(fn, obj, 'val');
   6971    *
   6972    * @name decreases
   6973    * @param {Function} modifier function
   6974    * @param {Object} object or getter function
   6975    * @param {String} property name _optional_
   6976    * @param {String} message _optional_
   6977    * @namespace Assert
   6978    * @api public
   6979    */
   6980 
   6981   assert.decreases = function (fn, obj, prop, msg) {
   6982     if (arguments.length === 3 && typeof obj === 'function') {
   6983       msg = prop;
   6984       prop = null;
   6985     }
   6986 
   6987     return new Assertion(fn, msg, assert.decreases, true)
   6988       .to.decrease(obj, prop);
   6989   }
   6990 
   6991   /**
   6992    * ### .decreasesBy(function, object, property, delta, [message])
   6993    *
   6994    * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta)
   6995    *
   6996    *     var obj = { val: 10 };
   6997    *     var fn = function() { obj.val -= 5 };
   6998    *     assert.decreasesBy(fn, obj, 'val', 5);
   6999    *
   7000    * @name decreasesBy
   7001    * @param {Function} modifier function
   7002    * @param {Object} object or getter function
   7003    * @param {String} property name _optional_
   7004    * @param {Number} change amount (delta)
   7005    * @param {String} message _optional_
   7006    * @namespace Assert
   7007    * @api public
   7008    */
   7009 
   7010   assert.decreasesBy = function (fn, obj, prop, delta, msg) {
   7011     if (arguments.length === 4 && typeof obj === 'function') {
   7012       var tmpMsg = delta;
   7013       delta = prop;
   7014       msg = tmpMsg;
   7015     } else if (arguments.length === 3) {
   7016       delta = prop;
   7017       prop = null;
   7018     }
   7019 
   7020     new Assertion(fn, msg, assert.decreasesBy, true)
   7021       .to.decrease(obj, prop).by(delta);
   7022   }
   7023 
   7024   /**
   7025    * ### .doesNotDecrease(function, object, property, [message])
   7026    *
   7027    * Asserts that a function does not decreases a numeric object property.
   7028    *
   7029    *     var obj = { val: 10 };
   7030    *     var fn = function() { obj.val = 15 };
   7031    *     assert.doesNotDecrease(fn, obj, 'val');
   7032    *
   7033    * @name doesNotDecrease
   7034    * @param {Function} modifier function
   7035    * @param {Object} object or getter function
   7036    * @param {String} property name _optional_
   7037    * @param {String} message _optional_
   7038    * @namespace Assert
   7039    * @api public
   7040    */
   7041 
   7042   assert.doesNotDecrease = function (fn, obj, prop, msg) {
   7043     if (arguments.length === 3 && typeof obj === 'function') {
   7044       msg = prop;
   7045       prop = null;
   7046     }
   7047 
   7048     return new Assertion(fn, msg, assert.doesNotDecrease, true)
   7049       .to.not.decrease(obj, prop);
   7050   }
   7051 
   7052   /**
   7053    * ### .doesNotDecreaseBy(function, object, property, delta, [message])
   7054    *
   7055    * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta)
   7056    *
   7057    *     var obj = { val: 10 };
   7058    *     var fn = function() { obj.val = 5 };
   7059    *     assert.doesNotDecreaseBy(fn, obj, 'val', 1);
   7060    *
   7061    * @name doesNotDecreaseBy
   7062    * @param {Function} modifier function
   7063    * @param {Object} object or getter function
   7064    * @param {String} property name _optional_
   7065    * @param {Number} change amount (delta)
   7066    * @param {String} message _optional_
   7067    * @namespace Assert
   7068    * @api public
   7069    */
   7070 
   7071   assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) {
   7072     if (arguments.length === 4 && typeof obj === 'function') {
   7073       var tmpMsg = delta;
   7074       delta = prop;
   7075       msg = tmpMsg;
   7076     } else if (arguments.length === 3) {
   7077       delta = prop;
   7078       prop = null;
   7079     }
   7080 
   7081     return new Assertion(fn, msg, assert.doesNotDecreaseBy, true)
   7082       .to.not.decrease(obj, prop).by(delta);
   7083   }
   7084 
   7085   /**
   7086    * ### .decreasesButNotBy(function, object, property, delta, [message])
   7087    *
   7088    * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta)
   7089    *
   7090    *     var obj = { val: 10 };
   7091    *     var fn = function() { obj.val = 5 };
   7092    *     assert.decreasesButNotBy(fn, obj, 'val', 1);
   7093    *
   7094    * @name decreasesButNotBy
   7095    * @param {Function} modifier function
   7096    * @param {Object} object or getter function
   7097    * @param {String} property name _optional_
   7098    * @param {Number} change amount (delta)
   7099    * @param {String} message _optional_
   7100    * @namespace Assert
   7101    * @api public
   7102    */
   7103 
   7104   assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) {
   7105     if (arguments.length === 4 && typeof obj === 'function') {
   7106       var tmpMsg = delta;
   7107       delta = prop;
   7108       msg = tmpMsg;
   7109     } else if (arguments.length === 3) {
   7110       delta = prop;
   7111       prop = null;
   7112     }
   7113 
   7114     new Assertion(fn, msg, assert.decreasesButNotBy, true)
   7115       .to.decrease(obj, prop).but.not.by(delta);
   7116   }
   7117 
   7118   /*!
   7119    * ### .ifError(object)
   7120    *
   7121    * Asserts if value is not a false value, and throws if it is a true value.
   7122    * This is added to allow for chai to be a drop-in replacement for Node's
   7123    * assert class.
   7124    *
   7125    *     var err = new Error('I am a custom error');
   7126    *     assert.ifError(err); // Rethrows err!
   7127    *
   7128    * @name ifError
   7129    * @param {Object} object
   7130    * @namespace Assert
   7131    * @api public
   7132    */
   7133 
   7134   assert.ifError = function (val) {
   7135     if (val) {
   7136       throw(val);
   7137     }
   7138   };
   7139 
   7140   /**
   7141    * ### .isExtensible(object)
   7142    *
   7143    * Asserts that `object` is extensible (can have new properties added to it).
   7144    *
   7145    *     assert.isExtensible({});
   7146    *
   7147    * @name isExtensible
   7148    * @alias extensible
   7149    * @param {Object} object
   7150    * @param {String} message _optional_
   7151    * @namespace Assert
   7152    * @api public
   7153    */
   7154 
   7155   assert.isExtensible = function (obj, msg) {
   7156     new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible;
   7157   };
   7158 
   7159   /**
   7160    * ### .isNotExtensible(object)
   7161    *
   7162    * Asserts that `object` is _not_ extensible.
   7163    *
   7164    *     var nonExtensibleObject = Object.preventExtensions({});
   7165    *     var sealedObject = Object.seal({});
   7166    *     var frozenObject = Object.freeze({});
   7167    *
   7168    *     assert.isNotExtensible(nonExtensibleObject);
   7169    *     assert.isNotExtensible(sealedObject);
   7170    *     assert.isNotExtensible(frozenObject);
   7171    *
   7172    * @name isNotExtensible
   7173    * @alias notExtensible
   7174    * @param {Object} object
   7175    * @param {String} message _optional_
   7176    * @namespace Assert
   7177    * @api public
   7178    */
   7179 
   7180   assert.isNotExtensible = function (obj, msg) {
   7181     new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible;
   7182   };
   7183 
   7184   /**
   7185    * ### .isSealed(object)
   7186    *
   7187    * Asserts that `object` is sealed (cannot have new properties added to it
   7188    * and its existing properties cannot be removed).
   7189    *
   7190    *     var sealedObject = Object.seal({});
   7191    *     var frozenObject = Object.seal({});
   7192    *
   7193    *     assert.isSealed(sealedObject);
   7194    *     assert.isSealed(frozenObject);
   7195    *
   7196    * @name isSealed
   7197    * @alias sealed
   7198    * @param {Object} object
   7199    * @param {String} message _optional_
   7200    * @namespace Assert
   7201    * @api public
   7202    */
   7203 
   7204   assert.isSealed = function (obj, msg) {
   7205     new Assertion(obj, msg, assert.isSealed, true).to.be.sealed;
   7206   };
   7207 
   7208   /**
   7209    * ### .isNotSealed(object)
   7210    *
   7211    * Asserts that `object` is _not_ sealed.
   7212    *
   7213    *     assert.isNotSealed({});
   7214    *
   7215    * @name isNotSealed
   7216    * @alias notSealed
   7217    * @param {Object} object
   7218    * @param {String} message _optional_
   7219    * @namespace Assert
   7220    * @api public
   7221    */
   7222 
   7223   assert.isNotSealed = function (obj, msg) {
   7224     new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed;
   7225   };
   7226 
   7227   /**
   7228    * ### .isFrozen(object)
   7229    *
   7230    * Asserts that `object` is frozen (cannot have new properties added to it
   7231    * and its existing properties cannot be modified).
   7232    *
   7233    *     var frozenObject = Object.freeze({});
   7234    *     assert.frozen(frozenObject);
   7235    *
   7236    * @name isFrozen
   7237    * @alias frozen
   7238    * @param {Object} object
   7239    * @param {String} message _optional_
   7240    * @namespace Assert
   7241    * @api public
   7242    */
   7243 
   7244   assert.isFrozen = function (obj, msg) {
   7245     new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen;
   7246   };
   7247 
   7248   /**
   7249    * ### .isNotFrozen(object)
   7250    *
   7251    * Asserts that `object` is _not_ frozen.
   7252    *
   7253    *     assert.isNotFrozen({});
   7254    *
   7255    * @name isNotFrozen
   7256    * @alias notFrozen
   7257    * @param {Object} object
   7258    * @param {String} message _optional_
   7259    * @namespace Assert
   7260    * @api public
   7261    */
   7262 
   7263   assert.isNotFrozen = function (obj, msg) {
   7264     new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen;
   7265   };
   7266 
   7267   /**
   7268    * ### .isEmpty(target)
   7269    *
   7270    * Asserts that the target does not contain any values.
   7271    * For arrays and strings, it checks the `length` property.
   7272    * For `Map` and `Set` instances, it checks the `size` property.
   7273    * For non-function objects, it gets the count of own
   7274    * enumerable string keys.
   7275    *
   7276    *     assert.isEmpty([]);
   7277    *     assert.isEmpty('');
   7278    *     assert.isEmpty(new Map);
   7279    *     assert.isEmpty({});
   7280    *
   7281    * @name isEmpty
   7282    * @alias empty
   7283    * @param {Object|Array|String|Map|Set} target
   7284    * @param {String} message _optional_
   7285    * @namespace Assert
   7286    * @api public
   7287    */
   7288 
   7289   assert.isEmpty = function(val, msg) {
   7290     new Assertion(val, msg, assert.isEmpty, true).to.be.empty;
   7291   };
   7292 
   7293   /**
   7294    * ### .isNotEmpty(target)
   7295    *
   7296    * Asserts that the target contains values.
   7297    * For arrays and strings, it checks the `length` property.
   7298    * For `Map` and `Set` instances, it checks the `size` property.
   7299    * For non-function objects, it gets the count of own
   7300    * enumerable string keys.
   7301    *
   7302    *     assert.isNotEmpty([1, 2]);
   7303    *     assert.isNotEmpty('34');
   7304    *     assert.isNotEmpty(new Set([5, 6]));
   7305    *     assert.isNotEmpty({ key: 7 });
   7306    *
   7307    * @name isNotEmpty
   7308    * @alias notEmpty
   7309    * @param {Object|Array|String|Map|Set} target
   7310    * @param {String} message _optional_
   7311    * @namespace Assert
   7312    * @api public
   7313    */
   7314 
   7315   assert.isNotEmpty = function(val, msg) {
   7316     new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty;
   7317   };
   7318 
   7319   /*!
   7320    * Aliases.
   7321    */
   7322 
   7323   (function alias(name, as){
   7324     assert[as] = assert[name];
   7325     return alias;
   7326   })
   7327   ('isOk', 'ok')
   7328   ('isNotOk', 'notOk')
   7329   ('throws', 'throw')
   7330   ('throws', 'Throw')
   7331   ('isExtensible', 'extensible')
   7332   ('isNotExtensible', 'notExtensible')
   7333   ('isSealed', 'sealed')
   7334   ('isNotSealed', 'notSealed')
   7335   ('isFrozen', 'frozen')
   7336   ('isNotFrozen', 'notFrozen')
   7337   ('isEmpty', 'empty')
   7338   ('isNotEmpty', 'notEmpty');
   7339 };
   7340 
   7341 },{}],7:[function(require,module,exports){
   7342 /*!
   7343  * chai
   7344  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
   7345  * MIT Licensed
   7346  */
   7347 
   7348 module.exports = function (chai, util) {
   7349   chai.expect = function (val, message) {
   7350     return new chai.Assertion(val, message);
   7351   };
   7352 
   7353   /**
   7354    * ### .fail([message])
   7355    * ### .fail(actual, expected, [message], [operator])
   7356    *
   7357    * Throw a failure.
   7358    *
   7359    *     expect.fail();
   7360    *     expect.fail("custom error message");
   7361    *     expect.fail(1, 2);
   7362    *     expect.fail(1, 2, "custom error message");
   7363    *     expect.fail(1, 2, "custom error message", ">");
   7364    *     expect.fail(1, 2, undefined, ">");
   7365    *
   7366    * @name fail
   7367    * @param {Mixed} actual
   7368    * @param {Mixed} expected
   7369    * @param {String} message
   7370    * @param {String} operator
   7371    * @namespace BDD
   7372    * @api public
   7373    */
   7374 
   7375   chai.expect.fail = function (actual, expected, message, operator) {
   7376     if (arguments.length < 2) {
   7377         message = actual;
   7378         actual = undefined;
   7379     }
   7380 
   7381     message = message || 'expect.fail()';
   7382     throw new chai.AssertionError(message, {
   7383         actual: actual
   7384       , expected: expected
   7385       , operator: operator
   7386     }, chai.expect.fail);
   7387   };
   7388 };
   7389 
   7390 },{}],8:[function(require,module,exports){
   7391 /*!
   7392  * chai
   7393  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
   7394  * MIT Licensed
   7395  */
   7396 
   7397 module.exports = function (chai, util) {
   7398   var Assertion = chai.Assertion;
   7399 
   7400   function loadShould () {
   7401     // explicitly define this method as function as to have it's name to include as `ssfi`
   7402     function shouldGetter() {
   7403       if (this instanceof String
   7404           || this instanceof Number
   7405           || this instanceof Boolean
   7406           || typeof Symbol === 'function' && this instanceof Symbol
   7407           || typeof BigInt === 'function' && this instanceof BigInt) {
   7408         return new Assertion(this.valueOf(), null, shouldGetter);
   7409       }
   7410       return new Assertion(this, null, shouldGetter);
   7411     }
   7412     function shouldSetter(value) {
   7413       // See https://github.com/chaijs/chai/issues/86: this makes
   7414       // `whatever.should = someValue` actually set `someValue`, which is
   7415       // especially useful for `global.should = require('chai').should()`.
   7416       //
   7417       // Note that we have to use [[DefineProperty]] instead of [[Put]]
   7418       // since otherwise we would trigger this very setter!
   7419       Object.defineProperty(this, 'should', {
   7420         value: value,
   7421         enumerable: true,
   7422         configurable: true,
   7423         writable: true
   7424       });
   7425     }
   7426     // modify Object.prototype to have `should`
   7427     Object.defineProperty(Object.prototype, 'should', {
   7428       set: shouldSetter
   7429       , get: shouldGetter
   7430       , configurable: true
   7431     });
   7432 
   7433     var should = {};
   7434 
   7435     /**
   7436      * ### .fail([message])
   7437      * ### .fail(actual, expected, [message], [operator])
   7438      *
   7439      * Throw a failure.
   7440      *
   7441      *     should.fail();
   7442      *     should.fail("custom error message");
   7443      *     should.fail(1, 2);
   7444      *     should.fail(1, 2, "custom error message");
   7445      *     should.fail(1, 2, "custom error message", ">");
   7446      *     should.fail(1, 2, undefined, ">");
   7447      *
   7448      *
   7449      * @name fail
   7450      * @param {Mixed} actual
   7451      * @param {Mixed} expected
   7452      * @param {String} message
   7453      * @param {String} operator
   7454      * @namespace BDD
   7455      * @api public
   7456      */
   7457 
   7458     should.fail = function (actual, expected, message, operator) {
   7459       if (arguments.length < 2) {
   7460           message = actual;
   7461           actual = undefined;
   7462       }
   7463 
   7464       message = message || 'should.fail()';
   7465       throw new chai.AssertionError(message, {
   7466           actual: actual
   7467         , expected: expected
   7468         , operator: operator
   7469       }, should.fail);
   7470     };
   7471 
   7472     /**
   7473      * ### .equal(actual, expected, [message])
   7474      *
   7475      * Asserts non-strict equality (`==`) of `actual` and `expected`.
   7476      *
   7477      *     should.equal(3, '3', '== coerces values to strings');
   7478      *
   7479      * @name equal
   7480      * @param {Mixed} actual
   7481      * @param {Mixed} expected
   7482      * @param {String} message
   7483      * @namespace Should
   7484      * @api public
   7485      */
   7486 
   7487     should.equal = function (val1, val2, msg) {
   7488       new Assertion(val1, msg).to.equal(val2);
   7489     };
   7490 
   7491     /**
   7492      * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])
   7493      *
   7494      * Asserts that `function` will throw an error that is an instance of
   7495      * `constructor`, or alternately that it will throw an error with message
   7496      * matching `regexp`.
   7497      *
   7498      *     should.throw(fn, 'function throws a reference error');
   7499      *     should.throw(fn, /function throws a reference error/);
   7500      *     should.throw(fn, ReferenceError);
   7501      *     should.throw(fn, ReferenceError, 'function throws a reference error');
   7502      *     should.throw(fn, ReferenceError, /function throws a reference error/);
   7503      *
   7504      * @name throw
   7505      * @alias Throw
   7506      * @param {Function} function
   7507      * @param {ErrorConstructor} constructor
   7508      * @param {RegExp} regexp
   7509      * @param {String} message
   7510      * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
   7511      * @namespace Should
   7512      * @api public
   7513      */
   7514 
   7515     should.Throw = function (fn, errt, errs, msg) {
   7516       new Assertion(fn, msg).to.Throw(errt, errs);
   7517     };
   7518 
   7519     /**
   7520      * ### .exist
   7521      *
   7522      * Asserts that the target is neither `null` nor `undefined`.
   7523      *
   7524      *     var foo = 'hi';
   7525      *
   7526      *     should.exist(foo, 'foo exists');
   7527      *
   7528      * @name exist
   7529      * @namespace Should
   7530      * @api public
   7531      */
   7532 
   7533     should.exist = function (val, msg) {
   7534       new Assertion(val, msg).to.exist;
   7535     }
   7536 
   7537     // negation
   7538     should.not = {}
   7539 
   7540     /**
   7541      * ### .not.equal(actual, expected, [message])
   7542      *
   7543      * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
   7544      *
   7545      *     should.not.equal(3, 4, 'these numbers are not equal');
   7546      *
   7547      * @name not.equal
   7548      * @param {Mixed} actual
   7549      * @param {Mixed} expected
   7550      * @param {String} message
   7551      * @namespace Should
   7552      * @api public
   7553      */
   7554 
   7555     should.not.equal = function (val1, val2, msg) {
   7556       new Assertion(val1, msg).to.not.equal(val2);
   7557     };
   7558 
   7559     /**
   7560      * ### .throw(function, [constructor/regexp], [message])
   7561      *
   7562      * Asserts that `function` will _not_ throw an error that is an instance of
   7563      * `constructor`, or alternately that it will not throw an error with message
   7564      * matching `regexp`.
   7565      *
   7566      *     should.not.throw(fn, Error, 'function does not throw');
   7567      *
   7568      * @name not.throw
   7569      * @alias not.Throw
   7570      * @param {Function} function
   7571      * @param {ErrorConstructor} constructor
   7572      * @param {RegExp} regexp
   7573      * @param {String} message
   7574      * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
   7575      * @namespace Should
   7576      * @api public
   7577      */
   7578 
   7579     should.not.Throw = function (fn, errt, errs, msg) {
   7580       new Assertion(fn, msg).to.not.Throw(errt, errs);
   7581     };
   7582 
   7583     /**
   7584      * ### .not.exist
   7585      *
   7586      * Asserts that the target is neither `null` nor `undefined`.
   7587      *
   7588      *     var bar = null;
   7589      *
   7590      *     should.not.exist(bar, 'bar does not exist');
   7591      *
   7592      * @name not.exist
   7593      * @namespace Should
   7594      * @api public
   7595      */
   7596 
   7597     should.not.exist = function (val, msg) {
   7598       new Assertion(val, msg).to.not.exist;
   7599     }
   7600 
   7601     should['throw'] = should['Throw'];
   7602     should.not['throw'] = should.not['Throw'];
   7603 
   7604     return should;
   7605   };
   7606 
   7607   chai.should = loadShould;
   7608   chai.Should = loadShould;
   7609 };
   7610 
   7611 },{}],9:[function(require,module,exports){
   7612 /*!
   7613  * Chai - addChainingMethod utility
   7614  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   7615  * MIT Licensed
   7616  */
   7617 
   7618 /*!
   7619  * Module dependencies
   7620  */
   7621 
   7622 var addLengthGuard = require('./addLengthGuard');
   7623 var chai = require('../../chai');
   7624 var flag = require('./flag');
   7625 var proxify = require('./proxify');
   7626 var transferFlags = require('./transferFlags');
   7627 
   7628 /*!
   7629  * Module variables
   7630  */
   7631 
   7632 // Check whether `Object.setPrototypeOf` is supported
   7633 var canSetPrototype = typeof Object.setPrototypeOf === 'function';
   7634 
   7635 // Without `Object.setPrototypeOf` support, this module will need to add properties to a function.
   7636 // However, some of functions' own props are not configurable and should be skipped.
   7637 var testFn = function() {};
   7638 var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) {
   7639   var propDesc = Object.getOwnPropertyDescriptor(testFn, name);
   7640 
   7641   // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties,
   7642   // but then returns `undefined` as the property descriptor for `callee`. As a
   7643   // workaround, we perform an otherwise unnecessary type-check for `propDesc`,
   7644   // and then filter it out if it's not an object as it should be.
   7645   if (typeof propDesc !== 'object')
   7646     return true;
   7647 
   7648   return !propDesc.configurable;
   7649 });
   7650 
   7651 // Cache `Function` properties
   7652 var call  = Function.prototype.call,
   7653     apply = Function.prototype.apply;
   7654 
   7655 /**
   7656  * ### .addChainableMethod(ctx, name, method, chainingBehavior)
   7657  *
   7658  * Adds a method to an object, such that the method can also be chained.
   7659  *
   7660  *     utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {
   7661  *       var obj = utils.flag(this, 'object');
   7662  *       new chai.Assertion(obj).to.be.equal(str);
   7663  *     });
   7664  *
   7665  * Can also be accessed directly from `chai.Assertion`.
   7666  *
   7667  *     chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);
   7668  *
   7669  * The result can then be used as both a method assertion, executing both `method` and
   7670  * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.
   7671  *
   7672  *     expect(fooStr).to.be.foo('bar');
   7673  *     expect(fooStr).to.be.foo.equal('foo');
   7674  *
   7675  * @param {Object} ctx object to which the method is added
   7676  * @param {String} name of method to add
   7677  * @param {Function} method function to be used for `name`, when called
   7678  * @param {Function} chainingBehavior function to be called every time the property is accessed
   7679  * @namespace Utils
   7680  * @name addChainableMethod
   7681  * @api public
   7682  */
   7683 
   7684 module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) {
   7685   if (typeof chainingBehavior !== 'function') {
   7686     chainingBehavior = function () { };
   7687   }
   7688 
   7689   var chainableBehavior = {
   7690       method: method
   7691     , chainingBehavior: chainingBehavior
   7692   };
   7693 
   7694   // save the methods so we can overwrite them later, if we need to.
   7695   if (!ctx.__methods) {
   7696     ctx.__methods = {};
   7697   }
   7698   ctx.__methods[name] = chainableBehavior;
   7699 
   7700   Object.defineProperty(ctx, name,
   7701     { get: function chainableMethodGetter() {
   7702         chainableBehavior.chainingBehavior.call(this);
   7703 
   7704         var chainableMethodWrapper = function () {
   7705           // Setting the `ssfi` flag to `chainableMethodWrapper` causes this
   7706           // function to be the starting point for removing implementation
   7707           // frames from the stack trace of a failed assertion.
   7708           //
   7709           // However, we only want to use this function as the starting point if
   7710           // the `lockSsfi` flag isn't set.
   7711           //
   7712           // If the `lockSsfi` flag is set, then this assertion is being
   7713           // invoked from inside of another assertion. In this case, the `ssfi`
   7714           // flag has already been set by the outer assertion.
   7715           //
   7716           // Note that overwriting a chainable method merely replaces the saved
   7717           // methods in `ctx.__methods` instead of completely replacing the
   7718           // overwritten assertion. Therefore, an overwriting assertion won't
   7719           // set the `ssfi` or `lockSsfi` flags.
   7720           if (!flag(this, 'lockSsfi')) {
   7721             flag(this, 'ssfi', chainableMethodWrapper);
   7722           }
   7723 
   7724           var result = chainableBehavior.method.apply(this, arguments);
   7725           if (result !== undefined) {
   7726             return result;
   7727           }
   7728 
   7729           var newAssertion = new chai.Assertion();
   7730           transferFlags(this, newAssertion);
   7731           return newAssertion;
   7732         };
   7733 
   7734         addLengthGuard(chainableMethodWrapper, name, true);
   7735 
   7736         // Use `Object.setPrototypeOf` if available
   7737         if (canSetPrototype) {
   7738           // Inherit all properties from the object by replacing the `Function` prototype
   7739           var prototype = Object.create(this);
   7740           // Restore the `call` and `apply` methods from `Function`
   7741           prototype.call = call;
   7742           prototype.apply = apply;
   7743           Object.setPrototypeOf(chainableMethodWrapper, prototype);
   7744         }
   7745         // Otherwise, redefine all properties (slow!)
   7746         else {
   7747           var asserterNames = Object.getOwnPropertyNames(ctx);
   7748           asserterNames.forEach(function (asserterName) {
   7749             if (excludeNames.indexOf(asserterName) !== -1) {
   7750               return;
   7751             }
   7752 
   7753             var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);
   7754             Object.defineProperty(chainableMethodWrapper, asserterName, pd);
   7755           });
   7756         }
   7757 
   7758         transferFlags(this, chainableMethodWrapper);
   7759         return proxify(chainableMethodWrapper);
   7760       }
   7761     , configurable: true
   7762   });
   7763 };
   7764 
   7765 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":31,"./transferFlags":33}],10:[function(require,module,exports){
   7766 var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length');
   7767 
   7768 /*!
   7769  * Chai - addLengthGuard utility
   7770  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   7771  * MIT Licensed
   7772  */
   7773 
   7774 /**
   7775  * ### .addLengthGuard(fn, assertionName, isChainable)
   7776  *
   7777  * Define `length` as a getter on the given uninvoked method assertion. The
   7778  * getter acts as a guard against chaining `length` directly off of an uninvoked
   7779  * method assertion, which is a problem because it references `function`'s
   7780  * built-in `length` property instead of Chai's `length` assertion. When the
   7781  * getter catches the user making this mistake, it throws an error with a
   7782  * helpful message.
   7783  *
   7784  * There are two ways in which this mistake can be made. The first way is by
   7785  * chaining the `length` assertion directly off of an uninvoked chainable
   7786  * method. In this case, Chai suggests that the user use `lengthOf` instead. The
   7787  * second way is by chaining the `length` assertion directly off of an uninvoked
   7788  * non-chainable method. Non-chainable methods must be invoked prior to
   7789  * chaining. In this case, Chai suggests that the user consult the docs for the
   7790  * given assertion.
   7791  *
   7792  * If the `length` property of functions is unconfigurable, then return `fn`
   7793  * without modification.
   7794  *
   7795  * Note that in ES6, the function's `length` property is configurable, so once
   7796  * support for legacy environments is dropped, Chai's `length` property can
   7797  * replace the built-in function's `length` property, and this length guard will
   7798  * no longer be necessary. In the mean time, maintaining consistency across all
   7799  * environments is the priority.
   7800  *
   7801  * @param {Function} fn
   7802  * @param {String} assertionName
   7803  * @param {Boolean} isChainable
   7804  * @namespace Utils
   7805  * @name addLengthGuard
   7806  */
   7807 
   7808 module.exports = function addLengthGuard (fn, assertionName, isChainable) {
   7809   if (!fnLengthDesc.configurable) return fn;
   7810 
   7811   Object.defineProperty(fn, 'length', {
   7812     get: function () {
   7813       if (isChainable) {
   7814         throw Error('Invalid Chai property: ' + assertionName + '.length. Due' +
   7815           ' to a compatibility issue, "length" cannot directly follow "' +
   7816           assertionName + '". Use "' + assertionName + '.lengthOf" instead.');
   7817       }
   7818 
   7819       throw Error('Invalid Chai property: ' + assertionName + '.length. See' +
   7820         ' docs for proper usage of "' + assertionName + '".');
   7821     }
   7822   });
   7823 
   7824   return fn;
   7825 };
   7826 
   7827 },{}],11:[function(require,module,exports){
   7828 /*!
   7829  * Chai - addMethod utility
   7830  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   7831  * MIT Licensed
   7832  */
   7833 
   7834 var addLengthGuard = require('./addLengthGuard');
   7835 var chai = require('../../chai');
   7836 var flag = require('./flag');
   7837 var proxify = require('./proxify');
   7838 var transferFlags = require('./transferFlags');
   7839 
   7840 /**
   7841  * ### .addMethod(ctx, name, method)
   7842  *
   7843  * Adds a method to the prototype of an object.
   7844  *
   7845  *     utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {
   7846  *       var obj = utils.flag(this, 'object');
   7847  *       new chai.Assertion(obj).to.be.equal(str);
   7848  *     });
   7849  *
   7850  * Can also be accessed directly from `chai.Assertion`.
   7851  *
   7852  *     chai.Assertion.addMethod('foo', fn);
   7853  *
   7854  * Then can be used as any other assertion.
   7855  *
   7856  *     expect(fooStr).to.be.foo('bar');
   7857  *
   7858  * @param {Object} ctx object to which the method is added
   7859  * @param {String} name of method to add
   7860  * @param {Function} method function to be used for name
   7861  * @namespace Utils
   7862  * @name addMethod
   7863  * @api public
   7864  */
   7865 
   7866 module.exports = function addMethod(ctx, name, method) {
   7867   var methodWrapper = function () {
   7868     // Setting the `ssfi` flag to `methodWrapper` causes this function to be the
   7869     // starting point for removing implementation frames from the stack trace of
   7870     // a failed assertion.
   7871     //
   7872     // However, we only want to use this function as the starting point if the
   7873     // `lockSsfi` flag isn't set.
   7874     //
   7875     // If the `lockSsfi` flag is set, then either this assertion has been
   7876     // overwritten by another assertion, or this assertion is being invoked from
   7877     // inside of another assertion. In the first case, the `ssfi` flag has
   7878     // already been set by the overwriting assertion. In the second case, the
   7879     // `ssfi` flag has already been set by the outer assertion.
   7880     if (!flag(this, 'lockSsfi')) {
   7881       flag(this, 'ssfi', methodWrapper);
   7882     }
   7883 
   7884     var result = method.apply(this, arguments);
   7885     if (result !== undefined)
   7886       return result;
   7887 
   7888     var newAssertion = new chai.Assertion();
   7889     transferFlags(this, newAssertion);
   7890     return newAssertion;
   7891   };
   7892 
   7893   addLengthGuard(methodWrapper, name, false);
   7894   ctx[name] = proxify(methodWrapper, name);
   7895 };
   7896 
   7897 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":31,"./transferFlags":33}],12:[function(require,module,exports){
   7898 /*!
   7899  * Chai - addProperty utility
   7900  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   7901  * MIT Licensed
   7902  */
   7903 
   7904 var chai = require('../../chai');
   7905 var flag = require('./flag');
   7906 var isProxyEnabled = require('./isProxyEnabled');
   7907 var transferFlags = require('./transferFlags');
   7908 
   7909 /**
   7910  * ### .addProperty(ctx, name, getter)
   7911  *
   7912  * Adds a property to the prototype of an object.
   7913  *
   7914  *     utils.addProperty(chai.Assertion.prototype, 'foo', function () {
   7915  *       var obj = utils.flag(this, 'object');
   7916  *       new chai.Assertion(obj).to.be.instanceof(Foo);
   7917  *     });
   7918  *
   7919  * Can also be accessed directly from `chai.Assertion`.
   7920  *
   7921  *     chai.Assertion.addProperty('foo', fn);
   7922  *
   7923  * Then can be used as any other assertion.
   7924  *
   7925  *     expect(myFoo).to.be.foo;
   7926  *
   7927  * @param {Object} ctx object to which the property is added
   7928  * @param {String} name of property to add
   7929  * @param {Function} getter function to be used for name
   7930  * @namespace Utils
   7931  * @name addProperty
   7932  * @api public
   7933  */
   7934 
   7935 module.exports = function addProperty(ctx, name, getter) {
   7936   getter = getter === undefined ? function () {} : getter;
   7937 
   7938   Object.defineProperty(ctx, name,
   7939     { get: function propertyGetter() {
   7940         // Setting the `ssfi` flag to `propertyGetter` causes this function to
   7941         // be the starting point for removing implementation frames from the
   7942         // stack trace of a failed assertion.
   7943         //
   7944         // However, we only want to use this function as the starting point if
   7945         // the `lockSsfi` flag isn't set and proxy protection is disabled.
   7946         //
   7947         // If the `lockSsfi` flag is set, then either this assertion has been
   7948         // overwritten by another assertion, or this assertion is being invoked
   7949         // from inside of another assertion. In the first case, the `ssfi` flag
   7950         // has already been set by the overwriting assertion. In the second
   7951         // case, the `ssfi` flag has already been set by the outer assertion.
   7952         //
   7953         // If proxy protection is enabled, then the `ssfi` flag has already been
   7954         // set by the proxy getter.
   7955         if (!isProxyEnabled() && !flag(this, 'lockSsfi')) {
   7956           flag(this, 'ssfi', propertyGetter);
   7957         }
   7958 
   7959         var result = getter.call(this);
   7960         if (result !== undefined)
   7961           return result;
   7962 
   7963         var newAssertion = new chai.Assertion();
   7964         transferFlags(this, newAssertion);
   7965         return newAssertion;
   7966       }
   7967     , configurable: true
   7968   });
   7969 };
   7970 
   7971 },{"../../chai":2,"./flag":15,"./isProxyEnabled":26,"./transferFlags":33}],13:[function(require,module,exports){
   7972 /*!
   7973  * Chai - compareByInspect utility
   7974  * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
   7975  * MIT Licensed
   7976  */
   7977 
   7978 /*!
   7979  * Module dependencies
   7980  */
   7981 
   7982 var inspect = require('./inspect');
   7983 
   7984 /**
   7985  * ### .compareByInspect(mixed, mixed)
   7986  *
   7987  * To be used as a compareFunction with Array.prototype.sort. Compares elements
   7988  * using inspect instead of default behavior of using toString so that Symbols
   7989  * and objects with irregular/missing toString can still be sorted without a
   7990  * TypeError.
   7991  *
   7992  * @param {Mixed} first element to compare
   7993  * @param {Mixed} second element to compare
   7994  * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1
   7995  * @name compareByInspect
   7996  * @namespace Utils
   7997  * @api public
   7998  */
   7999 
   8000 module.exports = function compareByInspect(a, b) {
   8001   return inspect(a) < inspect(b) ? -1 : 1;
   8002 };
   8003 
   8004 },{"./inspect":24}],14:[function(require,module,exports){
   8005 /*!
   8006  * Chai - expectTypes utility
   8007  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   8008  * MIT Licensed
   8009  */
   8010 
   8011 /**
   8012  * ### .expectTypes(obj, types)
   8013  *
   8014  * Ensures that the object being tested against is of a valid type.
   8015  *
   8016  *     utils.expectTypes(this, ['array', 'object', 'string']);
   8017  *
   8018  * @param {Mixed} obj constructed Assertion
   8019  * @param {Array} type A list of allowed types for this assertion
   8020  * @namespace Utils
   8021  * @name expectTypes
   8022  * @api public
   8023  */
   8024 
   8025 var AssertionError = require('assertion-error');
   8026 var flag = require('./flag');
   8027 var type = require('type-detect');
   8028 
   8029 module.exports = function expectTypes(obj, types) {
   8030   var flagMsg = flag(obj, 'message');
   8031   var ssfi = flag(obj, 'ssfi');
   8032 
   8033   flagMsg = flagMsg ? flagMsg + ': ' : '';
   8034 
   8035   obj = flag(obj, 'object');
   8036   types = types.map(function (t) { return t.toLowerCase(); });
   8037   types.sort();
   8038 
   8039   // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum'
   8040   var str = types.map(function (t, index) {
   8041     var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';
   8042     var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';
   8043     return or + art + ' ' + t;
   8044   }).join(', ');
   8045 
   8046   var objType = type(obj).toLowerCase();
   8047 
   8048   if (!types.some(function (expected) { return objType === expected; })) {
   8049     throw new AssertionError(
   8050       flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given',
   8051       undefined,
   8052       ssfi
   8053     );
   8054   }
   8055 };
   8056 
   8057 },{"./flag":15,"assertion-error":34,"type-detect":39}],15:[function(require,module,exports){
   8058 /*!
   8059  * Chai - flag utility
   8060  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   8061  * MIT Licensed
   8062  */
   8063 
   8064 /**
   8065  * ### .flag(object, key, [value])
   8066  *
   8067  * Get or set a flag value on an object. If a
   8068  * value is provided it will be set, else it will
   8069  * return the currently set value or `undefined` if
   8070  * the value is not set.
   8071  *
   8072  *     utils.flag(this, 'foo', 'bar'); // setter
   8073  *     utils.flag(this, 'foo'); // getter, returns `bar`
   8074  *
   8075  * @param {Object} object constructed Assertion
   8076  * @param {String} key
   8077  * @param {Mixed} value (optional)
   8078  * @namespace Utils
   8079  * @name flag
   8080  * @api private
   8081  */
   8082 
   8083 module.exports = function flag(obj, key, value) {
   8084   var flags = obj.__flags || (obj.__flags = Object.create(null));
   8085   if (arguments.length === 3) {
   8086     flags[key] = value;
   8087   } else {
   8088     return flags[key];
   8089   }
   8090 };
   8091 
   8092 },{}],16:[function(require,module,exports){
   8093 /*!
   8094  * Chai - getActual utility
   8095  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   8096  * MIT Licensed
   8097  */
   8098 
   8099 /**
   8100  * ### .getActual(object, [actual])
   8101  *
   8102  * Returns the `actual` value for an Assertion.
   8103  *
   8104  * @param {Object} object (constructed Assertion)
   8105  * @param {Arguments} chai.Assertion.prototype.assert arguments
   8106  * @namespace Utils
   8107  * @name getActual
   8108  */
   8109 
   8110 module.exports = function getActual(obj, args) {
   8111   return args.length > 4 ? args[4] : obj._obj;
   8112 };
   8113 
   8114 },{}],17:[function(require,module,exports){
   8115 /*!
   8116  * Chai - getEnumerableProperties utility
   8117  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   8118  * MIT Licensed
   8119  */
   8120 
   8121 /**
   8122  * ### .getEnumerableProperties(object)
   8123  *
   8124  * This allows the retrieval of enumerable property names of an object,
   8125  * inherited or not.
   8126  *
   8127  * @param {Object} object
   8128  * @returns {Array}
   8129  * @namespace Utils
   8130  * @name getEnumerableProperties
   8131  * @api public
   8132  */
   8133 
   8134 module.exports = function getEnumerableProperties(object) {
   8135   var result = [];
   8136   for (var name in object) {
   8137     result.push(name);
   8138   }
   8139   return result;
   8140 };
   8141 
   8142 },{}],18:[function(require,module,exports){
   8143 /*!
   8144  * Chai - message composition utility
   8145  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   8146  * MIT Licensed
   8147  */
   8148 
   8149 /*!
   8150  * Module dependencies
   8151  */
   8152 
   8153 var flag = require('./flag')
   8154   , getActual = require('./getActual')
   8155   , objDisplay = require('./objDisplay');
   8156 
   8157 /**
   8158  * ### .getMessage(object, message, negateMessage)
   8159  *
   8160  * Construct the error message based on flags
   8161  * and template tags. Template tags will return
   8162  * a stringified inspection of the object referenced.
   8163  *
   8164  * Message template tags:
   8165  * - `#{this}` current asserted object
   8166  * - `#{act}` actual value
   8167  * - `#{exp}` expected value
   8168  *
   8169  * @param {Object} object (constructed Assertion)
   8170  * @param {Arguments} chai.Assertion.prototype.assert arguments
   8171  * @namespace Utils
   8172  * @name getMessage
   8173  * @api public
   8174  */
   8175 
   8176 module.exports = function getMessage(obj, args) {
   8177   var negate = flag(obj, 'negate')
   8178     , val = flag(obj, 'object')
   8179     , expected = args[3]
   8180     , actual = getActual(obj, args)
   8181     , msg = negate ? args[2] : args[1]
   8182     , flagMsg = flag(obj, 'message');
   8183 
   8184   if(typeof msg === "function") msg = msg();
   8185   msg = msg || '';
   8186   msg = msg
   8187     .replace(/#\{this\}/g, function () { return objDisplay(val); })
   8188     .replace(/#\{act\}/g, function () { return objDisplay(actual); })
   8189     .replace(/#\{exp\}/g, function () { return objDisplay(expected); });
   8190 
   8191   return flagMsg ? flagMsg + ': ' + msg : msg;
   8192 };
   8193 
   8194 },{"./flag":15,"./getActual":16,"./objDisplay":27}],19:[function(require,module,exports){
   8195 var type = require('type-detect');
   8196 
   8197 var flag = require('./flag');
   8198 
   8199 function isObjectType(obj) {
   8200   var objectType = type(obj);
   8201   var objectTypes = ['Array', 'Object', 'function'];
   8202 
   8203   return objectTypes.indexOf(objectType) !== -1;
   8204 }
   8205 
   8206 /**
   8207  * ### .getOperator(message)
   8208  *
   8209  * Extract the operator from error message.
   8210  * Operator defined is based on below link
   8211  * https://nodejs.org/api/assert.html#assert_assert.
   8212  *
   8213  * Returns the `operator` or `undefined` value for an Assertion.
   8214  *
   8215  * @param {Object} object (constructed Assertion)
   8216  * @param {Arguments} chai.Assertion.prototype.assert arguments
   8217  * @namespace Utils
   8218  * @name getOperator
   8219  * @api public
   8220  */
   8221 
   8222 module.exports = function getOperator(obj, args) {
   8223   var operator = flag(obj, 'operator');
   8224   var negate = flag(obj, 'negate');
   8225   var expected = args[3];
   8226   var msg = negate ? args[2] : args[1];
   8227 
   8228   if (operator) {
   8229     return operator;
   8230   }
   8231 
   8232   if (typeof msg === 'function') msg = msg();
   8233 
   8234   msg = msg || '';
   8235   if (!msg) {
   8236     return undefined;
   8237   }
   8238 
   8239   if (/\shave\s/.test(msg)) {
   8240     return undefined;
   8241   }
   8242 
   8243   var isObject = isObjectType(expected);
   8244   if (/\snot\s/.test(msg)) {
   8245     return isObject ? 'notDeepStrictEqual' : 'notStrictEqual';
   8246   }
   8247 
   8248   return isObject ? 'deepStrictEqual' : 'strictEqual';
   8249 };
   8250 
   8251 },{"./flag":15,"type-detect":39}],20:[function(require,module,exports){
   8252 /*!
   8253  * Chai - getOwnEnumerableProperties utility
   8254  * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
   8255  * MIT Licensed
   8256  */
   8257 
   8258 /*!
   8259  * Module dependencies
   8260  */
   8261 
   8262 var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
   8263 
   8264 /**
   8265  * ### .getOwnEnumerableProperties(object)
   8266  *
   8267  * This allows the retrieval of directly-owned enumerable property names and
   8268  * symbols of an object. This function is necessary because Object.keys only
   8269  * returns enumerable property names, not enumerable property symbols.
   8270  *
   8271  * @param {Object} object
   8272  * @returns {Array}
   8273  * @namespace Utils
   8274  * @name getOwnEnumerableProperties
   8275  * @api public
   8276  */
   8277 
   8278 module.exports = function getOwnEnumerableProperties(obj) {
   8279   return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj));
   8280 };
   8281 
   8282 },{"./getOwnEnumerablePropertySymbols":21}],21:[function(require,module,exports){
   8283 /*!
   8284  * Chai - getOwnEnumerablePropertySymbols utility
   8285  * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
   8286  * MIT Licensed
   8287  */
   8288 
   8289 /**
   8290  * ### .getOwnEnumerablePropertySymbols(object)
   8291  *
   8292  * This allows the retrieval of directly-owned enumerable property symbols of an
   8293  * object. This function is necessary because Object.getOwnPropertySymbols
   8294  * returns both enumerable and non-enumerable property symbols.
   8295  *
   8296  * @param {Object} object
   8297  * @returns {Array}
   8298  * @namespace Utils
   8299  * @name getOwnEnumerablePropertySymbols
   8300  * @api public
   8301  */
   8302 
   8303 module.exports = function getOwnEnumerablePropertySymbols(obj) {
   8304   if (typeof Object.getOwnPropertySymbols !== 'function') return [];
   8305 
   8306   return Object.getOwnPropertySymbols(obj).filter(function (sym) {
   8307     return Object.getOwnPropertyDescriptor(obj, sym).enumerable;
   8308   });
   8309 };
   8310 
   8311 },{}],22:[function(require,module,exports){
   8312 /*!
   8313  * Chai - getProperties utility
   8314  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   8315  * MIT Licensed
   8316  */
   8317 
   8318 /**
   8319  * ### .getProperties(object)
   8320  *
   8321  * This allows the retrieval of property names of an object, enumerable or not,
   8322  * inherited or not.
   8323  *
   8324  * @param {Object} object
   8325  * @returns {Array}
   8326  * @namespace Utils
   8327  * @name getProperties
   8328  * @api public
   8329  */
   8330 
   8331 module.exports = function getProperties(object) {
   8332   var result = Object.getOwnPropertyNames(object);
   8333 
   8334   function addProperty(property) {
   8335     if (result.indexOf(property) === -1) {
   8336       result.push(property);
   8337     }
   8338   }
   8339 
   8340   var proto = Object.getPrototypeOf(object);
   8341   while (proto !== null) {
   8342     Object.getOwnPropertyNames(proto).forEach(addProperty);
   8343     proto = Object.getPrototypeOf(proto);
   8344   }
   8345 
   8346   return result;
   8347 };
   8348 
   8349 },{}],23:[function(require,module,exports){
   8350 /*!
   8351  * chai
   8352  * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
   8353  * MIT Licensed
   8354  */
   8355 
   8356 /*!
   8357  * Dependencies that are used for multiple exports are required here only once
   8358  */
   8359 
   8360 var pathval = require('pathval');
   8361 
   8362 /*!
   8363  * test utility
   8364  */
   8365 
   8366 exports.test = require('./test');
   8367 
   8368 /*!
   8369  * type utility
   8370  */
   8371 
   8372 exports.type = require('type-detect');
   8373 
   8374 /*!
   8375  * expectTypes utility
   8376  */
   8377 exports.expectTypes = require('./expectTypes');
   8378 
   8379 /*!
   8380  * message utility
   8381  */
   8382 
   8383 exports.getMessage = require('./getMessage');
   8384 
   8385 /*!
   8386  * actual utility
   8387  */
   8388 
   8389 exports.getActual = require('./getActual');
   8390 
   8391 /*!
   8392  * Inspect util
   8393  */
   8394 
   8395 exports.inspect = require('./inspect');
   8396 
   8397 /*!
   8398  * Object Display util
   8399  */
   8400 
   8401 exports.objDisplay = require('./objDisplay');
   8402 
   8403 /*!
   8404  * Flag utility
   8405  */
   8406 
   8407 exports.flag = require('./flag');
   8408 
   8409 /*!
   8410  * Flag transferring utility
   8411  */
   8412 
   8413 exports.transferFlags = require('./transferFlags');
   8414 
   8415 /*!
   8416  * Deep equal utility
   8417  */
   8418 
   8419 exports.eql = require('deep-eql');
   8420 
   8421 /*!
   8422  * Deep path info
   8423  */
   8424 
   8425 exports.getPathInfo = pathval.getPathInfo;
   8426 
   8427 /*!
   8428  * Check if a property exists
   8429  */
   8430 
   8431 exports.hasProperty = pathval.hasProperty;
   8432 
   8433 /*!
   8434  * Function name
   8435  */
   8436 
   8437 exports.getName = require('get-func-name');
   8438 
   8439 /*!
   8440  * add Property
   8441  */
   8442 
   8443 exports.addProperty = require('./addProperty');
   8444 
   8445 /*!
   8446  * add Method
   8447  */
   8448 
   8449 exports.addMethod = require('./addMethod');
   8450 
   8451 /*!
   8452  * overwrite Property
   8453  */
   8454 
   8455 exports.overwriteProperty = require('./overwriteProperty');
   8456 
   8457 /*!
   8458  * overwrite Method
   8459  */
   8460 
   8461 exports.overwriteMethod = require('./overwriteMethod');
   8462 
   8463 /*!
   8464  * Add a chainable method
   8465  */
   8466 
   8467 exports.addChainableMethod = require('./addChainableMethod');
   8468 
   8469 /*!
   8470  * Overwrite chainable method
   8471  */
   8472 
   8473 exports.overwriteChainableMethod = require('./overwriteChainableMethod');
   8474 
   8475 /*!
   8476  * Compare by inspect method
   8477  */
   8478 
   8479 exports.compareByInspect = require('./compareByInspect');
   8480 
   8481 /*!
   8482  * Get own enumerable property symbols method
   8483  */
   8484 
   8485 exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
   8486 
   8487 /*!
   8488  * Get own enumerable properties method
   8489  */
   8490 
   8491 exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties');
   8492 
   8493 /*!
   8494  * Checks error against a given set of criteria
   8495  */
   8496 
   8497 exports.checkError = require('check-error');
   8498 
   8499 /*!
   8500  * Proxify util
   8501  */
   8502 
   8503 exports.proxify = require('./proxify');
   8504 
   8505 /*!
   8506  * addLengthGuard util
   8507  */
   8508 
   8509 exports.addLengthGuard = require('./addLengthGuard');
   8510 
   8511 /*!
   8512  * isProxyEnabled helper
   8513  */
   8514 
   8515 exports.isProxyEnabled = require('./isProxyEnabled');
   8516 
   8517 /*!
   8518  * isNaN method
   8519  */
   8520 
   8521 exports.isNaN = require('./isNaN');
   8522 
   8523 /*!
   8524  * getOperator method
   8525  */
   8526 
   8527 exports.getOperator = require('./getOperator');
   8528 },{"./addChainableMethod":9,"./addLengthGuard":10,"./addMethod":11,"./addProperty":12,"./compareByInspect":13,"./expectTypes":14,"./flag":15,"./getActual":16,"./getMessage":18,"./getOperator":19,"./getOwnEnumerableProperties":20,"./getOwnEnumerablePropertySymbols":21,"./inspect":24,"./isNaN":25,"./isProxyEnabled":26,"./objDisplay":27,"./overwriteChainableMethod":28,"./overwriteMethod":29,"./overwriteProperty":30,"./proxify":31,"./test":32,"./transferFlags":33,"check-error":35,"deep-eql":36,"get-func-name":37,"pathval":38,"type-detect":39}],24:[function(require,module,exports){
   8529 // This is (almost) directly from Node.js utils
   8530 // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
   8531 
   8532 var getName = require('get-func-name');
   8533 var getProperties = require('./getProperties');
   8534 var getEnumerableProperties = require('./getEnumerableProperties');
   8535 var config = require('../config');
   8536 
   8537 module.exports = inspect;
   8538 
   8539 /**
   8540  * ### .inspect(obj, [showHidden], [depth], [colors])
   8541  *
   8542  * Echoes the value of a value. Tries to print the value out
   8543  * in the best way possible given the different types.
   8544  *
   8545  * @param {Object} obj The object to print out.
   8546  * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
   8547  *    properties of objects. Default is false.
   8548  * @param {Number} depth Depth in which to descend in object. Default is 2.
   8549  * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
   8550  *    output. Default is false (no coloring).
   8551  * @namespace Utils
   8552  * @name inspect
   8553  */
   8554 function inspect(obj, showHidden, depth, colors) {
   8555   var ctx = {
   8556     showHidden: showHidden,
   8557     seen: [],
   8558     stylize: function (str) { return str; }
   8559   };
   8560   return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
   8561 }
   8562 
   8563 // Returns true if object is a DOM element.
   8564 var isDOMElement = function (object) {
   8565   if (typeof HTMLElement === 'object') {
   8566     return object instanceof HTMLElement;
   8567   } else {
   8568     return object &&
   8569       typeof object === 'object' &&
   8570       'nodeType' in object &&
   8571       object.nodeType === 1 &&
   8572       typeof object.nodeName === 'string';
   8573   }
   8574 };
   8575 
   8576 function formatValue(ctx, value, recurseTimes) {
   8577   // Provide a hook for user-specified inspect functions.
   8578   // Check that value is an object with an inspect function on it
   8579   if (value && typeof value.inspect === 'function' &&
   8580       // Filter out the util module, it's inspect function is special
   8581       value.inspect !== exports.inspect &&
   8582       // Also filter out any prototype objects using the circular check.
   8583       !(value.constructor && value.constructor.prototype === value)) {
   8584     var ret = value.inspect(recurseTimes, ctx);
   8585     if (typeof ret !== 'string') {
   8586       ret = formatValue(ctx, ret, recurseTimes);
   8587     }
   8588     return ret;
   8589   }
   8590 
   8591   // Primitive types cannot have properties
   8592   var primitive = formatPrimitive(ctx, value);
   8593   if (primitive) {
   8594     return primitive;
   8595   }
   8596 
   8597   // If this is a DOM element, try to get the outer HTML.
   8598   if (isDOMElement(value)) {
   8599     if ('outerHTML' in value) {
   8600       return value.outerHTML;
   8601       // This value does not have an outerHTML attribute,
   8602       //   it could still be an XML element
   8603     } else {
   8604       // Attempt to serialize it
   8605       try {
   8606         if (document.xmlVersion) {
   8607           var xmlSerializer = new XMLSerializer();
   8608           return xmlSerializer.serializeToString(value);
   8609         } else {
   8610           // Firefox 11- do not support outerHTML
   8611           //   It does, however, support innerHTML
   8612           //   Use the following to render the element
   8613           var ns = "http://www.w3.org/1999/xhtml";
   8614           var container = document.createElementNS(ns, '_');
   8615 
   8616           container.appendChild(value.cloneNode(false));
   8617           var html = container.innerHTML
   8618             .replace('><', '>' + value.innerHTML + '<');
   8619           container.innerHTML = '';
   8620           return html;
   8621         }
   8622       } catch (err) {
   8623         // This could be a non-native DOM implementation,
   8624         //   continue with the normal flow:
   8625         //   printing the element as if it is an object.
   8626       }
   8627     }
   8628   }
   8629 
   8630   // Look up the keys of the object.
   8631   var visibleKeys = getEnumerableProperties(value);
   8632   var keys = ctx.showHidden ? getProperties(value) : visibleKeys;
   8633 
   8634   var name, nameSuffix;
   8635 
   8636   // Some type of object without properties can be shortcut.
   8637   // In IE, errors have a single `stack` property, or if they are vanilla `Error`,
   8638   // a `stack` plus `description` property; ignore those for consistency.
   8639   if (keys.length === 0 || (isError(value) && (
   8640       (keys.length === 1 && keys[0] === 'stack') ||
   8641       (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')
   8642      ))) {
   8643     if (typeof value === 'function') {
   8644       name = getName(value);
   8645       nameSuffix = name ? ': ' + name : '';
   8646       return ctx.stylize('[Function' + nameSuffix + ']', 'special');
   8647     }
   8648     if (isRegExp(value)) {
   8649       return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
   8650     }
   8651     if (isDate(value)) {
   8652       return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
   8653     }
   8654     if (isError(value)) {
   8655       return formatError(value);
   8656     }
   8657   }
   8658 
   8659   var base = ''
   8660     , array = false
   8661     , typedArray = false
   8662     , braces = ['{', '}'];
   8663 
   8664   if (isTypedArray(value)) {
   8665     typedArray = true;
   8666     braces = ['[', ']'];
   8667   }
   8668 
   8669   // Make Array say that they are Array
   8670   if (isArray(value)) {
   8671     array = true;
   8672     braces = ['[', ']'];
   8673   }
   8674 
   8675   // Make functions say that they are functions
   8676   if (typeof value === 'function') {
   8677     name = getName(value);
   8678     nameSuffix = name ? ': ' + name : '';
   8679     base = ' [Function' + nameSuffix + ']';
   8680   }
   8681 
   8682   // Make RegExps say that they are RegExps
   8683   if (isRegExp(value)) {
   8684     base = ' ' + RegExp.prototype.toString.call(value);
   8685   }
   8686 
   8687   // Make dates with properties first say the date
   8688   if (isDate(value)) {
   8689     base = ' ' + Date.prototype.toUTCString.call(value);
   8690   }
   8691 
   8692   // Make error with message first say the error
   8693   if (isError(value)) {
   8694     return formatError(value);
   8695   }
   8696 
   8697   if (keys.length === 0 && (!array || value.length == 0)) {
   8698     return braces[0] + base + braces[1];
   8699   }
   8700 
   8701   if (recurseTimes < 0) {
   8702     if (isRegExp(value)) {
   8703       return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
   8704     } else {
   8705       return ctx.stylize('[Object]', 'special');
   8706     }
   8707   }
   8708 
   8709   ctx.seen.push(value);
   8710 
   8711   var output;
   8712   if (array) {
   8713     output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
   8714   } else if (typedArray) {
   8715     return formatTypedArray(value);
   8716   } else {
   8717     output = keys.map(function(key) {
   8718       return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
   8719     });
   8720   }
   8721 
   8722   ctx.seen.pop();
   8723 
   8724   return reduceToSingleString(output, base, braces);
   8725 }
   8726 
   8727 function formatPrimitive(ctx, value) {
   8728   switch (typeof value) {
   8729     case 'undefined':
   8730       return ctx.stylize('undefined', 'undefined');
   8731 
   8732     case 'string':
   8733       var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
   8734                                                .replace(/'/g, "\\'")
   8735                                                .replace(/\\"/g, '"') + '\'';
   8736       return ctx.stylize(simple, 'string');
   8737 
   8738     case 'number':
   8739       if (value === 0 && (1/value) === -Infinity) {
   8740         return ctx.stylize('-0', 'number');
   8741       }
   8742       return ctx.stylize('' + value, 'number');
   8743 
   8744     case 'boolean':
   8745       return ctx.stylize('' + value, 'boolean');
   8746 
   8747     case 'symbol':
   8748       return ctx.stylize(value.toString(), 'symbol');
   8749 
   8750     case 'bigint':
   8751       return ctx.stylize(value.toString() + 'n', 'bigint');
   8752   }
   8753   // For some reason typeof null is "object", so special case here.
   8754   if (value === null) {
   8755     return ctx.stylize('null', 'null');
   8756   }
   8757 }
   8758 
   8759 function formatError(value) {
   8760   return '[' + Error.prototype.toString.call(value) + ']';
   8761 }
   8762 
   8763 function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
   8764   var output = [];
   8765   for (var i = 0, l = value.length; i < l; ++i) {
   8766     if (Object.prototype.hasOwnProperty.call(value, String(i))) {
   8767       output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
   8768           String(i), true));
   8769     } else {
   8770       output.push('');
   8771     }
   8772   }
   8773 
   8774   keys.forEach(function(key) {
   8775     if (!key.match(/^\d+$/)) {
   8776       output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
   8777           key, true));
   8778     }
   8779   });
   8780   return output;
   8781 }
   8782 
   8783 function formatTypedArray(value) {
   8784   var str = '[ ';
   8785 
   8786   for (var i = 0; i < value.length; ++i) {
   8787     if (str.length >= config.truncateThreshold - 7) {
   8788       str += '...';
   8789       break;
   8790     }
   8791     str += value[i] + ', ';
   8792   }
   8793   str += ' ]';
   8794 
   8795   // Removing trailing `, ` if the array was not truncated
   8796   if (str.indexOf(',  ]') !== -1) {
   8797     str = str.replace(',  ]', ' ]');
   8798   }
   8799 
   8800   return str;
   8801 }
   8802 
   8803 function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
   8804   var name;
   8805   var propDescriptor = Object.getOwnPropertyDescriptor(value, key);
   8806   var str;
   8807 
   8808   if (propDescriptor) {
   8809     if (propDescriptor.get) {
   8810       if (propDescriptor.set) {
   8811         str = ctx.stylize('[Getter/Setter]', 'special');
   8812       } else {
   8813         str = ctx.stylize('[Getter]', 'special');
   8814       }
   8815     } else {
   8816       if (propDescriptor.set) {
   8817         str = ctx.stylize('[Setter]', 'special');
   8818       }
   8819     }
   8820   }
   8821   if (visibleKeys.indexOf(key) < 0) {
   8822     name = '[' + key + ']';
   8823   }
   8824   if (!str) {
   8825     if (ctx.seen.indexOf(value[key]) < 0) {
   8826       if (recurseTimes === null) {
   8827         str = formatValue(ctx, value[key], null);
   8828       } else {
   8829         str = formatValue(ctx, value[key], recurseTimes - 1);
   8830       }
   8831       if (str.indexOf('\n') > -1) {
   8832         if (array) {
   8833           str = str.split('\n').map(function(line) {
   8834             return '  ' + line;
   8835           }).join('\n').substr(2);
   8836         } else {
   8837           str = '\n' + str.split('\n').map(function(line) {
   8838             return '   ' + line;
   8839           }).join('\n');
   8840         }
   8841       }
   8842     } else {
   8843       str = ctx.stylize('[Circular]', 'special');
   8844     }
   8845   }
   8846   if (typeof name === 'undefined') {
   8847     if (array && key.match(/^\d+$/)) {
   8848       return str;
   8849     }
   8850     name = JSON.stringify('' + key);
   8851     if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
   8852       name = name.substr(1, name.length - 2);
   8853       name = ctx.stylize(name, 'name');
   8854     } else {
   8855       name = name.replace(/'/g, "\\'")
   8856                  .replace(/\\"/g, '"')
   8857                  .replace(/(^"|"$)/g, "'");
   8858       name = ctx.stylize(name, 'string');
   8859     }
   8860   }
   8861 
   8862   return name + ': ' + str;
   8863 }
   8864 
   8865 function reduceToSingleString(output, base, braces) {
   8866   var length = output.reduce(function(prev, cur) {
   8867     return prev + cur.length + 1;
   8868   }, 0);
   8869 
   8870   if (length > 60) {
   8871     return braces[0] +
   8872            (base === '' ? '' : base + '\n ') +
   8873            ' ' +
   8874            output.join(',\n  ') +
   8875            ' ' +
   8876            braces[1];
   8877   }
   8878 
   8879   return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
   8880 }
   8881 
   8882 function isTypedArray(ar) {
   8883   // Unfortunately there's no way to check if an object is a TypedArray
   8884   // We have to check if it's one of these types
   8885   return (typeof ar === 'object' && /\w+Array]$/.test(objectToString(ar)));
   8886 }
   8887 
   8888 function isArray(ar) {
   8889   return Array.isArray(ar) ||
   8890          (typeof ar === 'object' && objectToString(ar) === '[object Array]');
   8891 }
   8892 
   8893 function isRegExp(re) {
   8894   return typeof re === 'object' && objectToString(re) === '[object RegExp]';
   8895 }
   8896 
   8897 function isDate(d) {
   8898   return typeof d === 'object' && objectToString(d) === '[object Date]';
   8899 }
   8900 
   8901 function isError(e) {
   8902   return typeof e === 'object' && objectToString(e) === '[object Error]';
   8903 }
   8904 
   8905 function objectToString(o) {
   8906   return Object.prototype.toString.call(o);
   8907 }
   8908 
   8909 },{"../config":4,"./getEnumerableProperties":17,"./getProperties":22,"get-func-name":37}],25:[function(require,module,exports){
   8910 /*!
   8911  * Chai - isNaN utility
   8912  * Copyright(c) 2012-2015 Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
   8913  * MIT Licensed
   8914  */
   8915 
   8916 /**
   8917  * ### .isNaN(value)
   8918  *
   8919  * Checks if the given value is NaN or not.
   8920  *
   8921  *     utils.isNaN(NaN); // true
   8922  *
   8923  * @param {Value} The value which has to be checked if it is NaN
   8924  * @name isNaN
   8925  * @api private
   8926  */
   8927 
   8928 function isNaN(value) {
   8929   // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number
   8930   // section's NOTE.
   8931   return value !== value;
   8932 }
   8933 
   8934 // If ECMAScript 6's Number.isNaN is present, prefer that.
   8935 module.exports = Number.isNaN || isNaN;
   8936 
   8937 },{}],26:[function(require,module,exports){
   8938 var config = require('../config');
   8939 
   8940 /*!
   8941  * Chai - isProxyEnabled helper
   8942  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   8943  * MIT Licensed
   8944  */
   8945 
   8946 /**
   8947  * ### .isProxyEnabled()
   8948  *
   8949  * Helper function to check if Chai's proxy protection feature is enabled. If
   8950  * proxies are unsupported or disabled via the user's Chai config, then return
   8951  * false. Otherwise, return true.
   8952  *
   8953  * @namespace Utils
   8954  * @name isProxyEnabled
   8955  */
   8956 
   8957 module.exports = function isProxyEnabled() {
   8958   return config.useProxy &&
   8959     typeof Proxy !== 'undefined' &&
   8960     typeof Reflect !== 'undefined';
   8961 };
   8962 
   8963 },{"../config":4}],27:[function(require,module,exports){
   8964 /*!
   8965  * Chai - flag utility
   8966  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   8967  * MIT Licensed
   8968  */
   8969 
   8970 /*!
   8971  * Module dependencies
   8972  */
   8973 
   8974 var inspect = require('./inspect');
   8975 var config = require('../config');
   8976 
   8977 /**
   8978  * ### .objDisplay(object)
   8979  *
   8980  * Determines if an object or an array matches
   8981  * criteria to be inspected in-line for error
   8982  * messages or should be truncated.
   8983  *
   8984  * @param {Mixed} javascript object to inspect
   8985  * @name objDisplay
   8986  * @namespace Utils
   8987  * @api public
   8988  */
   8989 
   8990 module.exports = function objDisplay(obj) {
   8991   var str = inspect(obj)
   8992     , type = Object.prototype.toString.call(obj);
   8993 
   8994   if (config.truncateThreshold && str.length >= config.truncateThreshold) {
   8995     if (type === '[object Function]') {
   8996       return !obj.name || obj.name === ''
   8997         ? '[Function]'
   8998         : '[Function: ' + obj.name + ']';
   8999     } else if (type === '[object Array]') {
   9000       return '[ Array(' + obj.length + ') ]';
   9001     } else if (type === '[object Object]') {
   9002       var keys = Object.keys(obj)
   9003         , kstr = keys.length > 2
   9004           ? keys.splice(0, 2).join(', ') + ', ...'
   9005           : keys.join(', ');
   9006       return '{ Object (' + kstr + ') }';
   9007     } else {
   9008       return str;
   9009     }
   9010   } else {
   9011     return str;
   9012   }
   9013 };
   9014 
   9015 },{"../config":4,"./inspect":24}],28:[function(require,module,exports){
   9016 /*!
   9017  * Chai - overwriteChainableMethod utility
   9018  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   9019  * MIT Licensed
   9020  */
   9021 
   9022 var chai = require('../../chai');
   9023 var transferFlags = require('./transferFlags');
   9024 
   9025 /**
   9026  * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior)
   9027  *
   9028  * Overwrites an already existing chainable method
   9029  * and provides access to the previous function or
   9030  * property.  Must return functions to be used for
   9031  * name.
   9032  *
   9033  *     utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf',
   9034  *       function (_super) {
   9035  *       }
   9036  *     , function (_super) {
   9037  *       }
   9038  *     );
   9039  *
   9040  * Can also be accessed directly from `chai.Assertion`.
   9041  *
   9042  *     chai.Assertion.overwriteChainableMethod('foo', fn, fn);
   9043  *
   9044  * Then can be used as any other assertion.
   9045  *
   9046  *     expect(myFoo).to.have.lengthOf(3);
   9047  *     expect(myFoo).to.have.lengthOf.above(3);
   9048  *
   9049  * @param {Object} ctx object whose method / property is to be overwritten
   9050  * @param {String} name of method / property to overwrite
   9051  * @param {Function} method function that returns a function to be used for name
   9052  * @param {Function} chainingBehavior function that returns a function to be used for property
   9053  * @namespace Utils
   9054  * @name overwriteChainableMethod
   9055  * @api public
   9056  */
   9057 
   9058 module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) {
   9059   var chainableBehavior = ctx.__methods[name];
   9060 
   9061   var _chainingBehavior = chainableBehavior.chainingBehavior;
   9062   chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() {
   9063     var result = chainingBehavior(_chainingBehavior).call(this);
   9064     if (result !== undefined) {
   9065       return result;
   9066     }
   9067 
   9068     var newAssertion = new chai.Assertion();
   9069     transferFlags(this, newAssertion);
   9070     return newAssertion;
   9071   };
   9072 
   9073   var _method = chainableBehavior.method;
   9074   chainableBehavior.method = function overwritingChainableMethodWrapper() {
   9075     var result = method(_method).apply(this, arguments);
   9076     if (result !== undefined) {
   9077       return result;
   9078     }
   9079 
   9080     var newAssertion = new chai.Assertion();
   9081     transferFlags(this, newAssertion);
   9082     return newAssertion;
   9083   };
   9084 };
   9085 
   9086 },{"../../chai":2,"./transferFlags":33}],29:[function(require,module,exports){
   9087 /*!
   9088  * Chai - overwriteMethod utility
   9089  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   9090  * MIT Licensed
   9091  */
   9092 
   9093 var addLengthGuard = require('./addLengthGuard');
   9094 var chai = require('../../chai');
   9095 var flag = require('./flag');
   9096 var proxify = require('./proxify');
   9097 var transferFlags = require('./transferFlags');
   9098 
   9099 /**
   9100  * ### .overwriteMethod(ctx, name, fn)
   9101  *
   9102  * Overwrites an already existing method and provides
   9103  * access to previous function. Must return function
   9104  * to be used for name.
   9105  *
   9106  *     utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {
   9107  *       return function (str) {
   9108  *         var obj = utils.flag(this, 'object');
   9109  *         if (obj instanceof Foo) {
   9110  *           new chai.Assertion(obj.value).to.equal(str);
   9111  *         } else {
   9112  *           _super.apply(this, arguments);
   9113  *         }
   9114  *       }
   9115  *     });
   9116  *
   9117  * Can also be accessed directly from `chai.Assertion`.
   9118  *
   9119  *     chai.Assertion.overwriteMethod('foo', fn);
   9120  *
   9121  * Then can be used as any other assertion.
   9122  *
   9123  *     expect(myFoo).to.equal('bar');
   9124  *
   9125  * @param {Object} ctx object whose method is to be overwritten
   9126  * @param {String} name of method to overwrite
   9127  * @param {Function} method function that returns a function to be used for name
   9128  * @namespace Utils
   9129  * @name overwriteMethod
   9130  * @api public
   9131  */
   9132 
   9133 module.exports = function overwriteMethod(ctx, name, method) {
   9134   var _method = ctx[name]
   9135     , _super = function () {
   9136       throw new Error(name + ' is not a function');
   9137     };
   9138 
   9139   if (_method && 'function' === typeof _method)
   9140     _super = _method;
   9141 
   9142   var overwritingMethodWrapper = function () {
   9143     // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this
   9144     // function to be the starting point for removing implementation frames from
   9145     // the stack trace of a failed assertion.
   9146     //
   9147     // However, we only want to use this function as the starting point if the
   9148     // `lockSsfi` flag isn't set.
   9149     //
   9150     // If the `lockSsfi` flag is set, then either this assertion has been
   9151     // overwritten by another assertion, or this assertion is being invoked from
   9152     // inside of another assertion. In the first case, the `ssfi` flag has
   9153     // already been set by the overwriting assertion. In the second case, the
   9154     // `ssfi` flag has already been set by the outer assertion.
   9155     if (!flag(this, 'lockSsfi')) {
   9156       flag(this, 'ssfi', overwritingMethodWrapper);
   9157     }
   9158 
   9159     // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion
   9160     // from changing the `ssfi` flag. By this point, the `ssfi` flag is already
   9161     // set to the correct starting point for this assertion.
   9162     var origLockSsfi = flag(this, 'lockSsfi');
   9163     flag(this, 'lockSsfi', true);
   9164     var result = method(_super).apply(this, arguments);
   9165     flag(this, 'lockSsfi', origLockSsfi);
   9166 
   9167     if (result !== undefined) {
   9168       return result;
   9169     }
   9170 
   9171     var newAssertion = new chai.Assertion();
   9172     transferFlags(this, newAssertion);
   9173     return newAssertion;
   9174   }
   9175 
   9176   addLengthGuard(overwritingMethodWrapper, name, false);
   9177   ctx[name] = proxify(overwritingMethodWrapper, name);
   9178 };
   9179 
   9180 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":31,"./transferFlags":33}],30:[function(require,module,exports){
   9181 /*!
   9182  * Chai - overwriteProperty utility
   9183  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   9184  * MIT Licensed
   9185  */
   9186 
   9187 var chai = require('../../chai');
   9188 var flag = require('./flag');
   9189 var isProxyEnabled = require('./isProxyEnabled');
   9190 var transferFlags = require('./transferFlags');
   9191 
   9192 /**
   9193  * ### .overwriteProperty(ctx, name, fn)
   9194  *
   9195  * Overwrites an already existing property getter and provides
   9196  * access to previous value. Must return function to use as getter.
   9197  *
   9198  *     utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {
   9199  *       return function () {
   9200  *         var obj = utils.flag(this, 'object');
   9201  *         if (obj instanceof Foo) {
   9202  *           new chai.Assertion(obj.name).to.equal('bar');
   9203  *         } else {
   9204  *           _super.call(this);
   9205  *         }
   9206  *       }
   9207  *     });
   9208  *
   9209  *
   9210  * Can also be accessed directly from `chai.Assertion`.
   9211  *
   9212  *     chai.Assertion.overwriteProperty('foo', fn);
   9213  *
   9214  * Then can be used as any other assertion.
   9215  *
   9216  *     expect(myFoo).to.be.ok;
   9217  *
   9218  * @param {Object} ctx object whose property is to be overwritten
   9219  * @param {String} name of property to overwrite
   9220  * @param {Function} getter function that returns a getter function to be used for name
   9221  * @namespace Utils
   9222  * @name overwriteProperty
   9223  * @api public
   9224  */
   9225 
   9226 module.exports = function overwriteProperty(ctx, name, getter) {
   9227   var _get = Object.getOwnPropertyDescriptor(ctx, name)
   9228     , _super = function () {};
   9229 
   9230   if (_get && 'function' === typeof _get.get)
   9231     _super = _get.get
   9232 
   9233   Object.defineProperty(ctx, name,
   9234     { get: function overwritingPropertyGetter() {
   9235         // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this
   9236         // function to be the starting point for removing implementation frames
   9237         // from the stack trace of a failed assertion.
   9238         //
   9239         // However, we only want to use this function as the starting point if
   9240         // the `lockSsfi` flag isn't set and proxy protection is disabled.
   9241         //
   9242         // If the `lockSsfi` flag is set, then either this assertion has been
   9243         // overwritten by another assertion, or this assertion is being invoked
   9244         // from inside of another assertion. In the first case, the `ssfi` flag
   9245         // has already been set by the overwriting assertion. In the second
   9246         // case, the `ssfi` flag has already been set by the outer assertion.
   9247         //
   9248         // If proxy protection is enabled, then the `ssfi` flag has already been
   9249         // set by the proxy getter.
   9250         if (!isProxyEnabled() && !flag(this, 'lockSsfi')) {
   9251           flag(this, 'ssfi', overwritingPropertyGetter);
   9252         }
   9253 
   9254         // Setting the `lockSsfi` flag to `true` prevents the overwritten
   9255         // assertion from changing the `ssfi` flag. By this point, the `ssfi`
   9256         // flag is already set to the correct starting point for this assertion.
   9257         var origLockSsfi = flag(this, 'lockSsfi');
   9258         flag(this, 'lockSsfi', true);
   9259         var result = getter(_super).call(this);
   9260         flag(this, 'lockSsfi', origLockSsfi);
   9261 
   9262         if (result !== undefined) {
   9263           return result;
   9264         }
   9265 
   9266         var newAssertion = new chai.Assertion();
   9267         transferFlags(this, newAssertion);
   9268         return newAssertion;
   9269       }
   9270     , configurable: true
   9271   });
   9272 };
   9273 
   9274 },{"../../chai":2,"./flag":15,"./isProxyEnabled":26,"./transferFlags":33}],31:[function(require,module,exports){
   9275 var config = require('../config');
   9276 var flag = require('./flag');
   9277 var getProperties = require('./getProperties');
   9278 var isProxyEnabled = require('./isProxyEnabled');
   9279 
   9280 /*!
   9281  * Chai - proxify utility
   9282  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   9283  * MIT Licensed
   9284  */
   9285 
   9286 /**
   9287  * ### .proxify(object)
   9288  *
   9289  * Return a proxy of given object that throws an error when a non-existent
   9290  * property is read. By default, the root cause is assumed to be a misspelled
   9291  * property, and thus an attempt is made to offer a reasonable suggestion from
   9292  * the list of existing properties. However, if a nonChainableMethodName is
   9293  * provided, then the root cause is instead a failure to invoke a non-chainable
   9294  * method prior to reading the non-existent property.
   9295  *
   9296  * If proxies are unsupported or disabled via the user's Chai config, then
   9297  * return object without modification.
   9298  *
   9299  * @param {Object} obj
   9300  * @param {String} nonChainableMethodName
   9301  * @namespace Utils
   9302  * @name proxify
   9303  */
   9304 
   9305 var builtins = ['__flags', '__methods', '_obj', 'assert'];
   9306 
   9307 module.exports = function proxify(obj, nonChainableMethodName) {
   9308   if (!isProxyEnabled()) return obj;
   9309 
   9310   return new Proxy(obj, {
   9311     get: function proxyGetter(target, property) {
   9312       // This check is here because we should not throw errors on Symbol properties
   9313       // such as `Symbol.toStringTag`.
   9314       // The values for which an error should be thrown can be configured using
   9315       // the `config.proxyExcludedKeys` setting.
   9316       if (typeof property === 'string' &&
   9317           config.proxyExcludedKeys.indexOf(property) === -1 &&
   9318           !Reflect.has(target, property)) {
   9319         // Special message for invalid property access of non-chainable methods.
   9320         if (nonChainableMethodName) {
   9321           throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' +
   9322             property + '. See docs for proper usage of "' +
   9323             nonChainableMethodName + '".');
   9324         }
   9325 
   9326         // If the property is reasonably close to an existing Chai property,
   9327         // suggest that property to the user. Only suggest properties with a
   9328         // distance less than 4.
   9329         var suggestion = null;
   9330         var suggestionDistance = 4;
   9331         getProperties(target).forEach(function(prop) {
   9332           if (
   9333             !Object.prototype.hasOwnProperty(prop) &&
   9334             builtins.indexOf(prop) === -1
   9335           ) {
   9336             var dist = stringDistanceCapped(
   9337               property,
   9338               prop,
   9339               suggestionDistance
   9340             );
   9341             if (dist < suggestionDistance) {
   9342               suggestion = prop;
   9343               suggestionDistance = dist;
   9344             }
   9345           }
   9346         });
   9347 
   9348         if (suggestion !== null) {
   9349           throw Error('Invalid Chai property: ' + property +
   9350             '. Did you mean "' + suggestion + '"?');
   9351         } else {
   9352           throw Error('Invalid Chai property: ' + property);
   9353         }
   9354       }
   9355 
   9356       // Use this proxy getter as the starting point for removing implementation
   9357       // frames from the stack trace of a failed assertion. For property
   9358       // assertions, this prevents the proxy getter from showing up in the stack
   9359       // trace since it's invoked before the property getter. For method and
   9360       // chainable method assertions, this flag will end up getting changed to
   9361       // the method wrapper, which is good since this frame will no longer be in
   9362       // the stack once the method is invoked. Note that Chai builtin assertion
   9363       // properties such as `__flags` are skipped since this is only meant to
   9364       // capture the starting point of an assertion. This step is also skipped
   9365       // if the `lockSsfi` flag is set, thus indicating that this assertion is
   9366       // being called from within another assertion. In that case, the `ssfi`
   9367       // flag is already set to the outer assertion's starting point.
   9368       if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) {
   9369         flag(target, 'ssfi', proxyGetter);
   9370       }
   9371 
   9372       return Reflect.get(target, property);
   9373     }
   9374   });
   9375 };
   9376 
   9377 /**
   9378  * # stringDistanceCapped(strA, strB, cap)
   9379  * Return the Levenshtein distance between two strings, but no more than cap.
   9380  * @param {string} strA
   9381  * @param {string} strB
   9382  * @param {number} number
   9383  * @return {number} min(string distance between strA and strB, cap)
   9384  * @api private
   9385  */
   9386 
   9387 function stringDistanceCapped(strA, strB, cap) {
   9388   if (Math.abs(strA.length - strB.length) >= cap) {
   9389     return cap;
   9390   }
   9391 
   9392   var memo = [];
   9393   // `memo` is a two-dimensional array containing distances.
   9394   // memo[i][j] is the distance between strA.slice(0, i) and
   9395   // strB.slice(0, j).
   9396   for (var i = 0; i <= strA.length; i++) {
   9397     memo[i] = Array(strB.length + 1).fill(0);
   9398     memo[i][0] = i;
   9399   }
   9400   for (var j = 0; j < strB.length; j++) {
   9401     memo[0][j] = j;
   9402   }
   9403 
   9404   for (var i = 1; i <= strA.length; i++) {
   9405     var ch = strA.charCodeAt(i - 1);
   9406     for (var j = 1; j <= strB.length; j++) {
   9407       if (Math.abs(i - j) >= cap) {
   9408         memo[i][j] = cap;
   9409         continue;
   9410       }
   9411       memo[i][j] = Math.min(
   9412         memo[i - 1][j] + 1,
   9413         memo[i][j - 1] + 1,
   9414         memo[i - 1][j - 1] +
   9415           (ch === strB.charCodeAt(j - 1) ? 0 : 1)
   9416       );
   9417     }
   9418   }
   9419 
   9420   return memo[strA.length][strB.length];
   9421 }
   9422 
   9423 },{"../config":4,"./flag":15,"./getProperties":22,"./isProxyEnabled":26}],32:[function(require,module,exports){
   9424 /*!
   9425  * Chai - test utility
   9426  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   9427  * MIT Licensed
   9428  */
   9429 
   9430 /*!
   9431  * Module dependencies
   9432  */
   9433 
   9434 var flag = require('./flag');
   9435 
   9436 /**
   9437  * ### .test(object, expression)
   9438  *
   9439  * Test and object for expression.
   9440  *
   9441  * @param {Object} object (constructed Assertion)
   9442  * @param {Arguments} chai.Assertion.prototype.assert arguments
   9443  * @namespace Utils
   9444  * @name test
   9445  */
   9446 
   9447 module.exports = function test(obj, args) {
   9448   var negate = flag(obj, 'negate')
   9449     , expr = args[0];
   9450   return negate ? !expr : expr;
   9451 };
   9452 
   9453 },{"./flag":15}],33:[function(require,module,exports){
   9454 /*!
   9455  * Chai - transferFlags utility
   9456  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
   9457  * MIT Licensed
   9458  */
   9459 
   9460 /**
   9461  * ### .transferFlags(assertion, object, includeAll = true)
   9462  *
   9463  * Transfer all the flags for `assertion` to `object`. If
   9464  * `includeAll` is set to `false`, then the base Chai
   9465  * assertion flags (namely `object`, `ssfi`, `lockSsfi`,
   9466  * and `message`) will not be transferred.
   9467  *
   9468  *
   9469  *     var newAssertion = new Assertion();
   9470  *     utils.transferFlags(assertion, newAssertion);
   9471  *
   9472  *     var anotherAssertion = new Assertion(myObj);
   9473  *     utils.transferFlags(assertion, anotherAssertion, false);
   9474  *
   9475  * @param {Assertion} assertion the assertion to transfer the flags from
   9476  * @param {Object} object the object to transfer the flags to; usually a new assertion
   9477  * @param {Boolean} includeAll
   9478  * @namespace Utils
   9479  * @name transferFlags
   9480  * @api private
   9481  */
   9482 
   9483 module.exports = function transferFlags(assertion, object, includeAll) {
   9484   var flags = assertion.__flags || (assertion.__flags = Object.create(null));
   9485 
   9486   if (!object.__flags) {
   9487     object.__flags = Object.create(null);
   9488   }
   9489 
   9490   includeAll = arguments.length === 3 ? includeAll : true;
   9491 
   9492   for (var flag in flags) {
   9493     if (includeAll ||
   9494         (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) {
   9495       object.__flags[flag] = flags[flag];
   9496     }
   9497   }
   9498 };
   9499 
   9500 },{}],34:[function(require,module,exports){
   9501 /*!
   9502  * assertion-error
   9503  * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>
   9504  * MIT Licensed
   9505  */
   9506 
   9507 /*!
   9508  * Return a function that will copy properties from
   9509  * one object to another excluding any originally
   9510  * listed. Returned function will create a new `{}`.
   9511  *
   9512  * @param {String} excluded properties ...
   9513  * @return {Function}
   9514  */
   9515 
   9516 function exclude () {
   9517   var excludes = [].slice.call(arguments);
   9518 
   9519   function excludeProps (res, obj) {
   9520     Object.keys(obj).forEach(function (key) {
   9521       if (!~excludes.indexOf(key)) res[key] = obj[key];
   9522     });
   9523   }
   9524 
   9525   return function extendExclude () {
   9526     var args = [].slice.call(arguments)
   9527       , i = 0
   9528       , res = {};
   9529 
   9530     for (; i < args.length; i++) {
   9531       excludeProps(res, args[i]);
   9532     }
   9533 
   9534     return res;
   9535   };
   9536 };
   9537 
   9538 /*!
   9539  * Primary Exports
   9540  */
   9541 
   9542 module.exports = AssertionError;
   9543 
   9544 /**
   9545  * ### AssertionError
   9546  *
   9547  * An extension of the JavaScript `Error` constructor for
   9548  * assertion and validation scenarios.
   9549  *
   9550  * @param {String} message
   9551  * @param {Object} properties to include (optional)
   9552  * @param {callee} start stack function (optional)
   9553  */
   9554 
   9555 function AssertionError (message, _props, ssf) {
   9556   var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')
   9557     , props = extend(_props || {});
   9558 
   9559   // default values
   9560   this.message = message || 'Unspecified AssertionError';
   9561   this.showDiff = false;
   9562 
   9563   // copy from properties
   9564   for (var key in props) {
   9565     this[key] = props[key];
   9566   }
   9567 
   9568   // capture stack trace
   9569   ssf = ssf || AssertionError;
   9570   if (Error.captureStackTrace) {
   9571     Error.captureStackTrace(this, ssf);
   9572   } else {
   9573     try {
   9574       throw new Error();
   9575     } catch(e) {
   9576       this.stack = e.stack;
   9577     }
   9578   }
   9579 }
   9580 
   9581 /*!
   9582  * Inherit from Error.prototype
   9583  */
   9584 
   9585 AssertionError.prototype = Object.create(Error.prototype);
   9586 
   9587 /*!
   9588  * Statically set name
   9589  */
   9590 
   9591 AssertionError.prototype.name = 'AssertionError';
   9592 
   9593 /*!
   9594  * Ensure correct constructor
   9595  */
   9596 
   9597 AssertionError.prototype.constructor = AssertionError;
   9598 
   9599 /**
   9600  * Allow errors to be converted to JSON for static transfer.
   9601  *
   9602  * @param {Boolean} include stack (default: `true`)
   9603  * @return {Object} object that can be `JSON.stringify`
   9604  */
   9605 
   9606 AssertionError.prototype.toJSON = function (stack) {
   9607   var extend = exclude('constructor', 'toJSON', 'stack')
   9608     , props = extend({ name: this.name }, this);
   9609 
   9610   // include stack if exists and not turned off
   9611   if (false !== stack && this.stack) {
   9612     props.stack = this.stack;
   9613   }
   9614 
   9615   return props;
   9616 };
   9617 
   9618 },{}],35:[function(require,module,exports){
   9619 'use strict';
   9620 
   9621 /* !
   9622  * Chai - checkError utility
   9623  * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
   9624  * MIT Licensed
   9625  */
   9626 
   9627 /**
   9628  * ### .checkError
   9629  *
   9630  * Checks that an error conforms to a given set of criteria and/or retrieves information about it.
   9631  *
   9632  * @api public
   9633  */
   9634 
   9635 /**
   9636  * ### .compatibleInstance(thrown, errorLike)
   9637  *
   9638  * Checks if two instances are compatible (strict equal).
   9639  * Returns false if errorLike is not an instance of Error, because instances
   9640  * can only be compatible if they're both error instances.
   9641  *
   9642  * @name compatibleInstance
   9643  * @param {Error} thrown error
   9644  * @param {Error|ErrorConstructor} errorLike object to compare against
   9645  * @namespace Utils
   9646  * @api public
   9647  */
   9648 
   9649 function compatibleInstance(thrown, errorLike) {
   9650   return errorLike instanceof Error && thrown === errorLike;
   9651 }
   9652 
   9653 /**
   9654  * ### .compatibleConstructor(thrown, errorLike)
   9655  *
   9656  * Checks if two constructors are compatible.
   9657  * This function can receive either an error constructor or
   9658  * an error instance as the `errorLike` argument.
   9659  * Constructors are compatible if they're the same or if one is
   9660  * an instance of another.
   9661  *
   9662  * @name compatibleConstructor
   9663  * @param {Error} thrown error
   9664  * @param {Error|ErrorConstructor} errorLike object to compare against
   9665  * @namespace Utils
   9666  * @api public
   9667  */
   9668 
   9669 function compatibleConstructor(thrown, errorLike) {
   9670   if (errorLike instanceof Error) {
   9671     // If `errorLike` is an instance of any error we compare their constructors
   9672     return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor;
   9673   } else if (errorLike.prototype instanceof Error || errorLike === Error) {
   9674     // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly
   9675     return thrown.constructor === errorLike || thrown instanceof errorLike;
   9676   }
   9677 
   9678   return false;
   9679 }
   9680 
   9681 /**
   9682  * ### .compatibleMessage(thrown, errMatcher)
   9683  *
   9684  * Checks if an error's message is compatible with a matcher (String or RegExp).
   9685  * If the message contains the String or passes the RegExp test,
   9686  * it is considered compatible.
   9687  *
   9688  * @name compatibleMessage
   9689  * @param {Error} thrown error
   9690  * @param {String|RegExp} errMatcher to look for into the message
   9691  * @namespace Utils
   9692  * @api public
   9693  */
   9694 
   9695 function compatibleMessage(thrown, errMatcher) {
   9696   var comparisonString = typeof thrown === 'string' ? thrown : thrown.message;
   9697   if (errMatcher instanceof RegExp) {
   9698     return errMatcher.test(comparisonString);
   9699   } else if (typeof errMatcher === 'string') {
   9700     return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers
   9701   }
   9702 
   9703   return false;
   9704 }
   9705 
   9706 /**
   9707  * ### .getFunctionName(constructorFn)
   9708  *
   9709  * Returns the name of a function.
   9710  * This also includes a polyfill function if `constructorFn.name` is not defined.
   9711  *
   9712  * @name getFunctionName
   9713  * @param {Function} constructorFn
   9714  * @namespace Utils
   9715  * @api private
   9716  */
   9717 
   9718 var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\(\/]+)/;
   9719 function getFunctionName(constructorFn) {
   9720   var name = '';
   9721   if (typeof constructorFn.name === 'undefined') {
   9722     // Here we run a polyfill if constructorFn.name is not defined
   9723     var match = String(constructorFn).match(functionNameMatch);
   9724     if (match) {
   9725       name = match[1];
   9726     }
   9727   } else {
   9728     name = constructorFn.name;
   9729   }
   9730 
   9731   return name;
   9732 }
   9733 
   9734 /**
   9735  * ### .getConstructorName(errorLike)
   9736  *
   9737  * Gets the constructor name for an Error instance or constructor itself.
   9738  *
   9739  * @name getConstructorName
   9740  * @param {Error|ErrorConstructor} errorLike
   9741  * @namespace Utils
   9742  * @api public
   9743  */
   9744 
   9745 function getConstructorName(errorLike) {
   9746   var constructorName = errorLike;
   9747   if (errorLike instanceof Error) {
   9748     constructorName = getFunctionName(errorLike.constructor);
   9749   } else if (typeof errorLike === 'function') {
   9750     // If `err` is not an instance of Error it is an error constructor itself or another function.
   9751     // If we've got a common function we get its name, otherwise we may need to create a new instance
   9752     // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more.
   9753     constructorName = getFunctionName(errorLike).trim() ||
   9754         getFunctionName(new errorLike()); // eslint-disable-line new-cap
   9755   }
   9756 
   9757   return constructorName;
   9758 }
   9759 
   9760 /**
   9761  * ### .getMessage(errorLike)
   9762  *
   9763  * Gets the error message from an error.
   9764  * If `err` is a String itself, we return it.
   9765  * If the error has no message, we return an empty string.
   9766  *
   9767  * @name getMessage
   9768  * @param {Error|String} errorLike
   9769  * @namespace Utils
   9770  * @api public
   9771  */
   9772 
   9773 function getMessage(errorLike) {
   9774   var msg = '';
   9775   if (errorLike && errorLike.message) {
   9776     msg = errorLike.message;
   9777   } else if (typeof errorLike === 'string') {
   9778     msg = errorLike;
   9779   }
   9780 
   9781   return msg;
   9782 }
   9783 
   9784 module.exports = {
   9785   compatibleInstance: compatibleInstance,
   9786   compatibleConstructor: compatibleConstructor,
   9787   compatibleMessage: compatibleMessage,
   9788   getMessage: getMessage,
   9789   getConstructorName: getConstructorName,
   9790 };
   9791 
   9792 },{}],36:[function(require,module,exports){
   9793 'use strict';
   9794 /* globals Symbol: false, Uint8Array: false, WeakMap: false */
   9795 /*!
   9796  * deep-eql
   9797  * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>
   9798  * MIT Licensed
   9799  */
   9800 
   9801 var type = require('type-detect');
   9802 function FakeMap() {
   9803   this._key = 'chai/deep-eql__' + Math.random() + Date.now();
   9804 }
   9805 
   9806 FakeMap.prototype = {
   9807   get: function getMap(key) {
   9808     return key[this._key];
   9809   },
   9810   set: function setMap(key, value) {
   9811     if (Object.isExtensible(key)) {
   9812       Object.defineProperty(key, this._key, {
   9813         value: value,
   9814         configurable: true,
   9815       });
   9816     }
   9817   },
   9818 };
   9819 
   9820 var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap;
   9821 /*!
   9822  * Check to see if the MemoizeMap has recorded a result of the two operands
   9823  *
   9824  * @param {Mixed} leftHandOperand
   9825  * @param {Mixed} rightHandOperand
   9826  * @param {MemoizeMap} memoizeMap
   9827  * @returns {Boolean|null} result
   9828 */
   9829 function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) {
   9830   // Technically, WeakMap keys can *only* be objects, not primitives.
   9831   if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
   9832     return null;
   9833   }
   9834   var leftHandMap = memoizeMap.get(leftHandOperand);
   9835   if (leftHandMap) {
   9836     var result = leftHandMap.get(rightHandOperand);
   9837     if (typeof result === 'boolean') {
   9838       return result;
   9839     }
   9840   }
   9841   return null;
   9842 }
   9843 
   9844 /*!
   9845  * Set the result of the equality into the MemoizeMap
   9846  *
   9847  * @param {Mixed} leftHandOperand
   9848  * @param {Mixed} rightHandOperand
   9849  * @param {MemoizeMap} memoizeMap
   9850  * @param {Boolean} result
   9851 */
   9852 function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) {
   9853   // Technically, WeakMap keys can *only* be objects, not primitives.
   9854   if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
   9855     return;
   9856   }
   9857   var leftHandMap = memoizeMap.get(leftHandOperand);
   9858   if (leftHandMap) {
   9859     leftHandMap.set(rightHandOperand, result);
   9860   } else {
   9861     leftHandMap = new MemoizeMap();
   9862     leftHandMap.set(rightHandOperand, result);
   9863     memoizeMap.set(leftHandOperand, leftHandMap);
   9864   }
   9865 }
   9866 
   9867 /*!
   9868  * Primary Export
   9869  */
   9870 
   9871 module.exports = deepEqual;
   9872 module.exports.MemoizeMap = MemoizeMap;
   9873 
   9874 /**
   9875  * Assert deeply nested sameValue equality between two objects of any type.
   9876  *
   9877  * @param {Mixed} leftHandOperand
   9878  * @param {Mixed} rightHandOperand
   9879  * @param {Object} [options] (optional) Additional options
   9880  * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality.
   9881  * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of
   9882     complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular
   9883     references to blow the stack.
   9884  * @return {Boolean} equal match
   9885  */
   9886 function deepEqual(leftHandOperand, rightHandOperand, options) {
   9887   // If we have a comparator, we can't assume anything; so bail to its check first.
   9888   if (options && options.comparator) {
   9889     return extensiveDeepEqual(leftHandOperand, rightHandOperand, options);
   9890   }
   9891 
   9892   var simpleResult = simpleEqual(leftHandOperand, rightHandOperand);
   9893   if (simpleResult !== null) {
   9894     return simpleResult;
   9895   }
   9896 
   9897   // Deeper comparisons are pushed through to a larger function
   9898   return extensiveDeepEqual(leftHandOperand, rightHandOperand, options);
   9899 }
   9900 
   9901 /**
   9902  * Many comparisons can be canceled out early via simple equality or primitive checks.
   9903  * @param {Mixed} leftHandOperand
   9904  * @param {Mixed} rightHandOperand
   9905  * @return {Boolean|null} equal match
   9906  */
   9907 function simpleEqual(leftHandOperand, rightHandOperand) {
   9908   // Equal references (except for Numbers) can be returned early
   9909   if (leftHandOperand === rightHandOperand) {
   9910     // Handle +-0 cases
   9911     return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand;
   9912   }
   9913 
   9914   // handle NaN cases
   9915   if (
   9916     leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare
   9917     rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare
   9918   ) {
   9919     return true;
   9920   }
   9921 
   9922   // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers,
   9923   // strings, and undefined, can be compared by reference.
   9924   if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
   9925     // Easy out b/c it would have passed the first equality check
   9926     return false;
   9927   }
   9928   return null;
   9929 }
   9930 
   9931 /*!
   9932  * The main logic of the `deepEqual` function.
   9933  *
   9934  * @param {Mixed} leftHandOperand
   9935  * @param {Mixed} rightHandOperand
   9936  * @param {Object} [options] (optional) Additional options
   9937  * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality.
   9938  * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of
   9939     complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular
   9940     references to blow the stack.
   9941  * @return {Boolean} equal match
   9942 */
   9943 function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) {
   9944   options = options || {};
   9945   options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap();
   9946   var comparator = options && options.comparator;
   9947 
   9948   // Check if a memoized result exists.
   9949   var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize);
   9950   if (memoizeResultLeft !== null) {
   9951     return memoizeResultLeft;
   9952   }
   9953   var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize);
   9954   if (memoizeResultRight !== null) {
   9955     return memoizeResultRight;
   9956   }
   9957 
   9958   // If a comparator is present, use it.
   9959   if (comparator) {
   9960     var comparatorResult = comparator(leftHandOperand, rightHandOperand);
   9961     // Comparators may return null, in which case we want to go back to default behavior.
   9962     if (comparatorResult === false || comparatorResult === true) {
   9963       memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult);
   9964       return comparatorResult;
   9965     }
   9966     // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide
   9967     // what to do, we need to make sure to return the basic tests first before we move on.
   9968     var simpleResult = simpleEqual(leftHandOperand, rightHandOperand);
   9969     if (simpleResult !== null) {
   9970       // Don't memoize this, it takes longer to set/retrieve than to just compare.
   9971       return simpleResult;
   9972     }
   9973   }
   9974 
   9975   var leftHandType = type(leftHandOperand);
   9976   if (leftHandType !== type(rightHandOperand)) {
   9977     memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false);
   9978     return false;
   9979   }
   9980 
   9981   // Temporarily set the operands in the memoize object to prevent blowing the stack
   9982   memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true);
   9983 
   9984   var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options);
   9985   memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result);
   9986   return result;
   9987 }
   9988 
   9989 function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) {
   9990   switch (leftHandType) {
   9991     case 'String':
   9992     case 'Number':
   9993     case 'Boolean':
   9994     case 'Date':
   9995       // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values
   9996       return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf());
   9997     case 'Promise':
   9998     case 'Symbol':
   9999     case 'function':
  10000     case 'WeakMap':
  10001     case 'WeakSet':
  10002     case 'Error':
  10003       return leftHandOperand === rightHandOperand;
  10004     case 'Arguments':
  10005     case 'Int8Array':
  10006     case 'Uint8Array':
  10007     case 'Uint8ClampedArray':
  10008     case 'Int16Array':
  10009     case 'Uint16Array':
  10010     case 'Int32Array':
  10011     case 'Uint32Array':
  10012     case 'Float32Array':
  10013     case 'Float64Array':
  10014     case 'Array':
  10015       return iterableEqual(leftHandOperand, rightHandOperand, options);
  10016     case 'RegExp':
  10017       return regexpEqual(leftHandOperand, rightHandOperand);
  10018     case 'Generator':
  10019       return generatorEqual(leftHandOperand, rightHandOperand, options);
  10020     case 'DataView':
  10021       return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options);
  10022     case 'ArrayBuffer':
  10023       return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options);
  10024     case 'Set':
  10025       return entriesEqual(leftHandOperand, rightHandOperand, options);
  10026     case 'Map':
  10027       return entriesEqual(leftHandOperand, rightHandOperand, options);
  10028     default:
  10029       return objectEqual(leftHandOperand, rightHandOperand, options);
  10030   }
  10031 }
  10032 
  10033 /*!
  10034  * Compare two Regular Expressions for equality.
  10035  *
  10036  * @param {RegExp} leftHandOperand
  10037  * @param {RegExp} rightHandOperand
  10038  * @return {Boolean} result
  10039  */
  10040 
  10041 function regexpEqual(leftHandOperand, rightHandOperand) {
  10042   return leftHandOperand.toString() === rightHandOperand.toString();
  10043 }
  10044 
  10045 /*!
  10046  * Compare two Sets/Maps for equality. Faster than other equality functions.
  10047  *
  10048  * @param {Set} leftHandOperand
  10049  * @param {Set} rightHandOperand
  10050  * @param {Object} [options] (Optional)
  10051  * @return {Boolean} result
  10052  */
  10053 
  10054 function entriesEqual(leftHandOperand, rightHandOperand, options) {
  10055   // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach
  10056   if (leftHandOperand.size !== rightHandOperand.size) {
  10057     return false;
  10058   }
  10059   if (leftHandOperand.size === 0) {
  10060     return true;
  10061   }
  10062   var leftHandItems = [];
  10063   var rightHandItems = [];
  10064   leftHandOperand.forEach(function gatherEntries(key, value) {
  10065     leftHandItems.push([ key, value ]);
  10066   });
  10067   rightHandOperand.forEach(function gatherEntries(key, value) {
  10068     rightHandItems.push([ key, value ]);
  10069   });
  10070   return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options);
  10071 }
  10072 
  10073 /*!
  10074  * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers.
  10075  *
  10076  * @param {Iterable} leftHandOperand
  10077  * @param {Iterable} rightHandOperand
  10078  * @param {Object} [options] (Optional)
  10079  * @return {Boolean} result
  10080  */
  10081 
  10082 function iterableEqual(leftHandOperand, rightHandOperand, options) {
  10083   var length = leftHandOperand.length;
  10084   if (length !== rightHandOperand.length) {
  10085     return false;
  10086   }
  10087   if (length === 0) {
  10088     return true;
  10089   }
  10090   var index = -1;
  10091   while (++index < length) {
  10092     if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) {
  10093       return false;
  10094     }
  10095   }
  10096   return true;
  10097 }
  10098 
  10099 /*!
  10100  * Simple equality for generator objects such as those returned by generator functions.
  10101  *
  10102  * @param {Iterable} leftHandOperand
  10103  * @param {Iterable} rightHandOperand
  10104  * @param {Object} [options] (Optional)
  10105  * @return {Boolean} result
  10106  */
  10107 
  10108 function generatorEqual(leftHandOperand, rightHandOperand, options) {
  10109   return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options);
  10110 }
  10111 
  10112 /*!
  10113  * Determine if the given object has an @@iterator function.
  10114  *
  10115  * @param {Object} target
  10116  * @return {Boolean} `true` if the object has an @@iterator function.
  10117  */
  10118 function hasIteratorFunction(target) {
  10119   return typeof Symbol !== 'undefined' &&
  10120     typeof target === 'object' &&
  10121     typeof Symbol.iterator !== 'undefined' &&
  10122     typeof target[Symbol.iterator] === 'function';
  10123 }
  10124 
  10125 /*!
  10126  * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array.
  10127  * This will consume the iterator - which could have side effects depending on the @@iterator implementation.
  10128  *
  10129  * @param {Object} target
  10130  * @returns {Array} an array of entries from the @@iterator function
  10131  */
  10132 function getIteratorEntries(target) {
  10133   if (hasIteratorFunction(target)) {
  10134     try {
  10135       return getGeneratorEntries(target[Symbol.iterator]());
  10136     } catch (iteratorError) {
  10137       return [];
  10138     }
  10139   }
  10140   return [];
  10141 }
  10142 
  10143 /*!
  10144  * Gets all entries from a Generator. This will consume the generator - which could have side effects.
  10145  *
  10146  * @param {Generator} target
  10147  * @returns {Array} an array of entries from the Generator.
  10148  */
  10149 function getGeneratorEntries(generator) {
  10150   var generatorResult = generator.next();
  10151   var accumulator = [ generatorResult.value ];
  10152   while (generatorResult.done === false) {
  10153     generatorResult = generator.next();
  10154     accumulator.push(generatorResult.value);
  10155   }
  10156   return accumulator;
  10157 }
  10158 
  10159 /*!
  10160  * Gets all own and inherited enumerable keys from a target.
  10161  *
  10162  * @param {Object} target
  10163  * @returns {Array} an array of own and inherited enumerable keys from the target.
  10164  */
  10165 function getEnumerableKeys(target) {
  10166   var keys = [];
  10167   for (var key in target) {
  10168     keys.push(key);
  10169   }
  10170   return keys;
  10171 }
  10172 
  10173 /*!
  10174  * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of
  10175  * each key. If any value of the given key is not equal, the function will return false (early).
  10176  *
  10177  * @param {Mixed} leftHandOperand
  10178  * @param {Mixed} rightHandOperand
  10179  * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against
  10180  * @param {Object} [options] (Optional)
  10181  * @return {Boolean} result
  10182  */
  10183 function keysEqual(leftHandOperand, rightHandOperand, keys, options) {
  10184   var length = keys.length;
  10185   if (length === 0) {
  10186     return true;
  10187   }
  10188   for (var i = 0; i < length; i += 1) {
  10189     if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) {
  10190       return false;
  10191     }
  10192   }
  10193   return true;
  10194 }
  10195 
  10196 /*!
  10197  * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual`
  10198  * for each enumerable key in the object.
  10199  *
  10200  * @param {Mixed} leftHandOperand
  10201  * @param {Mixed} rightHandOperand
  10202  * @param {Object} [options] (Optional)
  10203  * @return {Boolean} result
  10204  */
  10205 
  10206 function objectEqual(leftHandOperand, rightHandOperand, options) {
  10207   var leftHandKeys = getEnumerableKeys(leftHandOperand);
  10208   var rightHandKeys = getEnumerableKeys(rightHandOperand);
  10209   if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) {
  10210     leftHandKeys.sort();
  10211     rightHandKeys.sort();
  10212     if (iterableEqual(leftHandKeys, rightHandKeys) === false) {
  10213       return false;
  10214     }
  10215     return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options);
  10216   }
  10217 
  10218   var leftHandEntries = getIteratorEntries(leftHandOperand);
  10219   var rightHandEntries = getIteratorEntries(rightHandOperand);
  10220   if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) {
  10221     leftHandEntries.sort();
  10222     rightHandEntries.sort();
  10223     return iterableEqual(leftHandEntries, rightHandEntries, options);
  10224   }
  10225 
  10226   if (leftHandKeys.length === 0 &&
  10227       leftHandEntries.length === 0 &&
  10228       rightHandKeys.length === 0 &&
  10229       rightHandEntries.length === 0) {
  10230     return true;
  10231   }
  10232 
  10233   return false;
  10234 }
  10235 
  10236 /*!
  10237  * Returns true if the argument is a primitive.
  10238  *
  10239  * This intentionally returns true for all objects that can be compared by reference,
  10240  * including functions and symbols.
  10241  *
  10242  * @param {Mixed} value
  10243  * @return {Boolean} result
  10244  */
  10245 function isPrimitive(value) {
  10246   return value === null || typeof value !== 'object';
  10247 }
  10248 
  10249 },{"type-detect":39}],37:[function(require,module,exports){
  10250 'use strict';
  10251 
  10252 /* !
  10253  * Chai - getFuncName utility
  10254  * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
  10255  * MIT Licensed
  10256  */
  10257 
  10258 /**
  10259  * ### .getFuncName(constructorFn)
  10260  *
  10261  * Returns the name of a function.
  10262  * When a non-function instance is passed, returns `null`.
  10263  * This also includes a polyfill function if `aFunc.name` is not defined.
  10264  *
  10265  * @name getFuncName
  10266  * @param {Function} funct
  10267  * @namespace Utils
  10268  * @api public
  10269  */
  10270 
  10271 var toString = Function.prototype.toString;
  10272 var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/;
  10273 function getFuncName(aFunc) {
  10274   if (typeof aFunc !== 'function') {
  10275     return null;
  10276   }
  10277 
  10278   var name = '';
  10279   if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') {
  10280     // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined
  10281     var match = toString.call(aFunc).match(functionNameMatch);
  10282     if (match) {
  10283       name = match[1];
  10284     }
  10285   } else {
  10286     // If we've got a `name` property we just use it
  10287     name = aFunc.name;
  10288   }
  10289 
  10290   return name;
  10291 }
  10292 
  10293 module.exports = getFuncName;
  10294 
  10295 },{}],38:[function(require,module,exports){
  10296 'use strict';
  10297 
  10298 /* !
  10299  * Chai - pathval utility
  10300  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  10301  * @see https://github.com/logicalparadox/filtr
  10302  * MIT Licensed
  10303  */
  10304 
  10305 /**
  10306  * ### .hasProperty(object, name)
  10307  *
  10308  * This allows checking whether an object has own
  10309  * or inherited from prototype chain named property.
  10310  *
  10311  * Basically does the same thing as the `in`
  10312  * operator but works properly with null/undefined values
  10313  * and other primitives.
  10314  *
  10315  *     var obj = {
  10316  *         arr: ['a', 'b', 'c']
  10317  *       , str: 'Hello'
  10318  *     }
  10319  *
  10320  * The following would be the results.
  10321  *
  10322  *     hasProperty(obj, 'str');  // true
  10323  *     hasProperty(obj, 'constructor');  // true
  10324  *     hasProperty(obj, 'bar');  // false
  10325  *
  10326  *     hasProperty(obj.str, 'length'); // true
  10327  *     hasProperty(obj.str, 1);  // true
  10328  *     hasProperty(obj.str, 5);  // false
  10329  *
  10330  *     hasProperty(obj.arr, 'length');  // true
  10331  *     hasProperty(obj.arr, 2);  // true
  10332  *     hasProperty(obj.arr, 3);  // false
  10333  *
  10334  * @param {Object} object
  10335  * @param {String|Symbol} name
  10336  * @returns {Boolean} whether it exists
  10337  * @namespace Utils
  10338  * @name hasProperty
  10339  * @api public
  10340  */
  10341 
  10342 function hasProperty(obj, name) {
  10343   if (typeof obj === 'undefined' || obj === null) {
  10344     return false;
  10345   }
  10346 
  10347   // The `in` operator does not work with primitives.
  10348   return name in Object(obj);
  10349 }
  10350 
  10351 /* !
  10352  * ## parsePath(path)
  10353  *
  10354  * Helper function used to parse string object
  10355  * paths. Use in conjunction with `internalGetPathValue`.
  10356  *
  10357  *      var parsed = parsePath('myobject.property.subprop');
  10358  *
  10359  * ### Paths:
  10360  *
  10361  * * Can be infinitely deep and nested.
  10362  * * Arrays are also valid using the formal `myobject.document[3].property`.
  10363  * * Literal dots and brackets (not delimiter) must be backslash-escaped.
  10364  *
  10365  * @param {String} path
  10366  * @returns {Object} parsed
  10367  * @api private
  10368  */
  10369 
  10370 function parsePath(path) {
  10371   var str = path.replace(/([^\\])\[/g, '$1.[');
  10372   var parts = str.match(/(\\\.|[^.]+?)+/g);
  10373   return parts.map(function mapMatches(value) {
  10374     if (
  10375       value === 'constructor' ||
  10376       value === '__proto__' ||
  10377       value === 'prototype'
  10378     ) {
  10379       return {};
  10380     }
  10381     var regexp = /^\[(\d+)\]$/;
  10382     var mArr = regexp.exec(value);
  10383     var parsed = null;
  10384     if (mArr) {
  10385       parsed = { i: parseFloat(mArr[1]) };
  10386     } else {
  10387       parsed = { p: value.replace(/\\([.[\]])/g, '$1') };
  10388     }
  10389 
  10390     return parsed;
  10391   });
  10392 }
  10393 
  10394 /* !
  10395  * ## internalGetPathValue(obj, parsed[, pathDepth])
  10396  *
  10397  * Helper companion function for `.parsePath` that returns
  10398  * the value located at the parsed address.
  10399  *
  10400  *      var value = getPathValue(obj, parsed);
  10401  *
  10402  * @param {Object} object to search against
  10403  * @param {Object} parsed definition from `parsePath`.
  10404  * @param {Number} depth (nesting level) of the property we want to retrieve
  10405  * @returns {Object|Undefined} value
  10406  * @api private
  10407  */
  10408 
  10409 function internalGetPathValue(obj, parsed, pathDepth) {
  10410   var temporaryValue = obj;
  10411   var res = null;
  10412   pathDepth = typeof pathDepth === 'undefined' ? parsed.length : pathDepth;
  10413 
  10414   for (var i = 0; i < pathDepth; i++) {
  10415     var part = parsed[i];
  10416     if (temporaryValue) {
  10417       if (typeof part.p === 'undefined') {
  10418         temporaryValue = temporaryValue[part.i];
  10419       } else {
  10420         temporaryValue = temporaryValue[part.p];
  10421       }
  10422 
  10423       if (i === pathDepth - 1) {
  10424         res = temporaryValue;
  10425       }
  10426     }
  10427   }
  10428 
  10429   return res;
  10430 }
  10431 
  10432 /* !
  10433  * ## internalSetPathValue(obj, value, parsed)
  10434  *
  10435  * Companion function for `parsePath` that sets
  10436  * the value located at a parsed address.
  10437  *
  10438  *  internalSetPathValue(obj, 'value', parsed);
  10439  *
  10440  * @param {Object} object to search and define on
  10441  * @param {*} value to use upon set
  10442  * @param {Object} parsed definition from `parsePath`
  10443  * @api private
  10444  */
  10445 
  10446 function internalSetPathValue(obj, val, parsed) {
  10447   var tempObj = obj;
  10448   var pathDepth = parsed.length;
  10449   var part = null;
  10450   // Here we iterate through every part of the path
  10451   for (var i = 0; i < pathDepth; i++) {
  10452     var propName = null;
  10453     var propVal = null;
  10454     part = parsed[i];
  10455 
  10456     // If it's the last part of the path, we set the 'propName' value with the property name
  10457     if (i === pathDepth - 1) {
  10458       propName = typeof part.p === 'undefined' ? part.i : part.p;
  10459       // Now we set the property with the name held by 'propName' on object with the desired val
  10460       tempObj[propName] = val;
  10461     } else if (typeof part.p !== 'undefined' && tempObj[part.p]) {
  10462       tempObj = tempObj[part.p];
  10463     } else if (typeof part.i !== 'undefined' && tempObj[part.i]) {
  10464       tempObj = tempObj[part.i];
  10465     } else {
  10466       // If the obj doesn't have the property we create one with that name to define it
  10467       var next = parsed[i + 1];
  10468       // Here we set the name of the property which will be defined
  10469       propName = typeof part.p === 'undefined' ? part.i : part.p;
  10470       // Here we decide if this property will be an array or a new object
  10471       propVal = typeof next.p === 'undefined' ? [] : {};
  10472       tempObj[propName] = propVal;
  10473       tempObj = tempObj[propName];
  10474     }
  10475   }
  10476 }
  10477 
  10478 /**
  10479  * ### .getPathInfo(object, path)
  10480  *
  10481  * This allows the retrieval of property info in an
  10482  * object given a string path.
  10483  *
  10484  * The path info consists of an object with the
  10485  * following properties:
  10486  *
  10487  * * parent - The parent object of the property referenced by `path`
  10488  * * name - The name of the final property, a number if it was an array indexer
  10489  * * value - The value of the property, if it exists, otherwise `undefined`
  10490  * * exists - Whether the property exists or not
  10491  *
  10492  * @param {Object} object
  10493  * @param {String} path
  10494  * @returns {Object} info
  10495  * @namespace Utils
  10496  * @name getPathInfo
  10497  * @api public
  10498  */
  10499 
  10500 function getPathInfo(obj, path) {
  10501   var parsed = parsePath(path);
  10502   var last = parsed[parsed.length - 1];
  10503   var info = {
  10504     parent:
  10505       parsed.length > 1 ?
  10506         internalGetPathValue(obj, parsed, parsed.length - 1) :
  10507         obj,
  10508     name: last.p || last.i,
  10509     value: internalGetPathValue(obj, parsed),
  10510   };
  10511   info.exists = hasProperty(info.parent, info.name);
  10512 
  10513   return info;
  10514 }
  10515 
  10516 /**
  10517  * ### .getPathValue(object, path)
  10518  *
  10519  * This allows the retrieval of values in an
  10520  * object given a string path.
  10521  *
  10522  *     var obj = {
  10523  *         prop1: {
  10524  *             arr: ['a', 'b', 'c']
  10525  *           , str: 'Hello'
  10526  *         }
  10527  *       , prop2: {
  10528  *             arr: [ { nested: 'Universe' } ]
  10529  *           , str: 'Hello again!'
  10530  *         }
  10531  *     }
  10532  *
  10533  * The following would be the results.
  10534  *
  10535  *     getPathValue(obj, 'prop1.str'); // Hello
  10536  *     getPathValue(obj, 'prop1.att[2]'); // b
  10537  *     getPathValue(obj, 'prop2.arr[0].nested'); // Universe
  10538  *
  10539  * @param {Object} object
  10540  * @param {String} path
  10541  * @returns {Object} value or `undefined`
  10542  * @namespace Utils
  10543  * @name getPathValue
  10544  * @api public
  10545  */
  10546 
  10547 function getPathValue(obj, path) {
  10548   var info = getPathInfo(obj, path);
  10549   return info.value;
  10550 }
  10551 
  10552 /**
  10553  * ### .setPathValue(object, path, value)
  10554  *
  10555  * Define the value in an object at a given string path.
  10556  *
  10557  * ```js
  10558  * var obj = {
  10559  *     prop1: {
  10560  *         arr: ['a', 'b', 'c']
  10561  *       , str: 'Hello'
  10562  *     }
  10563  *   , prop2: {
  10564  *         arr: [ { nested: 'Universe' } ]
  10565  *       , str: 'Hello again!'
  10566  *     }
  10567  * };
  10568  * ```
  10569  *
  10570  * The following would be acceptable.
  10571  *
  10572  * ```js
  10573  * var properties = require('tea-properties');
  10574  * properties.set(obj, 'prop1.str', 'Hello Universe!');
  10575  * properties.set(obj, 'prop1.arr[2]', 'B');
  10576  * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' });
  10577  * ```
  10578  *
  10579  * @param {Object} object
  10580  * @param {String} path
  10581  * @param {Mixed} value
  10582  * @api private
  10583  */
  10584 
  10585 function setPathValue(obj, path, val) {
  10586   var parsed = parsePath(path);
  10587   internalSetPathValue(obj, val, parsed);
  10588   return obj;
  10589 }
  10590 
  10591 module.exports = {
  10592   hasProperty: hasProperty,
  10593   getPathInfo: getPathInfo,
  10594   getPathValue: getPathValue,
  10595   setPathValue: setPathValue,
  10596 };
  10597 
  10598 },{}],39:[function(require,module,exports){
  10599 (function (global, factory) {
  10600 	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  10601 	typeof define === 'function' && define.amd ? define(factory) :
  10602 	(global.typeDetect = factory());
  10603 }(this, (function () { 'use strict';
  10604 
  10605 /* !
  10606  * type-detect
  10607  * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
  10608  * MIT Licensed
  10609  */
  10610 var promiseExists = typeof Promise === 'function';
  10611 
  10612 /* eslint-disable no-undef */
  10613 var globalObject = typeof self === 'object' ? self : global; // eslint-disable-line id-blacklist
  10614 
  10615 var symbolExists = typeof Symbol !== 'undefined';
  10616 var mapExists = typeof Map !== 'undefined';
  10617 var setExists = typeof Set !== 'undefined';
  10618 var weakMapExists = typeof WeakMap !== 'undefined';
  10619 var weakSetExists = typeof WeakSet !== 'undefined';
  10620 var dataViewExists = typeof DataView !== 'undefined';
  10621 var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined';
  10622 var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined';
  10623 var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';
  10624 var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';
  10625 var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries());
  10626 var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries());
  10627 var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
  10628 var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
  10629 var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function';
  10630 var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());
  10631 var toStringLeftSliceLength = 8;
  10632 var toStringRightSliceLength = -1;
  10633 /**
  10634  * ### typeOf (obj)
  10635  *
  10636  * Uses `Object.prototype.toString` to determine the type of an object,
  10637  * normalising behaviour across engine versions & well optimised.
  10638  *
  10639  * @param {Mixed} object
  10640  * @return {String} object type
  10641  * @api public
  10642  */
  10643 function typeDetect(obj) {
  10644   /* ! Speed optimisation
  10645    * Pre:
  10646    *   string literal     x 3,039,035 ops/sec ±1.62% (78 runs sampled)
  10647    *   boolean literal    x 1,424,138 ops/sec ±4.54% (75 runs sampled)
  10648    *   number literal     x 1,653,153 ops/sec ±1.91% (82 runs sampled)
  10649    *   undefined          x 9,978,660 ops/sec ±1.92% (75 runs sampled)
  10650    *   function           x 2,556,769 ops/sec ±1.73% (77 runs sampled)
  10651    * Post:
  10652    *   string literal     x 38,564,796 ops/sec ±1.15% (79 runs sampled)
  10653    *   boolean literal    x 31,148,940 ops/sec ±1.10% (79 runs sampled)
  10654    *   number literal     x 32,679,330 ops/sec ±1.90% (78 runs sampled)
  10655    *   undefined          x 32,363,368 ops/sec ±1.07% (82 runs sampled)
  10656    *   function           x 31,296,870 ops/sec ±0.96% (83 runs sampled)
  10657    */
  10658   var typeofObj = typeof obj;
  10659   if (typeofObj !== 'object') {
  10660     return typeofObj;
  10661   }
  10662 
  10663   /* ! Speed optimisation
  10664    * Pre:
  10665    *   null               x 28,645,765 ops/sec ±1.17% (82 runs sampled)
  10666    * Post:
  10667    *   null               x 36,428,962 ops/sec ±1.37% (84 runs sampled)
  10668    */
  10669   if (obj === null) {
  10670     return 'null';
  10671   }
  10672 
  10673   /* ! Spec Conformance
  10674    * Test: `Object.prototype.toString.call(window)``
  10675    *  - Node === "[object global]"
  10676    *  - Chrome === "[object global]"
  10677    *  - Firefox === "[object Window]"
  10678    *  - PhantomJS === "[object Window]"
  10679    *  - Safari === "[object Window]"
  10680    *  - IE 11 === "[object Window]"
  10681    *  - IE Edge === "[object Window]"
  10682    * Test: `Object.prototype.toString.call(this)``
  10683    *  - Chrome Worker === "[object global]"
  10684    *  - Firefox Worker === "[object DedicatedWorkerGlobalScope]"
  10685    *  - Safari Worker === "[object DedicatedWorkerGlobalScope]"
  10686    *  - IE 11 Worker === "[object WorkerGlobalScope]"
  10687    *  - IE Edge Worker === "[object WorkerGlobalScope]"
  10688    */
  10689   if (obj === globalObject) {
  10690     return 'global';
  10691   }
  10692 
  10693   /* ! Speed optimisation
  10694    * Pre:
  10695    *   array literal      x 2,888,352 ops/sec ±0.67% (82 runs sampled)
  10696    * Post:
  10697    *   array literal      x 22,479,650 ops/sec ±0.96% (81 runs sampled)
  10698    */
  10699   if (
  10700     Array.isArray(obj) &&
  10701     (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))
  10702   ) {
  10703     return 'Array';
  10704   }
  10705 
  10706   // Not caching existence of `window` and related properties due to potential
  10707   // for `window` to be unset before tests in quasi-browser environments.
  10708   if (typeof window === 'object' && window !== null) {
  10709     /* ! Spec Conformance
  10710      * (https://html.spec.whatwg.org/multipage/browsers.html#location)
  10711      * WhatWG HTML$7.7.3 - The `Location` interface
  10712      * Test: `Object.prototype.toString.call(window.location)``
  10713      *  - IE <=11 === "[object Object]"
  10714      *  - IE Edge <=13 === "[object Object]"
  10715      */
  10716     if (typeof window.location === 'object' && obj === window.location) {
  10717       return 'Location';
  10718     }
  10719 
  10720     /* ! Spec Conformance
  10721      * (https://html.spec.whatwg.org/#document)
  10722      * WhatWG HTML$3.1.1 - The `Document` object
  10723      * Note: Most browsers currently adher to the W3C DOM Level 2 spec
  10724      *       (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268)
  10725      *       which suggests that browsers should use HTMLTableCellElement for
  10726      *       both TD and TH elements. WhatWG separates these.
  10727      *       WhatWG HTML states:
  10728      *         > For historical reasons, Window objects must also have a
  10729      *         > writable, configurable, non-enumerable property named
  10730      *         > HTMLDocument whose value is the Document interface object.
  10731      * Test: `Object.prototype.toString.call(document)``
  10732      *  - Chrome === "[object HTMLDocument]"
  10733      *  - Firefox === "[object HTMLDocument]"
  10734      *  - Safari === "[object HTMLDocument]"
  10735      *  - IE <=10 === "[object Document]"
  10736      *  - IE 11 === "[object HTMLDocument]"
  10737      *  - IE Edge <=13 === "[object HTMLDocument]"
  10738      */
  10739     if (typeof window.document === 'object' && obj === window.document) {
  10740       return 'Document';
  10741     }
  10742 
  10743     if (typeof window.navigator === 'object') {
  10744       /* ! Spec Conformance
  10745        * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
  10746        * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
  10747        * Test: `Object.prototype.toString.call(navigator.mimeTypes)``
  10748        *  - IE <=10 === "[object MSMimeTypesCollection]"
  10749        */
  10750       if (typeof window.navigator.mimeTypes === 'object' &&
  10751           obj === window.navigator.mimeTypes) {
  10752         return 'MimeTypeArray';
  10753       }
  10754 
  10755       /* ! Spec Conformance
  10756        * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
  10757        * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
  10758        * Test: `Object.prototype.toString.call(navigator.plugins)``
  10759        *  - IE <=10 === "[object MSPluginsCollection]"
  10760        */
  10761       if (typeof window.navigator.plugins === 'object' &&
  10762           obj === window.navigator.plugins) {
  10763         return 'PluginArray';
  10764       }
  10765     }
  10766 
  10767     if ((typeof window.HTMLElement === 'function' ||
  10768         typeof window.HTMLElement === 'object') &&
  10769         obj instanceof window.HTMLElement) {
  10770       /* ! Spec Conformance
  10771       * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
  10772       * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
  10773       * Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
  10774       *  - IE <=10 === "[object HTMLBlockElement]"
  10775       */
  10776       if (obj.tagName === 'BLOCKQUOTE') {
  10777         return 'HTMLQuoteElement';
  10778       }
  10779 
  10780       /* ! Spec Conformance
  10781        * (https://html.spec.whatwg.org/#htmltabledatacellelement)
  10782        * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
  10783        * Note: Most browsers currently adher to the W3C DOM Level 2 spec
  10784        *       (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
  10785        *       which suggests that browsers should use HTMLTableCellElement for
  10786        *       both TD and TH elements. WhatWG separates these.
  10787        * Test: Object.prototype.toString.call(document.createElement('td'))
  10788        *  - Chrome === "[object HTMLTableCellElement]"
  10789        *  - Firefox === "[object HTMLTableCellElement]"
  10790        *  - Safari === "[object HTMLTableCellElement]"
  10791        */
  10792       if (obj.tagName === 'TD') {
  10793         return 'HTMLTableDataCellElement';
  10794       }
  10795 
  10796       /* ! Spec Conformance
  10797        * (https://html.spec.whatwg.org/#htmltableheadercellelement)
  10798        * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
  10799        * Note: Most browsers currently adher to the W3C DOM Level 2 spec
  10800        *       (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
  10801        *       which suggests that browsers should use HTMLTableCellElement for
  10802        *       both TD and TH elements. WhatWG separates these.
  10803        * Test: Object.prototype.toString.call(document.createElement('th'))
  10804        *  - Chrome === "[object HTMLTableCellElement]"
  10805        *  - Firefox === "[object HTMLTableCellElement]"
  10806        *  - Safari === "[object HTMLTableCellElement]"
  10807        */
  10808       if (obj.tagName === 'TH') {
  10809         return 'HTMLTableHeaderCellElement';
  10810       }
  10811     }
  10812   }
  10813 
  10814   /* ! Speed optimisation
  10815   * Pre:
  10816   *   Float64Array       x 625,644 ops/sec ±1.58% (80 runs sampled)
  10817   *   Float32Array       x 1,279,852 ops/sec ±2.91% (77 runs sampled)
  10818   *   Uint32Array        x 1,178,185 ops/sec ±1.95% (83 runs sampled)
  10819   *   Uint16Array        x 1,008,380 ops/sec ±2.25% (80 runs sampled)
  10820   *   Uint8Array         x 1,128,040 ops/sec ±2.11% (81 runs sampled)
  10821   *   Int32Array         x 1,170,119 ops/sec ±2.88% (80 runs sampled)
  10822   *   Int16Array         x 1,176,348 ops/sec ±5.79% (86 runs sampled)
  10823   *   Int8Array          x 1,058,707 ops/sec ±4.94% (77 runs sampled)
  10824   *   Uint8ClampedArray  x 1,110,633 ops/sec ±4.20% (80 runs sampled)
  10825   * Post:
  10826   *   Float64Array       x 7,105,671 ops/sec ±13.47% (64 runs sampled)
  10827   *   Float32Array       x 5,887,912 ops/sec ±1.46% (82 runs sampled)
  10828   *   Uint32Array        x 6,491,661 ops/sec ±1.76% (79 runs sampled)
  10829   *   Uint16Array        x 6,559,795 ops/sec ±1.67% (82 runs sampled)
  10830   *   Uint8Array         x 6,463,966 ops/sec ±1.43% (85 runs sampled)
  10831   *   Int32Array         x 5,641,841 ops/sec ±3.49% (81 runs sampled)
  10832   *   Int16Array         x 6,583,511 ops/sec ±1.98% (80 runs sampled)
  10833   *   Int8Array          x 6,606,078 ops/sec ±1.74% (81 runs sampled)
  10834   *   Uint8ClampedArray  x 6,602,224 ops/sec ±1.77% (83 runs sampled)
  10835   */
  10836   var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]);
  10837   if (typeof stringTag === 'string') {
  10838     return stringTag;
  10839   }
  10840 
  10841   var objPrototype = Object.getPrototypeOf(obj);
  10842   /* ! Speed optimisation
  10843   * Pre:
  10844   *   regex literal      x 1,772,385 ops/sec ±1.85% (77 runs sampled)
  10845   *   regex constructor  x 2,143,634 ops/sec ±2.46% (78 runs sampled)
  10846   * Post:
  10847   *   regex literal      x 3,928,009 ops/sec ±0.65% (78 runs sampled)
  10848   *   regex constructor  x 3,931,108 ops/sec ±0.58% (84 runs sampled)
  10849   */
  10850   if (objPrototype === RegExp.prototype) {
  10851     return 'RegExp';
  10852   }
  10853 
  10854   /* ! Speed optimisation
  10855   * Pre:
  10856   *   date               x 2,130,074 ops/sec ±4.42% (68 runs sampled)
  10857   * Post:
  10858   *   date               x 3,953,779 ops/sec ±1.35% (77 runs sampled)
  10859   */
  10860   if (objPrototype === Date.prototype) {
  10861     return 'Date';
  10862   }
  10863 
  10864   /* ! Spec Conformance
  10865    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag)
  10866    * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise":
  10867    * Test: `Object.prototype.toString.call(Promise.resolve())``
  10868    *  - Chrome <=47 === "[object Object]"
  10869    *  - Edge <=20 === "[object Object]"
  10870    *  - Firefox 29-Latest === "[object Promise]"
  10871    *  - Safari 7.1-Latest === "[object Promise]"
  10872    */
  10873   if (promiseExists && objPrototype === Promise.prototype) {
  10874     return 'Promise';
  10875   }
  10876 
  10877   /* ! Speed optimisation
  10878   * Pre:
  10879   *   set                x 2,222,186 ops/sec ±1.31% (82 runs sampled)
  10880   * Post:
  10881   *   set                x 4,545,879 ops/sec ±1.13% (83 runs sampled)
  10882   */
  10883   if (setExists && objPrototype === Set.prototype) {
  10884     return 'Set';
  10885   }
  10886 
  10887   /* ! Speed optimisation
  10888   * Pre:
  10889   *   map                x 2,396,842 ops/sec ±1.59% (81 runs sampled)
  10890   * Post:
  10891   *   map                x 4,183,945 ops/sec ±6.59% (82 runs sampled)
  10892   */
  10893   if (mapExists && objPrototype === Map.prototype) {
  10894     return 'Map';
  10895   }
  10896 
  10897   /* ! Speed optimisation
  10898   * Pre:
  10899   *   weakset            x 1,323,220 ops/sec ±2.17% (76 runs sampled)
  10900   * Post:
  10901   *   weakset            x 4,237,510 ops/sec ±2.01% (77 runs sampled)
  10902   */
  10903   if (weakSetExists && objPrototype === WeakSet.prototype) {
  10904     return 'WeakSet';
  10905   }
  10906 
  10907   /* ! Speed optimisation
  10908   * Pre:
  10909   *   weakmap            x 1,500,260 ops/sec ±2.02% (78 runs sampled)
  10910   * Post:
  10911   *   weakmap            x 3,881,384 ops/sec ±1.45% (82 runs sampled)
  10912   */
  10913   if (weakMapExists && objPrototype === WeakMap.prototype) {
  10914     return 'WeakMap';
  10915   }
  10916 
  10917   /* ! Spec Conformance
  10918    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag)
  10919    * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView":
  10920    * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))``
  10921    *  - Edge <=13 === "[object Object]"
  10922    */
  10923   if (dataViewExists && objPrototype === DataView.prototype) {
  10924     return 'DataView';
  10925   }
  10926 
  10927   /* ! Spec Conformance
  10928    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag)
  10929    * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator":
  10930    * Test: `Object.prototype.toString.call(new Map().entries())``
  10931    *  - Edge <=13 === "[object Object]"
  10932    */
  10933   if (mapExists && objPrototype === mapIteratorPrototype) {
  10934     return 'Map Iterator';
  10935   }
  10936 
  10937   /* ! Spec Conformance
  10938    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag)
  10939    * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator":
  10940    * Test: `Object.prototype.toString.call(new Set().entries())``
  10941    *  - Edge <=13 === "[object Object]"
  10942    */
  10943   if (setExists && objPrototype === setIteratorPrototype) {
  10944     return 'Set Iterator';
  10945   }
  10946 
  10947   /* ! Spec Conformance
  10948    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag)
  10949    * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator":
  10950    * Test: `Object.prototype.toString.call([][Symbol.iterator]())``
  10951    *  - Edge <=13 === "[object Object]"
  10952    */
  10953   if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
  10954     return 'Array Iterator';
  10955   }
  10956 
  10957   /* ! Spec Conformance
  10958    * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag)
  10959    * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator":
  10960    * Test: `Object.prototype.toString.call(''[Symbol.iterator]())``
  10961    *  - Edge <=13 === "[object Object]"
  10962    */
  10963   if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
  10964     return 'String Iterator';
  10965   }
  10966 
  10967   /* ! Speed optimisation
  10968   * Pre:
  10969   *   object from null   x 2,424,320 ops/sec ±1.67% (76 runs sampled)
  10970   * Post:
  10971   *   object from null   x 5,838,000 ops/sec ±0.99% (84 runs sampled)
  10972   */
  10973   if (objPrototype === null) {
  10974     return 'Object';
  10975   }
  10976 
  10977   return Object
  10978     .prototype
  10979     .toString
  10980     .call(obj)
  10981     .slice(toStringLeftSliceLength, toStringRightSliceLength);
  10982 }
  10983 
  10984 return typeDetect;
  10985 
  10986 })));
  10987 
  10988 },{}]},{},[1])(1)
  10989 });