Skip to content

Instantly share code, notes, and snippets.

@Morriz
Created August 12, 2013 23:05
Show Gist options
  • Save Morriz/6216183 to your computer and use it in GitHub Desktop.
Save Morriz/6216183 to your computer and use it in GitHub Desktop.
proxyquire patch for late resolving stub paths
var stubsRegistry = {};
/**
* Loads a module using the given stubs instead of their normally resolved required modules.
* @param request The requirable module path to load.
* @param stubs The stubs to use. e.g., { "path": { extname: function () { ... } } }
* @return {*} A newly resolved module with the given stubs.
*/
Proxyquire.prototype.load = function (request, stubs) {
validateArguments(request, stubs);
// Find the ID (location) of the SUT, relative to the parent
var id = Module._resolveFilename(request, this._parent)
, stubsRegister = {}
;
// keep a registry of the stubs for later lookup, per proxyquire'd module
stubsRegistry[id] = stubsRegister;
for (var prop in stubs) {
if (stubs.hasOwnProperty(prop)) {
stubsRegister[prop] = stubs[prop];
}
}
// Temporarily delete the SUT from the require cache, if it exists.
var cached = Module._cache[id];
if (cached) delete Module._cache[id];
// Override the core require function for the SUT's file extension.
var extname = path.extname(id);
var ext_super = require.extensions[extname];
var self = this;
// var parent = this._parent;
require.extensions[extname] = function ext(module, filename) {
// NOTE: This function is for requiring the SUT
// require_super is the normal require for the SUT.
var require_super = module.require.bind(module);
require_super.extensions = require.extensions;
require_super.extensions[extname] = ext_super;
require_super.main = process.mainModule;
module.require = function (request) {
// NOTE: This function is for requiring dependencies for the SUT
var stubs = stubsRegistry[id];
// If the request string isn't stubbed, just do the usual thing.
if (!stubs.hasOwnProperty(request)) return require_super(request);
var stub = stubs[request];
if (stub.hasOwnProperty('@noCallThru') ? !stub['@noCallThru'] : !self._noCallThru)
fillMissingKeys(stub, require_super(request));
return stub;
};
// Now that we've overridden the SUT's require, we can proceed as usual.
return ext_super(module, filename);
};
try {
return this._parent.require(request);
} finally {
// if (cached)
// Module._cache[id] = cached;
// else
// delete Module._cache[id];
// if (ext_super)
// require.extensions[extname] = ext_super;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment