-
Notifications
You must be signed in to change notification settings - Fork 79
/
Runner.js
123 lines (96 loc) · 3.18 KB
/
Runner.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// @flow
const gracefulFs = require('graceful-fs');
const path = require('path');
const Parser = require('./Parser');
function findTests(
testFilePaths /*: Array<string> */,
sourceDirs /*: Array<string> */,
isPackageProject /*: boolean */
) /*: Promise<Array<{ moduleName: string, possiblyTests: Array<string> }>> */ {
return Promise.all(
testFilePaths.map((filePath) => {
const matchingSourceDirs = sourceDirs.filter((dir) =>
filePath.startsWith(`${dir}${path.sep}`)
);
// Tests must be in tests/ or in source-directories – otherwise they won’t
// compile. Elm won’t be able to find imports.
switch (matchingSourceDirs.length) {
case 0:
return Promise.reject(
Error(missingSourceDirectoryError(filePath, isPackageProject))
);
case 1:
// Keep going.
break;
default:
// This shouldn’t be possible for package projects.
return Promise.reject(
new Error(
multipleSourceDirectoriesError(filePath, matchingSourceDirs)
)
);
}
// By finding the module name from the file path we can import it even if
// the file is full of errors. Elm will then report what’s wrong.
const moduleNameParts = path
.relative(matchingSourceDirs[0], filePath)
.replace(/\.elm$/, '')
.split(path.sep);
const moduleName = moduleNameParts.join('.');
if (!moduleNameParts.every(Parser.isUpperName)) {
return Promise.reject(
new Error(
badModuleNameError(filePath, matchingSourceDirs[0], moduleName)
)
);
}
return Parser.extractExposedPossiblyTests(
filePath,
// We’re reading files asynchronously in a loop here, so it makes sense
// to use graceful-fs to avoid “too many open files” errors.
gracefulFs.createReadStream
).then((possiblyTests) => ({
moduleName,
possiblyTests,
}));
})
);
}
function missingSourceDirectoryError(filePath, isPackageProject) {
return `
This file:
${filePath}
…matches no source directory! Imports won’t work then.
${
isPackageProject
? 'Move it to tests/ or src/ in your project root.'
: 'Move it to tests/ in your project root, or make sure it is covered by "source-directories" in your elm.json.'
}
`.trim();
}
function multipleSourceDirectoriesError(filePath, matchingSourceDirs) {
return `
This file:
${filePath}
…matches more than one source directory:
${matchingSourceDirs.join('\n')}
Edit "source-directories" in your elm.json and try to make it so no source directory contains another source directory!
`.trim();
}
function badModuleNameError(filePath, sourceDir, moduleName) {
return `
This file:
${filePath}
…located in this directory:
${sourceDir}
…is problematic. Trying to construct a module name from the parts after the directory gives:
${moduleName}
…but module names need to look like for example:
Main
Http.Helpers
Make sure that all parts start with an uppercase letter and don’t contain any spaces or anything like that.
`.trim();
}
module.exports = {
findTests: findTests,
};