Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

require-inject

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

require-inject - npm Package Compare versions

Comparing version 1.3.1 to 1.4.0

test/injection-missing-1.js

22

CHANGELOG.md

@@ -0,1 +1,23 @@

## v1.4.0 (2016-06-03)
Add `requireInject.withEmptyCache` and
`requireInject.installGlobally.andClearCache` to support loading modules
to be injected with an empty cache. This can be useful when your test shares
dependencies with the module to be mocked and you need to mock a transitive
dependency of one of those dependencies. That is:
```
Test → A → B
ModuleToTest → A → MockedB
```
If we we didn't clear the cache then `ModuleToTest` would get the already
cached version of `A` and the `MockedB` would never be injected. By clearing the cache
first it means that `ModuleToTest` will get it's own copy of `A` which will then pick
up any mocks we defined.
Previously to achieve this you would need to have provided a mock for `A`,
which, if that isn't what you were testing, could be frustrating busy work.
## v1.3.1 (2016-03-04)

@@ -2,0 +24,0 @@

58

index.js

@@ -1,18 +0,38 @@

"use strict";
var path = require("path")
var caller = require('caller');
'use strict'
var path = require('path')
var caller = require('caller')
module.exports = function (toLoad, mocks) {
exports = module.exports = function (toLoad, mocks) {
return requireInject(toLoad, mocks)
}
exports.withEmptyCache = function (toLoad, mocks) {
return requireInject(toLoad, mocks, true)
}
exports.installGlobally = installGlobally
exports.installGlobally.andClearCache = function (toLoad, mocks) {
var callerFilename = getCallerFilename()
Object.keys(require.cache).forEach(function (name) {
if (name !== callerFilename) delete require.cache[name]
})
return installGlobally(toLoad, mocks)
}
var requireInject = function (toLoad, mocks, withEmptyCache) {
// Copy the existing cache
var originalCache = {}
Object.keys(require.cache).forEach(function(name) {
Object.keys(require.cache).forEach(function (name) {
originalCache[name] = require.cache[name]
})
var mocked = installGlobally(toLoad, mocks)
var mocked = withEmptyCache
? installGlobally.andClearCache(toLoad, mocks)
: installGlobally(toLoad, mocks)
// restore the cache, we can't just assign originalCache to require.cache as the require
// object is unique to each module, even though require.cache is shared
Object.keys(require.cache).forEach(function(name){ delete require.cache[name] })
Object.keys(originalCache).forEach(function(name){ require.cache[name] = originalCache[name] })
Object.keys(require.cache).forEach(function (name) { delete require.cache[name] })
Object.keys(originalCache).forEach(function (name) { require.cache[name] = originalCache[name] })

@@ -22,3 +42,3 @@ return mocked

function resolve(callerFilename, name) {
function resolve (callerFilename, name) {
if (/^[.][.]?\//.test(name)) {

@@ -30,12 +50,20 @@ name = path.resolve(path.dirname(callerFilename), name)

var installGlobally = module.exports.installGlobally = function (toLoad, mocks) {
var callerFilename = caller() == module.filename ? caller(2) : caller();
function getCallerFilename () {
var callerFilename
for (var ii = 1; ii <= 10; ++ii) {
callerFilename = caller(ii)
if (callerFilename !== module.filename) return callerFilename
}
throw new Error("Couldn't find caller that wasn't " + module.filename + ' in most recent 10 stackframes')
}
function installGlobally (toLoad, mocks) {
var callerFilename = getCallerFilename()
// Inject all of our mocks
Object.keys(mocks).forEach(function(name){
Object.keys(mocks).forEach(function (name) {
var namePath = resolve(callerFilename, name)
if (mocks[name] == null) {
delete require.cache[namePath]
}
else {
} else {
require.cache[namePath] = {exports: mocks[name]}

@@ -50,3 +78,3 @@ }

// load our new version using our mocks
return require.cache[callerFilename].require(toLoadPath);
return require.cache[callerFilename].require(toLoadPath)
}
{
"name": "require-inject",
"version": "1.3.1",
"version": "1.4.0",
"description": "A simple mock injector compatible needing no instrumentation in the libraries being tested",
"main": "index.js",
"scripts": {
"test": "tap test/*.js"
"test": "standard && tap test/*.js"
},

@@ -23,2 +23,4 @@ "author": "Rebecca Turner <me@re-becca.org> (http://re-becca.org)",

"devDependencies": {
"standard": "^7.1.2",
"tacks": "1.0.11",
"tap": "^2.2.0"

@@ -25,0 +27,0 @@ },

@@ -22,5 +22,5 @@ require-inject

var myglobal = requireInject.installGlobally('myglobal', { … })
### Usage
### Usage in your tests
* **`var mymod = requireInject( module, mocks )`**

@@ -34,3 +34,3 @@

*mocks* is an object with keys that are the names of the modules you want
*to mock and values of the mock version of the objects.
to mock and values of the mock version of the objects.

@@ -42,6 +42,35 @@ **requireInject** makes it so that when *module* is required, any of its

* **`var mymod = requireInject.withClearCache(module, mocks)`**
As with `requireInject` but your require cache will be cleared before requring
the module to have mocks injected into it. This can be useful when your test shares
dependencies with the module to be mocked and you need to mock a transitive
dependency of one of those dependencies. That is:
```
Test → A → B
ModuleToTest → A → MockedB
```
If we we didn't clear the cache then `ModuleToTest` would get the already
cached version of `A` and the `MockedB` would never be injected. By clearing the cache
first it means that `ModuleToTest` will get it's own copy of `A` which will then pick
up any mocks we defined.
Previously to achieve this you would need to have provided a mock for `A`,
which, if that isn't what you were testing, could be frustrating busy work.
* **`var myglobal = requireInject.installGlobally( module, mocks)`**
As with `requireInject`, except that the module and its mocks are left in
the require cache and any future requires will end up using them too. This is
helpful particularly in the case of things that defer loading.
the require cache and any future requires will end up using them too. This
is helpful particularly in the case of things that defer loading (that is,
do async loading).
* **`var myglobal = requireInject.installGlobally.andClearCache(module, mocks)`**
As with `requireInject.installGlobally` but clear the cache first as with
`requireInject.withClearCache`. Because this globally clears the cache it
means that any requires after this point will get fresh copies of their
required modules, even if you required them previously.

@@ -1,12 +0,40 @@

"use strict";
var test = require("tap").test
var requireInject = require("../index")
'use strict'
var test = require('tap').test
var requireInject = require('../index')
var path = require('path')
var Tacks = require('tacks')
var File = Tacks.File
var Dir = Tacks.Dir
var fixturepath = path.resolve(__dirname, 'lib')
var fixture = new Tacks(
Dir({
'a.js': File(
"'use strict'\n" +
"var b = require('./b')\n" +
'module.exports = function (infile, outfile, cb) {\n' +
' b(infile, outfile, cb)\n' +
'}\n'
),
'b.js': File(
"'use strict'\n" +
"var fs = require('fs')\n" +
'module.exports = function (infile, outfile, cb) {\n' +
' fs.rename(infile, outfile, cb)\n' +
'}\n'
)
})
)
test("injection leaking at a distance", function(t) {
test('setup', function (t) {
setup()
t.done()
})
test('injection leaking at a distance', function (t) {
t.plan(2)
var first = requireInject("./lib/a", {
"fs": {
rename: function(infile, outfile, cb) {
var first = requireInject('./lib/a', {
'fs': {
rename: function (infile, outfile, cb) {
cb()

@@ -16,7 +44,19 @@ }

})
first("in", "out", function (err) { t.notOk(err,"should be able to rename a file") })
first('in', 'out', function (err) { t.notOk(err, 'should be able to rename a file') })
var second = require("./lib/a");
var second = require('./lib/a')
second("in", "out", function (err) { t.ok(err,"shouldn\'t be able to rename now") })
second('in', 'out', function (err) { t.ok(err, 'shouldn\'t be able to rename now') })
})
test('cleanup', function (t) {
cleanup()
t.done()
})
function setup () {
cleanup()
fixture.create(fixturepath)
}
function cleanup () {
fixture.remove(fixturepath)
}

@@ -1,11 +0,40 @@

'use strict';
var test = require("tap").test
'use strict'
var test = require('tap').test
var requireInject = require('../index')
var path = require('path')
var Tacks = require('tacks')
var File = Tacks.File
var Dir = Tacks.Dir
test("injection leaking at a distance", function(t) {
var fixturepath = path.resolve(__dirname, 'lib')
var fixture = new Tacks(
Dir({
'b.js': File(
"'use strict'\n" +
"var fs = require('fs')\n" +
'module.exports = function (infile, outfile, cb) {\n' +
' fs.rename(infile, outfile, cb)\n' +
'}\n'
),
'c.js': File(
"'use strict'\n" +
"var b = require('./b')\n" +
'module.exports = function (infile, outfile, cb) {\n' +
' b(infile, outfile, cb)\n' +
'}\n'
)
})
)
test('setup', function (t) {
setup()
t.done()
})
test('injection leaking at a distance', function (t) {
t.plan(2)
var first = requireInject("./lib/b", {
"fs": {
rename: function(infile, outfile, cb) {
var first = requireInject('./lib/b', {
'fs': {
rename: function (infile, outfile, cb) {
cb()

@@ -15,7 +44,19 @@ }

})
first("in", "out", function (err) { t.notOk(err,"should be able to rename a file") })
first('in', 'out', function (err) { t.notOk(err, 'should be able to rename a file') })
var second = require("./lib/c");
var second = require('./lib/c')
second("in", "out", function (err) { t.ok(err,"shouldn\'t be able to rename now") })
second('in', 'out', function (err) { t.ok(err, 'shouldn\'t be able to rename now') })
})
test('cleanup', function (t) {
cleanup()
t.done()
})
function setup () {
cleanup()
fixture.create(fixturepath)
}
function cleanup () {
fixture.remove(fixturepath)
}
'use strict'
var path = require('path')
var test = require('tap').test
var Tacks = require('tacks')
var File = Tacks.File
var Dir = Tacks.Dir
var requireInject = require('../index')
var testdir = path.join(__dirname, path.basename(__filename, '.js'))
var adir = path.join(testdir, 'a')
var bdir = path.join(testdir, 'b')
var brelative = './' + path.relative(__dirname, bdir)
var fixture = new Tacks(
Dir({
'a.js': File(
"'use strict';\n" +
"var b = require('./b');\n" +
'module.exports = function(infile, outfile, cb) {\n' +
' b(infile, outfile, cb);\n' +
'};\n'
),
'b.js': File(
"'use strict';\n" +
"var fs = require('fs');\n" +
'module.exports = function(infile, outfile, cb) {\n' +
' fs.rename(infile, outfile, cb)\n' +
'};\n'
)
})
)
test('setup', function (t) {
fixture.create(testdir)
t.end()
})
test('mock with absolute path', function (t) {
t.plan(1)
var a = requireInject('./lib/a', {
[require.resolve('./lib/b')]: function (infile, outfile, cb) {
var a = requireInject(adir, {
[bdir]: function (infile, outfile, cb) {
cb()

@@ -23,4 +55,4 @@ }

var a = requireInject('./lib/a', {
'./lib/b': function (infile, outfile, cb) {
var a = requireInject(adir, {
[brelative]: function (infile, outfile, cb) {
cb()

@@ -34,1 +66,6 @@ }

})
test('cleanup', function (t) {
fixture.remove(testdir)
t.end()
})
SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc