diff options
author | Johannes <johannes.ewald@roomieplanet.de> | 2012-07-10 22:32:54 +0400 |
---|---|---|
committer | Johannes <johannes.ewald@roomieplanet.de> | 2012-07-10 22:32:54 +0400 |
commit | 0bb70adf091ce5ccf8c81f28cc72a229ac15eba1 (patch) | |
tree | 61ef88ea9646dd734533e295d7002653c311508e | |
parent | b443c61ab73679410f083e383be7aef3039d228f (diff) |
- fixed parsing error when trying to set a function as mockv0.3.2
- update to mocha 1.3.x
- fixed minor IE issues
-rw-r--r-- | lib/__set__.js | 86 | ||||
-rw-r--r-- | lib/getImportGlobalsSrc.js | 58 | ||||
-rw-r--r-- | package.json | 78 | ||||
-rw-r--r-- | test/__get__.test.js | 156 | ||||
-rw-r--r-- | test/__set__.test.js | 206 | ||||
-rw-r--r-- | test/browserify.browserifyRewire.test.js | 121 | ||||
-rw-r--r-- | test/browserify/index.html | 35 | ||||
-rw-r--r-- | test/detectStrictMode.test.js | 24 | ||||
-rw-r--r-- | test/testModules/moduleA.js | 256 | ||||
-rw-r--r-- | test/testModules/moduleB.js | 262 | ||||
-rw-r--r-- | test/testModules/sharedTestCases.js | 410 |
11 files changed, 857 insertions, 835 deletions
diff --git a/lib/__set__.js b/lib/__set__.js index 6e02727..66e8c0a 100644 --- a/lib/__set__.js +++ b/lib/__set__.js @@ -1,46 +1,42 @@ -/**
- * This function will be stringified and then injected into every rewired module.
- * Then you can set private variables by calling myModule.__set__("myPrivateVar", newValue);
- *
- * All variables within this function are namespaced in the arguments array because every
- * var declaration could possibly clash with a variable in the module scope.
- *
- * @param {!String|!Object} varName name of the variable to set
- * @param {String} varValue new value
- * @throws {TypeError}
- * @throws {ReferenceError} When the variable is unknown
- * @return {*}
- */
-function __set__() {
- arguments.varName = arguments[0];
- arguments.varValue = arguments[1];
- arguments.src = "";
- arguments.checkExistsSrc = function (varName, varValue) {
- return "if (typeof " + varName + " === 'undefined') { throw new ReferenceError('Cannot __set__(" + varName + ", " + varValue + "): " +
- varName + " is not declared within the module.'); } ";
- };
-
- 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");
- }
- 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" && arguments.length === 2) {
- if (!arguments.varName) {
- throw new TypeError("__set__ expects a non-empty string as a variable name");
- }
- arguments.src = arguments.checkExistsSrc(arguments.varName, arguments.varValue) + arguments.varName + " = arguments.varValue;";
- } else {
- throw new TypeError("__set__ expects an environment object or a non-empty string as a variable name");
- }
-
- eval(arguments.src);
-}
-
+/** + * This function will be stringified and then injected into every rewired module. + * Then you can set private variables by calling myModule.__set__("myPrivateVar", newValue); + * + * All variables within this function are namespaced in the arguments array because every + * var declaration could possibly clash with a variable in the module scope. + * + * @param {!String|!Object} varName name of the variable to set + * @param {String} varValue new value + * @throws {TypeError} + * @throws {ReferenceError} When the variable is unknown + * @return {*} + */ +function __set__() { + arguments.varName = arguments[0]; + arguments.varValue = arguments[1]; + arguments.src = ""; + + 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"); + } + 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 + "; "; + } + } + } 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;"; + } else { + throw new TypeError("__set__ expects an environment object or a non-empty string as a variable name"); + } + + eval(arguments.src); +} + module.exports = __set__;
\ No newline at end of file diff --git a/lib/getImportGlobalsSrc.js b/lib/getImportGlobalsSrc.js index f8c73c2..0e573f2 100644 --- a/lib/getImportGlobalsSrc.js +++ b/lib/getImportGlobalsSrc.js @@ -1,31 +1,29 @@ -/**
- * 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(ignore) {
- var key,
- value,
- src = "",
- globalObj = typeof global === "undefined"? window: global;
-
- 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 + "; ";
- }
- }
- }
-
-
- return src;
-}
-
+/** + * 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(ignore) { + var key, + value, + src = "", + globalObj = typeof global === "undefined"? window: global; + + ignore = ignore || []; + + for (key in globalObj) { + if (key !== "global" && ignore.indexOf(key) === -1) { // we don't use hasOwnProperty here because in some browsers not all global objects will be enumerated + value = globalObj[key]; + src += "var " + key + " = global." + key + "; "; + } + } + + + return src; +} + module.exports = getImportGlobalsSrc;
\ No newline at end of file diff --git a/package.json b/package.json index 645f76c..f3c22c3 100644 --- a/package.json +++ b/package.json @@ -1,40 +1,40 @@ -{
- "name" : "rewire",
- "version" : "0.3.1",
- "description" : "Dependency injection for node.js applications",
- "keywords" : [
- "dependency",
- "injection",
- "mock",
- "unit",
- "test",
- "leak",
- "inspect"
- ],
- "author" : {
- "name" : "Johannes Ewald",
- "email" : "mail@johannesewald.de",
- "web" : "http://johannesewald.de"
- },
- "main" : "lib/index.js",
- "homepage": "http://jhnns.github.com/rewire",
- "bugs" : {
- "url" : "http://github.com/jhnns/rewire/issues",
- "email" : "mail@johannesewald.de"
- },
- "repository": {
- "type": "git",
- "url": "git://github.com/jhnns/rewire.git"
- },
- "engines" : {
- "node" : "<0.9.x"
- },
- "devDependencies": {
- "mocha": "1.2.x",
- "expect.js": "0.1.x",
- "browserify": ">=1.13.5 <1.14.x"
- },
- "scripts" : {
- "test" : "mocha -R spec"
- }
+{ + "name" : "rewire", + "version" : "0.3.2", + "description" : "Dependency injection for node.js applications", + "keywords" : [ + "dependency", + "injection", + "mock", + "unit", + "test", + "leak", + "inspect" + ], + "author" : { + "name" : "Johannes Ewald", + "email" : "mail@johannesewald.de", + "web" : "http://johannesewald.de" + }, + "main" : "lib/index.js", + "homepage": "http://jhnns.github.com/rewire", + "bugs" : { + "url" : "http://github.com/jhnns/rewire/issues", + "email" : "mail@johannesewald.de" + }, + "repository": { + "type": "git", + "url": "git://github.com/jhnns/rewire.git" + }, + "engines" : { + "node" : "<0.9.x" + }, + "devDependencies": { + "mocha": "1.3.x", + "expect.js": "0.1.x", + "browserify": ">=1.13.5 <1.14.x" + }, + "scripts" : { + "test" : "node node_modules/mocha/bin/mocha -R spec" + } }
\ No newline at end of file diff --git a/test/__get__.test.js b/test/__get__.test.js index 7c40bdb..8f060f7 100644 --- a/test/__get__.test.js +++ b/test/__get__.test.js @@ -1,79 +1,79 @@ -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 === ErrConstructor.name).to.be(true);
- };
-}
-
-
-describe("__get__", function () {
- var moduleFake;
-
- beforeEach(function () {
- moduleFake = {
- __filename: "some/file.js",
- myNumber: 0,
- myObj: {}
- };
-
- vm.runInNewContext(
- "__get__ = " + __get__.toString() + "; " +
- "setNumber = function (value) { myNumber = value; }; " +
- "setObj = function (value) { myObj = value; }; ",
- moduleFake,
- __filename
- );
- });
- it("should return the initial value", function () {
- expect(moduleFake.__get__("myNumber") === 0).to.be(true);
- 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") === 2).to.be(true);
- expect(moduleFake.__get__("myObj") === newObj).to.be(true);
- });
- 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);
- });
+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 = { + __filename: "some/file.js", + myNumber: 0, + myObj: {} + }; + + vm.runInNewContext( + "__get__ = " + __get__.toString() + "; " + + "setNumber = function (value) { myNumber = value; }; " + + "setObj = function (value) { myObj = value; }; ", + moduleFake, + __filename + ); + }); + 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 index 85a1d37..7b9c2cb 100644 --- a/test/__set__.test.js +++ b/test/__set__.test.js @@ -1,104 +1,104 @@ -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 === ErrConstructor.name).to.be(true);
- };
-}
-
-describe("__set__", function () {
- var moduleFake;
-
- beforeEach(function () {
- moduleFake = {
- myNumber: 0, // copy by value
- myObj: {}, // copy by reference
-
- // these variables are used within the set method
- // because there is a eval() statement within the set method
- // these variables should not override same-named vars of the module
- key: "key",
- env: "env",
- src: "src"
- };
-
- 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() === 0).to.be(true);
- moduleFake.__set__("myNumber", 2);
- expect(moduleFake.getNumber() === 2).to.be(true);
- });
- 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() === newObj).to.be(true);
- });
- it("should set the new number and the new obj when calling with an env-obj", function () {
- var newObj = { hello: "hello" };
-
- expect(moduleFake.getNumber() === 0).to.be(true);
- expect(moduleFake.getObj()).to.eql({});
- moduleFake.__set__({
- myNumber: 2,
- myObj: newObj
- });
- expect(moduleFake.getNumber() === 2).to.be(true);
- expect(moduleFake.getObj() === newObj).to.be(true);
- });
- it("should return undefined", function () {
- expect(moduleFake.__set__("myNumber", 4) === undefined).to.be(true);
- });
- 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);
- expect(function () {
- moduleFake.__set__({}, true); // misfitting number of params
- }).to.throwException(expectTypeError);
- expect(function () {
- moduleFake.__set__("someVar"); // misfitting number of params
- }).to.throwException(expectTypeError);
- });
+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 = { + myValue: 0, // copy by value + myReference: {} // copy by reference + }; + + vm.runInNewContext( + "__set__ = " + __set__.toString() + "; " + + "getValue = function () { return myValue; }; " + + "getReference = function () { return myReference; }; ", + moduleFake + ); + }); + it("should set the new value when calling with varName, varValue", function () { + expect(moduleFake.getValue()).to.be(0); + moduleFake.__set__("myValue", undefined); + expect(moduleFake.getValue()).to.be(undefined); + moduleFake.__set__("myValue", null); + expect(moduleFake.getValue()).to.be(null); + moduleFake.__set__("myValue", 2); + expect(moduleFake.getValue()).to.be(2); + moduleFake.__set__("myValue", "hello"); + expect(moduleFake.getValue()).to.be("hello"); + }); + it("should set the new reference when calling with varName, varValue", function () { + var newObj = { hello: "hello" }, + newArr = [1, 2, 3], + regExp = /123/gi; + + function newFn() { + console.log("hello"); + } + + expect(moduleFake.getReference()).to.eql({}); + moduleFake.__set__("myReference", newObj); + expect(moduleFake.getReference()).to.be(newObj); + moduleFake.__set__("myReference", newArr); + expect(moduleFake.getReference()).to.be(newArr); + moduleFake.__set__("myReference", newFn); + expect(moduleFake.getReference()).to.be(newFn); + moduleFake.__set__("myReference", regExp); + expect(moduleFake.getReference()).to.be(regExp); + }); + it("should set the new number and the new obj when calling with an env-obj", function () { + var newObj = { hello: "hello" }; + + expect(moduleFake.getValue()).to.be(0); + expect(moduleFake.getReference()).to.eql({}); + moduleFake.__set__({ + myValue: 2, + myReference: newObj + }); + expect(moduleFake.getValue()).to.be(2); + expect(moduleFake.getReference()).to.be(newObj); + }); + it("should return undefined", function () { + expect(moduleFake.__set__("myValue", 4)).to.be(undefined); + }); + 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); + expect(function () { + moduleFake.__set__({}, true); // misfitting number of params + }).to.throwException(expectTypeError); + expect(function () { + moduleFake.__set__("someVar"); // misfitting number of params + }).to.throwException(expectTypeError); + }); });
\ No newline at end of file diff --git a/test/browserify.browserifyRewire.test.js b/test/browserify.browserifyRewire.test.js index 54f4ad1..9b0680d 100644 --- a/test/browserify.browserifyRewire.test.js +++ b/test/browserify.browserifyRewire.test.js @@ -1,62 +1,61 @@ -var vm = require("vm"),
- fs = require("fs"),
- pathUtil = require("path"),
- expect = require("expect.js"),
- browserify = require("browserify");
-
-/**
- * Executes the source in a context that pretends to be a browser
- * @param {!String} src
- */
-function runInFakeBrowserContext(src, filename) {
- vm.runInNewContext(src, {
- window: {
- console: console,
- describe: describe,
- it: it,
- before: before,
- after: after,
- beforeEach: beforeEach,
- afterEach: afterEach,
- setTimeout: setTimeout,
- clearTimeout: clearTimeout,
- setInterval: setInterval,
- clearInterval: clearInterval,
- parseFloat: parseFloat,
- parseInt: parseInt,
- encodeURIComponent: function () {},
- decodeURIComponent: function () {},
- document: {}
- },
- console: console
- }, filename);
-}
-
-describe("browserifyRewire", function () {
- before(require("./testHelpers/createFakePackageJSON.js"));
- after(require("./testHelpers/removeFakePackageJSON.js"));
- it("should run all sharedTestCases without exception", function () {
- var b = browserify({debug: true}),
- middleware = require("rewire").browserify,
- browserOutput = __dirname + "/browserify/bundle.js",
- browserBundle,
- vmBundle;
-
- b.use(middleware);
- b.addEntry(__dirname + "/testModules/sharedTestCases.js");
- vmBundle = b.bundle();
- browserBundle = vmBundle;
-
- // Setup for mocha
- browserBundle = "function enableTests() {" + browserBundle + "}";
-
- /*
- vmBundle += 'window.browserifyRequire("/test/testModules/sharedTestCases.js");'; */
-
- // Output for browser-testing
- fs.writeFileSync(browserOutput, browserBundle, "utf8");
-
- // This should throw no exception.
- runInFakeBrowserContext(vmBundle, browserOutput);
- });
+var vm = require("vm"), + fs = require("fs"), + pathUtil = require("path"), + expect = require("expect.js"), + browserify = require("browserify"); + +/** + * Executes the source in a context that pretends to be a browser + * @param {!String} src + */ +function runInFakeBrowserContext(src, filename) { + vm.runInNewContext(src, { + window: { + console: console, + describe: describe, + it: it, + before: before, + after: after, + beforeEach: beforeEach, + afterEach: afterEach, + setTimeout: setTimeout, + clearTimeout: clearTimeout, + setInterval: setInterval, + clearInterval: clearInterval, + parseFloat: parseFloat, + parseInt: parseInt, + encodeURIComponent: function () {}, + decodeURIComponent: function () {}, + document: {} + }, + console: console + }, filename); +} + +describe("browserifyRewire", function () { + before(require("./testHelpers/createFakePackageJSON.js")); + after(require("./testHelpers/removeFakePackageJSON.js")); + it("should run all sharedTestCases without exception", function () { + var b = browserify({ + //debug: true + }), + middleware = require("rewire").browserify, + browserOutput = __dirname + "/browserify/bundle.js", + browserBundle, + vmBundle; + + b.use(middleware); + b.addEntry(__dirname + "/testModules/sharedTestCases.js"); + vmBundle = b.bundle(); + browserBundle = vmBundle; + + // Setup for mocha + browserBundle = "function enableTests() {" + browserBundle + "}"; + + // Output for browser-testing + fs.writeFileSync(browserOutput, browserBundle, "utf8"); + + // This should throw no exception. + runInFakeBrowserContext(vmBundle, browserOutput); + }); });
\ No newline at end of file diff --git a/test/browserify/index.html b/test/browserify/index.html index d2ff012..dc76f31 100644 --- a/test/browserify/index.html +++ b/test/browserify/index.html @@ -1,17 +1,20 @@ -<!doctype html>
-<head>
- <link rel="stylesheet" href="../../node_modules/mocha/mocha.css" />
- <script src="../../node_modules/mocha/mocha.js" type="text/javascript"></script>
- <script src="bundle.js" type="text/javascript"></script>
-</head>
-<body>
- <script type="text/javascript">
- window.onload = function () {
- console.log("These tests will only work in all browsers with the console open");
- mocha.setup("bdd");
- enableTests();
- mocha.run();
- };
- </script>
- <div id="mocha"></div>
+<!doctype html> +<head> + <link rel="stylesheet" href="../../node_modules/mocha/mocha.css" /> + <script src="../../node_modules/mocha/mocha.js" type="text/javascript"></script> + <script src="bundle.js" type="text/javascript"></script> +</head> +<body> + <script type="text/javascript"> + window.onload = function () { + console.log("These tests will only work in all browsers with the console open"); + mocha.setup({ + ui: 'bdd', + globals: [ 'someGlobalVar' ] + }); + enableTests(); + mocha.run(); + }; + </script> + <div id="mocha"></div> </body>
\ No newline at end of file diff --git a/test/detectStrictMode.test.js b/test/detectStrictMode.test.js index dad674c..89ef936 100644 --- a/test/detectStrictMode.test.js +++ b/test/detectStrictMode.test.js @@ -1,13 +1,13 @@ -var expect = require("expect.js"),
- detectStrictMode = require("../lib/detectStrictMode.js");
-
-describe("detectStrictMode", function () {
- it("should detect \"use strict\"; at the beginning of a string and ignore all whitespace before", function () {
- expect(detectStrictMode('"use strict";') === true).to.be(true);
- expect(detectStrictMode(' "use strict";') === true).to.be(true);
- expect(detectStrictMode(' \n "use strict";') === true).to.be(true);
- });
- it("should not detect \"use strict\"; if it occurs in some nested function", function () {
- expect(detectStrictMode('function () {"use strict";}') === false).to.be(true);
- });
+var expect = require("expect.js"), + detectStrictMode = require("../lib/detectStrictMode.js"); + +describe("detectStrictMode", function () { + it("should detect \"use strict\"; at the beginning of a string and ignore all whitespace before", function () { + expect(detectStrictMode('"use strict";')).to.be(true); + expect(detectStrictMode(' "use strict";')).to.be(true); + expect(detectStrictMode(' \n "use strict";')).to.be(true); + }); + it("should not detect \"use strict\"; if it occurs in some nested function", function () { + expect(detectStrictMode('function () {"use strict";}')).to.be(false); + }); });
\ No newline at end of file diff --git a/test/testModules/moduleA.js b/test/testModules/moduleA.js index ba2116e..96fc02a 100644 --- a/test/testModules/moduleA.js +++ b/test/testModules/moduleA.js @@ -1,123 +1,135 @@ -"use strict"; // run code in ES5 strict mode
-
-var someOtherModule = require("./someOtherModule.js"),
- myNumber = 0, // copy by value
- myObj = {}, // copy by reference
- env = "bla",
- 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 !== "object") {
- throw new ReferenceError("global is not an object");
- }
- if (typeof console !== "object") {
- throw new ReferenceError("console is not an object");
- }
- if (typeof require !== "function") {
- throw new ReferenceError("require is not a function");
- }
- 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");
- }
- if (typeof setTimeout !== "function") {
- throw new ReferenceError("setTimeout is not a function");
- }
- if (typeof clearTimeout !== "function") {
- throw new ReferenceError("clearTimeout is not a function");
- }
- if (typeof setInterval !== "function") {
- throw new ReferenceError("setInterval is not a function");
- }
- if (typeof clearInterval !== "function") {
- throw new ReferenceError("clearInterval is not a function");
- }
- if (typeof Error !== "function") {
- throw new ReferenceError("Error is not a function");
- }
- if (typeof parseFloat !== "function") {
- throw new ReferenceError("parseFloat is not a function");
- }
- if (typeof parseInt !== "function") {
- throw new ReferenceError("parseInt is not a function");
- }
- if (typeof window === "undefined") {
- if (typeof process !== "object") {
- throw new ReferenceError("process is not an object");
- }
- if (typeof Buffer !== "function") {
- throw new ReferenceError("Buffer is not a function");
- }
- } else {
- if (typeof encodeURIComponent !== "function") {
- throw new ReferenceError("encodeURIComponent is not a function");
- }
- if (typeof decodeURIComponent !== "function") {
- throw new ReferenceError("decodeURIComponent is not a function");
- }
- if (typeof document !== "object") {
- throw new ReferenceError("document is not an object");
- }
- }
-}
-
-function getConsole() {
- return console;
-}
-
-function getFilename() {
- return __filename;
-}
-
-function getBuffer() {
- return Buffer;
-}
-
-function getDocument() {
- return document;
-}
-
-// 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.getBuffer = getBuffer;
-exports.getDocument = getDocument;
+"use strict"; // run code in ES5 strict mode + +var someOtherModule = require("./someOtherModule.js"), + myNumber = 0, // copy by value + myObj = {}, // copy by reference + env = "bla", + 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() { + var isLowerIE, + typeOfGlobalFunc; + + if (typeof navigator !== "undefined") { + isLowerIE = /MSIE [6-8]\.[0-9]/g.test(navigator.userAgent); + } + if (isLowerIE) { + typeOfGlobalFunc = "object"; + } else { + typeOfGlobalFunc = "function"; + } + + if (typeof global !== "object") { + throw new ReferenceError("global is not an object"); + } + if (typeof console !== "object") { + throw new ReferenceError("console is not an object"); + } + if (typeof require !== "function") { + throw new ReferenceError("require is not a function"); + } + 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"); + } + if (typeof setTimeout !== typeOfGlobalFunc) { + throw new ReferenceError("setTimeout is not a function"); + } + if (typeof clearTimeout !== typeOfGlobalFunc) { + throw new ReferenceError("clearTimeout is not a function"); + } + if (typeof setInterval !== typeOfGlobalFunc) { + throw new ReferenceError("setInterval is not a function"); + } + if (typeof clearInterval !== typeOfGlobalFunc) { + throw new ReferenceError("clearInterval is not a function"); + } + if (typeof Error !== "function") { + throw new ReferenceError("Error is not a function"); + } + if (typeof parseFloat !== "function") { + throw new ReferenceError("parseFloat is not a function"); + } + if (typeof parseInt !== "function") { + throw new ReferenceError("parseInt is not a function"); + } + if (typeof window === "undefined") { + if (typeof process !== "object") { + throw new ReferenceError("process is not an object"); + } + if (typeof Buffer !== "function") { + throw new ReferenceError("Buffer is not a function"); + } + } else { + if (typeof encodeURIComponent !== "function") { + throw new ReferenceError("encodeURIComponent is not a function"); + } + if (typeof decodeURIComponent !== "function") { + throw new ReferenceError("decodeURIComponent is not a function"); + } + if (typeof document !== "object") { + throw new ReferenceError("document is not an object"); + } + } +} + +function getConsole() { + return console; +} + +function getFilename() { + return __filename; +} + +function getBuffer() { + return Buffer; +} + +function getDocument() { + return document; +} + +// 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.getBuffer = getBuffer; +exports.getDocument = getDocument; exports.someOtherModule = someOtherModule;
\ No newline at end of file diff --git a/test/testModules/moduleB.js b/test/testModules/moduleB.js index 9f7a1c7..fcdec06 100644 --- a/test/testModules/moduleB.js +++ b/test/testModules/moduleB.js @@ -1,125 +1,137 @@ -"use strict"; // run code in ES5 strict mode
-
-var someOtherModule = require("./someOtherModule.js"),
- myNumber = 0, // copy by value
- myObj = {}, // copy by reference
- env = "bla",
- 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 !== "object") {
- throw new ReferenceError("global is not an object");
- }
- if (typeof console !== "object") {
- throw new ReferenceError("console is not an object");
- }
- if (typeof require !== "function") {
- throw new ReferenceError("require is not a function");
- }
- 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"); // because we're exporting via module.exports they should not be the same.
- }
- if (typeof __dirname !== "string") {
- throw new ReferenceError("__dirname is not a string");
- }
- if (typeof __filename !== "string") {
- throw new ReferenceError("__filename is not a string");
- }
- if (typeof setTimeout !== "function") {
- throw new ReferenceError("setTimeout is not a function");
- }
- if (typeof clearTimeout !== "function") {
- throw new ReferenceError("clearTimeout is not a function");
- }
- if (typeof setInterval !== "function") {
- throw new ReferenceError("setInterval is not a function");
- }
- if (typeof clearInterval !== "function") {
- throw new ReferenceError("clearInterval is not a function");
- }
- if (typeof Error !== "function") {
- throw new ReferenceError("Error is not a function");
- }
- if (typeof parseFloat !== "function") {
- throw new ReferenceError("parseFloat is not a function");
- }
- if (typeof parseInt !== "function") {
- throw new ReferenceError("parseInt is not a function");
- }
- if (typeof window === "undefined") {
- if (typeof process !== "object") {
- throw new ReferenceError("process is not an object");
- }
- if (typeof Buffer !== "function") {
- throw new ReferenceError("Buffer is not a function");
- }
- } else {
- if (typeof encodeURIComponent !== "function") {
- throw new ReferenceError("encodeURIComponent is not a function");
- }
- if (typeof decodeURIComponent !== "function") {
- throw new ReferenceError("decodeURIComponent is not a function");
- }
- if (typeof document !== "object") {
- throw new ReferenceError("document is not an object");
- }
- }
-}
-
-function getConsole() {
- return console;
-}
-
-function getFilename() {
- return __filename;
-}
-
-function getBuffer() {
- return Buffer;
-}
-
-function getDocument() {
- return document;
-}
-
-// different styles of exports in moduleA.js and moduleB.js
-module.exports = {
- setMyNumber: setMyNumber,
- getMyNumber: getMyNumber,
- setMyObj: setMyObj,
- getMyObj: getMyObj,
- readFileSync: readFileSync,
- checkSomeGlobals: checkSomeGlobals,
- getConsole: getConsole,
- getFilename: getFilename,
- getBuffer: getBuffer,
- getDocument: getDocument,
- someOtherModule: someOtherModule
-};
+"use strict"; // run code in ES5 strict mode + +var someOtherModule = require("./someOtherModule.js"), + myNumber = 0, // copy by value + myObj = {}, // copy by reference + env = "bla", + 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() { + var isLowerIE, + typeOfGlobalFunc; + + if (typeof navigator !== "undefined") { + isLowerIE = /MSIE [6-8]\.[0-9]/g.test(navigator.userAgent); + } + if (isLowerIE) { + typeOfGlobalFunc = "object"; + } else { + typeOfGlobalFunc = "function"; + } + + if (typeof global !== "object") { + throw new ReferenceError("global is not an object"); + } + if (typeof console !== "object") { + throw new ReferenceError("console is not an object"); + } + if (typeof require !== "function") { + throw new ReferenceError("require is not a function"); + } + 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"); + } + if (typeof __dirname !== "string") { + throw new ReferenceError("__dirname is not a string"); + } + if (typeof __filename !== "string") { + throw new ReferenceError("__filename is not a string"); + } + if (typeof setTimeout !== typeOfGlobalFunc) { + throw new ReferenceError("setTimeout is not a function"); + } + if (typeof clearTimeout !== typeOfGlobalFunc) { + throw new ReferenceError("clearTimeout is not a function"); + } + if (typeof setInterval !== typeOfGlobalFunc) { + throw new ReferenceError("setInterval is not a function"); + } + if (typeof clearInterval !== typeOfGlobalFunc) { + throw new ReferenceError("clearInterval is not a function"); + } + if (typeof Error !== "function") { + throw new ReferenceError("Error is not a function"); + } + if (typeof parseFloat !== "function") { + throw new ReferenceError("parseFloat is not a function"); + } + if (typeof parseInt !== "function") { + throw new ReferenceError("parseInt is not a function"); + } + if (typeof window === "undefined") { + if (typeof process !== "object") { + throw new ReferenceError("process is not an object"); + } + if (typeof Buffer !== "function") { + throw new ReferenceError("Buffer is not a function"); + } + } else { + if (typeof encodeURIComponent !== "function") { + throw new ReferenceError("encodeURIComponent is not a function"); + } + if (typeof decodeURIComponent !== "function") { + throw new ReferenceError("decodeURIComponent is not a function"); + } + if (typeof document !== "object") { + throw new ReferenceError("document is not an object"); + } + } +} + +function getConsole() { + return console; +} + +function getFilename() { + return __filename; +} + +function getBuffer() { + return Buffer; +} + +function getDocument() { + return document; +} + +// different styles of exports in moduleA.js and moduleB.js +module.exports = { + setMyNumber: setMyNumber, + getMyNumber: getMyNumber, + setMyObj: setMyObj, + getMyObj: getMyObj, + readFileSync: readFileSync, + checkSomeGlobals: checkSomeGlobals, + getConsole: getConsole, + getFilename: getFilename, + getBuffer: getBuffer, + getDocument: getDocument, + someOtherModule: someOtherModule +}; diff --git a/test/testModules/sharedTestCases.js b/test/testModules/sharedTestCases.js index 7c6c253..c558af0 100644 --- a/test/testModules/sharedTestCases.js +++ b/test/testModules/sharedTestCases.js @@ -1,205 +1,207 @@ -// Don't run code in ES5 strict mode.
-// In case this module was in strict mode, all other modules called by this would also be strict.
-// But when testing if the strict mode is preserved, we must ensure that this module is NOT strict.
-
-var path = require("path"),
- expect = require("expect.js"),
- rewire = require("rewire");
-
-var testModules = {
- A: path.resolve(__dirname, "./moduleA.js"),
- B: path.resolve(__dirname, "./moduleB.js"),
- someOtherModule: path.resolve(__dirname, "./someOtherModule.js"),
- emptyModule: path.resolve(__dirname, "./emptyModule.js"),
- strictModule: path.resolve(__dirname, "./strictModule.js")
- };
-
-
-function checkForTypeError(err) {
- expect(err.constructor === TypeError).to.be(true);
-}
-
-function cleanRequireCache() {
- var moduleName,
- modulePath;
-
- for (moduleName in testModules) {
- if (testModules.hasOwnProperty(moduleName)) {
- modulePath = testModules[moduleName];
- delete require.cache[modulePath];
- }
- }
-}
-
-describe("rewire " + (typeof window === "undefined"? "(node.js)": "(browser)"), function () {
- afterEach(cleanRequireCache); // ensuring a clean test environment
- it("should work like require()", function () {
- expect(rewire("./moduleA.js") === require("./moduleA.js")).to.be(true);
- cleanRequireCache();
- expect(rewire("../testModules/moduleA.js") === require("../testModules/moduleA.js")).to.be(true);
- cleanRequireCache();
- expect(rewire("./moduleA.js") === require("./moduleA.js")).to.be(true);
- });
- it("should modify the module so it provides a __set__ - function", function () {
- expect(rewire("./moduleA.js").__set__).to.be.a(Function);
- expect(rewire("./moduleB.js").__set__).to.be.a(Function);
- });
- it("should modify the module so it provides a __get__ - function", function () {
- expect(rewire("./moduleA.js").__get__).to.be.a(Function);
- expect(rewire("./moduleB.js").__get__).to.be.a(Function);
- });
- it("should not influence other modules", function () {
- var rewiredModuleA = rewire("./moduleA.js");
-
- expect(require("./someOtherModule.js").__set__ === undefined).to.be(true);
- expect(require("./someOtherModule.js").__get__ === undefined).to.be(true);
- expect(require("fs").__set__ === undefined).to.be(true);
- expect(require("fs").__get__ === undefined).to.be(true);
- });
- it("should not override/influence global objects by default", function () {
- // This should throw no exception
- rewire("./moduleA.js").checkSomeGlobals();
- rewire("./moduleB.js").checkSomeGlobals();
- });
- it("should provide the ability to set private vars", function () {
- var rewiredModuleA = rewire("./moduleA.js"),
- newObj = {};
-
- expect(rewiredModuleA.getMyNumber() === 0).to.be(true);
- rewiredModuleA.__set__("myNumber", 2);
- expect(rewiredModuleA.getMyNumber() === 2).to.be(true);
- rewiredModuleA.__set__("myObj", newObj);
- expect(rewiredModuleA.getMyObj() === newObj).to.be(true);
- rewiredModuleA.__set__("env", "ENVENV");
- });
- it("should provide the ability to get private vars", function () {
- var rewiredModuleA = rewire("./moduleA.js");
-
- expect(rewiredModuleA.__get__("myNumber") === rewiredModuleA.getMyNumber()).to.be(true);
- expect(rewiredModuleA.__get__("myObj") === rewiredModuleA.getMyObj()).to.be(true);
- });
- it("should provide the ability to inject mocks", function (done) {
- var rewiredModuleA = rewire("./moduleA.js"),
- mockedFs = {
- readFileSync: function (file) {
- expect(file === "bla.txt").to.be(true);
- done();
- }
- };
-
- rewiredModuleA.__set__("fs", mockedFs);
- rewiredModuleA.readFileSync();
- });
- it("should not influence other modules when injecting mocks", function () {
- var rewiredModuleA = rewire("./moduleA.js"),
- someOtherModule,
- mockedFs = {};
-
- rewiredModuleA.__set__("fs", mockedFs);
- someOtherModule = require("./someOtherModule.js");
- expect(someOtherModule.fs === mockedFs).to.be(false);
- });
- it("should provide the ability to mock global objects just within the module", function () {
- var rewiredModuleA = rewire("./moduleA.js"),
- rewiredModuleB = rewire("./moduleB.js"),
- consoleMock = {},
- bufferMock = {},
- documentMock = {},
- newFilename = "myFile.js";
-
- rewiredModuleA.__set__({
- console: consoleMock,
- __filename: newFilename
- });
- expect(rewiredModuleA.getConsole() === consoleMock).to.be(true);
- expect(rewiredModuleB.getConsole() === consoleMock).to.be(false);
- expect(console === consoleMock).to.be(false);
- expect(rewiredModuleA.getFilename() === newFilename).to.be(true);
- expect(rewiredModuleB.getFilename() === newFilename).to.be(false);
- expect(console === newFilename).to.be(false);
- if (typeof window === "undefined") {
- rewiredModuleA.__set__("Buffer", bufferMock);
- expect(rewiredModuleA.getBuffer() === bufferMock).to.be(true);
- expect(rewiredModuleB.getBuffer() === bufferMock).to.be(false);
- expect(Buffer === bufferMock).to.be(false);
- } else {
- rewiredModuleA.__set__("document", documentMock);
- expect(rewiredModuleA.getDocument() === documentMock).to.be(true);
- expect(rewiredModuleB.getDocument() === documentMock === false).to.be(true);
- expect(document === documentMock === false).to.be(true);
- }
- });
- it("should be possible to mock global objects that are added on runtime", function () {
- var rewiredModule;
-
- if (typeof window === "undefined") {
- global.someGlobalVar = "test";
- rewiredModule = rewire("./moduleA.js");
- rewiredModule.__set__("someGlobalVar", "other value");
- expect(global.someGlobalVar === "test").to.be(true);
- expect(rewiredModule.__get__("someGlobalVar") === "other value").to.be(true);
- delete global.someGlobalVar;
- } else {
- window.someGlobalVar = "test";
- rewiredModule = rewire("./moduleA.js");
- rewiredModule.__set__("someGlobalVar", "other value");
- expect(window.someGlobalVar === "test").to.be(true);
- expect(rewiredModule.__get__("someGlobalVar") === "other value").to.be(true);
- delete window.someGlobalVar;
- }
- });
- it("should cache the rewired module", function () {
- var rewired;
-
- rewired = rewire("./someOtherModule.js");
- expect(require("./moduleA.js").someOtherModule === rewired).to.be(true);
- cleanRequireCache();
- rewired = rewire("./someOtherModule.js", true);
- expect(require("./moduleA.js").someOtherModule === rewired).to.be(true);
- });
- it("should not cache the rewired module on demand", function () {
- var rewired,
- someOtherModule = require("./someOtherModule.js");
-
- someOtherModule.fs = "This has been changed";
-
- rewired = rewire("./someOtherModule.js", false);
- expect(require("./moduleA.js").someOtherModule === rewired).to.be(false);
- expect(require("./moduleA.js").someOtherModule.fs === "This has been changed").to.be(true);
- });
- 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__ === undefined).to.be(true); // 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") === rewire("./moduleA.js")).to.be(false);
- });
- 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 === "This has been modified").to.be(false);
- });
- describe("#reset", function () {
- it("should remove all rewired modules from cache", function () {
- var rewiredModuleA = rewire("./moduleA.js"),
- rewiredModuleB = rewire("./moduleB.js");
-
- expect(require("./moduleA.js") === rewiredModuleA).to.be(true);
- expect(require("./moduleB.js") === rewiredModuleB).to.be(true);
- rewire.reset();
- expect(require("./moduleA.js") === rewiredModuleA).to.be(false);
- expect(require("./moduleB.js") === rewiredModuleB).to.be(false);
- });
- });
+// Don't run code in ES5 strict mode. +// In case this module was in strict mode, all other modules called by this would also be strict. +// But when testing if the strict mode is preserved, we must ensure that this module is NOT strict. + +var path = require("path"), + expect = require("expect.js"), + rewire = require("rewire"); + +var testModules = { + A: path.resolve(__dirname, "./moduleA.js"), + B: path.resolve(__dirname, "./moduleB.js"), + someOtherModule: path.resolve(__dirname, "./someOtherModule.js"), + emptyModule: path.resolve(__dirname, "./emptyModule.js"), + strictModule: path.resolve(__dirname, "./strictModule.js") + }; + + +function checkForTypeError(err) { + expect(err.constructor).to.be(TypeError); +} + +function cleanRequireCache() { + var moduleName, + modulePath; + + for (moduleName in testModules) { + if (testModules.hasOwnProperty(moduleName)) { + modulePath = testModules[moduleName]; + delete require.cache[modulePath]; + } + } +} + +describe("rewire " + (typeof window === "undefined"? "(node.js)": "(browser)"), function () { + afterEach(cleanRequireCache); // ensuring a clean test environment + it("should work like require()", function () { + expect(rewire("./moduleA.js")).to.be(require("./moduleA.js")); + cleanRequireCache(); + expect(rewire("../testModules/moduleA.js")).to.be(require("../testModules/moduleA.js")); + cleanRequireCache(); + expect(rewire("./moduleA.js")).to.be(require("./moduleA.js")); + }); + it("should modify the module so it provides a __set__ - function", function () { + expect(rewire("./moduleA.js").__set__).to.be.a(Function); + expect(rewire("./moduleB.js").__set__).to.be.a(Function); + }); + it("should modify the module so it provides a __get__ - function", function () { + expect(rewire("./moduleA.js").__get__).to.be.a(Function); + expect(rewire("./moduleB.js").__get__).to.be.a(Function); + }); + it("should not influence other modules", function () { + var rewiredModuleA = rewire("./moduleA.js"); + + expect(require("./someOtherModule.js").__set__).to.be(undefined); + expect(require("./someOtherModule.js").__get__).to.be(undefined); + expect(require("fs").__set__).to.be(undefined); + expect(require("fs").__get__).to.be(undefined); + }); + it("should not override/influence global objects by default", function () { + // This should throw no exception + rewire("./moduleA.js").checkSomeGlobals(); + rewire("./moduleB.js").checkSomeGlobals(); + }); + it("should provide the ability to set private vars", function () { + var rewiredModuleA = rewire("./moduleA.js"), + 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); + rewiredModuleA.__set__("env", "ENVENV"); + }); + it("should provide the ability to get private vars", function () { + var rewiredModuleA = rewire("./moduleA.js"); + + expect(rewiredModuleA.__get__("myNumber")).to.be(rewiredModuleA.getMyNumber()); + expect(rewiredModuleA.__get__("myObj")).to.be(rewiredModuleA.getMyObj()); + }); + it("should provide the ability to inject mocks", function (done) { + var rewiredModuleA = rewire("./moduleA.js"), + mockedFs = { + readFileSync: function (file) { + expect(file).to.be("bla.txt"); + done(); + } + }; + + rewiredModuleA.__set__("fs", mockedFs); + rewiredModuleA.readFileSync(); + }); + it("should not influence other modules when injecting mocks", function () { + var rewiredModuleA = rewire("./moduleA.js"), + someOtherModule, + mockedFs = {}; + + rewiredModuleA.__set__("fs", mockedFs); + someOtherModule = require("./someOtherModule.js"); + expect(someOtherModule.fs).not.to.be(mockedFs); + }); + it("should provide the ability to mock global objects just within the module", function () { + var rewiredModuleA = rewire("./moduleA.js"), + rewiredModuleB = rewire("./moduleB.js"), + consoleMock = {}, + bufferMock = {}, + documentMock = {}, + newFilename = "myFile.js"; + + rewiredModuleA.__set__({ + console: consoleMock, + __filename: newFilename + }); + expect(rewiredModuleA.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()).not.to.be(newFilename); + expect(console).not.to.be(newFilename); + if (typeof window === "undefined") { + rewiredModuleA.__set__("Buffer", bufferMock); + expect(rewiredModuleA.getBuffer()).to.be(bufferMock); + expect(rewiredModuleB.getBuffer()).not.to.be(bufferMock); + expect(Buffer).not.to.be(bufferMock); + } else { + rewiredModuleA.__set__("document", documentMock); + expect(rewiredModuleA.getDocument()).to.be(documentMock); + expect(rewiredModuleB.getDocument() === documentMock).to.be(false); + expect(document === documentMock).to.be(false); + } + }); + it("should be possible to mock global objects that are added on runtime", function () { + var rewiredModule; + + if (typeof window === "undefined") { + global.someGlobalVar = "test"; + rewiredModule = rewire("./moduleA.js"); + rewiredModule.__set__("someGlobalVar", "other value"); + expect(global.someGlobalVar).to.be("test"); + expect(rewiredModule.__get__("someGlobalVar")).to.be("other value"); + delete global.someGlobalVar; + } else { + window.someGlobalVar = "test"; + rewiredModule = rewire("./moduleA.js"); + rewiredModule.__set__("someGlobalVar", "other value"); + expect(window.someGlobalVar).to.be("test"); + expect(rewiredModule.__get__("someGlobalVar")).to.be("other value"); + if (typeof navigator !== "undefined" && /MSIE [6-8]\.[0-9]/g.test(navigator.userAgent) === false) { + delete window.someGlobalVar; + } + } + }); + it("should cache the rewired module", function () { + var rewired; + + rewired = rewire("./someOtherModule.js"); + expect(require("./moduleA.js").someOtherModule).to.be(rewired); + cleanRequireCache(); + rewired = rewire("./someOtherModule.js", true); + expect(require("./moduleA.js").someOtherModule).to.be(rewired); + }); + it("should not cache the rewired module on demand", function () { + var rewired, + someOtherModule = require("./someOtherModule.js"); + + someOtherModule.fs = "This has been changed"; + + rewired = rewire("./someOtherModule.js", false); + expect(require("./moduleA.js").someOtherModule).not.to.be(rewired); + expect(require("./moduleA.js").someOtherModule.fs).to.be("This has been changed"); + }); + 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 (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"), + rewiredModuleB = rewire("./moduleB.js"); + + expect(require("./moduleA.js")).to.be(rewiredModuleA); + expect(require("./moduleB.js")).to.be(rewiredModuleB); + rewire.reset(); + expect(require("./moduleA.js")).not.to.be(rewiredModuleA); + expect(require("./moduleB.js")).not.to.be(rewiredModuleB); + }); + }); });
\ No newline at end of file |