This repository has been archived by the owner on Dec 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerateParameterizedTests.js
176 lines (158 loc) · 4.66 KB
/
generateParameterizedTests.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
const fs = require('fs');
const path = require('path');
/**
* Returns an array of files (absolute path) matching a file extension in a
* directory.
*
* @param {string} directory
* @param {string} extension
*
* @returns {string[]}
*/
function getFilesWithExtension(directory, extension) {
const matchedFiles = [];
if (!fs.existsSync(directory)) {
throw new Error(`Directory "${directory}" does not exist`);
}
const files = fs.readdirSync(directory);
for (let i = 0; i < files.length; i += 1) {
const filename = path.join(directory, files[i]);
const stat = fs.lstatSync(filename);
if (stat.isDirectory()) {
// Recurse
const nestedMatchedFiles = getFilesWithExtension(filename, extension);
matchedFiles.push(...nestedMatchedFiles);
} else if (filename.endsWith(extension)) {
matchedFiles.push(filename);
}
}
return matchedFiles;
}
/**
* @param {string} line
*
* @returns {null|{testCaseName: string, testCaseArguments: string}}
*/
function parseParameterizedTestCase(line) {
const regex = /^\s*\/\/>\s*(\w*)(.*)\s*$/m;
const matches = regex.exec(line);
if (matches === null) {
return null;
}
return {
testCaseName: matches[1],
testCaseArguments: matches[2],
};
}
/**
* @param {string} line
*
* @returns {null|string}
*/
function parseParameterizedTestAnnotation(line) {
const regex = /^\s*@ParameterizedTest(.*)$/m;
const matches = regex.exec(line);
if (matches === null) {
return null;
}
return matches[1];
}
/**
* @param {string} line
*
* @returns {null|string}
*/
function parseTestFunction(line) {
const regex = /^\s*public\s*void\s*([a-zA-Z0-9_]*)(.*)$/m;
const matches = regex.exec(line);
if (matches === null) {
return null;
}
return matches[1];
}
/**
* @param {string} testName
* @param {string} testAnnotation
* @param {{testCaseName: string, testCaseArguments: string}[]} testCases
*
* @returns {string[]}
*/
function generateTestsForParameterizedTest(testName, testAnnotation, testCases) {
return testCases.map((testCase) => `
@Test${testAnnotation}
public void ${testName + testCase.testCaseName}() {
${testName + testCase.testCaseArguments};
}`);
}
/**
* @param {string} filepath
*/
function processFile(filepath) {
const dividingLine = '\n // DO NOT EDIT BELOW THIS LINE\n';
const generatedTests = [];
// Keep track of various tokens while processing the file
let parameterizedTestCases = [];
let parameterizedTestAnnotation = null;
// Read contents of the file
const fileContent = fs.readFileSync(filepath, 'UTF-8');
const lines = fileContent.split(/\r?\n/);
// For each line in the file
lines.forEach((line) => {
// Find parameterized test cases
const parsedParameterizedTestCase = parseParameterizedTestCase(line);
if (parsedParameterizedTestCase !== null) {
parameterizedTestCases.push(parsedParameterizedTestCase);
return;
}
// Find parameterized test annotations, which may include "expected=..."
// attributes
const parsedParameterizedTestAnnotation = parseParameterizedTestAnnotation(
line,
);
if (parsedParameterizedTestAnnotation !== null) {
parameterizedTestAnnotation = parsedParameterizedTestAnnotation;
return;
}
// Find the parameterized test name
const parsedParameterizedTestName = parseTestFunction(line);
if (parsedParameterizedTestName !== null) {
if (
parameterizedTestCases.length > 0
&& parameterizedTestAnnotation !== null
) {
generatedTests.push(
...generateTestsForParameterizedTest(
parsedParameterizedTestName,
parameterizedTestAnnotation,
parameterizedTestCases,
),
);
}
parameterizedTestCases = [];
parameterizedTestAnnotation = null;
}
});
// If no parameterized tests were found, do not change anything
if (generatedTests.length === 0) {
return;
}
// Determine where to append the generated tests
let newFileContent;
const dividingLinePosition = fileContent.indexOf(dividingLine);
if (dividingLinePosition === -1) {
// Find the last '}' at the end of the file
newFileContent = fileContent.replace(/\s*}\s*$/g, '\n');
} else {
// Find the dividing line position
newFileContent = fileContent.substring(0, dividingLinePosition);
}
// Append generated tests to end of file
newFileContent += dividingLine;
newFileContent += generatedTests.join('\n');
newFileContent += '\n}\n';
fs.writeFileSync(filepath, newFileContent);
}
const testDir = `${process.cwd()}/${process.argv[2]}`;
getFilesWithExtension(testDir, '.java').forEach((filepath) => {
processFile(filepath);
});