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
|
@@ -32,7 +32,7 @@ jobs:
|
|
|
32
32
|
- name: Install dependencies
|
|
33
33
|
run: npm ci
|
|
34
34
|
- name: Release
|
|
35
|
-
run: npm run
|
|
35
|
+
run: npm run lint && npm run build && npm run build-test && npm run test
|
|
36
36
|
|
|
37
37
|
publish:
|
|
38
38
|
needs: build
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
join,
|
|
3
|
+
dirname
|
|
4
|
+
} from 'path'
|
|
5
|
+
import { readFileSync } from 'fs'
|
|
6
|
+
import { fileURLToPath } from 'url'
|
|
7
|
+
|
|
8
|
+
// We cannot use directly the import.meta.dirname or filename because all IDE usage do not produce them
|
|
9
|
+
// We use
|
|
10
|
+
function getDirname() {
|
|
11
|
+
|
|
12
|
+
let __dirname
|
|
13
|
+
|
|
14
|
+
if ( import.meta.dirname ) {
|
|
15
|
+
__dirname = import.meta.dirname
|
|
16
|
+
} else if ( import.meta.filename ) {
|
|
17
|
+
__dirname = dirname( import.meta.filename )
|
|
18
|
+
} else if ( import.meta.url ) {
|
|
19
|
+
const __filename = fileURLToPath( import.meta.url )
|
|
20
|
+
__dirname = dirname( __filename )
|
|
21
|
+
} else {
|
|
22
|
+
throw new Error( 'Unable to retrieve module dirname.' )
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Todo: distinguish between dirname and packageRootFolder to avoid misusing
|
|
26
|
+
__dirname = join( __dirname, '..' )
|
|
27
|
+
|
|
28
|
+
return __dirname
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const __dirname = getDirname()
|
|
33
|
+
const packagePath = join( __dirname, 'package.json' )
|
|
34
|
+
const packageData = readFileSync( packagePath )
|
|
35
|
+
const packageInfos = JSON.parse( packageData )
|
|
36
|
+
|
|
37
|
+
class Indenter {
|
|
38
|
+
|
|
39
|
+
_ = ''
|
|
40
|
+
__ = ''
|
|
41
|
+
___ = ''
|
|
42
|
+
____ = ''
|
|
43
|
+
_____ = ''
|
|
44
|
+
______ = ''
|
|
45
|
+
_______ = ''
|
|
46
|
+
________ = ''
|
|
47
|
+
_________ = ''
|
|
48
|
+
__________ = ''
|
|
49
|
+
|
|
50
|
+
constructor( indentationChar = '\t', maxIndentationLevel = 10 ) {
|
|
51
|
+
|
|
52
|
+
let currentProperty = '_'
|
|
53
|
+
for ( let currentIndentationLevel = 1 ; currentIndentationLevel <= maxIndentationLevel ; currentIndentationLevel++ ) {
|
|
54
|
+
this[ currentProperty ] = indentationChar.repeat( currentIndentationLevel )
|
|
55
|
+
currentProperty += '_'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export {
|
|
63
|
+
packageInfos,
|
|
64
|
+
Indenter,
|
|
65
|
+
getDirname
|
|
66
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { join } from 'path'
|
|
2
|
+
import rollupConfigurator from '../../configs/rollup.conf.js'
|
|
3
|
+
import parseArgs from 'minimist'
|
|
4
|
+
import { getDirname } from '../_utils.mjs'
|
|
5
|
+
import { packageInfos } from '../_utils.mjs'
|
|
6
|
+
import { rollup } from 'rollup'
|
|
7
|
+
import log from 'fancy-log'
|
|
8
|
+
|
|
9
|
+
function build( done ) {
|
|
10
|
+
|
|
11
|
+
const __dirname = getDirname()
|
|
12
|
+
|
|
13
|
+
const options = parseArgs( process.argv, {
|
|
14
|
+
string: [ 'n', 'i', 'f', 'e' ],
|
|
15
|
+
boolean: [ 's', 't' ],
|
|
16
|
+
default: {
|
|
17
|
+
i: join( __dirname, 'sources', `${ packageInfos.name }.js` ),
|
|
18
|
+
o: join( __dirname, 'builds' ),
|
|
19
|
+
f: [ 'esm', 'cjs', 'iife' ],
|
|
20
|
+
e: [ 'dev', 'prod' ],
|
|
21
|
+
s: true,
|
|
22
|
+
t: true
|
|
23
|
+
},
|
|
24
|
+
alias: {
|
|
25
|
+
i: 'input',
|
|
26
|
+
o: 'output',
|
|
27
|
+
f: 'formats',
|
|
28
|
+
e: 'envs',
|
|
29
|
+
s: 'sourcemap',
|
|
30
|
+
t: 'treeshake'
|
|
31
|
+
}
|
|
32
|
+
} )
|
|
33
|
+
|
|
34
|
+
const configs = rollupConfigurator( options )
|
|
35
|
+
|
|
36
|
+
nextBuild()
|
|
37
|
+
|
|
38
|
+
function nextBuild( error ) {
|
|
39
|
+
'use strict'
|
|
40
|
+
|
|
41
|
+
if ( error ) {
|
|
42
|
+
|
|
43
|
+
done( error )
|
|
44
|
+
|
|
45
|
+
} else if ( configs.length === 0 ) {
|
|
46
|
+
|
|
47
|
+
done()
|
|
48
|
+
|
|
49
|
+
} else {
|
|
50
|
+
|
|
51
|
+
const config = configs.pop()
|
|
52
|
+
log( `Building ${ config.output.file }` )
|
|
53
|
+
|
|
54
|
+
rollup( config )
|
|
55
|
+
.then( ( bundle ) => { return bundle.write( config.output ) } )
|
|
56
|
+
.then( () => { nextBuild() } )
|
|
57
|
+
.catch( nextBuild )
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { build }
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getGulpConfigForTask } from '../../configs/gulp.conf.mjs'
|
|
2
|
+
import { deleteAsync } from 'del'
|
|
3
|
+
import log from 'fancy-log'
|
|
4
|
+
import colors from 'ansi-colors'
|
|
5
|
+
|
|
6
|
+
const red = colors.red
|
|
7
|
+
|
|
8
|
+
function clean( done ) {
|
|
9
|
+
|
|
10
|
+
const filesToClean = getGulpConfigForTask( 'clean' )
|
|
11
|
+
|
|
12
|
+
for ( let fileIndex = 0, numberOfFiles = filesToClean.length ; fileIndex < numberOfFiles ; fileIndex++ ) {
|
|
13
|
+
log( red( `[${ fileIndex + 1 }/${ numberOfFiles }] Delete ${ filesToClean[ fileIndex ] }` ) )
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return deleteAsync( filesToClean )
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { clean }
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import log from 'fancy-log'
|
|
2
|
+
import jsdocConfiguration from '../../configs/jsdoc.conf.js'
|
|
3
|
+
import { getGulpConfigForTask } from '../../configs/gulp.conf.mjs'
|
|
4
|
+
import gulp from 'gulp'
|
|
5
|
+
import jsdoc from 'gulp-jsdoc3'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async function doc( done ) {
|
|
9
|
+
|
|
10
|
+
const config = jsdocConfiguration
|
|
11
|
+
const filesToDoc = getGulpConfigForTask( 'doc' )
|
|
12
|
+
|
|
13
|
+
for ( let fileIndex = 0, numberOfFiles = filesToDoc.length ; fileIndex < numberOfFiles ; fileIndex++ ) {
|
|
14
|
+
log( `[${ fileIndex + 1 }/${ numberOfFiles }] Documenting ${ filesToDoc[ fileIndex ] }` )
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// gulp
|
|
18
|
+
// .src( filesToDoc, {
|
|
19
|
+
// read: false,
|
|
20
|
+
// allowEmpty: true
|
|
21
|
+
// } )
|
|
22
|
+
// .pipe( jsdoc( config, done ) )
|
|
23
|
+
// .on( 'error', done )
|
|
24
|
+
|
|
25
|
+
await new Promise( ( ( resolve, reject ) => {
|
|
26
|
+
gulp.src( filesToDoc, {
|
|
27
|
+
read: false,
|
|
28
|
+
allowEmpty: true
|
|
29
|
+
} )
|
|
30
|
+
.pipe( jsdoc( config, resolve ) )
|
|
31
|
+
.on( 'error', reject )
|
|
32
|
+
} ) )
|
|
33
|
+
done()
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { doc }
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import childProcess from 'child_process'
|
|
2
|
+
import log from 'fancy-log'
|
|
3
|
+
import colors from 'ansi-colors'
|
|
4
|
+
import {
|
|
5
|
+
packageInfos,
|
|
6
|
+
Indenter
|
|
7
|
+
} from '../_utils.mjs'
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
red,
|
|
11
|
+
green,
|
|
12
|
+
blue,
|
|
13
|
+
cyan,
|
|
14
|
+
yellow,
|
|
15
|
+
magenta,
|
|
16
|
+
unstyle
|
|
17
|
+
} = colors
|
|
18
|
+
|
|
19
|
+
function getPrettyPackageName() {
|
|
20
|
+
|
|
21
|
+
let packageName = ''
|
|
22
|
+
|
|
23
|
+
const nameSplits = packageInfos.name.split( '-' )
|
|
24
|
+
for ( const nameSplit of nameSplits ) {
|
|
25
|
+
packageName += nameSplit.charAt( 0 ).toUpperCase() + nameSplit.slice( 1 ) + ' '
|
|
26
|
+
}
|
|
27
|
+
packageName = packageName.slice( 0, -1 )
|
|
28
|
+
|
|
29
|
+
return packageName
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getPrettyPackageVersion() {
|
|
34
|
+
|
|
35
|
+
return 'v' + packageInfos.version
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getPrettyNodeVersion() {
|
|
40
|
+
|
|
41
|
+
let nodeVersion = 'vX.x.ₓ'
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
nodeVersion = childProcess.execFileSync( 'node', [ '--version' ] )
|
|
45
|
+
.toString()
|
|
46
|
+
.replace( /(\r\n|\n|\r)/gm, '' )
|
|
47
|
+
} catch ( e ) {
|
|
48
|
+
log( red( e ) )
|
|
49
|
+
|
|
50
|
+
if ( e.message.includes( 'ENOENT' ) ) {
|
|
51
|
+
nodeVersion += yellow( ' Not seems to be accessible from the path environment.' )
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return ' node: ' + nodeVersion
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getPrettyNpmVersion() {
|
|
60
|
+
|
|
61
|
+
let npmVersion = 'X.x.ₓ'
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
npmVersion = childProcess.execFileSync( 'npm', [ '--version' ] )
|
|
65
|
+
.toString()
|
|
66
|
+
.replace( /(\r\n|\n|\r)/gm, '' )
|
|
67
|
+
} catch ( e ) {
|
|
68
|
+
log( red( e ) )
|
|
69
|
+
|
|
70
|
+
if ( e.message.includes( 'ENOENT' ) ) {
|
|
71
|
+
npmVersion += yellow( ' Not seems to be accessible from the path environment.' )
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return ' npm: v' + npmVersion
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function alignTextCenter( text, width ) {
|
|
80
|
+
|
|
81
|
+
const unstyledText = unstyle( text.repeat( 1 ) )
|
|
82
|
+
const marginLength = ( width - unstyledText.length ) / 2
|
|
83
|
+
|
|
84
|
+
let leftMargin, rightMargin
|
|
85
|
+
if ( Number.isInteger( marginLength ) ) {
|
|
86
|
+
leftMargin = marginLength
|
|
87
|
+
rightMargin = marginLength
|
|
88
|
+
} else {
|
|
89
|
+
const flooredMargin = Math.floor( marginLength )
|
|
90
|
+
leftMargin = flooredMargin
|
|
91
|
+
rightMargin = flooredMargin + 1
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return ' '.repeat( leftMargin ) + text + ' '.repeat( rightMargin )
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function alignTextLeft( text, width ) {
|
|
99
|
+
|
|
100
|
+
const unstyledText = unstyle( text.repeat( 1 ) )
|
|
101
|
+
let repeatTime = width - unstyledText.length
|
|
102
|
+
repeatTime = ( repeatTime > 0 ) ? repeatTime : 0
|
|
103
|
+
|
|
104
|
+
return text + ' '.repeat( repeatTime )
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function alignTextRight( text, width ) {
|
|
109
|
+
|
|
110
|
+
const unstyledText = unstyle( text.repeat( 1 ) )
|
|
111
|
+
let repeatTime = width - unstyledText.length
|
|
112
|
+
repeatTime = ( repeatTime > 0 ) ? repeatTime : 0
|
|
113
|
+
|
|
114
|
+
return ' '.repeat( repeatTime ) + text
|
|
115
|
+
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function help( done ) {
|
|
119
|
+
|
|
120
|
+
const bannerWidth = 70
|
|
121
|
+
const prettyPackageName = getPrettyPackageName()
|
|
122
|
+
const prettyPackageVersion = getPrettyPackageVersion()
|
|
123
|
+
const prettyNodeVersion = getPrettyNodeVersion()
|
|
124
|
+
const prettyNpmVersion = getPrettyNpmVersion()
|
|
125
|
+
|
|
126
|
+
const tableCharset = {
|
|
127
|
+
topLeftCorner: '┏',
|
|
128
|
+
topRightCorner: '┓',
|
|
129
|
+
bottomRightCorner: '┛',
|
|
130
|
+
bottomLeftCorner: '┗',
|
|
131
|
+
horizontalBorder: '━',
|
|
132
|
+
horizontalSeparator: '─',
|
|
133
|
+
leftJoinSeparator: '┠',
|
|
134
|
+
rightJoinSeparator: '┨',
|
|
135
|
+
verticalBorder: '┃',
|
|
136
|
+
verticalSeparator: '',
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const mainBorder = tableCharset.horizontalBorder.repeat( bannerWidth )
|
|
140
|
+
const thinBorder = tableCharset.horizontalSeparator.repeat( bannerWidth )
|
|
141
|
+
const tableTop = `${ tableCharset.topLeftCorner }${ mainBorder }${ tableCharset.topRightCorner }`
|
|
142
|
+
const tableSeparator = `${ tableCharset.leftJoinSeparator }${ thinBorder }${ tableCharset.rightJoinSeparator }`
|
|
143
|
+
const tableBottom = `${ tableCharset.bottomLeftCorner }${ mainBorder }${ tableCharset.bottomRightCorner }`
|
|
144
|
+
const tableLine = ( innerText ) => `${ tableCharset.verticalBorder }${ innerText }${ tableCharset.verticalBorder }`
|
|
145
|
+
|
|
146
|
+
const I = new Indenter( ' ', 5 )
|
|
147
|
+
const npmRun = blue( 'npm run' )
|
|
148
|
+
|
|
149
|
+
log( '' )
|
|
150
|
+
log( tableTop )
|
|
151
|
+
log( tableLine( alignTextCenter( 'HELP', bannerWidth ) ) )
|
|
152
|
+
log( tableLine( alignTextCenter( prettyPackageName, bannerWidth ) ) )
|
|
153
|
+
log( tableLine( alignTextCenter( prettyPackageVersion, bannerWidth ) ) )
|
|
154
|
+
log( tableSeparator )
|
|
155
|
+
log( tableLine( alignTextLeft( prettyNodeVersion, bannerWidth ) ) )
|
|
156
|
+
log( tableLine( alignTextLeft( prettyNpmVersion, bannerWidth ) ) )
|
|
157
|
+
log( tableBottom )
|
|
158
|
+
log( I._, 'Available commands are:' )
|
|
159
|
+
log( I.__, npmRun, cyan( 'help' ), '- Display this help.' )
|
|
160
|
+
log( I.__, npmRun, cyan( 'patch' ), '- Will apply some patch/replacements in dependencies.', red( '(Apply only once after run "npm install")' ) )
|
|
161
|
+
log( I.__, npmRun, cyan( 'clean' ), '- Will delete builds and temporary folders.' )
|
|
162
|
+
log( I.__, npmRun, cyan( 'lint' ), '- Will run the eslint in pedantic mode with auto fix when possible.' )
|
|
163
|
+
log( I.__, npmRun, cyan( 'doc' ), '- Will run jsdoc, and create documentation under `documentation` folder, using the docdash theme' )
|
|
164
|
+
log( I.__, npmRun, cyan( 'test' ), '- Will run the test framworks (unit and bench), and create reports under `documentation/report` folder, using the mochawesome theme' )
|
|
165
|
+
log( I.__, npmRun, cyan( 'unit' ), '- Will run the karma server for unit tests.' )
|
|
166
|
+
log( I.__, npmRun, cyan( 'bench' ), '- Will run the karma server for benchmarks.' )
|
|
167
|
+
log( I.__, npmRun, cyan( 'build' ), yellow( '--' ), green( '<options>' ), '- Will build the application for development and/or production environments.' )
|
|
168
|
+
log( I.___, yellow( 'Note: The two dash are only required if you provide options !' ) )
|
|
169
|
+
log( I.___, 'The available', green( '<options>' ), 'are:' )
|
|
170
|
+
log( I.____, green( '-i' ), 'or', green( '--input' ), '- The main file path to build', cyan( '[Default: "sources/main.js"]' ), '.' )
|
|
171
|
+
log( I.____, green( '-o' ), 'or', green( '--output' ), '- The folder where output the build', cyan( '[Default: "builds"]' ), '.' )
|
|
172
|
+
log(
|
|
173
|
+
I.____,
|
|
174
|
+
green( '-f:' ),
|
|
175
|
+
magenta( '<format>' ),
|
|
176
|
+
'or',
|
|
177
|
+
green( '--format:' ),
|
|
178
|
+
magenta( '<format>' ),
|
|
179
|
+
' - to specify the output build type. Where format could be any of:', magenta( 'cjs, esm, iife, umd' ), '.'
|
|
180
|
+
)
|
|
181
|
+
log( I.____, green( '-e:' ), magenta( '<env>' ), 'or', green( '--env:' ), magenta( '<env>' ), ' - to specify the build environment. Where env could be any of:', magenta(
|
|
182
|
+
'dev' ), magenta( 'prod' ), cyan( '[Default: "dev"]' ), '.' )
|
|
183
|
+
log( I.____, green( '-s' ), 'or', green( '--sourcemap' ), ' - to build with related source map', cyan( '[Default: true]' ), '.' )
|
|
184
|
+
log( I.____, green( '-t' ), 'or', green( '--treeshake' ), ' - allow to perform treeshaking when building', cyan( '[Default: true]' ), '.' )
|
|
185
|
+
log( I.__, npmRun, cyan( 'release' ), '- Will run all the lint, test stuff, and if succeed will build the application.' )
|
|
186
|
+
log( '' )
|
|
187
|
+
log( I._, 'In case you have', blue( 'gulp' ), 'installed globally, you could use also:' )
|
|
188
|
+
log( I.__, blue( 'gulp' ), cyan( 'command' ), '- It will perform the command like using "npm run" but with less characters to type... Because you\'re a developer, right ?' )
|
|
189
|
+
log( '' )
|
|
190
|
+
|
|
191
|
+
done()
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export { help }
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { getGulpConfigForTask } from '../../configs/gulp.conf.mjs'
|
|
2
|
+
import gulp from 'gulp'
|
|
3
|
+
import eslint from 'gulp-eslint'
|
|
4
|
+
import log from 'fancy-log'
|
|
5
|
+
|
|
6
|
+
function lint( done ) {
|
|
7
|
+
|
|
8
|
+
const filesToLint = getGulpConfigForTask( 'lint' )
|
|
9
|
+
|
|
10
|
+
for ( let fileIndex = 0, numberOfFiles = filesToLint.length ; fileIndex < numberOfFiles ; fileIndex++ ) {
|
|
11
|
+
log( `[${ fileIndex + 1 }/${ numberOfFiles }] Lint ${ filesToLint[ fileIndex ] }` )
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return gulp.src( filesToLint, { base: './' } )
|
|
15
|
+
.pipe( eslint( {
|
|
16
|
+
allowInlineConfig: true,
|
|
17
|
+
globals: [],
|
|
18
|
+
fix: true,
|
|
19
|
+
quiet: false,
|
|
20
|
+
envs: [],
|
|
21
|
+
configFile: './configs/eslint.conf.js',
|
|
22
|
+
parserOptions: {},
|
|
23
|
+
plugins: [],
|
|
24
|
+
rules: {},
|
|
25
|
+
useEslintrc: false
|
|
26
|
+
} ) )
|
|
27
|
+
.pipe( eslint.format( 'stylish' ) )
|
|
28
|
+
.pipe( gulp.dest( '.' ) )
|
|
29
|
+
.pipe( eslint.failAfterError() )
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { lint }
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import rollupBenchesConfigurator from '../../../configs/rollup.benchs.conf.js'
|
|
2
|
+
import log from 'fancy-log'
|
|
3
|
+
import { rollup } from 'rollup'
|
|
4
|
+
import colors from 'ansi-colors'
|
|
5
|
+
|
|
6
|
+
const red = colors.red
|
|
7
|
+
|
|
8
|
+
async function bundleBenchmarks( done ) {
|
|
9
|
+
|
|
10
|
+
const configs = rollupBenchesConfigurator()
|
|
11
|
+
|
|
12
|
+
for ( let config of configs ) {
|
|
13
|
+
|
|
14
|
+
log( `Building ${ config.output.file }` )
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
|
|
18
|
+
const bundle = await rollup( config )
|
|
19
|
+
await bundle.write( config.output )
|
|
20
|
+
|
|
21
|
+
} catch ( error ) {
|
|
22
|
+
|
|
23
|
+
log( red( error ) )
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
done()
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { bundleBenchmarks }
|
|
@@ -0,0 +1,215 @@
|
|
|
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 computeBenchmarks( done ) {
|
|
31
|
+
|
|
32
|
+
const baseDir = getDirname()
|
|
33
|
+
const sourcesDir = join( baseDir, 'sources' )
|
|
34
|
+
const testsDir = join( baseDir, 'tests' )
|
|
35
|
+
const benchesDir = join( testsDir, 'benchmarks' )
|
|
36
|
+
|
|
37
|
+
fs.mkdirSync( benchesDir, { recursive: true } )
|
|
38
|
+
|
|
39
|
+
const filePathsToIgnore = getGulpConfigForTask( 'compute-benchmarks' )
|
|
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 benchRootImports = []
|
|
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 benchFileName = `${ fileName }.bench.js`
|
|
59
|
+
const benchDirPath = join( benchesDir, specificDir )
|
|
60
|
+
const benchFilePath = join( benchDirPath, benchFileName )
|
|
61
|
+
|
|
62
|
+
const nsName = `${ fileName }Namespace`
|
|
63
|
+
const importDirPath = relative( benchDirPath, sourcesDir )
|
|
64
|
+
const importFilePath = join( importDirPath, specificFilePath ).replace( /\\/g, '/' )
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
|
|
68
|
+
const jsdocPath = join( baseDir, '/node_modules/jsdoc/jsdoc.js' )
|
|
69
|
+
const jsdocOutput = childProcess.execFileSync( 'node', [ jsdocPath, '-X', sourceFile ] ).toString()
|
|
70
|
+
|
|
71
|
+
const classNames = []
|
|
72
|
+
const usedLongnames = []
|
|
73
|
+
const jsonData = JSON.parse( jsdocOutput ).filter( data => {
|
|
74
|
+
|
|
75
|
+
const longName = data.longname
|
|
76
|
+
|
|
77
|
+
const kind = data.kind
|
|
78
|
+
if ( kind !== 'function' ) {
|
|
79
|
+
if ( kind === 'class' && !classNames.includes( longName ) ) {
|
|
80
|
+
classNames.push( longName )
|
|
81
|
+
}
|
|
82
|
+
return false
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// We don't care that data bloc have comment they are unused to generate benchmarks
|
|
86
|
+
// const undocumented = data.undocumented
|
|
87
|
+
// if ( undocumented ) {
|
|
88
|
+
// return false
|
|
89
|
+
// }
|
|
90
|
+
|
|
91
|
+
const scope = data.scope
|
|
92
|
+
if ( ![ 'global', 'static' ].includes( scope ) ) {
|
|
93
|
+
return false
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if ( longName.includes( ' ' ) || longName.includes( '~' ) || usedLongnames.includes( longName ) ) {
|
|
97
|
+
return false
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
for ( let className of classNames ) {
|
|
101
|
+
if ( longName.includes( className ) ) {
|
|
102
|
+
return false
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
usedLongnames.push( longName )
|
|
107
|
+
|
|
108
|
+
return true
|
|
109
|
+
|
|
110
|
+
} )
|
|
111
|
+
|
|
112
|
+
if ( jsonData.length === 0 ) {
|
|
113
|
+
log( yellow( `No usable exports found in [${ sourceFile }]. Ignore it !` ) )
|
|
114
|
+
continue
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Compute benchmark suites by grouping logically function by name[_x]
|
|
118
|
+
const suiteGroups = {}
|
|
119
|
+
for ( let docData of jsonData ) {
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
|
|
123
|
+
const functionName = docData.name
|
|
124
|
+
const nameSplits = functionName.split( '_' )
|
|
125
|
+
const rootName = nameSplits[ 0 ]
|
|
126
|
+
|
|
127
|
+
if ( !( rootName in suiteGroups ) ) {
|
|
128
|
+
suiteGroups[ rootName ] = []
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
suiteGroups[ rootName ].push( functionName )
|
|
132
|
+
|
|
133
|
+
} catch ( error ) {
|
|
134
|
+
|
|
135
|
+
log( red( error.message ) )
|
|
136
|
+
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Generate suites
|
|
142
|
+
let benchSuites = ''
|
|
143
|
+
const suitesToExports = []
|
|
144
|
+
for ( let suiteGroupName in suiteGroups ) {
|
|
145
|
+
suitesToExports.push( `${ suiteGroupName }Suite` )
|
|
146
|
+
benchSuites += `const ${ suiteGroupName }Suite = Benchmark.Suite( '${ nsName }.${ suiteGroupName }', Testing.createSuiteOptions() )` + '\n'
|
|
147
|
+
|
|
148
|
+
for ( let suiteGroupValue of suiteGroups[ suiteGroupName ] ) {
|
|
149
|
+
benchSuites += ` .add( '${ suiteGroupValue }()', Testing.iterateOverDataMap( ${ nsName }.${ suiteGroupValue } ), Testing.createBenchmarkOptions() )` + '\n'
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
benchSuites += '\n'
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const template = '' + '\n' +
|
|
156
|
+
`import Benchmark from 'benchmark'` + '\n' +
|
|
157
|
+
`import { Testing } from 'itee-utils'` + '\n' +
|
|
158
|
+
`import * as ${ nsName } from '${ importFilePath }'` + '\n' +
|
|
159
|
+
'\n' +
|
|
160
|
+
`${ benchSuites }` +
|
|
161
|
+
// '\n' +
|
|
162
|
+
`export { ${ suitesToExports } }` + '\n' +
|
|
163
|
+
'\n'
|
|
164
|
+
|
|
165
|
+
const importBenchFilePath = relative( benchesDir, benchFilePath ).replace( /\\/g, '/' )
|
|
166
|
+
benchRootImports.push( {
|
|
167
|
+
path: importBenchFilePath,
|
|
168
|
+
exports: suitesToExports
|
|
169
|
+
} )
|
|
170
|
+
|
|
171
|
+
log( green( `Create ${ benchFilePath }` ) )
|
|
172
|
+
fs.mkdirSync( benchDirPath, { recursive: true } )
|
|
173
|
+
fs.writeFileSync( benchFilePath, template )
|
|
174
|
+
|
|
175
|
+
} catch ( error ) {
|
|
176
|
+
|
|
177
|
+
log( red( error.message ) )
|
|
178
|
+
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
let templateImports = ''
|
|
184
|
+
let suites = []
|
|
185
|
+
for ( let i = 0 ; i < benchRootImports.length ; i++ ) {
|
|
186
|
+
|
|
187
|
+
const currentBench = benchRootImports[ i ]
|
|
188
|
+
const exports = currentBench.exports
|
|
189
|
+
const imports = exports.join( ', ' )
|
|
190
|
+
suites.push( ...exports )
|
|
191
|
+
|
|
192
|
+
templateImports += `import {${ imports }} from './${ currentBench.path }'` + '\n'
|
|
193
|
+
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const benchesTemplate = '' +
|
|
197
|
+
`${ templateImports }` + '\n' +
|
|
198
|
+
'const suites = [' + '\n' +
|
|
199
|
+
`${ suites.map( suite => `\t${ suite }` ).join( ',\n' ) }` + '\n' +
|
|
200
|
+
']' + '\n' +
|
|
201
|
+
'\n' +
|
|
202
|
+
`for ( const suite of suites ) {` + '\n' +
|
|
203
|
+
`\tsuite.run()` + '\n' +
|
|
204
|
+
`}` + '\n'
|
|
205
|
+
|
|
206
|
+
const benchesFilePath = join( benchesDir, `${ packageInfos.name }.benchs.js` )
|
|
207
|
+
|
|
208
|
+
log( green( `Create ${ benchesFilePath }` ) )
|
|
209
|
+
fs.writeFileSync( benchesFilePath, benchesTemplate )
|
|
210
|
+
|
|
211
|
+
done()
|
|
212
|
+
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export { computeBenchmarks }
|