Skip to content

Commit 1686bad

Browse files
authored
Merge pull request #53 from Pythagora-io/feat/expand-unit-tests
Feat/expand unit tests
2 parents e6446dc + 2e0a7f9 commit 1686bad

File tree

8 files changed

+412
-24
lines changed

8 files changed

+412
-24
lines changed

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,15 @@ npx pythagora --unit-tests --func <FUNCTION_NAME>
2626

2727
Where `<FUNCTION_NAME>` is the name of the function you want to generate unit tests for. Just make sure that your function is exported from a file. You can see other options like generating tests for multiple files or folders [below in the Options section](#-options).
2828

29-
<br>
29+
<br><br>
30+
If you wish to expand your current test suite with more tests to get better code coverage you can run:
31+
32+
```bash
33+
npx pythagora --expand-unit-tests --path <PATH_TO_YOUR_TEST_SUITE>
34+
```
35+
for more details on expanding existing tests see [below in the Expanding existing tests section](#-expand-existing-tests).
36+
37+
<br><br>
3038

3139
**NOTE:** on Windows make sure to run all commands using `Git Bash` and not `Power Shell` or anything similiar
3240

@@ -77,6 +85,16 @@ When Pythagora generates unit tests, it uses the following approach:
7785

7886
<br>
7987

88+
# 📈 Expand existing tests
89+
If you already have generated tests for your codebase but you just want to increase your code coverage or cover more edge cases, simply run:
90+
91+
```bash
92+
npx pythagora --expand-unit-tests --path <PATH_TO_YOUR_TEST_SUITE>
93+
```
94+
When running command `PATH_TO_YOUR_TEST_SUITE` can be path to a single test file or to a folder and all test files inside of that folder will be processed and expanded.
95+
96+
That's all, enjoy your new code coverage!
97+
8098
# 📖 Options
8199
- To generate unit tests for **one single function**, run:
82100

src/bin/run.bash

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ do
6363
echo "${green}${bold}Starting generation of unit tests...${reset}"
6464
PYTHAGORA_CONFIG="$@" node "${pythagora_dir}/src/scripts/unit.js"
6565
exit 0
66+
67+
elif [[ "${args[$i]}" == "--expand-unit-tests" ]]
68+
then
69+
echo "${green}${bold}Expanding unit tests...${reset}"
70+
PYTHAGORA_CONFIG="$@" node "${pythagora_dir}/src/scripts/unitExpand.js"
71+
exit 0
72+
6673
elif [[ "${args[$i]}" == "--export-setup" ]]
6774
then
6875
PYTHAGORA_CONFIG="$@" node "${pythagora_dir}/src/scripts/enterData.js"

src/helpers/api.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,18 @@ async function getUnitTests(data, customLogFunction) {
104104
}
105105
}
106106

107+
async function expandUnitTests(data, customLogFunction) {
108+
let options = setOptions({path: '/api/expand-unit-tests'});
109+
let tests, error;
110+
try {
111+
tests = await makeRequest(JSON.stringify(data), options, customLogFunction);
112+
} catch (e) {
113+
error = e;
114+
} finally {
115+
return {tests, error};
116+
}
117+
}
118+
107119
async function getJestAuthFunction(loginMongoQueriesArray, loginRequestBody, loginEndpointPath) {
108120
jestAuthFileGenerationLog();
109121

@@ -157,5 +169,6 @@ module.exports = {
157169
getJestTestName,
158170
isEligibleForExport,
159171
getUnitTests,
172+
expandUnitTests,
160173
checkForAPIKey
161174
}

src/helpers/unitTests.js

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ let functionList = {},
3333
ignoreFilesEndingWith = [".test.js", ".test.ts", ".test.tsx"],
3434
processExtensions = ['.js', '.ts', '.tsx'],
3535
ignoreErrors = ['BABEL_PARSER_SYNTAX_ERROR'],
36-
force
36+
force,
37+
isFileToIgnore = (fileName) => {
38+
return ignoreFilesEndingWith.some(ending => fileName.endsWith(ending))
39+
}
3740
;
3841

3942
function resolveFilePath(filePath, extension) {
@@ -182,9 +185,9 @@ async function createTests(filePath, funcToTest, processingFunction = 'getUnitTe
182185
))
183186
);
184187

185-
sortFolderTree();
186-
const fileIndex = folderStructureTree.findIndex(item => item.absolutePath === filePath);
188+
sortFolderTree(folderStructureTree);
187189

190+
const fileIndex = folderStructureTree.findIndex(item => item.absolutePath === filePath);
188191
for (const [i, funcData] of uniqueFoundFunctions.entries()) {
189192
let indexToPush = fileIndex + 1 + i;
190193
let prefix = folderStructureTree[fileIndex].line.split(path.basename(folderStructureTree[fileIndex].absolutePath))[0];
@@ -267,7 +270,7 @@ async function traverseDirectory(file, onlyCollectFunctionData, funcName, proces
267270
const absolutePath = path.resolve(file);
268271
const stat = fs.statSync(absolutePath);
269272

270-
if (ignoreFilesEndingWith.some(ending => file.endsWith(ending))) return;
273+
if (!stat.isDirectory() && isFileToIgnore(file)) return;
271274

272275
if (stat.isDirectory()) {
273276
if (ignoreFolders.includes(path.basename(absolutePath)) || path.basename(absolutePath).charAt(0) === '.') return;
@@ -285,7 +288,7 @@ async function traverseDirectory(file, onlyCollectFunctionData, funcName, proces
285288
return !ignoreFolders.includes(baseName) && !baseName.startsWith('.');
286289
} else {
287290
const ext = path.extname(f);
288-
return processExtensions.includes(ext) && !ignoreFilesEndingWith.some(ending => f.endsWith(ending));
291+
return processExtensions.includes(ext) && !isFileToIgnore(f);
289292
}
290293
})
291294
.map(f => path.join(absolutePath, f));
@@ -325,9 +328,9 @@ function updateFolderTree(absolutePath) {
325328
}
326329
}
327330

328-
function sortFolderTree() {
331+
function sortFolderTree(tree) {
329332
// 1. Sort the folderStructureTree
330-
folderStructureTree.sort((a, b) => {
333+
tree.sort((a, b) => {
331334
if (a.absolutePath < b.absolutePath) {
332335
return -1;
333336
}
@@ -338,23 +341,29 @@ function sortFolderTree() {
338341
});
339342

340343
// 2. Set prefix according to the position in the directory
341-
for (let i = 0; i < folderStructureTree.length; i++) {
344+
for (let i = 0; i < tree.length; i++) {
342345
// Get the current directory path
343-
const currentDirPath = path.dirname(folderStructureTree[i].absolutePath);
346+
const currentDirPath = path.dirname(tree[i].absolutePath);
344347
// Check if it's the last file in the directory
345-
if (i === folderStructureTree.length - 1 || path.dirname(folderStructureTree[i + 1].absolutePath) !== currentDirPath) {
348+
if (i === tree.length - 1 || path.dirname(tree[i + 1].absolutePath) !== currentDirPath) {
346349
// Update the prefix for the last file in the directory
347-
folderStructureTree[i].line = folderStructureTree[i].line.replace("├───", "└───");
350+
tree[i].line = tree[i].line.replace("├───", "└───");
348351
}
349352
}
350353
}
351354

352-
async function getFunctionsForExport(dirPath) {
353-
rootPath = dirPath;
354-
await traverseDirectory(rootPath, true);
355+
async function getFunctionsForExport(path, pythagoraRoot, ignoreFilesRewrite) {
356+
if (ignoreFilesRewrite) {
357+
isFileToIgnore = ignoreFilesRewrite;
358+
}
359+
queriedPath = path;
360+
rootPath = pythagoraRoot;
361+
362+
await traverseDirectory(queriedPath, true);
363+
processedFiles = [];
364+
await traverseDirectory(queriedPath, true);
355365
processedFiles = [];
356-
await traverseDirectory(rootPath, true);
357-
return functionList;
366+
return {functionList, folderStructureTree};
358367
}
359368

360369
async function generateTestsForDirectory(args, processingFunction = 'getUnitTests') {
@@ -390,10 +399,12 @@ async function generateTestsForDirectory(args, processingFunction = 'getUnitTest
390399
console.log(`Tests are saved in the following directories:${testsGenerated.reduce((acc, item) => acc + '\n' + blue + item, '')}`);
391400
console.log(`${bold+green}${testsGenerated.length} unit tests generated!${reset}`);
392401
}
402+
393403
process.exit(0);
394404
}
395405

396406
module.exports = {
397407
getFunctionsForExport,
398-
generateTestsForDirectory
408+
generateTestsForDirectory,
409+
sortFolderTree
399410
}

0 commit comments

Comments
 (0)