Skip to content

Commit

Permalink
Fix issues with reverting nested properties
Browse files Browse the repository at this point in the history
Fixes #39
  • Loading branch information
jhnns committed Feb 5, 2015
1 parent 972972e commit 75ebdd4
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
13 changes: 7 additions & 6 deletions lib/__set__.js
Expand Up @@ -13,35 +13,36 @@ function __set__() {
arguments.varName = arguments[0];
arguments.varValue = arguments[1];
arguments.src = "";
arguments.snapshot = {};
arguments.revertArgs = [];

if (typeof arguments[0] === "object" && arguments.length === 1) {
arguments.env = arguments.varName;
if (!arguments.env || Array.isArray(arguments.env)) {
throw new 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." + arguments.varName + "; ";
arguments.snapshot[arguments.varName] = eval(arguments.varName);
arguments.revertArgs[0][arguments.varName] = eval(arguments.varName);
}
}
} else if (typeof arguments.varName === "string" && arguments.length === 2) {
if (!arguments.varName) {
throw new TypeError("__set__ expects a non-empty string as a variable name");
}
arguments.src = arguments.varName + " = arguments.varValue;";
arguments.snapshot[arguments.varName] = eval(arguments.varName);
arguments.revertArgs = [arguments.varName, eval(arguments.varName)];
} else {
throw new TypeError("__set__ expects an environment object or a non-empty string as a variable name");
}

eval(arguments.src);

return function (snapshot) {
module.exports.__set__(snapshot);
}.bind(null, arguments.snapshot);
return function (revertArgs) {
__set__.apply(null, revertArgs);
}.bind(null, arguments.revertArgs);
}

module.exports = __set__;
21 changes: 20 additions & 1 deletion test/testModules/sharedTestCases.js
Expand Up @@ -267,4 +267,23 @@ describe("rewire " + (typeof testEnv === "undefined"? "(node)": "(" + testEnv +
}).to.throwException(checkForTypeError);
});

});
it("should also revert nested changes (with dot notation)", function () {
var rewiredModuleA = rewire("./moduleA.js"),
revert;

revert = rewiredModuleA.__set__("myObj.test", true);
expect(rewiredModuleA.getMyObj()).to.eql({
test: true
});
revert();
// This test also demonstrates a known drawback of the current implementation
// If the value doesn't exist at the time it is about to be set, it will be
// reverted to undefined instead deleting it from the object
// However, this is probably not a real world use-case because why would you
// want to mock something when it is not set.
expect(rewiredModuleA.getMyObj()).to.eql({
test: undefined
});
});

});

0 comments on commit 75ebdd4

Please sign in to comment.