-
Notifications
You must be signed in to change notification settings - Fork 3
/
ManualMockLoader.js
72 lines (61 loc) · 2.55 KB
/
ManualMockLoader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
'use strict';
const path = require('path');
const fs = require('fs');
const LOADER_DELIMITER = '!';
const MOCKS_DIR_NAME = '__mocks__';
/**
* A module is considered a package if a) it does not being with './',
* '/' or '../' and b) it's in a `config.resolve.modulesDirectories` dir.
* @param {String} loaderLessRawRequest The raw request (without loaders).
* @param {String} resourcePath The absolute resource path.
* @param {Array} modulesDirectories Array of module directories, e.g. 'node_modules',
* 'web_modules' etc.
* @return {Boolean}
*/
function isPackage(loaderLessRawRequest, resourcePath, modulesDirectories) {
return modulesDirectories.some(dir => {
return resourcePath.indexOf(dir) !== -1;
}) && !['.', '/'].some(val => {
return val === loaderLessRawRequest[0];
});
}
function manualMockLoader(source) {
const cwd = process.cwd();
const request = this.request;
const resourcePath = this.resourcePath;
const dirName = path.dirname(resourcePath);
const fileName = path.basename(resourcePath);
const rawRequest = this._module.rawRequest;
const rawRequestParts = rawRequest.split(LOADER_DELIMITER);
const loaderLessRawRequest = rawRequestParts[rawRequestParts.length - 1];
const modulesDirectories = this.options.resolve.modulesDirectories;
let mockResourcePath;
if (this.cacheable) {
this.cacheable();
}
// If the module is considered a package entry file then mocks are expected to be in
// cwd/__mocks__/**.
// NOTE: not sure if this is the exact same behaviour as `node-haste`
// https://github.com/facebook/jest/issues/509
if (isPackage(loaderLessRawRequest, resourcePath, modulesDirectories)) {
mockResourcePath = path.join(cwd, MOCKS_DIR_NAME, loaderLessRawRequest);
if (!/\.js$/.test(mockResourcePath)) {
mockResourcePath += '.js';
}
} else {
mockResourcePath = path.join(dirName, MOCKS_DIR_NAME, fileName);
}
try {
let stats = fs.statSync(mockResourcePath);
if (stats.isFile()) {
// Using '!!' (https://webpack.github.io/docs/loaders.html#loader-order) to disable all loaders
// specified in config as the `request` already contains the absolute loader paths.
source = 'jest._registerManualMock("!!' + request + '", "' +
mockResourcePath + '");\n' + source;
}
} catch (e) {
// Manual mock does not exist.
}
return source;
}
module.exports = manualMockLoader;