Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/rewire.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes <mail@johannesewald.de>2012-06-12 01:29:10 +0400
committerJohannes <mail@johannesewald.de>2012-06-12 01:29:10 +0400
commit0af1dcb6b2ccbc7ec0ae757549688e666cf569a7 (patch)
tree4b3854b937ff1f05bf8677c8fc1547fa733e6feb
parent75f6a7765a09344dab54a4a2ca99ac12f547a75d (diff)
- changed APIv0.2.0
- introduced __set__ and __get__ to rewired modules
-rw-r--r--README.md176
-rw-r--r--lib/__get__.js17
-rw-r--r--lib/__set__.js41
-rw-r--r--lib/getImportGlobalsSrc.js28
-rw-r--r--lib/getInjectionSrc.js37
-rw-r--r--lib/getLeakingSrc.js29
-rw-r--r--lib/index.js4
-rw-r--r--lib/rewire.js83
-rw-r--r--package.json9
-rw-r--r--test/__get__.test.js79
-rw-r--r--test/__set__.test.js93
-rw-r--r--test/debug.test.js8
-rw-r--r--test/getImportGlobalsSrc.test.js24
-rw-r--r--test/getInjectionSrc.test.js24
-rw-r--r--test/getLeakingSrc.test.js16
-rw-r--r--test/rewire.test.js207
-rw-r--r--test/testModules/A/moduleA.js26
-rw-r--r--test/testModules/B/moduleB.js7
-rw-r--r--test/testModules/debuggerModule.js10
-rw-r--r--test/testModules/emptyModule.js (renamed from test/testModules/C/moduleC.js)2
-rw-r--r--test/testModules/index.js5
-rw-r--r--test/testModules/moduleA.js75
-rw-r--r--test/testModules/moduleB.js81
-rw-r--r--test/testModules/privateModules/privateModuleA.js10
-rw-r--r--test/testModules/privateModules/privateModuleB.js10
-rw-r--r--test/testModules/someOtherModule.js5
26 files changed, 689 insertions, 417 deletions
diff --git a/README.md b/README.md
index 4826178..69c80b8 100644
--- a/README.md
+++ b/README.md
@@ -2,12 +2,12 @@ rewire
=====
**Dependency injection for node.js applications**.
-rewire allows you to modify the behaviour of modules for better unit testing. You may
+rewire adds a special setter and getter that allow you to modify the behaviour of modules
+for better unit testing. You may
- introduce mocks for other modules
- leak private variables
-- override variables within the module
-- inject your own scripts
+- override variables within the module.
rewire does **not** load the file and eval the contents to emulate node's require mechanism. In fact it uses node's own require to load the module. Thus your module behaves exactly the same in your test environment as under regular circumstances (except your modifications).
@@ -22,8 +22,7 @@ Installation
`npm install rewire`
**For older node versions:**<br />
-rewire is tested with node 0.6.x. I recommend to run the unit tests via `mocha` in the rewire-folder before
-using rewire with older node versions.
+rewire is tested with node 0.6.x. I recommend to run the unit tests via `mocha` in the rewire-folder before using rewire with older node versions.
-----------------------------------------------------------------
<br />
@@ -34,72 +33,77 @@ Examples
```javascript
var rewire = require("rewire");
-// rewire acts exactly like require when omitting all other params
-rewire("./myModuleA.js") === require("./myModuleA.js"); // = true
-```
-### Mocks
-```javascript
-// You can introduce your own mocks for modules that are required:
-rewiredModule = rewire("./myModuleA.js", {
- "fs": {
- readFile: function (path, encoding, cb) { cb(null, "Success!"); }
- },
- "../path/to/moduleB.js": myMockForModuleB
+// rewire acts exactly like require.
+var myRewiredModule = rewire("../lib/myModule.js");
+myRewiredModule === require("../lib/myModule.js"); // = true
+
+
+// Your module will now export a special setter and getter for private variables.
+myModule.__set__("myPrivateVar", 123);
+myModule.__get__("myPrivateVar"); // = 123
+
+
+// This allows you to mock almost everything within the module e.g. the fs-module.
+// Just pass the variable name as first parameter and your mock as second.
+myModule.__set__("fs", {
+ readFile: function (path, encoding, cb) {
+ cb(null, "Success!");
+ }
+});
+myModule.readSomethingFromFileSystem(function (err, data) {
+ console.log(data); // = Success!
});
-// 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.
-```
-### Injections
-```javascript
-// You can inject your own mocks for internal or global objects.
-// These injections are only visible within the module.
-rewiredModule = rewire("./myModuleA.js", null, {
+
+// All later requires will now return the module with the mock.
+myModule === require("./myModule.js"); // = true
+
+
+// You can set different variables with one call.
+myModule.__set__({
+ fs: fsMock,
+ http: httpMock,
+ someOtherVar: "hello"
+});
+
+
+// You may also override globals. These changes are only within the module,
+// so you don't have to be afraid that other modules are influenced by your mock.
+myModule.__set__({
console: {
log: function () { /* be quiet */ }
},
- process: { argv: ["some", "other", "args"] },
- __filename: "some/other/dir"
+ process: {
+ argv: ["testArg1", "testArg2"]
+ }
});
-// This will inject
-// var console = {log: function () { /* be quiet */ }};
-// var process = {argv: ["some", "other", "args"]};
-// var __filename = "some/other/dir";
-// at the end of the module.
-// You can also pass a script to inject at the end
-rewiredModule = rewire("./myModuleA.js", null, "console.log('hello');");
-// This will print "hello" when the module loads
-```
+// But be careful, if you do something like this you'll change your global
+// console instance.
+myModule.__set__("console.log", function () { /* be quiet */ });
-### Leaks
-```javascript
-// You can expose private variables for unit tests
-rewiredModule = rewire("./myModuleA.js", null, null, ["myVar1", "myVar2");
-// This will inject
-// module.exports.__ = {myVar1: myVar1, myVar2: myVar2}
-// at the end of the module.
+// By getting private variables you can test for instance if your
+// module is in a specific state
+assert.ok(myModule.__get__("currentState") === "idle");
-// You can access now your private variables under the special.__-object
-console.log(rewiredModule.__.myVar1);
-console.log(rewiredModule.__.myVar2);
-```
-### Cache
-```javascript
-// You can disable caching of the rewired module. 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");
-// = false
+// You can also disable caching when loading the rewired module. All
+// subsequent calls of require() will than return the original module again.
+rewire("./myModule.js", false) === require("./myModule.js"); // = false
+
+
+// Every call of rewire returns a new instance and overwrites the old
+// one in the module cache.
+rewire("./myModule.js") === rewire("./myModule.js"); // = false
-// You can also delete all rewired modules from the cache by one call.
+
+// If you want to remove all your rewired modules from the
+// cache just call rewire.reset().
+// Do this before every unit test to ensure a clean testing environment.
rewire.reset();
-// You should call this after every unit test to ensure a clean test environment.
```
-----------------------------------------------------------------
@@ -107,73 +111,37 @@ rewire.reset();
##API
-**rewire(***filename, mocks, injections, leaks, cache***)**
+**rewire(***filename, cache***): {RewiredModule}**
- *{!String} filename*: <br/>
Path to the module that shall be rewired. Use it exactly like require().
-- *{Object} mocks (optional)*: <br/>
-An object with module mocks. Keys should reflect the required path of the module.
-
-- *{Object|String} injections (optional)*: <br />
-If you pass an object, all keys of the object will be `var`s within the module. You can also eval a string.
-
-- *{Array&lt;String&gt;} leaks (optional)*: <br/>
-An array with variable names that should be exported. These variables are accessible via `myModule.__`.
-
- *{Boolean=true} cache (optional)*: <br />
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.
-
**rewire.reset()**
Removes all rewired modules from `require.cache`. Every `require()` will now return the original module again.
------------------------------------------------------------------
-<br />
+**RewiredModule.&#95;&#95;set&#95;&#95;(***name, value***)**
-## Please note
-### Keys should be 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}`.
+- *{!String} name*: <br/>
+Name of the variable to set. The variable should be a global or defined with `var` in the top-level
+scope of the module.
-### 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.
+- *{&lowast;} value*: <br/>
+The value to set
-Imagine `rewire("./myModule.js", null, {console: null});`:
+**RewiredModule.&#95;&#95;set&#95;&#95;(***env***)**
-```javascript
-console.log("Hello"); // ouch, that won't work. console is undefined at this point because of hoisting
-
-// End of module ///////////////
-// rewire will inject here
-var console = null;
-```
-
-### Leaks are executed at the end of the module.
-All variables, that are [copied by value](http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language)
-will not be updated anymore.
-
-A good approach to solve this would be:
-
-```javascript
-var myLeaks = {};
-
-module.exports = function (someValue) {
- myLeaks.someValue = someValue;
-};
-```
+- *{!Object} env*: <br/>
+Takes all keys as variable names and sets the values respectively.
-And then: ```rewire("myModuleA.js", null, null, ["myLeaks"]);```
+**RewiredModule.&#95;&#95;get&#95;&#95;(***name***): {&lowast;}**
-Because ```myLeaks``` is defined at the end of the module, you're able to access the leak object and all leaks that
-are attached to it later during runtime.
+Returns the private variable.
-### Call rewire.reset() after every unit test
-All ```require()```s will now return the original module again.
-----------------------------------------------------------------
<br />
diff --git a/lib/__get__.js b/lib/__get__.js
new file mode 100644
index 0000000..64c467d
--- /dev/null
+++ b/lib/__get__.js
@@ -0,0 +1,17 @@
+"use strict"; // run code in ES5 strict mode
+
+/**
+ * This function will be stringified and then injected into every rewired module.
+ * Then you can leak private variables by calling myModule.__get__("myPrivateVar");
+ *
+ * @param {!String} name name of the variable to retrieve
+ * @throws {TypeError}
+ * @return {*}
+ */
+module.exports = function __get__(name) {
+ if (typeof name !== "string" || name == false) {
+ throw new TypeError("__get__ expects a non-empty string");
+ }
+
+ return eval(name);
+}; \ No newline at end of file
diff --git a/lib/__set__.js b/lib/__set__.js
new file mode 100644
index 0000000..7de8eec
--- /dev/null
+++ b/lib/__set__.js
@@ -0,0 +1,41 @@
+"use strict"; // run code in ES5 strict mode
+
+/**
+ * This function will be stringified and then injected into every rewired module.
+ * Then you can set private variables by calling myModule.__set__("myPrivateVar", newValue);
+ *
+ * @param {!String|!Object} varName name of the variable to set
+ * @param {String} varValue new value
+ * @throws {TypeError}
+ * @return {*}
+ */
+module.exports = function __set__(varName, varValue) {
+ var key,
+ env,
+ src = "";
+
+ function checkExistsSrc(varName) {
+ return "if (typeof " + varName + " === 'undefined') { throw new ReferenceError('" + varName + " is not defined');} ";
+ }
+
+ if (typeof varName === "object") {
+ env = varName;
+ if (!env || Array.isArray(env)) {
+ throw new TypeError("__set__ expects an object as env");
+ }
+ for (key in env) {
+ if (env.hasOwnProperty(key)) {
+ src += checkExistsSrc(key) + key + " = env." + key + ";";
+ }
+ }
+ } else if (typeof varName === "string") {
+ if (!varName) {
+ throw new TypeError("__set__ expects a non-empty string as a variable name");
+ }
+ src = checkExistsSrc(varName) + varName + " = varValue;"
+ } else {
+ throw new TypeError("__set__ expects an environment object or a non-empty string as a variable name");
+ }
+
+ eval(src);
+}; \ No newline at end of file
diff --git a/lib/getImportGlobalsSrc.js b/lib/getImportGlobalsSrc.js
new file mode 100644
index 0000000..1bcfed4
--- /dev/null
+++ b/lib/getImportGlobalsSrc.js
@@ -0,0 +1,28 @@
+"use strict"; // run code in ES5 strict mode
+
+/**
+ * Declares all globals with a var and assigns the global object. Thus you're able to
+ * override globals without changing the global object itself.
+ *
+ * Returns something like
+ * "var console = console; var process = process; ..."
+ *
+ * @return {String}
+ */
+function getImportGlobalsSrc() {
+ var key,
+ value,
+ src = "";
+
+ for (key in global) {
+ if (global.hasOwnProperty(key) && key !== "global") {
+ value = global[key];
+ src += "var " + key + " = global." + key + "; ";
+ }
+ }
+
+
+ return src;
+}
+
+module.exports = getImportGlobalsSrc; \ No newline at end of file
diff --git a/lib/getInjectionSrc.js b/lib/getInjectionSrc.js
deleted file mode 100644
index 74174d0..0000000
--- a/lib/getInjectionSrc.js
+++ /dev/null
@@ -1,37 +0,0 @@
-"use strict"; // run code in ES5 strict mode
-
-var toSrc = require("toSrc");
-
-/**
- * Returns the source code for injecting vars.
- *
- * e.g.:
- * "var console=123;"
- *
- * @param {Object} obj
- * @return {String}
- */
-function getInjectionSrc(obj) {
- function walkObj(obj, level) {
- var key,
- value,
- src = "";
-
- for (key in obj) {
- if (obj.hasOwnProperty(key)) {
- value = obj[key];
- if (level === 0) {
- src += "var "; // on the top level we need a var statement
- }
- src += key + "=" + toSrc(value, 9999) + ";";
- }
- }
-
-
- return src;
- }
-
- return walkObj(obj, 0);
-}
-
-module.exports = getInjectionSrc; \ No newline at end of file
diff --git a/lib/getLeakingSrc.js b/lib/getLeakingSrc.js
deleted file mode 100644
index 882300b..0000000
--- a/lib/getLeakingSrc.js
+++ /dev/null
@@ -1,29 +0,0 @@
-"use strict"; // run code in ES5 strict mode
-
-/**
- * Returns the source code that will leak private vars.
- *
- * e.g.:
- * "module.exports.__ = {myPrivateVar: myPrivateVar};"
- *
- * @param {Array<String>} leaks
- * @return {String}
- */
-function getLeakingSrc(leaks) {
- var src = "module.exports.__ = {",
- varName,
- i;
-
- for (i = 0; i < leaks.length; i++) {
- varName = leaks[i];
- src += (varName + ":" + varName + ",");
- }
- if (i > 0) {
- src = src.slice(0, -1); // trim last comma
- }
- src += "};";
-
- return src;
-}
-
-module.exports = getLeakingSrc;
diff --git a/lib/index.js b/lib/index.js
index 8be8897..a6dbcd6 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -13,14 +13,14 @@ var rewireModule = require("./rewire.js");
* @param {Boolean} cache Indicates whether the rewired module should be cached by node so subsequent calls of require() will return the rewired module. Subsequent calls of rewire() will always overwrite the cache.
* @return {*} the rewired module
*/
-function rewire(request, mocks, injections, leaks, cache) {
+function rewire(request, cache) {
delete require.cache[__filename]; // deleting self from module cache so the parent module is always up to date
if (cache === undefined) {
cache = true;
}
- return rewireModule(module.parent, request, mocks, injections, leaks, cache);
+ return rewireModule(module.parent, request, cache);
}
rewire.reset = rewireModule.reset;
diff --git a/lib/rewire.js b/lib/rewire.js
index 33f5d22..ae23fb1 100644
--- a/lib/rewire.js
+++ b/lib/rewire.js
@@ -1,32 +1,38 @@
"use strict"; // run code in ES5 strict mode
var Module = require("module"),
- nodeWrapper0 = Module.wrapper[0], // caching original wrapper
- nodeWrapper1 = Module.wrapper[1],
- getLeakingSrc = require("./getLeakingSrc.js"),
- getInjectionSrc = require("./getInjectionSrc.js"),
- rewiredModules = [];
+ __get__ = require("./__get__.js"),
+ __set__ = require("./__set__.js"),
+ getImportGlobalsSrc = require("./getImportGlobalsSrc.js"),
+
+ moduleWrapper0 = Module.wrapper[0], // caching original wrapper
+ moduleWrapper1 = Module.wrapper[1], // caching original wrapper
+ rewiredModules = []; // cache for all rewired modules so it can be reset anytime
function restoreOriginalWrappers() {
- Module.wrapper[1] = nodeWrapper1;
+ Module.wrapper[0] = moduleWrapper0;
+ Module.wrapper[1] = moduleWrapper1;
}
/**
* Does actual rewiring the module. For further documentation @see index.js
*/
-function rewire(parentModule, filename, mocks, injections, leaks, cache) {
+function rewire(parentModule, filename, cache) {
var testModule,
nodeRequire,
- wrapperExtensions = "";
-
- function requireMock(path) {
+ prepend,
+ append;
+
+ /**
+ * Proxies the first require call in order to draw back all changes.
+ * Thus our changes don't influence other modules
+ *
+ * @param {!String} path
+ */
+ function requireProxy(path) {
restoreOriginalWrappers(); // we need to restore the wrappers now so we don't influence other modules
-
- if (mocks && mocks.hasOwnProperty(path)) {
- return mocks[path];
- } else {
- return nodeRequire.call(testModule, path); // node's require only works when "this" points to the module
- }
+ testModule.require = nodeRequire; // restoring original nodeRequire
+ return nodeRequire.call(testModule, path); // node's require only works when "this" points to the module
}
// Checking params
@@ -34,8 +40,8 @@ function rewire(parentModule, filename, mocks, injections, leaks, cache) {
throw new TypeError("Filename must be a string");
}
- // Init vars
- filename = Module._resolveFilename(filename, parentModule); // resolve full filename relative to the parent module
+ // Resolve full filename relative to the parent module
+ filename = Module._resolveFilename(filename, parentModule);
// Special support for older node versions that returned an array on Module._resolveFilename
// @see https://github.com/joyent/node/blob/865b077819a9271a29f982faaef99dc635b57fbc/lib/module.js#L319
@@ -43,37 +49,44 @@ function rewire(parentModule, filename, mocks, injections, leaks, cache) {
filename = filename[1];
}
+ // Create testModule as it would be created by require()
testModule = new Module(filename, parentModule);
- nodeRequire = testModule.require; // caching original node require
- // Prepare module for injection
- if (typeof injections === "object") {
- wrapperExtensions += getInjectionSrc(injections);
- } else if (typeof injections === "string") {
- wrapperExtensions += injections;
- }
+ // Patching requireProxy
+ nodeRequire = testModule.require;
+ testModule.require = requireProxy;
- // Prepare module for leaking private vars
- if (Array.isArray(leaks)) {
- wrapperExtensions += getLeakingSrc(leaks);
- }
- Module.wrapper[1] = wrapperExtensions + nodeWrapper1;
+ // We prepend a list of all globals declared with var so they can be overridden (without changing original globals)
+ prepend = getImportGlobalsSrc();
+
+ // We append our special setter and getter.
+ append = "module.exports.__set__ = " + __set__.toString() + "; ";
+ append += "module.exports.__get__ = " + __get__.toString() + "; ";
- // Mocking module.require-function
- testModule.require = requireMock;
- // Loading module
+ // Apply prepend and append
+ Module.wrapper[0] = moduleWrapper0 + prepend;
+ Module.wrapper[1] = append + moduleWrapper1;
+
+ //console.log(Module.wrapper);
+
+ // Let the show begin
testModule.load(testModule.id);
+ // Store the rewired module in the cache when enabled
if (cache) {
- require.cache[filename] = testModule;
rewiredModules.push(filename); // save in private cache for .reset()
+ require.cache[filename] = testModule;
}
- restoreOriginalWrappers(); // this is only necessary if nothing has been required within the module
+ // This is only necessary if nothing has been required within the module
+ restoreOriginalWrappers();
return testModule.exports;
}
+/**
+ * Deletes all rewired modules from the cache
+ */
rewire.reset = function () {
var i;
diff --git a/package.json b/package.json
index 6048f87..ae302fd 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,15 @@
{
"name" : "rewire",
- "version" : "0.1.3",
+ "version" : "0.2.0",
"description" : "Dependency injection for node.js applications",
"keywords" : [
"dependency",
"injection",
"mock",
"unit",
- "test"
+ "test",
+ "leak",
+ "inspect"
],
"author" : {
"name" : "Johannes Ewald",
@@ -27,9 +29,6 @@
"engines" : {
"node" : "0.6.x"
},
- "dependencies": {
- "toSrc": "0.1.x"
- },
"devDependencies": {
"mocha": "1.1.x",
"expect.js": "0.1.x"
diff --git a/test/__get__.test.js b/test/__get__.test.js
new file mode 100644
index 0000000..6506e84
--- /dev/null
+++ b/test/__get__.test.js
@@ -0,0 +1,79 @@
+"use strict"; // run code in ES5 strict mode
+
+var expect = require("expect.js"),
+ vm = require("vm"),
+ __get__ = require("../lib/__get__.js"),
+
+ expectReferenceError = expectError(ReferenceError),
+ expectTypeError = expectError(TypeError);
+
+function expectError(ErrConstructor) {
+ return function expectReferenceError(err) {
+ expect(err.constructor.name).to.be(ErrConstructor.name);
+ };
+}
+
+
+describe("__get__", function () {
+ var moduleFake;
+
+ beforeEach(function () {
+ moduleFake = {
+ myNumber: 0,
+ myObj: {}
+ };
+
+ vm.runInNewContext(
+ "__get__ = " + __get__.toString() + "; " +
+ "setNumber = function (value) { myNumber = value; }; " +
+ "setObj = function (value) { myObj = value; }; ",
+ moduleFake
+ );
+ });
+ it("should return the initial value", function () {
+ expect(moduleFake.__get__("myNumber")).to.be(0);
+ expect(moduleFake.__get__("myObj")).to.eql({});
+ });
+ it("should return the changed value of the number", function () {
+ var newObj = { hello: "hello" };
+
+ moduleFake.setNumber(2);
+ moduleFake.setObj(newObj);
+ expect(moduleFake.__get__("myNumber")).to.be(2);
+ expect(moduleFake.__get__("myObj")).to.be(newObj);
+ });
+ it("should throw a ReferenceError when getting not existing vars", function () {
+ expect(function () {
+ moduleFake.__get__("blabla");
+ }).to.throwException(expectReferenceError);
+ });
+ it("should throw a TypeError when passing misfitting params", function () {
+ expect(function () {
+ moduleFake.__get__();
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__get__(undefined);
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__get__(null);
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__get__(true);
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__get__(2);
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__get__("");
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__get__([]);
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__get__({});
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__get__(function () {});
+ }).to.throwException(expectTypeError);
+ });
+}); \ No newline at end of file
diff --git a/test/__set__.test.js b/test/__set__.test.js
new file mode 100644
index 0000000..e7950cb
--- /dev/null
+++ b/test/__set__.test.js
@@ -0,0 +1,93 @@
+"use strict"; // run code in ES5 strict mode
+
+var expect = require("expect.js"),
+ __set__ = require("../lib/__set__.js"),
+ vm = require("vm"),
+
+ expectReferenceError = expectError(ReferenceError),
+ expectTypeError = expectError(TypeError);
+
+function expectError(ErrConstructor) {
+ return function expectReferenceError(err) {
+ expect(err.constructor.name).to.be(ErrConstructor.name);
+ };
+}
+
+describe("__set__", function () {
+ var moduleFake;
+
+ beforeEach(function () {
+ moduleFake = {
+ myNumber: 0, // copy by value
+ myObj: {} // copy by reference
+ };
+
+ vm.runInNewContext(
+ "__set__ = " + __set__.toString() + "; " +
+ "getNumber = function () { return myNumber; }; " +
+ "getObj = function () { return myObj; }; ",
+ moduleFake
+ );
+ });
+ it("should set the new number when calling with varName, varValue", function () {
+ expect(moduleFake.getNumber()).to.be(0);
+ moduleFake.__set__("myNumber", 2);
+ expect(moduleFake.getNumber()).to.be(2);
+ });
+ it("should set the new object when calling with varName, varValue", function () {
+ var newObj = { hello: "hello" };
+
+ expect(moduleFake.getObj()).to.eql({});
+ moduleFake.__set__("myObj", newObj);
+ expect(moduleFake.getObj()).to.be(newObj);
+ });
+ it("should set the new number and the new obj when calling with an env-obj", function () {
+ var newObj = { hello: "hello" };
+
+ expect(moduleFake.getNumber()).to.be(0);
+ expect(moduleFake.getObj()).to.eql({});
+ moduleFake.__set__({
+ myNumber: 2,
+ myObj: newObj
+ });
+ expect(moduleFake.getNumber()).to.be(2);
+ expect(moduleFake.getObj()).to.be(newObj);
+ });
+ it("should return undefined", function () {
+ expect(moduleFake.__set__("myNumber", 4)).to.be(undefined);
+ });
+ it("should throw a ReferenceError when trying to set non-existing vars", function () {
+ expect(function () {
+ moduleFake.__set__("notExisting", 3);
+ }).to.throwException();
+ expect(function () {
+ moduleFake.__set__({
+ notExisting: "bla",
+ notExistingAsWell: "blabla"
+ });
+ }).to.throwException(expectReferenceError);
+ });
+ it("should throw a TypeError when passing misfitting params", function () {
+ expect(function () {
+ moduleFake.__set__();
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__set__(undefined);
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__set__(null);
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__set__(true);
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__set__(2);
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__set__("");
+ }).to.throwException(expectTypeError);
+ expect(function () {
+ moduleFake.__set__(function () {});
+ }).to.throwException(expectTypeError);
+ });
+}); \ No newline at end of file
diff --git a/test/debug.test.js b/test/debug.test.js
index 4a388b6..acd16ee 100644
--- a/test/debug.test.js
+++ b/test/debug.test.js
@@ -4,8 +4,10 @@ var rewire = require("../lib/index.js");
// add breakpoints in testModules/debuggerModule.js and debug this file with your IDE to
// check if debugging works with rewire.
-var debuggerModule = rewire("./testModules/debuggerModule.js", null, {
- someVar: "Look if you can see me in your IDE when holding at the breakpoints"
-});
+var debuggerModule = rewire("./testModules/debuggerModule.js");
+
+debugger;
+
+debuggerModule.__set__("myNumber", 1);
debuggerModule(); \ No newline at end of file
diff --git a/test/getImportGlobalsSrc.test.js b/test/getImportGlobalsSrc.test.js
new file mode 100644
index 0000000..b6f8576
--- /dev/null
+++ b/test/getImportGlobalsSrc.test.js
@@ -0,0 +1,24 @@
+"use strict"; // run code in ES5 strict mode
+
+var expect = require("expect.js"),
+ vm = require("vm"),
+ getImportGlobalsSrc = require("../lib/getImportGlobalsSrc.js");
+
+describe("getImportGlobalsSrc", function () {
+ it("should declare all globals with a var", function () {
+ var context = {
+ global: global
+ },
+ src,
+ actualGlobals,
+ expectedGlobals = Object.keys(global);
+
+ src = getImportGlobalsSrc();
+ vm.runInNewContext(src, context);
+ actualGlobals = Object.keys(context);
+ actualGlobals.sort();
+ expectedGlobals.sort();
+ expect(actualGlobals).to.eql(expectedGlobals);
+ expect(actualGlobals.length).to.be.above(1);
+ });
+}); \ No newline at end of file
diff --git a/test/getInjectionSrc.test.js b/test/getInjectionSrc.test.js
deleted file mode 100644
index 356b00d..0000000
--- a/test/getInjectionSrc.test.js
+++ /dev/null
@@ -1,24 +0,0 @@
-"use strict"; // run code in ES5 strict mode
-
-var expect = require("expect.js"),
- getInjectionSrc = require("../lib/getInjectionSrc.js");
-
-describe("getMonkeyPatchSrc", function () {
- it("should return ''", function () {
- var expectedSrc = "",
- subject = {};
-
- expect(getInjectionSrc(subject)).to.be(expectedSrc);
- });
- it("should return 'var process={\"argv\": [\"myArg1\", \"myArg2\"]};var console=456;'", function () {
- var expectedSrc = "var process={\"argv\": [\"myArg1\", \"myArg2\"]};var console=456;",
- subject = {
- process: {
- argv: ["myArg1", "myArg2"]
- },
- console: 456
- };
-
- expect(getInjectionSrc(subject)).to.be(expectedSrc);
- });
-}); \ No newline at end of file
diff --git a/test/getLeakingSrc.test.js b/test/getLeakingSrc.test.js
deleted file mode 100644
index b1e137b..0000000
--- a/test/getLeakingSrc.test.js
+++ /dev/null
@@ -1,16 +0,0 @@
-"use strict"; // run code in ES5 strict mode
-
-var expect = require("expect.js"),
- getLeakingWrapper = require("../lib/getLeakingSrc.js");
-
-describe("getLeakingWrapper", function () {
- it("should return 'module.exports.__ = {};'", function () {
- expect(getLeakingWrapper([])).to.be("module.exports.__ = {};");
- });
- it("should return 'module.exports.__ = {somethingPrivate:somethingPrivate,somethingSecret:somethingSecret};'", function () {
- var leakArr = ["somethingPrivate", "somethingSecret"];
-
- expect(getLeakingWrapper(leakArr))
- .to.be("module.exports.__ = {somethingPrivate:somethingPrivate,somethingSecret:somethingSecret};");
- });
-}); \ No newline at end of file
diff --git a/test/rewire.test.js b/test/rewire.test.js
index 1f8ebf9..9216af6 100644
--- a/test/rewire.test.js
+++ b/test/rewire.test.js
@@ -4,132 +4,151 @@ var path = require("path"),
expect = require("expect.js"),
rewire = require("../lib/index.js");
-var testModules = [
- path.resolve(__dirname, "./testModules/index.js"),
- path.resolve(__dirname, "./testModules/A/moduleA.js"),
- path.resolve(__dirname, "./testModules/B/moduleB.js"),
- path.resolve(__dirname, "./testModules/C/moduleC.js")
- ];
+var testModules = {
+ A: path.resolve(__dirname, "./testModules/moduleA.js"),
+ B: path.resolve(__dirname, "./testModules/moduleB.js"),
+ someOtherModule: path.resolve(__dirname, "./testModules/someOtherModule.js"),
+ emptyModule: path.resolve(__dirname, "./testModules/emptyModule.js")
+ };
function cleanRequireCache() {
- var i;
-
- for (i = 0; i < testModules.length; i++) {
- delete require.cache[testModules[i]];
+ var moduleName,
+ modulePath;
+
+ for (moduleName in testModules) {
+ if (testModules.hasOwnProperty(moduleName)) {
+ modulePath = testModules[moduleName];
+ delete require.cache[modulePath];
+ }
}
}
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"));
+ it("should work like require()", function () {
+ expect(rewire("./testModules/moduleA.js")).to.be(require("./testModules/moduleA.js"));
+ cleanRequireCache();
+ expect(rewire("../test/testModules/moduleA.js")).to.be(require("../test/testModules/moduleA.js"));
+ cleanRequireCache();
+ expect(rewire(testModules.A)).to.be(require(testModules.A));
});
- it("should require all mocks", function () {
- var rewired,
- fsMock = {},
- mocks = {},
- moduleBMock = {},
- moduleCMock = {},
- toSrcMock = {},
- indexMock = {};
-
- mocks["fs"] = fsMock;
- mocks[path.resolve(__dirname, "./testModules/B/moduleB.js")] = moduleBMock;
- mocks["../C/moduleC.js"] = moduleCMock;
- mocks["toSrc"] = toSrcMock;
- mocks["../"] = indexMock;
-
- rewired = rewire("./testModules/A/moduleA.js", mocks);
- expect(rewired.fs).to.be(fsMock);
- expect(rewired.b).to.be(moduleBMock);
- expect(rewired.c).to.be(moduleCMock);
- expect(rewired.toSrc).to.be(toSrcMock);
- expect(rewired.index).to.be(indexMock);
+ it("should modify the module so it provides a __set__ - function", function () {
+ expect(rewire(testModules.A).__set__).to.be.a(Function);
+ expect(rewire(testModules.B).__set__).to.be.a(Function);
});
- it("should inject object modifications", function () {
- var rewired,
- injections = {
- process: {
- argv: ["arg1", "arg2", "arg3"]
- },
- console: 123
- };
-
- rewired = rewire("./testModules/A/moduleA.js", null, injections);
- rewired.exportAll();
- expect(rewired.process).not.to.be(process);
- expect(process.argv).not.to.eql(injections.process.argv);
- expect(rewired.process).to.eql(injections.process);
- expect(rewired.console).to.be(123);
+ it("should modify the module so it provides a __get__ - function", function () {
+ expect(rewire(testModules.A).__get__).to.be.a(Function);
+ expect(rewire(testModules.B).__get__).to.be.a(Function);
});
- it("should inject custom scripts", function () {
- var rewired,
- script = "var console = 456;";
+ it("should not influence other modules", function () {
+ var rewiredModuleA = rewire(testModules.A);
- rewired = rewire("./testModules/A/moduleA.js", null, script);
- rewired.exportAll();
- expect(rewired.console).to.be(456);
+ expect(require(testModules.someOtherModule).__set__).to.be(undefined);
+ expect(require(testModules.someOtherModule).__get__).to.be(undefined);
+ expect(require("fs").__set__).to.be(undefined);
+ expect(require("fs").__get__).to.be(undefined);
});
- it("should leak private variables with both exports-styles (exports.bla = bla and module.exports = bla)", function () {
- var rewired,
- leaks = ["myPrivateVar"];
-
- rewired = rewire("./testModules/privateModules/privateModuleA.js", null, null, leaks);
- expect(rewired.__.myPrivateVar).to.be("Hello I'm very private");
- rewired = rewire("./testModules/privateModules/privateModuleB.js", null, null, leaks);
- expect(rewired.__.myPrivateVar).to.be("Hello I'm very private");
+ it("should not influence global objects by default", function () {
+ expect(function () {
+ rewire(testModules.A).checkSomeGlobals();
+ rewire(testModules.B).checkSomeGlobals();
+ }).to.not.throwException();
+ });
+ it("should provide the ability to set private vars", function () {
+ var rewiredModuleA = rewire(testModules.A),
+ newObj = {};
+
+ expect(rewiredModuleA.getMyNumber()).to.be(0);
+ rewiredModuleA.__set__("myNumber", 2);
+ expect(rewiredModuleA.getMyNumber()).to.be(2);
+ rewiredModuleA.__set__("myObj", newObj);
+ expect(rewiredModuleA.getMyObj()).to.be(newObj);
});
- it("should leak private functions with both exports-styles (exports.bla = bla and module.exports = bla)", function () {
- var rewired,
- leaks = ["myPrivateFunction"];
+ it("should provide the ability to get private vars", function () {
+ var rewiredModuleA = rewire(testModules.A);
- rewired = rewire("./testModules/privateModules/privateModuleA.js", null, null, leaks);
- expect(rewired.__.myPrivateFunction()).to.be("Hello I'm very private");
- rewired = rewire("./testModules/privateModules/privateModuleB.js", null, null, leaks);
- expect(rewired.__.myPrivateFunction()).to.be("Hello I'm very private");
+ expect(rewiredModuleA.__get__("myNumber")).to.be(rewiredModuleA.getMyNumber());
+ expect(rewiredModuleA.__get__("myObj")).to.be(rewiredModuleA.getMyObj());
});
- it("should leak nothing on demand", function () {
- var rewired;
+ it("should provide the ability to inject mocks", function (done) {
+ var rewiredModuleA = rewire(testModules.A),
+ mockedFs = {
+ readFileSync: function (file) {
+ expect(file).to.be("bla.txt");
+ done();
+ }
+ };
- rewired = rewire("./testModules/A/moduleA.js");
- expect(rewired.__).to.be(undefined);
+ rewiredModuleA.__set__("fs", mockedFs);
+ rewiredModuleA.readFileSync();
+ });
+ it("should not influence other modules when injecting mocks", function () {
+ var rewiredModuleA = rewire(testModules.A),
+ someOtherModule,
+ mockedFs = {};
+
+ rewiredModuleA.__set__("fs", mockedFs);
+ someOtherModule = require(testModules.someOtherModule);
+ expect(someOtherModule.fs).not.to.be(mockedFs);
+ });
+ it("should provide the ability to mock global objects just within the module", function () {
+ var rewiredModuleA = rewire(testModules.A),
+ rewiredModuleB = rewire(testModules.B),
+ consoleMock = {},
+ processMock = {},
+ newFilename = "myFile.js";
+
+ rewiredModuleA.__set__({
+ console: consoleMock,
+ process: processMock
+ });
+ rewiredModuleA.__set__("__filename", newFilename);
+ rewiredModuleB.__set__({
+ console: consoleMock,
+ process: processMock
+ });
+ rewiredModuleB.__set__("__filename", newFilename);
+ expect(rewiredModuleA.getConsole()).to.be(consoleMock);
+ expect(rewiredModuleB.getConsole()).to.be(consoleMock);
+ expect(console).not.to.be(consoleMock);
+ expect(rewiredModuleA.getProcess()).to.be(processMock);
+ expect(rewiredModuleB.getProcess()).to.be(processMock);
+ expect(process).not.to.be(processMock);
+ expect(rewiredModuleA.getFilename()).to.be(newFilename);
+ expect(rewiredModuleB.getFilename()).to.be(newFilename);
});
it("should cache the rewired module", function () {
var rewired;
- rewired = rewire("./testModules/B/moduleB.js");
- rewired.requireIndex();
- expect(rewired.index.b).to.be(rewired);
+ rewired = rewire(testModules.someOtherModule);
+ expect(require(testModules.A).someOtherModule).to.be(rewired);
cleanRequireCache();
- rewired = rewire("./testModules/B/moduleB.js", null, null, null, true);
- rewired.requireIndex();
- expect(rewired.index.b).to.be(rewired);
+ rewired = rewire(testModules.someOtherModule, true);
+ expect(require(testModules.A).someOtherModule).to.be(rewired);
});
it("should not cache the rewired module on demand", function () {
var rewired;
- rewired = rewire("./testModules/B/moduleB.js", null, null, null, false);
- rewired.requireIndex();
- expect(rewired.index.b).not.to.be(rewired);
+ rewired = rewire(testModules.someOtherModule, false);
+ expect(require(testModules.A).someOtherModule).not.to.be(rewired);
});
it("should not influence the original node require if nothing has been required within the rewired module", function () {
- var moduleCMock = {},
- moduleB,
- mocks = {
- "../C/moduleC.js": moduleCMock
- };
-
- rewire("./testModules/C/moduleC.js", mocks); // nothing happens here because moduleC doesn't require anything
- 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);
+ rewire(testModules.emptyModule); // nothing happens here because emptyModule doesn't require anything
+ expect(require(testModules.A).__set__).to.be(undefined); // if restoring the original node require didn't worked, the module would have a setter
+ });
+ it("subsequent calls of rewire should always return a new instance", function () {
+ expect(rewire(testModules.A)).not.to.be(rewire(testModules.A));
});
describe("#reset", function () {
it("should remove all rewired modules from cache", function () {
- var rewired = rewire("./testModules/B/moduleB.js");
+ var rewiredModuleA = rewire(testModules.A),
+ rewiredModuleB = rewire(testModules.B);
- expect(require("./testModules/B/moduleB.js")).to.be(rewired);
+ expect(require(testModules.A)).to.be(rewiredModuleA);
+ expect(require(testModules.B)).to.be(rewiredModuleB);
rewire.reset();
- expect(require("./testModules/B/moduleB.js")).not.to.be(rewired);
+ expect(require(testModules.A)).not.to.be(rewiredModuleA);
+ expect(require(testModules.B)).not.to.be(rewiredModuleB);
});
});
}); \ No newline at end of file
diff --git a/test/testModules/A/moduleA.js b/test/testModules/A/moduleA.js
deleted file mode 100644
index b8671cf..0000000
--- a/test/testModules/A/moduleA.js
+++ /dev/null
@@ -1,26 +0,0 @@
-"use strict"; // run code in ES5 strict mode
-
-var path = require("path"),
-
- // different ways to require a module
- fs = require("fs"), // native module
- c = require("../C/moduleC.js"), // relative path
- b = require(path.resolve(__dirname, "../B/moduleB.js")), // absolute path
- toSrc = require("toSrc"), // node_modules path
- index = require("../"); // index.js path
-
-function exportAll() {
- // expose all required modules to test for mocks
- exports.fs = fs;
- exports.b = b;
- exports.c = c;
- exports.toSrc = toSrc;
- exports.index = index;
- exports.process = process;
- exports.console = console;
-}
-
-exportAll();
-exports.exportAll = exportAll;
-
-
diff --git a/test/testModules/B/moduleB.js b/test/testModules/B/moduleB.js
deleted file mode 100644
index 7b7b32c..0000000
--- a/test/testModules/B/moduleB.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict"; // run code in ES5 strict mode
-
-var c = require("../C/moduleC.js");
-
-exports.requireIndex = function () { // necessary to avoid circular dependency
- exports.index = require("../index.js");
-}; \ No newline at end of file
diff --git a/test/testModules/debuggerModule.js b/test/testModules/debuggerModule.js
index 926c607..5a79b53 100644
--- a/test/testModules/debuggerModule.js
+++ b/test/testModules/debuggerModule.js
@@ -1,13 +1,7 @@
"use strict"; // run code in ES5 strict mode
-// Add a breakpoint on line 6 and on line 11 and debug "debug.test.js" to test if the IDE stops at these points.
-// Watch also the variable someVar that is injected by rewire. It will be undefined at this point because
-// all injections are executed at the end of the module.
-// It's already visible because of hoisting: http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-hoisting-explained/)
-var someNumber = 0;
+var myNumber = 0;
module.exports = function () {
- // In this line someVar will be defined.
- someNumber++;
- someVar;
+ myNumber = 1;
}; \ No newline at end of file
diff --git a/test/testModules/C/moduleC.js b/test/testModules/emptyModule.js
index b7245de..7c9ad5d 100644
--- a/test/testModules/C/moduleC.js
+++ b/test/testModules/emptyModule.js
@@ -1,3 +1 @@
"use strict"; // run code in ES5 strict mode
-
-module.exports = "c"; \ No newline at end of file
diff --git a/test/testModules/index.js b/test/testModules/index.js
deleted file mode 100644
index fa07160..0000000
--- a/test/testModules/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-"use strict"; // run code in ES5 strict mode
-
-exports.a = require("./A/moduleA.js");
-exports.b = require("./B/moduleB.js");
-exports.c = require("./C/moduleC.js"); \ No newline at end of file
diff --git a/test/testModules/moduleA.js b/test/testModules/moduleA.js
new file mode 100644
index 0000000..6cc63b2
--- /dev/null
+++ b/test/testModules/moduleA.js
@@ -0,0 +1,75 @@
+"use strict"; // run code in ES5 strict mode
+
+var someOtherModule = require("./someOtherModule.js"),
+ myNumber = 0, // copy by value
+ myObj = {}, // copy by reference
+ fs = require("fs");
+
+// We need getters and setters for private vars to check if our injected setters and getters actual work
+function setMyNumber(newNumber) {
+ myNumber = newNumber;
+}
+
+function getMyNumber() {
+ return myNumber;
+}
+
+function setMyObj(newObj) {
+ myObj = newObj;
+}
+
+function getMyObj() {
+ return myObj;
+}
+
+function readFileSync() {
+ fs.readFileSync("bla.txt", "utf8");
+}
+
+function checkSomeGlobals() {
+ if (typeof global === "undefined") {
+ //throw new ReferenceError("global is undefined");
+ }
+ if (typeof process === "undefined") {
+ throw new ReferenceError("process is undefined");
+ }
+ if (typeof console === "undefined") {
+ throw new ReferenceError("console is undefined");
+ }
+ if (typeof Buffer === "undefined") {
+ throw new ReferenceError("Buffer is undefined");
+ }
+ if (typeof __filename === "undefined") {
+ throw new ReferenceError("__filename is undefined");
+ }
+ if (typeof __dirname === "undefined") {
+ throw new ReferenceError("__dirname is undefined");
+ }
+ if (typeof setTimeout === "undefined") {
+ throw new ReferenceError("setTimeout is undefined");
+ }
+}
+
+function getConsole() {
+ return console;
+}
+
+function getProcess() {
+ return process;
+}
+
+function getFilename() {
+ return __filename;
+}
+
+// different styles of exports in moduleA.js and moduleB.js
+exports.setMyNumber = setMyNumber;
+exports.getMyNumber = getMyNumber;
+exports.setMyObj = setMyObj;
+exports.getMyObj = getMyObj;
+exports.readFileSync = readFileSync;
+exports.checkSomeGlobals = checkSomeGlobals;
+exports.getConsole = getConsole;
+exports.getProcess = getProcess;
+exports.getFilename = getFilename;
+exports.someOtherModule = someOtherModule; \ No newline at end of file
diff --git a/test/testModules/moduleB.js b/test/testModules/moduleB.js
new file mode 100644
index 0000000..c9fec13
--- /dev/null
+++ b/test/testModules/moduleB.js
@@ -0,0 +1,81 @@
+"use strict"; // run code in ES5 strict mode
+
+var someOtherModule = require("./someOtherModule.js"),
+ myNumber = 0, // copy by value
+ myObj = {}, // copy by reference
+ fs = require("fs");
+
+// We need getters and setters for private vars to check if our injected setters and getters actual work
+function setMyNumber(newNumber) {
+ myNumber = newNumber;
+}
+
+function getMyNumber() {
+ return myNumber;
+}
+
+function setMyObj(newObj) {
+ myObj = newObj;
+}
+
+function getMyObj() {
+ return myObj;
+}
+
+function readFileSync() {
+ fs.readFileSync("bla.txt", "utf8");
+}
+
+function checkSomeGlobals() {
+ if (typeof global === "undefined") {
+ throw new ReferenceError("global is undefined");
+ }
+ if (typeof process === "undefined") {
+ throw new ReferenceError("process is undefined");
+ }
+ if (typeof console === "undefined") {
+ throw new ReferenceError("console is undefined");
+ }
+ if (typeof Buffer === "undefined") {
+ throw new ReferenceError("Buffer is undefined");
+ }
+ if (typeof __filename === "undefined") {
+ throw new ReferenceError("__filename is undefined");
+ }
+ if (typeof __dirname === "undefined") {
+ throw new ReferenceError("__dirname is undefined");
+ }
+ if (typeof setTimeout === "undefined") {
+ throw new ReferenceError("setTimeout is undefined");
+ }
+}
+
+function getConsole() {
+ return console;
+}
+
+function getProcess() {
+ return process;
+}
+
+function getFilename() {
+ return __filename;
+}
+
+function main() {
+
+}
+
+main.setMyNumber = setMyNumber;
+main.getMyNumber = getMyNumber;
+main.setMyObj = setMyObj;
+main.getMyObj = getMyObj;
+main.readFileSync = readFileSync;
+main.checkSomeGlobals = checkSomeGlobals;
+main.getConsole = getConsole;
+main.getProcess = getProcess;
+main.getFilename = getFilename;
+main.someOtherModule = someOtherModule;
+
+// different styles of exports in moduleA.js and moduleB.js
+module.exports = main;
diff --git a/test/testModules/privateModules/privateModuleA.js b/test/testModules/privateModules/privateModuleA.js
deleted file mode 100644
index 757df3e..0000000
--- a/test/testModules/privateModules/privateModuleA.js
+++ /dev/null
@@ -1,10 +0,0 @@
-"use strict"; // run code in ES5 strict mode
-
-var myPrivateVar = "Hello I'm very private";
-
-function myPrivateFunction() {
- return "Hello I'm very private";
-}
-
-// privateModuleA and privateModuleB use different styles of exports
-exports.bla = "somevalue"; \ No newline at end of file
diff --git a/test/testModules/privateModules/privateModuleB.js b/test/testModules/privateModules/privateModuleB.js
deleted file mode 100644
index c9e5bc7..0000000
--- a/test/testModules/privateModules/privateModuleB.js
+++ /dev/null
@@ -1,10 +0,0 @@
-"use strict"; // run code in ES5 strict mode
-
-var myPrivateVar = "Hello I'm very private";
-
-function myPrivateFunction() {
- return "Hello I'm very private";
-}
-
-// privateModuleA and privateModuleB use different styles of exports
-module.exports = function bla() {}; \ No newline at end of file
diff --git a/test/testModules/someOtherModule.js b/test/testModules/someOtherModule.js
new file mode 100644
index 0000000..02287d1
--- /dev/null
+++ b/test/testModules/someOtherModule.js
@@ -0,0 +1,5 @@
+"use strict"; // run code in ES5 strict mode
+
+var fs = require("fs");
+
+exports.fs = fs; \ No newline at end of file