From 0328be8ff9ccbd2d4f083c8ba902033513059164 Mon Sep 17 00:00:00 2001 From: Denis Bardadym Date: Fri, 13 Sep 2013 12:49:02 +0400 Subject: [PATCH] Make should a function and expose it to world. Assert module merged to it. Closes #43. --- History.md | 1 + Readme.md | 6 +++++- lib/should.js | 46 +++++++++++++++++++++++++++------------------- lib/util.js | 26 +++++++++++++++++++++++++- 4 files changed, 58 insertions(+), 21 deletions(-) diff --git a/History.md b/History.md index 9626387..45f5926 100644 --- a/History.md +++ b/History.md @@ -1,4 +1,5 @@ + * expose should to exports, to do not require Object.prototype only * fixed usage of valueOf only for standard wrappers * updated eql.js to current version from assert.js * fixed object comparison in eql.js [dirtyrottenscoundrel] diff --git a/Readme.md b/Readme.md index d5fbc73..1ffa4cc 100644 --- a/Readme.md +++ b/Readme.md @@ -2,7 +2,7 @@ _should_ is an expressive, readable, test framework agnostic, assertion library It extends the Object prototype with a single non-enumerable getter that allows you to express how that object should behave. -_should_ literally extends node's _assert_ module, in fact, it is node's assert module, for example `should.equal(str, 'foo')` will work, just as `assert.equal(str, 'foo')` would, and `should.AssertionError` **is** `assert.AssertionError`, meaning any test framework supporting this constructor will function properly with _should_. +_should_ literally extends node's _assert_ module, for example `should.equal(str, 'foo')` will work, just as `assert.equal(str, 'foo')` would, and `should.AssertionError` **is** `assert.AssertionError`, meaning any test framework supporting this constructor will function properly with _should_. ## Example ```javascript @@ -14,6 +14,10 @@ var user = { user.should.have.property('name', 'tj'); user.should.have.property('pets').with.lengthOf(4); +// or without Object.prototype, for guys how did Object.create(null) + +should(user).have.property('name', 'tj'); + someAsyncTask(foo, function(err, result){ should.not.exist(err); should.exist(result); diff --git a/lib/should.js b/lib/should.js index 2182bda..768a182 100644 --- a/lib/should.js +++ b/lib/should.js @@ -17,7 +17,16 @@ var util = require('./util') , i = require('util').inspect; /** - * Expose assert as should. + * Our function should + * @param obj + * @returns {Assertion} + */ +var should = function(obj) { + return new Assertion(util.isWrapperType(obj) ? obj.valueOf(): obj); +}; + +/** + * Expose assert to should * * This allows you to do things like below * without require()ing the assert module. @@ -25,8 +34,8 @@ var util = require('./util') * should.equal(foo.bar, undefined); * */ +util.merge(should, assert); -exports = module.exports = assert; /** * Assert _obj_ exists, with optional message. @@ -35,12 +44,11 @@ exports = module.exports = assert; * @param {String} [msg] * @api public */ - -exports.exist = exports.exists = function(obj, msg){ - if (null == obj) { +should.exist = should.exists = function(obj, msg) { + if(null == obj) { throw new AssertionError({ - message: msg || ('expected ' + i(obj) + ' to exist') - , stackStartFunction: exports.exist + message: msg || ('expected ' + i(obj) + ' to exist') + , stackStartFunction: should.exist }); } }; @@ -53,16 +61,22 @@ exports.exist = exports.exists = function(obj, msg){ * @api public */ -exports.not = {}; -exports.not.exist = exports.not.exists = function(obj, msg){ +should.not = {}; +should.not.exist = should.not.exists = function(obj, msg){ if (null != obj) { throw new AssertionError({ - message: msg || ('expected ' + i(obj) + ' to not exist') - , stackStartFunction: exports.not.exist + message: msg || ('expected ' + i(obj) + ' to not exist') + , stackStartFunction: should.not.exist }); } }; +/** + * Expose should to external world. + */ +exports = module.exports = should; + + /** * Expose api via `Object#should`. * @@ -72,7 +86,7 @@ exports.not.exist = exports.not.exists = function(obj, msg){ Object.defineProperty(Object.prototype, 'should', { set: function(){}, get: function(){ - return new Assertion(util.isWrapperType(this) ? this.valueOf() : this); + return should(this); }, configurable: true }); @@ -84,7 +98,7 @@ Object.defineProperty(Object.prototype, 'should', { * @api private */ -var Assertion = exports.Assertion = function Assertion(obj) { +var Assertion = should.Assertion = function Assertion(obj) { this.obj = obj; }; @@ -94,12 +108,6 @@ var Assertion = exports.Assertion = function Assertion(obj) { Assertion.prototype = { - /** - * HACK: prevents double require() from failing. - */ - - exports: exports, - /** * Assert _expr_ with the given _msg_ and _negatedMsg_. * diff --git a/lib/util.js b/lib/util.js index 044124d..73d6490 100644 --- a/lib/util.js +++ b/lib/util.js @@ -6,4 +6,28 @@ */ exports.isWrapperType = function(obj) { return obj instanceof Number || obj instanceof String || obj instanceof Boolean; -} \ No newline at end of file +} + +/** + * Merge object b with object a. + * + * var a = { foo: 'bar' } + * , b = { bar: 'baz' }; + * + * utils.merge(a, b); + * // => { foo: 'bar', bar: 'baz' } + * + * @param {Object} a + * @param {Object} b + * @return {Object} + * @api private + */ + +exports.merge = function(a, b){ + if (a && b) { + for (var key in b) { + a[key] = b[key]; + } + } + return a; +}; \ No newline at end of file