8000 all tests up and running · ShMcK/rewire-coderoad@07496ad · GitHub
[go: up one dir, main page]

Skip to content

Commit 07496ad

Browse files
committed
all tests up and running
1 parent fb06490 commit 07496ad

14 files changed

+380
-0
lines changed

LICENSE

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Copyright (c) 2012 Nathan MacInnes
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
this software and associated documentation files (the "Software"), to deal in
5+
the Software without restriction, including without limitation the rights to
6+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7+
the Software, and to permit persons to whom the Software is furnished to do so,
8+
subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
test:
2+
mocha -R spec
3+
4+
.PHONY: test

lib/getLeakingSrc.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"use strict"; // run code in ES5 strict mode
2+
3+
function getLeakingSrc(leaks) {
4+
var src = "exports.__ = {",
5+
varName,
6+
i;
7+
8+
for (i = 0; i < leaks.length; i++) {
9+
varName = leaks[i];
10+
src += (varName + ":" + varName + ",");
11+
}
12+
if (i > 0) {
13+
src = src.slice(0, -1); // trim last comma
14+
}
15+
src += "};";
16+
17+
return src;
18+
}
19+
20+
module.exports = getLeakingSrc;

lib/getMonkeyPatchSrc.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"use strict"; // run code in ES5 strict mode
2+
3+
var toSrc = require("toSrc");
4+
5+
function getMonkeyPatchSrc(obj) {
6+
function walkObj(obj, level) {
7+
var key,
8+
value,
9+
src = "";
10+
11+
for (key in obj) {
12+
if (obj.hasOwnProperty(key)) {
13+
value = obj[key];
14+
if (typeof value === "object" && Array.isArray(value) === false) {
15+
src += key + ".";
16+
src += walkObj(value, level + 1);
17+
} else {
18+
if (level === 0) {
19+
src += "var "; // in the top level, we need a var statement to override variables
20+
}
21+
src += key + "=" + toSrc(value, 9999) + ";";
22+
}
23+
}
24+
}
25+
26+
27+
return src;
28+
}
29+
30+
return walkObj(obj, 0);
31+
}
32+
33+
module.exports = getMonkeyPatchSrc;

lib/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"use strict"; // run code in ES5 strict mode
2+
3+
var trick = require("./trick.js");
4+
5+
module.exports = function (request, mocks, injections, leaks, cache) {
6+
delete require.cache[__filename]; // deleting self from module cache so the parent module is always up to date
7+
8+
if (cache === undefined) {
9+
cache = true;
10+
}
11+
12+
return trick(module.parent, request, mocks, injections, leaks, cache);
13+
};

lib/trick.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"use strict"; // run code in ES5 strict mode
2+
3+
var Module = require("module"),
4+
nodeWrapper0 = Module.wrapper[0], // caching original wrapper
5+
nodeWrapper1 = Module.wrapper[1],
6+
getLeakingSrc = require("./getLeakingSrc.js"),
7+
getMonkeyPatchSrc = require("./getMonkeyPatchSrc.js");
8+
9+
function restoreOriginalWrappers() {
10+
Module.wrapper[0] = nodeWrapper0;
11+
Module.wrapper[1] = nodeWrapper1;
12+
}
13+
14+
function trick(parentModule, filename, mocks, injections, leaks, cache) {
15+
var testModule,
16+
nodeRequire;
17+
18+
function requireTrick(path) {
19+
restoreOriginalWrappers(); // we need to restore the wrappers now so we don't influence other modules
20+
21+
if (mocks && mocks.hasOwnProperty(path)) {
22+
return mocks[path];
23+
} else {
24+
return nodeRequire.call(testModule, path); // node's require only works when "this" points to the module
25+
}
26+
}
27+
28+
// Checking params
29+
if (typeof filename !== "string") {
30+
throw new TypeError("Filename must be a string");
31+
}
32+
33+
// Init vars
34+
filename = Module._resolveFilename(filename, parentModule); // resolve full filename relative to the parent module
35+
testModule = new Module(filename, parentModule);
36+
nodeRequire = testModule.require; // caching original node require
37+
38+
// Prepare module for injection
39+
if (typeof injections === "object") {
40+
Module.wrapper[0] = nodeWrapper0 + getMonkeyPatchSrc(injections);
41+
} else if (typeof injections === "string") {
42+
Module.wrapper[0] = nodeWrapper0 + injections;
43+
}
44+
45+
// Prepare module for leaking private vars
46+
if (Array.isArray(leaks)) {
47+
Module.wrapper[1] = getLeakingSrc(leaks) + nodeWrapper1;
48+
}
49+
50+
// Mocking module.require-function
51+
testModule.require = requireTrick;
52+
// Loading module
53+
testModule.load(testModule.id);
54+
55+
if (cache) {
56+
require.cache[filename] = testModule;
57+
}
58+
59+
restoreOriginalWrappers(); // this is only necessary if nothing has been required within the module
60+
61+
return testModule.exports;
62+
}
63+
64+
module.exports = trick;

