Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
JvJefke committed Nov 13, 2017
2 parents c176d02 + cce2de8 commit 0a77533
Show file tree
Hide file tree
Showing 13 changed files with 188 additions and 323 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
language: node_js
node_js:
- "0.10"
- "0.12"
- "4"
- "5"
- "6"
- "8"
- "9"

script:
- npm test
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Changelog
---------

### 3.0.0
- **Breaking:** Remove support for node versions below 4
- Add support for `const` [#79](https://github.com/jhnns/rewire/issues/79) [#95](https://github.com/jhnns/rewire/issues/95) [#117](https://github.com/jhnns/rewire/pull/117) [#118](https://github.com/jhnns/rewire/pull/118)

### 2.5.2
- Fix cluttering of `require.extensions` even if CoffeeScript is not installed [#98](https://github.com/jhnns/rewire/pull/98)

Expand Down
15 changes: 4 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ rewire adds a special setter and getter to modules so you can modify their behav
- inspect private variables
- override variables within the module.

rewire does **not** load the file and eval the contents to emulate node's require mechanism. In fact it uses node's own require to load the module. Thus your module behaves exactly the same in your test environment as under regular circumstances (except your modifications).

**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).
**Please note:** The current version of rewire is only compatible with CommonJS modules. See [Limitations](https://github.com/jhnns/rewire#limitations).

<br>

Expand Down Expand Up @@ -139,8 +137,8 @@ myModule.__with__({
Limitations
-----------

**Transpilers**<br>
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).
**Babel's ES module emulation**<br>
During the transpilation step from ESM to CJS modules, Babel renames internal variables. Rewire will not work in these cases (see [#62](https://github.com/jhnns/rewire/issues/62)). Other Babel transforms, however, should be fine. Another solution might be switching to [babel-plugin-rewire](https://github.com/speedskater/babel-plugin-rewire).

**Variables inside functions**<br>
Variables inside functions can not be changed by rewire. This is constrained by the language.
Expand Down Expand Up @@ -179,15 +177,10 @@ Please be aware that you can't rewire `eval()` or the global object itself.
API
---

### rewire(filename: String, [options]): rewiredModule
### rewire(filename: String): rewiredModule

Returns a rewired version of the module found at `filename`. Use `rewire()` exactly like `require()`.

#### Options
| Property | Default | Description |
|----------|---------|-------------|
| convertConst | false | Set to true to convert all `const` variables of the required module to `let`. This way you can mock const variables. **Caution**: Setting this to true can lead to inaccurate tests.

### rewiredModule.&#95;&#95;set&#95;&#95;(name: String, value: *): Function

Sets the internal variable `name` to the given `value`. Returns a function which can be called to revert the change.
Expand Down
4 changes: 2 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ var rewireModule = require("./rewire.js");
* @param {!String} filename Path to the module that shall be rewired. Use it exactly like require().
* @return {*} the rewired module
*/
function rewire(filename, opts) {
return rewireModule(module.parent, filename, opts);
function rewire(filename) {
return rewireModule(module.parent, filename);
}

module.exports = rewire;
Expand Down
49 changes: 29 additions & 20 deletions lib/moduleEnv.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,32 @@
var Module = require("module"),
fs = require("fs"),
babelCore = require("babel-core"),
// Requiring the babel plugin here because otherwise it will be lazy-loaded by Babel during rewire()
transformBlockScoping = require("babel-plugin-transform-es2015-block-scoping"),
coffee;

// caching original wrapper
var moduleWrapper0 = Module.wrapper[0],
moduleWrapper1 = Module.wrapper[1],
originalExtensions = {},
matchCoffeeExt = /\.coffee$/,
nodeRequire,
currentModule;

function load(targetModule, isTransform) {
function load(targetModule) {
nodeRequire = targetModule.require;
targetModule.require = requireProxy;
currentModule = targetModule;

registerExtensions();

targetModule.load(targetModule.id);

// This is only necessary if nothing has been required within the module
reset();
}

function compile(targetModule, src, filename) {
nodeRequire = targetModule.require;
targetModule.require = requireProxy;
targetModule.filename = filename;
currentModule = targetModule;

var convertedSrc = babelCore.transform(stripBOM(src), {
plugins: ["transform-es2015-constants"]
});

targetModule._compile(convertedSrc.code, filename);

reset();
}

function reset() {
Module.wrapper[0] = moduleWrapper0;
Module.wrapper[1] = moduleWrapper1;
restoreExtensions();
}

function inject(prelude, appendix) {
Expand All @@ -64,23 +49,48 @@ function requireProxy(path) {
}

function registerExtensions() {
var originalJsExtension = require.extensions[".js"];
var originalCoffeeExtension = require.extensions[".coffee"];

if (originalJsExtension) {
originalExtensions.js = originalJsExtension;
}
if (originalCoffeeExtension) {
originalExtensions.coffee = originalCoffeeExtension;
}
require.extensions[".js"] = jsExtension;
require.extensions[".coffee"] = coffeeExtension;
}

function restoreExtensions() {
if ("js" in originalExtensions) {
require.extensions[".js"] = originalExtensions.js;
}
if ("coffee" in originalExtensions) {
require.extensions[".coffee"] = originalExtensions.coffee;
}
}

function jsExtension(module, filename) {
var _compile = module._compile;

module._compile = function (content, filename) {
content = babelCore.transform(content, {
plugins: ["transform-es2015-block-scoping"],
retainLines: true,
filename: filename
}).code;
_compile.call(module, content, filename);
};

restoreExtensions();
originalExtensions.js(module, filename);
}

function coffeeExtension(module, filename) {
var content = stripBOM(fs.readFileSync(filename, "utf8"));

restoreExtensions();
content = coffee.compile(content, {
filename: filename,
bare: true
Expand Down Expand Up @@ -108,5 +118,4 @@ try {
}

exports.load = load;
exports.compile = compile;
exports.inject = inject;
23 changes: 3 additions & 20 deletions lib/rewire.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,11 @@ var Module = require("module"),
/**
* Does actual rewiring the module. For further documentation @see index.js
*/
function internalRewire(parentModulePath, targetPath, opts) {
function internalRewire(parentModulePath, targetPath) {
var targetModule,
prelude,
appendix,
src,
isTransform;

opts = typeof opts === "object" ? opts : {};
isTransform = !!opts.convertConst;
src;

// Checking params
if (typeof targetPath !== "string") {
Expand All @@ -27,14 +23,6 @@ function internalRewire(parentModulePath, targetPath, opts) {
// Resolve full filename relative to the parent module
targetPath = Module._resolveFilename(targetPath, parentModulePath);

// Special support for older node versions that returned an array on Module._resolveFilename
// @see https://github.com/joyent/node/blob/865b077819a9271a29f982faaef99dc635b57fbc/lib/module.js#L319
// TODO Remove this switch on the next major release
/* istanbul ignore next because it will be removed soon */
if (Array.isArray(targetPath)) {
targetPath = targetPath[1];
}

// Create testModule as it would be created by require()
targetModule = new Module(targetPath, parentModulePath);

Expand All @@ -59,12 +47,7 @@ function internalRewire(parentModulePath, targetPath, opts) {
}

moduleEnv.inject(prelude, appendix);

if(isTransform) {
moduleEnv.compile(targetModule, src, targetPath);
} else {
moduleEnv.load(targetModule);
}
moduleEnv.load(targetModule);

return targetModule.exports;
}
Expand Down
Loading

0 comments on commit 0a77533

Please sign in to comment.