diff options
Diffstat (limited to 'node_modules/kareem/test/examples.test.js')
-rw-r--r-- | node_modules/kareem/test/examples.test.js | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/node_modules/kareem/test/examples.test.js b/node_modules/kareem/test/examples.test.js new file mode 100644 index 0000000..f120723 --- /dev/null +++ b/node_modules/kareem/test/examples.test.js @@ -0,0 +1,379 @@ +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; + + beforeEach(function() { + hooks = new Kareem(); + }); + + it('runs without any hooks specified', function(done) { + hooks.execPre('cook', null, function() { + done(); + }); + }); + + /* 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; + + hooks.pre('cook', function(done) { + ++count; + done(); + }); + + hooks.execPre('cook', null, function() { + assert.equal(1, count); + done(); + }); + }); + + it('can run multipe pre hooks', function(done) { + var count1 = 0; + var count2 = 0; + + hooks.pre('cook', function(done) { + ++count1; + done(); + }); + + hooks.pre('cook', function(done) { + ++count2; + done(); + }); + + hooks.execPre('cook', null, function() { + assert.equal(1, count1); + assert.equal(1, count2); + 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; + + hooks.pre('cook', function() { + ++count1; + }); + + hooks.pre('cook', function() { + ++count2; + }); + + hooks.execPre('cook', null, function(error) { + assert.equal(null, error); + assert.equal(1, count1); + assert.equal(1, count2); + done(); + }); + }); + + /* 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; + done(); + }); + + hooks.pre('cook', function(done) { + this.eggs = 4; + done(); + }); + + var obj = { bacon: 0, eggs: 0 }; + + // In the pre hooks, `this` will refer to `obj` + hooks.execPre('cook', obj, function(error) { + assert.equal(null, error); + assert.equal(3, obj.bacon); + assert.equal(4, obj.eggs); + done(); + }); + }); + + /* 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; + 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(); + }); + + var obj = { bacon: 0, eggs: 0 }; + + hooks.execPre('cook', obj, function() { + assert.equal(3, obj.bacon); + assert.equal(4, obj.eggs); + assert.equal(false, obj.waffles); + done(); + }); + }); + + /* You can also return a promise from your pre hooks instead of calling + * `next()`. When the returned promise resolves, kareem will kick off the + * next middleware. + */ + it('supports returning a promise', function(done) { + hooks.pre('cook', function() { + return new Promise(resolve => { + setTimeout(() => { + this.bacon = 3; + resolve(); + }, 100); + }); + }); + + var obj = { bacon: 0 }; + + hooks.execPre('cook', obj, function() { + assert.equal(3, obj.bacon); + done(); + }); + }); +}); + +describe('post hooks', function() { + var hooks; + + beforeEach(function() { + hooks = new Kareem(); + }); + + it('runs without any hooks specified', function(done) { + hooks.execPost('cook', null, [1], function(error, eggs) { + assert.ifError(error); + assert.equal(1, eggs); + done(); + }); + }); + + it('executes with parameters passed in', function(done) { + hooks.post('cook', function(eggs, bacon, callback) { + assert.equal(1, eggs); + assert.equal(2, bacon); + callback(); + }); + + hooks.execPost('cook', null, [1, 2], function(error, eggs, bacon) { + assert.ifError(error); + assert.equal(1, eggs); + assert.equal(2, bacon); + done(); + }); + }); + + it('can use synchronous post hooks', function(done) { + var execed = {}; + + hooks.post('cook', function(eggs, bacon) { + execed.first = true; + assert.equal(1, eggs); + assert.equal(2, bacon); + }); + + hooks.post('cook', function(eggs, bacon, callback) { + execed.second = true; + assert.equal(1, eggs); + assert.equal(2, bacon); + callback(); + }); + + hooks.execPost('cook', null, [1, 2], function(error, eggs, bacon) { + assert.ifError(error); + assert.equal(2, Object.keys(execed).length); + assert.ok(execed.first); + assert.ok(execed.second); + assert.equal(1, eggs); + assert.equal(2, bacon); + done(); + }); + }); +}); + +describe('wrap()', function() { + var hooks; + + beforeEach(function() { + hooks = new Kareem(); + }); + + it('wraps pre and post calls into one call', function(done) { + 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 args = [obj]; + args.push(function(error, result) { + assert.ifError(error); + assert.equal(null, 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(); + }); + + hooks.wrap( + '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, + args); + }); +}); + +describe('createWrapper()', function() { + var hooks; + + beforeEach(function() { + hooks = new Kareem(); + }); + + it('wraps wrap() into a callable function', function(done) { + 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(); + }); + }); +}); + +describe('clone()', function() { + it('clones a Kareem object', function() { + var k1 = new Kareem(); + k1.pre('cook', function() {}); + k1.post('cook', function() {}); + + var k2 = k1.clone(); + assert.deepEqual(Array.from(k2._pres.keys()), ['cook']); + assert.deepEqual(Array.from(k2._posts.keys()), ['cook']); + }); +}); + +describe('merge()', function() { + it('pulls hooks from another Kareem object', function() { + var k1 = new Kareem(); + var test1 = function() {}; + k1.pre('cook', test1); + k1.post('cook', function() {}); + + var k2 = new Kareem(); + var test2 = function() {}; + k2.pre('cook', test2); + var k3 = k2.merge(k1); + assert.equal(k3._pres.get('cook').length, 2); + assert.equal(k3._pres.get('cook')[0].fn, test2); + assert.equal(k3._pres.get('cook')[1].fn, test1); + assert.equal(k3._posts.get('cook').length, 1); + }); +}); |