mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-11 18:32:50 +00:00
updated bunch of file paths and changed the way posts are loaded
This commit is contained in:
2
node_modules/hooks-fixed/.npmignore
generated
vendored
Normal file
2
node_modules/hooks-fixed/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
**.swp
|
||||
node_modules
|
||||
9
node_modules/hooks-fixed/Makefile
generated
vendored
Normal file
9
node_modules/hooks-fixed/Makefile
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
test:
|
||||
@NODE_ENV=test ./node_modules/expresso/bin/expresso \
|
||||
$(TESTFLAGS) \
|
||||
./test.js
|
||||
|
||||
test-cov:
|
||||
@TESTFLAGS=--cov $(MAKE) test
|
||||
|
||||
.PHONY: test test-cov
|
||||
369
node_modules/hooks-fixed/README.md
generated
vendored
Normal file
369
node_modules/hooks-fixed/README.md
generated
vendored
Normal file
@@ -0,0 +1,369 @@
|
||||
hooks
|
||||
============
|
||||
|
||||
Add pre and post middleware hooks to your JavaScript methods.
|
||||
|
||||
## Installation
|
||||
npm install hooks
|
||||
|
||||
## Motivation
|
||||
Suppose you have a JavaScript object with a `save` method.
|
||||
|
||||
It would be nice to be able to declare code that runs before `save` and after `save`.
|
||||
For example, you might want to run validation code before every `save`,
|
||||
and you might want to dispatch a job to a background job queue after `save`.
|
||||
|
||||
One might have an urge to hard code this all into `save`, but that turns out to
|
||||
couple all these pieces of functionality (validation, save, and job creation) more
|
||||
tightly than is necessary. For example, what if someone does not want to do background
|
||||
job creation after the logical save?
|
||||
|
||||
It is nicer to tack on functionality using what we call `pre` and `post` hooks. These
|
||||
are functions that you define and that you direct to execute before or after particular
|
||||
methods.
|
||||
|
||||
## Example
|
||||
We can use `hooks` to add validation and background jobs in the following way:
|
||||
|
||||
```javascript
|
||||
var hooks = require('hooks')
|
||||
, Document = require('./path/to/some/document/constructor');
|
||||
|
||||
// Add hooks' methods: `hook`, `pre`, and `post`
|
||||
for (var k in hooks) {
|
||||
Document[k] = hooks[k];
|
||||
}
|
||||
|
||||
// Define a new method that is able to invoke pre and post middleware
|
||||
Document.hook('save', Document.prototype.save);
|
||||
|
||||
// Define a middleware function to be invoked before 'save'
|
||||
Document.pre('save', function validate (next) {
|
||||
// The `this` context inside of `pre` and `post` functions
|
||||
// is the Document instance
|
||||
if (this.isValid()) next(); // next() passes control to the next middleware
|
||||
// or to the target method itself
|
||||
else next(new Error("Invalid")); // next(error) invokes an error callback
|
||||
});
|
||||
|
||||
// Define a middleware function to be invoked after 'save'
|
||||
Document.post('save', function createJob (next) {
|
||||
this.sendToBackgroundQueue();
|
||||
next();
|
||||
});
|
||||
```
|
||||
|
||||
If you already have defined `Document.prototype` methods for which you want pres and posts,
|
||||
then you do not need to explicitly invoke `Document.hook(...)`. Invoking `Document.pre(methodName, fn)`
|
||||
or `Document.post(methodName, fn)` will automatically and lazily change `Document.prototype[methodName]`
|
||||
so that it plays well with `hooks`. An equivalent way to implement the previous example is:
|
||||
|
||||
```javascript
|
||||
var hooks = require('hooks')
|
||||
, Document = require('./path/to/some/document/constructor');
|
||||
|
||||
// Add hooks' methods: `hook`, `pre`, and `post`
|
||||
for (var k in hooks) {
|
||||
Document[k] = hooks[k];
|
||||
}
|
||||
|
||||
Document.prototype.save = function () {
|
||||
// ...
|
||||
};
|
||||
|
||||
// Define a middleware function to be invoked before 'save'
|
||||
Document.pre('save', function validate (next) {
|
||||
// The `this` context inside of `pre` and `post` functions
|
||||
// is the Document instance
|
||||
if (this.isValid()) next(); // next() passes control to the next middleware
|
||||
// or to the target method itself
|
||||
else next(new Error("Invalid")); // next(error) invokes an error callback
|
||||
});
|
||||
|
||||
// Define a middleware function to be invoked after 'save'
|
||||
Document.post('save', function createJob (next) {
|
||||
this.sendToBackgroundQueue();
|
||||
next();
|
||||
});
|
||||
```
|
||||
|
||||
## Pres and Posts as Middleware
|
||||
We structure pres and posts as middleware to give you maximum flexibility:
|
||||
|
||||
1. You can define **multiple** pres (or posts) for a single method.
|
||||
2. These pres (or posts) are then executed as a chain of methods.
|
||||
3. Any functions in this middleware chain can choose to halt the chain's execution by `next`ing an Error from that middleware function. If this occurs, then none of the other middleware in the chain will execute, and the main method (e.g., `save`) will not execute. This is nice, for example, when we don't want a document to save if it is invalid.
|
||||
|
||||
## Defining multiple pres (or posts)
|
||||
`pre` and `post` are chainable, so you can define multiple via:
|
||||
```javascript
|
||||
Document.pre('save', function (next) {
|
||||
console.log("hello");
|
||||
next();
|
||||
}).pre('save', function (next) {
|
||||
console.log("world");
|
||||
next();
|
||||
});
|
||||
|
||||
Document.post('save', function (next) {
|
||||
console.log("hello");
|
||||
next();
|
||||
}).post('save', function (next) {
|
||||
console.log("world");
|
||||
next();
|
||||
});
|
||||
```
|
||||
|
||||
As soon as one pre finishes executing, the next one will be invoked, and so on.
|
||||
|
||||
## Error Handling
|
||||
You can define a default error handler by passing a 2nd function as the 3rd argument to `hook`:
|
||||
```javascript
|
||||
Document.hook('set', function (path, val) {
|
||||
this[path] = val;
|
||||
}, function (err) {
|
||||
// Handler the error here
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
Then, we can pass errors to this handler from a pre or post middleware function:
|
||||
```javascript
|
||||
Document.pre('set', function (next, path, val) {
|
||||
next(new Error());
|
||||
});
|
||||
```
|
||||
|
||||
If you do not set up a default handler, then `hooks` makes the default handler that just throws the `Error`.
|
||||
|
||||
The default error handler can be over-rided on a per method invocation basis.
|
||||
|
||||
If the main method that you are surrounding with pre and post middleware expects its last argument to be a function
|
||||
with callback signature `function (error, ...)`, then that callback becomes the error handler, over-riding the default
|
||||
error handler you may have set up.
|
||||
|
||||
```javascript
|
||||
Document.hook('save', function (callback) {
|
||||
// Save logic goes here
|
||||
...
|
||||
});
|
||||
|
||||
var doc = new Document();
|
||||
doc.save( function (err, saved) {
|
||||
// We can pass err via `next` in any of our pre or post middleware functions
|
||||
if (err) console.error(err);
|
||||
|
||||
// Rest of callback logic follows ...
|
||||
});
|
||||
```
|
||||
|
||||
## Mutating Arguments via Middleware
|
||||
`pre` and `post` middleware can also accept the intended arguments for the method
|
||||
they augment. This is useful if you want to mutate the arguments before passing
|
||||
them along to the next middleware and eventually pass a mutated arguments list to
|
||||
the main method itself.
|
||||
|
||||
As a simple example, let's define a method `set` that just sets a key, value pair.
|
||||
If we want to namespace the key, we can do so by adding a `pre` middleware hook
|
||||
that runs before `set`, alters the arguments by namespacing the `key` argument, and passes them onto `set`:
|
||||
|
||||
```javascript
|
||||
Document.hook('set', function (key, val) {
|
||||
this[key] = val;
|
||||
});
|
||||
Document.pre('set', function (next, key, val) {
|
||||
next('namespace-' + key, val);
|
||||
});
|
||||
var doc = new Document();
|
||||
doc.set('hello', 'world');
|
||||
console.log(doc.hello); // undefined
|
||||
console.log(doc['namespace-hello']); // 'world'
|
||||
```
|
||||
|
||||
As you can see above, we pass arguments via `next`.
|
||||
|
||||
If you are not mutating the arguments, then you can pass zero arguments
|
||||
to `next`, and the next middleware function will still have access
|
||||
to the arguments.
|
||||
|
||||
```javascript
|
||||
Document.hook('set', function (key, val) {
|
||||
this[key] = val;
|
||||
});
|
||||
Document.pre('set', function (next, key, val) {
|
||||
// I have access to key and val here
|
||||
next(); // We don't need to pass anything to next
|
||||
});
|
||||
Document.pre('set', function (next, key, val) {
|
||||
// And I still have access to the original key and val here
|
||||
next();
|
||||
});
|
||||
```
|
||||
|
||||
Finally, you can add arguments that downstream middleware can also see:
|
||||
|
||||
```javascript
|
||||
// Note that in the definition of `set`, there is no 3rd argument, options
|
||||
Document.hook('set', function (key, val) {
|
||||
// But...
|
||||
var options = arguments[2]; // ...I have access to an options argument
|
||||
// because of pre function pre2 (defined below)
|
||||
console.log(options); // '{debug: true}'
|
||||
this[key] = val;
|
||||
});
|
||||
Document.pre('set', function pre1 (next, key, val) {
|
||||
// I only have access to key and val arguments
|
||||
console.log(arguments.length); // 3
|
||||
next(key, val, {debug: true});
|
||||
});
|
||||
Document.pre('set', function pre2 (next, key, val, options) {
|
||||
console.log(arguments.length); // 4
|
||||
console.log(options); // '{ debug: true}'
|
||||
next();
|
||||
});
|
||||
Document.pre('set', function pre3 (next, key, val, options) {
|
||||
// I still have access to key, val, AND the options argument introduced via the preceding middleware
|
||||
console.log(arguments.length); // 4
|
||||
console.log(options); // '{ debug: true}'
|
||||
next();
|
||||
});
|
||||
|
||||
var doc = new Document()
|
||||
doc.set('hey', 'there');
|
||||
```
|
||||
|
||||
## Post middleware
|
||||
|
||||
Post middleware intercepts the callback originally sent to the asynchronous function you have hooked to.
|
||||
|
||||
This means that the following chain of execution will occur in a typical `save` operation:
|
||||
|
||||
(1) doc.save -> (2) pre --(next)--> (3) save calls back -> (4) post --(next)--> (5) targetFn
|
||||
|
||||
Illustrated below:
|
||||
|
||||
```
|
||||
Document.pre('save', function (next) {
|
||||
this.key = "value";
|
||||
next();
|
||||
});
|
||||
// Post handler occurs before `set` calls back. This is useful if we need to grab something
|
||||
// async before `set` finishes.
|
||||
Document.post('set', function (next) {
|
||||
var me = this;
|
||||
getSomethingAsync(function(value){ // let's assume it returns "Hello Async"
|
||||
me.key2 = value;
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
var doc = new Document();
|
||||
doc.save(function(err){
|
||||
console.log(this.key); // "value" - this value was saved
|
||||
console.log(this.key2); // "Hello Async" - this value was *not* saved
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Post middleware must call `next()` or execution will stop.
|
||||
|
||||
## Parallel `pre` middleware
|
||||
|
||||
All middleware up to this point has been "serial" middleware -- i.e., middleware whose logic
|
||||
is executed as a serial chain.
|
||||
|
||||
Some scenarios call for parallel middleware -- i.e., middleware that can wait for several
|
||||
asynchronous services at once to respond.
|
||||
|
||||
For instance, you may only want to save a Document only after you have checked
|
||||
that the Document is valid according to two different remote services.
|
||||
|
||||
We accomplish asynchronous middleware by adding a second kind of flow control callback
|
||||
(the only flow control callback so far has been `next`), called `done`.
|
||||
|
||||
- `next` passes control to the next middleware in the chain
|
||||
- `done` keeps track of how many parallel middleware have invoked `done` and passes
|
||||
control to the target method when ALL parallel middleware have invoked `done`. If
|
||||
you pass an `Error` to `done`, then the error is handled, and the main method that is
|
||||
wrapped by pres and posts will not get invoked.
|
||||
|
||||
We declare pre middleware that is parallel by passing a 3rd boolean argument to our `pre`
|
||||
definition method.
|
||||
|
||||
We illustrate via the parallel validation example mentioned above:
|
||||
|
||||
```javascript
|
||||
Document.hook('save', function targetFn (callback) {
|
||||
// Save logic goes here
|
||||
// ...
|
||||
// This only gets run once the two `done`s are both invoked via preOne and preTwo.
|
||||
});
|
||||
|
||||
// true marks this as parallel middleware
|
||||
Document.pre('save', true, function preOne (next, doneOne, callback) {
|
||||
remoteServiceOne.validate(this.serialize(), function (err, isValid) {
|
||||
// The code in here will probably be run after the `next` below this block
|
||||
// and could possibly be run after the console.log("Hola") in `preTwo
|
||||
if (err) return doneOne(err);
|
||||
if (isValid) doneOne();
|
||||
});
|
||||
next(); // Pass control to the next middleware
|
||||
});
|
||||
|
||||
// We will suppose that we need 2 different remote services to validate our document
|
||||
Document.pre('save', true, function preTwo (next, doneTwo, callback) {
|
||||
remoteServiceTwo.validate(this.serialize(), function (err, isValid) {
|
||||
if (err) return doneTwo(err);
|
||||
if (isValid) doneTwo();
|
||||
});
|
||||
next();
|
||||
});
|
||||
|
||||
// While preOne and preTwo are parallel, preThree is a serial pre middleware
|
||||
Document.pre('save', function preThree (next, callback) {
|
||||
next();
|
||||
});
|
||||
|
||||
var doc = new Document();
|
||||
doc.save( function (err, doc) {
|
||||
// Do stuff with the saved doc here...
|
||||
});
|
||||
```
|
||||
|
||||
In the above example, flow control may happen in the following way:
|
||||
|
||||
(1) doc.save -> (2) preOne --(next)--> (3) preTwo --(next)--> (4) preThree --(next)--> (wait for dones to invoke) -> (5) doneTwo -> (6) doneOne -> (7) targetFn
|
||||
|
||||
So what's happening is that:
|
||||
|
||||
1. You call `doc.save(...)`
|
||||
2. First, your preOne middleware gets executed. It makes a remote call to the validation service and `next()`s to the preTwo middleware.
|
||||
3. Now, your preTwo middleware gets executed. It makes a remote call to another validation service and `next()`s to the preThree middleware.
|
||||
4. Your preThree middleware gets executed. It immediately `next()`s. But nothing else gets executing until both `doneOne` and `doneTwo` are invoked inside the callbacks handling the response from the two valiation services.
|
||||
5. We will suppose that validation remoteServiceTwo returns a response to us first. In this case, we call `doneTwo` inside the callback to remoteServiceTwo.
|
||||
6. Some fractions of a second later, remoteServiceOne returns a response to us. In this case, we call `doneOne` inside the callback to remoteServiceOne.
|
||||
7. `hooks` implementation keeps track of how many parallel middleware has been defined per target function. It detects that both asynchronous pre middlewares (`preOne` and `preTwo`) have finally called their `done` functions (`doneOne` and `doneTwo`), so the implementation finally invokes our `targetFn` (i.e., our core `save` business logic).
|
||||
|
||||
## Removing Pres
|
||||
|
||||
You can remove a particular pre associated with a hook:
|
||||
|
||||
Document.pre('set', someFn);
|
||||
Document.removePre('set', someFn);
|
||||
|
||||
And you can also remove all pres associated with a hook:
|
||||
Document.removePre('set'); // Removes all declared `pre`s on the hook 'set'
|
||||
|
||||
## Tests
|
||||
To run the tests:
|
||||
make test
|
||||
|
||||
### Contributors
|
||||
- [Brian Noguchi](https://github.com/bnoguchi)
|
||||
|
||||
### License
|
||||
MIT License
|
||||
|
||||
---
|
||||
### Author
|
||||
Brian Noguchi
|
||||
134
node_modules/hooks-fixed/hooks.alt.js
generated
vendored
Normal file
134
node_modules/hooks-fixed/hooks.alt.js
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Hooks are useful if we want to add a method that automatically has `pre` and `post` hooks.
|
||||
* For example, it would be convenient to have `pre` and `post` hooks for `save`.
|
||||
* _.extend(Model, mixins.hooks);
|
||||
* Model.hook('save', function () {
|
||||
* console.log('saving');
|
||||
* });
|
||||
* Model.pre('save', function (next, done) {
|
||||
* console.log('about to save');
|
||||
* next();
|
||||
* });
|
||||
* Model.post('save', function (next, done) {
|
||||
* console.log('saved');
|
||||
* next();
|
||||
* });
|
||||
*
|
||||
* var m = new Model();
|
||||
* m.save();
|
||||
* // about to save
|
||||
* // saving
|
||||
* // saved
|
||||
*/
|
||||
|
||||
// TODO Add in pre and post skipping options
|
||||
module.exports = {
|
||||
/**
|
||||
* Declares a new hook to which you can add pres and posts
|
||||
* @param {String} name of the function
|
||||
* @param {Function} the method
|
||||
* @param {Function} the error handler callback
|
||||
*/
|
||||
hook: function (name, fn, err) {
|
||||
if (arguments.length === 1 && typeof name === 'object') {
|
||||
for (var k in name) { // `name` is a hash of hookName->hookFn
|
||||
this.hook(k, name[k]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!err) err = fn;
|
||||
|
||||
var proto = this.prototype || this
|
||||
, pres = proto._pres = proto._pres || {}
|
||||
, posts = proto._posts = proto._posts || {};
|
||||
pres[name] = pres[name] || [];
|
||||
posts[name] = posts[name] || [];
|
||||
|
||||
function noop () {}
|
||||
|
||||
proto[name] = function () {
|
||||
var self = this
|
||||
, pres = this._pres[name]
|
||||
, posts = this._posts[name]
|
||||
, numAsyncPres = 0
|
||||
, hookArgs = [].slice.call(arguments)
|
||||
, preChain = pres.map( function (pre, i) {
|
||||
var wrapper = function () {
|
||||
if (arguments[0] instanceof Error)
|
||||
return err(arguments[0]);
|
||||
if (numAsyncPres) {
|
||||
// arguments[1] === asyncComplete
|
||||
if (arguments.length)
|
||||
hookArgs = [].slice.call(arguments, 2);
|
||||
pre.apply(self,
|
||||
[ preChain[i+1] || allPresInvoked,
|
||||
asyncComplete
|
||||
].concat(hookArgs)
|
||||
);
|
||||
} else {
|
||||
if (arguments.length)
|
||||
hookArgs = [].slice.call(arguments);
|
||||
pre.apply(self,
|
||||
[ preChain[i+1] || allPresDone ].concat(hookArgs));
|
||||
}
|
||||
}; // end wrapper = function () {...
|
||||
if (wrapper.isAsync = pre.isAsync)
|
||||
numAsyncPres++;
|
||||
return wrapper;
|
||||
}); // end posts.map(...)
|
||||
function allPresInvoked () {
|
||||
if (arguments[0] instanceof Error)
|
||||
err(arguments[0]);
|
||||
}
|
||||
|
||||
function allPresDone () {
|
||||
if (arguments[0] instanceof Error)
|
||||
return err(arguments[0]);
|
||||
if (arguments.length)
|
||||
hookArgs = [].slice.call(arguments);
|
||||
fn.apply(self, hookArgs);
|
||||
var postChain = posts.map( function (post, i) {
|
||||
var wrapper = function () {
|
||||
if (arguments[0] instanceof Error)
|
||||
return err(arguments[0]);
|
||||
if (arguments.length)
|
||||
hookArgs = [].slice.call(arguments);
|
||||
post.apply(self,
|
||||
[ postChain[i+1] || noop].concat(hookArgs));
|
||||
}; // end wrapper = function () {...
|
||||
return wrapper;
|
||||
}); // end posts.map(...)
|
||||
if (postChain.length) postChain[0]();
|
||||
}
|
||||
|
||||
if (numAsyncPres) {
|
||||
complete = numAsyncPres;
|
||||
function asyncComplete () {
|
||||
if (arguments[0] instanceof Error)
|
||||
return err(arguments[0]);
|
||||
--complete || allPresDone.call(this);
|
||||
}
|
||||
}
|
||||
(preChain[0] || allPresDone)();
|
||||
};
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
pre: function (name, fn, isAsync) {
|
||||
var proto = this.prototype
|
||||
, pres = proto._pres = proto._pres || {};
|
||||
if (fn.isAsync = isAsync) {
|
||||
this.prototype[name].numAsyncPres++;
|
||||
}
|
||||
(pres[name] = pres[name] || []).push(fn);
|
||||
return this;
|
||||
},
|
||||
post: function (name, fn, isAsync) {
|
||||
var proto = this.prototype
|
||||
, posts = proto._posts = proto._posts || {};
|
||||
(posts[name] = posts[name] || []).push(fn);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
191
node_modules/hooks-fixed/hooks.js
generated
vendored
Normal file
191
node_modules/hooks-fixed/hooks.js
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
// TODO Add in pre and post skipping options
|
||||
module.exports = {
|
||||
/**
|
||||
* Declares a new hook to which you can add pres and posts
|
||||
* @param {String} name of the function
|
||||
* @param {Function} the method
|
||||
* @param {Function} the error handler callback
|
||||
*/
|
||||
hook: function (name, fn, errorCb) {
|
||||
if (arguments.length === 1 && typeof name === 'object') {
|
||||
for (var k in name) { // `name` is a hash of hookName->hookFn
|
||||
this.hook(k, name[k]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var proto = this.prototype || this
|
||||
, pres = proto._pres = proto._pres || {}
|
||||
, posts = proto._posts = proto._posts || {};
|
||||
pres[name] = pres[name] || [];
|
||||
posts[name] = posts[name] || [];
|
||||
|
||||
proto[name] = function () {
|
||||
var self = this
|
||||
, hookArgs // arguments eventually passed to the hook - are mutable
|
||||
, lastArg = arguments[arguments.length-1]
|
||||
, pres = this._pres[name]
|
||||
, posts = this._posts[name]
|
||||
, _total = pres.length
|
||||
, _current = -1
|
||||
, _asyncsLeft = proto[name].numAsyncPres
|
||||
, _asyncsDone = function(err) {
|
||||
if (err) {
|
||||
return handleError(err);
|
||||
}
|
||||
--_asyncsLeft || _done.apply(self, hookArgs);
|
||||
}
|
||||
, handleError = function(err) {
|
||||
if ('function' == typeof lastArg)
|
||||
return lastArg(err);
|
||||
if (errorCb) return errorCb.call(self, err);
|
||||
throw err;
|
||||
}
|
||||
, _next = function () {
|
||||
if (arguments[0] instanceof Error) {
|
||||
return handleError(arguments[0]);
|
||||
}
|
||||
var _args = Array.prototype.slice.call(arguments)
|
||||
, currPre
|
||||
, preArgs;
|
||||
if (_args.length && !(arguments[0] == null && typeof lastArg === 'function'))
|
||||
hookArgs = _args;
|
||||
if (++_current < _total) {
|
||||
currPre = pres[_current]
|
||||
if (currPre.isAsync && currPre.length < 2)
|
||||
throw new Error("Your pre must have next and done arguments -- e.g., function (next, done, ...)");
|
||||
if (currPre.length < 1)
|
||||
throw new Error("Your pre must have a next argument -- e.g., function (next, ...)");
|
||||
preArgs = (currPre.isAsync
|
||||
? [once(_next), once(_asyncsDone)]
|
||||
: [once(_next)]).concat(hookArgs);
|
||||
return currPre.apply(self, preArgs);
|
||||
} else if (!_asyncsLeft) {
|
||||
return _done.apply(self, hookArgs);
|
||||
}
|
||||
}
|
||||
, _done = function () {
|
||||
var args_ = Array.prototype.slice.call(arguments)
|
||||
, ret, total_, current_, next_, done_, postArgs;
|
||||
|
||||
if (_current === _total) {
|
||||
|
||||
next_ = function () {
|
||||
if (arguments[0] instanceof Error) {
|
||||
return handleError(arguments[0]);
|
||||
}
|
||||
var args_ = Array.prototype.slice.call(arguments, 1)
|
||||
, currPost
|
||||
, postArgs;
|
||||
if (args_.length) hookArgs = args_;
|
||||
if (++current_ < total_) {
|
||||
currPost = posts[current_]
|
||||
if (currPost.length < 1)
|
||||
throw new Error("Your post must have a next argument -- e.g., function (next, ...)");
|
||||
postArgs = [once(next_)].concat(hookArgs);
|
||||
return currPost.apply(self, postArgs);
|
||||
} else if (typeof lastArg === 'function'){
|
||||
// All post handlers are done, call original callback function
|
||||
return lastArg.apply(self, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
// We are assuming that if the last argument provided to the wrapped function is a function, it was expecting
|
||||
// a callback. We trap that callback and wait to call it until all post handlers have finished.
|
||||
if(typeof lastArg === 'function'){
|
||||
args_[args_.length - 1] = once(next_);
|
||||
}
|
||||
|
||||
total_ = posts.length;
|
||||
current_ = -1;
|
||||
ret = fn.apply(self, args_); // Execute wrapped function, post handlers come afterward
|
||||
|
||||
if (total_ && typeof lastArg !== 'function') return next_(); // no callback provided, execute next_() manually
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
return _next.apply(this, arguments);
|
||||
};
|
||||
|
||||
proto[name].numAsyncPres = 0;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
pre: function (name, isAsync, fn, errorCb) {
|
||||
if ('boolean' !== typeof arguments[1]) {
|
||||
errorCb = fn;
|
||||
fn = isAsync;
|
||||
isAsync = false;
|
||||
}
|
||||
var proto = this.prototype || this
|
||||
, pres = proto._pres = proto._pres || {};
|
||||
|
||||
this._lazySetupHooks(proto, name, errorCb);
|
||||
|
||||
if (fn.isAsync = isAsync) {
|
||||
proto[name].numAsyncPres++;
|
||||
}
|
||||
|
||||
(pres[name] = pres[name] || []).push(fn);
|
||||
return this;
|
||||
},
|
||||
post: function (name, isAsync, fn) {
|
||||
if (arguments.length === 2) {
|
||||
fn = isAsync;
|
||||
isAsync = false;
|
||||
}
|
||||
var proto = this.prototype || this
|
||||
, posts = proto._posts = proto._posts || {};
|
||||
|
||||
this._lazySetupHooks(proto, name);
|
||||
(posts[name] = posts[name] || []).push(fn);
|
||||
return this;
|
||||
},
|
||||
removePre: function (name, fnToRemove) {
|
||||
var proto = this.prototype || this
|
||||
, pres = proto._pres || (proto._pres || {});
|
||||
if (!pres[name]) return this;
|
||||
if (arguments.length === 1) {
|
||||
// Remove all pre callbacks for hook `name`
|
||||
pres[name].length = 0;
|
||||
} else {
|
||||
pres[name] = pres[name].filter( function (currFn) {
|
||||
return currFn !== fnToRemove;
|
||||
});
|
||||
}
|
||||
return this;
|
||||
},
|
||||
removePost: function (name, fnToRemove) {
|
||||
var proto = this.prototype || this
|
||||
, posts = proto._posts || (proto._posts || {});
|
||||
if (!posts[name]) return this;
|
||||
if (arguments.length === 1) {
|
||||
// Remove all post callbacks for hook `name`
|
||||
posts[name].length = 0;
|
||||
} else {
|
||||
posts[name] = posts[name].filter( function (currFn) {
|
||||
return currFn !== fnToRemove;
|
||||
});
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
_lazySetupHooks: function (proto, methodName, errorCb) {
|
||||
if ('undefined' === typeof proto[methodName].numAsyncPres) {
|
||||
this.hook(methodName, proto[methodName], errorCb);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function once (fn, scope) {
|
||||
return function fnWrapper () {
|
||||
if (fnWrapper.hookCalled) return;
|
||||
fnWrapper.hookCalled = true;
|
||||
var ret = fn.apply(scope, arguments);
|
||||
if (ret && ret.then) {
|
||||
ret.then(function() {}, function() {});
|
||||
}
|
||||
};
|
||||
}
|
||||
91
node_modules/hooks-fixed/package.json
generated
vendored
Normal file
91
node_modules/hooks-fixed/package.json
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"hooks-fixed@1.1.0",
|
||||
"/home/mitchell/Desktop/test-mywebsite/mywebsite/node_modules/mongoose"
|
||||
]
|
||||
],
|
||||
"_from": "hooks-fixed@1.1.0",
|
||||
"_id": "hooks-fixed@1.1.0",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/hooks-fixed",
|
||||
"_nodeVersion": "0.12.3",
|
||||
"_npmUser": {
|
||||
"email": "val@karpov.io",
|
||||
"name": "vkarpov15"
|
||||
},
|
||||
"_npmVersion": "2.9.1",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "hooks-fixed",
|
||||
"raw": "hooks-fixed@1.1.0",
|
||||
"rawSpec": "1.1.0",
|
||||
"scope": null,
|
||||
"spec": "1.1.0",
|
||||
"type": "version"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/mongoose"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-1.1.0.tgz",
|
||||
"_shasum": "0e8c15336708e6611185fe390b44687dd5230dbb",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "hooks-fixed@1.1.0",
|
||||
"_where": "/home/mitchell/Desktop/test-mywebsite/mywebsite/node_modules/mongoose",
|
||||
"author": {
|
||||
"email": "brian.noguchi@gmail.com",
|
||||
"name": "Brian Noguchi",
|
||||
"url": "https://github.com/bnoguchi/"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/vkarpov15/hooks-fixed/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"description": "Adds pre and post hook functionality to your JavaScript methods.",
|
||||
"devDependencies": {
|
||||
"expresso": ">=0.7.6",
|
||||
"should": ">=0.2.1",
|
||||
"underscore": ">=1.1.4"
|
||||
},
|
||||
"directories": {
|
||||
"lib": "."
|
||||
},
|
||||
"dist": {
|
||||
"shasum": "0e8c15336708e6611185fe390b44687dd5230dbb",
|
||||
"tarball": "http://registry.npmjs.org/hooks-fixed/-/hooks-fixed-1.1.0.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
},
|
||||
"gitHead": "17ef258ae58d7aa6de7cec5b57f76233a4ba1c96",
|
||||
"homepage": "https://github.com/vkarpov15/hooks-fixed/",
|
||||
"keywords": [
|
||||
"hooks",
|
||||
"middleware",
|
||||
"node",
|
||||
"post",
|
||||
"pre"
|
||||
],
|
||||
"licenses": [
|
||||
"MIT"
|
||||
],
|
||||
"main": "./hooks.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "vkarpov15",
|
||||
"email": "valkar207@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "hooks-fixed",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/vkarpov15/hooks-fixed.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"version": "1.1.0"
|
||||
}
|
||||
786
node_modules/hooks-fixed/test.js
generated
vendored
Normal file
786
node_modules/hooks-fixed/test.js
generated
vendored
Normal file
@@ -0,0 +1,786 @@
|
||||
var hooks = require('./hooks')
|
||||
, should = require('should')
|
||||
, assert = require('assert')
|
||||
, _ = require('underscore');
|
||||
|
||||
// TODO Add in test for making sure all pres get called if pre is defined directly on an instance.
|
||||
// TODO Test for calling `done` twice or `next` twice in the same function counts only once
|
||||
module.exports = {
|
||||
'should be able to assign multiple hooks at once': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook({
|
||||
hook1: function (a) {},
|
||||
hook2: function (b) {}
|
||||
});
|
||||
var a = new A();
|
||||
assert.equal(typeof a.hook1, 'function');
|
||||
assert.equal(typeof a.hook2, 'function');
|
||||
},
|
||||
'should run without pres and posts when not present': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(1);
|
||||
},
|
||||
'should run with pres when present': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
A.pre('save', function (next) {
|
||||
this.preValue = 2;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(1);
|
||||
a.preValue.should.equal(2);
|
||||
},
|
||||
'should run with posts when present': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
A.post('save', function (next) {
|
||||
this.value = 2;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(2);
|
||||
},
|
||||
'should run pres and posts when present': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
A.pre('save', function (next) {
|
||||
this.preValue = 2;
|
||||
next();
|
||||
});
|
||||
A.post('save', function (next) {
|
||||
this.value = 3;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(3);
|
||||
a.preValue.should.equal(2);
|
||||
},
|
||||
'should run posts after pres': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
A.pre('save', function (next) {
|
||||
this.override = 100;
|
||||
next();
|
||||
});
|
||||
A.post('save', function (next) {
|
||||
this.override = 200;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(1);
|
||||
a.override.should.equal(200);
|
||||
},
|
||||
'should not run a hook if a pre fails': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
var counter = 0;
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
}, function (err) {
|
||||
counter++;
|
||||
});
|
||||
A.pre('save', true, function (next, done) {
|
||||
next(new Error());
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
counter.should.equal(1);
|
||||
assert.equal(typeof a.value, 'undefined');
|
||||
},
|
||||
'should be able to run multiple pres': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
A.pre('save', function (next) {
|
||||
this.v1 = 1;
|
||||
next();
|
||||
}).pre('save', function (next) {
|
||||
this.v2 = 2;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.v1.should.equal(1);
|
||||
a.v2.should.equal(2);
|
||||
},
|
||||
'should run multiple pres until a pre fails and not call the hook': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
}, function (err) {});
|
||||
A.pre('save', function (next) {
|
||||
this.v1 = 1;
|
||||
next();
|
||||
}).pre('save', function (next) {
|
||||
next(new Error());
|
||||
}).pre('save', function (next) {
|
||||
this.v3 = 3;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.v1.should.equal(1);
|
||||
assert.equal(typeof a.v3, 'undefined');
|
||||
assert.equal(typeof a.value, 'undefined');
|
||||
},
|
||||
'should be able to run multiple posts': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
A.post('save', function (next) {
|
||||
this.value = 2;
|
||||
next();
|
||||
}).post('save', function (next) {
|
||||
this.value = 3.14;
|
||||
next();
|
||||
}).post('save', function (next) {
|
||||
this.v3 = 3;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
assert.equal(a.value, 3.14);
|
||||
assert.equal(a.v3, 3);
|
||||
},
|
||||
'should run only posts up until an error': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
}, function (err) {});
|
||||
A.post('save', function (next) {
|
||||
this.value = 2;
|
||||
next();
|
||||
}).post('save', function (next) {
|
||||
this.value = 3;
|
||||
next(new Error());
|
||||
}).post('save', function (next) {
|
||||
this.value = 4;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(3);
|
||||
},
|
||||
"should fall back first to the hook method's last argument as the error handler if it is a function of arity 1 or 2": function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
var counter = 0;
|
||||
A.hook('save', function (callback) {
|
||||
this.value = 1;
|
||||
});
|
||||
A.pre('save', true, function (next, done) {
|
||||
next(new Error());
|
||||
});
|
||||
var a = new A();
|
||||
a.save( function (err) {
|
||||
if (err instanceof Error) counter++;
|
||||
});
|
||||
counter.should.equal(1);
|
||||
should.deepEqual(undefined, a.value);
|
||||
},
|
||||
'should fall back second to the default error handler if specified': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
var counter = 0;
|
||||
A.hook('save', function (callback) {
|
||||
this.value = 1;
|
||||
}, function (err) {
|
||||
if (err instanceof Error) counter++;
|
||||
});
|
||||
A.pre('save', true, function (next, done) {
|
||||
next(new Error());
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
counter.should.equal(1);
|
||||
should.deepEqual(undefined, a.value);
|
||||
},
|
||||
'fallback default error handler should scope to the object': function () {
|
||||
var A = function () {
|
||||
this.counter = 0;
|
||||
};
|
||||
_.extend(A, hooks);
|
||||
var counter = 0;
|
||||
A.hook('save', function (callback) {
|
||||
this.value = 1;
|
||||
}, function (err) {
|
||||
if (err instanceof Error) this.counter++;
|
||||
});
|
||||
A.pre('save', true, function (next, done) {
|
||||
next(new Error());
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.counter.should.equal(1);
|
||||
should.deepEqual(undefined, a.value);
|
||||
},
|
||||
'should fall back last to throwing the error': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
var counter = 0;
|
||||
A.hook('save', function (err) {
|
||||
if (err instanceof Error) return counter++;
|
||||
this.value = 1;
|
||||
});
|
||||
A.pre('save', true, function (next, done) {
|
||||
next(new Error());
|
||||
});
|
||||
var a = new A();
|
||||
var didCatch = false;
|
||||
try {
|
||||
a.save();
|
||||
} catch (e) {
|
||||
didCatch = true;
|
||||
e.should.be.an.instanceof(Error);
|
||||
counter.should.equal(0);
|
||||
assert.equal(typeof a.value, 'undefined');
|
||||
}
|
||||
didCatch.should.be.true;
|
||||
},
|
||||
"should proceed without mutating arguments if `next(null|undefined)` is called in a serial pre, and the last argument of the target method is a callback with node-like signature function (err, obj) {...} or function (err) {...}": function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
var counter = 0;
|
||||
A.prototype.save = function (callback) {
|
||||
this.value = 1;
|
||||
callback();
|
||||
};
|
||||
A.pre('save', function (next) {
|
||||
next(null);
|
||||
});
|
||||
A.pre('save', function (next) {
|
||||
next(undefined);
|
||||
});
|
||||
var a = new A();
|
||||
a.save( function (err) {
|
||||
if (err instanceof Error) counter++;
|
||||
else counter--;
|
||||
});
|
||||
counter.should.equal(-1);
|
||||
a.value.should.eql(1);
|
||||
},
|
||||
"should proceed with mutating arguments if `next(null|undefined)` is callback in a serial pre, and the last argument of the target method is not a function": function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.prototype.set = function (v) {
|
||||
this.value = v;
|
||||
};
|
||||
A.pre('set', function (next) {
|
||||
next(undefined);
|
||||
});
|
||||
A.pre('set', function (next) {
|
||||
next(null);
|
||||
});
|
||||
var a = new A();
|
||||
a.set(1);
|
||||
should.strictEqual(null, a.value);
|
||||
},
|
||||
'should not run any posts if a pre fails': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 2;
|
||||
}, function (err) {});
|
||||
A.pre('save', function (next) {
|
||||
this.value = 1;
|
||||
next(new Error());
|
||||
}).post('save', function (next) {
|
||||
this.value = 3;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(1);
|
||||
},
|
||||
|
||||
"can pass the hook's arguments verbatim to pres": function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('set', function (path, val) {
|
||||
this[path] = val;
|
||||
});
|
||||
A.pre('set', function (next, path, val) {
|
||||
path.should.equal('hello');
|
||||
val.should.equal('world');
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.set('hello', 'world');
|
||||
a.hello.should.equal('world');
|
||||
},
|
||||
// "can pass the hook's arguments as an array to pres": function () {
|
||||
// // Great for dynamic arity - e.g., slice(...)
|
||||
// var A = function () {};
|
||||
// _.extend(A, hooks);
|
||||
// A.hook('set', function (path, val) {
|
||||
// this[path] = val;
|
||||
// });
|
||||
// A.pre('set', function (next, hello, world) {
|
||||
// hello.should.equal('hello');
|
||||
// world.should.equal('world');
|
||||
// next();
|
||||
// });
|
||||
// var a = new A();
|
||||
// a.set('hello', 'world');
|
||||
// assert.equal(a.hello, 'world');
|
||||
// },
|
||||
"can pass the hook's arguments verbatim to posts": function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('set', function (path, val) {
|
||||
this[path] = val;
|
||||
});
|
||||
A.post('set', function (next, path, val) {
|
||||
path.should.equal('hello');
|
||||
val.should.equal('world');
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.set('hello', 'world');
|
||||
assert.equal(a.hello, 'world');
|
||||
},
|
||||
// "can pass the hook's arguments as an array to posts": function () {
|
||||
// var A = function () {};
|
||||
// _.extend(A, hooks);
|
||||
// A.hook('set', function (path, val) {
|
||||
// this[path] = val;
|
||||
// });
|
||||
// A.post('set', function (next, halt, args) {
|
||||
// assert.equal(args[0], 'hello');
|
||||
// assert.equal(args[1], 'world');
|
||||
// next();
|
||||
// });
|
||||
// var a = new A();
|
||||
// a.set('hello', 'world');
|
||||
// assert.equal(a.hello, 'world');
|
||||
// },
|
||||
"pres should be able to modify and pass on a modified version of the hook's arguments": function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('set', function (path, val) {
|
||||
this[path] = val;
|
||||
assert.equal(arguments[2], 'optional');
|
||||
});
|
||||
A.pre('set', function (next, path, val) {
|
||||
next('foo', 'bar');
|
||||
});
|
||||
A.pre('set', function (next, path, val) {
|
||||
assert.equal(path, 'foo');
|
||||
assert.equal(val, 'bar');
|
||||
next('rock', 'says', 'optional');
|
||||
});
|
||||
A.pre('set', function (next, path, val, opt) {
|
||||
assert.equal(path, 'rock');
|
||||
assert.equal(val, 'says');
|
||||
assert.equal(opt, 'optional');
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.set('hello', 'world');
|
||||
assert.equal(typeof a.hello, 'undefined');
|
||||
a.rock.should.equal('says');
|
||||
},
|
||||
'posts should see the modified version of arguments if the pres modified them': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('set', function (path, val) {
|
||||
this[path] = val;
|
||||
});
|
||||
A.pre('set', function (next, path, val) {
|
||||
next('foo', 'bar');
|
||||
});
|
||||
A.post('set', function (next, path, val) {
|
||||
path.should.equal('foo');
|
||||
val.should.equal('bar');
|
||||
});
|
||||
var a = new A();
|
||||
a.set('hello', 'world');
|
||||
assert.equal(typeof a.hello, 'undefined');
|
||||
a.foo.should.equal('bar');
|
||||
},
|
||||
'should pad missing arguments (relative to expected arguments of the hook) with null': function () {
|
||||
// Otherwise, with hookFn = function (a, b, next, ),
|
||||
// if we use hookFn(a), then because the pre functions are of the form
|
||||
// preFn = function (a, b, next, ), then it actually gets executed with
|
||||
// preFn(a, next, ), so when we call next() from within preFn, we are actually
|
||||
// calling ()
|
||||
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('set', function (path, val, opts) {
|
||||
this[path] = val;
|
||||
});
|
||||
A.pre('set', function (next, path, val, opts) {
|
||||
next('foo', 'bar');
|
||||
assert.equal(typeof opts, 'undefined');
|
||||
});
|
||||
var a = new A();
|
||||
a.set('hello', 'world');
|
||||
},
|
||||
|
||||
'should not invoke the target method until all asynchronous middleware have invoked dones': function () {
|
||||
var counter = 0;
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('set', function (path, val) {
|
||||
counter++;
|
||||
this[path] = val;
|
||||
counter.should.equal(7);
|
||||
});
|
||||
A.pre('set', function (next, path, val) {
|
||||
counter++;
|
||||
next();
|
||||
});
|
||||
A.pre('set', true, function (next, done, path, val) {
|
||||
counter++;
|
||||
setTimeout(function () {
|
||||
counter++;
|
||||
done();
|
||||
}, 1000);
|
||||
next();
|
||||
});
|
||||
A.pre('set', function (next, path, val) {
|
||||
counter++;
|
||||
next();
|
||||
});
|
||||
A.pre('set', true, function (next, done, path, val) {
|
||||
counter++;
|
||||
setTimeout(function () {
|
||||
counter++;
|
||||
done();
|
||||
}, 500);
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.set('hello', 'world');
|
||||
},
|
||||
|
||||
'invoking a method twice should run its async middleware twice': function () {
|
||||
var counter = 0;
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('set', function (path, val) {
|
||||
this[path] = val;
|
||||
if (path === 'hello') counter.should.equal(1);
|
||||
if (path === 'foo') counter.should.equal(2);
|
||||
});
|
||||
A.pre('set', true, function (next, done, path, val) {
|
||||
setTimeout(function () {
|
||||
counter++;
|
||||
done();
|
||||
}, 1000);
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.set('hello', 'world');
|
||||
a.set('foo', 'bar');
|
||||
},
|
||||
|
||||
'calling the same done multiple times should have the effect of only calling it once': function () {
|
||||
var A = function () {
|
||||
this.acked = false;
|
||||
};
|
||||
_.extend(A, hooks);
|
||||
A.hook('ack', function () {
|
||||
console.log("UH OH, YOU SHOULD NOT BE SEEING THIS");
|
||||
this.acked = true;
|
||||
});
|
||||
A.pre('ack', true, function (next, done) {
|
||||
next();
|
||||
done();
|
||||
done();
|
||||
});
|
||||
A.pre('ack', true, function (next, done) {
|
||||
next();
|
||||
// Notice that done() is not invoked here
|
||||
});
|
||||
var a = new A();
|
||||
a.ack();
|
||||
setTimeout( function () {
|
||||
a.acked.should.be.false;
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
'calling the same next multiple times should have the effect of only calling it once': function (beforeExit) {
|
||||
var A = function () {
|
||||
this.acked = false;
|
||||
};
|
||||
_.extend(A, hooks);
|
||||
A.hook('ack', function () {
|
||||
console.log("UH OH, YOU SHOULD NOT BE SEEING THIS");
|
||||
this.acked = true;
|
||||
});
|
||||
A.pre('ack', function (next) {
|
||||
// force a throw to re-exec next()
|
||||
try {
|
||||
next(new Error('bam'));
|
||||
} catch (err) {
|
||||
next();
|
||||
}
|
||||
});
|
||||
A.pre('ack', function (next) {
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.ack();
|
||||
beforeExit( function () {
|
||||
a.acked.should.be.false;
|
||||
});
|
||||
},
|
||||
|
||||
'asynchronous middleware should be able to pass an error via `done`, stopping the middleware chain': function () {
|
||||
var counter = 0;
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('set', function (path, val, fn) {
|
||||
counter++;
|
||||
this[path] = val;
|
||||
fn(null);
|
||||
});
|
||||
A.pre('set', true, function (next, done, path, val, fn) {
|
||||
setTimeout(function () {
|
||||
counter++;
|
||||
done(new Error);
|
||||
}, 1000);
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.set('hello', 'world', function (err) {
|
||||
err.should.be.an.instanceof(Error);
|
||||
should.strictEqual(undefined, a['hello']);
|
||||
counter.should.eql(1);
|
||||
});
|
||||
},
|
||||
|
||||
'should be able to remove a particular pre': function () {
|
||||
var A = function () {}
|
||||
, preTwo;
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
A.pre('save', function (next) {
|
||||
this.preValueOne = 2;
|
||||
next();
|
||||
});
|
||||
A.pre('save', preTwo = function (next) {
|
||||
this.preValueTwo = 4;
|
||||
next();
|
||||
});
|
||||
A.removePre('save', preTwo);
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(1);
|
||||
a.preValueOne.should.equal(2);
|
||||
should.strictEqual(undefined, a.preValueTwo);
|
||||
},
|
||||
|
||||
'should be able to remove all pres associated with a hook': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
A.pre('save', function (next) {
|
||||
this.preValueOne = 2;
|
||||
next();
|
||||
});
|
||||
A.pre('save', function (next) {
|
||||
this.preValueTwo = 4;
|
||||
next();
|
||||
});
|
||||
A.removePre('save');
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(1);
|
||||
should.strictEqual(undefined, a.preValueOne);
|
||||
should.strictEqual(undefined, a.preValueTwo);
|
||||
},
|
||||
|
||||
'should be able to remove a particular post': function () {
|
||||
var A = function () {}
|
||||
, postTwo;
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
A.post('save', function (next) {
|
||||
this.postValueOne = 2;
|
||||
next();
|
||||
});
|
||||
A.post('save', postTwo = function (next) {
|
||||
this.postValueTwo = 4;
|
||||
next();
|
||||
});
|
||||
A.removePost('save', postTwo);
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(1);
|
||||
a.postValueOne.should.equal(2);
|
||||
should.strictEqual(undefined, a.postValueTwo);
|
||||
},
|
||||
|
||||
'should be able to remove all posts associated with a hook': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function () {
|
||||
this.value = 1;
|
||||
});
|
||||
A.post('save', function (next) {
|
||||
this.postValueOne = 2;
|
||||
next();
|
||||
});
|
||||
A.post('save', function (next) {
|
||||
this.postValueTwo = 4;
|
||||
next();
|
||||
});
|
||||
A.removePost('save');
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(1);
|
||||
should.strictEqual(undefined, a.postValueOne);
|
||||
should.strictEqual(undefined, a.postValueTwo);
|
||||
},
|
||||
|
||||
'#pre should lazily make a method hookable': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.prototype.save = function () {
|
||||
this.value = 1;
|
||||
};
|
||||
A.pre('save', function (next) {
|
||||
this.preValue = 2;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(1);
|
||||
a.preValue.should.equal(2);
|
||||
},
|
||||
|
||||
'#pre lazily making a method hookable should be able to provide a default errorHandler as the last argument': function () {
|
||||
var A = function () {};
|
||||
var preValue = "";
|
||||
_.extend(A, hooks);
|
||||
A.prototype.save = function () {
|
||||
this.value = 1;
|
||||
};
|
||||
A.pre('save', function (next) {
|
||||
next(new Error);
|
||||
}, function (err) {
|
||||
preValue = 'ERROR';
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
should.strictEqual(undefined, a.value);
|
||||
preValue.should.equal('ERROR');
|
||||
},
|
||||
|
||||
'#post should lazily make a method hookable': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.prototype.save = function () {
|
||||
this.value = 1;
|
||||
};
|
||||
A.post('save', function (next) {
|
||||
this.value = 2;
|
||||
next();
|
||||
});
|
||||
var a = new A();
|
||||
a.save();
|
||||
a.value.should.equal(2);
|
||||
},
|
||||
|
||||
"a lazy hooks setup should handle errors via a method's last argument, if it's a callback": function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.prototype.save = function (fn) {};
|
||||
A.pre('save', function (next) {
|
||||
next(new Error("hi there"));
|
||||
});
|
||||
var a = new A();
|
||||
a.save( function (err) {
|
||||
err.should.be.an.instanceof(Error);
|
||||
});
|
||||
},
|
||||
|
||||
'should intercept method callbacks for post handlers': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function (val, callback) {
|
||||
this.value = val;
|
||||
callback();
|
||||
});
|
||||
A.post('save', function (next) {
|
||||
assert.equal(a.value, 2);
|
||||
this.value += 2;
|
||||
setTimeout(next, 10);
|
||||
}).post('save', function (next) {
|
||||
assert.equal(a.value, 4);
|
||||
this.value += 3;
|
||||
setTimeout(next, 10);
|
||||
}).post('save', function (next) {
|
||||
assert.equal(a.value, 7);
|
||||
this.value2 = 3;
|
||||
setTimeout(next, 10);
|
||||
});
|
||||
var a = new A();
|
||||
a.save(2, function(){
|
||||
assert.equal(a.value, 7);
|
||||
assert.equal(a.value2, 3);
|
||||
});
|
||||
},
|
||||
|
||||
'should handle parallel followed by serial': function () {
|
||||
var A = function () {};
|
||||
_.extend(A, hooks);
|
||||
A.hook('save', function (val, callback) {
|
||||
this.value = val;
|
||||
callback();
|
||||
});
|
||||
A.pre('save', true, function(next, done) {
|
||||
process.nextTick(function() {
|
||||
done();
|
||||
});
|
||||
next();
|
||||
}).pre('save', function(done) {
|
||||
process.nextTick(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
var a = new A();
|
||||
a.save(2, function(){
|
||||
assert.ok(true);
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user