Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7db6092

Browse files
committed
captures imports for testing
1 parent0e4c439 commit7db6092

File tree

5 files changed

+43
-270
lines changed

5 files changed

+43
-270
lines changed

‎README.md

Lines changed: 4 additions & 248 deletions
Original file line numberDiff line numberDiff line change
@@ -1,250 +1,6 @@
1-
rewire
2-
======
3-
**Easy monkey-patching for node.js unit tests**
1+
#CodeRoad Rewire
42

5-
[![](https://img.shields.io/npm/v/rewire.svg)](https://www.npmjs.com/package/rewire)
6-
[![](https://img.shields.io/npm/dm/rewire.svg)](https://www.npmjs.com/package/rewire)
7-
[![Dependency Status](https://david-dm.org/jhnns/rewire.svg)](https://david-dm.org/jhnns/rewire)
8-
[![Build Status](https://travis-ci.org/jhnns/rewire.svg?branch=master)](https://travis-ci.org/rewire/jhnns)
9-
[![Coverage Status](https://img.shields.io/coveralls/jhnns/rewire.svg)](https://coveralls.io/r/jhnns/rewire?branch=master)
3+
Implementation for testing globals in the interactive coding tutorial framework[CodeRoad](https://coderoad.github.io).
104

11-
rewire adds a special setter and getter to modules so you can modify their behaviour for better unit testing. You may
12-
13-
- inject mocks for other modules or globals like`process`
14-
- inspect private variables
15-
- override variables within the module.
16-
17-
rewire does**not** load the file and eval the contents to emulate node's require mechanism. In fact it uses node's own require to load the module. Thus your module behaves exactly the same in your test environment as under regular circumstances (except your modifications).
18-
19-
**Please note:** The current version of rewire is not compatible with`const` or[babel](http://babeljs.io/). See[Limitations](https://github.com/jhnns/rewire#limitations).
20-
21-
<br>
22-
23-
Installation
24-
------------
25-
26-
`npm install rewire`
27-
28-
<br />
29-
30-
Introduction
31-
------------
32-
33-
Imagine you want to test this module:
34-
35-
```javascript
36-
// lib/myModules.js
37-
// With rewire you can change all these variables
38-
var fs=require("fs"),
39-
path="/somewhere/on/the/disk";
40-
41-
functionreadSomethingFromFileSystem(cb) {
42-
console.log("Reading from file system ...");
43-
fs.readFile(path,"utf8", cb);
44-
}
45-
46-
exports.readSomethingFromFileSystem= readSomethingFromFileSystem;
47-
```
48-
49-
Now within your test module:
50-
51-
```javascript
52-
// test/myModule.test.js
53-
var rewire=require("rewire");
54-
55-
var myModule=rewire("../lib/myModule.js");
56-
```
57-
58-
rewire acts exactly like require. With just one difference: Your module will now export a special setter and getter for private variables.
59-
60-
```javascript
61-
myModule.__set__("path","/dev/null");
62-
myModule.__get__("path");// = '/dev/null'
63-
```
64-
65-
This allows you to mock everything in the top-level scope of the module, like the fs module for example. Just pass the variable name as first parameter and your mock as second.
66-
67-
```javascript
68-
var fsMock= {
69-
readFile:function (path,encoding,cb) {
70-
expect(path).to.equal("/somewhere/on/the/disk");
71-
cb(null,"Success!");
72-
}
73-
};
74-
myModule.__set__("fs", fsMock);
75-
76-
myModule.readSomethingFromFileSystem(function (err,data) {
77-
console.log(data);// = Success!
78-
});
79-
```
80-
81-
You can also set multiple variables with one call.
82-
83-
```javascript
84-
myModule.__set__({
85-
fs: fsMock,
86-
path:"/dev/null"
87-
});
88-
```
89-
90-
You may also override globals. These changes are only within the module, so you don't have to be concerned that other modules are influenced by your mock.
91-
92-
```javascript
93-
myModule.__set__({
94-
console: {
95-
log:function () {/* be quiet*/ }
96-
},
97-
process: {
98-
argv: ["testArg1","testArg2"]
99-
}
100-
});
101-
```
102-
103-
`__set__` returns a function which reverts the changes introduced by this particular`__set__` call
104-
105-
```javascript
106-
var revert=myModule.__set__("port",3000);
107-
108-
// port is now 3000
109-
revert();
110-
// port is now the previous value
111-
```
112-
113-
For your convenience you can also use the`__with__` method which reverts the given changes after it finished.
114-
115-
```javascript
116-
myModule.__with__({
117-
port:3000
118-
})(function () {
119-
// within this function port is 3000
120-
});
121-
// now port is the previous value again
122-
```
123-
124-
The`__with__` method is also aware of promises. If a thenable is returned all changes stay until the promise has either been resolved or rejected.
125-
126-
```javascript
127-
myModule.__with__({
128-
port:3000
129-
})(function () {
130-
returnnewPromise(...);
131-
}).then(function () {
132-
// now port is the previous value again
133-
});
134-
// port is still 3000 here because the promise hasn't been resolved yet
135-
```
136-
137-
<br />
138-
139-
Limitations
140-
-----------
141-
142-
**Using`const`**<br>
143-
It's not possible to rewire`const` (see[#79](https://github.com/jhnns/rewire/issues/79)). This can probably be solved with[proxies](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy) someday but requires further research.
144-
145-
**Transpilers**<br>
146-
Some transpilers, like babel, rename variables in order to emulate certain language features. Rewire will not work in these cases (see[#62](https://github.com/jhnns/rewire/issues/62)). A possible solution might be switching to[babel-plugin-rewire](https://github.com/speedskater/babel-plugin-rewire).
147-
148-
**Variables inside functions**<br>
149-
Variables inside functions can not be changed by rewire. This is constrained by the language.
150-
151-
```javascript
152-
// myModule.js
153-
(function () {
154-
// Can't be changed by rewire
155-
var someVariable;
156-
})()
157-
```
158-
159-
**Modules that export primitives**<br>
160-
rewire is not able to attach the`__set__`- and`__get__`-method if your module is just exporting a primitive. Rewiring does not work in this case.
161-
162-
```javascript
163-
// Will throw an error if it's loaded with rewire()
164-
module.exports=2;
165-
```
166-
167-
**Globals with invalid variable names**<br>
168-
rewire imports global variables into the local scope by prepending a list of`var` declarations:
169-
170-
```javascript
171-
var someGlobalVar=global.someGlobalVar;
172-
```
173-
174-
If`someGlobalVar` is not a valid variable name, rewire just ignores it.**In this case you're not able to override the global variable locally**.
175-
176-
**Special globals**<br>
177-
Please be aware that you can't rewire`eval()` or the global object itself.
178-
179-
180-
<br />
181-
182-
API
183-
---
184-
185-
###rewire(filename: String): rewiredModule
186-
187-
Returns a rewired version of the module found at`filename`. Use`rewire()` exactly like`require()`.
188-
189-
###rewiredModule.&#95;&#95;set&#95;&#95;(name: String, value:*): Function
190-
191-
Sets the internal variable`name` to the given`value`. Returns a function which can be called to revert the change.
192-
193-
###rewiredModule.&#95;&#95;set&#95;&#95;(obj: Object): Function
194-
195-
Takes all enumerable keys of`obj` as variable names and sets the values respectively. Returns a function which can be called to revert the change.
196-
197-
###rewiredModule.&#95;&#95;get&#95;&#95;(name: String): *
198-
199-
Returns the private variable with the given`name`.
200-
201-
###rewiredModule.&#95;&#95;with&#95;&#95;(obj: Object): Function&lt;callback: Function>
202-
203-
Returns a function which - when being called - sets`obj`, executes the given`callback` and reverts`obj`. If`callback` returns a promise,`obj` is only reverted after the promise has been resolved or rejected. For your convenience the returned function passes the received promise through.
204-
205-
<br />
206-
207-
Caveats
208-
-------
209-
210-
**Difference to require()**<br>
211-
Every call of rewire() executes the module again and returns a fresh instance.
212-
213-
```javascript
214-
rewire("./myModule.js")===rewire("./myModule.js");// = false
215-
```
216-
217-
This can especially be a problem if the module is not idempotent[like mongoose models](https://github.com/jhnns/rewire/issues/27).
218-
219-
**Globals are imported into the module's scope at the time of rewiring**<br>
220-
Since rewire imports all gobals into the module's scope at the time of rewiring, property changes on the`global` object after that are not recognized anymore. This is a[problem when using sinon's fake timers*after* you've called`rewire()`](http://stackoverflow.com/questions/34885024/when-using-rewire-and-sinon-faketimer-order-matters/36025128).
221-
222-
**Dot notation**<br>
223-
Although it is possible to use dot notation when calling`__set__`, it is strongly discouraged in most cases. For instance, writing`myModule.__set__("console.log", fn)` is effectively the same as just writing`console.log = fn`. It would be better to write:
224-
225-
```javascript
226-
myModule.__set__("console", {
227-
log:function () {}
228-
});
229-
```
230-
231-
This replaces`console` just inside`myModule`. That is, because rewire is using`eval()` to turn the key expression into an assignment. Hence, calling`myModule.__set__("console.log", fn)` modifies the`log` function on the*global*`console` object.
232-
233-
<br />
234-
235-
webpack
236-
-------
237-
See[rewire-webpack](https://github.com/jhnns/rewire-webpack)
238-
239-
<br />
240-
241-
CoffeeScript
242-
------------
243-
244-
Good news to all caffeine-addicts: rewire works also with[Coffee-Script](http://coffeescript.org/). Note that in this case CoffeeScript needs to be listed in your devDependencies.
245-
246-
<br />
247-
248-
##License
249-
250-
MIT
5+
- overrides`require` to all access to`__get__` local vars for testing
6+
- allows testing on`import`'s by adding them as globals to the bottom of the file

‎lib/detectImports.jsrenamed to‎lib/addImportsAsVars.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,44 @@ function detectImports(src) {
1010
constmatch=line.match(importRegex);
1111
letvars=null;
1212
letpath=null;
13+
letimportType='default';
1314
if(match){
1415
vars=match[1];
15-
vars=vars.match(namedRegex) ?vars.slice(1,-1) :vars;
16+
// named export
17+
if(vars.match(namedRegex)){
18+
vars=vars.slice(1,-1);
19+
importType='named';
20+
}
1621
vars=vars.split(',').map(x=>x.trim());
1722
path=match[2];
1823
}
1924
// add to array of imports
2025
if(vars&&vars.length){
21-
vars.forEach(i=>imports[i]=path);
26+
vars.forEach(i=>imports[i]={
27+
path,
28+
importType,
29+
});
2230
}
2331
});
2432

25-
for(keyinimports){/* jshint forin: false */
26-
letvalue=imports[key];
33+
letoutput='';
34+
35+
for(letkeyinimports){/* jshint forin: false */
2736

2837
// key may be an invalid variable name (e.g. 'a-b')
2938
try{
39+
const{ path, importType}=imports[key];
3040
// eval(`var ${key};`);
31-
src+=`var${key}`;
41+
if(importType==='named'){
42+
output+=`global.${key} = require('${path}').${key};`;
43+
}else{
44+
output+=`global.${key} = require('${path}').default`;
45+
}
46+
3247
}catch(e){}
3348
}
3449

35-
returnsrc;
50+
returnoutput;
3651
}
3752

3853
module.exports=detectImports;

‎lib/getImportGlobalsSrc.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
constdetectImports=require('./detectImports');
21
/**
32
* Declares all globals with a var and assigns the global object. Thus you're able to
43
* override globals without changing the global object itself.
@@ -35,7 +34,7 @@ function getImportGlobalsSrc(ignore) {
3534
}catch(e){}
3635
}
3736

38-
returndetectImports(src);
37+
returnsrc;
3938
}
4039

4140
module.exports=getImportGlobalsSrc;

‎lib/rewire.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ var Module = require('module'),
33
getImportGlobalsSrc=require('./getImportGlobalsSrc.js'),
44
getDefinePropertySrc=require('./getDefinePropertySrc.js'),
55
detectStrictMode=require('./detectStrictMode.js'),
6-
moduleEnv=require('./moduleEnv.js');
6+
moduleEnv=require('./moduleEnv.js'),
7+
addImportsAsVars=require('./addImportsAsVars');
78

89
/**
910
* Does actual rewiring the module. For further documentation @see index.js
@@ -30,6 +31,10 @@ function internalRewire(parentModulePath, targetPath) {
3031
targetPath=targetPath[1];
3132
}
3233

34+
// Check if the module uses the strict mode.
35+
// If so we must ensure that "use strict"; stays at the beginning of the module.
36+
src=fs.readFileSync(targetPath,'utf8');
37+
3338
// Create testModule as it would be created by require()
3439
targetModule=newModule(targetPath,parentModulePath);
3540

@@ -43,12 +48,12 @@ function internalRewire(parentModulePath, targetPath) {
4348
// We append our special setter and getter.
4449
appendix='\n'+getDefinePropertySrc();
4550

51+
appendix+='\n'+addImportsAsVars(src);
52+
4653
// End of IIFE
4754
appendix+='})();';
4855

49-
// Check if the module uses the strict mode.
50-
// If so we must ensure that "use strict"; stays at the beginning of the module.
51-
src=fs.readFileSync(targetPath,'utf8');
56+
5257
if(detectStrictMode(src)===true){
5358
prelude=` "use strict";${prelude}`;
5459
}

‎package.json

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"name":"rewire",
3-
"version":"2.5.2",
4-
"description":"Easy dependency injection for node.js unit testing",
2+
"name":"coderoad-rewire",
3+
"version":"0.1.0",
4+
"description":"CodeRoad implementation to override 'require' in order to monkey-patch test globals",
55
"keywords": [
66
"dependency",
77
"injection",
@@ -16,21 +16,19 @@
1616
"require"
1717
],
1818
"author": {
19-
"name":"Johannes Ewald",
20-
"email":"mail@johannesewald.de"
19+
"name":"Shawn McKay",
20+
"email":"shawn.j.mckay@gmail.com"
2121
},
2222
"main":"lib/index.js",
23-
"homepage":"https://github.com/jhnns/rewire",
2423
"bugs": {
25-
"url":"https://github.com/jhnns/rewire/issues",
26-
"email":"mail@johannesewald.de"
24+
"url":"https://github.com/shmck/coderoad-rewire",
25+
"email":"shawn.j.mckay@gmail.com"
2726
},
2827
"repository": {
2928
"type":"git",
30-
"url":"git://github.com/jhnns/rewire.git"
29+
"url":"git://github.com/shmck/coderoad-rewire.git"
3130
},
3231
"devDependencies": {
33-
"coffee-script":"^1.8.0",
3432
"expect.js":"^0.3.1",
3533
"mocha":"^2.1.0"
3634
},

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp