lib/jspec.js in visionmedia-jspec-2.8.2 vs lib/jspec.js in visionmedia-jspec-2.8.3

- old
+ new

@@ -3,11 +3,11 @@ (function(){ JSpec = { - version : '2.8.2', + version : '2.8.3', cache : {}, suites : [], modules : [], allSuites : [], matchers : {}, @@ -644,15 +644,36 @@ hook : function(name, args) { args = argumentsToArray(arguments, 1) return inject(JSpec.modules, [], function(results, module){ if (typeof module[name] == 'function') - results.push(module[name].apply(this, args)) + results.push(JSpec.evalHook(module, name, args)) }) }, /** + * Eval _module_ hook _name_ with _args_. Evaluates in context + * to the module itself, JSpec, and JSpec.context. + * + * @param {Module} module + * @param {string} name + * @param {array} args + * @return {mixed} + * @api private + */ + + evalHook : function(module, name, args) { + var context = this.context || this.defaultContext + var contents = this.contentsOf(module[name]) + var params = this.paramsFor(module[name]) + params.unshift('context'); args.unshift(context) + hook('evaluatingHookBody', module, name, context) + try { return new Function(params.join(), 'with (this.utilities) { with (context) { with (JSpec) { ' + contents + ' }}}').apply(module, args) } + catch(e) { error('Error in hook ' + module.name + "." + name + ': ', e) } + }, + + /** * Same as hook() however accepts only one _arg_ which is * considered immutable. This function passes the arg * to the first module, then passes the return value of the last * module called, to the following module. * @@ -663,11 +684,11 @@ */ hookImmutable : function(name, arg) { return inject(JSpec.modules, arg, function(result, module){ if (typeof module[name] == 'function') - return module[name].call(this, result) + return JSpec.evalHook(module, name, [result]) }) }, /** * Find a suite by its description or name. @@ -1223,10 +1244,22 @@ */ contentsOf : function(body) { return body.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1] }, + + /** + * Return param names for a function body. + * + * @param {function} body + * @return {array} + * @api public + */ + + paramsFor : function(body) { + return body.toString().match(/\((.*?)\)/)[1].match(/[\w]+/g) || [] + }, /** * Evaluate a JSpec capture body. * * @param {function} body @@ -1350,10 +1383,9 @@ */ fail : function(message) { JSpec.currentSpec.fail(message) }, - /** * Report a passing assertion for the current spec. * * @param {string} message \ No newline at end of file