Skip to content

Commit

Permalink
fix: allow non-existent stub path when @noCallThru is set at stub lev…
Browse files Browse the repository at this point in the history
…el (#245)
  • Loading branch information
bvalerius authored and bendrucker committed Aug 8, 2019
1 parent 5b88b07 commit 0297d28
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
28 changes: 19 additions & 9 deletions lib/proxyquire.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Proxyquire.prototype.load = function (request, stubs) {
// Resolves a stub relative to a module.
// `baseModule` is the module we're resolving from. `pathToResolve` is the
// module we want to resolve (i.e. the string passed to `require()`).
Proxyquire.prototype._resolveModule = function (baseModule, pathToResolve) {
Proxyquire.prototype._resolveModule = function (baseModule, pathToResolve, stubs) {
try {
return resolve.sync(pathToResolve, {
basedir: path.dirname(baseModule),
Expand All @@ -153,9 +153,22 @@ Proxyquire.prototype._resolveModule = function (baseModule, pathToResolve) {
// back a different module than one that requires "./foo" from another
// directory. However, if !this._preserveCache, then we don't want to
// throw, since we can resolve modules that don't exist. Resolve as
// best we can.
if (!this._preserveCache || this._noCallThru) {
return path.resolve(path.dirname(baseModule), pathToResolve)
// best we can. We also need to check if the relative module has @noCallThru.
var moduleNoCallThru
var resolvedPath
if (hasOwnProperty.call(stubs, pathToResolve)) {
// pathToResolve is currently relative on stubs from _withoutCache() call
moduleNoCallThru = hasOwnProperty.call(stubs[pathToResolve], '@noCallThru') ? stubs[pathToResolve]['@noCallThru'] : undefined
resolvedPath = path.resolve(path.dirname(baseModule), pathToResolve)
} else {
resolvedPath = path.resolve(path.dirname(baseModule), pathToResolve)
if (hasOwnProperty.call(stubs, resolvedPath)) {
// after _withoutCache() alters stubs paths to be absolute
moduleNoCallThru = hasOwnProperty.call(stubs[resolvedPath], '@noCallThru') ? stubs[resolvedPath]['@noCallThru'] : undefined
}
}
if (!this._preserveCache || this._noCallThru || moduleNoCallThru) {
return resolvedPath
}

throw err
Expand All @@ -167,10 +180,9 @@ Proxyquire.prototype._require = function (module, stubs, path) {
assert(typeof path === 'string', 'path must be a string')
assert(path, 'missing path')

var resolvedPath = this._resolveModule(module.filename, path)
var resolvedPath = this._resolveModule(module.filename, path, stubs)
if (hasOwnProperty.call(stubs, resolvedPath)) {
var stub = stubs[resolvedPath]

if (stub === null) {
// Mimic the module-not-found exception thrown by node.js.
throw moduleNotFoundError(path)
Expand Down Expand Up @@ -202,11 +214,10 @@ Proxyquire.prototype._withoutCache = function (module, stubs, path, func) {
// Resolve all stubs to absolute paths.
stubs = Object.keys(stubs)
.reduce(function (result, stubPath) {
var resolvedStubPath = this._resolveModule(resolvedPath, stubPath)
var resolvedStubPath = this._resolveModule(resolvedPath, stubPath, stubs)
result[resolvedStubPath] = stubs[stubPath]
return result
}.bind(this), {})

// Override all require extension handlers
var restoreExtensionHandlers = this._overrideExtensionHandlers(module, stubs)

Expand Down Expand Up @@ -287,7 +298,6 @@ Proxyquire.prototype._disableModuleCache = function (path, module) {

Proxyquire.prototype._overrideExtensionHandlers = function (module, resolvedStubs) {
/* eslint node/no-deprecated-api: [error, {ignoreGlobalItems: ["require.extensions"]}] */

var originalExtensions = {}
var self = this

Expand Down
10 changes: 10 additions & 0 deletions test/proxyquire-notexisting.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var assert = require('assert')
var proxyquire = require('..')
var path = require('path')
var fooPath = path.join(__dirname, './samples/notexisting/foo.js')
var fooRelativePath = path.join(__dirname, './samples/notexisting/foo-relative.js')

describe('When resolving foo that requires stubbed /not/existing/bar.json', function () {
it('throws an error', function () {
Expand Down Expand Up @@ -34,3 +35,12 @@ describe('When resolving foo that requires stubbed /not/existing/bar.json with n
proxyquire.callThru()
})
})

describe('When resolving foo-relative that requires relative stubbed ../not/existing/bar.json with @noCallThru', function () {
it('resolves foo-relative with stubbed bar', function () {
var fooRelative = proxyquire(fooRelativePath, {
'../not/existing/bar.json': { config: 'bar\'s config', '@noCallThru': true }
})
assert.strictEqual(fooRelative.config, 'bar\'s config')
})
})
5 changes: 5 additions & 0 deletions test/samples/notexisting/foo-relative.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var bar = require('../not/existing/bar.json')

module.exports = {
config: bar.config
}

0 comments on commit 0297d28

Please sign in to comment.