diff --git a/lib/__set__.js b/lib/__set__.js index bdb5042..3e66b42 100644 --- a/lib/__set__.js +++ b/lib/__set__.js @@ -12,19 +12,30 @@ function __set__() { arguments.varName = arguments[0]; arguments.varValue = arguments[1]; + // Saving references to global objects and functions. Thus a test may even change these variables + // without interfering with rewire(). + // @see https://github.com/jhnns/rewire/issues/40 + arguments.refs = arguments[2] || { + isArray: Array.isArray, + TypeError: TypeError, + stringify: JSON.stringify + // We can't save eval() because eval() is a *special* global function + // That's why it can't be re-assigned in strict mode + //eval: eval + }; arguments.src = ""; arguments.revertArgs = []; - if (typeof arguments[0] === "object" && arguments.length === 1) { + if (typeof arguments[0] === "object") { arguments.env = arguments.varName; - if (!arguments.env || Array.isArray(arguments.env)) { - throw new TypeError("__set__ expects an object as env"); + if (!arguments.env || arguments.refs.isArray(arguments.env)) { + throw new arguments.refs.TypeError("__set__ expects an object as env"); } arguments.revertArgs[0] = {}; for (arguments.varName in arguments.env) { if (arguments.env.hasOwnProperty(arguments.varName)) { arguments.varValue = arguments.env[arguments.varName]; - arguments.src += arguments.varName + " = arguments.env[" + JSON.stringify(arguments.varName) + "]; "; + arguments.src += arguments.varName + " = arguments.env[" + arguments.refs.stringify(arguments.varName) + "]; "; try { // Allow tests to mock implicit globals // @see https://github.com/jhnns/rewire/issues/35 @@ -34,9 +45,9 @@ function __set__() { } } } - } else if (typeof arguments.varName === "string" && arguments.length === 2) { + } else if (typeof arguments.varName === "string") { if (!arguments.varName) { - throw new TypeError("__set__ expects a non-empty string as a variable name"); + throw new arguments.refs.TypeError("__set__ expects a non-empty string as a variable name"); } arguments.src = arguments.varName + " = arguments.varValue;"; try { @@ -47,9 +58,12 @@ function __set__() { arguments.revertArgs = [arguments.varName, undefined]; } } else { - throw new TypeError("__set__ expects an environment object or a non-empty string as a variable name"); + throw new arguments.refs.TypeError("__set__ expects an environment object or a non-empty string as a variable name"); } + // Passing our saved references on to the revert function + arguments.revertArgs[2] = arguments.refs; + eval(arguments.src); return function (revertArgs) { diff --git a/test/__set__.test.js b/test/__set__.test.js index ef69a07..efd1eeb 100644 --- a/test/__set__.test.js +++ b/test/__set__.test.js @@ -121,11 +121,5 @@ describe("__set__", function () { expect(function () { moduleFake.__set__(function () {}); }).to.throwException(expectTypeError); - expect(function () { - moduleFake.__set__({}, true); // misfitting number of params - }).to.throwException(expectTypeError); - expect(function () { - moduleFake.__set__("someVar"); // misfitting number of params - }).to.throwException(expectTypeError); }); -}); \ No newline at end of file +}); diff --git a/test/testModules/sharedTestCases.js b/test/testModules/sharedTestCases.js index 76498bd..7048ba8 100644 --- a/test/testModules/sharedTestCases.js +++ b/test/testModules/sharedTestCases.js @@ -337,4 +337,17 @@ describe("rewire " + (typeof testEnv === "undefined"? "(node)": "(" + testEnv + } }); + it("should be possible to mock and revert JSON.parse (see #40)", function () { + var moduleA = rewire("./moduleA.js"), + revert; + + revert = moduleA.__set__({ + JSON: { + parse: function () { return true; } + } + }); + + revert(); + }); + });