git-off

git off handles large files in git repos
git clone https://noulin.net/git/git-off.git
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 });