Socket
Socket
Sign inDemoInstall

rewire

Package Overview
Dependencies
0
Maintainers
2
Versions
45
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.1 to 2.1.0

lib/__with__.js

31

CHANGELOG.md

@@ -1,41 +0,46 @@

##Changelog
Changelog
---------
###2.0.1
### 2.1.0
- Added revert feature of `__set__` method
- Introduced `__with__` method to revert changes automatically
### 2.0.1
- Added test coverage tool
- Small README and description changes
###2.0.0
### 2.0.0
- Removed client-side bundler extensions. Browserify is not supported anymore. Webpack support has been extracted
into separate repository https://github.com/jhnns/rewire-webpack
###1.1.3
### 1.1.3
- Removed IDE stuff from npm package
###1.1.2
### 1.1.2
- Added deprecation warning for client-side bundlers
- Updated package.json for node v0.10
###1.1.1
### 1.1.1
- Fixed bug with modules that had a comment on the last line
###1.1.0
### 1.1.0
- Added Coffee-Script support
- Removed Makefile: Use `npm test` instead.
###1.0.4
### 1.0.4
- Improved client-side rewire() with webpack
###1.0.3
### 1.0.3
- Fixed error with client-side bundlers when a module was ending with a comment
###1.0.2
### 1.0.2
- Improved strict mode detection
###1.0.1
### 1.0.1
- Fixed crash when a global module has been used in the browser
###1.0.0
### 1.0.0
- Removed caching functionality. Now rewire doesn't modify `require.cache` at all
- Added support for [webpack](https://github.com/webpack/webpack)-bundler
- Moved browserify-middleware from `rewire.browserify` to `rewire.bundlers.browserify`
- Reached stable state :)
- Reached stable state :)

@@ -8,7 +8,5 @@ /**

*
* @param {!String|!Object} varName name of the variable to set
* @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 {*}
* @return {Function}
*/

@@ -19,2 +17,3 @@ function __set__() {

arguments.src = "";
arguments.snapshot = {};

@@ -30,2 +29,3 @@ if (typeof arguments[0] === "object" && arguments.length === 1) {

arguments.src += arguments.varName + " = arguments.env." + arguments.varName + "; ";
arguments.snapshot[arguments.varName] = eval(arguments.varName);
}

@@ -38,2 +38,3 @@ }

arguments.src = arguments.varName + " = arguments.varValue;";
arguments.snapshot[arguments.varName] = eval(arguments.varName);
} else {

@@ -44,4 +45,8 @@ throw new TypeError("__set__ expects an environment object or a non-empty string as a variable name");

eval(arguments.src);
return function (snapshot) {
module.exports.__set__(snapshot);
}.bind(null, arguments.snapshot);
}
module.exports = __set__;
module.exports = __set__;
var Module = require("module"),
fs = require("fs"),
__get__ = require("./__get__.js"),
__set__ = require("./__set__.js"),
__set__ = require ("./__set__.js"),
__with__ = require("./__with__.js"),
getImportGlobalsSrc = require("./getImportGlobalsSrc.js"),

@@ -10,3 +11,4 @@ detectStrictMode = require("./detectStrictMode.js"),

var __get__Src = __get__.toString(),
__set__Src = __set__.toString();
__set__Src = __set__.toString(),
__with_Src = __with__.toString();

