remove eval to create spy wrapper

This commit is contained in:
Tony Brix
2017-04-25 15:21:23 -05:00
committed by Gregg Van Hove
parent b771c083cb
commit 686d8157e5
+16 -16
View File
@@ -14,15 +14,10 @@ getJasmineRequireObj().Spy = function (j$) {
* @name Spy * @name Spy
*/ */
function Spy(name, originalFn) { function Spy(name, originalFn) {
var args = buildArgs(), var numArgs = (typeof originalFn === 'function' ? originalFn.length : 0),
/*`eval` is the only option to preserve both this and context: wrapper = makeFunc(numArgs, function () {
- former is needed to work as expected with methods, return spy.apply(this, Array.prototype.slice.call(arguments));
- latter is needed to access real spy function and allows to reduce eval'ed code to absolute minimum }),
More explanation here (look at comments): http://www.bennadel.com/blog/1909-javascript-function-constructor-does-not-create-a-closure.htm
*/
/* jshint evil: true */
wrapper = eval('(0, function (' + args + ') { return spy.apply(this, Array.prototype.slice.call(arguments)); })'),
/* jshint evil: false */
spyStrategy = new j$.SpyStrategy({ spyStrategy = new j$.SpyStrategy({
name: name, name: name,
fn: originalFn, fn: originalFn,
@@ -51,14 +46,19 @@ getJasmineRequireObj().Spy = function (j$) {
return returnValue; return returnValue;
}; };
function buildArgs() { function makeFunc(length, fn) {
var args = []; switch (length) {
case 1 : return function (a) { return fn.apply(this, arguments); };
while (originalFn instanceof Function && args.length < originalFn.length) { case 2 : return function (a,b) { return fn.apply(this, arguments); };
args.push('arg' + args.length); case 3 : return function (a,b,c) { return fn.apply(this, arguments); };
case 4 : return function (a,b,c,d) { return fn.apply(this, arguments); };
case 5 : return function (a,b,c,d,e) { return fn.apply(this, arguments); };
case 6 : return function (a,b,c,d,e,f) { return fn.apply(this, arguments); };
case 7 : return function (a,b,c,d,e,f,g) { return fn.apply(this, arguments); };
case 8 : return function (a,b,c,d,e,f,g,h) { return fn.apply(this, arguments); };
case 9 : return function (a,b,c,d,e,f,g,h,i) { return fn.apply(this, arguments); };
default : return function () { return fn.apply(this, arguments); };
} }
return args.join(', ');
} }
for (var prop in originalFn) { for (var prop in originalFn) {