package.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"name" : "trick",
3+
"version" : "0.1.0",
4+
"description" : "Dependency injection for node.js applications",
5+
"keywords" : [
6+
"dependency",
7+
"injection",
8+
"mock",
9+
"unit",
10+
"test"
11+
],
12+
"author" : {
13+
"name" : "Johannes Ewald",
14+
"email" : "mail@johannesewald.de",
15+
"web" : "http://johannesewald.de"
16+
},
17+
"main" : "lib/index.js",
18+
"bugs" : {
19+
"email" : "mail@johannesewald.de",
20+
"url" : "https://github.com/jhnns/trick/issues"
21+
},
22+
"licenses" : {
23+
"type" : "MIT",
24+
"url" : "http: //www.opensource.org/licenses/mit-license.php"
25+
},
26+
"repositories" : {
27+
"type" : "git",
28+
"url" : "https://github.com/jhnns/trick"
29+
},
30+
"engines" : {
31+
"node" : "0.6.x"
32+
},
33+
"dependencies": {
34+
"toSrc": "0.1.x"
35+
},
36+
"devDependencies": {
37+
"mocha": "1.1.x",
38+
"expect.js": "0.1.x"
39+
},
40+
"scripts" : {
41+
"test" : "make test"
42+
}
43+
}

test/getLeakingSrc.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"use strict"; // run code in ES5 strict mode
2+
3+
var expect = require("expect.js"),
4+
getLeakingWrapper = require("../lib/getLeakingSrc.js");
5+
6+
describe("#getLeakingWrapper", function () {
7+
it("should return 'exports.__ = {};'", function () {
8+
expect(getLeakingWrapper([])).to.be("exports.__ = {};");
9+
});
10+
it("should return 'exports.__ = {somethingPrivate:somethingPrivate,somethingSecret:somethingSecret};'", function () {
11+
var leakArr = ["somethingPrivate", "somethingSecret"];
12+
13+
expect(getLeakingWrapper(leakArr))
14+
.to.be("exports.__ = {somethingPrivate:somethingPrivate,somethingSecret:somethingSecret};");
15+
});
16+
});

test/getMonkeyPatchSrc.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"use strict"; // run code in ES5 strict mode
2+
3+
var expect = require("expect.js"),
4+
getMonkeyPatchSrc = require("../lib/getMonkeyPatchSrc.js");
5+
6+
describe("#getMonkeyPatchSrc", function () {
7+
it("should return ''", function () {
8+
var expectedSrc = "",
9+
subject = {};
10+
11+
expect(getMonkeyPatchSrc(subject)).to.be(expectedSrc);
12+
});
13+
it("should return 'process.argv=[\"myArg1\", \"myArg2\"];var console=456;'", function () {
14+
var expectedSrc = "process.argv=[\"myArg1\", \"myArg2\"];var console=456;",
15+
subject = {
16+
process: {
17+
argv: ["myArg1", "myArg2"]
18+
},
19+
console: 456
20+
};
21+
22+
expect(getMonkeyPatchSrc(subject)).to.be(expectedSrc);
23+
});
24+
it("should return 'level1.level2.level3.level4.level5=true;", function () {
25+
var expectedSrc = "level1.level2.level3.level4.level5=true;",
26+
subject = {level1: {level2: {level3: {level4: {level5: true}}}}};
27+
28+
expect(getMonkeyPatchSrc(subject)).to.be(expectedSrc);
29+
});
30+
});

test/testModules/A/moduleA.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"use strict"; // run code in ES5 strict mode
2+
3+
var path = require("path"),
4+
5+
// different ways to require a module
6+
fs = require("fs"), // native module
7+
c = require("../C/moduleC.js"), // relative path
8+
b = require(path.resolve(__dirname, "../B/moduleB.js")), // absolute path
9+
toSrc = require("toSrc"), // node_modules path
10+
index = require("../"); // index.js path
11+
12+
var myPrivateVar = "Hello I'm very private";
13+
14+
// expose all required modules to test for mocks
15+
exports.fs = fs;
16+
exports.b = b;
17+
exports.c = c;
18+
exports.toSrc = toSrc;
19+
exports.index = index;
20+
exports.process = process;
21+
exports.console = console;

test/testModules/B/moduleB.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"use strict"; // run code in ES5 strict mode
2+
3+
var c = require("../C/moduleC.js");
4+
5+
exports.requireIndex = function () { // necessary to avoid circular dependency
6+
exports.index = require("../index.js");
7+
};

test/testModules/C/moduleC.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"use strict"; // run code in ES5 strict mode
2+
3+
module.exports = "c";

test/testModules/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"use strict"; // run code in ES5 strict mode
2+
3+
exports.a = require("./A/moduleA.js");
4+
exports.b = require("./B/moduleB.js");
5+
exports.c = require("./C/moduleC.js");

0 commit comments

Comments
 (0)
0