diff --git a/README.md b/README.md index 3988f7d..92976c2 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,14 @@ Named for the NBA's all-time leading scorer Kareem Abdul-Jabbar, known for his m ## pre hooks +Much like [hooks](https://npmjs.org/package/hooks), kareem lets you define +pre and post hooks: pre hooks are called before a given function executes. +Unlike hooks, kareem stores hooks and other internal state in a separate +object, rather than relying on inheritance. Furthermore, kareem exposes +an `execPre()` function that allows you to execute your pre hooks when +appropriate, giving you more fine-grained control over your function hooks. + + #### It runs without any hooks specified ```javascript @@ -24,6 +32,10 @@ Named for the NBA's all-time leading scorer Kareem Abdul-Jabbar, known for his m #### It runs basic serial pre hooks +pre hook functions take one parameter, a "done" function that you execute +when your pre hook is finished. + + ```javascript var count = 0; @@ -40,7 +52,7 @@ Named for the NBA's all-time leading scorer Kareem Abdul-Jabbar, known for his m ``` -#### It can run multipe pres +#### It can run multipe pre hooks ```javascript @@ -65,7 +77,11 @@ Named for the NBA's all-time leading scorer Kareem Abdul-Jabbar, known for his m ``` -#### It can run fully synchronous pres +#### It can run fully synchronous pre hooks + +If your pre hook function takes no parameters, its assumed to be +fully synchronous. + ```javascript @@ -90,6 +106,9 @@ Named for the NBA's all-time leading scorer Kareem Abdul-Jabbar, known for his m #### It properly attaches context to pre hooks +Pre save hook functions are bound to the second parameter to `execPre()` + + ```javascript hooks.pre('cook', function(done) { @@ -104,6 +123,7 @@ Named for the NBA's all-time leading scorer Kareem Abdul-Jabbar, known for his m var obj = { bacon: 0, eggs: 0 }; + // In the pre hooks, `this` will refer to `obj` hooks.execPre('cook', obj, function() { assert.equal(3, obj.bacon); assert.equal(4, obj.eggs); @@ -114,6 +134,12 @@ Named for the NBA's all-time leading scorer Kareem Abdul-Jabbar, known for his m #### It can execute parallel (async) pre hooks +Like the hooks module, you can declare "async" pre hooks - these take two +parameters, the functions `next()` and `done()`. `next()` passes control to +the next pre hook, but the underlying function won't be called until all +async pre hooks have called `done()`. + + ```javascript hooks.pre('cook', true, function(next, done) { @@ -273,3 +299,61 @@ Named for the NBA's all-time leading scorer Kareem Abdul-Jabbar, known for his m ``` +## createWrapper() + +#### It wraps wrap() into a callable function + +```javascript + + hooks.pre('cook', true, function(next, done) { + this.bacon = 3; + next(); + setTimeout(function() { + done(); + }, 5); + }); + + hooks.pre('cook', true, function(next, done) { + next(); + var _this = this; + setTimeout(function() { + _this.eggs = 4; + done(); + }, 10); + }); + + hooks.pre('cook', function(next) { + this.waffles = false; + next(); + }); + + hooks.post('cook', function(obj) { + obj.tofu = 'no'; + }); + + var obj = { bacon: 0, eggs: 0 }; + + var cook = hooks.createWrapper( + 'cook', + function(o, callback) { + assert.equal(3, obj.bacon); + assert.equal(4, obj.eggs); + assert.equal(false, obj.waffles); + assert.equal(undefined, obj.tofu); + callback(null, o); + }, + obj); + + cook(obj, function(error, result) { + assert.ifError(error); + assert.equal(3, obj.bacon); + assert.equal(4, obj.eggs); + assert.equal(false, obj.waffles); + assert.equal('no', obj.tofu); + + assert.equal(obj, result); + done(); + }); + +``` + diff --git a/docs.js b/docs.js index 8ff1202..49f968b 100644 --- a/docs.js +++ b/docs.js @@ -19,13 +19,15 @@ for (var i = 0; i < blocks.length; ++i) { var describe = blocks[i]; mdOutput += '## ' + describe.contents + '\n\n'; mdOutput += describe.comments[0] ? - trimEachLine(describe.comments[0]) + '\n\n' : + acquit.trimEachLine(describe.comments[0]) + '\n\n' : ''; for (var j = 0; j < describe.blocks.length; ++j) { var it = describe.blocks[j]; mdOutput += '#### It ' + it.contents + '\n\n'; - mdOutput += it.comments[0] ? trimEachLine(it.comments[0]) + '\n\n' : ''; + mdOutput += it.comments[0] ? + acquit.trimEachLine(it.comments[0]) + '\n\n' : + ''; mdOutput += '```javascript\n'; mdOutput += ' ' + it.code + '\n'; mdOutput += '```\n\n'; diff --git a/test/examples.test.js b/test/examples.test.js index dcdaa16..b1ee8cf 100644 --- a/test/examples.test.js +++ b/test/examples.test.js @@ -1,6 +1,13 @@ var assert = require('assert'); var Kareem = require('../'); +/* Much like [hooks](https://npmjs.org/package/hooks), kareem lets you define + * pre and post hooks: pre hooks are called before a given function executes. + * Unlike hooks, kareem stores hooks and other internal state in a separate + * object, rather than relying on inheritance. Furthermore, kareem exposes + * an `execPre()` function that allows you to execute your pre hooks when + * appropriate, giving you more fine-grained control over your function hooks. + */ describe('pre hooks', function() { var hooks; @@ -14,6 +21,9 @@ describe('pre hooks', function() { }); }); + /* pre hook functions take one parameter, a "done" function that you execute + * when your pre hook is finished. + */ it('runs basic serial pre hooks', function(done) { var count = 0; @@ -28,7 +38,7 @@ describe('pre hooks', function() { }); }); - it('can run multipe pres', function(done) { + it('can run multipe pre hooks', function(done) { var count1 = 0; var count2 = 0; @@ -49,7 +59,10 @@ describe('pre hooks', function() { }); }); - it('can run fully synchronous pres', function(done) { + /* If your pre hook function takes no parameters, its assumed to be + * fully synchronous. + */ + it('can run fully synchronous pre hooks', function(done) { var count1 = 0; var count2 = 0; @@ -68,6 +81,8 @@ describe('pre hooks', function() { }); }); + /* Pre save hook functions are bound to the second parameter to `execPre()` + */ it('properly attaches context to pre hooks', function(done) { hooks.pre('cook', function(done) { this.bacon = 3; @@ -81,6 +96,7 @@ describe('pre hooks', function() { var obj = { bacon: 0, eggs: 0 }; + // In the pre hooks, `this` will refer to `obj` hooks.execPre('cook', obj, function() { assert.equal(3, obj.bacon); assert.equal(4, obj.eggs); @@ -88,6 +104,11 @@ describe('pre hooks', function() { }); }); + /* Like the hooks module, you can declare "async" pre hooks - these take two + * parameters, the functions `next()` and `done()`. `next()` passes control to + * the next pre hook, but the underlying function won't be called until all + * async pre hooks have called `done()`. + */ it('can execute parallel (async) pre hooks', function(done) { hooks.pre('cook', true, function(next, done) { this.bacon = 3;