UNPKG

rewiremock

Version:

Advanced dependency mocking device.

374 lines (306 loc) 12 kB
'use strict'; 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;