💾 Archived View for gmi.noulin.net › gitRepositories › git-off › file › node_modules › chai › chai.j… captured on 2023-07-10 at 15:57:05. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

git-off

Log

Files

Refs

README

chai.js (158570B)

     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 e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({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   , exports = module.exports = {};
    13 
    14 /*!
    15  * Chai version
    16  */
    17 
    18 exports.version = '3.5.0';
    19 
    20 /*!
    21  * Assertion Error
    22  */
    23 
    24 exports.AssertionError = require('assertion-error');
    25 
    26 /*!
    27  * Utils for plugins (not exported)
    28  */
    29 
    30 var util = require('./chai/utils');
    31 
    32 /**
    33  * # .use(function)
    34  *
    35  * Provides a way to extend the internals of Chai
    36  *
    37  * @param {Function}
    38  * @returns {this} for chaining
    39  * @api public
    40  */
    41 
    42 exports.use = function (fn) {
    43   if (!~used.indexOf(fn)) {
    44     fn(this, util);
    45     used.push(fn);
    46   }
    47 
    48   return this;
    49 };
    50 
    51 /*!
    52  * Utility Functions
    53  */
    54 
    55 exports.util = util;
    56 
    57 /*!
    58  * Configuration
    59  */
    60 
    61 var config = require('./chai/config');
    62 exports.config = config;
    63 
    64 /*!
    65  * Primary `Assertion` prototype
    66  */
    67 
    68 var assertion = require('./chai/assertion');
    69 exports.use(assertion);
    70 
    71 /*!
    72  * Core Assertions
    73  */
    74 
    75 var core = require('./chai/core/assertions');
    76 exports.use(core);
    77 
    78 /*!
    79  * Expect interface
    80  */
    81 
    82 var expect = require('./chai/interface/expect');
    83 exports.use(expect);
    84 
    85 /*!
    86  * Should interface
    87  */
    88 
    89 var should = require('./chai/interface/should');
    90 exports.use(should);
    91 
    92 /*!
    93  * Assert interface
    94  */
    95 
    96 var assert = require('./chai/interface/assert');
    97 exports.use(assert);
    98 
    99 },{"./chai/assertion":3,"./chai/config":4,"./chai/core/assertions":5,"./chai/interface/assert":6,"./chai/interface/expect":7,"./chai/interface/should":8,"./chai/utils":22,"assertion-error":30}],3:[function(require,module,exports){
   100 /*!
   101  * chai
   102  * http://chaijs.com
   103  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
   104  * MIT Licensed
   105  */
   106 
   107 var config = require('./config');
   108 
   109 module.exports = function (_chai, util) {
   110   /*!
   111    * Module dependencies.
   112    */
   113 
   114   var AssertionError = _chai.AssertionError
   115     , flag = util.flag;
   116 
   117   /*!
   118    * Module export.
   119    */
   120 
   121   _chai.Assertion = Assertion;
   122 
   123   /*!
   124    * Assertion Constructor
   125    *
   126    * Creates object for chaining.
   127    *
   128    * @api private
   129    */
   130 
   131   function Assertion (obj, msg, stack) {
   132     flag(this, 'ssfi', stack || arguments.callee);
   133     flag(this, 'object', obj);
   134     flag(this, 'message', msg);
   135   }
   136 
   137   Object.defineProperty(Assertion, 'includeStack', {
   138     get: function() {
   139       console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
   140       return config.includeStack;
   141     },
   142     set: function(value) {
   143       console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
   144       config.includeStack = value;
   145     }
   146   });
   147 
   148   Object.defineProperty(Assertion, 'showDiff', {
   149     get: function() {
   150       console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
   151       return config.showDiff;
   152     },
   153     set: function(value) {
   154       console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
   155       config.showDiff = value;
   156     }
   157   });
   158 
   159   Assertion.addProperty = function (name, fn) {
   160     util.addProperty(this.prototype, name, fn);
   161   };
   162 
   163   Assertion.addMethod = function (name, fn) {
   164     util.addMethod(this.prototype, name, fn);
   165   };
   166 
   167   Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
   168     util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
   169   };
   170 
   171   Assertion.overwriteProperty = function (name, fn) {
   172     util.overwriteProperty(this.prototype, name, fn);
   173   };
   174 
   175   Assertion.overwriteMethod = function (name, fn) {
   176     util.overwriteMethod(this.prototype, name, fn);
   177   };
   178 
   179   Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {
   180     util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
   181   };
   182 
   183   /**
   184    * ### .assert(expression, message, negateMessage, expected, actual, showDiff)
   185    *
   186    * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
   187    *
   188    * @name assert
   189    * @param {Philosophical} expression to be tested
   190    * @param {String|Function} message or function that returns message to display if expression fails
   191    * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails
   192    * @param {Mixed} expected value (remember to check for negation)
   193    * @param {Mixed} actual (optional) will default to `this.obj`
   194    * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails
   195    * @api private
   196    */
   197 
   198   Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
   199     var ok = util.test(this, arguments);
   200     if (true !== showDiff) showDiff = false;
   201     if (true !== config.showDiff) showDiff = false;
   202 
   203     if (!ok) {
   204       var msg = util.getMessage(this, arguments)
   205         , actual = util.getActual(this, arguments);
   206       throw new AssertionError(msg, {
   207           actual: actual
   208         , expected: expected
   209         , showDiff: showDiff
   210       }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));
   211     }
   212   };
   213 
   214   /*!
   215    * ### ._obj
   216    *
   217    * Quick reference to stored `actual` value for plugin developers.
   218    *
   219    * @api private
   220    */
   221 
   222   Object.defineProperty(Assertion.prototype, '_obj',
   223     { get: function () {
   224         return flag(this, 'object');
   225       }
   226     , set: function (val) {
   227         flag(this, 'object', val);
   228       }
   229   });
   230 };
   231 
   232 },{"./config":4}],4:[function(require,module,exports){
   233 module.exports = {
   234 
   235   /**
   236    * ### config.includeStack
   237    *
   238    * User configurable property, influences whether stack trace
   239    * is included in Assertion error message. Default of false
   240    * suppresses stack trace in the error message.
   241    *
   242    *     chai.config.includeStack = true;  // enable stack on error
   243    *
   244    * @param {Boolean}
   245    * @api public
   246    */
   247 
   248    includeStack: false,
   249 
   250   /**
   251    * ### config.showDiff
   252    *
   253    * User configurable property, influences whether or not
   254    * the `showDiff` flag should be included in the thrown
   255    * AssertionErrors. `false` will always be `false`; `true`
   256    * will be true when the assertion has requested a diff
   257    * be shown.
   258    *
   259    * @param {Boolean}
   260    * @api public
   261    */
   262 
   263   showDiff: true,
   264 
   265   /**
   266    * ### config.truncateThreshold
   267    *
   268    * User configurable property, sets length threshold for actual and
   269    * expected values in assertion errors. If this threshold is exceeded, for
   270    * example for large data structures, the value is replaced with something
   271    * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.
   272    *
   273    * Set it to zero if you want to disable truncating altogether.
   274    *
   275    * This is especially userful when doing assertions on arrays: having this
   276    * set to a reasonable large value makes the failure messages readily
   277    * inspectable.
   278    *
   279    *     chai.config.truncateThreshold = 0;  // disable truncating
   280    *
   281    * @param {Number}
   282    * @api public
   283    */
   284 
   285   truncateThreshold: 40
   286 
   287 };
   288 
   289 },{}],5:[function(require,module,exports){
   290 /*!
   291  * chai
   292  * http://chaijs.com
   293  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
   294  * MIT Licensed
   295  */
   296 
   297 module.exports = function (chai, _) {
   298   var Assertion = chai.Assertion
   299     , toString = Object.prototype.toString
   300     , flag = _.flag;
   301 
   302   /**
   303    * ### Language Chains
   304    *
   305    * The following are provided as chainable getters to
   306    * improve the readability of your assertions. They
   307    * do not provide testing capabilities unless they
   308    * have been overwritten by a plugin.
   309    *
   310    * **Chains**
   311    *
   312    * - to
   313    * - be
   314    * - been
   315    * - is
   316    * - that
   317    * - which
   318    * - and
   319    * - has
   320    * - have
   321    * - with
   322    * - at
   323    * - of
   324    * - same
   325    *
   326    * @name language chains
   327    * @namespace BDD
   328    * @api public
   329    */
   330 
   331   [ 'to', 'be', 'been'
   332   , 'is', 'and', 'has', 'have'
   333   , 'with', 'that', 'which', 'at'
   334   , 'of', 'same' ].forEach(function (chain) {
   335     Assertion.addProperty(chain, function () {
   336       return this;
   337     });
   338   });
   339 
   340   /**
   341    * ### .not
   342    *
   343    * Negates any of assertions following in the chain.
   344    *
   345    *     expect(foo).to.not.equal('bar');
   346    *     expect(goodFn).to.not.throw(Error);
   347    *     expect({ foo: 'baz' }).to.have.property('foo')
   348    *       .and.not.equal('bar');
   349    *
   350    * @name not
   351    * @namespace BDD
   352    * @api public
   353    */
   354 
   355   Assertion.addProperty('not', function () {
   356     flag(this, 'negate', true);
   357   });
   358 
   359   /**
   360    * ### .deep
   361    *
   362    * Sets the `deep` flag, later used by the `equal` and
   363    * `property` assertions.
   364    *
   365    *     expect(foo).to.deep.equal({ bar: 'baz' });
   366    *     expect({ foo: { bar: { baz: 'quux' } } })
   367    *       .to.have.deep.property('foo.bar.baz', 'quux');
   368    *
   369    * `.deep.property` special characters can be escaped
   370    * by adding two slashes before the `.` or `[]`.
   371    *
   372    *     var deepCss = { '.link': { '[target]': 42 }};
   373    *     expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42);
   374    *
   375    * @name deep
   376    * @namespace BDD
   377    * @api public
   378    */
   379 
   380   Assertion.addProperty('deep', function () {
   381     flag(this, 'deep', true);
   382   });
   383 
   384   /**
   385    * ### .any
   386    *
   387    * Sets the `any` flag, (opposite of the `all` flag)
   388    * later used in the `keys` assertion.
   389    *
   390    *     expect(foo).to.have.any.keys('bar', 'baz');
   391    *
   392    * @name any
   393    * @namespace BDD
   394    * @api public
   395    */
   396 
   397   Assertion.addProperty('any', function () {
   398     flag(this, 'any', true);
   399     flag(this, 'all', false)
   400   });
   401 
   402 
   403   /**
   404    * ### .all
   405    *
   406    * Sets the `all` flag (opposite of the `any` flag)
   407    * later used by the `keys` assertion.
   408    *
   409    *     expect(foo).to.have.all.keys('bar', 'baz');
   410    *
   411    * @name all
   412    * @namespace BDD
   413    * @api public
   414    */
   415 
   416   Assertion.addProperty('all', function () {
   417     flag(this, 'all', true);
   418     flag(this, 'any', false);
   419   });
   420 
   421   /**
   422    * ### .a(type)
   423    *
   424    * The `a` and `an` assertions are aliases that can be
   425    * used either as language chains or to assert a value's
   426    * type.
   427    *
   428    *     // typeof
   429    *     expect('test').to.be.a('string');
   430    *     expect({ foo: 'bar' }).to.be.an('object');
   431    *     expect(null).to.be.a('null');
   432    *     expect(undefined).to.be.an('undefined');
   433    *     expect(new Error).to.be.an('error');
   434    *     expect(new Promise).to.be.a('promise');
   435    *     expect(new Float32Array()).to.be.a('float32array');
   436    *     expect(Symbol()).to.be.a('symbol');
   437    *
   438    *     // es6 overrides
   439    *     expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');
   440    *
   441    *     // language chain
   442    *     expect(foo).to.be.an.instanceof(Foo);
   443    *
   444    * @name a
   445    * @alias an
   446    * @param {String} type
   447    * @param {String} message _optional_
   448    * @namespace BDD
   449    * @api public
   450    */
   451 
   452   function an (type, msg) {
   453     if (msg) flag(this, 'message', msg);
   454     type = type.toLowerCase();
   455     var obj = flag(this, 'object')
   456       , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
   457 
   458     this.assert(
   459         type === _.type(obj)
   460       , 'expected #{this} to be ' + article + type
   461       , 'expected #{this} not to be ' + article + type
   462     );
   463   }
   464 
   465   Assertion.addChainableMethod('an', an);
   466   Assertion.addChainableMethod('a', an);
   467 
   468   /**
   469    * ### .include(value)
   470    *
   471    * The `include` and `contain` assertions can be used as either property
   472    * based language chains or as methods to assert the inclusion of an object
   473    * in an array or a substring in a string. When used as language chains,
   474    * they toggle the `contains` flag for the `keys` assertion.
   475    *
   476    *     expect([1,2,3]).to.include(2);
   477    *     expect('foobar').to.contain('foo');
   478    *     expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');
   479    *
   480    * @name include
   481    * @alias contain
   482    * @alias includes
   483    * @alias contains
   484    * @param {Object|String|Number} obj
   485    * @param {String} message _optional_
   486    * @namespace BDD
   487    * @api public
   488    */
   489 
   490   function includeChainingBehavior () {
   491     flag(this, 'contains', true);
   492   }
   493 
   494   function include (val, msg) {
   495     _.expectTypes(this, ['array', 'object', 'string']);
   496 
   497     if (msg) flag(this, 'message', msg);
   498     var obj = flag(this, 'object');
   499     var expected = false;
   500 
   501     if (_.type(obj) === 'array' && _.type(val) === 'object') {
   502       for (var i in obj) {
   503         if (_.eql(obj[i], val)) {
   504           expected = true;
   505           break;
   506         }
   507       }
   508     } else if (_.type(val) === 'object') {
   509       if (!flag(this, 'negate')) {
   510         for (var k in val) new Assertion(obj).property(k, val[k]);
   511         return;
   512       }
   513       var subset = {};
   514       for (var k in val) subset[k] = obj[k];
   515       expected = _.eql(subset, val);
   516     } else {
   517       expected = (obj != undefined) && ~obj.indexOf(val);
   518     }
   519     this.assert(
   520         expected
   521       , 'expected #{this} to include ' + _.inspect(val)
   522       , 'expected #{this} to not include ' + _.inspect(val));
   523   }
   524 
   525   Assertion.addChainableMethod('include', include, includeChainingBehavior);
   526   Assertion.addChainableMethod('contain', include, includeChainingBehavior);
   527   Assertion.addChainableMethod('contains', include, includeChainingBehavior);
   528   Assertion.addChainableMethod('includes', include, includeChainingBehavior);
   529 
   530   /**
   531    * ### .ok
   532    *
   533    * Asserts that the target is truthy.
   534    *
   535    *     expect('everything').to.be.ok;
   536    *     expect(1).to.be.ok;
   537    *     expect(false).to.not.be.ok;
   538    *     expect(undefined).to.not.be.ok;
   539    *     expect(null).to.not.be.ok;
   540    *
   541    * @name ok
   542    * @namespace BDD
   543    * @api public
   544    */
   545 
   546   Assertion.addProperty('ok', function () {
   547     this.assert(
   548         flag(this, 'object')
   549       , 'expected #{this} to be truthy'
   550       , 'expected #{this} to be falsy');
   551   });
   552 
   553   /**
   554    * ### .true
   555    *
   556    * Asserts that the target is `true`.
   557    *
   558    *     expect(true).to.be.true;
   559    *     expect(1).to.not.be.true;
   560    *
   561    * @name true
   562    * @namespace BDD
   563    * @api public
   564    */
   565 
   566   Assertion.addProperty('true', function () {
   567     this.assert(
   568         true === flag(this, 'object')
   569       , 'expected #{this} to be true'
   570       , 'expected #{this} to be false'
   571       , this.negate ? false : true
   572     );
   573   });
   574 
   575   /**
   576    * ### .false
   577    *
   578    * Asserts that the target is `false`.
   579    *
   580    *     expect(false).to.be.false;
   581    *     expect(0).to.not.be.false;
   582    *
   583    * @name false
   584    * @namespace BDD
   585    * @api public
   586    */
   587 
   588   Assertion.addProperty('false', function () {
   589     this.assert(
   590         false === flag(this, 'object')
   591       , 'expected #{this} to be false'
   592       , 'expected #{this} to be true'
   593       , this.negate ? true : false
   594     );
   595   });
   596 
   597   /**
   598    * ### .null
   599    *
   600    * Asserts that the target is `null`.
   601    *
   602    *     expect(null).to.be.null;
   603    *     expect(undefined).to.not.be.null;
   604    *
   605    * @name null
   606    * @namespace BDD
   607    * @api public
   608    */
   609 
   610   Assertion.addProperty('null', function () {
   611     this.assert(
   612         null === flag(this, 'object')
   613       , 'expected #{this} to be null'
   614       , 'expected #{this} not to be null'
   615     );
   616   });
   617 
   618   /**
   619    * ### .undefined
   620    *
   621    * Asserts that the target is `undefined`.
   622    *
   623    *     expect(undefined).to.be.undefined;
   624    *     expect(null).to.not.be.undefined;
   625    *
   626    * @name undefined
   627    * @namespace BDD
   628    * @api public
   629    */
   630 
   631   Assertion.addProperty('undefined', function () {
   632     this.assert(
   633         undefined === flag(this, 'object')
   634       , 'expected #{this} to be undefined'
   635       , 'expected #{this} not to be undefined'
   636     );
   637   });
   638 
   639   /**
   640    * ### .NaN
   641    * Asserts that the target is `NaN`.
   642    *
   643    *     expect('foo').to.be.NaN;
   644    *     expect(4).not.to.be.NaN;
   645    *
   646    * @name NaN
   647    * @namespace BDD
   648    * @api public
   649    */
   650 
   651   Assertion.addProperty('NaN', function () {
   652     this.assert(
   653         isNaN(flag(this, 'object'))
   654         , 'expected #{this} to be NaN'
   655         , 'expected #{this} not to be NaN'
   656     );
   657   });
   658 
   659   /**
   660    * ### .exist
   661    *
   662    * Asserts that the target is neither `null` nor `undefined`.
   663    *
   664    *     var foo = 'hi'
   665    *       , bar = null
   666    *       , baz;
   667    *
   668    *     expect(foo).to.exist;
   669    *     expect(bar).to.not.exist;
   670    *     expect(baz).to.not.exist;
   671    *
   672    * @name exist
   673    * @namespace BDD
   674    * @api public
   675    */
   676 
   677   Assertion.addProperty('exist', function () {
   678     this.assert(
   679         null != flag(this, 'object')
   680       , 'expected #{this} to exist'
   681       , 'expected #{this} to not exist'
   682     );
   683   });
   684 
   685 
   686   /**
   687    * ### .empty
   688    *
   689    * Asserts that the target's length is `0`. For arrays and strings, it checks
   690    * the `length` property. For objects, it gets the count of
   691    * enumerable keys.
   692    *
   693    *     expect([]).to.be.empty;
   694    *     expect('').to.be.empty;
   695    *     expect({}).to.be.empty;
   696    *
   697    * @name empty
   698    * @namespace BDD
   699    * @api public
   700    */
   701 
   702   Assertion.addProperty('empty', function () {
   703     var obj = flag(this, 'object')
   704       , expected = obj;
   705 
   706     if (Array.isArray(obj) || 'string' === typeof object) {
   707       expected = obj.length;
   708     } else if (typeof obj === 'object') {
   709       expected = Object.keys(obj).length;
   710     }
   711 
   712     this.assert(
   713         !expected
   714       , 'expected #{this} to be empty'
   715       , 'expected #{this} not to be empty'
   716     );
   717   });
   718 
   719   /**
   720    * ### .arguments
   721    *
   722    * Asserts that the target is an arguments object.
   723    *
   724    *     function test () {
   725    *       expect(arguments).to.be.arguments;
   726    *     }
   727    *
   728    * @name arguments
   729    * @alias Arguments
   730    * @namespace BDD
   731    * @api public
   732    */
   733 
   734   function checkArguments () {
   735     var obj = flag(this, 'object')
   736       , type = Object.prototype.toString.call(obj);
   737     this.assert(
   738         '[object Arguments]' === type
   739       , 'expected #{this} to be arguments but got ' + type
   740       , 'expected #{this} to not be arguments'
   741     );
   742   }
   743 
   744   Assertion.addProperty('arguments', checkArguments);
   745   Assertion.addProperty('Arguments', checkArguments);
   746 
   747   /**
   748    * ### .equal(value)
   749    *
   750    * Asserts that the target is strictly equal (`===`) to `value`.
   751    * Alternately, if the `deep` flag is set, asserts that
   752    * the target is deeply equal to `value`.
   753    *
   754    *     expect('hello').to.equal('hello');
   755    *     expect(42).to.equal(42);
   756    *     expect(1).to.not.equal(true);
   757    *     expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });
   758    *     expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });
   759    *
   760    * @name equal
   761    * @alias equals
   762    * @alias eq
   763    * @alias deep.equal
   764    * @param {Mixed} value
   765    * @param {String} message _optional_
   766    * @namespace BDD
   767    * @api public
   768    */
   769 
   770   function assertEqual (val, msg) {
   771     if (msg) flag(this, 'message', msg);
   772     var obj = flag(this, 'object');
   773     if (flag(this, 'deep')) {
   774       return this.eql(val);
   775     } else {
   776       this.assert(
   777           val === obj
   778         , 'expected #{this} to equal #{exp}'
   779         , 'expected #{this} to not equal #{exp}'
   780         , val
   781         , this._obj
   782         , true
   783       );
   784     }
   785   }
   786 
   787   Assertion.addMethod('equal', assertEqual);
   788   Assertion.addMethod('equals', assertEqual);
   789   Assertion.addMethod('eq', assertEqual);
   790 
   791   /**
   792    * ### .eql(value)
   793    *
   794    * Asserts that the target is deeply equal to `value`.
   795    *
   796    *     expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
   797    *     expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);
   798    *
   799    * @name eql
   800    * @alias eqls
   801    * @param {Mixed} value
   802    * @param {String} message _optional_
   803    * @namespace BDD
   804    * @api public
   805    */
   806 
   807   function assertEql(obj, msg) {
   808     if (msg) flag(this, 'message', msg);
   809     this.assert(
   810         _.eql(obj, flag(this, 'object'))
   811       , 'expected #{this} to deeply equal #{exp}'
   812       , 'expected #{this} to not deeply equal #{exp}'
   813       , obj
   814       , this._obj
   815       , true
   816     );
   817   }
   818 
   819   Assertion.addMethod('eql', assertEql);
   820   Assertion.addMethod('eqls', assertEql);
   821 
   822   /**
   823    * ### .above(value)
   824    *
   825    * Asserts that the target is greater than `value`.
   826    *
   827    *     expect(10).to.be.above(5);
   828    *
   829    * Can also be used in conjunction with `length` to
   830    * assert a minimum length. The benefit being a
   831    * more informative error message than if the length
   832    * was supplied directly.
   833    *
   834    *     expect('foo').to.have.length.above(2);
   835    *     expect([ 1, 2, 3 ]).to.have.length.above(2);
   836    *
   837    * @name above
   838    * @alias gt
   839    * @alias greaterThan
   840    * @param {Number} value
   841    * @param {String} message _optional_
   842    * @namespace BDD
   843    * @api public
   844    */
   845 
   846   function assertAbove (n, msg) {
   847     if (msg) flag(this, 'message', msg);
   848     var obj = flag(this, 'object');
   849     if (flag(this, 'doLength')) {
   850       new Assertion(obj, msg).to.have.property('length');
   851       var len = obj.length;
   852       this.assert(
   853           len > n
   854         , 'expected #{this} to have a length above #{exp} but got #{act}'
   855         , 'expected #{this} to not have a length above #{exp}'
   856         , n
   857         , len
   858       );
   859     } else {
   860       this.assert(
   861           obj > n
   862         , 'expected #{this} to be above ' + n
   863         , 'expected #{this} to be at most ' + n
   864       );
   865     }
   866   }
   867 
   868   Assertion.addMethod('above', assertAbove);
   869   Assertion.addMethod('gt', assertAbove);
   870   Assertion.addMethod('greaterThan', assertAbove);
   871 
   872   /**
   873    * ### .least(value)
   874    *
   875    * Asserts that the target is greater than or equal to `value`.
   876    *
   877    *     expect(10).to.be.at.least(10);
   878    *
   879    * Can also be used in conjunction with `length` to
   880    * assert a minimum length. The benefit being a
   881    * more informative error message than if the length
   882    * was supplied directly.
   883    *
   884    *     expect('foo').to.have.length.of.at.least(2);
   885    *     expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);
   886    *
   887    * @name least
   888    * @alias gte
   889    * @param {Number} value
   890    * @param {String} message _optional_
   891    * @namespace BDD
   892    * @api public
   893    */
   894 
   895   function assertLeast (n, msg) {
   896     if (msg) flag(this, 'message', msg);
   897     var obj = flag(this, 'object');
   898     if (flag(this, 'doLength')) {
   899       new Assertion(obj, msg).to.have.property('length');
   900       var len = obj.length;
   901       this.assert(
   902           len >= n
   903         , 'expected #{this} to have a length at least #{exp} but got #{act}'
   904         , 'expected #{this} to have a length below #{exp}'
   905         , n
   906         , len
   907       );
   908     } else {
   909       this.assert(
   910           obj >= n
   911         , 'expected #{this} to be at least ' + n
   912         , 'expected #{this} to be below ' + n
   913       );
   914     }
   915   }
   916 
   917   Assertion.addMethod('least', assertLeast);
   918   Assertion.addMethod('gte', assertLeast);
   919 
   920   /**
   921    * ### .below(value)
   922    *
   923    * Asserts that the target is less than `value`.
   924    *
   925    *     expect(5).to.be.below(10);
   926    *
   927    * Can also be used in conjunction with `length` to
   928    * assert a maximum length. The benefit being a
   929    * more informative error message than if the length
   930    * was supplied directly.
   931    *
   932    *     expect('foo').to.have.length.below(4);
   933    *     expect([ 1, 2, 3 ]).to.have.length.below(4);
   934    *
   935    * @name below
   936    * @alias lt
   937    * @alias lessThan
   938    * @param {Number} value
   939    * @param {String} message _optional_
   940    * @namespace BDD
   941    * @api public
   942    */
   943 
   944   function assertBelow (n, msg) {
   945     if (msg) flag(this, 'message', msg);
   946     var obj = flag(this, 'object');
   947     if (flag(this, 'doLength')) {
   948       new Assertion(obj, msg).to.have.property('length');
   949       var len = obj.length;
   950       this.assert(
   951           len < n
   952         , 'expected #{this} to have a length below #{exp} but got #{act}'
   953         , 'expected #{this} to not have a length below #{exp}'
   954         , n
   955         , len
   956       );
   957     } else {
   958       this.assert(
   959           obj < n
   960         , 'expected #{this} to be below ' + n
   961         , 'expected #{this} to be at least ' + n
   962       );
   963     }
   964   }
   965 
   966   Assertion.addMethod('below', assertBelow);
   967   Assertion.addMethod('lt', assertBelow);
   968   Assertion.addMethod('lessThan', assertBelow);
   969 
   970   /**
   971    * ### .most(value)
   972    *
   973    * Asserts that the target is less than or equal to `value`.
   974    *
   975    *     expect(5).to.be.at.most(5);
   976    *
   977    * Can also be used in conjunction with `length` to
   978    * assert a maximum length. The benefit being a
   979    * more informative error message than if the length
   980    * was supplied directly.
   981    *
   982    *     expect('foo').to.have.length.of.at.most(4);
   983    *     expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);
   984    *
   985    * @name most
   986    * @alias lte
   987    * @param {Number} value
   988    * @param {String} message _optional_
   989    * @namespace BDD
   990    * @api public
   991    */
   992 
   993   function assertMost (n, msg) {
   994     if (msg) flag(this, 'message', msg);
   995     var obj = flag(this, 'object');
   996     if (flag(this, 'doLength')) {
   997       new Assertion(obj, msg).to.have.property('length');
   998       var len = obj.length;
   999       this.assert(
  1000           len <= n
  1001         , 'expected #{this} to have a length at most #{exp} but got #{act}'
  1002         , 'expected #{this} to have a length above #{exp}'
  1003         , n
  1004         , len
  1005       );
  1006     } else {
  1007       this.assert(
  1008           obj <= n
  1009         , 'expected #{this} to be at most ' + n
  1010         , 'expected #{this} to be above ' + n
  1011       );
  1012     }
  1013   }
  1014 
  1015   Assertion.addMethod('most', assertMost);
  1016   Assertion.addMethod('lte', assertMost);
  1017 
  1018   /**
  1019    * ### .within(start, finish)
  1020    *
  1021    * Asserts that the target is within a range.
  1022    *
  1023    *     expect(7).to.be.within(5,10);
  1024    *
  1025    * Can also be used in conjunction with `length` to
  1026    * assert a length range. The benefit being a
  1027    * more informative error message than if the length
  1028    * was supplied directly.
  1029    *
  1030    *     expect('foo').to.have.length.within(2,4);
  1031    *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);
  1032    *
  1033    * @name within
  1034    * @param {Number} start lowerbound inclusive
  1035    * @param {Number} finish upperbound inclusive
  1036    * @param {String} message _optional_
  1037    * @namespace BDD
  1038    * @api public
  1039    */
  1040 
  1041   Assertion.addMethod('within', function (start, finish, msg) {
  1042     if (msg) flag(this, 'message', msg);
  1043     var obj = flag(this, 'object')
  1044       , range = start + '..' + finish;
  1045     if (flag(this, 'doLength')) {
  1046       new Assertion(obj, msg).to.have.property('length');
  1047       var len = obj.length;
  1048       this.assert(
  1049           len >= start && len <= finish
  1050         , 'expected #{this} to have a length within ' + range
  1051         , 'expected #{this} to not have a length within ' + range
  1052       );
  1053     } else {
  1054       this.assert(
  1055           obj >= start && obj <= finish
  1056         , 'expected #{this} to be within ' + range
  1057         , 'expected #{this} to not be within ' + range
  1058       );
  1059     }
  1060   });
  1061 
  1062   /**
  1063    * ### .instanceof(constructor)
  1064    *
  1065    * Asserts that the target is an instance of `constructor`.
  1066    *
  1067    *     var Tea = function (name) { this.name = name; }
  1068    *       , Chai = new Tea('chai');
  1069    *
  1070    *     expect(Chai).to.be.an.instanceof(Tea);
  1071    *     expect([ 1, 2, 3 ]).to.be.instanceof(Array);
  1072    *
  1073    * @name instanceof
  1074    * @param {Constructor} constructor
  1075    * @param {String} message _optional_
  1076    * @alias instanceOf
  1077    * @namespace BDD
  1078    * @api public
  1079    */
  1080 
  1081   function assertInstanceOf (constructor, msg) {
  1082     if (msg) flag(this, 'message', msg);
  1083     var name = _.getName(constructor);
  1084     this.assert(
  1085         flag(this, 'object') instanceof constructor
  1086       , 'expected #{this} to be an instance of ' + name
  1087       , 'expected #{this} to not be an instance of ' + name
  1088     );
  1089   };
  1090 
  1091   Assertion.addMethod('instanceof', assertInstanceOf);
  1092   Assertion.addMethod('instanceOf', assertInstanceOf);
  1093 
  1094   /**
  1095    * ### .property(name, [value])
  1096    *
  1097    * Asserts that the target has a property `name`, optionally asserting that
  1098    * the value of that property is strictly equal to  `value`.
  1099    * If the `deep` flag is set, you can use dot- and bracket-notation for deep
  1100    * references into objects and arrays.
  1101    *
  1102    *     // simple referencing
  1103    *     var obj = { foo: 'bar' };
  1104    *     expect(obj).to.have.property('foo');
  1105    *     expect(obj).to.have.property('foo', 'bar');
  1106    *
  1107    *     // deep referencing
  1108    *     var deepObj = {
  1109    *         green: { tea: 'matcha' }
  1110    *       , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]
  1111    *     };
  1112    *
  1113    *     expect(deepObj).to.have.deep.property('green.tea', 'matcha');
  1114    *     expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
  1115    *     expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');
  1116    *
  1117    * You can also use an array as the starting point of a `deep.property`
  1118    * assertion, or traverse nested arrays.
  1119    *
  1120    *     var arr = [
  1121    *         [ 'chai', 'matcha', 'konacha' ]
  1122    *       , [ { tea: 'chai' }
  1123    *         , { tea: 'matcha' }
  1124    *         , { tea: 'konacha' } ]
  1125    *     ];
  1126    *
  1127    *     expect(arr).to.have.deep.property('[0][1]', 'matcha');
  1128    *     expect(arr).to.have.deep.property('[1][2].tea', 'konacha');
  1129    *
  1130    * Furthermore, `property` changes the subject of the assertion
  1131    * to be the value of that property from the original object. This
  1132    * permits for further chainable assertions on that property.
  1133    *
  1134    *     expect(obj).to.have.property('foo')
  1135    *       .that.is.a('string');
  1136    *     expect(deepObj).to.have.property('green')
  1137    *       .that.is.an('object')
  1138    *       .that.deep.equals({ tea: 'matcha' });
  1139    *     expect(deepObj).to.have.property('teas')
  1140    *       .that.is.an('array')
  1141    *       .with.deep.property('[2]')
  1142    *         .that.deep.equals({ tea: 'konacha' });
  1143    *
  1144    * Note that dots and bracket in `name` must be backslash-escaped when
  1145    * the `deep` flag is set, while they must NOT be escaped when the `deep`
  1146    * flag is not set.
  1147    *
  1148    *     // simple referencing
  1149    *     var css = { '.link[target]': 42 };
  1150    *     expect(css).to.have.property('.link[target]', 42);
  1151    *
  1152    *     // deep referencing
  1153    *     var deepCss = { '.link': { '[target]': 42 }};
  1154    *     expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42);
  1155    *
  1156    * @name property
  1157    * @alias deep.property
  1158    * @param {String} name
  1159    * @param {Mixed} value (optional)
  1160    * @param {String} message _optional_
  1161    * @returns value of property for chaining
  1162    * @namespace BDD
  1163    * @api public
  1164    */
  1165 
  1166   Assertion.addMethod('property', function (name, val, msg) {
  1167     if (msg) flag(this, 'message', msg);
  1168 
  1169     var isDeep = !!flag(this, 'deep')
  1170       , descriptor = isDeep ? 'deep property ' : 'property '
  1171       , negate = flag(this, 'negate')
  1172       , obj = flag(this, 'object')
  1173       , pathInfo = isDeep ? _.getPathInfo(name, obj) : null
  1174       , hasProperty = isDeep
  1175         ? pathInfo.exists
  1176         : _.hasProperty(name, obj)
  1177       , value = isDeep
  1178         ? pathInfo.value
  1179         : obj[name];
  1180 
  1181     if (negate && arguments.length > 1) {
  1182       if (undefined === value) {
  1183         msg = (msg != null) ? msg + ': ' : '';
  1184         throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
  1185       }
  1186     } else {
  1187       this.assert(
  1188           hasProperty
  1189         , 'expected #{this} to have a ' + descriptor + _.inspect(name)
  1190         , 'expected #{this} to not have ' + descriptor + _.inspect(name));
  1191     }
  1192 
  1193     if (arguments.length > 1) {
  1194       this.assert(
  1195           val === value
  1196         , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
  1197         , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'
  1198         , val
  1199         , value
  1200       );
  1201     }
  1202 
  1203     flag(this, 'object', value);
  1204   });
  1205 
  1206 
  1207   /**
  1208    * ### .ownProperty(name)
  1209    *
  1210    * Asserts that the target has an own property `name`.
  1211    *
  1212    *     expect('test').to.have.ownProperty('length');
  1213    *
  1214    * @name ownProperty
  1215    * @alias haveOwnProperty
  1216    * @param {String} name
  1217    * @param {String} message _optional_
  1218    * @namespace BDD
  1219    * @api public
  1220    */
  1221 
  1222   function assertOwnProperty (name, msg) {
  1223     if (msg) flag(this, 'message', msg);
  1224     var obj = flag(this, 'object');
  1225     this.assert(
  1226         obj.hasOwnProperty(name)
  1227       , 'expected #{this} to have own property ' + _.inspect(name)
  1228       , 'expected #{this} to not have own property ' + _.inspect(name)
  1229     );
  1230   }
  1231 
  1232   Assertion.addMethod('ownProperty', assertOwnProperty);
  1233   Assertion.addMethod('haveOwnProperty', assertOwnProperty);
  1234 
  1235   /**
  1236    * ### .ownPropertyDescriptor(name[, descriptor[, message]])
  1237    *
  1238    * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.
  1239    *
  1240    *     expect('test').to.have.ownPropertyDescriptor('length');
  1241    *     expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });
  1242    *     expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });
  1243    *     expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);
  1244    *     expect('test').ownPropertyDescriptor('length').to.have.keys('value');
  1245    *
  1246    * @name ownPropertyDescriptor
  1247    * @alias haveOwnPropertyDescriptor
  1248    * @param {String} name
  1249    * @param {Object} descriptor _optional_
  1250    * @param {String} message _optional_
  1251    * @namespace BDD
  1252    * @api public
  1253    */
  1254 
  1255   function assertOwnPropertyDescriptor (name, descriptor, msg) {
  1256     if (typeof descriptor === 'string') {
  1257       msg = descriptor;
  1258       descriptor = null;
  1259     }
  1260     if (msg) flag(this, 'message', msg);
  1261     var obj = flag(this, 'object');
  1262     var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);
  1263     if (actualDescriptor && descriptor) {
  1264       this.assert(
  1265           _.eql(descriptor, actualDescriptor)
  1266         , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)
  1267         , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)
  1268         , descriptor
  1269         , actualDescriptor
  1270         , true
  1271       );
  1272     } else {
  1273       this.assert(
  1274           actualDescriptor
  1275         , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)
  1276         , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)
  1277       );
  1278     }
  1279     flag(this, 'object', actualDescriptor);
  1280   }
  1281 
  1282   Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);
  1283   Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);
  1284 
  1285   /**
  1286    * ### .length
  1287    *
  1288    * Sets the `doLength` flag later used as a chain precursor to a value
  1289    * comparison for the `length` property.
  1290    *
  1291    *     expect('foo').to.have.length.above(2);
  1292    *     expect([ 1, 2, 3 ]).to.have.length.above(2);
  1293    *     expect('foo').to.have.length.below(4);
  1294    *     expect([ 1, 2, 3 ]).to.have.length.below(4);
  1295    *     expect('foo').to.have.length.within(2,4);
  1296    *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);
  1297    *
  1298    * *Deprecation notice:* Using `length` as an assertion will be deprecated
  1299    * in version 2.4.0 and removed in 3.0.0. Code using the old style of
  1300    * asserting for `length` property value using `length(value)` should be
  1301    * switched to use `lengthOf(value)` instead.
  1302    *
  1303    * @name length
  1304    * @namespace BDD
  1305    * @api public
  1306    */
  1307 
  1308   /**
  1309    * ### .lengthOf(value[, message])
  1310    *
  1311    * Asserts that the target's `length` property has
  1312    * the expected value.
  1313    *
  1314    *     expect([ 1, 2, 3]).to.have.lengthOf(3);
  1315    *     expect('foobar').to.have.lengthOf(6);
  1316    *
  1317    * @name lengthOf
  1318    * @param {Number} length
  1319    * @param {String} message _optional_
  1320    * @namespace BDD
  1321    * @api public
  1322    */
  1323 
  1324   function assertLengthChain () {
  1325     flag(this, 'doLength', true);
  1326   }
  1327 
  1328   function assertLength (n, msg) {
  1329     if (msg) flag(this, 'message', msg);
  1330     var obj = flag(this, 'object');
  1331     new Assertion(obj, msg).to.have.property('length');
  1332     var len = obj.length;
  1333 
  1334     this.assert(
  1335         len == n
  1336       , 'expected #{this} to have a length of #{exp} but got #{act}'
  1337       , 'expected #{this} to not have a length of #{act}'
  1338       , n
  1339       , len
  1340     );
  1341   }
  1342 
  1343   Assertion.addChainableMethod('length', assertLength, assertLengthChain);
  1344   Assertion.addMethod('lengthOf', assertLength);
  1345 
  1346   /**
  1347    * ### .match(regexp)
  1348    *
  1349    * Asserts that the target matches a regular expression.
  1350    *
  1351    *     expect('foobar').to.match(/^foo/);
  1352    *
  1353    * @name match
  1354    * @alias matches
  1355    * @param {RegExp} RegularExpression
  1356    * @param {String} message _optional_
  1357    * @namespace BDD
  1358    * @api public
  1359    */
  1360   function assertMatch(re, msg) {
  1361     if (msg) flag(this, 'message', msg);
  1362     var obj = flag(this, 'object');
  1363     this.assert(
  1364         re.exec(obj)
  1365       , 'expected #{this} to match ' + re
  1366       , 'expected #{this} not to match ' + re
  1367     );
  1368   }
  1369 
  1370   Assertion.addMethod('match', assertMatch);
  1371   Assertion.addMethod('matches', assertMatch);
  1372 
  1373   /**
  1374    * ### .string(string)
  1375    *
  1376    * Asserts that the string target contains another string.
  1377    *
  1378    *     expect('foobar').to.have.string('bar');
  1379    *
  1380    * @name string
  1381    * @param {String} string
  1382    * @param {String} message _optional_
  1383    * @namespace BDD
  1384    * @api public
  1385    */
  1386 
  1387   Assertion.addMethod('string', function (str, msg) {
  1388     if (msg) flag(this, 'message', msg);
  1389     var obj = flag(this, 'object');
  1390     new Assertion(obj, msg).is.a('string');
  1391 
  1392     this.assert(
  1393         ~obj.indexOf(str)
  1394       , 'expected #{this} to contain ' + _.inspect(str)
  1395       , 'expected #{this} to not contain ' + _.inspect(str)
  1396     );
  1397   });
  1398 
  1399 
  1400   /**
  1401    * ### .keys(key1, [key2], [...])
  1402    *
  1403    * Asserts that the target contains any or all of the passed-in keys.
  1404    * Use in combination with `any`, `all`, `contains`, or `have` will affect
  1405    * what will pass.
  1406    *
  1407    * When used in conjunction with `any`, at least one key that is passed
  1408    * in must exist in the target object. This is regardless whether or not
  1409    * the `have` or `contain` qualifiers are used. Note, either `any` or `all`
  1410    * should be used in the assertion. If neither are used, the assertion is
  1411    * defaulted to `all`.
  1412    *
  1413    * When both `all` and `contain` are used, the target object must have at
  1414    * least all of the passed-in keys but may have more keys not listed.
  1415    *
  1416    * When both `all` and `have` are used, the target object must both contain
  1417    * all of the passed-in keys AND the number of keys in the target object must
  1418    * match the number of keys passed in (in other words, a target object must
  1419    * have all and only all of the passed-in keys).
  1420    *
  1421    *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');
  1422    *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');
  1423    *     expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');
  1424    *     expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);
  1425    *     expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});
  1426    *     expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);
  1427    *     expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});
  1428    *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);
  1429    *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});
  1430    *
  1431    *
  1432    * @name keys
  1433    * @alias key
  1434    * @param {...String|Array|Object} keys
  1435    * @namespace BDD
  1436    * @api public
  1437    */
  1438 
  1439   function assertKeys (keys) {
  1440     var obj = flag(this, 'object')
  1441       , str
  1442       , ok = true
  1443       , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';
  1444 
  1445     switch (_.type(keys)) {
  1446       case "array":
  1447         if (arguments.length > 1) throw (new Error(mixedArgsMsg));
  1448         break;
  1449       case "object":
  1450         if (arguments.length > 1) throw (new Error(mixedArgsMsg));
  1451         keys = Object.keys(keys);
  1452         break;
  1453       default:
  1454         keys = Array.prototype.slice.call(arguments);
  1455     }
  1456 
  1457     if (!keys.length) throw new Error('keys required');
  1458 
  1459     var actual = Object.keys(obj)
  1460       , expected = keys
  1461       , len = keys.length
  1462       , any = flag(this, 'any')
  1463       , all = flag(this, 'all');
  1464 
  1465     if (!any && !all) {
  1466       all = true;
  1467     }
  1468 
  1469     // Has any
  1470     if (any) {
  1471       var intersection = expected.filter(function(key) {
  1472         return ~actual.indexOf(key);
  1473       });
  1474       ok = intersection.length > 0;
  1475     }
  1476 
  1477     // Has all
  1478     if (all) {
  1479       ok = keys.every(function(key){
  1480         return ~actual.indexOf(key);
  1481       });
  1482       if (!flag(this, 'negate') && !flag(this, 'contains')) {
  1483         ok = ok && keys.length == actual.length;
  1484       }
  1485     }
  1486 
  1487     // Key string
  1488     if (len > 1) {
  1489       keys = keys.map(function(key){
  1490         return _.inspect(key);
  1491       });
  1492       var last = keys.pop();
  1493       if (all) {
  1494         str = keys.join(', ') + ', and ' + last;
  1495       }
  1496       if (any) {
  1497         str = keys.join(', ') + ', or ' + last;
  1498       }
  1499     } else {
  1500       str = _.inspect(keys[0]);
  1501     }
  1502 
  1503     // Form
  1504     str = (len > 1 ? 'keys ' : 'key ') + str;
  1505 
  1506     // Have / include
  1507     str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
  1508 
  1509     // Assertion
  1510     this.assert(
  1511         ok
  1512       , 'expected #{this} to ' + str
  1513       , 'expected #{this} to not ' + str
  1514       , expected.slice(0).sort()
  1515       , actual.sort()
  1516       , true
  1517     );
  1518   }
  1519 
  1520   Assertion.addMethod('keys', assertKeys);
  1521   Assertion.addMethod('key', assertKeys);
  1522 
  1523   /**
  1524    * ### .throw(constructor)
  1525    *
  1526    * Asserts that the function target will throw a specific error, or specific type of error
  1527    * (as determined using `instanceof`), optionally with a RegExp or string inclusion test
  1528    * for the error's message.
  1529    *
  1530    *     var err = new ReferenceError('This is a bad function.');
  1531    *     var fn = function () { throw err; }
  1532    *     expect(fn).to.throw(ReferenceError);
  1533    *     expect(fn).to.throw(Error);
  1534    *     expect(fn).to.throw(/bad function/);
  1535    *     expect(fn).to.not.throw('good function');
  1536    *     expect(fn).to.throw(ReferenceError, /bad function/);
  1537    *     expect(fn).to.throw(err);
  1538    *
  1539    * Please note that when a throw expectation is negated, it will check each
  1540    * parameter independently, starting with error constructor type. The appropriate way
  1541    * to check for the existence of a type of error but for a message that does not match
  1542    * is to use `and`.
  1543    *
  1544    *     expect(fn).to.throw(ReferenceError)
  1545    *        .and.not.throw(/good function/);
  1546    *
  1547    * @name throw
  1548    * @alias throws
  1549    * @alias Throw
  1550    * @param {ErrorConstructor} constructor
  1551    * @param {String|RegExp} expected error message
  1552    * @param {String} message _optional_
  1553    * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
  1554    * @returns error for chaining (null if no error)
  1555    * @namespace BDD
  1556    * @api public
  1557    */
  1558 
  1559   function assertThrows (constructor, errMsg, msg) {
  1560     if (msg) flag(this, 'message', msg);
  1561     var obj = flag(this, 'object');
  1562     new Assertion(obj, msg).is.a('function');
  1563 
  1564     var thrown = false
  1565       , desiredError = null
  1566       , name = null
  1567       , thrownError = null;
  1568 
  1569     if (arguments.length === 0) {
  1570       errMsg = null;
  1571       constructor = null;
  1572     } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
  1573       errMsg = constructor;
  1574       constructor = null;
  1575     } else if (constructor && constructor instanceof Error) {
  1576       desiredError = constructor;
  1577       constructor = null;
  1578       errMsg = null;
  1579     } else if (typeof constructor === 'function') {
  1580       name = constructor.prototype.name;
  1581       if (!name || (name === 'Error' && constructor !== Error)) {
  1582         name = constructor.name || (new constructor()).name;
  1583       }
  1584     } else {
  1585       constructor = null;
  1586     }
  1587 
  1588     try {
  1589       obj();
  1590     } catch (err) {
  1591       // first, check desired error
  1592       if (desiredError) {
  1593         this.assert(
  1594             err === desiredError
  1595           , 'expected #{this} to throw #{exp} but #{act} was thrown'
  1596           , 'expected #{this} to not throw #{exp}'
  1597           , (desiredError instanceof Error ? desiredError.toString() : desiredError)
  1598           , (err instanceof Error ? err.toString() : err)
  1599         );
  1600 
  1601         flag(this, 'object', err);
  1602         return this;
  1603       }
  1604 
  1605       // next, check constructor
  1606       if (constructor) {
  1607         this.assert(
  1608             err instanceof constructor
  1609           , 'expected #{this} to throw #{exp} but #{act} was thrown'
  1610           , 'expected #{this} to not throw #{exp} but #{act} was thrown'
  1611           , name
  1612           , (err instanceof Error ? err.toString() : err)
  1613         );
  1614 
  1615         if (!errMsg) {
  1616           flag(this, 'object', err);
  1617           return this;
  1618         }
  1619       }
  1620 
  1621       // next, check message
  1622       var message = 'error' === _.type(err) && "message" in err
  1623         ? err.message
  1624         : '' + err;
  1625 
  1626       if ((message != null) && errMsg && errMsg instanceof RegExp) {
  1627         this.assert(
  1628             errMsg.exec(message)
  1629           , 'expected #{this} to throw error matching #{exp} but got #{act}'
  1630           , 'expected #{this} to throw error not matching #{exp}'
  1631           , errMsg
  1632           , message
  1633         );
  1634 
  1635         flag(this, 'object', err);
  1636         return this;
  1637       } else if ((message != null) && errMsg && 'string' === typeof errMsg) {
  1638         this.assert(
  1639             ~message.indexOf(errMsg)
  1640           , 'expected #{this} to throw error including #{exp} but got #{act}'
  1641           , 'expected #{this} to throw error not including #{act}'
  1642           , errMsg
  1643           , message
  1644         );
  1645 
  1646         flag(this, 'object', err);
  1647         return this;
  1648       } else {
  1649         thrown = true;
  1650         thrownError = err;
  1651       }
  1652     }
  1653 
  1654     var actuallyGot = ''
  1655       , expectedThrown = name !== null
  1656         ? name
  1657         : desiredError
  1658           ? '#{exp}' //_.inspect(desiredError)
  1659           : 'an error';
  1660 
  1661     if (thrown) {
  1662       actuallyGot = ' but #{act} was thrown'
  1663     }
  1664 
  1665     this.assert(
  1666         thrown === true
  1667       , 'expected #{this} to throw ' + expectedThrown + actuallyGot
  1668       , 'expected #{this} to not throw ' + expectedThrown + actuallyGot
  1669       , (desiredError instanceof Error ? desiredError.toString() : desiredError)
  1670       , (thrownError instanceof Error ? thrownError.toString() : thrownError)
  1671     );
  1672 
  1673     flag(this, 'object', thrownError);
  1674   };
  1675 
  1676   Assertion.addMethod('throw', assertThrows);
  1677   Assertion.addMethod('throws', assertThrows);
  1678   Assertion.addMethod('Throw', assertThrows);
  1679 
  1680   /**
  1681    * ### .respondTo(method)
  1682    *
  1683    * Asserts that the object or class target will respond to a method.
  1684    *
  1685    *     Klass.prototype.bar = function(){};
  1686    *     expect(Klass).to.respondTo('bar');
  1687    *     expect(obj).to.respondTo('bar');
  1688    *
  1689    * To check if a constructor will respond to a static function,
  1690    * set the `itself` flag.
  1691    *
  1692    *     Klass.baz = function(){};
  1693    *     expect(Klass).itself.to.respondTo('baz');
  1694    *
  1695    * @name respondTo
  1696    * @alias respondsTo
  1697    * @param {String} method
  1698    * @param {String} message _optional_
  1699    * @namespace BDD
  1700    * @api public
  1701    */
  1702 
  1703   function respondTo (method, msg) {
  1704     if (msg) flag(this, 'message', msg);
  1705     var obj = flag(this, 'object')
  1706       , itself = flag(this, 'itself')
  1707       , context = ('function' === _.type(obj) && !itself)
  1708         ? obj.prototype[method]
  1709         : obj[method];
  1710 
  1711     this.assert(
  1712         'function' === typeof context
  1713       , 'expected #{this} to respond to ' + _.inspect(method)
  1714       , 'expected #{this} to not respond to ' + _.inspect(method)
  1715     );
  1716   }
  1717 
  1718   Assertion.addMethod('respondTo', respondTo);
  1719   Assertion.addMethod('respondsTo', respondTo);
  1720 
  1721   /**
  1722    * ### .itself
  1723    *
  1724    * Sets the `itself` flag, later used by the `respondTo` assertion.
  1725    *
  1726    *     function Foo() {}
  1727    *     Foo.bar = function() {}
  1728    *     Foo.prototype.baz = function() {}
  1729    *
  1730    *     expect(Foo).itself.to.respondTo('bar');
  1731    *     expect(Foo).itself.not.to.respondTo('baz');
  1732    *
  1733    * @name itself
  1734    * @namespace BDD
  1735    * @api public
  1736    */
  1737 
  1738   Assertion.addProperty('itself', function () {
  1739     flag(this, 'itself', true);
  1740   });
  1741 
  1742   /**
  1743    * ### .satisfy(method)
  1744    *
  1745    * Asserts that the target passes a given truth test.
  1746    *
  1747    *     expect(1).to.satisfy(function(num) { return num > 0; });
  1748    *
  1749    * @name satisfy
  1750    * @alias satisfies
  1751    * @param {Function} matcher
  1752    * @param {String} message _optional_
  1753    * @namespace BDD
  1754    * @api public
  1755    */
  1756 
  1757   function satisfy (matcher, msg) {
  1758     if (msg) flag(this, 'message', msg);
  1759     var obj = flag(this, 'object');
  1760     var result = matcher(obj);
  1761     this.assert(
  1762         result
  1763       , 'expected #{this} to satisfy ' + _.objDisplay(matcher)
  1764       , 'expected #{this} to not satisfy' + _.objDisplay(matcher)
  1765       , this.negate ? false : true
  1766       , result
  1767     );
  1768   }
  1769 
  1770   Assertion.addMethod('satisfy', satisfy);
  1771   Assertion.addMethod('satisfies', satisfy);
  1772 
  1773   /**
  1774    * ### .closeTo(expected, delta)
  1775    *
  1776    * Asserts that the target is equal `expected`, to within a +/- `delta` range.
  1777    *
  1778    *     expect(1.5).to.be.closeTo(1, 0.5);
  1779    *
  1780    * @name closeTo
  1781    * @alias approximately
  1782    * @param {Number} expected
  1783    * @param {Number} delta
  1784    * @param {String} message _optional_
  1785    * @namespace BDD
  1786    * @api public
  1787    */
  1788 
  1789   function closeTo(expected, delta, msg) {
  1790     if (msg) flag(this, 'message', msg);
  1791     var obj = flag(this, 'object');
  1792 
  1793     new Assertion(obj, msg).is.a('number');
  1794     if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {
  1795       throw new Error('the arguments to closeTo or approximately must be numbers');
  1796     }
  1797 
  1798     this.assert(
  1799         Math.abs(obj - expected) <= delta
  1800       , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
  1801       , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
  1802     );
  1803   }
  1804 
  1805   Assertion.addMethod('closeTo', closeTo);
  1806   Assertion.addMethod('approximately', closeTo);
  1807 
  1808   function isSubsetOf(subset, superset, cmp) {
  1809     return subset.every(function(elem) {
  1810       if (!cmp) return superset.indexOf(elem) !== -1;
  1811 
  1812       return superset.some(function(elem2) {
  1813         return cmp(elem, elem2);
  1814       });
  1815     })
  1816   }
  1817 
  1818   /**
  1819    * ### .members(set)
  1820    *
  1821    * Asserts that the target is a superset of `set`,
  1822    * or that the target and `set` have the same strictly-equal (===) members.
  1823    * Alternately, if the `deep` flag is set, set members are compared for deep
  1824    * equality.
  1825    *
  1826    *     expect([1, 2, 3]).to.include.members([3, 2]);
  1827    *     expect([1, 2, 3]).to.not.include.members([3, 2, 8]);
  1828    *
  1829    *     expect([4, 2]).to.have.members([2, 4]);
  1830    *     expect([5, 2]).to.not.have.members([5, 2, 1]);
  1831    *
  1832    *     expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);
  1833    *
  1834    * @name members
  1835    * @param {Array} set
  1836    * @param {String} message _optional_
  1837    * @namespace BDD
  1838    * @api public
  1839    */
  1840 
  1841   Assertion.addMethod('members', function (subset, msg) {
  1842     if (msg) flag(this, 'message', msg);
  1843     var obj = flag(this, 'object');
  1844 
  1845     new Assertion(obj).to.be.an('array');
  1846     new Assertion(subset).to.be.an('array');
  1847 
  1848     var cmp = flag(this, 'deep') ? _.eql : undefined;
  1849 
  1850     if (flag(this, 'contains')) {
  1851       return this.assert(
  1852           isSubsetOf(subset, obj, cmp)
  1853         , 'expected #{this} to be a superset of #{act}'
  1854         , 'expected #{this} to not be a superset of #{act}'
  1855         , obj
  1856         , subset
  1857       );
  1858     }
  1859 
  1860     this.assert(
  1861         isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)
  1862         , 'expected #{this} to have the same members as #{act}'
  1863         , 'expected #{this} to not have the same members as #{act}'
  1864         , obj
  1865         , subset
  1866     );
  1867   });
  1868 
  1869   /**
  1870    * ### .oneOf(list)
  1871    *
  1872    * Assert that a value appears somewhere in the top level of array `list`.
  1873    *
  1874    *     expect('a').to.be.oneOf(['a', 'b', 'c']);
  1875    *     expect(9).to.not.be.oneOf(['z']);
  1876    *     expect([3]).to.not.be.oneOf([1, 2, [3]]);
  1877    *
  1878    *     var three = [3];
  1879    *     // for object-types, contents are not compared
  1880    *     expect(three).to.not.be.oneOf([1, 2, [3]]);
  1881    *     // comparing references works
  1882    *     expect(three).to.be.oneOf([1, 2, three]);
  1883    *
  1884    * @name oneOf
  1885    * @param {Array<*>} list
  1886    * @param {String} message _optional_
  1887    * @namespace BDD
  1888    * @api public
  1889    */
  1890 
  1891   function oneOf (list, msg) {
  1892     if (msg) flag(this, 'message', msg);
  1893     var expected = flag(this, 'object');
  1894     new Assertion(list).to.be.an('array');
  1895 
  1896     this.assert(
  1897         list.indexOf(expected) > -1
  1898       , 'expected #{this} to be one of #{exp}'
  1899       , 'expected #{this} to not be one of #{exp}'
  1900       , list
  1901       , expected
  1902     );
  1903   }
  1904 
  1905   Assertion.addMethod('oneOf', oneOf);
  1906 
  1907 
  1908   /**
  1909    * ### .change(function)
  1910    *
  1911    * Asserts that a function changes an object property
  1912    *
  1913    *     var obj = { val: 10 };
  1914    *     var fn = function() { obj.val += 3 };
  1915    *     var noChangeFn = function() { return 'foo' + 'bar'; }
  1916    *     expect(fn).to.change(obj, 'val');
  1917    *     expect(noChangeFn).to.not.change(obj, 'val')
  1918    *
  1919    * @name change
  1920    * @alias changes
  1921    * @alias Change
  1922    * @param {String} object
  1923    * @param {String} property name
  1924    * @param {String} message _optional_
  1925    * @namespace BDD
  1926    * @api public
  1927    */
  1928 
  1929   function assertChanges (object, prop, msg) {
  1930     if (msg) flag(this, 'message', msg);
  1931     var fn = flag(this, 'object');
  1932     new Assertion(object, msg).to.have.property(prop);
  1933     new Assertion(fn).is.a('function');
  1934 
  1935     var initial = object[prop];
  1936     fn();
  1937 
  1938     this.assert(
  1939       initial !== object[prop]
  1940       , 'expected .' + prop + ' to change'
  1941       , 'expected .' + prop + ' to not change'
  1942     );
  1943   }
  1944 
  1945   Assertion.addChainableMethod('change', assertChanges);
  1946   Assertion.addChainableMethod('changes', assertChanges);
  1947 
  1948   /**
  1949    * ### .increase(function)
  1950    *
  1951    * Asserts that a function increases an object property
  1952    *
  1953    *     var obj = { val: 10 };
  1954    *     var fn = function() { obj.val = 15 };
  1955    *     expect(fn).to.increase(obj, 'val');
  1956    *
  1957    * @name increase
  1958    * @alias increases
  1959    * @alias Increase
  1960    * @param {String} object
  1961    * @param {String} property name
  1962    * @param {String} message _optional_
  1963    * @namespace BDD
  1964    * @api public
  1965    */
  1966 
  1967   function assertIncreases (object, prop, msg) {
  1968     if (msg) flag(this, 'message', msg);
  1969     var fn = flag(this, 'object');
  1970     new Assertion(object, msg).to.have.property(prop);
  1971     new Assertion(fn).is.a('function');
  1972 
  1973     var initial = object[prop];
  1974     fn();
  1975 
  1976     this.assert(
  1977       object[prop] - initial > 0
  1978       , 'expected .' + prop + ' to increase'
  1979       , 'expected .' + prop + ' to not increase'
  1980     );
  1981   }
  1982 
  1983   Assertion.addChainableMethod('increase', assertIncreases);
  1984   Assertion.addChainableMethod('increases', assertIncreases);
  1985 
  1986   /**
  1987    * ### .decrease(function)
  1988    *
  1989    * Asserts that a function decreases an object property
  1990    *
  1991    *     var obj = { val: 10 };
  1992    *     var fn = function() { obj.val = 5 };
  1993    *     expect(fn).to.decrease(obj, 'val');
  1994    *
  1995    * @name decrease
  1996    * @alias decreases
  1997    * @alias Decrease
  1998    * @param {String} object
  1999    * @param {String} property name
  2000    * @param {String} message _optional_
  2001    * @namespace BDD
  2002    * @api public
  2003    */
  2004 
  2005   function assertDecreases (object, prop, msg) {
  2006     if (msg) flag(this, 'message', msg);
  2007     var fn = flag(this, 'object');
  2008     new Assertion(object, msg).to.have.property(prop);
  2009     new Assertion(fn).is.a('function');
  2010 
  2011     var initial = object[prop];
  2012     fn();
  2013 
  2014     this.assert(
  2015       object[prop] - initial < 0
  2016       , 'expected .' + prop + ' to decrease'
  2017       , 'expected .' + prop + ' to not decrease'
  2018     );
  2019   }
  2020 
  2021   Assertion.addChainableMethod('decrease', assertDecreases);
  2022   Assertion.addChainableMethod('decreases', assertDecreases);
  2023 
  2024   /**
  2025    * ### .extensible
  2026    *
  2027    * Asserts that the target is extensible (can have new properties added to
  2028    * it).
  2029    *
  2030    *     var nonExtensibleObject = Object.preventExtensions({});
  2031    *     var sealedObject = Object.seal({});
  2032    *     var frozenObject = Object.freeze({});
  2033    *
  2034    *     expect({}).to.be.extensible;
  2035    *     expect(nonExtensibleObject).to.not.be.extensible;
  2036    *     expect(sealedObject).to.not.be.extensible;
  2037    *     expect(frozenObject).to.not.be.extensible;
  2038    *
  2039    * @name extensible
  2040    * @namespace BDD
  2041    * @api public
  2042    */
  2043 
  2044   Assertion.addProperty('extensible', function() {
  2045     var obj = flag(this, 'object');
  2046 
  2047     // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.
  2048     // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.
  2049     // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
  2050     // The following provides ES6 behavior when a TypeError is thrown under ES5.
  2051 
  2052     var isExtensible;
  2053 
  2054     try {
  2055       isExtensible = Object.isExtensible(obj);
  2056     } catch (err) {
  2057       if (err instanceof TypeError) isExtensible = false;
  2058       else throw err;
  2059     }
  2060 
  2061     this.assert(
  2062       isExtensible
  2063       , 'expected #{this} to be extensible'
  2064       , 'expected #{this} to not be extensible'
  2065     );
  2066   });
  2067 
  2068   /**
  2069    * ### .sealed
  2070    *
  2071    * Asserts that the target is sealed (cannot have new properties added to it
  2072    * and its existing properties cannot be removed).
  2073    *
  2074    *     var sealedObject = Object.seal({});
  2075    *     var frozenObject = Object.freeze({});
  2076    *
  2077    *     expect(sealedObject).to.be.sealed;
  2078    *     expect(frozenObject).to.be.sealed;
  2079    *     expect({}).to.not.be.sealed;
  2080    *
  2081    * @name sealed
  2082    * @namespace BDD
  2083    * @api public
  2084    */
  2085 
  2086   Assertion.addProperty('sealed', function() {
  2087     var obj = flag(this, 'object');
  2088 
  2089     // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.
  2090     // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.
  2091     // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed
  2092     // The following provides ES6 behavior when a TypeError is thrown under ES5.
  2093 
  2094     var isSealed;
  2095 
  2096     try {
  2097       isSealed = Object.isSealed(obj);
  2098     } catch (err) {
  2099       if (err instanceof TypeError) isSealed = true;
  2100       else throw err;
  2101     }
  2102 
  2103     this.assert(
  2104       isSealed
  2105       , 'expected #{this} to be sealed'
  2106       , 'expected #{this} to not be sealed'
  2107     );
  2108   });
  2109 
  2110   /**
  2111    * ### .frozen
  2112    *
  2113    * Asserts that the target is frozen (cannot have new properties added to it
  2114    * and its existing properties cannot be modified).
  2115    *
  2116    *     var frozenObject = Object.freeze({});
  2117    *
  2118    *     expect(frozenObject).to.be.frozen;
  2119    *     expect({}).to.not.be.frozen;
  2120    *
  2121    * @name frozen
  2122    * @namespace BDD
  2123    * @api public
  2124    */
  2125 
  2126   Assertion.addProperty('frozen', function() {
  2127     var obj = flag(this, 'object');
  2128 
  2129     // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.
  2130     // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.
  2131     // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen
  2132     // The following provides ES6 behavior when a TypeError is thrown under ES5.
  2133 
  2134     var isFrozen;
  2135 
  2136     try {
  2137       isFrozen = Object.isFrozen(obj);
  2138     } catch (err) {
  2139       if (err instanceof TypeError) isFrozen = true;
  2140       else throw err;
  2141     }
  2142 
  2143     this.assert(
  2144       isFrozen
  2145       , 'expected #{this} to be frozen'
  2146       , 'expected #{this} to not be frozen'
  2147     );
  2148   });
  2149 };
  2150 
  2151 },{}],6:[function(require,module,exports){
  2152 /*!
  2153  * chai
  2154  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
  2155  * MIT Licensed
  2156  */
  2157 
  2158 
  2159 module.exports = function (chai, util) {
  2160 
  2161   /*!
  2162    * Chai dependencies.
  2163    */
  2164 
  2165   var Assertion = chai.Assertion
  2166     , flag = util.flag;
  2167 
  2168   /*!
  2169    * Module export.
  2170    */
  2171 
  2172   /**
  2173    * ### assert(expression, message)
  2174    *
  2175    * Write your own test expressions.
  2176    *
  2177    *     assert('foo' !== 'bar', 'foo is not bar');
  2178    *     assert(Array.isArray([]), 'empty arrays are arrays');
  2179    *
  2180    * @param {Mixed} expression to test for truthiness
  2181    * @param {String} message to display on error
  2182    * @name assert
  2183    * @namespace Assert
  2184    * @api public
  2185    */
  2186 
  2187   var assert = chai.assert = function (express, errmsg) {
  2188     var test = new Assertion(null, null, chai.assert);
  2189     test.assert(
  2190         express
  2191       , errmsg
  2192       , '[ negation message unavailable ]'
  2193     );
  2194   };
  2195 
  2196   /**
  2197    * ### .fail(actual, expected, [message], [operator])
  2198    *
  2199    * Throw a failure. Node.js `assert` module-compatible.
  2200    *
  2201    * @name fail
  2202    * @param {Mixed} actual
  2203    * @param {Mixed} expected
  2204    * @param {String} message
  2205    * @param {String} operator
  2206    * @namespace Assert
  2207    * @api public
  2208    */
  2209 
  2210   assert.fail = function (actual, expected, message, operator) {
  2211     message = message || 'assert.fail()';
  2212     throw new chai.AssertionError(message, {
  2213         actual: actual
  2214       , expected: expected
  2215       , operator: operator
  2216     }, assert.fail);
  2217   };
  2218 
  2219   /**
  2220    * ### .isOk(object, [message])
  2221    *
  2222    * Asserts that `object` is truthy.
  2223    *
  2224    *     assert.isOk('everything', 'everything is ok');
  2225    *     assert.isOk(false, 'this will fail');
  2226    *
  2227    * @name isOk
  2228    * @alias ok
  2229    * @param {Mixed} object to test
  2230    * @param {String} message
  2231    * @namespace Assert
  2232    * @api public
  2233    */
  2234 
  2235   assert.isOk = function (val, msg) {
  2236     new Assertion(val, msg).is.ok;
  2237   };
  2238 
  2239   /**
  2240    * ### .isNotOk(object, [message])
  2241    *
  2242    * Asserts that `object` is falsy.
  2243    *
  2244    *     assert.isNotOk('everything', 'this will fail');
  2245    *     assert.isNotOk(false, 'this will pass');
  2246    *
  2247    * @name isNotOk
  2248    * @alias notOk
  2249    * @param {Mixed} object to test
  2250    * @param {String} message
  2251    * @namespace Assert
  2252    * @api public
  2253    */
  2254 
  2255   assert.isNotOk = function (val, msg) {
  2256     new Assertion(val, msg).is.not.ok;
  2257   };
  2258 
  2259   /**
  2260    * ### .equal(actual, expected, [message])
  2261    *
  2262    * Asserts non-strict equality (`==`) of `actual` and `expected`.
  2263    *
  2264    *     assert.equal(3, '3', '== coerces values to strings');
  2265    *
  2266    * @name equal
  2267    * @param {Mixed} actual
  2268    * @param {Mixed} expected
  2269    * @param {String} message
  2270    * @namespace Assert
  2271    * @api public
  2272    */
  2273 
  2274   assert.equal = function (act, exp, msg) {
  2275     var test = new Assertion(act, msg, assert.equal);
  2276 
  2277     test.assert(
  2278         exp == flag(test, 'object')
  2279       , 'expected #{this} to equal #{exp}'
  2280       , 'expected #{this} to not equal #{act}'
  2281       , exp
  2282       , act
  2283     );
  2284   };
  2285 
  2286   /**
  2287    * ### .notEqual(actual, expected, [message])
  2288    *
  2289    * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
  2290    *
  2291    *     assert.notEqual(3, 4, 'these numbers are not equal');
  2292    *
  2293    * @name notEqual
  2294    * @param {Mixed} actual
  2295    * @param {Mixed} expected
  2296    * @param {String} message
  2297    * @namespace Assert
  2298    * @api public
  2299    */
  2300 
  2301   assert.notEqual = function (act, exp, msg) {
  2302     var test = new Assertion(act, msg, assert.notEqual);
  2303 
  2304     test.assert(
  2305         exp != flag(test, 'object')
  2306       , 'expected #{this} to not equal #{exp}'
  2307       , 'expected #{this} to equal #{act}'
  2308       , exp
  2309       , act
  2310     );
  2311   };
  2312 
  2313   /**
  2314    * ### .strictEqual(actual, expected, [message])
  2315    *
  2316    * Asserts strict equality (`===`) of `actual` and `expected`.
  2317    *
  2318    *     assert.strictEqual(true, true, 'these booleans are strictly equal');
  2319    *
  2320    * @name strictEqual
  2321    * @param {Mixed} actual
  2322    * @param {Mixed} expected
  2323    * @param {String} message
  2324    * @namespace Assert
  2325    * @api public
  2326    */
  2327 
  2328   assert.strictEqual = function (act, exp, msg) {
  2329     new Assertion(act, msg).to.equal(exp);
  2330   };
  2331 
  2332   /**
  2333    * ### .notStrictEqual(actual, expected, [message])
  2334    *
  2335    * Asserts strict inequality (`!==`) of `actual` and `expected`.
  2336    *
  2337    *     assert.notStrictEqual(3, '3', 'no coercion for strict equality');
  2338    *
  2339    * @name notStrictEqual
  2340    * @param {Mixed} actual
  2341    * @param {Mixed} expected
  2342    * @param {String} message
  2343    * @namespace Assert
  2344    * @api public
  2345    */
  2346 
  2347   assert.notStrictEqual = function (act, exp, msg) {
  2348     new Assertion(act, msg).to.not.equal(exp);
  2349   };
  2350 
  2351   /**
  2352    * ### .deepEqual(actual, expected, [message])
  2353    *
  2354    * Asserts that `actual` is deeply equal to `expected`.
  2355    *
  2356    *     assert.deepEqual({ tea: 'green' }, { tea: 'green' });
  2357    *
  2358    * @name deepEqual
  2359    * @param {Mixed} actual
  2360    * @param {Mixed} expected
  2361    * @param {String} message
  2362    * @namespace Assert
  2363    * @api public
  2364    */
  2365 
  2366   assert.deepEqual = function (act, exp, msg) {
  2367     new Assertion(act, msg).to.eql(exp);
  2368   };
  2369 
  2370   /**
  2371    * ### .notDeepEqual(actual, expected, [message])
  2372    *
  2373    * Assert that `actual` is not deeply equal to `expected`.
  2374    *
  2375    *     assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
  2376    *
  2377    * @name notDeepEqual
  2378    * @param {Mixed} actual
  2379    * @param {Mixed} expected
  2380    * @param {String} message
  2381    * @namespace Assert
  2382    * @api public
  2383    */
  2384 
  2385   assert.notDeepEqual = function (act, exp, msg) {
  2386     new Assertion(act, msg).to.not.eql(exp);
  2387   };
  2388 
  2389    /**
  2390    * ### .isAbove(valueToCheck, valueToBeAbove, [message])
  2391    *
  2392    * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`
  2393    *
  2394    *     assert.isAbove(5, 2, '5 is strictly greater than 2');
  2395    *
  2396    * @name isAbove
  2397    * @param {Mixed} valueToCheck
  2398    * @param {Mixed} valueToBeAbove
  2399    * @param {String} message
  2400    * @namespace Assert
  2401    * @api public
  2402    */
  2403 
  2404   assert.isAbove = function (val, abv, msg) {
  2405     new Assertion(val, msg).to.be.above(abv);
  2406   };
  2407 
  2408    /**
  2409    * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])
  2410    *
  2411    * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`
  2412    *
  2413    *     assert.isAtLeast(5, 2, '5 is greater or equal to 2');
  2414    *     assert.isAtLeast(3, 3, '3 is greater or equal to 3');
  2415    *
  2416    * @name isAtLeast
  2417    * @param {Mixed} valueToCheck
  2418    * @param {Mixed} valueToBeAtLeast
  2419    * @param {String} message
  2420    * @namespace Assert
  2421    * @api public
  2422    */
  2423 
  2424   assert.isAtLeast = function (val, atlst, msg) {
  2425     new Assertion(val, msg).to.be.least(atlst);
  2426   };
  2427 
  2428    /**
  2429    * ### .isBelow(valueToCheck, valueToBeBelow, [message])
  2430    *
  2431    * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`
  2432    *
  2433    *     assert.isBelow(3, 6, '3 is strictly less than 6');
  2434    *
  2435    * @name isBelow
  2436    * @param {Mixed} valueToCheck
  2437    * @param {Mixed} valueToBeBelow
  2438    * @param {String} message
  2439    * @namespace Assert
  2440    * @api public
  2441    */
  2442 
  2443   assert.isBelow = function (val, blw, msg) {
  2444     new Assertion(val, msg).to.be.below(blw);
  2445   };
  2446 
  2447    /**
  2448    * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])
  2449    *
  2450    * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`
  2451    *
  2452    *     assert.isAtMost(3, 6, '3 is less than or equal to 6');
  2453    *     assert.isAtMost(4, 4, '4 is less than or equal to 4');
  2454    *
  2455    * @name isAtMost
  2456    * @param {Mixed} valueToCheck
  2457    * @param {Mixed} valueToBeAtMost
  2458    * @param {String} message
  2459    * @namespace Assert
  2460    * @api public
  2461    */
  2462 
  2463   assert.isAtMost = function (val, atmst, msg) {
  2464     new Assertion(val, msg).to.be.most(atmst);
  2465   };
  2466 
  2467   /**
  2468    * ### .isTrue(value, [message])
  2469    *
  2470    * Asserts that `value` is true.
  2471    *
  2472    *     var teaServed = true;
  2473    *     assert.isTrue(teaServed, 'the tea has been served');
  2474    *
  2475    * @name isTrue
  2476    * @param {Mixed} value
  2477    * @param {String} message
  2478    * @namespace Assert
  2479    * @api public
  2480    */
  2481 
  2482   assert.isTrue = function (val, msg) {
  2483     new Assertion(val, msg).is['true'];
  2484   };
  2485 
  2486   /**
  2487    * ### .isNotTrue(value, [message])
  2488    *
  2489    * Asserts that `value` is not true.
  2490    *
  2491    *     var tea = 'tasty chai';
  2492    *     assert.isNotTrue(tea, 'great, time for tea!');
  2493    *
  2494    * @name isNotTrue
  2495    * @param {Mixed} value
  2496    * @param {String} message
  2497    * @namespace Assert
  2498    * @api public
  2499    */
  2500 
  2501   assert.isNotTrue = function (val, msg) {
  2502     new Assertion(val, msg).to.not.equal(true);
  2503   };
  2504 
  2505   /**
  2506    * ### .isFalse(value, [message])
  2507    *
  2508    * Asserts that `value` is false.
  2509    *
  2510    *     var teaServed = false;
  2511    *     assert.isFalse(teaServed, 'no tea yet? hmm...');
  2512    *
  2513    * @name isFalse
  2514    * @param {Mixed} value
  2515    * @param {String} message
  2516    * @namespace Assert
  2517    * @api public
  2518    */
  2519 
  2520   assert.isFalse = function (val, msg) {
  2521     new Assertion(val, msg).is['false'];
  2522   };
  2523 
  2524   /**
  2525    * ### .isNotFalse(value, [message])
  2526    *
  2527    * Asserts that `value` is not false.
  2528    *
  2529    *     var tea = 'tasty chai';
  2530    *     assert.isNotFalse(tea, 'great, time for tea!');
  2531    *
  2532    * @name isNotFalse
  2533    * @param {Mixed} value
  2534    * @param {String} message
  2535    * @namespace Assert
  2536    * @api public
  2537    */
  2538 
  2539   assert.isNotFalse = function (val, msg) {
  2540     new Assertion(val, msg).to.not.equal(false);
  2541   };
  2542 
  2543   /**
  2544    * ### .isNull(value, [message])
  2545    *
  2546    * Asserts that `value` is null.
  2547    *
  2548    *     assert.isNull(err, 'there was no error');
  2549    *
  2550    * @name isNull
  2551    * @param {Mixed} value
  2552    * @param {String} message
  2553    * @namespace Assert
  2554    * @api public
  2555    */
  2556 
  2557   assert.isNull = function (val, msg) {
  2558     new Assertion(val, msg).to.equal(null);
  2559   };
  2560 
  2561   /**
  2562    * ### .isNotNull(value, [message])
  2563    *
  2564    * Asserts that `value` is not null.
  2565    *
  2566    *     var tea = 'tasty chai';
  2567    *     assert.isNotNull(tea, 'great, time for tea!');
  2568    *
  2569    * @name isNotNull
  2570    * @param {Mixed} value
  2571    * @param {String} message
  2572    * @namespace Assert
  2573    * @api public
  2574    */
  2575 
  2576   assert.isNotNull = function (val, msg) {
  2577     new Assertion(val, msg).to.not.equal(null);
  2578   };
  2579 
  2580   /**
  2581    * ### .isNaN
  2582    * Asserts that value is NaN
  2583    *
  2584    *    assert.isNaN('foo', 'foo is NaN');
  2585    *
  2586    * @name isNaN
  2587    * @param {Mixed} value
  2588    * @param {String} message
  2589    * @namespace Assert
  2590    * @api public
  2591    */
  2592 
  2593   assert.isNaN = function (val, msg) {
  2594     new Assertion(val, msg).to.be.NaN;
  2595   };
  2596 
  2597   /**
  2598    * ### .isNotNaN
  2599    * Asserts that value is not NaN
  2600    *
  2601    *    assert.isNotNaN(4, '4 is not NaN');
  2602    *
  2603    * @name isNotNaN
  2604    * @param {Mixed} value
  2605    * @param {String} message
  2606    * @namespace Assert
  2607    * @api public
  2608    */
  2609   assert.isNotNaN = function (val, msg) {
  2610     new Assertion(val, msg).not.to.be.NaN;
  2611   };
  2612 
  2613   /**
  2614    * ### .isUndefined(value, [message])
  2615    *
  2616    * Asserts that `value` is `undefined`.
  2617    *
  2618    *     var tea;
  2619    *     assert.isUndefined(tea, 'no tea defined');
  2620    *
  2621    * @name isUndefined
  2622    * @param {Mixed} value
  2623    * @param {String} message
  2624    * @namespace Assert
  2625    * @api public
  2626    */
  2627 
  2628   assert.isUndefined = function (val, msg) {
  2629     new Assertion(val, msg).to.equal(undefined);
  2630   };
  2631 
  2632   /**
  2633    * ### .isDefined(value, [message])
  2634    *
  2635    * Asserts that `value` is not `undefined`.
  2636    *
  2637    *     var tea = 'cup of chai';
  2638    *     assert.isDefined(tea, 'tea has been defined');
  2639    *
  2640    * @name isDefined
  2641    * @param {Mixed} value
  2642    * @param {String} message
  2643    * @namespace Assert
  2644    * @api public
  2645    */
  2646 
  2647   assert.isDefined = function (val, msg) {
  2648     new Assertion(val, msg).to.not.equal(undefined);
  2649   };
  2650 
  2651   /**
  2652    * ### .isFunction(value, [message])
  2653    *
  2654    * Asserts that `value` is a function.
  2655    *
  2656    *     function serveTea() { return 'cup of tea'; };
  2657    *     assert.isFunction(serveTea, 'great, we can have tea now');
  2658    *
  2659    * @name isFunction
  2660    * @param {Mixed} value
  2661    * @param {String} message
  2662    * @namespace Assert
  2663    * @api public
  2664    */
  2665 
  2666   assert.isFunction = function (val, msg) {
  2667     new Assertion(val, msg).to.be.a('function');
  2668   };
  2669 
  2670   /**
  2671    * ### .isNotFunction(value, [message])
  2672    *
  2673    * Asserts that `value` is _not_ a function.
  2674    *
  2675    *     var serveTea = [ 'heat', 'pour', 'sip' ];
  2676    *     assert.isNotFunction(serveTea, 'great, we have listed the steps');
  2677    *
  2678    * @name isNotFunction
  2679    * @param {Mixed} value
  2680    * @param {String} message
  2681    * @namespace Assert
  2682    * @api public
  2683    */
  2684 
  2685   assert.isNotFunction = function (val, msg) {
  2686     new Assertion(val, msg).to.not.be.a('function');
  2687   };
  2688 
  2689   /**
  2690    * ### .isObject(value, [message])
  2691    *
  2692    * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).
  2693    * _The assertion does not match subclassed objects._
  2694    *
  2695    *     var selection = { name: 'Chai', serve: 'with spices' };
  2696    *     assert.isObject(selection, 'tea selection is an object');
  2697    *
  2698    * @name isObject
  2699    * @param {Mixed} value
  2700    * @param {String} message
  2701    * @namespace Assert
  2702    * @api public
  2703    */
  2704 
  2705   assert.isObject = function (val, msg) {
  2706     new Assertion(val, msg).to.be.a('object');
  2707   };
  2708 
  2709   /**
  2710    * ### .isNotObject(value, [message])
  2711    *
  2712    * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).
  2713    *
  2714    *     var selection = 'chai'
  2715    *     assert.isNotObject(selection, 'tea selection is not an object');
  2716    *     assert.isNotObject(null, 'null is not an object');
  2717    *
  2718    * @name isNotObject
  2719    * @param {Mixed} value
  2720    * @param {String} message
  2721    * @namespace Assert
  2722    * @api public
  2723    */
  2724 
  2725   assert.isNotObject = function (val, msg) {
  2726     new Assertion(val, msg).to.not.be.a('object');
  2727   };
  2728 
  2729   /**
  2730    * ### .isArray(value, [message])
  2731    *
  2732    * Asserts that `value` is an array.
  2733    *
  2734    *     var menu = [ 'green', 'chai', 'oolong' ];
  2735    *     assert.isArray(menu, 'what kind of tea do we want?');
  2736    *
  2737    * @name isArray
  2738    * @param {Mixed} value
  2739    * @param {String} message
  2740    * @namespace Assert
  2741    * @api public
  2742    */
  2743 
  2744   assert.isArray = function (val, msg) {
  2745     new Assertion(val, msg).to.be.an('array');
  2746   };
  2747 
  2748   /**
  2749    * ### .isNotArray(value, [message])
  2750    *
  2751    * Asserts that `value` is _not_ an array.
  2752    *
  2753    *     var menu = 'green|chai|oolong';
  2754    *     assert.isNotArray(menu, 'what kind of tea do we want?');
  2755    *
  2756    * @name isNotArray
  2757    * @param {Mixed} value
  2758    * @param {String} message
  2759    * @namespace Assert
  2760    * @api public
  2761    */
  2762 
  2763   assert.isNotArray = function (val, msg) {
  2764     new Assertion(val, msg).to.not.be.an('array');
  2765   };
  2766 
  2767   /**
  2768    * ### .isString(value, [message])
  2769    *
  2770    * Asserts that `value` is a string.
  2771    *
  2772    *     var teaOrder = 'chai';
  2773    *     assert.isString(teaOrder, 'order placed');
  2774    *
  2775    * @name isString
  2776    * @param {Mixed} value
  2777    * @param {String} message
  2778    * @namespace Assert
  2779    * @api public
  2780    */
  2781 
  2782   assert.isString = function (val, msg) {
  2783     new Assertion(val, msg).to.be.a('string');
  2784   };
  2785 
  2786   /**
  2787    * ### .isNotString(value, [message])
  2788    *
  2789    * Asserts that `value` is _not_ a string.
  2790    *
  2791    *     var teaOrder = 4;
  2792    *     assert.isNotString(teaOrder, 'order placed');
  2793    *
  2794    * @name isNotString
  2795    * @param {Mixed} value
  2796    * @param {String} message
  2797    * @namespace Assert
  2798    * @api public
  2799    */
  2800 
  2801   assert.isNotString = function (val, msg) {
  2802     new Assertion(val, msg).to.not.be.a('string');
  2803   };
  2804 
  2805   /**
  2806    * ### .isNumber(value, [message])
  2807    *
  2808    * Asserts that `value` is a number.
  2809    *
  2810    *     var cups = 2;
  2811    *     assert.isNumber(cups, 'how many cups');
  2812    *
  2813    * @name isNumber
  2814    * @param {Number} value
  2815    * @param {String} message
  2816    * @namespace Assert
  2817    * @api public
  2818    */
  2819 
  2820   assert.isNumber = function (val, msg) {
  2821     new Assertion(val, msg).to.be.a('number');
  2822   };
  2823 
  2824   /**
  2825    * ### .isNotNumber(value, [message])
  2826    *
  2827    * Asserts that `value` is _not_ a number.
  2828    *
  2829    *     var cups = '2 cups please';
  2830    *     assert.isNotNumber(cups, 'how many cups');
  2831    *
  2832    * @name isNotNumber
  2833    * @param {Mixed} value
  2834    * @param {String} message
  2835    * @namespace Assert
  2836    * @api public
  2837    */
  2838 
  2839   assert.isNotNumber = function (val, msg) {
  2840     new Assertion(val, msg).to.not.be.a('number');
  2841   };
  2842 
  2843   /**
  2844    * ### .isBoolean(value, [message])
  2845    *
  2846    * Asserts that `value` is a boolean.
  2847    *
  2848    *     var teaReady = true
  2849    *       , teaServed = false;
  2850    *
  2851    *     assert.isBoolean(teaReady, 'is the tea ready');
  2852    *     assert.isBoolean(teaServed, 'has tea been served');
  2853    *
  2854    * @name isBoolean
  2855    * @param {Mixed} value
  2856    * @param {String} message
  2857    * @namespace Assert
  2858    * @api public
  2859    */
  2860 
  2861   assert.isBoolean = function (val, msg) {
  2862     new Assertion(val, msg).to.be.a('boolean');
  2863   };
  2864 
  2865   /**
  2866    * ### .isNotBoolean(value, [message])
  2867    *
  2868    * Asserts that `value` is _not_ a boolean.
  2869    *
  2870    *     var teaReady = 'yep'
  2871    *       , teaServed = 'nope';
  2872    *
  2873    *     assert.isNotBoolean(teaReady, 'is the tea ready');
  2874    *     assert.isNotBoolean(teaServed, 'has tea been served');
  2875    *
  2876    * @name isNotBoolean
  2877    * @param {Mixed} value
  2878    * @param {String} message
  2879    * @namespace Assert
  2880    * @api public
  2881    */
  2882 
  2883   assert.isNotBoolean = function (val, msg) {
  2884     new Assertion(val, msg).to.not.be.a('boolean');
  2885   };
  2886 
  2887   /**
  2888    * ### .typeOf(value, name, [message])
  2889    *
  2890    * Asserts that `value`'s type is `name`, as determined by
  2891    * `Object.prototype.toString`.
  2892    *
  2893    *     assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');
  2894    *     assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');
  2895    *     assert.typeOf('tea', 'string', 'we have a string');
  2896    *     assert.typeOf(/tea/, 'regexp', 'we have a regular expression');
  2897    *     assert.typeOf(null, 'null', 'we have a null');
  2898    *     assert.typeOf(undefined, 'undefined', 'we have an undefined');
  2899    *
  2900    * @name typeOf
  2901    * @param {Mixed} value
  2902    * @param {String} name
  2903    * @param {String} message
  2904    * @namespace Assert
  2905    * @api public
  2906    */
  2907 
  2908   assert.typeOf = function (val, type, msg) {
  2909     new Assertion(val, msg).to.be.a(type);
  2910   };
  2911 
  2912   /**
  2913    * ### .notTypeOf(value, name, [message])
  2914    *
  2915    * Asserts that `value`'s type is _not_ `name`, as determined by
  2916    * `Object.prototype.toString`.
  2917    *
  2918    *     assert.notTypeOf('tea', 'number', 'strings are not numbers');
  2919    *
  2920    * @name notTypeOf
  2921    * @param {Mixed} value
  2922    * @param {String} typeof name
  2923    * @param {String} message
  2924    * @namespace Assert
  2925    * @api public
  2926    */
  2927 
  2928   assert.notTypeOf = function (val, type, msg) {
  2929     new Assertion(val, msg).to.not.be.a(type);
  2930   };
  2931 
  2932   /**
  2933    * ### .instanceOf(object, constructor, [message])
  2934    *
  2935    * Asserts that `value` is an instance of `constructor`.
  2936    *
  2937    *     var Tea = function (name) { this.name = name; }
  2938    *       , chai = new Tea('chai');
  2939    *
  2940    *     assert.instanceOf(chai, Tea, 'chai is an instance of tea');
  2941    *
  2942    * @name instanceOf
  2943    * @param {Object} object
  2944    * @param {Constructor} constructor
  2945    * @param {String} message
  2946    * @namespace Assert
  2947    * @api public
  2948    */
  2949 
  2950   assert.instanceOf = function (val, type, msg) {
  2951     new Assertion(val, msg).to.be.instanceOf(type);
  2952   };
  2953 
  2954   /**
  2955    * ### .notInstanceOf(object, constructor, [message])
  2956    *
  2957    * Asserts `value` is not an instance of `constructor`.
  2958    *
  2959    *     var Tea = function (name) { this.name = name; }
  2960    *       , chai = new String('chai');
  2961    *
  2962    *     assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');
  2963    *
  2964    * @name notInstanceOf
  2965    * @param {Object} object
  2966    * @param {Constructor} constructor
  2967    * @param {String} message
  2968    * @namespace Assert
  2969    * @api public
  2970    */
  2971 
  2972   assert.notInstanceOf = function (val, type, msg) {
  2973     new Assertion(val, msg).to.not.be.instanceOf(type);
  2974   };
  2975 
  2976   /**
  2977    * ### .include(haystack, needle, [message])
  2978    *
  2979    * Asserts that `haystack` includes `needle`. Works
  2980    * for strings and arrays.
  2981    *
  2982    *     assert.include('foobar', 'bar', 'foobar contains string "bar"');
  2983    *     assert.include([ 1, 2, 3 ], 3, 'array contains value');
  2984    *
  2985    * @name include
  2986    * @param {Array|String} haystack
  2987    * @param {Mixed} needle
  2988    * @param {String} message
  2989    * @namespace Assert
  2990    * @api public
  2991    */
  2992 
  2993   assert.include = function (exp, inc, msg) {
  2994     new Assertion(exp, msg, assert.include).include(inc);
  2995   };
  2996 
  2997   /**
  2998    * ### .notInclude(haystack, needle, [message])
  2999    *
  3000    * Asserts that `haystack` does not include `needle`. Works
  3001    * for strings and arrays.
  3002    *
  3003    *     assert.notInclude('foobar', 'baz', 'string not include substring');
  3004    *     assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');
  3005    *
  3006    * @name notInclude
  3007    * @param {Array|String} haystack
  3008    * @param {Mixed} needle
  3009    * @param {String} message
  3010    * @namespace Assert
  3011    * @api public
  3012    */
  3013 
  3014   assert.notInclude = function (exp, inc, msg) {
  3015     new Assertion(exp, msg, assert.notInclude).not.include(inc);
  3016   };
  3017 
  3018   /**
  3019    * ### .match(value, regexp, [message])
  3020    *
  3021    * Asserts that `value` matches the regular expression `regexp`.
  3022    *
  3023    *     assert.match('foobar', /^foo/, 'regexp matches');
  3024    *
  3025    * @name match
  3026    * @param {Mixed} value
  3027    * @param {RegExp} regexp
  3028    * @param {String} message
  3029    * @namespace Assert
  3030    * @api public
  3031    */
  3032 
  3033   assert.match = function (exp, re, msg) {
  3034     new Assertion(exp, msg).to.match(re);
  3035   };
  3036 
  3037   /**
  3038    * ### .notMatch(value, regexp, [message])
  3039    *
  3040    * Asserts that `value` does not match the regular expression `regexp`.
  3041    *
  3042    *     assert.notMatch('foobar', /^foo/, 'regexp does not match');
  3043    *
  3044    * @name notMatch
  3045    * @param {Mixed} value
  3046    * @param {RegExp} regexp
  3047    * @param {String} message
  3048    * @namespace Assert
  3049    * @api public
  3050    */
  3051 
  3052   assert.notMatch = function (exp, re, msg) {
  3053     new Assertion(exp, msg).to.not.match(re);
  3054   };
  3055 
  3056   /**
  3057    * ### .property(object, property, [message])
  3058    *
  3059    * Asserts that `object` has a property named by `property`.
  3060    *
  3061    *     assert.property({ tea: { green: 'matcha' }}, 'tea');
  3062    *
  3063    * @name property
  3064    * @param {Object} object
  3065    * @param {String} property
  3066    * @param {String} message
  3067    * @namespace Assert
  3068    * @api public
  3069    */
  3070 
  3071   assert.property = function (obj, prop, msg) {
  3072     new Assertion(obj, msg).to.have.property(prop);
  3073   };
  3074 
  3075   /**
  3076    * ### .notProperty(object, property, [message])
  3077    *
  3078    * Asserts that `object` does _not_ have a property named by `property`.
  3079    *
  3080    *     assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');
  3081    *
  3082    * @name notProperty
  3083    * @param {Object} object
  3084    * @param {String} property
  3085    * @param {String} message
  3086    * @namespace Assert
  3087    * @api public
  3088    */
  3089 
  3090   assert.notProperty = function (obj, prop, msg) {
  3091     new Assertion(obj, msg).to.not.have.property(prop);
  3092   };
  3093 
  3094   /**
  3095    * ### .deepProperty(object, property, [message])
  3096    *
  3097    * Asserts that `object` has a property named by `property`, which can be a
  3098    * string using dot- and bracket-notation for deep reference.
  3099    *
  3100    *     assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');
  3101    *
  3102    * @name deepProperty
  3103    * @param {Object} object
  3104    * @param {String} property
  3105    * @param {String} message
  3106    * @namespace Assert
  3107    * @api public
  3108    */
  3109 
  3110   assert.deepProperty = function (obj, prop, msg) {
  3111     new Assertion(obj, msg).to.have.deep.property(prop);
  3112   };
  3113 
  3114   /**
  3115    * ### .notDeepProperty(object, property, [message])
  3116    *
  3117    * Asserts that `object` does _not_ have a property named by `property`, which
  3118    * can be a string using dot- and bracket-notation for deep reference.
  3119    *
  3120    *     assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');
  3121    *
  3122    * @name notDeepProperty
  3123    * @param {Object} object
  3124    * @param {String} property
  3125    * @param {String} message
  3126    * @namespace Assert
  3127    * @api public
  3128    */
  3129 
  3130   assert.notDeepProperty = function (obj, prop, msg) {
  3131     new Assertion(obj, msg).to.not.have.deep.property(prop);
  3132   };
  3133 
  3134   /**
  3135    * ### .propertyVal(object, property, value, [message])
  3136    *
  3137    * Asserts that `object` has a property named by `property` with value given
  3138    * by `value`.
  3139    *
  3140    *     assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');
  3141    *
  3142    * @name propertyVal
  3143    * @param {Object} object
  3144    * @param {String} property
  3145    * @param {Mixed} value
  3146    * @param {String} message
  3147    * @namespace Assert
  3148    * @api public
  3149    */
  3150 
  3151   assert.propertyVal = function (obj, prop, val, msg) {
  3152     new Assertion(obj, msg).to.have.property(prop, val);
  3153   };
  3154 
  3155   /**
  3156    * ### .propertyNotVal(object, property, value, [message])
  3157    *
  3158    * Asserts that `object` has a property named by `property`, but with a value
  3159    * different from that given by `value`.
  3160    *
  3161    *     assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');
  3162    *
  3163    * @name propertyNotVal
  3164    * @param {Object} object
  3165    * @param {String} property
  3166    * @param {Mixed} value
  3167    * @param {String} message
  3168    * @namespace Assert
  3169    * @api public
  3170    */
  3171 
  3172   assert.propertyNotVal = function (obj, prop, val, msg) {
  3173     new Assertion(obj, msg).to.not.have.property(prop, val);
  3174   };
  3175 
  3176   /**
  3177    * ### .deepPropertyVal(object, property, value, [message])
  3178    *
  3179    * Asserts that `object` has a property named by `property` with value given
  3180    * by `value`. `property` can use dot- and bracket-notation for deep
  3181    * reference.
  3182    *
  3183    *     assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');
  3184    *
  3185    * @name deepPropertyVal
  3186    * @param {Object} object
  3187    * @param {String} property
  3188    * @param {Mixed} value
  3189    * @param {String} message
  3190    * @namespace Assert
  3191    * @api public
  3192    */
  3193 
  3194   assert.deepPropertyVal = function (obj, prop, val, msg) {
  3195     new Assertion(obj, msg).to.have.deep.property(prop, val);
  3196   };
  3197 
  3198   /**
  3199    * ### .deepPropertyNotVal(object, property, value, [message])
  3200    *
  3201    * Asserts that `object` has a property named by `property`, but with a value
  3202    * different from that given by `value`. `property` can use dot- and
  3203    * bracket-notation for deep reference.
  3204    *
  3205    *     assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');
  3206    *
  3207    * @name deepPropertyNotVal
  3208    * @param {Object} object
  3209    * @param {String} property
  3210    * @param {Mixed} value
  3211    * @param {String} message
  3212    * @namespace Assert
  3213    * @api public
  3214    */
  3215 
  3216   assert.deepPropertyNotVal = function (obj, prop, val, msg) {
  3217     new Assertion(obj, msg).to.not.have.deep.property(prop, val);
  3218   };
  3219 
  3220   /**
  3221    * ### .lengthOf(object, length, [message])
  3222    *
  3223    * Asserts that `object` has a `length` property with the expected value.
  3224    *
  3225    *     assert.lengthOf([1,2,3], 3, 'array has length of 3');
  3226    *     assert.lengthOf('foobar', 6, 'string has length of 6');
  3227    *
  3228    * @name lengthOf
  3229    * @param {Mixed} object
  3230    * @param {Number} length
  3231    * @param {String} message
  3232    * @namespace Assert
  3233    * @api public
  3234    */
  3235 
  3236   assert.lengthOf = function (exp, len, msg) {
  3237     new Assertion(exp, msg).to.have.length(len);
  3238   };
  3239 
  3240   /**
  3241    * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])
  3242    *
  3243    * Asserts that `function` will throw an error that is an instance of
  3244    * `constructor`, or alternately that it will throw an error with message
  3245    * matching `regexp`.
  3246    *
  3247    *     assert.throws(fn, 'function throws a reference error');
  3248    *     assert.throws(fn, /function throws a reference error/);
  3249    *     assert.throws(fn, ReferenceError);
  3250    *     assert.throws(fn, ReferenceError, 'function throws a reference error');
  3251    *     assert.throws(fn, ReferenceError, /function throws a reference error/);
  3252    *
  3253    * @name throws
  3254    * @alias throw
  3255    * @alias Throw
  3256    * @param {Function} function
  3257    * @param {ErrorConstructor} constructor
  3258    * @param {RegExp} regexp
  3259    * @param {String} message
  3260    * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
  3261    * @namespace Assert
  3262    * @api public
  3263    */
  3264 
  3265   assert.throws = function (fn, errt, errs, msg) {
  3266     if ('string' === typeof errt || errt instanceof RegExp) {
  3267       errs = errt;
  3268       errt = null;
  3269     }
  3270 
  3271     var assertErr = new Assertion(fn, msg).to.throw(errt, errs);
  3272     return flag(assertErr, 'object');
  3273   };
  3274 
  3275   /**
  3276    * ### .doesNotThrow(function, [constructor/regexp], [message])
  3277    *
  3278    * Asserts that `function` will _not_ throw an error that is an instance of
  3279    * `constructor`, or alternately that it will not throw an error with message
  3280    * matching `regexp`.
  3281    *
  3282    *     assert.doesNotThrow(fn, Error, 'function does not throw');
  3283    *
  3284    * @name doesNotThrow
  3285    * @param {Function} function
  3286    * @param {ErrorConstructor} constructor
  3287    * @param {RegExp} regexp
  3288    * @param {String} message
  3289    * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
  3290    * @namespace Assert
  3291    * @api public
  3292    */
  3293 
  3294   assert.doesNotThrow = function (fn, type, msg) {
  3295     if ('string' === typeof type) {
  3296       msg = type;
  3297       type = null;
  3298     }
  3299 
  3300     new Assertion(fn, msg).to.not.Throw(type);
  3301   };
  3302 
  3303   /**
  3304    * ### .operator(val1, operator, val2, [message])
  3305    *
  3306    * Compares two values using `operator`.
  3307    *
  3308    *     assert.operator(1, '<', 2, 'everything is ok');
  3309    *     assert.operator(1, '>', 2, 'this will fail');
  3310    *
  3311    * @name operator
  3312    * @param {Mixed} val1
  3313    * @param {String} operator
  3314    * @param {Mixed} val2
  3315    * @param {String} message
  3316    * @namespace Assert
  3317    * @api public
  3318    */
  3319 
  3320   assert.operator = function (val, operator, val2, msg) {
  3321     var ok;
  3322     switch(operator) {
  3323       case '==':
  3324         ok = val == val2;
  3325         break;
  3326       case '===':
  3327         ok = val === val2;
  3328         break;
  3329       case '>':
  3330         ok = val > val2;
  3331         break;
  3332       case '>=':
  3333         ok = val >= val2;
  3334         break;
  3335       case '<':
  3336         ok = val < val2;
  3337         break;
  3338       case '<=':
  3339         ok = val <= val2;
  3340         break;
  3341       case '!=':
  3342         ok = val != val2;
  3343         break;
  3344       case '!==':
  3345         ok = val !== val2;
  3346         break;
  3347       default:
  3348         throw new Error('Invalid operator "' + operator + '"');
  3349     }
  3350     var test = new Assertion(ok, msg);
  3351     test.assert(
  3352         true === flag(test, 'object')
  3353       , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
  3354       , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );
  3355   };
  3356 
  3357   /**
  3358    * ### .closeTo(actual, expected, delta, [message])
  3359    *
  3360    * Asserts that the target is equal `expected`, to within a +/- `delta` range.
  3361    *
  3362    *     assert.closeTo(1.5, 1, 0.5, 'numbers are close');
  3363    *
  3364    * @name closeTo
  3365    * @param {Number} actual
  3366    * @param {Number} expected
  3367    * @param {Number} delta
  3368    * @param {String} message
  3369    * @namespace Assert
  3370    * @api public
  3371    */
  3372 
  3373   assert.closeTo = function (act, exp, delta, msg) {
  3374     new Assertion(act, msg).to.be.closeTo(exp, delta);
  3375   };
  3376 
  3377   /**
  3378    * ### .approximately(actual, expected, delta, [message])
  3379    *
  3380    * Asserts that the target is equal `expected`, to within a +/- `delta` range.
  3381    *
  3382    *     assert.approximately(1.5, 1, 0.5, 'numbers are close');
  3383    *
  3384    * @name approximately
  3385    * @param {Number} actual
  3386    * @param {Number} expected
  3387    * @param {Number} delta
  3388    * @param {String} message
  3389    * @namespace Assert
  3390    * @api public
  3391    */
  3392 
  3393   assert.approximately = function (act, exp, delta, msg) {
  3394     new Assertion(act, msg).to.be.approximately(exp, delta);
  3395   };
  3396 
  3397   /**
  3398    * ### .sameMembers(set1, set2, [message])
  3399    *
  3400    * Asserts that `set1` and `set2` have the same members.
  3401    * Order is not taken into account.
  3402    *
  3403    *     assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');
  3404    *
  3405    * @name sameMembers
  3406    * @param {Array} set1
  3407    * @param {Array} set2
  3408    * @param {String} message
  3409    * @namespace Assert
  3410    * @api public
  3411    */
  3412 
  3413   assert.sameMembers = function (set1, set2, msg) {
  3414     new Assertion(set1, msg).to.have.same.members(set2);
  3415   }
  3416 
  3417   /**
  3418    * ### .sameDeepMembers(set1, set2, [message])
  3419    *
  3420    * Asserts that `set1` and `set2` have the same members - using a deep equality checking.
  3421    * Order is not taken into account.
  3422    *
  3423    *     assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');
  3424    *
  3425    * @name sameDeepMembers
  3426    * @param {Array} set1
  3427    * @param {Array} set2
  3428    * @param {String} message
  3429    * @namespace Assert
  3430    * @api public
  3431    */
  3432 
  3433   assert.sameDeepMembers = function (set1, set2, msg) {
  3434     new Assertion(set1, msg).to.have.same.deep.members(set2);
  3435   }
  3436 
  3437   /**
  3438    * ### .includeMembers(superset, subset, [message])
  3439    *
  3440    * Asserts that `subset` is included in `superset`.
  3441    * Order is not taken into account.
  3442    *
  3443    *     assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');
  3444    *
  3445    * @name includeMembers
  3446    * @param {Array} superset
  3447    * @param {Array} subset
  3448    * @param {String} message
  3449    * @namespace Assert
  3450    * @api public
  3451    */
  3452 
  3453   assert.includeMembers = function (superset, subset, msg) {
  3454     new Assertion(superset, msg).to.include.members(subset);
  3455   }
  3456 
  3457   /**
  3458    * ### .includeDeepMembers(superset, subset, [message])
  3459    *
  3460    * Asserts that `subset` is included in `superset` - using deep equality checking.
  3461    * Order is not taken into account.
  3462    * Duplicates are ignored.
  3463    *
  3464    *     assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');
  3465    *
  3466    * @name includeDeepMembers
  3467    * @param {Array} superset
  3468    * @param {Array} subset
  3469    * @param {String} message
  3470    * @namespace Assert
  3471    * @api public
  3472    */
  3473 
  3474   assert.includeDeepMembers = function (superset, subset, msg) {
  3475     new Assertion(superset, msg).to.include.deep.members(subset);
  3476   }
  3477 
  3478   /**
  3479    * ### .oneOf(inList, list, [message])
  3480    *
  3481    * Asserts that non-object, non-array value `inList` appears in the flat array `list`.
  3482    *
  3483    *     assert.oneOf(1, [ 2, 1 ], 'Not found in list');
  3484    *
  3485    * @name oneOf
  3486    * @param {*} inList
  3487    * @param {Array<*>} list
  3488    * @param {String} message
  3489    * @namespace Assert
  3490    * @api public
  3491    */
  3492 
  3493   assert.oneOf = function (inList, list, msg) {
  3494     new Assertion(inList, msg).to.be.oneOf(list);
  3495   }
  3496 
  3497    /**
  3498    * ### .changes(function, object, property)
  3499    *
  3500    * Asserts that a function changes the value of a property
  3501    *
  3502    *     var obj = { val: 10 };
  3503    *     var fn = function() { obj.val = 22 };
  3504    *     assert.changes(fn, obj, 'val');
  3505    *
  3506    * @name changes
  3507    * @param {Function} modifier function
  3508    * @param {Object} object
  3509    * @param {String} property name
  3510    * @param {String} message _optional_
  3511    * @namespace Assert
  3512    * @api public
  3513    */
  3514 
  3515   assert.changes = function (fn, obj, prop) {
  3516     new Assertion(fn).to.change(obj, prop);
  3517   }
  3518 
  3519    /**
  3520    * ### .doesNotChange(function, object, property)
  3521    *
  3522    * Asserts that a function does not changes the value of a property
  3523    *
  3524    *     var obj = { val: 10 };
  3525    *     var fn = function() { console.log('foo'); };
  3526    *     assert.doesNotChange(fn, obj, 'val');
  3527    *
  3528    * @name doesNotChange
  3529    * @param {Function} modifier function
  3530    * @param {Object} object
  3531    * @param {String} property name
  3532    * @param {String} message _optional_
  3533    * @namespace Assert
  3534    * @api public
  3535    */
  3536 
  3537   assert.doesNotChange = function (fn, obj, prop) {
  3538     new Assertion(fn).to.not.change(obj, prop);
  3539   }
  3540 
  3541    /**
  3542    * ### .increases(function, object, property)
  3543    *
  3544    * Asserts that a function increases an object property
  3545    *
  3546    *     var obj = { val: 10 };
  3547    *     var fn = function() { obj.val = 13 };
  3548    *     assert.increases(fn, obj, 'val');
  3549    *
  3550    * @name increases
  3551    * @param {Function} modifier function
  3552    * @param {Object} object
  3553    * @param {String} property name
  3554    * @param {String} message _optional_
  3555    * @namespace Assert
  3556    * @api public
  3557    */
  3558 
  3559   assert.increases = function (fn, obj, prop) {
  3560     new Assertion(fn).to.increase(obj, prop);
  3561   }
  3562 
  3563    /**
  3564    * ### .doesNotIncrease(function, object, property)
  3565    *
  3566    * Asserts that a function does not increase object property
  3567    *
  3568    *     var obj = { val: 10 };
  3569    *     var fn = function() { obj.val = 8 };
  3570    *     assert.doesNotIncrease(fn, obj, 'val');
  3571    *
  3572    * @name doesNotIncrease
  3573    * @param {Function} modifier function
  3574    * @param {Object} object
  3575    * @param {String} property name
  3576    * @param {String} message _optional_
  3577    * @namespace Assert
  3578    * @api public
  3579    */
  3580 
  3581   assert.doesNotIncrease = function (fn, obj, prop) {
  3582     new Assertion(fn).to.not.increase(obj, prop);
  3583   }
  3584 
  3585    /**
  3586    * ### .decreases(function, object, property)
  3587    *
  3588    * Asserts that a function decreases an object property
  3589    *
  3590    *     var obj = { val: 10 };
  3591    *     var fn = function() { obj.val = 5 };
  3592    *     assert.decreases(fn, obj, 'val');
  3593    *
  3594    * @name decreases
  3595    * @param {Function} modifier function
  3596    * @param {Object} object
  3597    * @param {String} property name
  3598    * @param {String} message _optional_
  3599    * @namespace Assert
  3600    * @api public
  3601    */
  3602 
  3603   assert.decreases = function (fn, obj, prop) {
  3604     new Assertion(fn).to.decrease(obj, prop);
  3605   }
  3606 
  3607    /**
  3608    * ### .doesNotDecrease(function, object, property)
  3609    *
  3610    * Asserts that a function does not decreases an object property
  3611    *
  3612    *     var obj = { val: 10 };
  3613    *     var fn = function() { obj.val = 15 };
  3614    *     assert.doesNotDecrease(fn, obj, 'val');
  3615    *
  3616    * @name doesNotDecrease
  3617    * @param {Function} modifier function
  3618    * @param {Object} object
  3619    * @param {String} property name
  3620    * @param {String} message _optional_
  3621    * @namespace Assert
  3622    * @api public
  3623    */
  3624 
  3625   assert.doesNotDecrease = function (fn, obj, prop) {
  3626     new Assertion(fn).to.not.decrease(obj, prop);
  3627   }
  3628 
  3629   /*!
  3630    * ### .ifError(object)
  3631    *
  3632    * Asserts if value is not a false value, and throws if it is a true value.
  3633    * This is added to allow for chai to be a drop-in replacement for Node's
  3634    * assert class.
  3635    *
  3636    *     var err = new Error('I am a custom error');
  3637    *     assert.ifError(err); // Rethrows err!
  3638    *
  3639    * @name ifError
  3640    * @param {Object} object
  3641    * @namespace Assert
  3642    * @api public
  3643    */
  3644 
  3645   assert.ifError = function (val) {
  3646     if (val) {
  3647       throw(val);
  3648     }
  3649   };
  3650 
  3651   /**
  3652    * ### .isExtensible(object)
  3653    *
  3654    * Asserts that `object` is extensible (can have new properties added to it).
  3655    *
  3656    *     assert.isExtensible({});
  3657    *
  3658    * @name isExtensible
  3659    * @alias extensible
  3660    * @param {Object} object
  3661    * @param {String} message _optional_
  3662    * @namespace Assert
  3663    * @api public
  3664    */
  3665 
  3666   assert.isExtensible = function (obj, msg) {
  3667     new Assertion(obj, msg).to.be.extensible;
  3668   };
  3669 
  3670   /**
  3671    * ### .isNotExtensible(object)
  3672    *
  3673    * Asserts that `object` is _not_ extensible.
  3674    *
  3675    *     var nonExtensibleObject = Object.preventExtensions({});
  3676    *     var sealedObject = Object.seal({});
  3677    *     var frozenObject = Object.freese({});
  3678    *
  3679    *     assert.isNotExtensible(nonExtensibleObject);
  3680    *     assert.isNotExtensible(sealedObject);
  3681    *     assert.isNotExtensible(frozenObject);
  3682    *
  3683    * @name isNotExtensible
  3684    * @alias notExtensible
  3685    * @param {Object} object
  3686    * @param {String} message _optional_
  3687    * @namespace Assert
  3688    * @api public
  3689    */
  3690 
  3691   assert.isNotExtensible = function (obj, msg) {
  3692     new Assertion(obj, msg).to.not.be.extensible;
  3693   };
  3694 
  3695   /**
  3696    * ### .isSealed(object)
  3697    *
  3698    * Asserts that `object` is sealed (cannot have new properties added to it
  3699    * and its existing properties cannot be removed).
  3700    *
  3701    *     var sealedObject = Object.seal({});
  3702    *     var frozenObject = Object.seal({});
  3703    *
  3704    *     assert.isSealed(sealedObject);
  3705    *     assert.isSealed(frozenObject);
  3706    *
  3707    * @name isSealed
  3708    * @alias sealed
  3709    * @param {Object} object
  3710    * @param {String} message _optional_
  3711    * @namespace Assert
  3712    * @api public
  3713    */
  3714 
  3715   assert.isSealed = function (obj, msg) {
  3716     new Assertion(obj, msg).to.be.sealed;
  3717   };
  3718 
  3719   /**
  3720    * ### .isNotSealed(object)
  3721    *
  3722    * Asserts that `object` is _not_ sealed.
  3723    *
  3724    *     assert.isNotSealed({});
  3725    *
  3726    * @name isNotSealed
  3727    * @alias notSealed
  3728    * @param {Object} object
  3729    * @param {String} message _optional_
  3730    * @namespace Assert
  3731    * @api public
  3732    */
  3733 
  3734   assert.isNotSealed = function (obj, msg) {
  3735     new Assertion(obj, msg).to.not.be.sealed;
  3736   };
  3737 
  3738   /**
  3739    * ### .isFrozen(object)
  3740    *
  3741    * Asserts that `object` is frozen (cannot have new properties added to it
  3742    * and its existing properties cannot be modified).
  3743    *
  3744    *     var frozenObject = Object.freeze({});
  3745    *     assert.frozen(frozenObject);
  3746    *
  3747    * @name isFrozen
  3748    * @alias frozen
  3749    * @param {Object} object
  3750    * @param {String} message _optional_
  3751    * @namespace Assert
  3752    * @api public
  3753    */
  3754 
  3755   assert.isFrozen = function (obj, msg) {
  3756     new Assertion(obj, msg).to.be.frozen;
  3757   };
  3758 
  3759   /**
  3760    * ### .isNotFrozen(object)
  3761    *
  3762    * Asserts that `object` is _not_ frozen.
  3763    *
  3764    *     assert.isNotFrozen({});
  3765    *
  3766    * @name isNotFrozen
  3767    * @alias notFrozen
  3768    * @param {Object} object
  3769    * @param {String} message _optional_
  3770    * @namespace Assert
  3771    * @api public
  3772    */
  3773 
  3774   assert.isNotFrozen = function (obj, msg) {
  3775     new Assertion(obj, msg).to.not.be.frozen;
  3776   };
  3777 
  3778   /*!
  3779    * Aliases.
  3780    */
  3781 
  3782   (function alias(name, as){
  3783     assert[as] = assert[name];
  3784     return alias;
  3785   })
  3786   ('isOk', 'ok')
  3787   ('isNotOk', 'notOk')
  3788   ('throws', 'throw')
  3789   ('throws', 'Throw')
  3790   ('isExtensible', 'extensible')
  3791   ('isNotExtensible', 'notExtensible')
  3792   ('isSealed', 'sealed')
  3793   ('isNotSealed', 'notSealed')
  3794   ('isFrozen', 'frozen')
  3795   ('isNotFrozen', 'notFrozen');
  3796 };
  3797 
  3798 },{}],7:[function(require,module,exports){
  3799 /*!
  3800  * chai
  3801  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
  3802  * MIT Licensed
  3803  */
  3804 
  3805 module.exports = function (chai, util) {
  3806   chai.expect = function (val, message) {
  3807     return new chai.Assertion(val, message);
  3808   };
  3809 
  3810   /**
  3811    * ### .fail(actual, expected, [message], [operator])
  3812    *
  3813    * Throw a failure.
  3814    *
  3815    * @name fail
  3816    * @param {Mixed} actual
  3817    * @param {Mixed} expected
  3818    * @param {String} message
  3819    * @param {String} operator
  3820    * @namespace Expect
  3821    * @api public
  3822    */
  3823 
  3824   chai.expect.fail = function (actual, expected, message, operator) {
  3825     message = message || 'expect.fail()';
  3826     throw new chai.AssertionError(message, {
  3827         actual: actual
  3828       , expected: expected
  3829       , operator: operator
  3830     }, chai.expect.fail);
  3831   };
  3832 };
  3833 
  3834 },{}],8:[function(require,module,exports){
  3835 /*!
  3836  * chai
  3837  * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
  3838  * MIT Licensed
  3839  */
  3840 
  3841 module.exports = function (chai, util) {
  3842   var Assertion = chai.Assertion;
  3843 
  3844   function loadShould () {
  3845     // explicitly define this method as function as to have it's name to include as `ssfi`
  3846     function shouldGetter() {
  3847       if (this instanceof String || this instanceof Number || this instanceof Boolean ) {
  3848         return new Assertion(this.valueOf(), null, shouldGetter);
  3849       }
  3850       return new Assertion(this, null, shouldGetter);
  3851     }
  3852     function shouldSetter(value) {
  3853       // See https://github.com/chaijs/chai/issues/86: this makes
  3854       // `whatever.should = someValue` actually set `someValue`, which is
  3855       // especially useful for `global.should = require('chai').should()`.
  3856       //
  3857       // Note that we have to use [[DefineProperty]] instead of [[Put]]
  3858       // since otherwise we would trigger this very setter!
  3859       Object.defineProperty(this, 'should', {
  3860         value: value,
  3861         enumerable: true,
  3862         configurable: true,
  3863         writable: true
  3864       });
  3865     }
  3866     // modify Object.prototype to have `should`
  3867     Object.defineProperty(Object.prototype, 'should', {
  3868       set: shouldSetter
  3869       , get: shouldGetter
  3870       , configurable: true
  3871     });
  3872 
  3873     var should = {};
  3874 
  3875     /**
  3876      * ### .fail(actual, expected, [message], [operator])
  3877      *
  3878      * Throw a failure.
  3879      *
  3880      * @name fail
  3881      * @param {Mixed} actual
  3882      * @param {Mixed} expected
  3883      * @param {String} message
  3884      * @param {String} operator
  3885      * @namespace Should
  3886      * @api public
  3887      */
  3888 
  3889     should.fail = function (actual, expected, message, operator) {
  3890       message = message || 'should.fail()';
  3891       throw new chai.AssertionError(message, {
  3892           actual: actual
  3893         , expected: expected
  3894         , operator: operator
  3895       }, should.fail);
  3896     };
  3897 
  3898     /**
  3899      * ### .equal(actual, expected, [message])
  3900      *
  3901      * Asserts non-strict equality (`==`) of `actual` and `expected`.
  3902      *
  3903      *     should.equal(3, '3', '== coerces values to strings');
  3904      *
  3905      * @name equal
  3906      * @param {Mixed} actual
  3907      * @param {Mixed} expected
  3908      * @param {String} message
  3909      * @namespace Should
  3910      * @api public
  3911      */
  3912 
  3913     should.equal = function (val1, val2, msg) {
  3914       new Assertion(val1, msg).to.equal(val2);
  3915     };
  3916 
  3917     /**
  3918      * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])
  3919      *
  3920      * Asserts that `function` will throw an error that is an instance of
  3921      * `constructor`, or alternately that it will throw an error with message
  3922      * matching `regexp`.
  3923      *
  3924      *     should.throw(fn, 'function throws a reference error');
  3925      *     should.throw(fn, /function throws a reference error/);
  3926      *     should.throw(fn, ReferenceError);
  3927      *     should.throw(fn, ReferenceError, 'function throws a reference error');
  3928      *     should.throw(fn, ReferenceError, /function throws a reference error/);
  3929      *
  3930      * @name throw
  3931      * @alias Throw
  3932      * @param {Function} function
  3933      * @param {ErrorConstructor} constructor
  3934      * @param {RegExp} regexp
  3935      * @param {String} message
  3936      * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
  3937      * @namespace Should
  3938      * @api public
  3939      */
  3940 
  3941     should.Throw = function (fn, errt, errs, msg) {
  3942       new Assertion(fn, msg).to.Throw(errt, errs);
  3943     };
  3944 
  3945     /**
  3946      * ### .exist
  3947      *
  3948      * Asserts that the target is neither `null` nor `undefined`.
  3949      *
  3950      *     var foo = 'hi';
  3951      *
  3952      *     should.exist(foo, 'foo exists');
  3953      *
  3954      * @name exist
  3955      * @namespace Should
  3956      * @api public
  3957      */
  3958 
  3959     should.exist = function (val, msg) {
  3960       new Assertion(val, msg).to.exist;
  3961     }
  3962 
  3963     // negation
  3964     should.not = {}
  3965 
  3966     /**
  3967      * ### .not.equal(actual, expected, [message])
  3968      *
  3969      * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
  3970      *
  3971      *     should.not.equal(3, 4, 'these numbers are not equal');
  3972      *
  3973      * @name not.equal
  3974      * @param {Mixed} actual
  3975      * @param {Mixed} expected
  3976      * @param {String} message
  3977      * @namespace Should
  3978      * @api public
  3979      */
  3980 
  3981     should.not.equal = function (val1, val2, msg) {
  3982       new Assertion(val1, msg).to.not.equal(val2);
  3983     };
  3984 
  3985     /**
  3986      * ### .throw(function, [constructor/regexp], [message])
  3987      *
  3988      * Asserts that `function` will _not_ throw an error that is an instance of
  3989      * `constructor`, or alternately that it will not throw an error with message
  3990      * matching `regexp`.
  3991      *
  3992      *     should.not.throw(fn, Error, 'function does not throw');
  3993      *
  3994      * @name not.throw
  3995      * @alias not.Throw
  3996      * @param {Function} function
  3997      * @param {ErrorConstructor} constructor
  3998      * @param {RegExp} regexp
  3999      * @param {String} message
  4000      * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
  4001      * @namespace Should
  4002      * @api public
  4003      */
  4004 
  4005     should.not.Throw = function (fn, errt, errs, msg) {
  4006       new Assertion(fn, msg).to.not.Throw(errt, errs);
  4007     };
  4008 
  4009     /**
  4010      * ### .not.exist
  4011      *
  4012      * Asserts that the target is neither `null` nor `undefined`.
  4013      *
  4014      *     var bar = null;
  4015      *
  4016      *     should.not.exist(bar, 'bar does not exist');
  4017      *
  4018      * @name not.exist
  4019      * @namespace Should
  4020      * @api public
  4021      */
  4022 
  4023     should.not.exist = function (val, msg) {
  4024       new Assertion(val, msg).to.not.exist;
  4025     }
  4026 
  4027     should['throw'] = should['Throw'];
  4028     should.not['throw'] = should.not['Throw'];
  4029 
  4030     return should;
  4031   };
  4032 
  4033   chai.should = loadShould;
  4034   chai.Should = loadShould;
  4035 };
  4036 
  4037 },{}],9:[function(require,module,exports){
  4038 /*!
  4039  * Chai - addChainingMethod utility
  4040  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4041  * MIT Licensed
  4042  */
  4043 
  4044 /*!
  4045  * Module dependencies
  4046  */
  4047 
  4048 var transferFlags = require('./transferFlags');
  4049 var flag = require('./flag');
  4050 var config = require('../config');
  4051 
  4052 /*!
  4053  * Module variables
  4054  */
  4055 
  4056 // Check whether `__proto__` is supported
  4057 var hasProtoSupport = '__proto__' in Object;
  4058 
  4059 // Without `__proto__` support, this module will need to add properties to a function.
  4060 // However, some Function.prototype methods cannot be overwritten,
  4061 // and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).
  4062 var excludeNames = /^(?:length|name|arguments|caller)$/;
  4063 
  4064 // Cache `Function` properties
  4065 var call  = Function.prototype.call,
  4066     apply = Function.prototype.apply;
  4067 
  4068 /**
  4069  * ### addChainableMethod (ctx, name, method, chainingBehavior)
  4070  *
  4071  * Adds a method to an object, such that the method can also be chained.
  4072  *
  4073  *     utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {
  4074  *       var obj = utils.flag(this, 'object');
  4075  *       new chai.Assertion(obj).to.be.equal(str);
  4076  *     });
  4077  *
  4078  * Can also be accessed directly from `chai.Assertion`.
  4079  *
  4080  *     chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);
  4081  *
  4082  * The result can then be used as both a method assertion, executing both `method` and
  4083  * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.
  4084  *
  4085  *     expect(fooStr).to.be.foo('bar');
  4086  *     expect(fooStr).to.be.foo.equal('foo');
  4087  *
  4088  * @param {Object} ctx object to which the method is added
  4089  * @param {String} name of method to add
  4090  * @param {Function} method function to be used for `name`, when called
  4091  * @param {Function} chainingBehavior function to be called every time the property is accessed
  4092  * @namespace Utils
  4093  * @name addChainableMethod
  4094  * @api public
  4095  */
  4096 
  4097 module.exports = function (ctx, name, method, chainingBehavior) {
  4098   if (typeof chainingBehavior !== 'function') {
  4099     chainingBehavior = function () { };
  4100   }
  4101 
  4102   var chainableBehavior = {
  4103       method: method
  4104     , chainingBehavior: chainingBehavior
  4105   };
  4106 
  4107   // save the methods so we can overwrite them later, if we need to.
  4108   if (!ctx.__methods) {
  4109     ctx.__methods = {};
  4110   }
  4111   ctx.__methods[name] = chainableBehavior;
  4112 
  4113   Object.defineProperty(ctx, name,
  4114     { get: function () {
  4115         chainableBehavior.chainingBehavior.call(this);
  4116 
  4117         var assert = function assert() {
  4118           var old_ssfi = flag(this, 'ssfi');
  4119           if (old_ssfi && config.includeStack === false)
  4120             flag(this, 'ssfi', assert);
  4121           var result = chainableBehavior.method.apply(this, arguments);
  4122           return result === undefined ? this : result;
  4123         };
  4124 
  4125         // Use `__proto__` if available
  4126         if (hasProtoSupport) {
  4127           // Inherit all properties from the object by replacing the `Function` prototype
  4128           var prototype = assert.__proto__ = Object.create(this);
  4129           // Restore the `call` and `apply` methods from `Function`
  4130           prototype.call = call;
  4131           prototype.apply = apply;
  4132         }
  4133         // Otherwise, redefine all properties (slow!)
  4134         else {
  4135           var asserterNames = Object.getOwnPropertyNames(ctx);
  4136           asserterNames.forEach(function (asserterName) {
  4137             if (!excludeNames.test(asserterName)) {
  4138               var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);
  4139               Object.defineProperty(assert, asserterName, pd);
  4140             }
  4141           });
  4142         }
  4143 
  4144         transferFlags(this, assert);
  4145         return assert;
  4146       }
  4147     , configurable: true
  4148   });
  4149 };
  4150 
  4151 },{"../config":4,"./flag":13,"./transferFlags":29}],10:[function(require,module,exports){
  4152 /*!
  4153  * Chai - addMethod utility
  4154  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4155  * MIT Licensed
  4156  */
  4157 
  4158 var config = require('../config');
  4159 
  4160 /**
  4161  * ### .addMethod (ctx, name, method)
  4162  *
  4163  * Adds a method to the prototype of an object.
  4164  *
  4165  *     utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {
  4166  *       var obj = utils.flag(this, 'object');
  4167  *       new chai.Assertion(obj).to.be.equal(str);
  4168  *     });
  4169  *
  4170  * Can also be accessed directly from `chai.Assertion`.
  4171  *
  4172  *     chai.Assertion.addMethod('foo', fn);
  4173  *
  4174  * Then can be used as any other assertion.
  4175  *
  4176  *     expect(fooStr).to.be.foo('bar');
  4177  *
  4178  * @param {Object} ctx object to which the method is added
  4179  * @param {String} name of method to add
  4180  * @param {Function} method function to be used for name
  4181  * @namespace Utils
  4182  * @name addMethod
  4183  * @api public
  4184  */
  4185 var flag = require('./flag');
  4186 
  4187 module.exports = function (ctx, name, method) {
  4188   ctx[name] = function () {
  4189     var old_ssfi = flag(this, 'ssfi');
  4190     if (old_ssfi && config.includeStack === false)
  4191       flag(this, 'ssfi', ctx[name]);
  4192     var result = method.apply(this, arguments);
  4193     return result === undefined ? this : result;
  4194   };
  4195 };
  4196 
  4197 },{"../config":4,"./flag":13}],11:[function(require,module,exports){
  4198 /*!
  4199  * Chai - addProperty utility
  4200  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4201  * MIT Licensed
  4202  */
  4203 
  4204 var config = require('../config');
  4205 var flag = require('./flag');
  4206 
  4207 /**
  4208  * ### addProperty (ctx, name, getter)
  4209  *
  4210  * Adds a property to the prototype of an object.
  4211  *
  4212  *     utils.addProperty(chai.Assertion.prototype, 'foo', function () {
  4213  *       var obj = utils.flag(this, 'object');
  4214  *       new chai.Assertion(obj).to.be.instanceof(Foo);
  4215  *     });
  4216  *
  4217  * Can also be accessed directly from `chai.Assertion`.
  4218  *
  4219  *     chai.Assertion.addProperty('foo', fn);
  4220  *
  4221  * Then can be used as any other assertion.
  4222  *
  4223  *     expect(myFoo).to.be.foo;
  4224  *
  4225  * @param {Object} ctx object to which the property is added
  4226  * @param {String} name of property to add
  4227  * @param {Function} getter function to be used for name
  4228  * @namespace Utils
  4229  * @name addProperty
  4230  * @api public
  4231  */
  4232 
  4233 module.exports = function (ctx, name, getter) {
  4234   Object.defineProperty(ctx, name,
  4235     { get: function addProperty() {
  4236         var old_ssfi = flag(this, 'ssfi');
  4237         if (old_ssfi && config.includeStack === false)
  4238           flag(this, 'ssfi', addProperty);
  4239 
  4240         var result = getter.call(this);
  4241         return result === undefined ? this : result;
  4242       }
  4243     , configurable: true
  4244   });
  4245 };
  4246 
  4247 },{"../config":4,"./flag":13}],12:[function(require,module,exports){
  4248 /*!
  4249  * Chai - expectTypes utility
  4250  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4251  * MIT Licensed
  4252  */
  4253 
  4254 /**
  4255  * ### expectTypes(obj, types)
  4256  *
  4257  * Ensures that the object being tested against is of a valid type.
  4258  *
  4259  *     utils.expectTypes(this, ['array', 'object', 'string']);
  4260  *
  4261  * @param {Mixed} obj constructed Assertion
  4262  * @param {Array} type A list of allowed types for this assertion
  4263  * @namespace Utils
  4264  * @name expectTypes
  4265  * @api public
  4266  */
  4267 
  4268 var AssertionError = require('assertion-error');
  4269 var flag = require('./flag');
  4270 var type = require('type-detect');
  4271 
  4272 module.exports = function (obj, types) {
  4273   var obj = flag(obj, 'object');
  4274   types = types.map(function (t) { return t.toLowerCase(); });
  4275   types.sort();
  4276 
  4277   // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'
  4278   var str = types.map(function (t, index) {
  4279     var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';
  4280     var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';
  4281     return or + art + ' ' + t;
  4282   }).join(', ');
  4283 
  4284   if (!types.some(function (expected) { return type(obj) === expected; })) {
  4285     throw new AssertionError(
  4286       'object tested must be ' + str + ', but ' + type(obj) + ' given'
  4287     );
  4288   }
  4289 };
  4290 
  4291 },{"./flag":13,"assertion-error":30,"type-detect":35}],13:[function(require,module,exports){
  4292 /*!
  4293  * Chai - flag utility
  4294  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4295  * MIT Licensed
  4296  */
  4297 
  4298 /**
  4299  * ### flag(object, key, [value])
  4300  *
  4301  * Get or set a flag value on an object. If a
  4302  * value is provided it will be set, else it will
  4303  * return the currently set value or `undefined` if
  4304  * the value is not set.
  4305  *
  4306  *     utils.flag(this, 'foo', 'bar'); // setter
  4307  *     utils.flag(this, 'foo'); // getter, returns `bar`
  4308  *
  4309  * @param {Object} object constructed Assertion
  4310  * @param {String} key
  4311  * @param {Mixed} value (optional)
  4312  * @namespace Utils
  4313  * @name flag
  4314  * @api private
  4315  */
  4316 
  4317 module.exports = function (obj, key, value) {
  4318   var flags = obj.__flags || (obj.__flags = Object.create(null));
  4319   if (arguments.length === 3) {
  4320     flags[key] = value;
  4321   } else {
  4322     return flags[key];
  4323   }
  4324 };
  4325 
  4326 },{}],14:[function(require,module,exports){
  4327 /*!
  4328  * Chai - getActual utility
  4329  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4330  * MIT Licensed
  4331  */
  4332 
  4333 /**
  4334  * # getActual(object, [actual])
  4335  *
  4336  * Returns the `actual` value for an Assertion
  4337  *
  4338  * @param {Object} object (constructed Assertion)
  4339  * @param {Arguments} chai.Assertion.prototype.assert arguments
  4340  * @namespace Utils
  4341  * @name getActual
  4342  */
  4343 
  4344 module.exports = function (obj, args) {
  4345   return args.length > 4 ? args[4] : obj._obj;
  4346 };
  4347 
  4348 },{}],15:[function(require,module,exports){
  4349 /*!
  4350  * Chai - getEnumerableProperties utility
  4351  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4352  * MIT Licensed
  4353  */
  4354 
  4355 /**
  4356  * ### .getEnumerableProperties(object)
  4357  *
  4358  * This allows the retrieval of enumerable property names of an object,
  4359  * inherited or not.
  4360  *
  4361  * @param {Object} object
  4362  * @returns {Array}
  4363  * @namespace Utils
  4364  * @name getEnumerableProperties
  4365  * @api public
  4366  */
  4367 
  4368 module.exports = function getEnumerableProperties(object) {
  4369   var result = [];
  4370   for (var name in object) {
  4371     result.push(name);
  4372   }
  4373   return result;
  4374 };
  4375 
  4376 },{}],16:[function(require,module,exports){
  4377 /*!
  4378  * Chai - message composition utility
  4379  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4380  * MIT Licensed
  4381  */
  4382 
  4383 /*!
  4384  * Module dependancies
  4385  */
  4386 
  4387 var flag = require('./flag')
  4388   , getActual = require('./getActual')
  4389   , inspect = require('./inspect')
  4390   , objDisplay = require('./objDisplay');
  4391 
  4392 /**
  4393  * ### .getMessage(object, message, negateMessage)
  4394  *
  4395  * Construct the error message based on flags
  4396  * and template tags. Template tags will return
  4397  * a stringified inspection of the object referenced.
  4398  *
  4399  * Message template tags:
  4400  * - `#{this}` current asserted object
  4401  * - `#{act}` actual value
  4402  * - `#{exp}` expected value
  4403  *
  4404  * @param {Object} object (constructed Assertion)
  4405  * @param {Arguments} chai.Assertion.prototype.assert arguments
  4406  * @namespace Utils
  4407  * @name getMessage
  4408  * @api public
  4409  */
  4410 
  4411 module.exports = function (obj, args) {
  4412   var negate = flag(obj, 'negate')
  4413     , val = flag(obj, 'object')
  4414     , expected = args[3]
  4415     , actual = getActual(obj, args)
  4416     , msg = negate ? args[2] : args[1]
  4417     , flagMsg = flag(obj, 'message');
  4418 
  4419   if(typeof msg === "function") msg = msg();
  4420   msg = msg || '';
  4421   msg = msg
  4422     .replace(/#\{this\}/g, function () { return objDisplay(val); })
  4423     .replace(/#\{act\}/g, function () { return objDisplay(actual); })
  4424     .replace(/#\{exp\}/g, function () { return objDisplay(expected); });
  4425 
  4426   return flagMsg ? flagMsg + ': ' + msg : msg;
  4427 };
  4428 
  4429 },{"./flag":13,"./getActual":14,"./inspect":23,"./objDisplay":24}],17:[function(require,module,exports){
  4430 /*!
  4431  * Chai - getName utility
  4432  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4433  * MIT Licensed
  4434  */
  4435 
  4436 /**
  4437  * # getName(func)
  4438  *
  4439  * Gets the name of a function, in a cross-browser way.
  4440  *
  4441  * @param {Function} a function (usually a constructor)
  4442  * @namespace Utils
  4443  * @name getName
  4444  */
  4445 
  4446 module.exports = function (func) {
  4447   if (func.name) return func.name;
  4448 
  4449   var match = /^\s?function ([^(]*)\(/.exec(func);
  4450   return match && match[1] ? match[1] : "";
  4451 };
  4452 
  4453 },{}],18:[function(require,module,exports){
  4454 /*!
  4455  * Chai - getPathInfo utility
  4456  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4457  * MIT Licensed
  4458  */
  4459 
  4460 var hasProperty = require('./hasProperty');
  4461 
  4462 /**
  4463  * ### .getPathInfo(path, object)
  4464  *
  4465  * This allows the retrieval of property info in an
  4466  * object given a string path.
  4467  *
  4468  * The path info consists of an object with the
  4469  * following properties:
  4470  *
  4471  * * parent - The parent object of the property referenced by `path`
  4472  * * name - The name of the final property, a number if it was an array indexer
  4473  * * value - The value of the property, if it exists, otherwise `undefined`
  4474  * * exists - Whether the property exists or not
  4475  *
  4476  * @param {String} path
  4477  * @param {Object} object
  4478  * @returns {Object} info
  4479  * @namespace Utils
  4480  * @name getPathInfo
  4481  * @api public
  4482  */
  4483 
  4484 module.exports = function getPathInfo(path, obj) {
  4485   var parsed = parsePath(path),
  4486       last = parsed[parsed.length - 1];
  4487 
  4488   var info = {
  4489     parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,
  4490     name: last.p || last.i,
  4491     value: _getPathValue(parsed, obj)
  4492   };
  4493   info.exists = hasProperty(info.name, info.parent);
  4494 
  4495   return info;
  4496 };
  4497 
  4498 
  4499 /*!
  4500  * ## parsePath(path)
  4501  *
  4502  * Helper function used to parse string object
  4503  * paths. Use in conjunction with `_getPathValue`.
  4504  *
  4505  *      var parsed = parsePath('myobject.property.subprop');
  4506  *
  4507  * ### Paths:
  4508  *
  4509  * * Can be as near infinitely deep and nested
  4510  * * Arrays are also valid using the formal `myobject.document[3].property`.
  4511  * * Literal dots and brackets (not delimiter) must be backslash-escaped.
  4512  *
  4513  * @param {String} path
  4514  * @returns {Object} parsed
  4515  * @api private
  4516  */
  4517 
  4518 function parsePath (path) {
  4519   var str = path.replace(/([^\\])\[/g, '$1.[')
  4520     , parts = str.match(/(\\\.|[^.]+?)+/g);
  4521   return parts.map(function (value) {
  4522     var re = /^\[(\d+)\]$/
  4523       , mArr = re.exec(value);
  4524     if (mArr) return { i: parseFloat(mArr[1]) };
  4525     else return { p: value.replace(/\\([.\[\]])/g, '$1') };
  4526   });
  4527 }
  4528 
  4529 
  4530 /*!
  4531  * ## _getPathValue(parsed, obj)
  4532  *
  4533  * Helper companion function for `.parsePath` that returns
  4534  * the value located at the parsed address.
  4535  *
  4536  *      var value = getPathValue(parsed, obj);
  4537  *
  4538  * @param {Object} parsed definition from `parsePath`.
  4539  * @param {Object} object to search against
  4540  * @param {Number} object to search against
  4541  * @returns {Object|Undefined} value
  4542  * @api private
  4543  */
  4544 
  4545 function _getPathValue (parsed, obj, index) {
  4546   var tmp = obj
  4547     , res;
  4548 
  4549   index = (index === undefined ? parsed.length : index);
  4550 
  4551   for (var i = 0, l = index; i < l; i++) {
  4552     var part = parsed[i];
  4553     if (tmp) {
  4554       if ('undefined' !== typeof part.p)
  4555         tmp = tmp[part.p];
  4556       else if ('undefined' !== typeof part.i)
  4557         tmp = tmp[part.i];
  4558       if (i == (l - 1)) res = tmp;
  4559     } else {
  4560       res = undefined;
  4561     }
  4562   }
  4563   return res;
  4564 }
  4565 
  4566 },{"./hasProperty":21}],19:[function(require,module,exports){
  4567 /*!
  4568  * Chai - getPathValue utility
  4569  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4570  * @see https://github.com/logicalparadox/filtr
  4571  * MIT Licensed
  4572  */
  4573 
  4574 var getPathInfo = require('./getPathInfo');
  4575 
  4576 /**
  4577  * ### .getPathValue(path, object)
  4578  *
  4579  * This allows the retrieval of values in an
  4580  * object given a string path.
  4581  *
  4582  *     var obj = {
  4583  *         prop1: {
  4584  *             arr: ['a', 'b', 'c']
  4585  *           , str: 'Hello'
  4586  *         }
  4587  *       , prop2: {
  4588  *             arr: [ { nested: 'Universe' } ]
  4589  *           , str: 'Hello again!'
  4590  *         }
  4591  *     }
  4592  *
  4593  * The following would be the results.
  4594  *
  4595  *     getPathValue('prop1.str', obj); // Hello
  4596  *     getPathValue('prop1.att[2]', obj); // b
  4597  *     getPathValue('prop2.arr[0].nested', obj); // Universe
  4598  *
  4599  * @param {String} path
  4600  * @param {Object} object
  4601  * @returns {Object} value or `undefined`
  4602  * @namespace Utils
  4603  * @name getPathValue
  4604  * @api public
  4605  */
  4606 module.exports = function(path, obj) {
  4607   var info = getPathInfo(path, obj);
  4608   return info.value;
  4609 };
  4610 
  4611 },{"./getPathInfo":18}],20:[function(require,module,exports){
  4612 /*!
  4613  * Chai - getProperties utility
  4614  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4615  * MIT Licensed
  4616  */
  4617 
  4618 /**
  4619  * ### .getProperties(object)
  4620  *
  4621  * This allows the retrieval of property names of an object, enumerable or not,
  4622  * inherited or not.
  4623  *
  4624  * @param {Object} object
  4625  * @returns {Array}
  4626  * @namespace Utils
  4627  * @name getProperties
  4628  * @api public
  4629  */
  4630 
  4631 module.exports = function getProperties(object) {
  4632   var result = Object.getOwnPropertyNames(object);
  4633 
  4634   function addProperty(property) {
  4635     if (result.indexOf(property) === -1) {
  4636       result.push(property);
  4637     }
  4638   }
  4639 
  4640   var proto = Object.getPrototypeOf(object);
  4641   while (proto !== null) {
  4642     Object.getOwnPropertyNames(proto).forEach(addProperty);
  4643     proto = Object.getPrototypeOf(proto);
  4644   }
  4645 
  4646   return result;
  4647 };
  4648 
  4649 },{}],21:[function(require,module,exports){
  4650 /*!
  4651  * Chai - hasProperty utility
  4652  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  4653  * MIT Licensed
  4654  */
  4655 
  4656 var type = require('type-detect');
  4657 
  4658 /**
  4659  * ### .hasProperty(object, name)
  4660  *
  4661  * This allows checking whether an object has
  4662  * named property or numeric array index.
  4663  *
  4664  * Basically does the same thing as the `in`
  4665  * operator but works properly with natives
  4666  * and null/undefined values.
  4667  *
  4668  *     var obj = {
  4669  *         arr: ['a', 'b', 'c']
  4670  *       , str: 'Hello'
  4671  *     }
  4672  *
  4673  * The following would be the results.
  4674  *
  4675  *     hasProperty('str', obj);  // true
  4676  *     hasProperty('constructor', obj);  // true
  4677  *     hasProperty('bar', obj);  // false
  4678  *
  4679  *     hasProperty('length', obj.str); // true
  4680  *     hasProperty(1, obj.str);  // true
  4681  *     hasProperty(5, obj.str);  // false
  4682  *
  4683  *     hasProperty('length', obj.arr);  // true
  4684  *     hasProperty(2, obj.arr);  // true
  4685  *     hasProperty(3, obj.arr);  // false
  4686  *
  4687  * @param {Objuect} object
  4688  * @param {String|Number} name
  4689  * @returns {Boolean} whether it exists
  4690  * @namespace Utils
  4691  * @name getPathInfo
  4692  * @api public
  4693  */
  4694 
  4695 var literals = {
  4696     'number': Number
  4697   , 'string': String
  4698 };
  4699 
  4700 module.exports = function hasProperty(name, obj) {
  4701   var ot = type(obj);
  4702 
  4703   // Bad Object, obviously no props at all
  4704   if(ot === 'null' || ot === 'undefined')
  4705     return false;
  4706 
  4707   // The `in` operator does not work with certain literals
  4708   // box these before the check
  4709   if(literals[ot] && typeof obj !== 'object')
  4710     obj = new literals[ot](obj);
  4711 
  4712   return name in obj;
  4713 };
  4714 
  4715 },{"type-detect":35}],22:[function(require,module,exports){
  4716 /*!
  4717  * chai
  4718  * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
  4719  * MIT Licensed
  4720  */
  4721 
  4722 /*!
  4723  * Main exports
  4724  */
  4725 
  4726 var exports = module.exports = {};
  4727 
  4728 /*!
  4729  * test utility
  4730  */
  4731 
  4732 exports.test = require('./test');
  4733 
  4734 /*!
  4735  * type utility
  4736  */
  4737 
  4738 exports.type = require('type-detect');
  4739 
  4740 /*!
  4741  * expectTypes utility
  4742  */
  4743 exports.expectTypes = require('./expectTypes');
  4744 
  4745 /*!
  4746  * message utility
  4747  */
  4748 
  4749 exports.getMessage = require('./getMessage');
  4750 
  4751 /*!
  4752  * actual utility
  4753  */
  4754 
  4755 exports.getActual = require('./getActual');
  4756 
  4757 /*!
  4758  * Inspect util
  4759  */
  4760 
  4761 exports.inspect = require('./inspect');
  4762 
  4763 /*!
  4764  * Object Display util
  4765  */
  4766 
  4767 exports.objDisplay = require('./objDisplay');
  4768 
  4769 /*!
  4770  * Flag utility
  4771  */
  4772 
  4773 exports.flag = require('./flag');
  4774 
  4775 /*!
  4776  * Flag transferring utility
  4777  */
  4778 
  4779 exports.transferFlags = require('./transferFlags');
  4780 
  4781 /*!
  4782  * Deep equal utility
  4783  */
  4784 
  4785 exports.eql = require('deep-eql');
  4786 
  4787 /*!
  4788  * Deep path value
  4789  */
  4790 
  4791 exports.getPathValue = require('./getPathValue');
  4792 
  4793 /*!
  4794  * Deep path info
  4795  */
  4796 
  4797 exports.getPathInfo = require('./getPathInfo');
  4798 
  4799 /*!
  4800  * Check if a property exists
  4801  */
  4802 
  4803 exports.hasProperty = require('./hasProperty');
  4804 
  4805 /*!
  4806  * Function name
  4807  */
  4808 
  4809 exports.getName = require('./getName');
  4810 
  4811 /*!
  4812  * add Property
  4813  */
  4814 
  4815 exports.addProperty = require('./addProperty');
  4816 
  4817 /*!
  4818  * add Method
  4819  */
  4820 
  4821 exports.addMethod = require('./addMethod');
  4822 
  4823 /*!
  4824  * overwrite Property
  4825  */
  4826 
  4827 exports.overwriteProperty = require('./overwriteProperty');
  4828 
  4829 /*!
  4830  * overwrite Method
  4831  */
  4832 
  4833 exports.overwriteMethod = require('./overwriteMethod');
  4834 
  4835 /*!
  4836  * Add a chainable method
  4837  */
  4838 
  4839 exports.addChainableMethod = require('./addChainableMethod');
  4840 
  4841 /*!
  4842  * Overwrite chainable method
  4843  */
  4844 
  4845 exports.overwriteChainableMethod = require('./overwriteChainableMethod');
  4846 
  4847 },{"./addChainableMethod":9,"./addMethod":10,"./addProperty":11,"./expectTypes":12,"./flag":13,"./getActual":14,"./getMessage":16,"./getName":17,"./getPathInfo":18,"./getPathValue":19,"./hasProperty":21,"./inspect":23,"./objDisplay":24,"./overwriteChainableMethod":25,"./overwriteMethod":26,"./overwriteProperty":27,"./test":28,"./transferFlags":29,"deep-eql":31,"type-detect":35}],23:[function(require,module,exports){
  4848 // This is (almost) directly from Node.js utils
  4849 // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
  4850 
  4851 var getName = require('./getName');
  4852 var getProperties = require('./getProperties');
  4853 var getEnumerableProperties = require('./getEnumerableProperties');
  4854 
  4855 module.exports = inspect;
  4856 
  4857 /**
  4858  * Echos the value of a value. Trys to print the value out
  4859  * in the best way possible given the different types.
  4860  *
  4861  * @param {Object} obj The object to print out.
  4862  * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
  4863  *    properties of objects.
  4864  * @param {Number} depth Depth in which to descend in object. Default is 2.
  4865  * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
  4866  *    output. Default is false (no coloring).
  4867  * @namespace Utils
  4868  * @name inspect
  4869  */
  4870 function inspect(obj, showHidden, depth, colors) {
  4871   var ctx = {
  4872     showHidden: showHidden,
  4873     seen: [],
  4874     stylize: function (str) { return str; }
  4875   };
  4876   return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
  4877 }
  4878 
  4879 // Returns true if object is a DOM element.
  4880 var isDOMElement = function (object) {
  4881   if (typeof HTMLElement === 'object') {
  4882     return object instanceof HTMLElement;
  4883   } else {
  4884     return object &&
  4885       typeof object === 'object' &&
  4886       object.nodeType === 1 &&
  4887       typeof object.nodeName === 'string';
  4888   }
  4889 };
  4890 
  4891 function formatValue(ctx, value, recurseTimes) {
  4892   // Provide a hook for user-specified inspect functions.
  4893   // Check that value is an object with an inspect function on it
  4894   if (value && typeof value.inspect === 'function' &&
  4895       // Filter out the util module, it's inspect function is special
  4896       value.inspect !== exports.inspect &&
  4897       // Also filter out any prototype objects using the circular check.
  4898       !(value.constructor && value.constructor.prototype === value)) {
  4899     var ret = value.inspect(recurseTimes);
  4900     if (typeof ret !== 'string') {
  4901       ret = formatValue(ctx, ret, recurseTimes);
  4902     }
  4903     return ret;
  4904   }
  4905 
  4906   // Primitive types cannot have properties
  4907   var primitive = formatPrimitive(ctx, value);
  4908   if (primitive) {
  4909     return primitive;
  4910   }
  4911 
  4912   // If this is a DOM element, try to get the outer HTML.
  4913   if (isDOMElement(value)) {
  4914     if ('outerHTML' in value) {
  4915       return value.outerHTML;
  4916       // This value does not have an outerHTML attribute,
  4917       //   it could still be an XML element
  4918     } else {
  4919       // Attempt to serialize it
  4920       try {
  4921         if (document.xmlVersion) {
  4922           var xmlSerializer = new XMLSerializer();
  4923           return xmlSerializer.serializeToString(value);
  4924         } else {
  4925           // Firefox 11- do not support outerHTML
  4926           //   It does, however, support innerHTML
  4927           //   Use the following to render the element
  4928           var ns = "http://www.w3.org/1999/xhtml";
  4929           var container = document.createElementNS(ns, '_');
  4930 
  4931           container.appendChild(value.cloneNode(false));
  4932           html = container.innerHTML
  4933             .replace('><', '>' + value.innerHTML + '<');
  4934           container.innerHTML = '';
  4935           return html;
  4936         }
  4937       } catch (err) {
  4938         // This could be a non-native DOM implementation,
  4939         //   continue with the normal flow:
  4940         //   printing the element as if it is an object.
  4941       }
  4942     }
  4943   }
  4944 
  4945   // Look up the keys of the object.
  4946   var visibleKeys = getEnumerableProperties(value);
  4947   var keys = ctx.showHidden ? getProperties(value) : visibleKeys;
  4948 
  4949   // Some type of object without properties can be shortcutted.
  4950   // In IE, errors have a single `stack` property, or if they are vanilla `Error`,
  4951   // a `stack` plus `description` property; ignore those for consistency.
  4952   if (keys.length === 0 || (isError(value) && (
  4953       (keys.length === 1 && keys[0] === 'stack') ||
  4954       (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')
  4955      ))) {
  4956     if (typeof value === 'function') {
  4957       var name = getName(value);
  4958       var nameSuffix = name ? ': ' + name : '';
  4959       return ctx.stylize('[Function' + nameSuffix + ']', 'special');
  4960     }
  4961     if (isRegExp(value)) {
  4962       return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
  4963     }
  4964     if (isDate(value)) {
  4965       return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
  4966     }
  4967     if (isError(value)) {
  4968       return formatError(value);
  4969     }
  4970   }
  4971 
  4972   var base = '', array = false, braces = ['{', '}'];
  4973 
  4974   // Make Array say that they are Array
  4975   if (isArray(value)) {
  4976     array = true;
  4977     braces = ['[', ']'];
  4978   }
  4979 
  4980   // Make functions say that they are functions
  4981   if (typeof value === 'function') {
  4982     var name = getName(value);
  4983     var nameSuffix = name ? ': ' + name : '';
  4984     base = ' [Function' + nameSuffix + ']';
  4985   }
  4986 
  4987   // Make RegExps say that they are RegExps
  4988   if (isRegExp(value)) {
  4989     base = ' ' + RegExp.prototype.toString.call(value);
  4990   }
  4991 
  4992   // Make dates with properties first say the date
  4993   if (isDate(value)) {
  4994     base = ' ' + Date.prototype.toUTCString.call(value);
  4995   }
  4996 
  4997   // Make error with message first say the error
  4998   if (isError(value)) {
  4999     return formatError(value);
  5000   }
  5001 
  5002   if (keys.length === 0 && (!array || value.length == 0)) {
  5003     return braces[0] + base + braces[1];
  5004   }
  5005 
  5006   if (recurseTimes < 0) {
  5007     if (isRegExp(value)) {
  5008       return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
  5009     } else {
  5010       return ctx.stylize('[Object]', 'special');
  5011     }
  5012   }
  5013 
  5014   ctx.seen.push(value);
  5015 
  5016   var output;
  5017   if (array) {
  5018     output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
  5019   } else {
  5020     output = keys.map(function(key) {
  5021       return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
  5022     });
  5023   }
  5024 
  5025   ctx.seen.pop();
  5026 
  5027   return reduceToSingleString(output, base, braces);
  5028 }
  5029 
  5030 
  5031 function formatPrimitive(ctx, value) {
  5032   switch (typeof value) {
  5033     case 'undefined':
  5034       return ctx.stylize('undefined', 'undefined');
  5035 
  5036     case 'string':
  5037       var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
  5038                                                .replace(/'/g, "\\'")
  5039                                                .replace(/\\"/g, '"') + '\'';
  5040       return ctx.stylize(simple, 'string');
  5041 
  5042     case 'number':
  5043       if (value === 0 && (1/value) === -Infinity) {
  5044         return ctx.stylize('-0', 'number');
  5045       }
  5046       return ctx.stylize('' + value, 'number');
  5047 
  5048     case 'boolean':
  5049       return ctx.stylize('' + value, 'boolean');
  5050   }
  5051   // For some reason typeof null is "object", so special case here.
  5052   if (value === null) {
  5053     return ctx.stylize('null', 'null');
  5054   }
  5055 }
  5056 
  5057 
  5058 function formatError(value) {
  5059   return '[' + Error.prototype.toString.call(value) + ']';
  5060 }
  5061 
  5062 
  5063 function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
  5064   var output = [];
  5065   for (var i = 0, l = value.length; i < l; ++i) {
  5066     if (Object.prototype.hasOwnProperty.call(value, String(i))) {
  5067       output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
  5068           String(i), true));
  5069     } else {
  5070       output.push('');
  5071     }
  5072   }
  5073   keys.forEach(function(key) {
  5074     if (!key.match(/^\d+$/)) {
  5075       output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
  5076           key, true));
  5077     }
  5078   });
  5079   return output;
  5080 }
  5081 
  5082 
  5083 function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
  5084   var name, str;
  5085   if (value.__lookupGetter__) {
  5086     if (value.__lookupGetter__(key)) {
  5087       if (value.__lookupSetter__(key)) {
  5088         str = ctx.stylize('[Getter/Setter]', 'special');
  5089       } else {
  5090         str = ctx.stylize('[Getter]', 'special');
  5091       }
  5092     } else {
  5093       if (value.__lookupSetter__(key)) {
  5094         str = ctx.stylize('[Setter]', 'special');
  5095       }
  5096     }
  5097   }
  5098   if (visibleKeys.indexOf(key) < 0) {
  5099     name = '[' + key + ']';
  5100   }
  5101   if (!str) {
  5102     if (ctx.seen.indexOf(value[key]) < 0) {
  5103       if (recurseTimes === null) {
  5104         str = formatValue(ctx, value[key], null);
  5105       } else {
  5106         str = formatValue(ctx, value[key], recurseTimes - 1);
  5107       }
  5108       if (str.indexOf('\n') > -1) {
  5109         if (array) {
  5110           str = str.split('\n').map(function(line) {
  5111             return '  ' + line;
  5112           }).join('\n').substr(2);
  5113         } else {
  5114           str = '\n' + str.split('\n').map(function(line) {
  5115             return '   ' + line;
  5116           }).join('\n');
  5117         }
  5118       }
  5119     } else {
  5120       str = ctx.stylize('[Circular]', 'special');
  5121     }
  5122   }
  5123   if (typeof name === 'undefined') {
  5124     if (array && key.match(/^\d+$/)) {
  5125       return str;
  5126     }
  5127     name = JSON.stringify('' + key);
  5128     if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
  5129       name = name.substr(1, name.length - 2);
  5130       name = ctx.stylize(name, 'name');
  5131     } else {
  5132       name = name.replace(/'/g, "\\'")
  5133                  .replace(/\\"/g, '"')
  5134                  .replace(/(^"|"$)/g, "'");
  5135       name = ctx.stylize(name, 'string');
  5136     }
  5137   }
  5138 
  5139   return name + ': ' + str;
  5140 }
  5141 
  5142 
  5143 function reduceToSingleString(output, base, braces) {
  5144   var numLinesEst = 0;
  5145   var length = output.reduce(function(prev, cur) {
  5146     numLinesEst++;
  5147     if (cur.indexOf('\n') >= 0) numLinesEst++;
  5148     return prev + cur.length + 1;
  5149   }, 0);
  5150 
  5151   if (length > 60) {
  5152     return braces[0] +
  5153            (base === '' ? '' : base + '\n ') +
  5154            ' ' +
  5155            output.join(',\n  ') +
  5156            ' ' +
  5157            braces[1];
  5158   }
  5159 
  5160   return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
  5161 }
  5162 
  5163 function isArray(ar) {
  5164   return Array.isArray(ar) ||
  5165          (typeof ar === 'object' && objectToString(ar) === '[object Array]');
  5166 }
  5167 
  5168 function isRegExp(re) {
  5169   return typeof re === 'object' && objectToString(re) === '[object RegExp]';
  5170 }
  5171 
  5172 function isDate(d) {
  5173   return typeof d === 'object' && objectToString(d) === '[object Date]';
  5174 }
  5175 
  5176 function isError(e) {
  5177   return typeof e === 'object' && objectToString(e) === '[object Error]';
  5178 }
  5179 
  5180 function objectToString(o) {
  5181   return Object.prototype.toString.call(o);
  5182 }
  5183 
  5184 },{"./getEnumerableProperties":15,"./getName":17,"./getProperties":20}],24:[function(require,module,exports){
  5185 /*!
  5186  * Chai - flag utility
  5187  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  5188  * MIT Licensed
  5189  */
  5190 
  5191 /*!
  5192  * Module dependancies
  5193  */
  5194 
  5195 var inspect = require('./inspect');
  5196 var config = require('../config');
  5197 
  5198 /**
  5199  * ### .objDisplay (object)
  5200  *
  5201  * Determines if an object or an array matches
  5202  * criteria to be inspected in-line for error
  5203  * messages or should be truncated.
  5204  *
  5205  * @param {Mixed} javascript object to inspect
  5206  * @name objDisplay
  5207  * @namespace Utils
  5208  * @api public
  5209  */
  5210 
  5211 module.exports = function (obj) {
  5212   var str = inspect(obj)
  5213     , type = Object.prototype.toString.call(obj);
  5214 
  5215   if (config.truncateThreshold && str.length >= config.truncateThreshold) {
  5216     if (type === '[object Function]') {
  5217       return !obj.name || obj.name === ''
  5218         ? '[Function]'
  5219         : '[Function: ' + obj.name + ']';
  5220     } else if (type === '[object Array]') {
  5221       return '[ Array(' + obj.length + ') ]';
  5222     } else if (type === '[object Object]') {
  5223       var keys = Object.keys(obj)
  5224         , kstr = keys.length > 2
  5225           ? keys.splice(0, 2).join(', ') + ', ...'
  5226           : keys.join(', ');
  5227       return '{ Object (' + kstr + ') }';
  5228     } else {
  5229       return str;
  5230     }
  5231   } else {
  5232     return str;
  5233   }
  5234 };
  5235 
  5236 },{"../config":4,"./inspect":23}],25:[function(require,module,exports){
  5237 /*!
  5238  * Chai - overwriteChainableMethod utility
  5239  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  5240  * MIT Licensed
  5241  */
  5242 
  5243 /**
  5244  * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)
  5245  *
  5246  * Overwites an already existing chainable method
  5247  * and provides access to the previous function or
  5248  * property.  Must return functions to be used for
  5249  * name.
  5250  *
  5251  *     utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',
  5252  *       function (_super) {
  5253  *       }
  5254  *     , function (_super) {
  5255  *       }
  5256  *     );
  5257  *
  5258  * Can also be accessed directly from `chai.Assertion`.
  5259  *
  5260  *     chai.Assertion.overwriteChainableMethod('foo', fn, fn);
  5261  *
  5262  * Then can be used as any other assertion.
  5263  *
  5264  *     expect(myFoo).to.have.length(3);
  5265  *     expect(myFoo).to.have.length.above(3);
  5266  *
  5267  * @param {Object} ctx object whose method / property is to be overwritten
  5268  * @param {String} name of method / property to overwrite
  5269  * @param {Function} method function that returns a function to be used for name
  5270  * @param {Function} chainingBehavior function that returns a function to be used for property
  5271  * @namespace Utils
  5272  * @name overwriteChainableMethod
  5273  * @api public
  5274  */
  5275 
  5276 module.exports = function (ctx, name, method, chainingBehavior) {
  5277   var chainableBehavior = ctx.__methods[name];
  5278 
  5279   var _chainingBehavior = chainableBehavior.chainingBehavior;
  5280   chainableBehavior.chainingBehavior = function () {
  5281     var result = chainingBehavior(_chainingBehavior).call(this);
  5282     return result === undefined ? this : result;
  5283   };
  5284 
  5285   var _method = chainableBehavior.method;
  5286   chainableBehavior.method = function () {
  5287     var result = method(_method).apply(this, arguments);
  5288     return result === undefined ? this : result;
  5289   };
  5290 };
  5291 
  5292 },{}],26:[function(require,module,exports){
  5293 /*!
  5294  * Chai - overwriteMethod utility
  5295  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  5296  * MIT Licensed
  5297  */
  5298 
  5299 /**
  5300  * ### overwriteMethod (ctx, name, fn)
  5301  *
  5302  * Overwites an already existing method and provides
  5303  * access to previous function. Must return function
  5304  * to be used for name.
  5305  *
  5306  *     utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {
  5307  *       return function (str) {
  5308  *         var obj = utils.flag(this, 'object');
  5309  *         if (obj instanceof Foo) {
  5310  *           new chai.Assertion(obj.value).to.equal(str);
  5311  *         } else {
  5312  *           _super.apply(this, arguments);
  5313  *         }
  5314  *       }
  5315  *     });
  5316  *
  5317  * Can also be accessed directly from `chai.Assertion`.
  5318  *
  5319  *     chai.Assertion.overwriteMethod('foo', fn);
  5320  *
  5321  * Then can be used as any other assertion.
  5322  *
  5323  *     expect(myFoo).to.equal('bar');
  5324  *
  5325  * @param {Object} ctx object whose method is to be overwritten
  5326  * @param {String} name of method to overwrite
  5327  * @param {Function} method function that returns a function to be used for name
  5328  * @namespace Utils
  5329  * @name overwriteMethod
  5330  * @api public
  5331  */
  5332 
  5333 module.exports = function (ctx, name, method) {
  5334   var _method = ctx[name]
  5335     , _super = function () { return this; };
  5336 
  5337   if (_method && 'function' === typeof _method)
  5338     _super = _method;
  5339 
  5340   ctx[name] = function () {
  5341     var result = method(_super).apply(this, arguments);
  5342     return result === undefined ? this : result;
  5343   }
  5344 };
  5345 
  5346 },{}],27:[function(require,module,exports){
  5347 /*!
  5348  * Chai - overwriteProperty utility
  5349  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  5350  * MIT Licensed
  5351  */
  5352 
  5353 /**
  5354  * ### overwriteProperty (ctx, name, fn)
  5355  *
  5356  * Overwites an already existing property getter and provides
  5357  * access to previous value. Must return function to use as getter.
  5358  *
  5359  *     utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {
  5360  *       return function () {
  5361  *         var obj = utils.flag(this, 'object');
  5362  *         if (obj instanceof Foo) {
  5363  *           new chai.Assertion(obj.name).to.equal('bar');
  5364  *         } else {
  5365  *           _super.call(this);
  5366  *         }
  5367  *       }
  5368  *     });
  5369  *
  5370  *
  5371  * Can also be accessed directly from `chai.Assertion`.
  5372  *
  5373  *     chai.Assertion.overwriteProperty('foo', fn);
  5374  *
  5375  * Then can be used as any other assertion.
  5376  *
  5377  *     expect(myFoo).to.be.ok;
  5378  *
  5379  * @param {Object} ctx object whose property is to be overwritten
  5380  * @param {String} name of property to overwrite
  5381  * @param {Function} getter function that returns a getter function to be used for name
  5382  * @namespace Utils
  5383  * @name overwriteProperty
  5384  * @api public
  5385  */
  5386 
  5387 module.exports = function (ctx, name, getter) {
  5388   var _get = Object.getOwnPropertyDescriptor(ctx, name)
  5389     , _super = function () {};
  5390 
  5391   if (_get && 'function' === typeof _get.get)
  5392     _super = _get.get
  5393 
  5394   Object.defineProperty(ctx, name,
  5395     { get: function () {
  5396         var result = getter(_super).call(this);
  5397         return result === undefined ? this : result;
  5398       }
  5399     , configurable: true
  5400   });
  5401 };
  5402 
  5403 },{}],28:[function(require,module,exports){
  5404 /*!
  5405  * Chai - test utility
  5406  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  5407  * MIT Licensed
  5408  */
  5409 
  5410 /*!
  5411  * Module dependancies
  5412  */
  5413 
  5414 var flag = require('./flag');
  5415 
  5416 /**
  5417  * # test(object, expression)
  5418  *
  5419  * Test and object for expression.
  5420  *
  5421  * @param {Object} object (constructed Assertion)
  5422  * @param {Arguments} chai.Assertion.prototype.assert arguments
  5423  * @namespace Utils
  5424  * @name test
  5425  */
  5426 
  5427 module.exports = function (obj, args) {
  5428   var negate = flag(obj, 'negate')
  5429     , expr = args[0];
  5430   return negate ? !expr : expr;
  5431 };
  5432 
  5433 },{"./flag":13}],29:[function(require,module,exports){
  5434 /*!
  5435  * Chai - transferFlags utility
  5436  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  5437  * MIT Licensed
  5438  */
  5439 
  5440 /**
  5441  * ### transferFlags(assertion, object, includeAll = true)
  5442  *
  5443  * Transfer all the flags for `assertion` to `object`. If
  5444  * `includeAll` is set to `false`, then the base Chai
  5445  * assertion flags (namely `object`, `ssfi`, and `message`)
  5446  * will not be transferred.
  5447  *
  5448  *
  5449  *     var newAssertion = new Assertion();
  5450  *     utils.transferFlags(assertion, newAssertion);
  5451  *
  5452  *     var anotherAsseriton = new Assertion(myObj);
  5453  *     utils.transferFlags(assertion, anotherAssertion, false);
  5454  *
  5455  * @param {Assertion} assertion the assertion to transfer the flags from
  5456  * @param {Object} object the object to transfer the flags to; usually a new assertion
  5457  * @param {Boolean} includeAll
  5458  * @namespace Utils
  5459  * @name transferFlags
  5460  * @api private
  5461  */
  5462 
  5463 module.exports = function (assertion, object, includeAll) {
  5464   var flags = assertion.__flags || (assertion.__flags = Object.create(null));
  5465 
  5466   if (!object.__flags) {
  5467     object.__flags = Object.create(null);
  5468   }
  5469 
  5470   includeAll = arguments.length === 3 ? includeAll : true;
  5471 
  5472   for (var flag in flags) {
  5473     if (includeAll ||
  5474         (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {
  5475       object.__flags[flag] = flags[flag];
  5476     }
  5477   }
  5478 };
  5479 
  5480 },{}],30:[function(require,module,exports){
  5481 /*!
  5482  * assertion-error
  5483  * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>
  5484  * MIT Licensed
  5485  */
  5486 
  5487 /*!
  5488  * Return a function that will copy properties from
  5489  * one object to another excluding any originally
  5490  * listed. Returned function will create a new `{}`.
  5491  *
  5492  * @param {String} excluded properties ...
  5493  * @return {Function}
  5494  */
  5495 
  5496 function exclude () {
  5497   var excludes = [].slice.call(arguments);
  5498 
  5499   function excludeProps (res, obj) {
  5500     Object.keys(obj).forEach(function (key) {
  5501       if (!~excludes.indexOf(key)) res[key] = obj[key];
  5502     });
  5503   }
  5504 
  5505   return function extendExclude () {
  5506     var args = [].slice.call(arguments)
  5507       , i = 0
  5508       , res = {};
  5509 
  5510     for (; i < args.length; i++) {
  5511       excludeProps(res, args[i]);
  5512     }
  5513 
  5514     return res;
  5515   };
  5516 };
  5517 
  5518 /*!
  5519  * Primary Exports
  5520  */
  5521 
  5522 module.exports = AssertionError;
  5523 
  5524 /**
  5525  * ### AssertionError
  5526  *
  5527  * An extension of the JavaScript `Error` constructor for
  5528  * assertion and validation scenarios.
  5529  *
  5530  * @param {String} message
  5531  * @param {Object} properties to include (optional)
  5532  * @param {callee} start stack function (optional)
  5533  */
  5534 
  5535 function AssertionError (message, _props, ssf) {
  5536   var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')
  5537     , props = extend(_props || {});
  5538 
  5539   // default values
  5540   this.message = message || 'Unspecified AssertionError';
  5541   this.showDiff = false;
  5542 
  5543   // copy from properties
  5544   for (var key in props) {
  5545     this[key] = props[key];
  5546   }
  5547 
  5548   // capture stack trace
  5549   ssf = ssf || arguments.callee;
  5550   if (ssf && Error.captureStackTrace) {
  5551     Error.captureStackTrace(this, ssf);
  5552   } else {
  5553     this.stack = new Error().stack;
  5554   }
  5555 }
  5556 
  5557 /*!
  5558  * Inherit from Error.prototype
  5559  */
  5560 
  5561 AssertionError.prototype = Object.create(Error.prototype);
  5562 
  5563 /*!
  5564  * Statically set name
  5565  */
  5566 
  5567 AssertionError.prototype.name = 'AssertionError';
  5568 
  5569 /*!
  5570  * Ensure correct constructor
  5571  */
  5572 
  5573 AssertionError.prototype.constructor = AssertionError;
  5574 
  5575 /**
  5576  * Allow errors to be converted to JSON for static transfer.
  5577  *
  5578  * @param {Boolean} include stack (default: `true`)
  5579  * @return {Object} object that can be `JSON.stringify`
  5580  */
  5581 
  5582 AssertionError.prototype.toJSON = function (stack) {
  5583   var extend = exclude('constructor', 'toJSON', 'stack')
  5584     , props = extend({ name: this.name }, this);
  5585 
  5586   // include stack if exists and not turned off
  5587   if (false !== stack && this.stack) {
  5588     props.stack = this.stack;
  5589   }
  5590 
  5591   return props;
  5592 };
  5593 
  5594 },{}],31:[function(require,module,exports){
  5595 module.exports = require('./lib/eql');
  5596 
  5597 },{"./lib/eql":32}],32:[function(require,module,exports){
  5598 /*!
  5599  * deep-eql
  5600  * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>
  5601  * MIT Licensed
  5602  */
  5603 
  5604 /*!
  5605  * Module dependencies
  5606  */
  5607 
  5608 var type = require('type-detect');
  5609 
  5610 /*!
  5611  * Buffer.isBuffer browser shim
  5612  */
  5613 
  5614 var Buffer;
  5615 try { Buffer = require('buffer').Buffer; }
  5616 catch(ex) {
  5617   Buffer = {};
  5618   Buffer.isBuffer = function() { return false; }
  5619 }
  5620 
  5621 /*!
  5622  * Primary Export
  5623  */
  5624 
  5625 module.exports = deepEqual;
  5626 
  5627 /**
  5628  * Assert super-strict (egal) equality between
  5629  * two objects of any type.
  5630  *
  5631  * @param {Mixed} a
  5632  * @param {Mixed} b
  5633  * @param {Array} memoised (optional)
  5634  * @return {Boolean} equal match
  5635  */
  5636 
  5637 function deepEqual(a, b, m) {
  5638   if (sameValue(a, b)) {
  5639     return true;
  5640   } else if ('date' === type(a)) {
  5641     return dateEqual(a, b);
  5642   } else if ('regexp' === type(a)) {
  5643     return regexpEqual(a, b);
  5644   } else if (Buffer.isBuffer(a)) {
  5645     return bufferEqual(a, b);
  5646   } else if ('arguments' === type(a)) {
  5647     return argumentsEqual(a, b, m);
  5648   } else if (!typeEqual(a, b)) {
  5649     return false;
  5650   } else if (('object' !== type(a) && 'object' !== type(b))
  5651   && ('array' !== type(a) && 'array' !== type(b))) {
  5652     return sameValue(a, b);
  5653   } else {
  5654     return objectEqual(a, b, m);
  5655   }
  5656 }
  5657 
  5658 /*!
  5659  * Strict (egal) equality test. Ensures that NaN always
  5660  * equals NaN and `-0` does not equal `+0`.
  5661  *
  5662  * @param {Mixed} a
  5663  * @param {Mixed} b
  5664  * @return {Boolean} equal match
  5665  */
  5666 
  5667 function sameValue(a, b) {
  5668   if (a === b) return a !== 0 || 1 / a === 1 / b;
  5669   return a !== a && b !== b;
  5670 }
  5671 
  5672 /*!
  5673  * Compare the types of two given objects and
  5674  * return if they are equal. Note that an Array
  5675  * has a type of `array` (not `object`) and arguments
  5676  * have a type of `arguments` (not `array`/`object`).
  5677  *
  5678  * @param {Mixed} a
  5679  * @param {Mixed} b
  5680  * @return {Boolean} result
  5681  */
  5682 
  5683 function typeEqual(a, b) {
  5684   return type(a) === type(b);
  5685 }
  5686 
  5687 /*!
  5688  * Compare two Date objects by asserting that
  5689  * the time values are equal using `saveValue`.
  5690  *
  5691  * @param {Date} a
  5692  * @param {Date} b
  5693  * @return {Boolean} result
  5694  */
  5695 
  5696 function dateEqual(a, b) {
  5697   if ('date' !== type(b)) return false;
  5698   return sameValue(a.getTime(), b.getTime());
  5699 }
  5700 
  5701 /*!
  5702  * Compare two regular expressions by converting them
  5703  * to string and checking for `sameValue`.
  5704  *
  5705  * @param {RegExp} a
  5706  * @param {RegExp} b
  5707  * @return {Boolean} result
  5708  */
  5709 
  5710 function regexpEqual(a, b) {
  5711   if ('regexp' !== type(b)) return false;
  5712   return sameValue(a.toString(), b.toString());
  5713 }
  5714 
  5715 /*!
  5716  * Assert deep equality of two `arguments` objects.
  5717  * Unfortunately, these must be sliced to arrays
  5718  * prior to test to ensure no bad behavior.
  5719  *
  5720  * @param {Arguments} a
  5721  * @param {Arguments} b
  5722  * @param {Array} memoize (optional)
  5723  * @return {Boolean} result
  5724  */
  5725 
  5726 function argumentsEqual(a, b, m) {
  5727   if ('arguments' !== type(b)) return false;
  5728   a = [].slice.call(a);
  5729   b = [].slice.call(b);
  5730   return deepEqual(a, b, m);
  5731 }
  5732 
  5733 /*!
  5734  * Get enumerable properties of a given object.
  5735  *
  5736  * @param {Object} a
  5737  * @return {Array} property names
  5738  */
  5739 
  5740 function enumerable(a) {
  5741   var res = [];
  5742   for (var key in a) res.push(key);
  5743   return res;
  5744 }
  5745 
  5746 /*!
  5747  * Simple equality for flat iterable objects
  5748  * such as Arrays or Node.js buffers.
  5749  *
  5750  * @param {Iterable} a
  5751  * @param {Iterable} b
  5752  * @return {Boolean} result
  5753  */
  5754 
  5755 function iterableEqual(a, b) {
  5756   if (a.length !==  b.length) return false;
  5757 
  5758   var i = 0;
  5759   var match = true;
  5760 
  5761   for (; i < a.length; i++) {
  5762     if (a[i] !== b[i]) {
  5763       match = false;
  5764       break;
  5765     }
  5766   }
  5767 
  5768   return match;
  5769 }
  5770 
  5771 /*!
  5772  * Extension to `iterableEqual` specifically
  5773  * for Node.js Buffers.
  5774  *
  5775  * @param {Buffer} a
  5776  * @param {Mixed} b
  5777  * @return {Boolean} result
  5778  */
  5779 
  5780 function bufferEqual(a, b) {
  5781   if (!Buffer.isBuffer(b)) return false;
  5782   return iterableEqual(a, b);
  5783 }
  5784 
  5785 /*!
  5786  * Block for `objectEqual` ensuring non-existing
  5787  * values don't get in.
  5788  *
  5789  * @param {Mixed} object
  5790  * @return {Boolean} result
  5791  */
  5792 
  5793 function isValue(a) {
  5794   return a !== null && a !== undefined;
  5795 }
  5796 
  5797 /*!
  5798  * Recursively check the equality of two objects.
  5799  * Once basic sameness has been established it will
  5800  * defer to `deepEqual` for each enumerable key
  5801  * in the object.
  5802  *
  5803  * @param {Mixed} a
  5804  * @param {Mixed} b
  5805  * @return {Boolean} result
  5806  */
  5807 
  5808 function objectEqual(a, b, m) {
  5809   if (!isValue(a) || !isValue(b)) {
  5810     return false;
  5811   }
  5812 
  5813   if (a.prototype !== b.prototype) {
  5814     return false;
  5815   }
  5816 
  5817   var i;
  5818   if (m) {
  5819     for (i = 0; i < m.length; i++) {
  5820       if ((m[i][0] === a && m[i][1] === b)
  5821       ||  (m[i][0] === b && m[i][1] === a)) {
  5822         return true;
  5823       }
  5824     }
  5825   } else {
  5826     m = [];
  5827   }
  5828 
  5829   try {
  5830     var ka = enumerable(a);
  5831     var kb = enumerable(b);
  5832   } catch (ex) {
  5833     return false;
  5834   }
  5835 
  5836   ka.sort();
  5837   kb.sort();
  5838 
  5839   if (!iterableEqual(ka, kb)) {
  5840     return false;
  5841   }
  5842 
  5843   m.push([ a, b ]);
  5844 
  5845   var key;
  5846   for (i = ka.length - 1; i >= 0; i--) {
  5847     key = ka[i];
  5848     if (!deepEqual(a[key], b[key], m)) {
  5849       return false;
  5850     }
  5851   }
  5852 
  5853   return true;
  5854 }
  5855 
  5856 },{"buffer":undefined,"type-detect":33}],33:[function(require,module,exports){
  5857 module.exports = require('./lib/type');
  5858 
  5859 },{"./lib/type":34}],34:[function(require,module,exports){
  5860 /*!
  5861  * type-detect
  5862  * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
  5863  * MIT Licensed
  5864  */
  5865 
  5866 /*!
  5867  * Primary Exports
  5868  */
  5869 
  5870 var exports = module.exports = getType;
  5871 
  5872 /*!
  5873  * Detectable javascript natives
  5874  */
  5875 
  5876 var natives = {
  5877     '[object Array]': 'array'
  5878   , '[object RegExp]': 'regexp'
  5879   , '[object Function]': 'function'
  5880   , '[object Arguments]': 'arguments'
  5881   , '[object Date]': 'date'
  5882 };
  5883 
  5884 /**
  5885  * ### typeOf (obj)
  5886  *
  5887  * Use several different techniques to determine
  5888  * the type of object being tested.
  5889  *
  5890  *
  5891  * @param {Mixed} object
  5892  * @return {String} object type
  5893  * @api public
  5894  */
  5895 
  5896 function getType (obj) {
  5897   var str = Object.prototype.toString.call(obj);
  5898   if (natives[str]) return natives[str];
  5899   if (obj === null) return 'null';
  5900   if (obj === undefined) return 'undefined';
  5901   if (obj === Object(obj)) return 'object';
  5902   return typeof obj;
  5903 }
  5904 
  5905 exports.Library = Library;
  5906 
  5907 /**
  5908  * ### Library
  5909  *
  5910  * Create a repository for custom type detection.
  5911  *
  5912  * ```js
  5913  * var lib = new type.Library;
  5914  * ```
  5915  *
  5916  */
  5917 
  5918 function Library () {
  5919   this.tests = {};
  5920 }
  5921 
  5922 /**
  5923  * #### .of (obj)
  5924  *
  5925  * Expose replacement `typeof` detection to the library.
  5926  *
  5927  * ```js
  5928  * if ('string' === lib.of('hello world')) {
  5929  *   // ...
  5930  * }
  5931  * ```
  5932  *
  5933  * @param {Mixed} object to test
  5934  * @return {String} type
  5935  */
  5936 
  5937 Library.prototype.of = getType;
  5938 
  5939 /**
  5940  * #### .define (type, test)
  5941  *
  5942  * Add a test to for the `.test()` assertion.
  5943  *
  5944  * Can be defined as a regular expression:
  5945  *
  5946  * ```js
  5947  * lib.define('int', /^[0-9]+$/);
  5948  * ```
  5949  *
  5950  * ... or as a function:
  5951  *
  5952  * ```js
  5953  * lib.define('bln', function (obj) {
  5954  *   if ('boolean' === lib.of(obj)) return true;
  5955  *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];
  5956  *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();
  5957  *   return !! ~blns.indexOf(obj);
  5958  * });
  5959  * ```
  5960  *
  5961  * @param {String} type
  5962  * @param {RegExp|Function} test
  5963  * @api public
  5964  */
  5965 
  5966 Library.prototype.define = function (type, test) {
  5967   if (arguments.length === 1) return this.tests[type];
  5968   this.tests[type] = test;
  5969   return this;
  5970 };
  5971 
  5972 /**
  5973  * #### .test (obj, test)
  5974  *
  5975  * Assert that an object is of type. Will first
  5976  * check natives, and if that does not pass it will
  5977  * use the user defined custom tests.
  5978  *
  5979  * ```js
  5980  * assert(lib.test('1', 'int'));
  5981  * assert(lib.test('yes', 'bln'));
  5982  * ```
  5983  *
  5984  * @param {Mixed} object
  5985  * @param {String} type
  5986  * @return {Boolean} result
  5987  * @api public
  5988  */
  5989 
  5990 Library.prototype.test = function (obj, type) {
  5991   if (type === getType(obj)) return true;
  5992   var test = this.tests[type];
  5993 
  5994   if (test && 'regexp' === getType(test)) {
  5995     return test.test(obj);
  5996   } else if (test && 'function' === getType(test)) {
  5997     return test(obj);
  5998   } else {
  5999     throw new ReferenceError('Type test "' + type + '" not defined or invalid.');
  6000   }
  6001 };
  6002 
  6003 },{}],35:[function(require,module,exports){
  6004 arguments[4][33][0].apply(exports,arguments)
  6005 },{"./lib/type":36,"dup":33}],36:[function(require,module,exports){
  6006 /*!
  6007  * type-detect
  6008  * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
  6009  * MIT Licensed
  6010  */
  6011 
  6012 /*!
  6013  * Primary Exports
  6014  */
  6015 
  6016 var exports = module.exports = getType;
  6017 
  6018 /**
  6019  * ### typeOf (obj)
  6020  *
  6021  * Use several different techniques to determine
  6022  * the type of object being tested.
  6023  *
  6024  *
  6025  * @param {Mixed} object
  6026  * @return {String} object type
  6027  * @api public
  6028  */
  6029 var objectTypeRegexp = /^\[object (.*)\]$/;
  6030 
  6031 function getType(obj) {
  6032   var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();
  6033   // Let "new String('')" return 'object'
  6034   if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';
  6035   // PhantomJS has type "DOMWindow" for null
  6036   if (obj === null) return 'null';
  6037   // PhantomJS has type "DOMWindow" for undefined
  6038   if (obj === undefined) return 'undefined';
  6039   return type;
  6040 }
  6041 
  6042 exports.Library = Library;
  6043 
  6044 /**
  6045  * ### Library
  6046  *
  6047  * Create a repository for custom type detection.
  6048  *
  6049  * ```js
  6050  * var lib = new type.Library;
  6051  * ```
  6052  *
  6053  */
  6054 
  6055 function Library() {
  6056   if (!(this instanceof Library)) return new Library();
  6057   this.tests = {};
  6058 }
  6059 
  6060 /**
  6061  * #### .of (obj)
  6062  *
  6063  * Expose replacement `typeof` detection to the library.
  6064  *
  6065  * ```js
  6066  * if ('string' === lib.of('hello world')) {
  6067  *   // ...
  6068  * }
  6069  * ```
  6070  *
  6071  * @param {Mixed} object to test
  6072  * @return {String} type
  6073  */
  6074 
  6075 Library.prototype.of = getType;
  6076 
  6077 /**
  6078  * #### .define (type, test)
  6079  *
  6080  * Add a test to for the `.test()` assertion.
  6081  *
  6082  * Can be defined as a regular expression:
  6083  *
  6084  * ```js
  6085  * lib.define('int', /^[0-9]+$/);
  6086  * ```
  6087  *
  6088  * ... or as a function:
  6089  *
  6090  * ```js
  6091  * lib.define('bln', function (obj) {
  6092  *   if ('boolean' === lib.of(obj)) return true;
  6093  *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];
  6094  *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();
  6095  *   return !! ~blns.indexOf(obj);
  6096  * });
  6097  * ```
  6098  *
  6099  * @param {String} type
  6100  * @param {RegExp|Function} test
  6101  * @api public
  6102  */
  6103 
  6104 Library.prototype.define = function(type, test) {
  6105   if (arguments.length === 1) return this.tests[type];
  6106   this.tests[type] = test;
  6107   return this;
  6108 };
  6109 
  6110 /**
  6111  * #### .test (obj, test)
  6112  *
  6113  * Assert that an object is of type. Will first
  6114  * check natives, and if that does not pass it will
  6115  * use the user defined custom tests.
  6116  *
  6117  * ```js
  6118  * assert(lib.test('1', 'int'));
  6119  * assert(lib.test('yes', 'bln'));
  6120  * ```
  6121  *
  6122  * @param {Mixed} object
  6123  * @param {String} type
  6124  * @return {Boolean} result
  6125  * @api public
  6126  */
  6127 
  6128 Library.prototype.test = function(obj, type) {
  6129   if (type === getType(obj)) return true;
  6130   var test = this.tests[type];
  6131 
  6132   if (test && 'regexp' === getType(test)) {
  6133     return test.test(obj);
  6134   } else if (test && 'function' === getType(test)) {
  6135     return test(obj);
  6136   } else {
  6137     throw new ReferenceError('Type test "' + type + '" not defined or invalid.');
  6138   }
  6139 };
  6140 
  6141 },{}]},{},[1])(1)
  6142 ```