diff options
Diffstat (limited to 'node_modules/should/lib')
| -rw-r--r-- | node_modules/should/lib/eql.js | 91 | ||||
| -rw-r--r-- | node_modules/should/lib/should.js | 701 |
2 files changed, 792 insertions, 0 deletions
diff --git a/node_modules/should/lib/eql.js b/node_modules/should/lib/eql.js new file mode 100644 index 0000000..ef21923 --- /dev/null +++ b/node_modules/should/lib/eql.js @@ -0,0 +1,91 @@ + +// Taken from node's assert module, because it sucks +// and exposes next to nothing useful. + +module.exports = _deepEqual; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3. Other pairs that do not both pass typeof value == "object", + // equivalence is determined by ==. + } else if (typeof actual != 'object' && typeof expected != 'object') { + return actual === expected; + + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical "prototype" property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isUndefinedOrNull (value) { + return value === null || value === undefined; +} + +function isArguments (object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv (a, b) { + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical "prototype" property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try{ + var ka = Object.keys(a), + kb = Object.keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key] )) + return false; + } + return true; +} diff --git a/node_modules/should/lib/should.js b/node_modules/should/lib/should.js new file mode 100644 index 0000000..0273287 --- /dev/null +++ b/node_modules/should/lib/should.js @@ -0,0 +1,701 @@ +/*! + * Should + * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca> + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var util = require('util') + , http = require('http') + , assert = require('assert') + , AssertionError = assert.AssertionError + , statusCodes = http.STATUS_CODES + , eql = require('./eql') + , i = util.inspect; + +/** + * Expose assert as should. + * + * This allows you to do things like below + * without require()ing the assert module. + * + * should.equal(foo.bar, undefined); + * + */ + +exports = module.exports = assert; + +/** + * Library version. + */ + +exports.version = '0.6.0'; + +/** + * Assert _obj_ exists, with optional message. + * + * @param {Mixed} obj + * @param {String} msg + * @api public + */ + +exports.exist = function(obj, msg){ + if (null == obj) { + throw new AssertionError({ + message: msg || ('expected ' + i(obj) + ' to exist') + , stackStartFunction: should.exist + }); + } +}; + +/** + * Asserts _obj_ does not exist, with optional message. + * + * @param {Mixed} obj + * @param {String} msg + * @api public + */ + +exports.not = {}; +exports.not.exist = function(obj, msg){ + if (null != obj) { + throw new AssertionError({ + message: msg || ('expected ' + i(obj) + ' to not exist') + , stackStartFunction: should.not.exist + }); + } +}; + +/** + * Expose api via `Object#should`. + * + * @api public + */ + +Object.defineProperty(Object.prototype, 'should', { + set: function(){}, + get: function(){ + return new Assertion(this); + }, + configurable: true +}); + +/** + * Initialize a new `Assertion` with the given _obj_. + * + * @param {Mixed} obj + * @api private + */ + +var Assertion = exports.Assertion = function Assertion(obj) { + this.obj = obj; +}; + +/** + * Prototype. + */ + +Assertion.prototype = { + + /** + * HACK: prevents double require() from failing. + */ + + exports: exports, + + /** + * Assert _expr_ with the given _msg_ and _negatedMsg_. + * + * @param {Boolean} expr + * @param {String} msg + * @param {String} negatedMsg + * @param {Object} expected + * @api private + */ + + assert: function(expr, msg, negatedMsg, expected){ + var msg = this.negate ? negatedMsg : msg + , ok = this.negate ? !expr : expr; + + if (!ok) { + throw new AssertionError({ + message: msg + , actual: this.obj + , expected: expected + , stackStartFunction: this.assert + }); + } + }, + + /** + * Dummy getter. + * + * @api public + */ + + get an() { + return this; + }, + + /** + * Dummy getter. + * + * @api public + */ + + get and() { + return this; + }, + + /** + * Dummy getter. + * + * @api public + */ + + get be() { + return this; + }, + + /** + * Dummy getter. + * + * @api public + */ + + get have() { + return this; + }, + + /** + * Dummy getter. + * + * @api public + */ + + get with() { + return this; + }, + + /** + * Negation modifier. + * + * @api public + */ + + get not() { + this.negate = true; + return this; + }, + + /** + * Get object inspection string. + * + * @return {String} + * @api private + */ + + get inspect() { + return i(this.obj); + }, + + /** + * Assert instanceof `Arguments`. + * + * @api public + */ + + get arguments() { + this.assert( + '[object Arguments]' == Object.prototype.toString.call(this.obj) + , 'expected ' + this.inspect + ' to be arguments' + , 'expected ' + this.inspect + ' to not be arguments'); + return this; + }, + + /** + * Assert that an object is empty aka length of 0. + * + * @api public + */ + + get empty() { + this.obj.should.have.property('length'); + this.assert( + 0 === this.obj.length + , 'expected ' + this.inspect + ' to be empty' + , 'expected ' + this.inspect + ' not to be empty'); + return this; + }, + + /** + * Assert ok. + * + * @api public + */ + + get ok() { + this.assert( + this.obj + , 'expected ' + this.inspect + ' to be truthy' + , 'expected ' + this.inspect + ' to be falsey'); + return this; + }, + + /** + * Assert true. + * + * @api public + */ + + get true() { + this.assert( + true === this.obj + , 'expected ' + this.inspect + ' to be true' + , 'expected ' + this.inspect + ' not to be true'); + return this; + }, + + /** + * Assert false. + * + * @api public + */ + + get false() { + this.assert( + false === this.obj + , 'expected ' + this.inspect + ' to be false' + , 'expected ' + this.inspect + ' not to be false'); + return this; + }, + + /** + * Assert equal. + * + * @param {Mixed} val + * @param {String} description + * @api public + */ + + eql: function(val, desc){ + this.assert( + eql(val, this.obj) + , 'expected ' + this.inspect + ' to equal ' + i(val) + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to not equal ' + i(val) + (desc ? " | " + desc : "") + , val); + return this; + }, + + /** + * Assert strict equal. + * + * @param {Mixed} val + * @param {String} description + * @api public + */ + + equal: function(val, desc){ + this.assert( + val === this.obj + , 'expected ' + this.inspect + ' to equal ' + i(val) + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to not equal ' + i(val) + (desc ? " | " + desc : "") + , val); + return this; + }, + + /** + * Assert within start to finish (inclusive). + * + * @param {Number} start + * @param {Number} finish + * @param {String} description + * @api public + */ + + within: function(start, finish, desc){ + var range = start + '..' + finish; + this.assert( + this.obj >= start && this.obj <= finish + , 'expected ' + this.inspect + ' to be within ' + range + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to not be within ' + range + (desc ? " | " + desc : "")); + return this; + }, + + /** + * Assert typeof. + * + * @param {Mixed} type + * @param {String} description + * @api public + */ + + a: function(type, desc){ + this.assert( + type == typeof this.obj + , 'expected ' + this.inspect + ' to be a ' + type + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' not to be a ' + type + (desc ? " | " + desc : "")); + return this; + }, + + /** + * Assert instanceof. + * + * @param {Function} constructor + * @param {String} description + * @api public + */ + + instanceof: function(constructor, desc){ + var name = constructor.name; + this.assert( + this.obj instanceof constructor + , 'expected ' + this.inspect + ' to be an instance of ' + name + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' not to be an instance of ' + name + (desc ? " | " + desc : "")); + return this; + }, + + /** + * Assert numeric value above _n_. + * + * @param {Number} n + * @param {String} description + * @api public + */ + + above: function(n, desc){ + this.assert( + this.obj > n + , 'expected ' + this.inspect + ' to be above ' + n + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to be below ' + n + (desc ? " | " + desc : "")); + return this; + }, + + /** + * Assert numeric value below _n_. + * + * @param {Number} n + * @param {String} description + * @api public + */ + + below: function(n, desc){ + this.assert( + this.obj < n + , 'expected ' + this.inspect + ' to be below ' + n + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to be above ' + n + (desc ? " | " + desc : "")); + return this; + }, + + /** + * Assert string value matches _regexp_. + * + * @param {RegExp} regexp + * @param {String} description + * @api public + */ + + match: function(regexp, desc){ + this.assert( + regexp.exec(this.obj) + , 'expected ' + this.inspect + ' to match ' + regexp + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' not to match ' + regexp + (desc ? " | " + desc : "")); + return this; + }, + + /** + * Assert property "length" exists and has value of _n_. + * + * @param {Number} n + * @param {String} description + * @api public + */ + + length: function(n, desc){ + this.obj.should.have.property('length'); + var len = this.obj.length; + this.assert( + n == len + , 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to not have a length of ' + len + (desc ? " | " + desc : "")); + return this; + }, + + /** + * Assert property _name_ exists, with optional _val_. + * + * @param {String} name + * @param {Mixed} val + * @param {String} description + * @api public + */ + + property: function(name, val, desc){ + if (this.negate && undefined !== val) { + if (undefined === this.obj[name]) { + throw new Error(this.inspect + ' has no property ' + i(name) + (desc ? " | " + desc : "")); + } + } else { + this.assert( + undefined !== this.obj[name] + , 'expected ' + this.inspect + ' to have a property ' + i(name) + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to not have a property ' + i(name) + (desc ? " | " + desc : "")); + } + + if (undefined !== val) { + this.assert( + val === this.obj[name] + , 'expected ' + this.inspect + ' to have a property ' + i(name) + + ' of ' + i(val) + ', but got ' + i(this.obj[name]) + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to not have a property ' + i(name) + ' of ' + i(val) + (desc ? " | " + desc : "")); + } + + this.obj = this.obj[name]; + return this; + }, + + /** + * Assert own property _name_ exists. + * + * @param {String} name + * @param {String} description + * @api public + */ + + ownProperty: function(name, desc){ + this.assert( + this.obj.hasOwnProperty(name) + , 'expected ' + this.inspect + ' to have own property ' + i(name) + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to not have own property ' + i(name) + (desc ? " | " + desc : "")); + return this; + }, + + /** + * Assert that `obj` is present via `.indexOf()`. + * + * @param {Mixed} obj + * @param {String} description + * @api public + */ + + include: function(obj, desc){ + this.assert( + ~this.obj.indexOf(obj) + , 'expected ' + this.inspect + ' to include ' + i(obj) + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to not include ' + i(obj) + (desc ? " | " + desc : "")); + + return this; + }, + + /** + * Assert that an object equal to `obj` is present. + * + * @param {Array} obj + * @param {String} description + * @api public + */ + + includeEql: function(obj, desc){ + this.assert( + this.obj.some(function(item) { return eql(obj, item); }) + , 'expected ' + this.inspect + ' to include an object equal to ' + i(obj) + (desc ? " | " + desc : "") + , 'expected ' + this.inspect + ' to not include an object equal to ' + i(obj) + (desc ? " | " + desc : "")); + return this; + }, + + /** + * Assert that the array contains _obj_. + * + * @param {Mixed} obj + * @api public + */ + + contain: function(obj){ + console.warn('should.contain() is deprecated, use should.include()'); + this.obj.should.be.an.instanceof(Array); + this.assert( + ~this.obj.indexOf(obj) + , 'expected ' + this.inspect + ' to contain ' + i(obj) + , 'expected ' + this.inspect + ' to not contain ' + i(obj)); + return this; + }, + + /** + * Assert exact keys or inclusion of keys by using + * the `.include` modifier. + * + * @param {Array|String ...} keys + * @api public + */ + + keys: function(keys){ + var 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(this.obj) + , len = keys.length; + + // make sure they're all present + ok = keys.every(function(key){ + return ~actual.indexOf(key); + }); + + // matching length + ok = ok && keys.length == actual.length; + + // key string + if (len > 1) { + keys = keys.map(function(key){ + return i(key); + }); + var last = keys.pop(); + str = keys.join(', ') + ', and ' + last; + } else { + str = i(keys[0]); + } + + // message + str = 'have ' + (len > 1 ? 'keys ' : 'key ') + str; + + this.assert( + ok + , 'expected ' + this.inspect + ' to ' + str + , 'expected ' + this.inspect + ' to not ' + str); + + return this; + }, + + /** + * Assert that header `field` has the given `val`. + * + * @param {String} field + * @param {String} val + * @return {Assertion} for chaining + * @api public + */ + + header: function(field, val){ + this.obj.should + .have.property('headers').and + .have.property(field.toLowerCase(), val); + return this; + }, + + /** + * Assert `.statusCode` of `code`. + * + * @param {Number} code + * @return {Assertion} for chaining + * @api public + */ + + status: function(code){ + this.obj.should.have.property('statusCode'); + var status = this.obj.statusCode; + + this.assert( + code == status + , 'expected response code of ' + code + ' ' + i(statusCodes[code]) + + ', but got ' + status + ' ' + i(statusCodes[status]) + , 'expected to not respond with ' + code + ' ' + i(statusCodes[code])); + + return this; + }, + + /** + * Assert that this response has content-type: application/json. + * + * @return {Assertion} for chaining + * @api public + */ + + get json() { + this.obj.should.have.property('headers'); + this.obj.headers.should.have.property('content-type'); + this.obj.headers['content-type'].should.include('application/json'); + return this; + }, + + /** + * Assert that this response has content-type: text/html. + * + * @return {Assertion} for chaining + * @api public + */ + + get html() { + this.obj.should.have.property('headers'); + this.obj.headers.should.have.property('content-type'); + this.obj.headers['content-type'].should.include('text/html'); + return this; + }, + + /** + * Assert that this function will or will not + * throw an exception. + * + * @return {Assertion} for chaining + * @api public + */ + + throw: function(message){ + var fn = this.obj + , err = {} + , errorInfo = '' + , ok = true; + + try { + fn(); + ok = false; + } catch (e) { + err = e; + } + + if (ok) { + if ('string' == typeof message) { + ok = message == err.message; + } else if (message instanceof RegExp) { + ok = message.test(err.message); + } + + if (message && !ok) { + if ('string' == typeof message) { + errorInfo = " with a message matching '" + message + "', but got '" + err.message + "'"; + } else { + errorInfo = " with a message matching " + message + ", but got '" + err.message + "'"; + } + } + } + + this.assert( + ok + , 'expected an exception to be thrown' + errorInfo + , 'expected no exception to be thrown, got "' + err.message + '"'); + + return this; + } +}; + +/** + * Aliases. + */ + +(function alias(name, as){ + Assertion.prototype[as] = Assertion.prototype[name]; + return alias; +}) +('length', 'lengthOf') +('keys', 'key') +('ownProperty', 'haveOwnProperty') +('above', 'greaterThan') +('below', 'lessThan'); + |
