UNPKG

underscore.inflections

Version:

Port of ActiveSupport::Inflector::Inflections for underscore.js

2,126 lines (1,861 loc) 83.4 kB
!function (name, definition) { if (typeof define == 'function' && typeof define.amd == 'object') define(definition); else this[name] = definition(); }('chai', function () { // CommonJS require() function require(p){ var path = require.resolve(p) , mod = require.modules[path]; if (!mod) throw new Error('failed to require "' + p + '"'); if (!mod.exports) { mod.exports = {}; mod.call(mod.exports, mod, mod.exports, require.relative(path)); } return mod.exports; } require.modules = {}; require.resolve = function (path){ var orig = path , reg = path + '.js' , index = path + '/index.js'; return require.modules[reg] && reg || require.modules[index] && index || orig; }; require.register = function (path, fn){ require.modules[path] = fn; }; require.relative = function (parent) { return function(p){ if ('.' != p[0]) return require(p); var path = parent.split('/') , segs = p.split('/'); path.pop(); for (var i = 0; i < segs.length; i++) { var seg = segs[i]; if ('..' == seg) path.pop(); else if ('.' != seg) path.push(seg); } return require(path.join('/')); }; }; require.register("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. */ module.exports = Assertion; /*! * Assertion Constructor * * Creates object for chaining. * * @api private */ function Assertion (obj, msg, stack) { flag(this, 'ssfi', stack || arguments.callee); flag(this, 'object', obj); flag(this, 'message', msg); } /*! * ### Assertion.includeStack * * User configurable property, influences whether stack trace * is included in Assertion error message. Default of false * suppresses stack trace in the error message * * Assertion.includeStack = true; // enable stack on error * * @api public */ Assertion.includeStack = false; Assertion.addProperty = function (name, fn) { util.addProperty(this.prototype, name, fn); }; Assertion.addMethod = function (name, fn) { util.addMethod(this.prototype, name, fn); }; Assertion.addChainableMethod = function (name, fn, chainingBehavior) { util.addChainableMethod(this.prototype, name, fn, chainingBehavior); }; Assertion.overwriteProperty = function (name, fn) { util.overwriteProperty(this.prototype, name, fn); }; Assertion.overwriteMethod = function (name, fn) { util.overwriteMethod(this.prototype, name, fn); }; /*! * ### .assert(expression, message, negateMessage, expected, actual) * * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. * * @name assert * @param {Philosophical} expression to be tested * @param {String} message to display if fails * @param {String} negatedMessage to display if negated expression fails * @param {Mixed} expected value (remember to check for negation) * @param {Mixed} actual (optional) will default to `this.obj` * @api private */ Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual) { var msg = util.getMessage(this, arguments) , actual = util.getActual(this, arguments) , ok = util.test(this, arguments); if (!ok) { throw new AssertionError({ message: msg , actual: actual , expected: expected , stackStartFunction: (Assertion.includeStack) ? this.assert : flag(this, 'ssfi') }); } }; /*! * * ### ._obj * * Quick reference to stored `actual` value for plugin developers. * * @api private */ Object.defineProperty(Assertion.prototype, '_obj', { get: function () { return flag(this, 'object'); } , 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 */ [ '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 */ Object.defineProperty(Assertion.prototype, 'not', { get: 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 */ 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) ); } Assertion.addChainableMethod('an', an); Assertion.addChainableMethod('a', an); /** * ### .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 */ function includeChainingBehavior () { flag(this, 'contains', true); } 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 */ Object.defineProperty(Assertion.prototype, 'ok', { get: 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 */ 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 ); return this; } , configurable: true }); /** * ### .false * * Asserts that the target is `false`. * * expect(false).to.be.false; * expect(0).to.not.be.false; * * @name false * @api public */ 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 ); return this; } , configurable: true }); /** * ### .null * * Asserts that the target is `null`. * * expect(null).to.be.null; * expect(undefined).not.to.be.null; * * @name null * @api public */ 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 ); return this; } , configurable: true }); /** * ### .undefined * * Asserts that the target is `undefined`. * * expect(undefined).to.be.undefined; * expect(null).to.not.be.undefined; * * @name undefined * @api public */ 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 ); return this; } , configurable: true }); /** * ### .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 */ Object.defineProperty(Assertion.prototype, 'exist', { get: function () { this.assert( null != flag(this, 'object') , 'expected #{this} to exist' , 'expected #{this} to not exist' ); return this; } , configurable: true }); /** * ### .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 */ Object.defineProperty(Assertion.prototype, 'empty', { get: function () { var obj = flag(this, 'object') , expected = obj; if (Array.isArray(obj) || 'string' === typeof object) { expected = obj.length; } else if (typeof obj === 'object') { expected = Object.keys(obj).length; } this.assert( !expected , 'expected #{this} to be empty' , 'expected #{this} not to be empty'); return this; } , configurable: true }); /** * ### .arguments * * Asserts that the target is an arguments object. * * function test () { * expect(arguments).to.be.arguments; * } * * @name arguments * @alias Arguments * @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('arguments', checkArguments); Assertion.addProperty('Arguments', checkArguments); /** * ### .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 { this.assert( val === obj , 'expected #{this} to equal #{exp}' , 'expected #{this} to not equal #{exp}' , val); } 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 */ 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 ); return this; }; /** * ### .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 */ Assertion.prototype.above = function (val) { this.assert( flag(this, 'object') > val , 'expected #{this} to be above ' + val , 'expected #{this} to be below ' + val); return this; }; /** * ### .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.prototype.below = function (val) { this.assert( flag(this, 'object') < val , 'expected #{this} to be below ' + val , 'expected #{this} to be above ' + val); return this; }; /** * ### .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.prototype.within = function (start, finish) { var obj = flag(this, 'object') , range = start + '..' + finish; this.assert( obj >= start && obj <= finish , 'expected #{this} to be within ' + range , 'expected #{this} to not be within ' + range); return this; }; /** * ### .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 */ 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); return this; }; /** * ### .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' } ] * }; * 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.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'); if (negate && undefined !== val) { if (undefined === value) { throw new Error(util.inspect(obj) + ' has no ' + descriptor + util.inspect(name)); } } 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) { 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', value); return this; }; /** * ### .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 */ 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; }; /** * ### .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.prototype.length = function (n) { var obj = flag(this, 'object'); new Assertion(obj).to.have.property('length'); var len = obj.length; 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 ); return this; }; /** * ### .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); return this; }; /** * ### .string(string) * * Asserts that the string target contains another string. * * expect('foobar').to.have.string('bar'); * * @name string * @param {String} string * @api public */ Assertion.prototype.string = function (str) { var obj = flag(this, 'object'); new Assertion(obj).is.a('string'); this.assert( ~obj.indexOf(str) , 'expected #{this} to contain ' + util.inspect(str) , 'expected #{this} to not contain ' + util.inspect(str)); return this; }; /** * ### .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.prototype.keys = function(keys) { var obj = flag(this, 'object') , str , ok = true; keys = keys instanceof Array ? keys : Array.prototype.slice.call(arguments); if (!keys.length) throw new Error('keys required'); var actual = Object.keys(obj) , len = keys.length; // Inclusion ok = keys.every(function(key){ return ~actual.indexOf(key); }); // 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]); } // Form str = (len > 1 ? 'keys ' : 'key ') + str; // Have / include str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; // Assertion this.assert( ok , 'expected #{this} to ' + str , 'expected #{this} to not ' + str , keys , Object.keys(obj) ); return this; } /** * ### .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 */ 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; } // 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; } else { thrown = true; } } var expectedThrown = name ? name : desiredError ? util.inspect(desiredError) : 'an error'; this.assert( thrown === true , 'expected #{this} to throw ' + expectedThrown , 'expected #{this} to not throw ' + expectedThrown); return this; }; /** * ### .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.prototype.respondTo = function (method) { var obj = flag(this, 'object') , itself = flag(this, 'itself') , context = ('function' === typeof obj && !itself) ? obj.prototype[method] : obj[method]; 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 ); return this; }; /** * ### .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; } , 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 */ 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) ); return this; }; /** * ### .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.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); return this; }; /*! * Aliases. */ (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'); }); // module: assertion.js require.register("browser/error.js", function(module, exports, require){ /*! * chai * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ module.exports = AssertionError; function AssertionError (options) { options = options || {}; this.message = options.message; this.actual = options.actual; this.expected = options.expected; this.operator = options.operator; if (options.stackStartFunction && Error.captureStackTrace) { var stackStartFunction = options.stackStartFunction; Error.captureStackTrace(this, stackStartFunction); } } 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 require.register("chai.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. */ var Assertion = chai.Assertion , flag = util.flag; /*! * Module export. */ /** * ### assert(expression, message) * * Write your own test expressions. * * assert('foo' !== 'bar', 'foo is not bar'); * assert(Array.isArray([]), 'empty arrays are arrays'); * * @param {Mixed} expression to test for truthiness * @param {String} message to display on error * @name assert * @api public */ var assert = chai.assert = function (express, errmsg) { var test = new Assertion(null); test.assert( express , errmsg , '[ negation message unavailable ]' ); }; /** * ### .fail(actual, expected, [message], [operator]) * * Throw a failure. Node.js `assert` module-compatible. * * @name fail * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @param {String} operator * @api public */ assert.fail = function (actual, expected, message, operator) { throw new chai.AssertionError({ actual: actual , expected: expected , message: message , operator: operator , stackStartFunction: assert.fail }); }; /** * ### .ok(object, [message]) * * Asserts that `object` is truthy. * * assert.ok('everything', 'everything is ok'); * assert.ok(false, 'this will fail'); * * @name ok * @param {Mixed} object to test * @param {String} message * @api public */ assert.ok = function (val, msg) { new Assertion(val, msg).is.ok; }; /** * ### .equal(actual, expected, [message]) * * Asserts non-strict equality (`==`) of `actual` and `expected`. * * assert.equal(3, '3', '== coerces values to strings'); * * @name equal * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @api public */ assert.equal = function (act, exp, msg) { var test = new Assertion(act, msg); test.assert( exp == flag(test, 'object') , 'expected #{this} to equal #{exp}' , 'expected #{this} to not equal #{act}' , exp , act ); }; /** * ### .notEqual(actual, expected, [message]) * * Asserts non-strict inequality (`!=`) of `actual` and `expected`. * * assert.notEqual(3, 4, 'these numbers are not equal'); * * @name notEqual * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @api public */ assert.notEqual = function (act, exp, msg) { var test = new Assertion(act, msg); test.assert( exp != flag(test, 'object') , 'expected #{this} to not equal #{exp}' , 'expected #{this} to equal #{act}' , exp , act ); }; /** * ### .strictEqual(actual, expected, [message]) * * Asserts strict equality (`===`) of `actual` and `expected`. * * assert.strictEqual(true, true, 'these booleans are strictly equal'); * * @name strictEqual * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @api public */ assert.strictEqual = function (act, exp, msg) { new Assertion(act, msg).to.equal(exp); }; /** * ### .notStrictEqual(actual, expected, [message]) * * Asserts strict inequality (`!==`) of `actual` and `expected`. * * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); * * @name notStrictEqual * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @api public */ assert.notStrictEqual = function (act, exp, msg) { new Assertion(act, msg).to.not.equal(exp); }; /** * ### .deepEqual(actual, expected, [message]) * * Asserts that `actual` is deeply equal to `expected`. * * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); * * @name deepEqual * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @api public */ assert.deepEqual = function (act, exp, msg) { new Assertion(act, msg).to.eql(exp); }; /** * ### .notDeepEqual(actual, expected, [message]) * * Assert that `actual` is not deeply equal to `expected`. * * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); * * @name notDeepEqual * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @api public */ assert.notDeepEqual = function (act, exp, msg) { new Assertion(act, msg).to.not.eql(exp); }; /** * ### .isTrue(value, [message]) * * Asserts that `value` is true. * * var teaServed = true; * assert.isTrue(teaServed, 'the tea has been served'); * * @name isTrue * @param {Mixed} value * @param {String} message * @api public */ assert.isTrue = function (val, msg) { new Assertion(val, msg).is['true']; }; /** * ### .isFalse(value, [message]) * * Asserts that `value` is false. * * var teaServed = false; * assert.isFalse(teaServed, 'no tea yet? hmm...'); * * @name isFalse * @param {Mixed} value * @param {String} message * @api public */ assert.isFalse = function (val, msg) { new Assertion(val, msg).is['false']; }; /** * ### .isNull(value, [message]) * * Asserts that `value` is null. * * assert.isNull(err, 'there was no error'); * * @name isNull * @param {Mixed} value * @param {String} message * @api public */ assert.isNull = function (val, msg) { new Assertion(val, msg).to.equal(null); }; /** * ### .isNotNull(value, [message]) * * Asserts that `value` is not null. * * var tea = 'tasty chai'; * assert.isNotNull(tea, 'great, time for tea!'); * * @name isNotNull * @param {Mixed} value * @param {String} message * @api public */ assert.isNotNull = function (val, msg) { new Assertion(val, msg).to.not.equal(null); }; /** * ### .isUndefined(value, [message]) * * Asserts that `value` is `undefined`. * * var tea; * assert.isUndefined(tea, 'no tea defined'); * * @name isUndefined * @param {Mixed} value * @param {String} message * @api public */ assert.isUndefined = function (val, msg) { new Assertion(val, msg).to.equal(undefined); }; /** * ### .isDefined(value, [message]) * * Asserts that `value` is not `undefined`. * * var tea = 'cup of chai'; * assert.isDefined(tea, 'tea has been defined'); * * @name isUndefined * @param {Mixed} value * @param {String} message * @api public */ assert.isDefined = function (val, msg) { new Assertion(val, msg).to.not.equal(undefined); }; /** * ### .isFunction(value, [message]) * * Asserts that `value` is a function. * * function serveTea() { return 'cup of tea'; }; * assert.isFunction(serveTea, 'great, we can have tea now'); * * @name isFunction * @param {Mixed} value * @param {String} message * @api public */ assert.isFunction = function (val, msg) { new Assertion(val, msg).to.be.a('function'); }; /** * ### .isNotFunction(value, [message]) * * Asserts that `value` is _not_ a function. * * var serveTea = [ 'heat', 'pour', 'sip' ]; * assert.isNotFunction(serveTea, 'great, we have listed the steps'); * * @name isNotFunction * @param {Mixed} value * @param {String} message * @api public */ assert.isNotFunction = function (val, msg) { new Assertion(val, msg).to.not.be.a('function'); }; /** * ### .isObject(value, [message]) * * Asserts that `value` is an object (as revealed by * `Object.prototype.toString`). * * var selection = { name: 'Chai', serve: 'with spices' }; * assert.isObject(selection, 'tea selection is an object'); * * @name isObject * @param {Mixed} value * @param {String} message * @api public */ assert.isObject = function (val, msg) { new Assertion(val, msg).to.be.a('object'); }; /** * ### .isNotObject(value, [message]) * * Asserts that `value` is _not_ an object. * * var selection = 'chai' * assert.isObject(selection, 'tea selection is not an object'); * assert.isObject(null, 'null is not an object'); * * @name isNotObject * @param {Mixed} value * @param {String} message * @api public */ assert.isNotObject = function (val, msg) { new Assertion(val, msg).to.not.be.a('object'); }; /** * ### .isArray(value, [message]) * * Asserts that `value` is an array. * * var menu = [ 'green', 'chai', 'oolong' ]; * assert.isArray(menu, 'what kind of tea do we want?'); * * @name isArray * @param {Mixed} value * @param {String} message * @api public */ assert.isArray = function (val, msg) { new Assertion(val, msg).to.be.an('array'); }; /** * ### .isNotArray(value, [message]) * * Asserts that `value` is _not_ an array. * * var menu = 'green|chai|oolong'; * assert.isNotArray(menu, 'what kind of tea do we want?'); * * @name isNotArray * @param {Mixed} value * @param {String} message * @api public */ assert.isNotArray = function (val, msg) { new Assertion(val, msg).to.not.be.an('array'); }; /** * ### .isString(value, [message]) * * Asserts that `value` is a string. * * var teaOrder = 'chai'; * assert.isString(teaOrder, 'order placed'); * * @name isString * @param {Mixed} value * @param {String} message * @api public */ assert.isString = function (val, msg) { new Assertion(val, msg).to.be.a('string'); }; /** * ### .isNotString(value, [message]) * * Asserts that `value` is _not_ a string. * * var teaOrder = 4; * assert.isNotString(teaOrder, 'order placed'); * * @name isNotString * @param {Mixed} value * @param {String} message * @api public */ assert.isNotString = function (val, msg) { new Assertion(val, msg).to.not.be.a('string'); }; /** * ### .isNumber(value, [message]) * * Asserts that `value` is a number. * * var cups = 2; * assert.isNumber(cups, 'how many cups'); * * @name isNumber * @param {Number} value * @param {String} message * @api public */ assert.isNumber = function (val, msg) { new Assertion(val, msg).to.be.a('number'); }; /** * ### .isNotNumber(value, [message]) * * Asserts that `value` is _not_ a number. * * var cups = '2 cups please'; * assert.isNotNumber(cups, 'how many cups'); * * @name isNotNumber * @param {Mixed} value * @param {String} message * @api public */ assert.isNotNumber = function (val, msg) { new Assertion(val, msg).to.not.be.a('number'); }; /** * ### .isBoolean(value, [message]) * * Asserts that `value` is a boolean. * * var teaReady = true * , teaServed = false; * * assert.isBoolean(teaReady, 'is the tea ready'); * assert.isBoolean(teaServed, 'has tea been served'); * * @name isBoolean * @param {Mixed} value * @param {String} message * @api public */ assert.isBoolean = function (val, msg) { new Assertion(val, msg).to.be.a('boolean'); }; /** * ### .isNotBoolean(value, [message]) * * Asserts that `value` is _not_ a boolean. * * var teaReady = 'yep' * , teaServed = 'nope'; * * assert.isNotBoolean(teaReady, 'is the tea ready'); * assert.isNotBoolean(teaServed, 'has tea been served'); * * @name isNotBoolean * @param {Mixed} value * @param {String} message * @api public */ assert.isNotBoolean = function (val, msg) { new Assertion(val, msg).to.not.be.a('boolean'); }; /** * ### .typeOf(value, name, [message]) * * Asserts that `value`'s type is `name`, as determined by * `Object.prototype.toString`. * * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); * assert.typeOf('tea', 'string', 'we have a string'); * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); * assert.typeOf(null, 'null', 'we have a null'); * assert.typeOf(undefined, 'undefined', 'we have an undefined'); * * @name typeOf * @param {Mixed} value * @param {String} name * @param {String} message * @api public */ assert.typeOf = function (val, type, msg) { new Assertion(val, msg).to.be.a(type); }; /** * ### .notTypeOf(value, name, [message]) * * Asserts that `value`'s type is _not_ `name`, as determined by * `Object.prototype.toString`. * * assert.notTypeOf('tea', 'number', 'strings are not numbers'); * * @name notTypeOf * @param {Mixed} value * @param {String} typeof name * @param {String} message * @api public */ assert.notTypeOf = function (val, type, msg) { new Assertion(val, msg).to.not.be.a(type); }; /** * ### .instanceOf(object, constructor, [message]) * * Asserts that `value` is an instance of `constructor`. * * var Tea = function (name) { this.name = name; } * , chai = new Tea('chai'); * * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); * * @name instanceOf * @param {Object} object * @param {Constructor} constructor * @param {String} message * @api public */ assert.instanceOf = function (val, type, msg) { new Assertion(val, msg).to.be.instanceOf(type); }; /** * ### .notInstanceOf(object, constructor, [message]) * * Asserts `value` is not an instance of `constructor`. * * var Tea = function (name) { this.name = name; } * , chai = new String('chai'); * * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); * * @name notInstanceOf * @param {Object} object * @param {Constructor} constructor * @param {String} message * @api public */ assert.notInstanceOf = function (val, type, msg) { new Assertion(val, msg).to.not.be.instanceOf(type); }; /** * ### .include(haystack, needle, [message]) * * Asserts that `haystack` includes `needle`. Works * for strings and arrays. * * assert.include('foobar', 'bar', 'foobar contains string "bar"'); * assert.include([ 1, 2, 3 ], 3, 'array contains value'); * * @name include * @param {Array|String} haystack * @param {Mixed} needle * @param {String} message * @api public */ assert.include = function (exp, inc, msg) { var obj = new Assertion(exp, msg); if (Array.isArray(exp)) { obj.to.include(inc); } else if ('string' === typeof exp) { obj.to.contain.string(inc); } }; /** * ### .match(value, regexp, [message]) * * Asserts that `value` matches the regular expression `regexp`. * * assert.match('foobar', /^foo/, 'regexp matches'); * * @name match * @param {Mixed} value * @param {RegExp} regexp * @param {String} message * @api public */ assert.match = function (exp, re, msg) { new Assertion(exp, msg).to.match(re); }; /** * ### .notMatch(value, regexp, [message]) * * Asserts that `value` does not match the regular expression `regexp`. * * assert.notMatch('foobar', /^foo/, 'regexp does not match'); * * @name notMatch * @param {Mixed} value * @param {RegExp} regexp * @param {String} message * @api public */ assert.notMatch = function (exp, re, msg) { new Assertion(exp, msg).to.not.match(re); }; /** * ### .property(object, property, [message]) * * Asserts that `object` has a property named by `property`. * * assert.property({ tea: { green: 'matcha' }}, 'tea'); * * @name property * @param {Object} object * @param {String} property * @param {String} message * @api public */ assert.property = function (obj, prop, msg) { new Assertion(obj, msg).to.have.property(prop); }; /** * ### .notProperty(object, property, [message]) * * Asserts that `object` does _not_ have a property named by `property`. * * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); * * @name notProperty * @param {Object} object * @param {String} property * @param {String} message * @api public */ assert.notProperty = function (obj, prop, msg) { new Assertion(obj, msg).to.not.have.property(prop); }; /** * ### .deepProperty(object, property, [message]) * * Asserts that `object` has a property named by `property`, which can be a * string using dot- and bracket-notation for deep reference. * * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green'); * * @name deepProperty * @param {Object} object * @param {String} property * @param {String} message * @api public */ assert.deepProperty = function (obj, prop, msg) { new Assertion(obj, msg).to.have.deep.property(prop); }; /** * ### .notDeepProperty(object, property, [message]) * * Asserts that `object` does _not_ have a property named by `property`, which * can be a string using dot- and bracket-notation for deep reference. * * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); * * @name notDeepProperty * @param {Object} object * @param {String} property * @param {String} message * @api public */ assert.notDeepProperty = function (obj, prop, msg) { new Assertion(obj, msg).to.not.have.deep.property(prop); }; /** * ### .propertyVal(object, property, value, [message]) * * Asserts that `object` has a property named by `property` with value given * by `value`. * * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); * * @name propertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @api public */ assert.propertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg).to.have.property(prop, val); }; /** * ### .propertyNotVal(object, property, value, [message]) * * Asserts that `object` has a property named by `property`, but with a value * different from that given by `value`. * * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad'); * * @name propertyNotVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @api public */ assert.propertyNotVal = function (obj, prop, val, msg) { new Assertion(obj, msg).to.not.have.property(prop, val); }; /** * ### .deepPropertyVal(object, property, value, [message]) * * Asserts that `object` has a property named by `property` with value given * by `value`. `property` can use dot- and bracket-notation for deep * reference. * * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); * * @name deepPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @api public */ assert.deepPropertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg).to.have.deep.property(prop, val); }; /** * ### .deepPropertyNotVal(object, property, value, [message]) * * Asserts that `object` has a property named by `property`, but with a value * different from that given by `value`. `property` can use dot- and * bracket-notation for deep reference. * * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); * * @name deepPropertyNotVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @api public */ assert.deepPropertyNotVal = function (obj, prop, val, msg) { new Assertion(obj, msg).to.not.have.deep.property(prop, val); }; /** * ### .lengthOf(object, length, [message]) * * Asserts that `object` has a `length` property with the expected value. * * assert.lengthOf([1,2,3], 3, 'array has length of 3'); * assert.lengthOf('foobar', 5, 'string has lengt