vendor/assets/javascripts/chai.js in konacha-1.2.4 vs vendor/assets/javascripts/chai.js in konacha-1.3.0

- old
+ new

@@ -48,25 +48,106 @@ return require(path.join('/')); }; }; -require.register("assertion.js", function(module, exports, require){ +require.register("chai.js", function(module, exports, require){ /*! * chai - * http://chaijs.com * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ +var used = [] + , exports = module.exports = {}; /*! + * Chai version + */ + +exports.version = '1.1.0'; + +/*! + * Primary `Assertion` prototype + */ + +exports.Assertion = require('./chai/assertion'); + +/*! + * Assertion Error + */ + +exports.AssertionError = require('./chai/browser/error'); + +/*! + * Utils for plugins (not exported) + */ + +var util = require('./chai/utils'); + +/** + * # .use(function) + * + * Provides a way to extend the internals of Chai + * + * @param {Function} + * @returns {this} for chaining + * @api public + */ + +exports.use = function (fn) { + if (!~used.indexOf(fn)) { + fn(this, util); + used.push(fn); + } + + return this; +}; + +/*! + * Core Assertions + */ + +var core = require('./chai/core/assertions'); +exports.use(core); + +/*! + * Expect interface + */ + +var expect = require('./chai/interface/expect'); +exports.use(expect); + +/*! + * Should interface + */ + +var should = require('./chai/interface/should'); +exports.use(should); + +/*! + * Assert interface + */ + +var assert = require('./chai/interface/assert'); +exports.use(assert); + +}); // module: chai.js + +require.register("chai/assertion.js", function(module, exports, require){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed + */ + +/*! * Module dependencies. */ var AssertionError = require('./browser/error') - , toString = Object.prototype.toString , util = require('./utils') , flag = util.flag; /*! * Module export. @@ -151,11 +232,10 @@ }); } }; /*! - * * ### ._obj * * Quick reference to stored `actual` value for plugin developers. * * @api private @@ -168,1122 +248,1103 @@ , set: function (val) { flag(this, 'object', val); } }); -/** - * ### Language Chains - * - * The following are provide as chainable getters to - * improve the readability of your assertions. They - * do not provide an testing capability unless they - * have been overwritten by a plugin. - * - * **Chains** - * - * - to - * - be - * - been - * - is - * - and - * - have - * - with - * - * @name language chains - * @api public - */ +}); // module: chai/assertion.js -[ 'to', 'be', 'been' -, 'is', 'and', 'have' -, 'with' ].forEach(function (chain) { - Object.defineProperty(Assertion.prototype, chain, - { get: function () { - return this; - } - , configurable: true - }); -}); - -/** - * ### .not - * - * Negates any of assertions following in the chain. - * - * expect(foo).to.not.equal('bar'); - * expect(goodFn).to.not.throw(Error); - * expect({ foo: 'baz' }).to.have.property('foo') - * .and.not.equal('bar'); - * - * @name not - * @api public +require.register("chai/browser/error.js", function(module, exports, require){ +/*! + * chai + * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed */ -Object.defineProperty(Assertion.prototype, 'not', - { get: function () { - flag(this, 'negate', true); - return this; - } - , configurable: true -}); +module.exports = AssertionError; -/** - * ### .deep - * - * Sets the `deep` flag, later used by the `equal` and - * `property` assertions. - * - * expect(foo).to.deep.equal({ bar: 'baz' }); - * expect({ foo: { bar: { baz: 'quux' } } }) - * .to.have.deep.property('foo.bar.baz', 'quux'); - * - * @name deep - * @api public - */ +function AssertionError (options) { + options = options || {}; + this.message = options.message; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; -Object.defineProperty(Assertion.prototype, 'deep', - { get: function () { - flag(this, 'deep', true); - return this; - } - , configurable: true -}); - -/** - * ### .a(type) - * - * The `a` and `an` assertions are aliases that can be - * used either as language chains or to assert a value's - * type (as revealed by `Object.prototype.toString`). - * - * // typeof - * expect('test').to.be.a('string'); - * expect({ foo: 'bar' }).to.be.an('object'); - * expect(null).to.be.a('null'); - * expect(undefined).to.be.an('undefined'); - * - * // language chain - * expect(foo).to.be.an.instanceof(Foo); - * - * @name a - * @alias an - * @param {String} type - * @api public - */ - -function an(type) { - var obj = flag(this, 'object') - , klassStart = type.charAt(0).toUpperCase() - , klass = klassStart + type.slice(1) - , article = ~[ 'A', 'E', 'I', 'O', 'U' ].indexOf(klassStart) ? 'an ' : 'a '; - - this.assert( - '[object ' + klass + ']' === toString.call(obj) - , 'expected #{this} to be ' + article + type - , 'expected #{this} not to be ' + article + type - , '[object ' + klass + ']' - , toString.call(obj) - ); + if (options.stackStartFunction && Error.captureStackTrace) { + var stackStartFunction = options.stackStartFunction; + Error.captureStackTrace(this, stackStartFunction); + } } -Assertion.addChainableMethod('an', an); -Assertion.addChainableMethod('a', an); +AssertionError.prototype = Object.create(Error.prototype); +AssertionError.prototype.name = 'AssertionError'; +AssertionError.prototype.constructor = AssertionError; -/** - * ### .include(value) - * - * The `include` and `contain` assertions can be used as either property - * based language chains or as methods to assert the inclusion of an object - * in an array or a substring in a string. When used as language chains, - * they toggle the `contain` flag for the `keys` assertion. - * - * expect([1,2,3]).to.include(2); - * expect('foobar').to.contain('foo'); - * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo'); - * - * @name include - * @alias contain - * @param {Object|String|Number} obj - * @api public - */ +AssertionError.prototype.toString = function() { + return this.message; +}; -function includeChainingBehavior () { - flag(this, 'contains', true); -} +}); // module: chai/browser/error.js -function include (val) { - var obj = flag(this, 'object') - this.assert( - ~obj.indexOf(val) - , 'expected #{this} to include ' + util.inspect(val) - , 'expected #{this} to not include ' + util.inspect(val)); -} - -Assertion.addChainableMethod('include', include, includeChainingBehavior); -Assertion.addChainableMethod('contain', include, includeChainingBehavior); - -/** - * ### .ok - * - * Asserts that the target is truthy. - * - * expect('everthing').to.be.ok; - * expect(1).to.be.ok; - * expect(false).to.not.be.ok; - * expect(undefined).to.not.be.ok; - * expect(null).to.not.be.ok; - * - * @name ok - * @api public +require.register("chai/core/assertions.js", function(module, exports, require){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> + * MIT Licensed */ -Object.defineProperty(Assertion.prototype, 'ok', - { get: function () { - this.assert( - flag(this, 'object') - , 'expected #{this} to be truthy' - , 'expected #{this} to be falsy'); +module.exports = function (chai, _) { + var Assertion = chai.Assertion + , toString = Object.prototype.toString + , flag = _.flag; + /** + * ### Language Chains + * + * The following are provide as chainable getters to + * improve the readability of your assertions. They + * do not provide an testing capability unless they + * have been overwritten by a plugin. + * + * **Chains** + * + * - to + * - be + * - been + * - is + * - that + * - and + * - have + * - with + * + * @name language chains + * @api public + */ + + [ 'to', 'be', 'been' + , 'is', 'and', 'have' + , 'with', 'that' ].forEach(function (chain) { + Assertion.addProperty(chain, function () { return this; - } - , configurable: true -}); + }); + }); -/** - * ### .true - * - * Asserts that the target is `true`. - * - * expect(true).to.be.true; - * expect(1).to.not.be.true; - * - * @name true - * @api public - */ + /** + * ### .not + * + * Negates any of assertions following in the chain. + * + * expect(foo).to.not.equal('bar'); + * expect(goodFn).to.not.throw(Error); + * expect({ foo: 'baz' }).to.have.property('foo') + * .and.not.equal('bar'); + * + * @name not + * @api public + */ -Object.defineProperty(Assertion.prototype, 'true', - { get: function () { - this.assert( - true === flag(this, 'object') - , 'expected #{this} to be true' - , 'expected #{this} to be false' - , this.negate ? false : true - ); + Assertion.addProperty('not', function () { + flag(this, 'negate', true); + }); - return this; - } - , configurable: true -}); + /** + * ### .deep + * + * Sets the `deep` flag, later used by the `equal` and + * `property` assertions. + * + * expect(foo).to.deep.equal({ bar: 'baz' }); + * expect({ foo: { bar: { baz: 'quux' } } }) + * .to.have.deep.property('foo.bar.baz', 'quux'); + * + * @name deep + * @api public + */ -/** - * ### .false - * - * Asserts that the target is `false`. - * - * expect(false).to.be.false; - * expect(0).to.not.be.false; - * - * @name false - * @api public - */ + Assertion.addProperty('deep', function () { + flag(this, 'deep', true); + }); -Object.defineProperty(Assertion.prototype, 'false', - { get: function () { - this.assert( - false === flag(this, 'object') - , 'expected #{this} to be false' - , 'expected #{this} to be true' - , this.negate ? true : false - ); + /** + * ### .a(type) + * + * The `a` and `an` assertions are aliases that can be + * used either as language chains or to assert a value's + * type (as revealed by `Object.prototype.toString`). + * + * // typeof + * expect('test').to.be.a('string'); + * expect({ foo: 'bar' }).to.be.an('object'); + * expect(null).to.be.a('null'); + * expect(undefined).to.be.an('undefined'); + * + * // language chain + * expect(foo).to.be.an.instanceof(Foo); + * + * @name a + * @alias an + * @param {String} type + * @api public + */ - return this; - } - , configurable: true -}); + function an(type) { + var obj = flag(this, 'object') + , klassStart = type.charAt(0).toUpperCase() + , klass = klassStart + type.slice(1) + , article = ~[ 'A', 'E', 'I', 'O', 'U' ].indexOf(klassStart) ? 'an ' : 'a '; -/** - * ### .null - * - * Asserts that the target is `null`. - * - * expect(null).to.be.null; - * expect(undefined).not.to.be.null; - * - * @name null - * @api public - */ + this.assert( + '[object ' + klass + ']' === toString.call(obj) + , 'expected #{this} to be ' + article + type + , 'expected #{this} not to be ' + article + type + ); + } -Object.defineProperty(Assertion.prototype, 'null', - { get: function () { - this.assert( - null === flag(this, 'object') - , 'expected #{this} to be null' - , 'expected #{this} not to be null' - , this.negate ? false : true - ); + Assertion.addChainableMethod('an', an); + Assertion.addChainableMethod('a', an); - return this; - } - , configurable: true -}); + /** + * ### .include(value) + * + * The `include` and `contain` assertions can be used as either property + * based language chains or as methods to assert the inclusion of an object + * in an array or a substring in a string. When used as language chains, + * they toggle the `contain` flag for the `keys` assertion. + * + * expect([1,2,3]).to.include(2); + * expect('foobar').to.contain('foo'); + * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo'); + * + * @name include + * @alias contain + * @param {Object|String|Number} obj + * @api public + */ -/** - * ### .undefined - * - * Asserts that the target is `undefined`. - * - * expect(undefined).to.be.undefined; - * expect(null).to.not.be.undefined; - * - * @name undefined - * @api public - */ + function includeChainingBehavior () { + flag(this, 'contains', true); + } -Object.defineProperty(Assertion.prototype, 'undefined', - { get: function () { - this.assert( - undefined === flag(this, 'object') - , 'expected #{this} to be undefined' - , 'expected #{this} not to be undefined' - , this.negate ? false : true - ); + function include (val) { + var obj = flag(this, 'object') + this.assert( + ~obj.indexOf(val) + , 'expected #{this} to include ' + _.inspect(val) + , 'expected #{this} to not include ' + _.inspect(val)); + } - return this; - } - , configurable: true -}); + Assertion.addChainableMethod('include', include, includeChainingBehavior); + Assertion.addChainableMethod('contain', include, includeChainingBehavior); -/** - * ### .exist - * - * Asserts that the target is neither `null` nor `undefined`. - * - * var foo = 'hi' - * , bar = null - * , baz; - * - * expect(foo).to.exist; - * expect(bar).to.not.exist; - * expect(baz).to.not.exist; - * - * @name exist - * @api public - */ + /** + * ### .ok + * + * Asserts that the target is truthy. + * + * expect('everthing').to.be.ok; + * expect(1).to.be.ok; + * expect(false).to.not.be.ok; + * expect(undefined).to.not.be.ok; + * expect(null).to.not.be.ok; + * + * @name ok + * @api public + */ -Object.defineProperty(Assertion.prototype, 'exist', - { get: function () { - this.assert( - null != flag(this, 'object') - , 'expected #{this} to exist' - , 'expected #{this} to not exist' - ); + Assertion.addProperty('ok', function () { + this.assert( + flag(this, 'object') + , 'expected #{this} to be truthy' + , 'expected #{this} to be falsy'); + }); - return this; - } - , configurable: true -}); + /** + * ### .true + * + * Asserts that the target is `true`. + * + * expect(true).to.be.true; + * expect(1).to.not.be.true; + * + * @name true + * @api public + */ -/** - * ### .empty - * - * Asserts that the target's length is `0`. For arrays, it checks - * the `length` property. For objects, it gets the count of - * enumerable keys. - * - * expect([]).to.be.empty; - * expect('').to.be.empty; - * expect({}).to.be.empty; - * - * @name empty - * @api public - */ + Assertion.addProperty('true', function () { + this.assert( + true === flag(this, 'object') + , 'expected #{this} to be true' + , 'expected #{this} to be false' + , this.negate ? false : true + ); + }); -Object.defineProperty(Assertion.prototype, 'empty', - { get: function () { - var obj = flag(this, 'object') - , expected = obj; + /** + * ### .false + * + * Asserts that the target is `false`. + * + * expect(false).to.be.false; + * expect(0).to.not.be.false; + * + * @name false + * @api public + */ - if (Array.isArray(obj) || 'string' === typeof object) { - expected = obj.length; - } else if (typeof obj === 'object') { - expected = Object.keys(obj).length; - } + Assertion.addProperty('false', function () { + this.assert( + false === flag(this, 'object') + , 'expected #{this} to be false' + , 'expected #{this} to be true' + , this.negate ? true : false + ); + }); - this.assert( - !expected - , 'expected #{this} to be empty' - , 'expected #{this} not to be empty'); + /** + * ### .null + * + * Asserts that the target is `null`. + * + * expect(null).to.be.null; + * expect(undefined).not.to.be.null; + * + * @name null + * @api public + */ - return this; - } - , configurable: true -}); + Assertion.addProperty('null', function () { + this.assert( + null === flag(this, 'object') + , 'expected #{this} to be null' + , 'expected #{this} not to be null' + ); + }); -/** - * ### .arguments - * - * Asserts that the target is an arguments object. - * - * function test () { - * expect(arguments).to.be.arguments; - * } - * - * @name arguments - * @alias Arguments - * @api public - */ + /** + * ### .undefined + * + * Asserts that the target is `undefined`. + * + * expect(undefined).to.be.undefined; + * expect(null).to.not.be.undefined; + * + * @name undefined + * @api public + */ -function checkArguments () { - var obj = flag(this, 'object') - , type = Object.prototype.toString.call(obj); - this.assert( - '[object Arguments]' === type - , 'expected #{this} to be arguments but got ' + type - , 'expected #{this} to not be arguments' - ); -} + Assertion.addProperty('undefined', function () { + this.assert( + undefined === flag(this, 'object') + , 'expected #{this} to be undefined' + , 'expected #{this} not to be undefined' + ); + }); -Assertion.addProperty('arguments', checkArguments); -Assertion.addProperty('Arguments', checkArguments); + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi' + * , bar = null + * , baz; + * + * expect(foo).to.exist; + * expect(bar).to.not.exist; + * expect(baz).to.not.exist; + * + * @name exist + * @api public + */ -/** - * ### .equal(value) - * - * Asserts that the target is strictly equal (`===`) to `value`. - * Alternately, if the `deep` flag is set, asserts that - * the target is deeply equal to `value`. - * - * expect('hello').to.equal('hello'); - * expect(42).to.equal(42); - * expect(1).to.not.equal(true); - * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' }); - * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' }); - * - * @name equal - * @param {Mixed} value - * @api public - */ - -Assertion.prototype.equal = function (val) { - var obj = flag(this, 'object'); - if (flag(this, 'deep')) { - return this.eql(val); - } else { + Assertion.addProperty('exist', function () { this.assert( - val === obj - , 'expected #{this} to equal #{exp}' - , 'expected #{this} to not equal #{exp}' - , val); - } + null != flag(this, 'object') + , 'expected #{this} to exist' + , 'expected #{this} to not exist' + ); + }); - return this; -}; -/** - * ### .eql(value) - * - * Asserts that the target is deeply equal to `value`. - * - * expect({ foo: 'bar' }).to.eql({ foo: 'bar' }); - * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]); - * - * @name eql - * @param {Mixed} value - * @api public - */ + /** + * ### .empty + * + * Asserts that the target's length is `0`. For arrays, it checks + * the `length` property. For objects, it gets the count of + * enumerable keys. + * + * expect([]).to.be.empty; + * expect('').to.be.empty; + * expect({}).to.be.empty; + * + * @name empty + * @api public + */ -Assertion.prototype.eql = function (obj) { - this.assert( - util.eql(obj, flag(this, 'object')) - , 'expected #{this} to deeply equal #{exp}' - , 'expected #{this} to not deeply equal #{exp}' - , obj ); + Assertion.addProperty('empty', function () { + var obj = flag(this, 'object') + , expected = obj; - return this; -}; + if (Array.isArray(obj) || 'string' === typeof object) { + expected = obj.length; + } else if (typeof obj === 'object') { + expected = Object.keys(obj).length; + } -/** - * ### .above(value) - * - * Asserts that the target is greater than `value`. - * - * expect(10).to.be.above(5); - * - * @name above - * @alias gt - * @param {Number} value - * @api public - */ + this.assert( + !expected + , 'expected #{this} to be empty' + , 'expected #{this} not to be empty' + ); + }); -Assertion.prototype.above = function (val) { - this.assert( - flag(this, 'object') > val - , 'expected #{this} to be above ' + val - , 'expected #{this} to be below ' + val); + /** + * ### .arguments + * + * Asserts that the target is an arguments object. + * + * function test () { + * expect(arguments).to.be.arguments; + * } + * + * @name arguments + * @alias Arguments + * @api public + */ - return this; -}; + function checkArguments () { + var obj = flag(this, 'object') + , type = Object.prototype.toString.call(obj); + this.assert( + '[object Arguments]' === type + , 'expected #{this} to be arguments but got ' + type + , 'expected #{this} to not be arguments' + ); + } -/** - * ### .below(value) - * - * Asserts that the target is less than `value`. - * - * expect(5).to.be.below(10); - * - * @name below - * @alias lt - * @param {Number} value - * @api public - */ + Assertion.addProperty('arguments', checkArguments); + Assertion.addProperty('Arguments', checkArguments); -Assertion.prototype.below = function (val) { - this.assert( - flag(this, 'object') < val - , 'expected #{this} to be below ' + val - , 'expected #{this} to be above ' + val); + /** + * ### .equal(value) + * + * Asserts that the target is strictly equal (`===`) to `value`. + * Alternately, if the `deep` flag is set, asserts that + * the target is deeply equal to `value`. + * + * expect('hello').to.equal('hello'); + * expect(42).to.equal(42); + * expect(1).to.not.equal(true); + * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' }); + * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' }); + * + * @name equal + * @alias eq + * @alias deep.equal + * @param {Mixed} value + * @api public + */ - return this; -}; + function assertEqual (val) { + var obj = flag(this, 'object'); + if (flag(this, 'deep')) { + return this.eql(val); + } else { + this.assert( + val === obj + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{exp}' + , val + ); + } + } -/** - * ### .within(start, finish) - * - * Asserts that the target is within a range. - * - * expect(7).to.be.within(5,10); - * - * @name within - * @param {Number} start lowerbound inclusive - * @param {Number} finish upperbound inclusive - * @api public - */ + Assertion.addMethod('equal', assertEqual); + Assertion.addMethod('eq', assertEqual); -Assertion.prototype.within = function (start, finish) { - var obj = flag(this, 'object') - , range = start + '..' + finish; + /** + * ### .eql(value) + * + * Asserts that the target is deeply equal to `value`. + * + * expect({ foo: 'bar' }).to.eql({ foo: 'bar' }); + * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]); + * + * @name eql + * @param {Mixed} value + * @api public + */ - this.assert( - obj >= start && obj <= finish - , 'expected #{this} to be within ' + range - , 'expected #{this} to not be within ' + range); + Assertion.addMethod('eql', function (obj) { + this.assert( + _.eql(obj, flag(this, 'object')) + , 'expected #{this} to deeply equal #{exp}' + , 'expected #{this} to not deeply equal #{exp}' + , obj + ); + }); - return this; -}; + /** + * ### .above(value) + * + * Asserts that the target is greater than `value`. + * + * expect(10).to.be.above(5); + * + * Can also be used in conjunction with `length` to + * assert a minimum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.above(2); + * expect([ 1, 2, 3 ]).to.have.length.above(2); + * + * @name above + * @alias gt + * @alias greaterThan + * @param {Number} value + * @api public + */ -/** - * ### .instanceof(constructor) - * - * Asserts that the target is an instance of `constructor`. - * - * var Tea = function (name) { this.name = name; } - * , Chai = new Tea('chai'); - * - * expect(Chai).to.be.an.instanceof(Tea); - * expect([ 1, 2, 3 ]).to.be.instanceof(Array); - * - * @name instanceof - * @param {Constructor} constructor - * @alias instanceOf - * @api public - */ + function assertAbove (n) { + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj).to.have.property('length'); + var len = obj.length; + this.assert( + len > n + , 'expected #{this} to have a length above #{exp} but got #{act}' + , 'expected #{this} to not have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj > n + , 'expected #{this} to be above ' + n + , 'expected #{this} to be below ' + n + ); + } + } -Assertion.prototype.instanceOf = function (constructor) { - var name = util.getName(constructor); - this.assert( - flag(this, 'object') instanceof constructor - , 'expected #{this} to be an instance of ' + name - , 'expected #{this} to not be an instance of ' + name); + Assertion.addMethod('above', assertAbove); + Assertion.addMethod('gt', assertAbove); + Assertion.addMethod('greaterThan', assertAbove); - return this; -}; + /** + * ### .below(value) + * + * Asserts that the target is less than `value`. + * + * expect(5).to.be.below(10); + * + * Can also be used in conjunction with `length` to + * assert a maximum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.below(4); + * expect([ 1, 2, 3 ]).to.have.length.below(4); + * + * @name below + * @alias lt + * @alias lessThan + * @param {Number} value + * @api public + */ -/** - * ### .property(name, [value]) - * - * Asserts that the target has a property `name`, optionally asserting that - * the value of that property is strictly equal to `value`. - * If the `deep` flag is set, you can use dot- and bracket-notation for deep - * references into objects and arrays. - * - * // simple referencing - * var obj = { foo: 'bar' }; - * expect(obj).to.have.property('foo'); - * expect(obj).to.have.property('foo', 'bar'); - * expect(obj).to.have.property('foo').to.be.a('string'); - * - * // deep referencing - * var deepObj = { - * green: { tea: 'matcha' } - * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ] - * }; + function assertBelow (n) { + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj).to.have.property('length'); + var len = obj.length; + this.assert( + len < n + , 'expected #{this} to have a length below #{exp} but got #{act}' + , 'expected #{this} to not have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj < n + , 'expected #{this} to be below ' + n + , 'expected #{this} to be above ' + n + ); + } + } - * expect(deepObj).to.have.deep.property('green.tea', 'matcha'); - * expect(deepObj).to.have.deep.property('teas[1]', 'matcha'); - * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha'); - * - * @name property - * @param {String} name - * @param {Mixed} value (optional) - * @returns value of property for chaining - * @api public - */ + Assertion.addMethod('below', assertBelow); + Assertion.addMethod('lt', assertBelow); + Assertion.addMethod('lessThan', assertBelow); -Assertion.prototype.property = function (name, val) { - var obj = flag(this, 'object') - , value = flag(this, 'deep') ? util.getPathValue(name, obj) : obj[name] - , descriptor = flag(this, 'deep') ? 'deep property ' : 'property ' - , negate = flag(this, 'negate'); + /** + * ### .within(start, finish) + * + * Asserts that the target is within a range. + * + * expect(7).to.be.within(5,10); + * + * Can also be used in conjunction with `length` to + * assert a length range. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.within(2,4); + * expect([ 1, 2, 3 ]).to.have.length.within(2,4); + * + * @name within + * @param {Number} start lowerbound inclusive + * @param {Number} finish upperbound inclusive + * @api public + */ - if (negate && undefined !== val) { - if (undefined === value) { - throw new Error(util.inspect(obj) + ' has no ' + descriptor + util.inspect(name)); + Assertion.addMethod('within', function (start, finish) { + var obj = flag(this, 'object') + , range = start + '..' + finish; + if (flag(this, 'doLength')) { + new Assertion(obj).to.have.property('length'); + var len = obj.length; + this.assert( + len >= start && len <= finish + , 'expected #{this} to have a length within ' + range + , 'expected #{this} to not have a length within ' + range + ); + } else { + this.assert( + obj >= start && obj <= finish + , 'expected #{this} to be within ' + range + , 'expected #{this} to not be within ' + range + ); } - } else { - this.assert( - undefined !== value - , 'expected #{this} to have a ' + descriptor + util.inspect(name) - , 'expected #{this} to not have ' + descriptor + util.inspect(name)); - } + }); - if (undefined !== val) { + /** + * ### .instanceof(constructor) + * + * Asserts that the target is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , Chai = new Tea('chai'); + * + * expect(Chai).to.be.an.instanceof(Tea); + * expect([ 1, 2, 3 ]).to.be.instanceof(Array); + * + * @name instanceof + * @param {Constructor} constructor + * @alias instanceOf + * @api public + */ + + function assertInstanceOf (constructor) { + var name = _.getName(constructor); this.assert( - val === value - , 'expected #{this} to have a ' + descriptor + util.inspect(name) + ' of #{exp}, but got #{act}' - , 'expected #{this} to not have a ' + descriptor + util.inspect(name) + ' of #{act}' - , val - , value + flag(this, 'object') instanceof constructor + , 'expected #{this} to be an instance of ' + name + , 'expected #{this} to not be an instance of ' + name ); - } + }; - flag(this, 'object', value); - return this; -}; + Assertion.addMethod('instanceof', assertInstanceOf); + Assertion.addMethod('instanceOf', assertInstanceOf); -/** - * ### .ownProperty(name) - * - * Asserts that the target has an own property `name`. - * - * expect('test').to.have.ownProperty('length'); - * - * @name ownProperty - * @alias haveOwnProperty - * @param {String} name - * @api public - */ + /** + * ### .property(name, [value]) + * + * Asserts that the target has a property `name`, optionally asserting that + * the value of that property is strictly equal to `value`. + * If the `deep` flag is set, you can use dot- and bracket-notation for deep + * references into objects and arrays. + * + * // simple referencing + * var obj = { foo: 'bar' }; + * expect(obj).to.have.property('foo'); + * expect(obj).to.have.property('foo', 'bar'); + * + * // deep referencing + * var deepObj = { + * green: { tea: 'matcha' } + * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ] + * }; -Assertion.prototype.ownProperty = function (name) { - var obj = flag(this, 'object'); - this.assert( - obj.hasOwnProperty(name) - , 'expected #{this} to have own property ' + util.inspect(name) - , 'expected #{this} to not have own property ' + util.inspect(name)); - return this; -}; + * expect(deepObj).to.have.deep.property('green.tea', 'matcha'); + * expect(deepObj).to.have.deep.property('teas[1]', 'matcha'); + * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha'); + * + * You can also use an array as the starting point of a `deep.property` + * assertion, or traverse nested arrays. + * + * var arr = [ + * [ 'chai', 'matcha', 'konacha' ] + * , [ { tea: 'chai' } + * , { tea: 'matcha' } + * , { tea: 'konacha' } ] + * ]; + * + * expect(arr).to.have.deep.property('[0][1]', 'matcha'); + * expect(arr).to.have.deep.property('[1][2].tea', 'konacha'); + * + * Furthermore, `property` changes the subject of the assertion + * to be the value of that property from the original object. This + * permits for further chainable assertions on that property. + * + * expect(obj).to.have.property('foo') + * .that.is.a('string'); + * expect(deepObj).to.have.property('green') + * .that.is.an('object') + * .that.deep.equals({ tea: 'matcha' }); + * expect(deepObj).to.have.property('teas') + * .that.is.an('array') + * .with.deep.property('[2]') + * .that.deep.equals({ tea: 'konacha' }); + * + * @name property + * @alias deep.property + * @param {String} name + * @param {Mixed} value (optional) + * @returns value of property for chaining + * @api public + */ -/** - * ### .length(value) - * - * Asserts that the target's `length` property has the expected value. - * - * expect([1,2,3]).to.have.length(3); - * expect('foobar').to.have.length(6); - * - * @name length - * @alias lengthOf - * @param {Number} length - * @api public - */ + Assertion.addMethod('property', function (name, val) { + var obj = flag(this, 'object') + , value = flag(this, 'deep') ? _.getPathValue(name, obj) : obj[name] + , descriptor = flag(this, 'deep') ? 'deep property ' : 'property ' + , negate = flag(this, 'negate'); -Assertion.prototype.length = function (n) { - var obj = flag(this, 'object'); - new Assertion(obj).to.have.property('length'); - var len = obj.length; + if (negate && undefined !== val) { + if (undefined === value) { + throw new Error(_.inspect(obj) + ' has no ' + descriptor + _.inspect(name)); + } + } else { + this.assert( + undefined !== value + , 'expected #{this} to have a ' + descriptor + _.inspect(name) + , 'expected #{this} to not have ' + descriptor + _.inspect(name)); + } - this.assert( - len == n - , 'expected #{this} to have a length of #{exp} but got #{act}' - , 'expected #{this} to not have a length of #{act}' - , n - , len - ); + if (undefined !== val) { + this.assert( + val === value + , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' + , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}' + , val + , value + ); + } - return this; -}; + flag(this, 'object', value); + }); -/** - * ### .match(regexp) - * - * Asserts that the target matches a regular expression. - * - * expect('foobar').to.match(/^foo/); - * - * @name match - * @param {RegExp} RegularExpression - * @api public - */ -Assertion.prototype.match = function (re) { - var obj = flag(this, 'object'); - this.assert( - re.exec(obj) - , 'expected #{this} to match ' + re - , 'expected #{this} not to match ' + re); + /** + * ### .ownProperty(name) + * + * Asserts that the target has an own property `name`. + * + * expect('test').to.have.ownProperty('length'); + * + * @name ownProperty + * @alias haveOwnProperty + * @param {String} name + * @api public + */ - return this; -}; + function assertOwnProperty (name) { + var obj = flag(this, 'object'); + this.assert( + obj.hasOwnProperty(name) + , 'expected #{this} to have own property ' + _.inspect(name) + , 'expected #{this} to not have own property ' + _.inspect(name) + ); + } + Assertion.addMethod('ownProperty', assertOwnProperty); + Assertion.addMethod('haveOwnProperty', assertOwnProperty); -/** - * ### .string(string) - * - * Asserts that the string target contains another string. - * - * expect('foobar').to.have.string('bar'); - * - * @name string - * @param {String} string - * @api public - */ + /** + * ### .length(value) + * + * Asserts that the target's `length` property has + * the expected value. + * + * expect([ 1, 2, 3]).to.have.length(3); + * expect('foobar').to.have.length(6); + * + * Can also be used as a chain precursor to a value + * comparison for the length property. + * + * expect('foo').to.have.length.above(2); + * expect([ 1, 2, 3 ]).to.have.length.above(2); + * expect('foo').to.have.length.below(4); + * expect([ 1, 2, 3 ]).to.have.length.below(4); + * expect('foo').to.have.length.within(2,4); + * expect([ 1, 2, 3 ]).to.have.length.within(2,4); + * + * @name length + * @alias lengthOf + * @param {Number} length + * @api public + */ -Assertion.prototype.string = function (str) { - var obj = flag(this, 'object'); - new Assertion(obj).is.a('string'); + function assertLengthChain () { + flag(this, 'doLength', true); + } - this.assert( - ~obj.indexOf(str) - , 'expected #{this} to contain ' + util.inspect(str) - , 'expected #{this} to not contain ' + util.inspect(str)); + function assertLength (n) { + var obj = flag(this, 'object'); + new Assertion(obj).to.have.property('length'); + var len = obj.length; - return this; -}; + this.assert( + len == n + , 'expected #{this} to have a length of #{exp} but got #{act}' + , 'expected #{this} to not have a length of #{act}' + , n + , len + ); + } -/** - * ### .keys(key1, [key2], [...]) - * - * Asserts that the target has exactly the given keys, or - * asserts the inclusion of some keys when using the - * `include` or `contain` modifiers. - * - * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']); - * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar'); - * - * @name keys - * @alias key - * @param {String...|Array} keys - * @api public - */ + Assertion.addChainableMethod('length', assertLength, assertLengthChain); + Assertion.addMethod('lengthOf', assertLength, assertLengthChain); -Assertion.prototype.keys = function(keys) { - var obj = flag(this, 'object') - , str - , ok = true; + /** + * ### .match(regexp) + * + * Asserts that the target matches a regular expression. + * + * expect('foobar').to.match(/^foo/); + * + * @name match + * @param {RegExp} RegularExpression + * @api public + */ - keys = keys instanceof Array - ? keys - : Array.prototype.slice.call(arguments); + Assertion.addMethod('match', function (re) { + var obj = flag(this, 'object'); + this.assert( + re.exec(obj) + , 'expected #{this} to match ' + re + , 'expected #{this} not to match ' + re + ); + }); - if (!keys.length) throw new Error('keys required'); + /** + * ### .string(string) + * + * Asserts that the string target contains another string. + * + * expect('foobar').to.have.string('bar'); + * + * @name string + * @param {String} string + * @api public + */ - var actual = Object.keys(obj) - , len = keys.length; + Assertion.addMethod('string', function (str) { + var obj = flag(this, 'object'); + new Assertion(obj).is.a('string'); - // Inclusion - ok = keys.every(function(key){ - return ~actual.indexOf(key); + this.assert( + ~obj.indexOf(str) + , 'expected #{this} to contain ' + _.inspect(str) + , 'expected #{this} to not contain ' + _.inspect(str) + ); }); - // Strict - if (!flag(this, 'negate') && !flag(this, 'contains')) { - ok = ok && keys.length == actual.length; - } - // Key string - if (len > 1) { - keys = keys.map(function(key){ - return util.inspect(key); - }); - var last = keys.pop(); - str = keys.join(', ') + ', and ' + last; - } else { - str = util.inspect(keys[0]); - } + /** + * ### .keys(key1, [key2], [...]) + * + * Asserts that the target has exactly the given keys, or + * asserts the inclusion of some keys when using the + * `include` or `contain` modifiers. + * + * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']); + * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar'); + * + * @name keys + * @alias key + * @param {String...|Array} keys + * @api public + */ - // Form - str = (len > 1 ? 'keys ' : 'key ') + str; + function assertKeys (keys) { + var obj = flag(this, 'object') + , str + , ok = true; - // Have / include - str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; + keys = keys instanceof Array + ? keys + : Array.prototype.slice.call(arguments); - // Assertion - this.assert( - ok - , 'expected #{this} to ' + str - , 'expected #{this} to not ' + str - , keys - , Object.keys(obj) - ); + if (!keys.length) throw new Error('keys required'); - return this; -} + var actual = Object.keys(obj) + , len = keys.length; -/** - * ### .throw(constructor) - * - * Asserts that the function target will throw a specific error, or specific type of error - * (as determined using `instanceof`), optionally with a RegExp or string inclusion test - * for the error's message. - * - * var err = new ReferenceError('This is a bad function.'); - * var fn = function () { throw err; } - * expect(fn).to.throw(ReferenceError); - * expect(fn).to.throw(Error); - * expect(fn).to.throw(/bad function/); - * expect(fn).to.not.throw('good function'); - * expect(fn).to.throw(ReferenceError, /bad function/); - * expect(fn).to.throw(err); - * expect(fn).to.not.throw(new RangeError('Out of range.')); - * - * Please note that when a throw expectation is negated, it will check each - * parameter independently, starting with error constructor type. The appropriate way - * to check for the existence of a type of error but for a message that does not match - * is to use `and`. - * - * expect(fn).to.throw(ReferenceError) - * .and.not.throw(/good function/); - * - * @name throw - * @alias throws - * @alias Throw - * @param {ErrorConstructor} constructor - * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types - * @api public - */ + // Inclusion + ok = keys.every(function(key){ + return ~actual.indexOf(key); + }); -Assertion.prototype.Throw = function (constructor, msg) { - var obj = flag(this, 'object'); - new Assertion(obj).is.a('function'); - - var thrown = false - , desiredError = null - , name = null; - - if (arguments.length === 0) { - msg = null; - constructor = null; - } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) { - msg = constructor; - constructor = null; - } else if (constructor && constructor instanceof Error) { - desiredError = constructor; - constructor = null; - msg = null; - } else if (typeof constructor === 'function') { - name = (new constructor()).name; - } else { - constructor = null; - } - - try { - obj(); - } catch (err) { - // first, check desired error - if (desiredError) { - this.assert( - err === desiredError - , 'expected #{this} to throw ' + util.inspect(desiredError) + ' but ' + util.inspect(err) + ' was thrown' - , 'expected #{this} to not throw ' + util.inspect(desiredError) - ); - return this; + // Strict + if (!flag(this, 'negate') && !flag(this, 'contains')) { + ok = ok && keys.length == actual.length; } - // next, check constructor - if (constructor) { - this.assert( - err instanceof constructor - , 'expected #{this} to throw ' + name + ' but a ' + err.name + ' was thrown' - , 'expected #{this} to not throw ' + name ); - if (!msg) return this; - } - // next, check message - if (err.message && msg && msg instanceof RegExp) { - this.assert( - msg.exec(err.message) - , 'expected #{this} to throw error matching ' + msg + ' but got ' + util.inspect(err.message) - , 'expected #{this} to throw error not matching ' + msg - ); - return this; - } else if (err.message && msg && 'string' === typeof msg) { - this.assert( - ~err.message.indexOf(msg) - , 'expected #{this} to throw error including #{exp} but got #{act}' - , 'expected #{this} to throw error not including #{act}' - , msg - , err.message - ); - return this; + + // Key string + if (len > 1) { + keys = keys.map(function(key){ + return _.inspect(key); + }); + var last = keys.pop(); + str = keys.join(', ') + ', and ' + last; } else { - thrown = true; + str = _.inspect(keys[0]); } - } - var expectedThrown = name ? name : desiredError ? util.inspect(desiredError) : 'an error'; + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; - this.assert( - thrown === true - , 'expected #{this} to throw ' + expectedThrown - , 'expected #{this} to not throw ' + expectedThrown); + // Have / include + str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; - return this; -}; + // Assertion + this.assert( + ok + , 'expected #{this} to ' + str + , 'expected #{this} to not ' + str + ); + } -/** - * ### .respondTo(method) - * - * Asserts that the object or class target will respond to a method. - * - * Klass.prototype.bar = function(){}; - * expect(Klass).to.respondTo('bar'); - * expect(obj).to.respondTo('bar'); - * - * To check if a constructor will respond to a static function, - * set the `itself` flag. - * - * Klass.baz = function(){}; - * expect(Klass).itself.to.respondTo('baz'); - * - * @name respondTo - * @param {String} method - * @api public - */ + Assertion.addMethod('keys', assertKeys); + Assertion.addMethod('key', assertKeys); -Assertion.prototype.respondTo = function (method) { - var obj = flag(this, 'object') - , itself = flag(this, 'itself') - , context = ('function' === typeof obj && !itself) - ? obj.prototype[method] - : obj[method]; + /** + * ### .throw(constructor) + * + * Asserts that the function target will throw a specific error, or specific type of error + * (as determined using `instanceof`), optionally with a RegExp or string inclusion test + * for the error's message. + * + * var err = new ReferenceError('This is a bad function.'); + * var fn = function () { throw err; } + * expect(fn).to.throw(ReferenceError); + * expect(fn).to.throw(Error); + * expect(fn).to.throw(/bad function/); + * expect(fn).to.not.throw('good function'); + * expect(fn).to.throw(ReferenceError, /bad function/); + * expect(fn).to.throw(err); + * expect(fn).to.not.throw(new RangeError('Out of range.')); + * + * Please note that when a throw expectation is negated, it will check each + * parameter independently, starting with error constructor type. The appropriate way + * to check for the existence of a type of error but for a message that does not match + * is to use `and`. + * + * expect(fn).to.throw(ReferenceError) + * .and.not.throw(/good function/); + * + * @name throw + * @alias throws + * @alias Throw + * @param {ErrorConstructor} constructor + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @api public + */ - this.assert( - 'function' === typeof context - , 'expected #{this} to respond to ' + util.inspect(method) - , 'expected #{this} to not respond to ' + util.inspect(method) - , 'function' - , typeof context - ); + function assertThrows (constructor, msg) { + var obj = flag(this, 'object'); + new Assertion(obj).is.a('function'); - return this; -}; + var thrown = false + , desiredError = null + , name = null; -/** - * ### .itself - * - * Sets the `itself` flag, later used by the `respondTo` assertion. - * - * function Foo() {} - * Foo.bar = function() {} - * Foo.prototype.baz = function() {} - * - * expect(Foo).itself.to.respondTo('bar'); - * expect(Foo).itself.not.to.respondTo('baz'); - * - * @name itself - * @api public - */ -Object.defineProperty(Assertion.prototype, 'itself', - { get: function () { - flag(this, 'itself', true); - return this; + if (arguments.length === 0) { + msg = null; + constructor = null; + } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) { + msg = constructor; + constructor = null; + } else if (constructor && constructor instanceof Error) { + desiredError = constructor; + constructor = null; + msg = null; + } else if (typeof constructor === 'function') { + name = (new constructor()).name; + } else { + constructor = null; } - , configurable: true -}); -/** - * ### .satisfy(method) - * - * Asserts that the target passes a given truth test. - * - * expect(1).to.satisfy(function(num) { return num > 0; }); - * - * @name satisfy - * @param {Function} matcher - * @api public - */ + try { + obj(); + } catch (err) { + // first, check desired error + if (desiredError) { + this.assert( + err === desiredError + , 'expected #{this} to throw ' + _.inspect(desiredError) + ' but ' + _.inspect(err) + ' was thrown' + , 'expected #{this} to not throw ' + _.inspect(desiredError) + ); + return this; + } + // next, check constructor + if (constructor) { + this.assert( + err instanceof constructor + , 'expected #{this} to throw ' + name + ' but a ' + err.name + ' was thrown' + , 'expected #{this} to not throw ' + name ); + if (!msg) return this; + } + // next, check message + if (err.message && msg && msg instanceof RegExp) { + this.assert( + msg.exec(err.message) + , 'expected #{this} to throw error matching ' + msg + ' but got ' + _.inspect(err.message) + , 'expected #{this} to throw error not matching ' + msg + ); + return this; + } else if (err.message && msg && 'string' === typeof msg) { + this.assert( + ~err.message.indexOf(msg) + , 'expected #{this} to throw error including #{exp} but got #{act}' + , 'expected #{this} to throw error not including #{act}' + , msg + , err.message + ); + return this; + } else { + thrown = true; + } + } -Assertion.prototype.satisfy = function (matcher) { - var obj = flag(this, 'object'); - this.assert( - matcher(obj) - , 'expected #{this} to satisfy ' + util.inspect(matcher) - , 'expected #{this} to not satisfy' + util.inspect(matcher) - , this.negate ? false : true - , matcher(obj) - ); + var expectedThrown = name ? name : desiredError ? _.inspect(desiredError) : 'an error'; - return this; -}; + this.assert( + thrown === true + , 'expected #{this} to throw ' + expectedThrown + , 'expected #{this} to not throw ' + expectedThrown + ); + }; -/** - * ### .closeTo(expected, delta) - * - * Asserts that the target is equal `expected`, to within a +/- `delta` range. - * - * expect(1.5).to.be.closeTo(1, 0.5); - * - * @name closeTo - * @param {Number} expected - * @param {Number} delta - * @api public - */ + Assertion.addMethod('throw', assertThrows); + Assertion.addMethod('throws', assertThrows); + Assertion.addMethod('Throw', assertThrows); -Assertion.prototype.closeTo = function (expected, delta) { - var obj = flag(this, 'object'); - this.assert( - (obj - delta === expected) || (obj + delta === expected) - , 'expected #{this} to be close to ' + expected + ' +/- ' + delta - , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta); + /** + * ### .respondTo(method) + * + * Asserts that the object or class target will respond to a method. + * + * Klass.prototype.bar = function(){}; + * expect(Klass).to.respondTo('bar'); + * expect(obj).to.respondTo('bar'); + * + * To check if a constructor will respond to a static function, + * set the `itself` flag. + * + * Klass.baz = function(){}; + * expect(Klass).itself.to.respondTo('baz'); + * + * @name respondTo + * @param {String} method + * @api public + */ - return this; -}; + Assertion.addMethod('respondTo', function (method) { + var obj = flag(this, 'object') + , itself = flag(this, 'itself') + , context = ('function' === typeof obj && !itself) + ? obj.prototype[method] + : obj[method]; -/*! - * Aliases. - */ + this.assert( + 'function' === typeof context + , 'expected #{this} to respond to ' + _.inspect(method) + , 'expected #{this} to not respond to ' + _.inspect(method) + ); + }); -(function alias(name, as){ - Assertion.prototype[as] = Assertion.prototype[name]; - return alias; -}) -('equal', 'eq') -('above', 'gt') -('below', 'lt') -('length', 'lengthOf') -('keys', 'key') -('ownProperty', 'haveOwnProperty') -('above', 'greaterThan') -('below', 'lessThan') -('Throw', 'throws') -('Throw', 'throw') -('instanceOf', 'instanceof'); + /** + * ### .itself + * + * Sets the `itself` flag, later used by the `respondTo` assertion. + * + * function Foo() {} + * Foo.bar = function() {} + * Foo.prototype.baz = function() {} + * + * expect(Foo).itself.to.respondTo('bar'); + * expect(Foo).itself.not.to.respondTo('baz'); + * + * @name itself + * @api public + */ -}); // module: assertion.js + Assertion.addProperty('itself', function () { + flag(this, 'itself', true); + }); -require.register("browser/error.js", function(module, exports, require){ -/*! - * chai - * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - */ + /** + * ### .satisfy(method) + * + * Asserts that the target passes a given truth test. + * + * expect(1).to.satisfy(function(num) { return num > 0; }); + * + * @name satisfy + * @param {Function} matcher + * @api public + */ -module.exports = AssertionError; + Assertion.addMethod('satisfy', function (matcher) { + var obj = flag(this, 'object'); + this.assert( + matcher(obj) + , 'expected #{this} to satisfy ' + _.inspect(matcher) + , 'expected #{this} to not satisfy' + _.inspect(matcher) + , this.negate ? false : true + , matcher(obj) + ); + }); -function AssertionError (options) { - options = options || {}; - this.message = options.message; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; + /** + * ### .closeTo(expected, delta) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * expect(1.5).to.be.closeTo(1, 0.5); + * + * @name closeTo + * @param {Number} expected + * @param {Number} delta + * @api public + */ - if (options.stackStartFunction && Error.captureStackTrace) { - var stackStartFunction = options.stackStartFunction; - Error.captureStackTrace(this, stackStartFunction); - } -} + Assertion.addMethod('closeTo', function (expected, delta) { + var obj = flag(this, 'object'); + this.assert( + Math.abs(obj - expected) <= delta + , 'expected #{this} to be close to ' + expected + ' +/- ' + delta + , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta + ); + }); -AssertionError.prototype = Object.create(Error.prototype); -AssertionError.prototype.name = 'AssertionError'; -AssertionError.prototype.constructor = AssertionError; - -AssertionError.prototype.toString = function() { - return this.message; }; -}); // module: browser/error.js +}); // module: chai/core/assertions.js -require.register("chai.js", function(module, exports, require){ +require.register("chai/interface/assert.js", function(module, exports, require){ /*! * chai * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ -var used = [] - , exports = module.exports = {}; -/*! - * Chai version - */ - -exports.version = '1.0.4'; - -/*! - * Primary `Assertion` prototype - */ - -exports.Assertion = require('./assertion'); - -/*! - * Assertion Error - */ - -exports.AssertionError = require('./browser/error'); - -/*! - * Utils for plugins (not exported) - */ - -var util = require('./utils'); - -/** - * # .use(function) - * - * Provides a way to extend the internals of Chai - * - * @param {Function} - * @returns {this} for chaining - * @api public - */ - -exports.use = function (fn) { - if (!~used.indexOf(fn)) { - fn(this, util); - used.push(fn); - } - - return this; -}; - -/*! - * Expect interface - */ - -var expect = require('./interface/expect'); -exports.use(expect); - -/*! - * Should interface - */ - -var should = require('./interface/should'); -exports.use(should); - -/*! - * Assert interface - */ - -var assert = require('./interface/assert'); -exports.use(assert); - -}); // module: chai.js - -require.register("interface/assert.js", function(module, exports, require){ -/*! - * chai - * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> - * MIT Licensed - */ - - module.exports = function (chai, util) { /*! * Chai dependencies. */ @@ -2237,13 +2298,13 @@ }) ('Throw', 'throw') ('Throw', 'throws'); }; -}); // module: interface/assert.js +}); // module: chai/interface/assert.js -require.register("interface/expect.js", function(module, exports, require){ +require.register("chai/interface/expect.js", function(module, exports, require){ /*! * chai * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -2253,13 +2314,13 @@ return new chai.Assertion(val, message); }; }; -}); // module: interface/expect.js +}); // module: chai/interface/expect.js -require.register("interface/should.js", function(module, exports, require){ +require.register("chai/interface/should.js", function(module, exports, require){ /*! * chai * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -2319,13 +2380,13 @@ chai.should = loadShould; chai.Should = loadShould; }; -}); // module: interface/should.js +}); // module: chai/interface/should.js -require.register("utils/addChainableMethod.js", function(module, exports, require){ +require.register("chai/utils/addChainableMethod.js", function(module, exports, require){ /*! * Chai - addChainingMethod utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -2393,13 +2454,13 @@ } , configurable: true }); }; -}); // module: utils/addChainableMethod.js +}); // module: chai/utils/addChainableMethod.js -require.register("utils/addMethod.js", function(module, exports, require){ +require.register("chai/utils/addMethod.js", function(module, exports, require){ /*! * Chai - addMethod utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -2434,13 +2495,13 @@ var result = method.apply(this, arguments); return result === undefined ? this : result; }; }; -}); // module: utils/addMethod.js +}); // module: chai/utils/addMethod.js -require.register("utils/addProperty.js", function(module, exports, require){ +require.register("chai/utils/addProperty.js", function(module, exports, require){ /*! * Chai - addProperty utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -2478,13 +2539,13 @@ } , configurable: true }); }; -}); // module: utils/addProperty.js +}); // module: chai/utils/addProperty.js -require.register("utils/eql.js", function(module, exports, require){ +require.register("chai/utils/eql.js", function(module, exports, require){ // This is directly from Node.js assert // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js module.exports = _deepEqual; @@ -2581,13 +2642,13 @@ key = ka[i]; if (!_deepEqual(a[key], b[key])) return false; } return true; } -}); // module: utils/eql.js +}); // module: chai/utils/eql.js -require.register("utils/flag.js", function(module, exports, require){ +require.register("chai/utils/flag.js", function(module, exports, require){ /*! * Chai - flag utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -2617,13 +2678,13 @@ } else { return flags[key]; } }; -}); // module: utils/flag.js +}); // module: chai/utils/flag.js -require.register("utils/getActual.js", function(module, exports, require){ +require.register("chai/utils/getActual.js", function(module, exports, require){ /*! * Chai - getActual utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -2640,13 +2701,13 @@ module.exports = function (obj, args) { var actual = args[4]; return 'undefined' !== actual ? actual : obj.obj; }; -}); // module: utils/getActual.js +}); // module: chai/utils/getActual.js -require.register("utils/getMessage.js", function(module, exports, require){ +require.register("chai/utils/getMessage.js", function(module, exports, require){ /*! * Chai - message composition utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -2690,13 +2751,13 @@ .replace(/#{exp}/g, inspect(expected)); return flagMsg ? flagMsg + ': ' + msg : msg; }; -}); // module: utils/getMessage.js +}); // module: chai/utils/getMessage.js -require.register("utils/getName.js", function(module, exports, require){ +require.register("chai/utils/getName.js", function(module, exports, require){ /*! * Chai - getName utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -2714,13 +2775,13 @@ var match = /^\s?function ([^(]*)\(/.exec(func); return match && match[1] ? match[1] : ""; }; -}); // module: utils/getName.js +}); // module: chai/utils/getName.js -require.register("utils/getPathValue.js", function(module, exports, require){ +require.register("chai/utils/getPathValue.js", function(module, exports, require){ /*! * Chai - getPathValue utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * @see https://github.com/logicalparadox/filtr * MIT Licensed @@ -2778,17 +2839,17 @@ * @returns {Object} parsed * @api private */ function parsePath (path) { - var parts = path.split('.').filter(Boolean); + var str = path.replace(/\[/g, '.[') + , parts = str.match(/(\\\.|[^.]+?)+/g); return parts.map(function (value) { - var re = /([A-Za-z0-9]+)\[(\d+)\]$/ + var re = /\[(\d+)\]$/ , mArr = re.exec(value) - , val; - if (mArr) val = { p: mArr[1], i: parseFloat(mArr[2]) }; - return val || value; + if (mArr) return { i: parseFloat(mArr[1]) }; + else return { p: value }; }); }; /*! * ## _getPathValue(parsed, obj) @@ -2808,26 +2869,25 @@ var tmp = obj , res; for (var i = 0, l = parsed.length; i < l; i++) { var part = parsed[i]; if (tmp) { - if ('object' === typeof part && tmp[part.p]) { - tmp = tmp[part.p][part.i]; - } else { - tmp = tmp[part]; - } + if ('undefined' !== typeof part.p) + tmp = tmp[part.p]; + else if ('undefined' !== typeof part.i) + tmp = tmp[part.i]; if (i == (l - 1)) res = tmp; } else { res = undefined; } } return res; }; -}); // module: utils/getPathValue.js +}); // module: chai/utils/getPathValue.js -require.register("utils/index.js", function(module, exports, require){ +require.register("chai/utils/index.js", function(module, exports, require){ /*! * chai * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -2921,13 +2981,13 @@ */ exports.addChainableMethod = require('./addChainableMethod'); -}); // module: utils/index.js +}); // module: chai/utils/index.js -require.register("utils/inspect.js", function(module, exports, require){ +require.register("chai/utils/inspect.js", function(module, exports, require){ // This is (almost) directly from Node.js utils // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js var getName = require('./getName'); @@ -3005,12 +3065,13 @@ braces = ['[', ']']; } // Make functions say that they are functions if (typeof value === 'function') { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; + var name = getName(value); + var nameSuffix = name ? ': ' + name : ''; + base = ' [Function' + nameSuffix + ']'; } // Make RegExps say that they are RegExps if (isRegExp(value)) { base = ' ' + RegExp.prototype.toString.call(value); @@ -3203,13 +3264,13 @@ function objectToString(o) { return Object.prototype.toString.call(o); } -}); // module: utils/inspect.js +}); // module: chai/utils/inspect.js -require.register("utils/overwriteMethod.js", function(module, exports, require){ +require.register("chai/utils/overwriteMethod.js", function(module, exports, require){ /*! * Chai - overwriteMethod utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -3258,13 +3319,13 @@ var result = method(_super).apply(this, arguments); return result === undefined ? this : result; } }; -}); // module: utils/overwriteMethod.js +}); // module: chai/utils/overwriteMethod.js -require.register("utils/overwriteProperty.js", function(module, exports, require){ +require.register("chai/utils/overwriteProperty.js", function(module, exports, require){ /*! * Chai - overwriteProperty utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -3316,13 +3377,13 @@ } , configurable: true }); }; -}); // module: utils/overwriteProperty.js +}); // module: chai/utils/overwriteProperty.js -require.register("utils/test.js", function(module, exports, require){ +require.register("chai/utils/test.js", function(module, exports, require){ /*! * Chai - test utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -3346,13 +3407,13 @@ var negate = flag(obj, 'negate') , expr = args[0]; return negate ? !expr : expr; }; -}); // module: utils/test.js +}); // module: chai/utils/test.js -require.register("utils/transferFlags.js", function(module, exports, require){ +require.register("chai/utils/transferFlags.js", function(module, exports, require){ /*! * Chai - transferFlags utility * Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ @@ -3394,10 +3455,10 @@ object.__flags[flag] = flags[flag]; } } }; -}); // module: utils/transferFlags.js +}); // module: chai/utils/transferFlags.js return require('chai'); }); \ No newline at end of file