Merge branch 'UziTech-remove-evil'

- Merges #1330 from @UziTech
- Fixes #1325
This commit is contained in:
Gregg Van Hove
2017-04-26 13:35:16 -07:00
2 changed files with 32 additions and 32 deletions

View File

@@ -4222,15 +4222,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,
@@ -4259,14 +4254,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) {

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) {