itee-validators 5.5.0 → 5.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/node.js.yml +1 -1
- package/.tasks/_utils.mjs +66 -0
- package/.tasks/builds/build.mjs +65 -0
- package/.tasks/cleans/clean.mjs +20 -0
- package/.tasks/docs/doc.mjs +37 -0
- package/.tasks/helps/help.mjs +195 -0
- package/.tasks/lints/lint.mjs +33 -0
- package/.tasks/patches/patch.mjs +9 -0
- package/.tasks/tests/benchmarks/bundle-benchmarks.mjs +33 -0
- package/.tasks/tests/benchmarks/compute-benchmarks.mjs +215 -0
- package/.tasks/tests/benchmarks/run-benchmarks-for-backend.mjs +24 -0
- package/.tasks/tests/benchmarks/run-benchmarks-for-frontend.mjs +38 -0
- package/.tasks/tests/bundling/check-bundling-from-esm-build-import.mjs +167 -0
- package/.tasks/tests/bundling/check-bundling-from-esm-files-direct.mjs +129 -0
- package/.tasks/tests/bundling/check-bundling-from-esm-files-import.mjs +149 -0
- package/.tasks/tests/unit-tests/bundle-unit-tests.mjs +33 -0
- package/.tasks/tests/unit-tests/compute-unit-tests.mjs +578 -0
- package/.tasks/tests/unit-tests/run-unit-tests-for-backend.mjs +25 -0
- package/.tasks/tests/unit-tests/run-unit-tests-for-frontend.mjs +41 -0
- package/CHANGELOG.md +10 -0
- package/builds/itee-validators.cjs.js +18 -10
- package/builds/itee-validators.cjs.js.map +1 -1
- package/builds/itee-validators.cjs.min.js +62 -62
- package/builds/itee-validators.esm.js +2 -2
- package/builds/itee-validators.iife.js +4 -3
- package/builds/itee-validators.iife.js.map +1 -1
- package/builds/itee-validators.iife.min.js +17 -17
- package/package.json +1 -1
- package/sources/file-system/block-devices/isBlockDevicePath.js +2 -1
- package/sources/file-system/character-devices/isCharacterDevicePath.js +2 -1
- package/sources/file-system/directories/isDirectoryPath.js +2 -1
- package/sources/file-system/fifo-pipes/isFIFOPath.js +2 -1
- package/sources/file-system/files/isEmptyFile.js +2 -1
- package/sources/file-system/files/isFilePath.js +2 -1
- package/sources/file-system/sockets/isSocketPath.js +2 -1
- package/sources/file-system/symbolic-links/isSymbolicLinkPath.js +2 -1
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
import {
|
|
2
|
+
join,
|
|
3
|
+
normalize,
|
|
4
|
+
basename,
|
|
5
|
+
dirname,
|
|
6
|
+
extname,
|
|
7
|
+
relative
|
|
8
|
+
} from 'path'
|
|
9
|
+
import {
|
|
10
|
+
getDirname,
|
|
11
|
+
packageInfos
|
|
12
|
+
} from '../../_utils.mjs'
|
|
13
|
+
import glob from 'glob'
|
|
14
|
+
import fs from 'fs'
|
|
15
|
+
import log from 'fancy-log'
|
|
16
|
+
import colors from 'ansi-colors'
|
|
17
|
+
import { getGulpConfigForTask } from '../../../configs/gulp.conf.mjs'
|
|
18
|
+
import childProcess from 'child_process'
|
|
19
|
+
|
|
20
|
+
const {
|
|
21
|
+
red,
|
|
22
|
+
green,
|
|
23
|
+
blue,
|
|
24
|
+
cyan,
|
|
25
|
+
yellow,
|
|
26
|
+
magenta
|
|
27
|
+
} = colors
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
function computeUnitTests( done ) {
|
|
31
|
+
|
|
32
|
+
const baseDir = getDirname()
|
|
33
|
+
const sourcesDir = join( baseDir, 'sources' )
|
|
34
|
+
const testsDir = join( baseDir, 'tests' )
|
|
35
|
+
const unitsDir = join( testsDir, 'units' )
|
|
36
|
+
|
|
37
|
+
fs.mkdirSync( unitsDir, { recursive: true } )
|
|
38
|
+
|
|
39
|
+
const filePathsToIgnore = getGulpConfigForTask( 'compute-unit-tests' )
|
|
40
|
+
|
|
41
|
+
const sourcesFiles = glob.sync( join( sourcesDir, '**' ) )
|
|
42
|
+
.map( filePath => normalize( filePath ) )
|
|
43
|
+
.filter( filePath => {
|
|
44
|
+
const fileName = basename( filePath )
|
|
45
|
+
const isJsFile = fileName.endsWith( '.js' )
|
|
46
|
+
const isNotPrivateFile = !fileName.startsWith( '_' )
|
|
47
|
+
const isNotIgnoredFile = !filePathsToIgnore.includes( fileName )
|
|
48
|
+
return isJsFile && isNotPrivateFile && isNotIgnoredFile
|
|
49
|
+
} )
|
|
50
|
+
|
|
51
|
+
const unitsImportMap = []
|
|
52
|
+
for ( let sourceFile of sourcesFiles ) {
|
|
53
|
+
|
|
54
|
+
const specificFilePath = sourceFile.replace( sourcesDir, '' )
|
|
55
|
+
const specificDir = dirname( specificFilePath )
|
|
56
|
+
|
|
57
|
+
const fileName = basename( sourceFile, extname( sourceFile ) )
|
|
58
|
+
const unitFileName = `${ fileName }.unit.js`
|
|
59
|
+
const unitDirPath = join( unitsDir, specificDir )
|
|
60
|
+
const unitFilePath = join( unitDirPath, unitFileName )
|
|
61
|
+
|
|
62
|
+
const nsName = `${ fileName }Namespace`
|
|
63
|
+
const unitName = `${ fileName }Units`
|
|
64
|
+
const importDirPath = relative( unitDirPath, sourcesDir )
|
|
65
|
+
const importFilePath = join( importDirPath, specificFilePath ).replace( /\\/g, '/' )
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
|
|
69
|
+
const jsdocPath = join( baseDir, '/node_modules/jsdoc/jsdoc.js' )
|
|
70
|
+
const jsdocOutput = childProcess.execFileSync( 'node', [ jsdocPath, '-X', sourceFile ] )
|
|
71
|
+
.toString()
|
|
72
|
+
|
|
73
|
+
const classNames = []
|
|
74
|
+
const usedLongnames = []
|
|
75
|
+
const jsonData = JSON.parse( jsdocOutput ).filter( data => {
|
|
76
|
+
|
|
77
|
+
const longName = data.longname
|
|
78
|
+
|
|
79
|
+
const kind = data.kind
|
|
80
|
+
if ( kind !== 'function' ) {
|
|
81
|
+
if ( kind === 'class' && !classNames.includes( longName ) ) {
|
|
82
|
+
classNames.push( longName )
|
|
83
|
+
}
|
|
84
|
+
return false
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const undocumented = data.undocumented
|
|
88
|
+
if ( undocumented ) {
|
|
89
|
+
return false
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const scope = data.scope
|
|
93
|
+
if ( ![ 'global', 'static' ].includes( scope ) ) {
|
|
94
|
+
return false
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if ( longName.includes( ' ' ) || longName.includes( '~' ) || usedLongnames.includes( longName ) ) {
|
|
98
|
+
return false
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for ( let className of classNames ) {
|
|
102
|
+
if ( longName.includes( className ) ) {
|
|
103
|
+
return false
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
usedLongnames.push( longName )
|
|
108
|
+
|
|
109
|
+
return true
|
|
110
|
+
|
|
111
|
+
} )
|
|
112
|
+
|
|
113
|
+
if ( jsonData.length === 0 ) {
|
|
114
|
+
log( yellow( `No usable exports found in [${ sourceFile }]. Ignore it !` ) )
|
|
115
|
+
continue
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let describes = ''
|
|
119
|
+
const I = n => '\t'.repeat( n )
|
|
120
|
+
I._ = I( 1 )
|
|
121
|
+
I.__ = I( 2 )
|
|
122
|
+
I.___ = I( 3 )
|
|
123
|
+
I.____ = I( 4 )
|
|
124
|
+
I._____ = I( 5 )
|
|
125
|
+
|
|
126
|
+
for ( let docData of jsonData ) {
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
|
|
130
|
+
//check input parameters and types
|
|
131
|
+
const docParameters = docData.params || []
|
|
132
|
+
const parameters = []
|
|
133
|
+
for ( let pIndex = 0 ; pIndex < docParameters.length ; pIndex++ ) {
|
|
134
|
+
const param = docParameters[ pIndex ]
|
|
135
|
+
let paramName = param.name
|
|
136
|
+
if ( !paramName ) {
|
|
137
|
+
paramName = `param${ pIndex }`
|
|
138
|
+
// eslint-disable-next-line no-console
|
|
139
|
+
console.warn( `Missing parameter name for [${ docData.longname }]. Defaulting to [${ paramName }]` )
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const paramType = param.type
|
|
143
|
+
if ( !paramType ) {
|
|
144
|
+
throw new ReferenceError( `Missing parameter type. Unable to create unit test for [${ docData.longname }] !` )
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const parameter = {
|
|
148
|
+
name: paramName,
|
|
149
|
+
types: []
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const paramTypeNames = paramType.names
|
|
153
|
+
for ( let type of paramTypeNames ) {
|
|
154
|
+
parameter.types.push( type )
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
parameters.push( parameter )
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Check returns types
|
|
161
|
+
const docReturns = docData.returns || []
|
|
162
|
+
const returns = []
|
|
163
|
+
for ( let docReturn of docReturns ) {
|
|
164
|
+
const returnType = docReturn.type
|
|
165
|
+
if ( !returnType ) {
|
|
166
|
+
throw new ReferenceError( `Missing return type for [${ docData.longname }]. Ignore current target !` )
|
|
167
|
+
}
|
|
168
|
+
returns.push( ...returnType.names )
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Todo check throws
|
|
172
|
+
|
|
173
|
+
// Get user define rules
|
|
174
|
+
// const rules = []
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
// Infer basic rules
|
|
178
|
+
let its = ''
|
|
179
|
+
|
|
180
|
+
if ( parameters.length === 0 ) {
|
|
181
|
+
|
|
182
|
+
if ( returns.length === 0 ) {
|
|
183
|
+
|
|
184
|
+
const result = `${ I( 1 + 1 + 1 + 1 ) }const result = ${ nsName }.${ docData.name }()` + '\n'
|
|
185
|
+
const expect = `${ I( 1 + 1 + 1 + 1 ) }expect(result).to.be.a('undefined')` + '\n'
|
|
186
|
+
|
|
187
|
+
its += '' +
|
|
188
|
+
`${ I( 1 + 1 + 1 ) }it( 'return type is undefined', () => {` + '\n' +
|
|
189
|
+
'\n' +
|
|
190
|
+
`${ result }` +
|
|
191
|
+
`${ expect }` +
|
|
192
|
+
'\n' +
|
|
193
|
+
`${ I( 1 + 1 + 1 ) }} )` + '\n'
|
|
194
|
+
|
|
195
|
+
} else if ( returns.length === 1 ) {
|
|
196
|
+
|
|
197
|
+
const firstReturnType = returns[ 0 ]
|
|
198
|
+
const lowerName = firstReturnType.toLowerCase()
|
|
199
|
+
|
|
200
|
+
const result = `${ I( 1 + 1 + 1 + 1 ) }const result = ${ nsName }.${ docData.name }()` + '\n'
|
|
201
|
+
|
|
202
|
+
let expect = ''
|
|
203
|
+
if ( lowerName.startsWith( 'array' ) ) {
|
|
204
|
+
//todo array of...
|
|
205
|
+
expect += `${ I( 1 + 1 + 1 + 1 ) }expect(result).to.be.a('array')` + '\n'
|
|
206
|
+
} else {
|
|
207
|
+
expect += `${ I( 1 + 1 + 1 + 1 ) }expect(result).to.be.a('${ lowerName }')` + '\n'
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
its += '' +
|
|
211
|
+
`${ I( 1 + 1 + 1 ) }it( 'return type is ${ lowerName }', () => {` + '\n' +
|
|
212
|
+
'\n' +
|
|
213
|
+
`${ result }` +
|
|
214
|
+
`${ expect }` +
|
|
215
|
+
'\n' +
|
|
216
|
+
`${ I( 1 + 1 + 1 ) }} )` + '\n'
|
|
217
|
+
|
|
218
|
+
} else {
|
|
219
|
+
|
|
220
|
+
const result = `${ I( 1 + 1 + 1 + 1 ) }const result = ${ nsName }.${ docData.name }()` + '\n'
|
|
221
|
+
|
|
222
|
+
let returnTypesLabel = []
|
|
223
|
+
let expects = []
|
|
224
|
+
for ( let returnType of returns ) {
|
|
225
|
+
|
|
226
|
+
const lowerName = returnType.toLowerCase()
|
|
227
|
+
returnTypesLabel.push( lowerName )
|
|
228
|
+
|
|
229
|
+
if ( lowerName.startsWith( 'array' ) ) {
|
|
230
|
+
expects.push( `expect(result).to.be.a('array')` )
|
|
231
|
+
//todo array of...
|
|
232
|
+
} else {
|
|
233
|
+
expects.push( `expect(result).to.be.a('${ lowerName }')` )
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
let indent = 1 + 1 + 1 + 1
|
|
239
|
+
let openTry = ''
|
|
240
|
+
let closeTry = ''
|
|
241
|
+
for ( let expect of expects ) {
|
|
242
|
+
openTry += '' +
|
|
243
|
+
`${ I( indent ) }try {` + '\n' +
|
|
244
|
+
`${ I( indent + 1 ) }${ expect }` + '\n' +
|
|
245
|
+
`${ I( indent ) }} catch(e) {` + '\n'
|
|
246
|
+
|
|
247
|
+
closeTry = `${ I( indent ) }}` + '\n' + `${ closeTry }`
|
|
248
|
+
|
|
249
|
+
indent++
|
|
250
|
+
}
|
|
251
|
+
const _expect = '' +
|
|
252
|
+
`${ openTry }` +
|
|
253
|
+
`${ I( indent ) }expect.fail("expect result to be of type ${ returnTypesLabel.join( ' or ' ) }")` + '\n' +
|
|
254
|
+
`${ closeTry }`
|
|
255
|
+
|
|
256
|
+
its += '' +
|
|
257
|
+
`${ I( 1 + 1 + 1 ) }it( 'return type is ${ returnTypesLabel.join( ' or ' ) }', () => {` + '\n' +
|
|
258
|
+
'\n' +
|
|
259
|
+
`${ result }` +
|
|
260
|
+
`${ _expect }` +
|
|
261
|
+
'\n' +
|
|
262
|
+
`${ I( 1 + 1 + 1 ) }} )` + '\n'
|
|
263
|
+
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
} else {
|
|
267
|
+
|
|
268
|
+
if ( returns.length === 0 ) {
|
|
269
|
+
|
|
270
|
+
let itDeclaration = []
|
|
271
|
+
let index = 0
|
|
272
|
+
let indent = 1 + 1 + 1 + 1
|
|
273
|
+
let localIndent = indent
|
|
274
|
+
let dataSets = ''
|
|
275
|
+
let forLoopOpens = ''
|
|
276
|
+
let forLoopCloses = ''
|
|
277
|
+
let args = []
|
|
278
|
+
for ( let parameter of parameters ) {
|
|
279
|
+
|
|
280
|
+
const parameterType = parameter.types[ 0 ]
|
|
281
|
+
itDeclaration.push( `${ parameter.name } is of type ${ parameterType }` )
|
|
282
|
+
|
|
283
|
+
dataSets += `${ I( indent ) }const dataSet${ index } = this._dataMap[ '${ parameterType }s' ]` + '\n'
|
|
284
|
+
forLoopOpens += '' + '\n' +
|
|
285
|
+
`${ I( localIndent ) }for ( let key${ index } in dataSet${ index } ) {` + '\n' +
|
|
286
|
+
`${ I( localIndent + 1 ) }const dataSetValue${ index } = dataSet${ index }[ key${ index } ]` + '\n'
|
|
287
|
+
|
|
288
|
+
args.push( `dataSetValue${ index }` )
|
|
289
|
+
|
|
290
|
+
forLoopCloses = `${ I( localIndent ) }}` + '\n' + `${ forLoopCloses }`
|
|
291
|
+
|
|
292
|
+
index++
|
|
293
|
+
localIndent++
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const result = `${ I( localIndent ) }const result = ${ nsName }.${ docData.name }( ${ args.join( ', ' ) } )` + '\n'
|
|
297
|
+
const expect = `${ I( localIndent ) }expect(result).to.be.a('undefined')` + '\n'
|
|
298
|
+
|
|
299
|
+
const param = '' +
|
|
300
|
+
`${ dataSets }` +
|
|
301
|
+
`${ forLoopOpens }` +
|
|
302
|
+
`${ result }` +
|
|
303
|
+
`${ expect }` +
|
|
304
|
+
`${ forLoopCloses }`
|
|
305
|
+
|
|
306
|
+
its += '' +
|
|
307
|
+
`${ I( 1 + 1 + 1 ) }it( 'return type is undefined when ${ itDeclaration.join( ' and ' ) }', () => {` + '\n' +
|
|
308
|
+
'\n' +
|
|
309
|
+
`${ param }` +
|
|
310
|
+
'\n' +
|
|
311
|
+
`${ I( 1 + 1 + 1 ) }} )` + '\n'
|
|
312
|
+
|
|
313
|
+
} else if ( returns.length === 1 ) {
|
|
314
|
+
|
|
315
|
+
const firstReturnType = returns[ 0 ]
|
|
316
|
+
const lowerName = firstReturnType.toLowerCase()
|
|
317
|
+
|
|
318
|
+
let itDeclaration = []
|
|
319
|
+
let index = 0
|
|
320
|
+
let indent = 1 + 1 + 1 + 1
|
|
321
|
+
let localIndent = indent
|
|
322
|
+
let dataSets = ''
|
|
323
|
+
let forLoopOpens = ''
|
|
324
|
+
let forLoopCloses = ''
|
|
325
|
+
let args = []
|
|
326
|
+
for ( let parameter of parameters ) {
|
|
327
|
+
|
|
328
|
+
const parameterType = parameter.types[ 0 ]
|
|
329
|
+
const isAnyType = ( parameterType === '*' || parameterType.toLowerCase() === 'any' )
|
|
330
|
+
const declaration = ( isAnyType )
|
|
331
|
+
? `${ parameter.name } is of any type`
|
|
332
|
+
: `${ parameter.name } is of type ${ parameterType }`
|
|
333
|
+
itDeclaration.push( declaration )
|
|
334
|
+
|
|
335
|
+
if ( isAnyType ) {
|
|
336
|
+
|
|
337
|
+
dataSets += `${ I( indent ) }const dataMap${ index } = this._dataMap` + '\n' +
|
|
338
|
+
`${ I( localIndent ) }for ( let dataSetKey${ index } in dataMap${ index } ) {` + '\n'
|
|
339
|
+
|
|
340
|
+
localIndent++
|
|
341
|
+
dataSets += `${ I( indent + 1 ) }const dataSet${ index } = dataMap${ index }[ dataSetKey${ index } ]` + '\n'
|
|
342
|
+
forLoopOpens += '' + '\n' +
|
|
343
|
+
`${ I( localIndent ) }for ( let key${ index } in dataSet${ index } ) {` + '\n' +
|
|
344
|
+
`${ I( localIndent + 1 ) }const dataSetValue${ index } = dataSet${ index }[ key${ index } ]` + '\n'
|
|
345
|
+
|
|
346
|
+
args.push( `dataSetValue${ index }` )
|
|
347
|
+
|
|
348
|
+
forLoopCloses = `${ I( localIndent ) }}` + '\n' +
|
|
349
|
+
`${ I( localIndent - 1 ) }}` + '\n' +
|
|
350
|
+
`${ forLoopCloses }`
|
|
351
|
+
|
|
352
|
+
} else {
|
|
353
|
+
|
|
354
|
+
dataSets += `${ I( indent ) }const dataSet${ index } = this._dataMap[ '${ parameterType }s' ]` + '\n'
|
|
355
|
+
forLoopOpens += '' + '\n' +
|
|
356
|
+
`${ I( localIndent ) }for ( let key${ index } in dataSet${ index } ) {` + '\n' +
|
|
357
|
+
`${ I( localIndent + 1 ) }const dataSetValue${ index } = dataSet${ index }[ key${ index } ]` + '\n'
|
|
358
|
+
|
|
359
|
+
args.push( `dataSetValue${ index }` )
|
|
360
|
+
|
|
361
|
+
forLoopCloses = `${ I( localIndent ) }}` + '\n' + `${ forLoopCloses }`
|
|
362
|
+
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
index++
|
|
367
|
+
localIndent++
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const result = `${ I( localIndent ) }const result = ${ nsName }.${ docData.name }( ${ args.join( ', ' ) } )` + '\n'
|
|
371
|
+
|
|
372
|
+
let expect = ''
|
|
373
|
+
if ( lowerName.startsWith( 'array' ) ) {
|
|
374
|
+
expect = `${ I( localIndent ) }expect(result).to.be.a('array')` + '\n'
|
|
375
|
+
//todo array of...
|
|
376
|
+
} else {
|
|
377
|
+
expect = `${ I( localIndent ) }expect(result).to.be.a('${ lowerName }')` + '\n'
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const param = '' +
|
|
381
|
+
`${ dataSets }` +
|
|
382
|
+
`${ forLoopOpens }` +
|
|
383
|
+
`${ result }` +
|
|
384
|
+
`${ expect }` +
|
|
385
|
+
`${ forLoopCloses }`
|
|
386
|
+
|
|
387
|
+
its += '' +
|
|
388
|
+
`${ I( 1 + 1 + 1 ) }it( 'return type is ${ lowerName } when ${ itDeclaration.join( ' and ' ) }', () => {` + '\n' +
|
|
389
|
+
'\n' +
|
|
390
|
+
`${ param }` +
|
|
391
|
+
'\n' +
|
|
392
|
+
`${ I( 1 + 1 + 1 ) }} )` + '\n'
|
|
393
|
+
|
|
394
|
+
} else {
|
|
395
|
+
|
|
396
|
+
let itDeclaration = []
|
|
397
|
+
let index = 0
|
|
398
|
+
let indent = 1 + 1 + 1 + 1
|
|
399
|
+
let localIndent = indent
|
|
400
|
+
let dataSets = ''
|
|
401
|
+
let forLoopOpens = ''
|
|
402
|
+
let forLoopCloses = ''
|
|
403
|
+
let args = []
|
|
404
|
+
for ( let parameter of parameters ) {
|
|
405
|
+
|
|
406
|
+
const parameterType = parameter.types[ 0 ]
|
|
407
|
+
itDeclaration.push( `${ parameter.name } is of type ${ parameterType }` )
|
|
408
|
+
|
|
409
|
+
dataSets += `${ I( indent ) }const dataSet${ index } = this._dataMap[ '${ parameterType }s' ]` + '\n'
|
|
410
|
+
forLoopOpens += '' + '\n' +
|
|
411
|
+
`${ I( localIndent ) }for ( let key${ index } in dataSet${ index } ) {` + '\n' +
|
|
412
|
+
`${ I( localIndent + 1 ) }const dataSetValue${ index } = dataSet${ index }[ key${ index } ]` + '\n'
|
|
413
|
+
|
|
414
|
+
args.push( `dataSetValue${ index }` )
|
|
415
|
+
|
|
416
|
+
forLoopCloses = `${ I( localIndent ) }}` + '\n' + `${ forLoopCloses }`
|
|
417
|
+
|
|
418
|
+
index++
|
|
419
|
+
localIndent++
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const result = `${ I( localIndent ) }const result = ${ nsName }.${ docData.name }( ${ args.join( ', ' ) } )` + '\n'
|
|
423
|
+
|
|
424
|
+
let returnTypesLabel = []
|
|
425
|
+
let expects = []
|
|
426
|
+
for ( let returnType of returns ) {
|
|
427
|
+
|
|
428
|
+
const lowerName = returnType.toLowerCase()
|
|
429
|
+
returnTypesLabel.push( lowerName )
|
|
430
|
+
|
|
431
|
+
if ( lowerName.startsWith( 'array' ) ) {
|
|
432
|
+
expects.push( `expect(result).to.be.a('array')` )
|
|
433
|
+
//todo array of...
|
|
434
|
+
} else {
|
|
435
|
+
expects.push( `expect(result).to.be.a('${ lowerName }')` )
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
}
|
|
439
|
+
let openTry = ''
|
|
440
|
+
let closeTry = ''
|
|
441
|
+
for ( let expect of expects ) {
|
|
442
|
+
openTry += '' +
|
|
443
|
+
`${ I( localIndent ) }try {` + '\n' +
|
|
444
|
+
`${ I( localIndent + 1 ) }${ expect }` + '\n' +
|
|
445
|
+
`${ I( localIndent ) }} catch(e) {` + '\n'
|
|
446
|
+
|
|
447
|
+
closeTry = `${ I( localIndent ) }}` + '\n' + `${ closeTry }`
|
|
448
|
+
|
|
449
|
+
localIndent++
|
|
450
|
+
}
|
|
451
|
+
const _expect = '' +
|
|
452
|
+
`${ openTry }` +
|
|
453
|
+
`${ I( localIndent ) }expect.fail("expect result to be of type ${ returnTypesLabel.join( ' or ' ) }")` + '\n' +
|
|
454
|
+
`${ closeTry }`
|
|
455
|
+
|
|
456
|
+
const param = '' +
|
|
457
|
+
`${ dataSets }` +
|
|
458
|
+
`${ forLoopOpens }` +
|
|
459
|
+
`${ result }` +
|
|
460
|
+
`${ _expect }` +
|
|
461
|
+
`${ forLoopCloses }`
|
|
462
|
+
|
|
463
|
+
its += '' +
|
|
464
|
+
`${ I( 1 + 1 + 1 ) }it( 'return type is ${ returnTypesLabel.join( ' or ' ) } when ${ itDeclaration.join( ' and ' ) }', () => {` + '\n' +
|
|
465
|
+
'\n' +
|
|
466
|
+
`${ param }` +
|
|
467
|
+
'\n' +
|
|
468
|
+
`${ I( 1 + 1 + 1 ) }} )` + '\n'
|
|
469
|
+
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
describes += '' +
|
|
475
|
+
`${ I.__ }describe( '${ docData.name }()', () => {` + '\n' +
|
|
476
|
+
'\n' +
|
|
477
|
+
`${ I.___ }it( 'is bundlable', () => {` + '\n' +
|
|
478
|
+
'\n' +
|
|
479
|
+
`${ I.____ }expect(${ nsName }.${ docData.name }).to.exist` + '\n' +
|
|
480
|
+
'\n' +
|
|
481
|
+
`${ I.___ }} )` + '\n' +
|
|
482
|
+
'\n' +
|
|
483
|
+
`${ its }` +
|
|
484
|
+
'\n' +
|
|
485
|
+
`${ I.__ }} )` + '\n' +
|
|
486
|
+
'\n'
|
|
487
|
+
|
|
488
|
+
} catch ( error ) {
|
|
489
|
+
|
|
490
|
+
log( red( error.message ) )
|
|
491
|
+
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const template = '' +
|
|
497
|
+
`import { expect } from 'chai'` + '\n' +
|
|
498
|
+
`import { beforeEach, afterEach, describe, it } from 'mocha'` + '\n' +
|
|
499
|
+
`import { Testing } from 'itee-utils'` + '\n' +
|
|
500
|
+
`import * as ${ nsName } from '${ importFilePath }'` + '\n' +
|
|
501
|
+
'\n' +
|
|
502
|
+
`function ${ unitName } () {` + '\n' +
|
|
503
|
+
'\n' +
|
|
504
|
+
`${ I( 1 ) }beforeEach( () => {` + '\n' +
|
|
505
|
+
'\n' +
|
|
506
|
+
`${ I( 1 + 1 ) }this._dataMap = Testing.createDataMap()` + '\n' +
|
|
507
|
+
'\n' +
|
|
508
|
+
`${ I( 1 ) }} )` + '\n' +
|
|
509
|
+
'\n' +
|
|
510
|
+
`${ I( 1 ) }afterEach( () => {` + '\n' +
|
|
511
|
+
'\n' +
|
|
512
|
+
`${ I( 1 + 1 ) }delete this._dataMap` + '\n' +
|
|
513
|
+
'\n' +
|
|
514
|
+
`${ I( 1 ) }} )` + '\n' +
|
|
515
|
+
'\n' +
|
|
516
|
+
`${ I( 1 ) }describe( '${ unitName }', () => {` + '\n' +
|
|
517
|
+
'\n' +
|
|
518
|
+
`${ describes }` +
|
|
519
|
+
'' +
|
|
520
|
+
`${ I( 1 ) }} )` + '\n' +
|
|
521
|
+
'\n' +
|
|
522
|
+
'}' + '\n' +
|
|
523
|
+
'\n' +
|
|
524
|
+
`export { ${ unitName } }` + '\n' +
|
|
525
|
+
'\n'
|
|
526
|
+
|
|
527
|
+
const importUnitFilePath = relative( unitsDir, unitFilePath )
|
|
528
|
+
unitsImportMap.push( {
|
|
529
|
+
exportName: unitName,
|
|
530
|
+
path: importUnitFilePath.replace( /\\/g, '/' )
|
|
531
|
+
} )
|
|
532
|
+
|
|
533
|
+
log( green( `Create ${ unitFilePath }` ) )
|
|
534
|
+
fs.mkdirSync( unitDirPath, { recursive: true } )
|
|
535
|
+
fs.writeFileSync( unitFilePath, template )
|
|
536
|
+
|
|
537
|
+
} catch ( error ) {
|
|
538
|
+
|
|
539
|
+
log( red( error.message ) )
|
|
540
|
+
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Global units file
|
|
546
|
+
let computedImports = ''
|
|
547
|
+
let computedUnitCalls = ''
|
|
548
|
+
for ( let entry of unitsImportMap ) {
|
|
549
|
+
computedImports += `import { ${ entry.exportName } } from './${ entry.path }'` + '\n'
|
|
550
|
+
computedUnitCalls += ` ${ entry.exportName }.call( root )` + '\n'
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
const unitsTemplate = '' +
|
|
554
|
+
'import { describe } from \'mocha\'' + '\n' +
|
|
555
|
+
`${ computedImports }` +
|
|
556
|
+
'\n' +
|
|
557
|
+
'const root = typeof window === \'undefined\'' + '\n' +
|
|
558
|
+
' ? typeof global === \'undefined\'' + '\n' +
|
|
559
|
+
' ? Function( \'return this\' )() ' + '\n' +
|
|
560
|
+
' : global ' + '\n' +
|
|
561
|
+
' : window' + '\n' +
|
|
562
|
+
'\n' +
|
|
563
|
+
'describe( \'Itee#Validators\', () => {' + '\n' +
|
|
564
|
+
'\n' +
|
|
565
|
+
`${ computedUnitCalls }` +
|
|
566
|
+
'\n' +
|
|
567
|
+
'} )' + '\n'
|
|
568
|
+
|
|
569
|
+
const unitsFilePath = join( unitsDir, `${ packageInfos.name }.units.js` )
|
|
570
|
+
|
|
571
|
+
log( green( `Create ${ unitsFilePath }` ) )
|
|
572
|
+
fs.writeFileSync( unitsFilePath, unitsTemplate )
|
|
573
|
+
|
|
574
|
+
done()
|
|
575
|
+
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export { computeUnitTests }
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { join } from 'path'
|
|
2
|
+
import { spawn } from 'child_process'
|
|
3
|
+
import {
|
|
4
|
+
getDirname,
|
|
5
|
+
packageInfos
|
|
6
|
+
} from '../../_utils.mjs'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
function runUnitTestsForBackend( done ) {
|
|
10
|
+
|
|
11
|
+
const projectDir = getDirname()
|
|
12
|
+
const mochaPath = join( projectDir, 'node_modules/mocha/bin/mocha' )
|
|
13
|
+
const testsPath = join( projectDir, `tests/units/builds/${ packageInfos.name }.units.cjs.js` )
|
|
14
|
+
const mocha = spawn( 'node', [ mochaPath, testsPath ], { stdio: 'inherit' } )
|
|
15
|
+
mocha.on( 'close', ( code ) => {
|
|
16
|
+
|
|
17
|
+
( code === 0 )
|
|
18
|
+
? done()
|
|
19
|
+
: done( `mocha exited with code ${ code }` )
|
|
20
|
+
|
|
21
|
+
} )
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { runUnitTestsForBackend }
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { normalize } from 'path'
|
|
2
|
+
import karma from 'karma'
|
|
3
|
+
import log from 'fancy-log'
|
|
4
|
+
import colors from 'ansi-colors'
|
|
5
|
+
import {
|
|
6
|
+
getDirname,
|
|
7
|
+
packageInfos
|
|
8
|
+
} from '../../_utils.mjs'
|
|
9
|
+
|
|
10
|
+
const {
|
|
11
|
+
red,
|
|
12
|
+
green,
|
|
13
|
+
blue,
|
|
14
|
+
cyan,
|
|
15
|
+
yellow,
|
|
16
|
+
magenta
|
|
17
|
+
} = colors
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
async function runUnitTestsForFrontend( done ) {
|
|
21
|
+
|
|
22
|
+
const projectDir = getDirname()
|
|
23
|
+
const configFile = normalize( `${ projectDir }/configs/karma.units.conf.js` )
|
|
24
|
+
const karmaConfig = karma.config.parseConfig( configFile )
|
|
25
|
+
const karmaServer = new karma.Server( karmaConfig, ( exitCode ) => {
|
|
26
|
+
if ( exitCode === 0 ) {
|
|
27
|
+
log( `Karma server exit with code ${ exitCode }` )
|
|
28
|
+
done()
|
|
29
|
+
} else {
|
|
30
|
+
done( `Karma server exit with code ${ exitCode }` )
|
|
31
|
+
}
|
|
32
|
+
} )
|
|
33
|
+
karmaServer.on( 'browser_error', ( browser, error ) => {
|
|
34
|
+
log( red( error.message ) )
|
|
35
|
+
} )
|
|
36
|
+
|
|
37
|
+
await karmaServer.start()
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { runUnitTestsForFrontend }
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
# [v5.6.0](https://github.com/Itee/itee-validators/compare/v5.5.1...v5.6.0) (2025-10-18)
|
|
2
|
+
|
|
3
|
+
## ✨ New Features
|
|
4
|
+
- [`187970c`](https://github.com/Itee/itee-validators/commit/187970c) (gulpfile) split gulpfile tasks into sub-tasks files
|
|
5
|
+
|
|
6
|
+
## 🐛 Bug Fixes
|
|
7
|
+
- [`1ae6d25`](https://github.com/Itee/itee-validators/commit/1ae6d25) (sources) avoid validator with thrown during migration
|
|
8
|
+
|
|
9
|
+
# [v5.5.1](https://github.com/Itee/itee-validators/compare/v5.5.0...v5.5.1) (2025-10-16)
|
|
10
|
+
|
|
1
11
|
# [v5.5.0](https://github.com/Itee/itee-validators/compare/v5.4.0...v5.5.0) (2025-10-16)
|
|
2
12
|
|
|
3
13
|
## ✨ New Features
|