@@ -48,2 +50,3 @@ /**

appendix += "module.exports.__get__ = " + __get__Src + "; ";
appendix += "module.exports.__with__ = " + __with_Src + "; ";

@@ -63,2 +66,2 @@ // Check if the module uses the strict mode.

module.exports = internalRewire;
module.exports = internalRewire;
{
"name" : "rewire",
"version" : "2.0.1",
"version" : "2.1.0",
"description" : "Easy dependency injection for node.js unit testing",

@@ -5,0 +5,0 @@ "keywords" : [

@@ -5,2 +5,7 @@ rewire

[![Build Status](https://travis-ci.org/jhnns/rewire.svg?branch=master)](http://travis-ci.org/jhnns/rewire)
[![Dependency Status](https://david-dm.org/jhnns/rewire.svg)](https://david-dm.org/jhnns/rewire)
[![Coverage Status](https://img.shields.io/coveralls/jhnns/rewire.svg)](https://coveralls.io/r/jhnns/rewire)
[![Gittip Donate Button](http://img.shields.io/gittip/peerigon.svg)](https://www.gittip.com/peerigon/)
rewire adds a special setter and getter to modules so you can modify their behaviour for better unit testing. You may

@@ -21,16 +26,7 @@

[![Build Status](https://travis-ci.org/jhnns/rewire.svg?branch=master)](http://travis-ci.org/jhnns/rewire)
[![Dependency Status](https://david-dm.org/jhnns/rewire.svg)](https://david-dm.org/jhnns/rewire)
[![Coverage Status](https://img.shields.io/coveralls/jhnns/rewire.svg)](https://coveralls.io/r/jhnns/rewire)
[![npm status](https://nodei.co/npm/rewire.svg?downloads=true&stars=true)](https://npmjs.org/package/rewire)
<br />
Installation
------------
`npm install rewire`
<br />
Examples
Introduction
--------

@@ -40,15 +36,9 @@

`lib/myModule.js`
```javascript
// lib/myModule.js
// With rewire you can change all these variables
var fs = require("fs"),
http = require("http"),
someOtherVar = "hi",
myPrivateVar = 1;
path = "/somewhere/on/the/disk";
function readSomethingFromFileSystem(cb) {
// But no scoped variables
var path = "/somewhere/on/the/disk";
console.log("Reading from file system ...");

@@ -63,35 +53,44 @@ fs.readFile(path, "utf8", cb);

`test/myModule.test.js`
```javascript
// test/myModule.test.js
var rewire = require("rewire");
// rewire acts exactly like require.
var myModule = rewire("../lib/myModule.js");
```
// Just with one difference:
// Your module will now export a special setter and getter for private variables.
myModule.__set__("myPrivateVar", 123);
myModule.__get__("myPrivateVar"); // = 123
rewire acts exactly like require. Just with one difference: Your module will now export a special setter and getter for private variables.
// This allows you to mock almost everything within the module e.g. the fs-module.
// Just pass the variable name as first parameter and your mock as second.
myModule.__set__("fs", {
```javascript
myModule.__set__("path", "/dev/null");
myModule.__get__("path"); // = '/dev/null'
```
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.
```javascript
var fsMock = {
readFile: function (path, encoding, cb) {
expect(path).to.equal("/somewhere/on/the/disk");
cb(null, "Success!");
}
});
};
myModule.__set__("fs", fsMock);
myModule.readSomethingFromFileSystem(function (err, data) {
console.log(data); // = Success!
});
```
// You can set different variables with one call.
You can also set multiple variables with one call.
```javascript
myModule.__set__({
fs: fsMock,
http: httpMock,
someOtherVar: "hello"
path: "/dev/null"
});
```
// 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.
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.
```javascript
myModule.__set__({

@@ -105,36 +104,81 @@ console: {

});
```
// But be careful, if you do something like this you'll change your global
// console instance.
myModule.__set__("console.log", function () { /* be quiet */ });
`__set__` returns a function which reverts the changes introduced by this particular `__set__` call
// There is another difference to require:
// Every call of rewire() returns a new instance.
```javascript
var revert = myModule.__set__("port", 3000);
// port is now 3000
revert();
// port is now the previous value
```
For your convenience you can also use the `__with__` method which reverts the given changes after it finished.
```javascript
myModule.__with__({
port: 3000
})(function () {
// within this function port is 3000
});
// now port is the previous value again
```
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.
```javascript
myModule.__with__({
port: 3000
})(function () {
return new Promise(...);
}).then(function () {
// now port is the previous value again
});
// port is still 3000 here because the promise hasn't been resolved yet
```
### Caveats
**Difference to require()**<br>
Every call of rewire() executes the module again and returns a fresh instance.
```javascript
rewire("./myModule.js") === rewire("./myModule.js"); // = false
```
This can especially be a problem if the module is not idempotent [like mongoose models](https://github.com/jhnns/rewire/issues/27).
**Changing globals**<br>
Be careful, if you do something like this you'll change your global console instance.
```javascript
myModule.__set__("console.log", function () { /* be quiet */ });
```
<br />
##API
API
------
###rewire(filename): rewiredModule
### rewire(filename: String): rewiredModule
- *filename*: <br/>
Path to the module that shall be rewired. Use it exactly like require().
Returns a rewired version of the module found at `filename`. Use `rewire()` exactly like `require()`.
###rewiredModule.&#95;&#95;set&#95;&#95;(name, value)
### rewiredModule.&#95;&#95;set&#95;&#95;(name: String, value: *): Function
- *name*: <br/>
Name of the variable to set. The variable should be global or defined with `var` in the top-leve scope of the module.
- *value*: <br/>
The value to set.
Sets the internal variable `name` to the given `value`. Returns a function which can be called to revert the change.
###rewiredModule.&#95;&#95;set&#95;&#95;(env)
- *env*: <br/>
Takes all keys as variable names and sets the values respectively.
### rewiredModule.&#95;&#95;set&#95;&#95;(obj: Object): Function
###rewiredModule.&#95;&#95;get&#95;&#95;(name): value
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.
Returns the private variable.
### rewiredModule.&#95;&#95;get&#95;&#95;(name: String): *
Returns the private variable with the given `name`.
### rewiredModule.&#95;&#95;with&#95;&#95;(obj: Object): Function&lt;callback: Function>
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.
<br />

@@ -141,0 +185,0 @@

@@ -5,3 +5,2 @@ var expect = require("expect.js"),

expectReferenceError = expectError(ReferenceError),
expectTypeError = expectError(TypeError);

@@ -16,6 +15,10 @@

describe("__set__", function () {
var moduleFake;
var moduleFake,
undo;
beforeEach(function () {
moduleFake = {
module: {
exports: {}
},
myValue: 0, // copy by value

@@ -26,3 +29,4 @@ myReference: {} // copy by reference

vm.runInNewContext(
"__set__ = " + __set__.toString() + "; " +
//__set__ requires __set__ to be present on module.exports
"__set__ = module.exports.__set__ = " + __set__.toString() + "; " +
"getValue = function () { return myValue; }; " +

@@ -75,5 +79,28 @@ "getReference = function () { return myReference; }; ",

});
it("should return undefined", function () {
expect(moduleFake.__set__("myValue", 4)).to.be(undefined);
it("should return a function that when invoked reverts to the values before set was called", function () {
undo = moduleFake.__set__("myValue", 4);
expect(undo).to.be.a("function");
expect(moduleFake.getValue()).to.be(4);
undo();
expect(moduleFake.getValue()).to.be(0);
});
it("should be able to revert when calling with an env-obj", function () {
var newObj = { hello: "hello" };
expect(moduleFake.getValue()).to.be(0);
expect(moduleFake.getReference()).to.eql({});
undo = moduleFake.__set__({
myValue: 2,
myReference: newObj
});
expect(moduleFake.getValue()).to.be(2);
expect(moduleFake.getReference()).to.be(newObj);
undo();
expect(moduleFake.getValue()).to.be(0);
expect(moduleFake.getReference()).to.eql({});
});
it("should throw a TypeError when passing misfitting params", function () {

@@ -80,0 +107,0 @@ expect(function () {

@@ -5,4 +5,12 @@ // Don't run code in ES5 strict mode.

// These shared test cases are used to check if the provided implementation of rewire is compatible
// with the original rewire. Since you can use rewire with client-side bundlers like webpack we need
// to test the implementation there again.
// @see https://github.com/jhnns/rewire-webpack
var expect = require("expect.js"),
rewire = require("rewire");
rewire = require("rewire"),
__set__Src = require("../../lib/__set__.js").toString(),
__get__Src = require("../../lib/__get__.js").toString(),
__with__Src = require("../../lib/__with__.js").toString();

@@ -14,2 +22,3 @@ function checkForTypeError(err) {

describe("rewire " + (typeof testEnv === "undefined"? "(node)": "(" + testEnv + ")"), function () {
it("should work like require()", function () {

@@ -21,2 +30,3 @@ rewire("./moduleA.js").getFilename();

});
it("should return a fresh instance of the module", function () {

@@ -30,2 +40,3 @@ var someOtherModule = require("./someOtherModule.js"),

});
it("should not cache the rewired module", function () {

@@ -43,10 +54,21 @@ var rewired,

});
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);
// By comparing the src we can ensure that the provided __set__ function is our tested implementation
it("should modify the module so it provides the __set__ - function", function () {
expect(rewire("./moduleA.js").__set__.toString()).to.be(__set__Src);
expect(rewire("./moduleB.js").__set__.toString()).to.be(__set__Src);
});
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);
// By comparing the src we can ensure that the provided __set__ function is our tested implementation
it("should modify the module so it provides the __get__ - function", function () {
expect(rewire("./moduleA.js").__get__.toString()).to.be(__get__Src);
expect(rewire("./moduleB.js").__get__.toString()).to.be(__get__Src);
});
// By comparing the src we can ensure that the provided __set__ function is our tested implementation
it("should modify the module so it provides the __with__ - function", function () {
expect(rewire("./moduleA.js").__with__.toString()).to.be(__with__Src);
expect(rewire("./moduleB.js").__with__.toString()).to.be(__with__Src);
});
it("should not influence other modules", function () {

@@ -57,3 +79,5 @@ rewire("./moduleA.js");

expect(require("./someOtherModule.js").__get__).to.be(undefined);
expect(require("./someOtherModule.js").__with__).to.be(undefined);
});
it("should not override/influence global objects by default", function () {

@@ -64,3 +88,6 @@ // This should throw no exception

});
it("should provide the ability to set private vars", function () {
// This is just an integration test for the __set__ method
// You can find a full test for __set__ under /test/__set__.test.js
it("should provide a working __set__ method", function () {
var rewiredModuleA = rewire("./moduleA.js"),

@@ -76,3 +103,6 @@ newObj = {};

});
it("should provide the ability to get private vars", function () {
// This is just an integration test for the __get__ method
// You can find a full test for __get__ under /test/__get__.test.js
it("should provide a working __get__ method", function () {
var rewiredModuleA = rewire("./moduleA.js");

@@ -83,2 +113,24 @@

});
// This is just an integration test for the __with__ method
// You can find a full test for __with__ under /test/__with__.test.js
it("should provide a working __with__ method", function () {
var rewiredModuleA = rewire("./moduleA.js"),
newObj = {};
expect(rewiredModuleA.getMyNumber()).to.be(0);
expect(rewiredModuleA.getMyObj()).to.not.be(newObj);
rewiredModuleA.__with__({
myNumber: 2,
myObj: newObj
})(function () {
expect(rewiredModuleA.getMyNumber()).to.be(2);
expect(rewiredModuleA.getMyObj()).to.be(newObj);
});
expect(rewiredModuleA.getMyNumber()).to.be(0);
expect(rewiredModuleA.getMyObj()).to.not.be(newObj);
});
it("should provide the ability to inject mocks", function (done) {

@@ -96,2 +148,3 @@ var rewiredModuleA = rewire("./moduleA.js"),

});
it("should not influence other modules when injecting mocks", function () {

@@ -106,2 +159,3 @@ var rewiredModuleA = rewire("./moduleA.js"),

});
it("should provide the ability to mock global objects just within the module", function () {

@@ -137,2 +191,3 @@ var rewiredModuleA = rewire("./moduleA.js"),

});
it("should be possible to mock global objects that are added on runtime", function () {

@@ -159,2 +214,3 @@ var rewiredModule;

});
it("should not be a problem to have a comment on file end", function () {

@@ -166,2 +222,3 @@ var rewired = rewire("./emptyModule.js");

});
it("should not influence the original require if nothing has been required within the rewired module", function () {

@@ -171,5 +228,7 @@ rewire("./emptyModule.js"); // nothing happens here because emptyModule doesn't require anything

});
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 () {

@@ -182,2 +241,3 @@ var strictModule = rewire("./strictModule.js");

});
it("should not modify line numbers in stack traces", function () {

@@ -194,2 +254,3 @@ var throwError = rewire("./throwError.js");

});
it("should throw a TypeError if the path is not a string", function () {

@@ -200,2 +261,3 @@ expect(function () {

});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc