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:
-rw-r--r--lib/__set__.js7
-rw-r--r--lib/browser/shims.js48
-rw-r--r--lib/browserify/browserInit.js44
-rw-r--r--lib/browserify/browserifyMiddleware.js56
-rw-r--r--lib/browserify/browserifyRewire.js166
-rw-r--r--lib/getImportGlobalsSrc.js17
-rw-r--r--package.json6
-rw-r--r--test/browserify.browserifyRewire.test.js77
-rw-r--r--test/browserify/index.html (renamed from test/browser/index.html)2
-rw-r--r--test/getImportGlobalsSrc.test.js20
-rw-r--r--test/testModules/moduleA.js62
-rw-r--r--test/testModules/moduleB.js82
-rw-r--r--test/testModules/sharedTestCases.js37
13 files changed, 441 insertions, 183 deletions
diff --git a/lib/__set__.js b/lib/__set__.js
index 79175ed..61e8f94 100644
--- a/lib/__set__.js
+++ b/lib/__set__.js
@@ -25,9 +25,10 @@ function __set__() {
if (!arguments.env || Array.isArray(arguments.env)) {
throw new TypeError("__set__ expects an object as env");
}
- for (arguments.key in arguments.env) {
- if (arguments.env.hasOwnProperty(arguments.key)) {
- arguments.src += arguments.checkExistsSrc(arguments.key) + arguments.key + " = arguments.env." + arguments.key + ";";
+ for (arguments.varName in arguments.env) {
+ if (arguments.env.hasOwnProperty(arguments.varName)) {
+ arguments.varValue = arguments.env[arguments.varName];
+ arguments.src += arguments.checkExistsSrc(arguments.varName, arguments.varValue) + arguments.varName + " = arguments.env." + arguments.varName + ";";
}
}
} else if (typeof arguments.varName === "string") {
diff --git a/lib/browser/shims.js b/lib/browser/shims.js
new file mode 100644
index 0000000..df7bd63
--- /dev/null
+++ b/lib/browser/shims.js
@@ -0,0 +1,48 @@
+// Taken from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf#Compatibility
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
+ "use strict";
+ if (this == null) {
+ throw new TypeError();
+ }
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (len === 0) {
+ return -1;
+ }
+ var n = 0;
+ if (arguments.length > 0) {
+ n = Number(arguments[1]);
+ if (n != n) { // shortcut for verifying if it's NaN
+ n = 0;
+ } else if (n != 0 && n != Infinity && n != -Infinity) {
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ }
+ }
+ if (n >= len) {
+ return -1;
+ }
+ var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
+ for (; k < len; k++) {
+ if (k in t && t[k] === searchElement) {
+ return k;
+ }
+ }
+ return -1;
+ }
+}
+
+
+// Taken from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/trim#Compatibility
+if(!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return this.replace(/^\s+|\s+$/g,'');
+ };
+}
+
+// Taken from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray#Compatibility
+if(!Array.isArray) {
+ Array.isArray = function (vArg) {
+ return Object.prototype.toString.call(vArg) === "[object Array]";
+ };
+} \ No newline at end of file
diff --git a/lib/browserify/browserInit.js b/lib/browserify/browserInit.js
index 02fd9c1..b79005d 100644
--- a/lib/browserify/browserInit.js
+++ b/lib/browserify/browserInit.js
@@ -2,43 +2,11 @@
* This code gets injected at the end of the browserify bundle via b.append().
*/
-if (typeof window.browserifyRequire !== "undefined") {
- throw new Error("Naming collision detected: window.browserifyRequire seems to be occupied.");
+if (typeof window.browserifyRequire === "undefined") {
+ // Saves the browserifyRequire under a new name. Necessary to call the original browserifyRequire within
+ // a module where the variable name "require" is overridden by the module's internal require.
+ window.browserifyRequire = require;
+} else {
+ throw new Error("(rewire/browserify) Naming collision detected: window.browserifyRequire seems to be occupied.");
}
-// Saves the browserifyRequire under a new name. Necessary to call the original browserifyRequire within
-// a module where the variable name "require" is overridden by the module's internal require.
-window.browserifyRequire = require;
-
-/**
- * Provides a special require-proxy. Every module calls window.browserifyRequire.getProxy(require, __filename) at the
- * beginning and overrides its own require with this proxy.
- *
- * This is necessary to call rewire() with the original __filename. Thus you can use rewire() like require().
- *
- * @param {!Function} internalRequire the module's own require
- * @param {String} filename the __filename of the module
- * @return {Function} requireProxy
- */
-window.browserifyRequire.getProxy = function (internalRequire, filename) {
- var rewireModule = internalRequire("rewire"),
- key;
-
- function rewireProxy(path, cache) {
- return rewireModule(filename, path, cache);
- }
-
- for (key in rewireModule) {
- if (rewireModule.hasOwnProperty(key)) {
- rewireProxy[key] = rewireModule[key];
- }
- }
-
- return function requireProxy(path) {
- if (path === "rewire") {
- return rewireProxy;
- } else {
- return internalRequire(path);
- }
- };
-}; \ No newline at end of file
diff --git a/lib/browserify/browserifyMiddleware.js b/lib/browserify/browserifyMiddleware.js
index d62352e..8fa564a 100644
--- a/lib/browserify/browserifyMiddleware.js
+++ b/lib/browserify/browserifyMiddleware.js
@@ -7,7 +7,6 @@ var setterSrc = require("../__set__.js").toString(),
detectStrictMode = require("../detectStrictMode.js"),
browserInit = fs.readFileSync(__dirname + "/browserInit.js", "utf8"),
- importGlobalsSrc = getImportGlobalsSrc(),
injectionSrc = getInjectionSrc().replace(/\s+/g, " "); // strip out unnecessary spaces to be unobtrusive in the debug view
/**
@@ -19,18 +18,20 @@ var setterSrc = require("../__set__.js").toString(),
* @return {String}
*/
function getInjectionSrc() {
- // Registers the setters and getters of every module according to their filename. The setters and getters must be
- // injected as string here to gain access to the private scope of the module.
- return 'require("rewire").register(__filename, ' + setterSrc + ', ' + getterSrc + ');' +
- // Overrides the module internal require with a require proxy. This proxy is necessary to call rewire with the
- // module's filename at the first parameter to resolve the path. This way rewire() works exactly like require().
- 'require = window.browserifyRequire.getProxy(require, __filename);';
+ return 'var rewire = require("rewire"); ' +
+ // Registers the setters and getters of every module according to their filename. The setters and getters must be
+ // injected as string here to gain access to the private scope of the module.
+ 'rewire.register(__filename, module, ' + setterSrc + ', ' + getterSrc + ');' +
+ // Overrides the module internal require with a require proxy. This proxy is necessary to call rewire with the
+ // module's filename at the first parameter to resolve the path. This way rewire() works exactly like require().
+ 'require = rewire.getProxy(require, __dirname);' +
+ // Cleaning up
+ 'rewire = undefined;';
}
function browserifyMiddleware(b) {
function injectRewire(src, filename) {
- var rewireRequires,
- strictMode = "";
+ var rewireRequires;
// Search for all rewire() statements an return the required path.
rewireRequires = getRewireRequires(src);
@@ -45,24 +46,39 @@ function browserifyMiddleware(b) {
b.require(requirePath);
});
- // If the module uses strict mode we must ensure that "use strict" stays at the beginning of the module.
- if (detectStrictMode(src) === true) {
- strictMode = ' "use strict"; ';
+ // Convert back slashes to normal slashes on windows.
+ if (process.platform.indexOf("win") === 0) {
+ filename = filename.replace(/\\/g, "/");
}
- // Convert back slashes to normal slashes.
- filename = filename.replace(/\\/g, "/");
-
// We don't want to inject this code at the beginning of a rewire/lib-module. Otherwise
// it would cause a black hole that devours our universe.
if (filename.indexOf("/rewire/lib") === -1) {
src =
- strictMode + // either '' or ' "use strict"; '
- "/* this line was injected by rewire() */" +
- "var global = window; " + // window is our new global object
- importGlobalsSrc +
+ // Trying to hide the injected line in the debug view with extra whitespaces.
+ ' ' +
+ '/* this line was injected by rewire() */ ' + // Comment for the curious developer
+
+ // Now all global variables are declared with a var statement so they can be changed via __set__()
+ // without influencing global objects.
+ 'var global = window; ' + // window is our new global object
+ 'eval(require("rewire").getImportGlobalsSrc()); ' +
+
+ // The module src is wrapped inside a self-executing function.
+ // This is necessary to separate the module src from the preceding eval(importGlobalsSrc),
+ // because the module src can be in strict mode.
+ // In strict mode eval() can only declare vars the current scope. In this case our setters
+ // and getters won't work.
+ // @see https://developer.mozilla.org/en/JavaScript/Strict_mode#Making_eval_and_arguments_simpler
+ "(function () {" +
+
+ // If the module uses strict mode we must ensure that "use strict" stays at the beginning of the module.
+ (detectStrictMode(src)? ' "use strict"; ': ' ') +
+
injectionSrc + "\n" +
- src;
+ src +
+
+ "})();";
}
return src;
diff --git a/lib/browserify/browserifyRewire.js b/lib/browserify/browserifyRewire.js
index d70f31e..8e24c09 100644
--- a/lib/browserify/browserifyRewire.js
+++ b/lib/browserify/browserifyRewire.js
@@ -1,5 +1,38 @@
-var pathUtil = require("path"),
- browserifyRequire = window.browserifyRequire;
+require("../browser/shims.js"); // some shims for older browsers that are used by rewire()
+
+var browserifyRequire = window.browserifyRequire,
+ getImportGlobalsSrc = require("../getImportGlobalsSrc.js");
+
+/**
+ * Clones an object deeply. Used to clone the module-object that is
+ * stored in the cache. Because browserify doesn't create the module-
+ * object newly if the module is executed again we can't modify the
+ * exports object directly. Instead of we have to make an independent copy.
+ *
+ * @param {!Object} obj
+ * @return {Object}
+ */
+function clone(obj) {
+ var target = {},
+ value,
+ key;
+
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ value = obj[key];
+ if (Array.isArray(value)) {
+ target[key] = value.slice(0);
+ } else if (typeof value === "object" && value !== null) {
+ target[key] = clone(value);
+ } else {
+ target[key] = value;
+ }
+
+ }
+ }
+
+ return target;
+}
// Saves all setters and getters for every module according to its filename
var registry = {},
@@ -11,59 +44,55 @@ var registry = {},
* The parentModulePath is usually set by the requireProxy.
*
* @param {!String} parentModulePath __filename of the module, that wants to rewire() another module.
- * @param {!String} targetPath path to the module that shall be rewired
+ * @param {!String} path path to the module that shall be rewired
* @param {Boolean=true} cache indicates whether the rewired module should be cached or not
* @return {Object}
*/
-function browserifyRewire(parentModulePath, targetPath, cache) {
+function browserifyRewire(parentModulePath, path, cache) {
var originalModule,
- rewiredModule = {},
- registeredTargetModule;
+ absPath,
+ rewiredExports,
+ rewiredModule,
+ registryEntry;
// Default cache to true
if (cache === undefined) {
cache = true;
}
- // Make absolute paths
- if (targetPath.charAt(0) === ".") {
- targetPath = pathUtil.resolve(pathUtil.dirname(parentModulePath), targetPath);
- }
-
// Normalize path with file extensions
- targetPath = require.resolve(targetPath);
-
- // Deleting module from cache to trigger execution again
- delete browserifyRequire.modules[targetPath]._cached;
+ absPath = browserifyRequire.resolve(path, parentModulePath);
- // Require module to trigger rewire.register() if it hasnt been required yet
- // Putting (require) within brackets is a hack to disable browserifys require sniffing
- // @see https://github.com/substack/node-browserify/issues/132#issuecomment-5281470
- originalModule = (require)(targetPath);
+ // Delete the original module from the cache so the next call to browserifyRequre()
+ // executes the module
+ delete browserifyRequire.cache[absPath];
- // Copy all exported values to our rewired module
- for (var key in originalModule) {
- if (originalModule.hasOwnProperty(key)) {
- rewiredModule[key] = originalModule[key];
- }
- }
-
- // If caching is enabled we store the rewiredModule in the cache
- if (cache) {
- browserifyRequire.modules[targetPath]._cached = rewiredModule;
- }
+ // Require module to trigger rewire.register()
+ browserifyRequire(path, parentModulePath);
// Get registry entry of the target module
- registeredTargetModule = registry[targetPath];
+ registryEntry = registry[absPath];
+ originalModule = registryEntry.module;
+
+ // Make an independent copy of the original module so we can modify the copy
+ // without influencing the original module.
+ rewiredModule = clone(originalModule);
+ rewiredExports = rewiredModule.exports;
// Apply setter and getters
- rewiredModule.__set__ = registeredTargetModule.setter;
- rewiredModule.__get__ = registeredTargetModule.getter;
+ rewiredExports.__set__ = registryEntry.setter;
+ rewiredExports.__get__ = registryEntry.getter;
+
+ if (cache) {
+ browserifyRequire.cache[absPath] = rewiredModule;
+ } else {
+ browserifyRequire.cache[absPath] = originalModule; // returning originalModule to the cache
+ }
// Store rewired modules for rewire.reset()
- rewiredModules.push(targetPath);
+ rewiredModules.push(absPath);
- return rewiredModule;
+ return rewiredExports;
}
/**
@@ -73,8 +102,9 @@ function browserifyRewire(parentModulePath, targetPath, cache) {
* @param {!Function} setter
* @param {!Function} getter
*/
-browserifyRewire.register = function (filename, setter, getter) {
+browserifyRewire.register = function (filename, module, setter, getter) {
registry[filename] = {
+ module: module,
setter: setter,
getter: getter
};
@@ -84,14 +114,72 @@ browserifyRewire.register = function (filename, setter, getter) {
* Deletes all rewired modules from the cache
*/
browserifyRewire.reset = function () {
- var modules = browserifyRequire.modules,
- i;
+ var cache = browserifyRequire.cache,
+ i,
+ absPath;
for (i = 0; i < rewiredModules.length; i++) {
- delete modules[rewiredModules[i]]._cached;
+ absPath = rewiredModules[i];
+ delete cache[absPath];
}
rewiredModules = [];
};
+/**
+ * Provides a special require-proxy. Every module calls require("rewire").getProxy(require, __filename) at the
+ * beginning and overrides its own require with this proxy.
+ *
+ * This is necessary to call rewire() with the original __filename. Thus you can use rewire() like require().
+ *
+ * @param {!Function} internalRequire the module's own require
+ * @param {String} dirname the __dirname of the module
+ * @return {Function} requireProxy
+ */
+browserifyRewire.getProxy = function (internalRequire, dirname) {
+ var rewire = internalRequire("rewire"),
+ rewireProxyInit = false;
+
+ function copyProperties(from, to) {
+ var key;
+
+ for (key in from) {
+ if (from.hasOwnProperty(key)) {
+ to[key] = from[key];
+ }
+ }
+ }
+
+ function rewireProxy(path, cache) {
+ return rewire(dirname, path, cache);
+ }
+
+ function requireProxy(path) {
+ if (path === "rewire") {
+ if (rewireProxyInit === false) {
+ copyProperties(rewire, rewireProxy); // lazy copy
+ rewireProxyInit = true;
+ }
+ return rewireProxy;
+ } else {
+ return internalRequire(path);
+ }
+ }
+
+ copyProperties(internalRequire, requireProxy);
+
+ return requireProxy;
+};
+
+/**
+ * Scans for global vars an returns an evalable string that declares all globals as a var.
+ * This way a global variable can be overridden by __set__ without changing the global instance.
+ * It is
+ *
+ * @type {String}
+ */
+browserifyRewire.getImportGlobalsSrc = function () {
+ return getImportGlobalsSrc(['require','module','exports','__dirname','__filename','process']);
+};
+
module.exports = browserifyRewire; \ No newline at end of file
diff --git a/lib/getImportGlobalsSrc.js b/lib/getImportGlobalsSrc.js
index dc40a4b..f8c73c2 100644
--- a/lib/getImportGlobalsSrc.js
+++ b/lib/getImportGlobalsSrc.js
@@ -7,15 +7,20 @@
*
* @return {String}
*/
-function getImportGlobalsSrc() {
+function getImportGlobalsSrc(ignore) {
var key,
value,
- src = "";
+ src = "",
+ globalObj = typeof global === "undefined"? window: global;
- for (key in global) {
- if (global.hasOwnProperty(key) && key !== "global") {
- value = global[key];
- src += "var " + key + " = global." + key + "; ";
+ ignore = ignore || [];
+
+ for (key in globalObj) {
+ if (globalObj.hasOwnProperty === undefined || globalObj.hasOwnProperty(key)) { // in IE8 window.hasOwnProperty is undefined
+ if (key !== "global" && ignore.indexOf(key) === -1) {
+ value = globalObj[key];
+ src += "var " + key + " = global." + key + "; ";
+ }
}
}
diff --git a/package.json b/package.json
index c05ab1a..645f76c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name" : "rewire",
- "version" : "0.3.0",
+ "version" : "0.3.1",
"description" : "Dependency injection for node.js applications",
"keywords" : [
"dependency",
@@ -27,12 +27,12 @@
"url": "git://github.com/jhnns/rewire.git"
},
"engines" : {
- "node" : "<=0.8.x"
+ "node" : "<0.9.x"
},
"devDependencies": {
"mocha": "1.2.x",
"expect.js": "0.1.x",
- "browserify": "1.13.x"
+ "browserify": ">=1.13.5 <1.14.x"
},
"scripts" : {
"test" : "mocha -R spec"
diff --git a/test/browserify.browserifyRewire.test.js b/test/browserify.browserifyRewire.test.js
index 43c7082..e52a50c 100644
--- a/test/browserify.browserifyRewire.test.js
+++ b/test/browserify.browserifyRewire.test.js
@@ -20,7 +20,15 @@ function runInFakeBrowserContext(src, filename) {
afterEach: afterEach,
setTimeout: setTimeout
},
- console: console
+ console: console,
+ setTimeout: setTimeout,
+ clearTimeout: clearTimeout,
+ setInterval: setInterval,
+ clearInterval: clearInterval,
+ parseFloat: parseFloat,
+ parseInt: parseInt,
+ encodeURIComponent: function () {},
+ decodeURIComponent: function () {}
}, filename);
}
@@ -28,8 +36,10 @@ describe("browserifyRewire", function () {
before(require("./testHelpers/createFakePackageJSON.js"));
after(require("./testHelpers/removeFakePackageJSON.js"));
it("should attach __set__ and __get__ to the exports-obj", function (done) {
- var context,
+ var pathToBrowserfiyRewire = pathUtil.resolve(__dirname, "../lib/browserify/browserifyRewire.js"),
+ context,
exportsObj = {},
+ moduleObj = {exports: exportsObj},
returnedObj,
browserifyRewire;
@@ -38,13 +48,14 @@ describe("browserifyRewire", function () {
function moduleA() {
"use strict";
- browserifyRewire.register("/a.js", null, null);
+ browserifyRewire.register("/a.js", null, null, null);
returnedObj = browserifyRewire("/a.js", "/b.js");
}
function moduleB() {
"use strict";
- browserifyRewire.register("/b.js", setter, getter);
+
+ browserifyRewire.register("/b.js", moduleObj, setter, getter);
return exportsObj;
}
@@ -53,51 +64,60 @@ describe("browserifyRewire", function () {
return "/b.js";
}
- function fakeRequire(requirePath) {
- if (requirePath === "path") {
- return pathUtil;
- } else {
- return moduleB();
+ function fakeRequire(path, parentModulePath) {
+ var module;
+
+ if (path === "../browser/shims.js") {
+ return;
+ } else if (path === "../getImportGlobalsSrc.js") {
+ return require("../lib/getImportGlobalsSrc.js");
}
+
+ module = moduleB();
+
+ expect(path).to.be("/b.js");
+ expect(parentModulePath).to.be("/a.js");
+ fakeRequire.cache["/b.js"] = module;
+
+ return module;
}
fakeRequire.resolve = fakeResolve;
+ fakeRequire.cache = {};
function setter() {}
function getter() {}
context = {
- require: fakeRequire,
module: {},
console: console,
window: {
- browserifyRequire: {
- modules: {
- "/b.js": {
- _cached : {}
- }
- }
- }
- }
+ browserifyRequire: fakeRequire
+ },
+ require: fakeRequire
};
- fs.readFile(pathUtil.resolve(__dirname, "../lib/browserify/browserifyRewire.js"), "utf8", function onBrowserifyRewireRead(err, src) {
- vm.runInNewContext(src, context);
+ fs.readFile(pathToBrowserfiyRewire, "utf8", function onBrowserifyRewireRead(err, src) {
+ vm.runInNewContext(src, context, pathToBrowserfiyRewire);
browserifyRewire = context.module.exports;
moduleA();
- expect(returnedObj).not.to.be(exportsObj);
expect(returnedObj.__set__).to.be(setter);
expect(returnedObj.__get__).to.be(getter);
- expect(context.window.browserifyRequire.modules["/b.js"]._cached).to.be(returnedObj);
+ // Because browserify does not create the module-object newly when executing the module
+ // again we have to copy the module object deeply and store that copy in the
+ // cache. Therefore we're checking here if the returned exports-object and the
+ // cached module-object are an independent copy.
+ expect(returnedObj).not.to.be(exportsObj);
+ expect(context.window.browserifyRequire.cache["/b.js"]).not.to.be(moduleObj);
done();
});
});
- it("should run all sharedTestCases without exception", function (done) {
+ it("should run all sharedTestCases without exception", function () {
var b = browserify({debug: true}),
middleware = require("rewire").browserify,
- browserOutput = __dirname + "/browser/browseroutput.js",
+ browserOutput = __dirname + "/browserify/bundle.js",
browserBundle,
vmBundle;
@@ -108,6 +128,7 @@ describe("browserifyRewire", function () {
// Setup for mocha
browserBundle += 'window.onload = function () {' +
+ 'console.log("These tests will only work in all browsers with the console being opened");' +
'mocha.setup("bdd");' +
'window.browserifyRequire("/test/testModules/sharedTestCases.js");' +
'mocha.run();' +
@@ -116,11 +137,9 @@ describe("browserifyRewire", function () {
vmBundle += 'window.browserifyRequire("/test/testModules/sharedTestCases.js");';
// Output for browser-testing
- fs.mkdir(__dirname + "/browser", function onMkDir() {
- fs.writeFile(browserOutput, browserBundle, "utf8", done);
+ fs.writeFileSync(browserOutput, browserBundle, "utf8");
- // This should throw no exception.
- runInFakeBrowserContext(vmBundle, browserOutput);
- });
+ // This should throw no exception.
+ runInFakeBrowserContext(vmBundle, browserOutput);
});
}); \ No newline at end of file
diff --git a/test/browser/index.html b/test/browserify/index.html
index 46d63d9..8f869a5 100644
--- a/test/browser/index.html
+++ b/test/browserify/index.html
@@ -2,7 +2,7 @@
<head>
<link rel="stylesheet" href="../../node_modules/mocha/mocha.css" />
<script src="../../node_modules/mocha/mocha.js" type="text/javascript"></script>
- <script src="browseroutput.js" type="text/javascript"></script>
+ <script src="bundle.js" type="text/javascript"></script>
</head>
<body>
<div id="mocha"></div>
diff --git a/test/getImportGlobalsSrc.test.js b/test/getImportGlobalsSrc.test.js
index 065bd59..0d9b020 100644
--- a/test/getImportGlobalsSrc.test.js
+++ b/test/getImportGlobalsSrc.test.js
@@ -19,4 +19,24 @@ describe("getImportGlobalsSrc", function () {
expect(actualGlobals).to.eql(expectedGlobals);
expect(actualGlobals.length).to.be.above(1);
});
+ it("should ignore the given variables", function () {
+ var context = {
+ global: global
+ },
+ ignore = ["console", "setTimeout"],
+ src,
+ actualGlobals,
+ expectedGlobals = Object.keys(global);
+
+ src = getImportGlobalsSrc(ignore);
+ expectedGlobals = expectedGlobals.filter(function filterIgnoredVars(value) {
+ return ignore.indexOf(value) === -1;
+ });
+ 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/testModules/moduleA.js b/test/testModules/moduleA.js
index 6e655ab..1e14071 100644
--- a/test/testModules/moduleA.js
+++ b/test/testModules/moduleA.js
@@ -28,21 +28,67 @@ function readFileSync() {
}
function checkSomeGlobals() {
- if (typeof global === "undefined") {
- throw new ReferenceError("global is undefined");
+ if (typeof global !== "object") {
+ throw new ReferenceError("global is not an object");
}
- if (typeof console === "undefined") {
- throw new ReferenceError("console is undefined");
+ if (typeof console !== "object") {
+ throw new ReferenceError("console is not an object");
}
- if (typeof __filename === "undefined") {
- throw new ReferenceError("__filename is undefined");
+ if (typeof require !== "function") {
+ throw new ReferenceError("require is not a function");
}
- if (typeof __dirname === "undefined") {
- throw new ReferenceError("__dirname is undefined");
+ if (typeof module !== "object") {
+ throw new ReferenceError("module is not an object");
}
+ if (typeof exports !== "object") {
+ throw new ReferenceError("exports is not an object");
+ }
+ if (module.exports !== exports) {
+ throw new Error("module.exports === exports returns false");
+ }
+ if (typeof __dirname !== "string") {
+ throw new ReferenceError("__dirname is not a string");
+ }
+ if (typeof __filename !== "string") {
+ throw new ReferenceError("__filename is not a string");
+ }
+ //TODO add accurate checks here
if (typeof setTimeout === "undefined") {
throw new ReferenceError("setTimeout is undefined");
}
+ if (typeof clearTimeout === "undefined") {
+ throw new ReferenceError("clearTimeout is undefined");
+ }
+ if (typeof setInterval === "undefined") {
+ throw new ReferenceError("setInterval is undefined");
+ }
+ if (typeof clearInterval === "undefined") {
+ throw new ReferenceError("clearInterval is undefined");
+ }
+ if (typeof Error === "undefined") {
+ throw new ReferenceError("Error is undefined");
+ }
+ if (typeof parseFloat === "undefined") {
+ throw new ReferenceError("parseFloat is undefined");
+ }
+ if (typeof parseInt === "undefined") {
+ throw new ReferenceError("parseInt is undefined");
+ }
+ if (typeof window === "undefined") {
+ if (typeof process === "undefined") {
+ throw new ReferenceError("process is undefined");
+ }
+ if (typeof Buffer === "undefined") {
+ throw new ReferenceError("Buffer is undefined");
+ }
+ } else {
+ if (typeof encodeURIComponent === "undefined") {
+ throw new ReferenceError("encodeURIComponent is undefined");
+ }
+ if (typeof decodeURIComponent === "undefined") {
+ throw new ReferenceError("decodeURIComponent is undefined");
+ }
+ }
}
function getConsole() {
diff --git a/test/testModules/moduleB.js b/test/testModules/moduleB.js
index 6e655ab..b7646bd 100644
--- a/test/testModules/moduleB.js
+++ b/test/testModules/moduleB.js
@@ -28,21 +28,67 @@ function readFileSync() {
}
function checkSomeGlobals() {
- if (typeof global === "undefined") {
- throw new ReferenceError("global is undefined");
+ if (typeof global !== "object") {
+ throw new ReferenceError("global is not an object");
}
- if (typeof console === "undefined") {
- throw new ReferenceError("console is undefined");
+ if (typeof console !== "object") {
+ throw new ReferenceError("console is not an object");
}
- if (typeof __filename === "undefined") {
- throw new ReferenceError("__filename is undefined");
+ if (typeof require !== "function") {
+ throw new ReferenceError("require is not a function");
}
- if (typeof __dirname === "undefined") {
- throw new ReferenceError("__dirname is undefined");
+ if (typeof module !== "object") {
+ throw new ReferenceError("module is not an object");
}
+ if (typeof exports !== "object") {
+ throw new ReferenceError("exports is not an object");
+ }
+ if (module.exports === exports) {
+ throw new Error("module.exports === exports returns true"); // should be false because we're setting module.exports at the bottom of this file
+ }
+ if (typeof __dirname !== "string") {
+ throw new ReferenceError("__dirname is not a string");
+ }
+ if (typeof __filename !== "string") {
+ throw new ReferenceError("__filename is not a string");
+ }
+ //TODO add accurate checks here
if (typeof setTimeout === "undefined") {
throw new ReferenceError("setTimeout is undefined");
}
+ if (typeof clearTimeout === "undefined") {
+ throw new ReferenceError("clearTimeout is undefined");
+ }
+ if (typeof setInterval === "undefined") {
+ throw new ReferenceError("setInterval is undefined");
+ }
+ if (typeof clearInterval === "undefined") {
+ throw new ReferenceError("clearInterval is undefined");
+ }
+ if (typeof Error === "undefined") {
+ throw new ReferenceError("Error is undefined");
+ }
+ if (typeof parseFloat === "undefined") {
+ throw new ReferenceError("parseFloat is undefined");
+ }
+ if (typeof parseInt === "undefined") {
+ throw new ReferenceError("parseInt is undefined");
+ }
+ if (typeof window === "undefined") {
+ if (typeof process === "undefined") {
+ throw new ReferenceError("process is undefined");
+ }
+ if (typeof Buffer === "undefined") {
+ throw new ReferenceError("Buffer is undefined");
+ }
+ } else {
+ if (typeof encodeURIComponent === "undefined") {
+ throw new ReferenceError("encodeURIComponent is undefined");
+ }
+ if (typeof decodeURIComponent === "undefined") {
+ throw new ReferenceError("decodeURIComponent is undefined");
+ }
+ }
}
function getConsole() {
@@ -54,12 +100,14 @@ function getFilename() {
}
// 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.getFilename = getFilename;
-exports.someOtherModule = someOtherModule; \ No newline at end of file
+module.exports = {
+ setMyNumber: setMyNumber,
+ getMyNumber: getMyNumber,
+ setMyObj: setMyObj,
+ getMyObj: getMyObj,
+ readFileSync: readFileSync,
+ checkSomeGlobals: checkSomeGlobals,
+ getConsole: getConsole,
+ getFilename: getFilename,
+ someOtherModule: someOtherModule
+};
diff --git a/test/testModules/sharedTestCases.js b/test/testModules/sharedTestCases.js
index b705e40..5f0a78b 100644
--- a/test/testModules/sharedTestCases.js
+++ b/test/testModules/sharedTestCases.js
@@ -26,19 +26,13 @@ function cleanRequireCache() {
for (moduleName in testModules) {
if (testModules.hasOwnProperty(moduleName)) {
modulePath = testModules[moduleName];
- if (typeof window === "undefined") {
- delete require.cache[modulePath];
- } else {
- if (typeof window.browserifyRequire.modules[modulePath]._cached === "object") {
- delete window.browserifyRequire.modules[modulePath]._cached;
- }
- }
+ delete require.cache[modulePath];
}
}
}
describe("rewire " + (typeof window === "undefined"? "(node.js)": "(browser)"), function () {
- beforeEach(cleanRequireCache); // ensuring a clean test environment
+ afterEach(cleanRequireCache); // ensuring a clean test environment
it("should work like require()", function () {
expect(rewire("./moduleA.js")).to.be(require("./moduleA.js"));
cleanRequireCache();
@@ -62,7 +56,7 @@ describe("rewire " + (typeof window === "undefined"? "(node.js)": "(browser)"),
expect(require("fs").__set__).to.be(undefined);
expect(require("fs").__get__).to.be(undefined);
});
- it("should not influence global objects by default", function () {
+ it("should not override/influence global objects by default", function () {
// This should throw no exception
rewire("./moduleA.js").checkSomeGlobals();
rewire("./moduleB.js").checkSomeGlobals();
@@ -112,18 +106,14 @@ describe("rewire " + (typeof window === "undefined"? "(node.js)": "(browser)"),
newFilename = "myFile.js";
rewiredModuleA.__set__({
- console: consoleMock
- });
- rewiredModuleA.__set__("__filename", newFilename);
- rewiredModuleB.__set__({
- console: consoleMock
+ console: consoleMock,
+ __filename: newFilename
});
- rewiredModuleB.__set__("__filename", newFilename);
expect(rewiredModuleA.getConsole()).to.be(consoleMock);
- expect(rewiredModuleB.getConsole()).to.be(consoleMock);
+ expect(rewiredModuleB.getConsole()).not.to.be(consoleMock);
expect(console).not.to.be(consoleMock);
expect(rewiredModuleA.getFilename()).to.be(newFilename);
- expect(rewiredModuleB.getFilename()).to.be(newFilename);
+ expect(rewiredModuleB.getFilename()).not.to.be(newFilename);
});
it("should cache the rewired module", function () {
var rewired;
@@ -140,20 +130,29 @@ describe("rewire " + (typeof window === "undefined"? "(node.js)": "(browser)"),
rewired = rewire("./someOtherModule.js", false);
expect(require("./moduleA.js").someOtherModule).not.to.be(rewired);
});
- it("should not influence the original node require if nothing has been required within the rewired module", function () {
+ it("should not influence the original require if nothing has been required within the rewired module", function () {
rewire("./emptyModule.js"); // nothing happens here because emptyModule doesn't require anything
expect(require("./moduleA.js").__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("./moduleA.js")).not.to.be(rewire("./moduleA.js"));
});
- it("should preserve the strict mode", function () {
+ it("should preserve the strict mode (not IE)", function () {
var strictModule = rewire("./strictModule.js");
expect(function () {
strictModule.doSomethingUnstrict();
}).to.throwException(checkForTypeError);
});
+ it("should return a fresh instance of the module", function () {
+ var someOtherModule = require("./someOtherModule.js"),
+ rewiredSomeOtherModule;
+
+ someOtherModule.fs = "This has been modified";
+ rewiredSomeOtherModule = rewire("./someOtherModule.js");
+ expect(rewiredSomeOtherModule.fs).not.to.be("This has been modified");
+ });
describe("#reset", function () {
it("should remove all rewired modules from cache", function () {
var rewiredModuleA = rewire("./moduleA.js"),