@@ -2,42 +2,38 @@ const fs = require('fs');
2
2
const path = require ( 'path' ) ;
3
3
const _ = require ( 'lodash' ) ;
4
4
const { expandUnitTests, checkForAPIKey} = require ( './api' ) ;
5
- // const {PYTHAGORA_UNIT_DIR} = require("../const/common");
6
- // const generator = require("@babel/generator").default;
7
- const { delay, checkDirectoryExists} = require ( "../utils/common" ) ;
5
+ const { PYTHAGORA_UNIT_DIR } = require ( "../const/common" ) ;
6
+ const { checkDirectoryExists} = require ( "../utils/common" ) ;
8
7
const {
9
8
getAstFromFilePath,
10
9
getRelatedTestImports,
11
10
getSourceCodeFromAst,
12
11
getModuleTypeFromFilePath
13
12
} = require ( "../utils/code" ) ;
14
13
const { getFunctionsForExport } = require ( "./unitTests" )
15
- const { getRelativePath, getFolderTreeItem , getTestFolderPath, checkPathType, isPathInside } = require ( "../utils/files" ) ;
14
+ const { getRelativePath, getTestFolderPath, checkPathType} = require ( "../utils/files" ) ;
16
15
const { initScreenForUnitTests} = require ( "./cmdGUI" ) ;
17
- const { forEach } = require ( 'lodash' ) ;
18
- //const {green, red, blue, bold, reset} = require('../utils/cmdPrint').colors;
16
+ const { green, red, blue, bold, reset} = require ( '../utils/cmdPrint' ) . colors ;
19
17
20
18
let functionList = { } ,
21
- leftPanel ,
22
- rightPanel ,
23
19
screen ,
24
20
scrollableContent ,
25
21
spinner ,
26
22
rootPath = '' ,
27
23
queriedPath = '' ,
28
24
folderStructureTree = [ ] ,
29
25
testsGenerated = [ ] ,
26
+ skippedFiles = [ ] ,
30
27
errors = [ ] ,
31
28
ignoreFolders = [ 'node_modules' , 'pythagora_tests' ] ,
29
+ filesEndingWith = [ ".js" , ".ts" , ".tsx" ] ,
32
30
processExtensions = [ '.js' , '.ts' ] ,
33
31
ignoreErrors = [ 'BABEL_PARSER_SYNTAX_ERROR' ] ,
34
32
force
35
33
;
36
34
37
- //the same like in uniTests.js - TODO: reuse it
38
35
async function saveTests ( filePath , fileName , testData ) {
39
36
let dir = filePath . substring ( 0 , filePath . lastIndexOf ( '/' ) ) ;
40
- //dir = getTestFolderPath(filePath, rootPath);
41
37
42
38
if ( ! await checkDirectoryExists ( dir ) ) {
43
39
fs . mkdirSync ( dir , { recursive : true } ) ;
@@ -52,18 +48,17 @@ function reformatDataForPythagoraAPI(filePath, testCode, relatedCode, syntaxType
52
48
const importedFiles = [ ] ;
53
49
54
50
_ . forEach ( relatedCode , ( f ) => {
55
- const fileFolderPath = f . filePath . substring ( 0 , f . filePath . lastIndexOf ( '/' ) )
51
+ const fileFolderPath = f . filePath . substring ( 0 , f . filePath . lastIndexOf ( '/' ) ) ;
56
52
const pathRelativeToTest = getRelativePath ( f . filePath , getTestFolderPath ( fileFolderPath , rootPath ) ) ;
57
53
f . pathRelativeToTest = pathRelativeToTest ;
58
- //f.fileName = f.fileName.substring(f.fileName.lastIndexOf('/') + 1);
59
54
60
55
if ( ! importedFiles . find ( i => i . filePath == f . filePath ) ) {
61
56
importedFiles . push ( {
62
57
fileName : f . fileName . substring ( f . fileName . lastIndexOf ( '/' ) + 1 ) ,
63
58
filePath : f . filePath ,
64
59
pathRelativeToTest : f . pathRelativeToTest ,
65
60
syntaxType : f . syntaxType
66
- } )
61
+ } ) ;
67
62
}
68
63
} )
69
64
@@ -77,47 +72,62 @@ function reformatDataForPythagoraAPI(filePath, testCode, relatedCode, syntaxType
77
72
importedFiles,
78
73
isES6Syntax : syntaxType === 'ES6' ,
79
74
pathRelativeToTest
80
- }
75
+ } ;
81
76
}
82
77
83
78
async function createAdditionalTests ( filePath , prefix ) {
84
- //TODO-1: get test source code and source code of related functions (import, require)
85
- const ast = await getAstFromFilePath ( filePath ) ;
86
- let syntaxType = await getModuleTypeFromFilePath ( ast ) ;
87
-
88
- //const testCode = getSourceCodeFromAst(ast);
89
-
90
- const importRegex = / ^ ( .* i m p o r t .* | .* r e q u i r e .* ) $ / gm;
91
- let testCode = getSourceCodeFromAst ( ast ) ;
92
- testCode = testCode . replace ( importRegex , '' ) ;
93
-
94
-
95
- const relatedTestCode = getRelatedTestImports ( ast , filePath , functionList )
96
-
97
- // Now we have test source code and related test functions source code (imported or required)
98
- // TODO-1: reformat data
99
-
100
- const testPath = getTestFolderPath ( filePath , rootPath )
101
- const formattedData = reformatDataForPythagoraAPI ( filePath , testCode , relatedTestCode , syntaxType )
102
-
103
- // TODO-2: send date to API for processing
104
- // TODO-3: check only for *.test.js files pattern
105
- // TODO-4: save processing results data
79
+ try {
80
+ const ast = await getAstFromFilePath ( filePath ) ;
81
+ let syntaxType = await getModuleTypeFromFilePath ( ast ) ;
82
+
83
+ const importRegex = / ^ ( .* i m p o r t .* | .* r e q u i r e .* ) $ / gm;
84
+ let testCode = getSourceCodeFromAst ( ast ) ;
85
+ testCode = testCode . replace ( importRegex , '' ) ;
86
+
87
+ const relatedTestCode = getRelatedTestImports ( ast , filePath , functionList ) ;
88
+ const testPath = path . join (
89
+ path . resolve ( PYTHAGORA_UNIT_DIR ) ,
90
+ filePath . replace ( rootPath , '' )
91
+ ) ;
92
+
93
+ const formattedData = reformatDataForPythagoraAPI ( filePath , testCode , relatedTestCode , syntaxType )
94
+ const fileIndex = folderStructureTree . findIndex ( item => item . absolutePath === filePath ) ;
95
+ spinner . start ( folderStructureTree , fileIndex ) ;
96
+
97
+ if ( fs . existsSync ( testPath ) && ! force ) {
98
+ skippedFiles . push ( testPath ) ;
99
+ await spinner . stop ( ) ;
100
+ folderStructureTree [ fileIndex ] . line = `${ green } ${ folderStructureTree [ fileIndex ] . line } ${ reset } ` ;
101
+ return ;
102
+ }
106
103
107
- console . log ( 'formattedData: ' , formattedData )
108
- let { tests, error } = await expandUnitTests ( formattedData ) ;
109
- if ( tests ) {
110
- await saveTests ( testPath , formattedData . testFileName , tests ) ;
104
+ let { tests, error } = await expandUnitTests ( formattedData , ( content ) => {
105
+ scrollableContent . setContent ( content ) ;
106
+ scrollableContent . setScrollPerc ( 100 ) ;
107
+ screen . render ( ) ;
108
+ } ) ;
109
+
110
+ if ( tests ) {
111
+ await saveTests ( testPath , formattedData . testFileName , tests ) ;
112
+ testsGenerated . push ( testPath ) ;
113
+ await spinner . stop ( ) ;
114
+ folderStructureTree [ fileIndex ] . line = `${ green } ${ folderStructureTree [ fileIndex ] . line } ${ reset } ` ;
115
+ } else if ( error ) {
116
+ errors . push ( {
117
+ file : filePath ,
118
+ error : { stack : error . stack , message : error . message }
119
+ } ) ;
120
+ await spinner . stop ( ) ;
121
+ folderStructureTree [ fileIndex ] . line = `${ red } ${ folderStructureTree [ fileIndex ] . line } ${ reset } ` ;
122
+ }
123
+ } catch ( e ) {
124
+ if ( ! ignoreErrors . includes ( e . code ) ) errors . push ( e ) ;
111
125
}
112
-
113
- // TODO-5: display processing progress in a proper way
114
126
}
115
127
116
128
function checkForTestFilePath ( filePath ) {
117
- const pattern = / t e s t \. ( j s | t s ) $ / ;
129
+ const pattern = / t e s t \. ( j s | t s | t s x ) $ / ;
118
130
return pattern . test ( filePath ) ;
119
- // if (pattern.test(filePath)) return true
120
- // else
121
131
}
122
132
123
133
async function traverseDirectoryTests ( directory , prefix = '' ) {
@@ -132,32 +142,49 @@ async function traverseDirectoryTests(directory, prefix = '') {
132
142
for ( const file of files ) {
133
143
const absolutePath = path . join ( directory , file ) ;
134
144
const stat = fs . statSync ( absolutePath ) ;
135
- //const isLast = files.indexOf(file) === files.length - 1;
136
145
if ( stat . isDirectory ( ) ) {
137
146
if ( ignoreFolders . includes ( path . basename ( absolutePath ) ) || path . basename ( absolutePath ) . charAt ( 0 ) === '.' ) continue ;
138
-
139
- //const newPrefix = isLast ? `${prefix} ` : `${prefix}| `;
140
147
await traverseDirectoryTests ( absolutePath , prefix ) ;
141
148
} else {
142
149
if ( ! processExtensions . includes ( path . extname ( absolutePath ) ) || ! checkForTestFilePath ( file ) ) continue ;
143
- //const newPrefix = isLast ? `| ${prefix} ` : `| ${prefix}| `;
144
- //await createAdditionalTests(absolutePath, newPrefix);
145
150
await createAdditionalTests ( absolutePath , prefix ) ;
146
151
}
147
152
}
148
153
}
149
154
150
155
async function expandTestsForDirectory ( args ) {
151
- let pathToProcess = args . expand_path ,
152
- force = args . force ;
156
+ let pathToProcess = args . expand_path ;
157
+ force = args . force ;
153
158
154
159
checkForAPIKey ( ) ;
155
160
queriedPath = path . resolve ( pathToProcess ) ;
156
161
rootPath = process . cwd ( ) ;
157
162
( { screen, spinner, scrollableContent } = initScreenForUnitTests ( ) ) ;
158
- functionList = await getFunctionsForExport ( rootPath )
159
163
160
- await traverseDirectoryTests ( queriedPath , false )
164
+ const exportData = await getFunctionsForExport ( pathToProcess || rootPath , ( fileName ) => {
165
+ return ! filesEndingWith . some ( ending => fileName . endsWith ( ending ) ) ;
166
+ } ) ;
167
+ functionList = exportData . functionList ;
168
+ folderStructureTree = exportData . folderStructureTree ;
169
+ folderStructureTree = folderStructureTree . filter ( ( i ) => checkForTestFilePath ( i . absolutePath ) || i . isDirectory ) ;
170
+
171
+ await traverseDirectoryTests ( queriedPath , false ) ;
172
+
173
+ screen . destroy ( ) ;
174
+ process . stdout . write ( '\x1B[2J\x1B[0f' ) ;
175
+ if ( errors . length ) {
176
+ let errLogPath = `${ path . resolve ( PYTHAGORA_UNIT_DIR , 'errorLogs.log' ) } ` ;
177
+ fs . writeFileSync ( errLogPath , JSON . stringify ( errors , null , 2 ) ) ;
178
+ console . error ( 'There were errors encountered while trying to expand unit tests.\n' ) ;
179
+ console . error ( `You can find logs here: ${ errLogPath } ` ) ;
180
+ }
181
+ if ( skippedFiles . length ) console . log ( `${ bold } Generation of ${ skippedFiles . length } test suites were skipped because tests already exist. If you want to override them add "--force" flag to command${ reset } ` ) ;
182
+ if ( testsGenerated . length === 0 ) {
183
+ console . log ( `${ bold + red } No tests generated!${ reset } ` ) ;
184
+ } else {
185
+ console . log ( `Tests are saved in the following directories:${ testsGenerated . reduce ( ( acc , item ) => acc + '\n' + blue + item , '' ) } ` ) ;
186
+ console . log ( `${ bold + green } ${ testsGenerated . length } unit tests generated!${ reset } ` ) ;
187
+ }
161
188
162
189
process . exit ( 0 ) ;
163
190
}
0 commit comments