rewiremock
Version:
Advanced dependency mocking device.
374 lines (306 loc) • 12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.requireModule = undefined;
var _defineProperty2 = require('babel-runtime/core-js/object/define-property');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _getOwnPropertyDescriptor = require('babel-runtime/core-js/object/get-own-property-descriptor');
var _getOwnPropertyDescriptor2 = _interopRequireDefault(_getOwnPropertyDescriptor);
var _getOwnPropertyDescriptors = require('babel-runtime/core-js/object/get-own-property-descriptors');
var _getOwnPropertyDescriptors2 = _interopRequireDefault(_getOwnPropertyDescriptors);
var _setPrototypeOf = require('babel-runtime/core-js/object/set-prototype-of');
var _setPrototypeOf2 = _interopRequireDefault(_setPrototypeOf);
var _defineProperty4 = require('babel-runtime/helpers/defineProperty');
var _defineProperty5 = _interopRequireDefault(_defineProperty4);
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _typeof2 = require('babel-runtime/helpers/typeof');
var _typeof3 = _interopRequireDefault(_typeof2);
var _path = require('path');
var _module = require('./module');
var _module2 = _interopRequireDefault(_module);
var _plugins = require('./plugins');
var _mocks = require('./mocks');
var _globals = require('./globals');
var _globals2 = _interopRequireDefault(_globals);
var _asyncModules = require('./asyncModules');
var _asyncModules2 = _interopRequireDefault(_asyncModules);
var _getModule = require('./getModule');
var _getModule2 = _interopRequireDefault(_getModule);
var _compareModuleExports = require('compare-module-exports');
var _compareModuleExports2 = _interopRequireDefault(_compareModuleExports);
var _common = require('./plugins/_common');
var _wipeCache = require('./wipeCache');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var matchOrigin = (0, _compareModuleExports2.default)('rewiremock');
var thisModule = module;
var patternMatch = function patternMatch(fileName) {
return function (pattern) {
if (typeof pattern == 'function') {
return pattern(fileName);
}
return fileName.match(pattern);
};
};
var requireModule = exports.requireModule = function requireModule(name, parentModule) {
if (typeof __webpack_require__ !== 'undefined') {
return __webpack_require__(name);
} else {
//return Module._load(name);
return parentModule ? _getModule2.default._load(name, parentModule) : require(name);
}
};
var testPassby = function testPassby(request, module) {
var _getScope = (0, _globals2.default)(),
parentModule = _getScope.parentModule,
mockedModules = _getScope.mockedModules;
var passBy = (0, _globals.collectScopeVariable)('passBy');
var isolation = (0, _globals.getScopeVariable)('isolation');
// was called from test
if ((0, _module.moduleCompare)(module, parentModule)) {
//if (module === parentModule || module == module.parent) {
return true;
}
// if parent is in the pass list - pass everything
var fileName = _module2.default._resolveFilename(request, module);
var m = module;
var test = function test(fileName) {
return (
// parent was mocked
!isolation.noAutoPassBy && mockedModules[fileName] ||
// parent is in pass list
passBy.filter(patternMatch(fileName)).length
);
};
if (!isolation.noParentPassBy) {
while (m && !(0, _module.moduleCompare)(m, parentModule)) {
if (test(fileName)) {
return true;
}
fileName = (0, _module.getModuleName)(m);
m = (0, _module.getModuleParent)(m);
}
}
return test(fileName);
};
function mockResult(name, mock, dataFactory) {
var factory = function factory() {
var data = dataFactory();
if (mock.matchOrigin) {
var matchResult = matchOrigin(mock.original, data, name, '%mock%', { noFunctionCompare: true });
if (matchResult) {
// eslint-disable-next-line no-console
matchResult.forEach(function (line) {
return console.error(line);
});
throw new Error('Rewiremock: provided mocks does not match ' + name);
}
}
if (data && !data.default) {
if (['object', 'function'].indexOf(typeof data === 'undefined' ? 'undefined' : (0, _typeof3.default)(data)) >= 0) {
Object.defineProperty(data, 'default', {
enumerable: false,
value: data
});
}
}
return data;
};
if (mock.flag_dynamic) {
var origin = factory();
if (['object', 'function'].indexOf(typeof origin === 'undefined' ? 'undefined' : (0, _typeof3.default)(origin)) >= 0) {
return new Proxy(origin, {
get: function get(target, prop) {
return factory()[prop];
}
});
}
}
return factory();
}
function standardStubFactory(name, object, deeperMock) {
if (typeof object === 'function') {
return function () {};
}
if ((typeof object === 'undefined' ? 'undefined' : (0, _typeof3.default)(object)) === 'object') {
return deeperMock(deeperMock);
}
return object;
}
function mockThought(stubFactory, mockOriginal) {
var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
if (typeof mockOriginal === 'function') {
return stubFactory(name || 'default', mockOriginal);
}
if ((typeof mockOriginal === 'undefined' ? 'undefined' : (0, _typeof3.default)(mockOriginal)) === 'object') {
var deeperMock = function deeperMock(key, value) {
return mockThought(stubFactory, value, name ? name + '.' + key : key);
};
if (Array.isArray(mockOriginal)) {
return mockOriginal.map(function (x, i) {
return deeperMock(i, x);
});
} else {
return (0, _keys2.default)(mockOriginal).map(function (key) {
return { key: key, value: deeperMock(key, mockOriginal[key]) };
}).reduce(function (acc, x) {
return (0, _assign2.default)(acc, (0, _defineProperty5.default)({}, x.key, x.value));
}, {});
}
}
return mockOriginal;
}
function monkeyPatchPath(addr) {
var path = addr.split('/');
if (path[0] === '..') {
path[0] = '.';
return path.join('/');
}
return addr;
}
function asyncTest() {
var asyncModulesLeft = _asyncModules2.default.hasAsyncModules();
if (asyncModulesLeft) {
/* eslint-disable no-console */
console.error('Rewiremock: listed async modules should finish loading first. Use async API of rewiremock.', asyncModulesLeft.map(function (module) {
return module.creator;
}));
/* eslint-enable */
throw new Error('Rewiremock: listed async modules should finish loading first. Use async API of rewiremock.');
}
}
function tryOr(fn, failBack) {
try {
return fn();
} catch (e) {
// probably file not found
}
return failBack;
}
function protoCopy(source, override) {
var dest = (0, _assign2.default)({}, override);
(0, _setPrototypeOf2.default)(dest, source);
return dest;
}
function restoreProperties(dest, source) {
var values = (0, _getOwnPropertyDescriptors2.default)(source);
(0, _keys2.default)(values).forEach(function (key) {
if (!(0, _getOwnPropertyDescriptor2.default)(dest, key)) {
(0, _defineProperty3.default)(dest, key, values[key]);
}
});
return dest;
}
function restoreESModuleState(dest, original) {
if (original && original.__esModule) {
try {
Object.defineProperty(dest, "__esModule", {
value: true
});
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
}
return dest;
}
function mockLoader(request, parent, isMain) {
var _getScope2 = (0, _globals2.default)(),
parentModule = _getScope2.parentModule,
mockedModules = _getScope2.mockedModules;
var isolation = (0, _globals.getScopeVariable)('isolation');
asyncTest();
var baseRequest = tryOr(function () {
return _module2.default._resolveFilename(request, parent);
}, request);
var shortRequest = monkeyPatchPath((0, _path.relative)((0, _module.getModuleName)(parent), request));
if ((0, _module.moduleCompare)(parent, parentModule) || (0, _module.moduleCompare)(parent, thisModule)) {
(0, _wipeCache.safelyRemoveCache)(baseRequest);
mockedModules[baseRequest] = true;
}
var mock = (0, _mocks.getMock)(baseRequest) || (0, _mocks.getMock)(request) || (0, _mocks.getMock)(shortRequest) || (0, _plugins.autoMock)(baseRequest);
if (mock) {
mock.wasRequired = true;
var shouldResult = {};
if (mock.alwaysMock || (0, _plugins.shouldMock)(mock, request, parent, parentModule, shouldResult)) {
// this file fill be not cached, but it`s opener - will. And we have to remember it
mockedModules[(0, _module.getModuleName)(parent)] = true;
mock.usedAs = mock.usedAs || [];
mock.usedAs.push(baseRequest);
mockedModules[baseRequest] = true;
if (mock.allowCallThrough || mock.matchOrigin || mock.mockThrough) {
if (!mock.original) {
mock.original = (0, _module.originalLoader)(request, parent, isMain);
}
}
if (mock.mockThrough) {
var factory = mock.mockThrough === true ? (0, _globals.getScopeOption)('stubFactory') : mock.mockThrough;
mock.override = mockThought(factory || standardStubFactory, mock.original);
return mockResult(request, mock, function () {
return restoreESModuleState((0, _assign2.default)({}, mock.override, mock.value), mock.original);
});
}
if (mock.overrideBy) {
if (!mock.override) {
if (typeof mock.overrideBy === 'string') {
mock.override = (0, _module.originalLoader)((0, _module.pickModuleName)(mock.overrideBy, parent), parent, isMain);
} else {
mock.override = mock.overrideBy({
name: request,
fullName: baseRequest,
parent: parent,
original: mock.original,
requireActual: function requireActual(name) {
return (0, _module.originalLoader)((0, _module.pickModuleName)(name, parent), parent, isMain);
}
});
}
}
return mockResult(request, mock, function () {
return mock.override;
});
}
if (mock.allowCallThrough) {
if (typeof mock.original === 'function') {
if ((0, _typeof3.default)(mock.value) === 'object' && (0, _keys2.default)(mock.value).length === 0) {
return mockResult(request, mock, function () {
return mock.original;
});
} else {
throw new Error('rewiremock: trying to merge Functional base with callThrough mock at ' + request + '. Use overrideBy instead.');
}
}
return mockResult(request, mock, function () {
return restoreProperties(protoCopy(mock.original, mock.value), mock.original);
});
}
return mockResult(request, mock, function () {
return mock.value;
});
} else {
// console.error('reject', baseRequest, parent.id, parent.parent.id);
mock.rejected = mock.rejected || [];
if (shouldResult.plugins) {
mock.rejected.push({
parent: parent,
plugins: shouldResult.plugins.filter(function (p, index) {
return shouldResult.values[index] === _common.NO;
}).map(function (p) {
return p.name;
})
});
}
// why you shouldn't?
}
}
if (isolation && !mockedModules[baseRequest]) {
if (!testPassby(request, parent)) {
throw new Error('rewiremock: isolation breach by [' + request + ']. Requested from ', (0, _module.getModuleName)(parent));
}
}
return (0, _module.originalLoader)(request, parent, isMain);
}
exports.default = mockLoader;