From 141cfec3be41780169854e48d2c2a254f630cc0a Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 4 Jun 2012 14:35:06 +0200 Subject: introduced require.reset() --- README.md | 50 ++++++++++++++++++++++++++++++++------------ lib/index.js | 2 ++ lib/rewire.js | 20 +++++++++++++++--- test/getInjectionSrc.test.js | 2 +- test/getLeakingSrc.test.js | 2 +- test/rewire.test.js | 12 +++++++++-- 6 files changed, 68 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 48c708a..3a83cfb 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ rewire does **not** load the file and eval the contents to emulate node's requir Installation ------------ -```npm install rewire``` +`npm install rewire` ----------------------------------------------------------------- @@ -45,8 +45,9 @@ var mockedModuleB = {}, "path/to/moduleB.js": mockedModuleB }; -// The rewired module will now use your mocks instead of fs and moduleB.js. -// Just make sure that the path is exactly as in myModuleA.js required. +// The rewired module will now use your mocks instead of fs +// and moduleB.js. Just make sure that the path is exactly as +// in myModuleA.js required. rewiredModule = rewire("./myModuleA.js", mocks); @@ -70,7 +71,8 @@ var injections = { rewiredModule = rewire("./myModuleA.js", null, injections); // You can also pass a script to inject -rewiredModule = rewire("./myModuleA.js", null, "console.log('hellooo');"); // prints "hellooo" +rewiredModule = + rewire("./myModuleA.js", null, "console.log('hellooo');"); // prints "hellooo" @@ -88,22 +90,44 @@ rewiredModule.__.myPrivateVar2; // returns former private myPrivateVar2 // Cache //////////////////////////////// // By disabling the module cache the rewired module will not be cached. -// Any later require()-calls within other modules will now return the original -// module again instead of the rewired. Caching is enabled by default. -rewire("./myModuleA.js", null, null, null, false) !== require("./myModuleA.js"); // = true +// Any require()-calls will now return the original module again instead +// of the rewired. Caching is enabled by default. +rewire("./myModuleA.js", null, null, null, false) !== + require("./myModuleA.js"); // = true + +// This removes all rewired modules from require.cache. +rewire.reset(); +// IMPORTANT: You should call this before every unit test to ensure +// a clean test environment. ``` ----------------------------------------------------------------- ##API -**rewire(***filename, mocks, injections, leaks, cache***)** +**rewire(***filename, mocks, injections, leaks, cache***)** -- *{!String} filename*: Path to the module that shall be rewired. Use it exactly like require(). -- *{Object} mocks (optional)*: An object with mocks. Keys should be the exactly the same like they're required in the target module. So if you write ```require("../../myModules/myModuleA.js")``` you need to pass ```{"../../myModules/myModuleA.js": myModuleAMock}```. -- *{Object|String} injections (optional)*: If you pass an object, all keys of the object will be ```var```s within the module. You can also eval a string. **Please note**: All scripts are injected at the end of the module. So if there is any code in your module that is executed during ```require()```, your injected variables will be undefined at this point. For example: passing ```{console: null}``` will cause all calls of ```console.log()``` to throw an exception if they're executed during ```require()```. -- *{Array<String>} leaks (optional)*: An array with variable names that should be exported. These variables are accessible via ```myModule.__``` -- *{Boolean=true} cache (optional)*: Indicates whether the rewired module should be cached by node so subsequent calls of ```require()``` will return the rewired module. Further calls of ```rewire()``` will always overwrite the cache. +Returns the rewired module. + +- *{!String} filename*:
+Path to the module that shall be rewired. Use it exactly like require(). + +- *{Object} mocks (optional)*:
+An object with mocks. Keys should be the exactly the same like they're required in the target module. So if you write `require("../../myModules/myModuleA.js")` you need to pass `{"../../myModules/myModuleA.js": myModuleAMock}`. + +- *{Object|String} injections (optional)*:
+If you pass an object, all keys of the object will be `var`s within the module. You can also eval a string. **Please note**: All scripts are injected at the end of the module. So if there is any code in your module that is executed during `require()`, your injected variables will be undefined at this point. For example: passing `{console: null}` will cause all calls of `console.log()` to throw an exception if they're executed during `require()`. + +- *{Array<String>} leaks (optional)*:
+An array with variable names that should be exported. These variables are accessible via `myModule.__` + + +- *{Boolean=true} cache (optional)*:
+Indicates whether the rewired module should be cached by node so subsequent calls of `require()` will return the rewired module. Further calls of `rewire()` will always overwrite the cache. + +**rewire.reset()** + +Removes all rewired modules from `require.cache`. Every `require()` will now return the original module again.
**Please note:** You should call this before every unit test to ensure a clean test environment. ----------------------------------------------------------------- diff --git a/lib/index.js b/lib/index.js index 321b65c..8be8897 100644 --- a/lib/index.js +++ b/lib/index.js @@ -23,4 +23,6 @@ function rewire(request, mocks, injections, leaks, cache) { return rewireModule(module.parent, request, mocks, injections, leaks, cache); } +rewire.reset = rewireModule.reset; + module.exports = rewire; \ No newline at end of file diff --git a/lib/rewire.js b/lib/rewire.js index 6834494..3de8418 100644 --- a/lib/rewire.js +++ b/lib/rewire.js @@ -4,7 +4,8 @@ var Module = require("module"), nodeWrapper0 = Module.wrapper[0], // caching original wrapper nodeWrapper1 = Module.wrapper[1], getLeakingSrc = require("./getLeakingSrc.js"), - getInjectionSrc = require("./getInjectionSrc.js"); + getInjectionSrc = require("./getInjectionSrc.js"), + rewiredModules = []; function restoreOriginalWrappers() { Module.wrapper[1] = nodeWrapper1; @@ -13,7 +14,7 @@ function restoreOriginalWrappers() { /** * Does actual rewiring the module. For further documentation @see index.js */ -module.exports = function doRewire(parentModule, filename, mocks, injections, leaks, cache) { +function rewire(parentModule, filename, mocks, injections, leaks, cache) { var testModule, nodeRequire, wrapperExtensions = ""; @@ -58,9 +59,22 @@ module.exports = function doRewire(parentModule, filename, mocks, injections, le if (cache) { require.cache[filename] = testModule; + rewiredModules.push(filename); // save in private cache for .reset() } restoreOriginalWrappers(); // this is only necessary if nothing has been required within the module return testModule.exports; -}; \ No newline at end of file +} + +rewire.reset = function () { + var i; + + for (i = 0; i < rewiredModules.length; i++) { + delete require.cache[rewiredModules[i]]; + } + + rewiredModules = []; +}; + +module.exports = rewire; \ No newline at end of file diff --git a/test/getInjectionSrc.test.js b/test/getInjectionSrc.test.js index 0ec9a49..356b00d 100644 --- a/test/getInjectionSrc.test.js +++ b/test/getInjectionSrc.test.js @@ -3,7 +3,7 @@ var expect = require("expect.js"), getInjectionSrc = require("../lib/getInjectionSrc.js"); -describe("#getMonkeyPatchSrc", function () { +describe("getMonkeyPatchSrc", function () { it("should return ''", function () { var expectedSrc = "", subject = {}; diff --git a/test/getLeakingSrc.test.js b/test/getLeakingSrc.test.js index cc215ea..c9a595f 100644 --- a/test/getLeakingSrc.test.js +++ b/test/getLeakingSrc.test.js @@ -3,7 +3,7 @@ var expect = require("expect.js"), getLeakingWrapper = require("../lib/getLeakingSrc.js"); -describe("#getLeakingWrapper", function () { +describe("getLeakingWrapper", function () { it("should return 'exports.__ = {};'", function () { expect(getLeakingWrapper([])).to.be("exports.__ = {};"); }); diff --git a/test/rewire.test.js b/test/rewire.test.js index 2df19e0..3414399 100644 --- a/test/rewire.test.js +++ b/test/rewire.test.js @@ -11,7 +11,6 @@ var testModules = [ path.resolve(__dirname, "./testModules/C/moduleC.js") ]; - function cleanRequireCache() { var i; @@ -20,7 +19,7 @@ function cleanRequireCache() { } } -describe("#rewire", function () { +describe("rewire", function () { beforeEach(cleanRequireCache); // ensuring a clean test environment it("should work like require() when omitting all other params", function () { expect(rewire("./testModules/A/moduleA.js")).to.be(require("./testModules/A/moduleA.js")); @@ -120,4 +119,13 @@ describe("#rewire", function () { moduleB = require("./testModules/A/moduleA.js"); // if restoring the original node require didn't worked, the mock would be applied now expect(moduleB.c).not.to.be(moduleCMock); }); + describe("#reset", function () { + it("should remove all rewired modules from cache", function () { + var rewired = rewire("./testModules/B/moduleB.js"); + + expect(require("./testModules/B/moduleB.js")).to.be(rewired); + rewire.reset(); + expect(require("./testModules/B/moduleB.js")).not.to.be(rewired); + }); + }); }); \ No newline at end of file -- cgit v1.2.3