diff --git a/Readme.md b/Readme.md index 82db1f5..b4facf0 100644 --- a/Readme.md +++ b/Readme.md @@ -275,9 +275,9 @@ res.should.be.json res.should.be.html ``` -## include(obj) +## include(obj) or contain(obj) -Assert that the given `obj` is present via `indexOf()`, so this works for strings, arrays, or custom objects implementing indexOf. Also it can assert if given object will have some sub-object +Assert that the given `obj` is present via `indexOf()`, so this works for strings, arrays, or custom objects implementing indexOf. Also it can assert if given object will have some sub-object. Assert array value: ```javascript diff --git a/lib/should.js b/lib/should.js index 714a92f..9e1c732 100644 --- a/lib/should.js +++ b/lib/should.js @@ -41,7 +41,7 @@ util.merge(should, assert); /** * Assert _obj_ exists, with optional message. * - * @param {Mixed} obj + * @param {*} obj * @param {String} [msg] * @api public */ @@ -57,7 +57,7 @@ should.exist = should.exists = function(obj, msg) { /** * Asserts _obj_ does not exist, with optional message. * - * @param {Mixed} obj + * @param {*} obj * @param {String} [msg] * @api public */ @@ -95,7 +95,7 @@ Object.defineProperty(Object.prototype, 'should', { /** * Initialize a new `Assertion` with the given _obj_. * - * @param {Mixed} obj + * @param {*} obj * @api private */ @@ -115,15 +115,18 @@ Assertion.prototype = { * Assert _expr_ with the given _msg_ and _negatedMsg_. * * @param {Boolean} expr - * @param {String} msg - * @param {String} negatedMsg - * @param {Object} expected + * @param {function} msg + * @param {function} negatedMsg + * @param {Object} [expected] + * @param {Boolean} [showDiff] + * @param {String} [description] * @api private */ - assert: function(expr, msg, negatedMsg, expected, showDiff){ - var msg = this.negate ? negatedMsg : msg - , ok = this.negate ? !expr : expr + assert: function(expr, msg, negatedMsg, expected, showDiff, description){ + msg = this.negate ? negatedMsg : msg + + var ok = this.negate ? !expr : expr , obj = this.obj; if (ok) return; @@ -137,6 +140,7 @@ Assertion.prototype = { }); err.showDiff = showDiff; + err.description = description throw err; }, @@ -342,35 +346,38 @@ Assertion.prototype = { /** * Assert equal. * - * @param {Mixed} val + * @param {*} val * @param {String} description * @api public */ - eql: function(val, desc){ + eql: function(val, description){ this.assert( eql(val, this.obj) - , function(){ return 'expected ' + this.inspect + ' to equal ' + should.inspect(val) + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to not equal ' + should.inspect(val) + (desc ? " | " + desc : "") } + , function(){ return 'expected ' + this.inspect + ' to equal ' + should.inspect(val) + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to not equal ' + should.inspect(val) + (description ? " | " + description : "") } , val - , true); + , true + , description); return this; }, /** * Assert strict equal. * - * @param {Mixed} val + * @param {*} val * @param {String} description * @api public */ - equal: function(val, desc){ + equal: function(val, description){ this.assert( val === this.obj - , function(){ return 'expected ' + this.inspect + ' to equal ' + should.inspect(val) + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to not equal ' + should.inspect(val) + (desc ? " | " + desc : "") } - , val); + , function(){ return 'expected ' + this.inspect + ' to equal ' + should.inspect(val) + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to not equal ' + should.inspect(val) + (description ? " | " + description : "") } + , val + , void 0 + , description); return this; }, @@ -383,12 +390,15 @@ Assertion.prototype = { * @api public */ - within: function(start, finish, desc){ + within: function(start, finish, description){ var range = start + '..' + finish; this.assert( this.obj >= start && this.obj <= finish - , function(){ return 'expected ' + this.inspect + ' to be within ' + range + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to not be within ' + range + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to be within ' + range + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to not be within ' + range + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, @@ -405,23 +415,28 @@ Assertion.prototype = { this.assert( Math.abs(this.obj - value) <= delta , function(){ return 'expected ' + this.inspect + ' to be approximately ' + value + " +- " + delta + (description ? " | " + description : "") } - , function(){ return 'expected ' + this.inspect + ' to not be approximately ' + value + " +- " + delta + (description ? " | " + description : "") }); + , function(){ return 'expected ' + this.inspect + ' to not be approximately ' + value + " +- " + delta + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, /** * Assert typeof. * - * @param {Mixed} type + * @param {*} type * @param {String} description * @api public */ - - type: function(type, desc){ + type: function(type, description){ this.assert( type == typeof this.obj - , function(){ return 'expected ' + this.inspect + ' to have type ' + type + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' not to have type ' + type + (desc ? " | " + desc : "") }) + , function(){ return 'expected ' + this.inspect + ' to have type ' + type + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' not to have type ' + type + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, @@ -433,12 +448,15 @@ Assertion.prototype = { * @api public */ - instanceof: function(constructor, desc){ + instanceof: function(constructor, description){ var name = constructor.name; this.assert( this.obj instanceof constructor - , function(){ return 'expected ' + this.inspect + ' to be an instance of ' + name + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' not to be an instance of ' + name + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to be an instance of ' + name + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' not to be an instance of ' + name + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, @@ -526,11 +544,14 @@ Assertion.prototype = { * @api public */ - above: function(n, desc){ + above: function(n, description){ this.assert( this.obj > n - , function(){ return 'expected ' + this.inspect + ' to be above ' + n + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to be below ' + n + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to be above ' + n + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to be below ' + n + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, @@ -542,11 +563,14 @@ Assertion.prototype = { * @api public */ - below: function(n, desc){ + below: function(n, description){ this.assert( this.obj < n - , function(){ return 'expected ' + this.inspect + ' to be below ' + n + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to be above ' + n + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to be below ' + n + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to be above ' + n + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, @@ -558,11 +582,14 @@ Assertion.prototype = { * @api public */ - match: function(regexp, desc){ + match: function(regexp, description){ this.assert( regexp.exec(this.obj) - , function(){ return 'expected ' + this.inspect + ' to match ' + regexp + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' not to match ' + regexp + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to match ' + regexp + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' not to match ' + regexp + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, @@ -574,13 +601,16 @@ Assertion.prototype = { * @api public */ - length: function(n, desc){ + length: function(n, description){ this.obj.should.have.property('length'); var len = this.obj.length; this.assert( n == len - , function(){ return 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to not have a length of ' + len + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to not have a length of ' + len + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, @@ -588,29 +618,35 @@ Assertion.prototype = { * Assert property _name_ exists, with optional _val_. * * @param {String} name - * @param {Mixed} [val] + * @param {*} [val] * @param {String} description * @api public */ - property: function(name, val, desc){ + property: function(name, val, description){ if (this.negate && undefined !== val) { if (undefined === this.obj[name]) { - throw new Error(this.inspect + ' has no property ' + should.inspect(name) + (desc ? " | " + desc : "")); + throw new Error(this.inspect + ' has no property ' + should.inspect(name) + (description ? " | " + description : "")); } } else { this.assert( undefined !== this.obj[name] - , function(){ return 'expected ' + this.inspect + ' to have a property ' + should.inspect(name) + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to not have a property ' + should.inspect(name) + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to have a property ' + should.inspect(name) + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to not have a property ' + should.inspect(name) + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); } if (undefined !== val) { this.assert( val === this.obj[name] , function(){ return 'expected ' + this.inspect + ' to have a property ' + should.inspect(name) - + ' of ' + should.inspect(val) + ', but got ' + should.inspect(this.obj[name]) + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to not have a property ' + should.inspect(name) + ' of ' + should.inspect(val) + (desc ? " | " + desc : "") }); + + ' of ' + should.inspect(val) + ', but got ' + should.inspect(this.obj[name]) + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to not have a property ' + should.inspect(name) + ' of ' + should.inspect(val) + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); } this.obj = this.obj[name]; @@ -668,11 +704,14 @@ Assertion.prototype = { * @api public */ - ownProperty: function(name, desc){ + ownProperty: function(name, description){ this.assert( hasOwnProperty.call(this.obj, name) - , function(){ return 'expected ' + this.inspect + ' to have own property ' + should.inspect(name) + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to not have own property ' + should.inspect(name) + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to have own property ' + should.inspect(name) + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to not have own property ' + should.inspect(name) + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); this.obj = this.obj[name]; return this; }, @@ -680,52 +719,64 @@ Assertion.prototype = { /** * Assert that string starts with `str`. * @param {String} str - * @param {String} desc + * @param {String} description * @api public */ - startWith: function(str, desc) { + startWith: function(str, description) { this.assert(0 === this.obj.indexOf(str) - , function() { return 'expected ' + this.inspect + ' to start with ' + should.inspect(str) + (desc ? " | " + desc : "") } - , function() { return 'expected ' + this.inspect + ' to not start with ' + should.inspect(str) + (desc ? " | " + desc : "") }); + , function() { return 'expected ' + this.inspect + ' to start with ' + should.inspect(str) + (description ? " | " + description : "") } + , function() { return 'expected ' + this.inspect + ' to not start with ' + should.inspect(str) + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, /** * Assert that string ends with `str`. * @param {String} str - * @param {String} desc + * @param {String} description * @api public */ - endWith: function(str, desc) { + endWith: function(str, description) { this.assert(-1 !== this.obj.indexOf(str, this.obj.length - str.length) - , function() { return 'expected ' + this.inspect + ' to end with ' + should.inspect(str) + (desc ? " | " + desc : "") } - , function() { return 'expected ' + this.inspect + ' to not end with ' + should.inspect(str) + (desc ? " | " + desc : "") }); + , function() { return 'expected ' + this.inspect + ' to end with ' + should.inspect(str) + (description ? " | " + description : "") } + , function() { return 'expected ' + this.inspect + ' to not end with ' + should.inspect(str) + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, /** * Assert that `obj` is present via `.indexOf()` or that `obj` contains some sub-object. * - * @param {Mixed} obj + * @param {*} obj * @param {String} description * @api public */ - include: function(obj, desc){ + include: function(obj, description){ if (obj.constructor == Object){ var cmp = {}; for (var key in obj) cmp[key] = this.obj[key]; this.assert( eql(cmp, obj) - , function(){ return 'expected ' + this.inspect + ' to include an object equal to ' + should.inspect(obj) + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to not include an object equal to ' + should.inspect(obj) + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to include an object equal to ' + should.inspect(obj) + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to not include an object equal to ' + should.inspect(obj) + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); } else { this.assert( ~this.obj.indexOf(obj) - , function(){ return 'expected ' + this.inspect + ' to include ' + should.inspect(obj) + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to not include ' + should.inspect(obj) + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to include ' + should.inspect(obj) + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to not include ' + should.inspect(obj) + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); } return this; }, @@ -738,15 +789,17 @@ Assertion.prototype = { * @api public */ - includeEql: function(obj, desc){ + includeEql: function(obj, description){ this.assert( this.obj.some(function(item) { return eql(obj, item); }) - , function(){ return 'expected ' + this.inspect + ' to include an object equal to ' + should.inspect(obj) + (desc ? " | " + desc : "") } - , function(){ return 'expected ' + this.inspect + ' to not include an object equal to ' + should.inspect(obj) + (desc ? " | " + desc : "") }); + , function(){ return 'expected ' + this.inspect + ' to include an object equal to ' + should.inspect(obj) + (description ? " | " + description : "") } + , function(){ return 'expected ' + this.inspect + ' to not include an object equal to ' + should.inspect(obj) + (description ? " | " + description : "") } + , void 0 + , void 0 + , description); return this; }, - /** * Assert exact keys or inclusion of keys by using * the `.include` modifier.