itee-tasks 1.0.3

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.
Files changed (48) hide show
  1. package/.czrc +6 -0
  2. package/.github/workflows/node.js.yml +56 -0
  3. package/.releaserc.mjs +94 -0
  4. package/CHANGELOG.md +25 -0
  5. package/README.md +1 -0
  6. package/configs/builds/build.conf.mjs +1 -0
  7. package/configs/cleans/clean.conf.mjs +1 -0
  8. package/configs/docs/doc.conf.json +1 -0
  9. package/configs/lints/lint.conf.mjs +91 -0
  10. package/configs/refresh.conf.mjs +1 -0
  11. package/configs/tests/benchmarks/compute-benchmarks.conf.mjs +25 -0
  12. package/configs/tests/benchmarks/run-benchmarks-for-frontend.conf.mjs +41 -0
  13. package/configs/tests/benchmarks/run-benchmarks.conf.mjs +7 -0
  14. package/configs/tests/bundlings/check-bundling-from-esm-build-import.conf.mjs +45 -0
  15. package/configs/tests/bundlings/check-bundling-from-esm-files-direct.conf.mjs +45 -0
  16. package/configs/tests/bundlings/check-bundling-from-esm-files-import.conf.mjs +42 -0
  17. package/configs/tests/bundlings/check-bundling.conf.mjs +25 -0
  18. package/configs/tests/units/compute-unit-tests.conf.mjs +25 -0
  19. package/configs/tests/units/run-unit-tests-for-frontend.conf.mjs +15 -0
  20. package/configs/tests/units/run-unit-tests.conf.mjs +7 -0
  21. package/gulpfile.mjs +28 -0
  22. package/package.json +91 -0
  23. package/sources/_utils.mjs +389 -0
  24. package/sources/builds/build.task.mjs +55 -0
  25. package/sources/cleans/clean.task.mjs +36 -0
  26. package/sources/docs/doc.task.mjs +49 -0
  27. package/sources/helps/help.task.mjs +154 -0
  28. package/sources/index.mjs +21 -0
  29. package/sources/lints/lint.task.mjs +47 -0
  30. package/sources/refresh.mjs +100 -0
  31. package/sources/releases/release.task.mjs +31 -0
  32. package/sources/tests/benchmarks/compute-benchmarks.task.mjs +224 -0
  33. package/sources/tests/benchmarks/run-benchmarks-for-backend.task.mjs +42 -0
  34. package/sources/tests/benchmarks/run-benchmarks-for-frontend.task.mjs +52 -0
  35. package/sources/tests/benchmarks/run-benchmarks.task.mjs +21 -0
  36. package/sources/tests/bundlings/check-bundling-from-esm-build-import.task.mjs +131 -0
  37. package/sources/tests/bundlings/check-bundling-from-esm-files-direct.task.mjs +88 -0
  38. package/sources/tests/bundlings/check-bundling-from-esm-files-import.task.mjs +106 -0
  39. package/sources/tests/bundlings/check-bundling.task.mjs +23 -0
  40. package/sources/tests/run-tests.task.mjs +21 -0
  41. package/sources/tests/units/compute-unit-tests.task.mjs +535 -0
  42. package/sources/tests/units/run-unit-tests-for-backend.task.mjs +47 -0
  43. package/sources/tests/units/run-unit-tests-for-frontend.task.mjs +52 -0
  44. package/sources/tests/units/run-unit-tests.task.mjs +21 -0
  45. package/tests/benchmarks/default/default.bench.js +1 -0
  46. package/tests/benchmarks/itee-tasks.benchmarks.js +8 -0
  47. package/tests/units/default/default.unit.mjs +1 -0
  48. package/tests/units/itee-tasks.units.mjs +1 -0
@@ -0,0 +1,154 @@
1
+ import colors from 'ansi-colors'
2
+ import log from 'fancy-log'
3
+ import {
4
+ getPrettyNodeVersion,
5
+ getPrettyNpmVersion,
6
+ getPrettyPackageName,
7
+ getPrettyPackageVersion,
8
+ Indenter,
9
+ logLoadingTask
10
+ } from '../_utils.mjs'
11
+
12
+ const {
13
+ red,
14
+ green,
15
+ blue,
16
+ cyan,
17
+ yellow,
18
+ magenta,
19
+ unstyle
20
+ } = colors
21
+
22
+ function alignTextCenter( text, width ) {
23
+
24
+ const unstyledText = unstyle( text.repeat( 1 ) )
25
+ const marginLength = ( width - unstyledText.length ) / 2
26
+
27
+ let leftMargin, rightMargin
28
+ if ( Number.isInteger( marginLength ) ) {
29
+ leftMargin = marginLength
30
+ rightMargin = marginLength
31
+ } else {
32
+ const flooredMargin = Math.floor( marginLength )
33
+ leftMargin = flooredMargin
34
+ rightMargin = flooredMargin + 1
35
+ }
36
+
37
+ return ' '.repeat( leftMargin ) + text + ' '.repeat( rightMargin )
38
+
39
+ }
40
+
41
+ function alignTextLeft( text, width ) {
42
+
43
+ const unstyledText = unstyle( text.repeat( 1 ) )
44
+ let repeatTime = width - unstyledText.length
45
+ repeatTime = ( repeatTime > 0 ) ? repeatTime : 0
46
+
47
+ return text + ' '.repeat( repeatTime )
48
+
49
+ }
50
+
51
+ function alignTextRight( text, width ) {
52
+
53
+ const unstyledText = unstyle( text.repeat( 1 ) )
54
+ let repeatTime = width - unstyledText.length
55
+ repeatTime = ( repeatTime > 0 ) ? repeatTime : 0
56
+
57
+ return ' '.repeat( repeatTime ) + text
58
+
59
+ }
60
+
61
+ /**
62
+ * @method npm run help ( default )
63
+ * @global
64
+ * @description Will display the help in console
65
+ */
66
+ const helpTask = ( done ) => {
67
+
68
+ const bannerWidth = 70
69
+ const prettyPackageName = getPrettyPackageName()
70
+ const prettyPackageVersion = getPrettyPackageVersion()
71
+ const prettyNodeVersion = getPrettyNodeVersion()
72
+ const prettyNpmVersion = getPrettyNpmVersion()
73
+
74
+ const tableCharset = {
75
+ topLeftCorner: '┏',
76
+ topRightCorner: '┓',
77
+ bottomRightCorner: '┛',
78
+ bottomLeftCorner: '┗',
79
+ horizontalBorder: '━',
80
+ horizontalSeparator: '─',
81
+ leftJoinSeparator: '┠',
82
+ rightJoinSeparator: '┨',
83
+ verticalBorder: '┃',
84
+ verticalSeparator: '',
85
+ }
86
+
87
+ const mainBorder = tableCharset.horizontalBorder.repeat( bannerWidth )
88
+ const thinBorder = tableCharset.horizontalSeparator.repeat( bannerWidth )
89
+ const tableTop = `${ tableCharset.topLeftCorner }${ mainBorder }${ tableCharset.topRightCorner }`
90
+ const tableSeparator = `${ tableCharset.leftJoinSeparator }${ thinBorder }${ tableCharset.rightJoinSeparator }`
91
+ const tableBottom = `${ tableCharset.bottomLeftCorner }${ mainBorder }${ tableCharset.bottomRightCorner }`
92
+ const tableLine = ( innerText ) => `${ tableCharset.verticalBorder }${ innerText }${ tableCharset.verticalBorder }`
93
+
94
+ const {
95
+ I_,
96
+ I__,
97
+ I___,
98
+ I____,
99
+ } = new Indenter( '\t', 4 )
100
+
101
+ const npmRun = blue( 'npm run' )
102
+
103
+ log( '' )
104
+ log( tableTop )
105
+ log( tableLine( alignTextCenter( 'HELP', bannerWidth ) ) )
106
+ log( tableLine( alignTextCenter( prettyPackageName, bannerWidth ) ) )
107
+ log( tableLine( alignTextCenter( prettyPackageVersion, bannerWidth ) ) )
108
+ log( tableSeparator )
109
+ log( tableLine( alignTextLeft( prettyNodeVersion, bannerWidth ) ) )
110
+ log( tableLine( alignTextLeft( prettyNpmVersion, bannerWidth ) ) )
111
+ log( tableBottom )
112
+ log( I_, 'Available commands are:' )
113
+ log( I__, npmRun, cyan( 'help' ), '- Display this help.' )
114
+ log( I__, npmRun, cyan( 'patch' ), '- Will apply some patch/replacements in dependencies.', red( '(Apply only once after run "npm install")' ) )
115
+ log( I__, npmRun, cyan( 'clean' ), '- Will delete builds and temporary folders.' )
116
+ log( I__, npmRun, cyan( 'lint' ), '- Will run the eslint in pedantic mode with auto fix when possible.' )
117
+ log( I__, npmRun, cyan( 'doc' ), '- Will run jsdoc, and create documentation under `documentation` folder, using the docdash theme' )
118
+ log( I__, npmRun, cyan( 'test' ), '- Will run the test framworks (unit and bench), and create reports under `documentation/report` folder, using the mochawesome theme' )
119
+ log( I__, npmRun, cyan( 'unit' ), '- Will run the karma server for unit tests.' )
120
+ log( I__, npmRun, cyan( 'bench' ), '- Will run the karma server for benchmarks.' )
121
+ log( I__, npmRun, cyan( 'build' ), yellow( '--' ), green( '<options>' ), '- Will build the application for development and/or production environments.' )
122
+ log( I___, yellow( 'Note: The two dash are only required if you provide options !' ) )
123
+ log( I___, 'The available', green( '<options>' ), 'are:' )
124
+ log( I____, green( '-i' ), 'or', green( '--input' ), '- The main file path to build', cyan( '[Default: "sources/main.js"]' ), '.' )
125
+ log( I____, green( '-o' ), 'or', green( '--output' ), '- The folder where output the build', cyan( '[Default: "builds"]' ), '.' )
126
+ log(
127
+ I____,
128
+ green( '-f:' ),
129
+ magenta( '<format>' ),
130
+ 'or',
131
+ green( '--format:' ),
132
+ magenta( '<format>' ),
133
+ ' - to specify the output build type. Where format could be any of:', magenta( 'cjs, esm, iife, umd' ), '.'
134
+ )
135
+ log( I____, green( '-e:' ), magenta( '<env>' ), 'or', green( '--env:' ), magenta( '<env>' ), ' - to specify the build environment. Where env could be any of:', magenta(
136
+ 'dev' ), magenta( 'prod' ), cyan( '[Default: "dev"]' ), '.' )
137
+ log( I____, green( '-s' ), 'or', green( '--sourcemap' ), ' - to build with related source map', cyan( '[Default: true]' ), '.' )
138
+ log( I____, green( '-t' ), 'or', green( '--treeshake' ), ' - allow to perform treeshaking when building', cyan( '[Default: true]' ), '.' )
139
+ log( I__, npmRun, cyan( 'release' ), '- Will run all the lint, test stuff, and if succeed will build the application.' )
140
+ log( '' )
141
+ log( I_, 'In case you have', blue( 'gulp' ), 'installed globally, you could use also:' )
142
+ 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 ?' )
143
+ log( '' )
144
+
145
+ done()
146
+
147
+ }
148
+ helpTask.displayName = 'help'
149
+ helpTask.description = 'Display the package help'
150
+ helpTask.flags = null
151
+
152
+ logLoadingTask( import.meta.filename, helpTask )
153
+
154
+ export { helpTask }
@@ -0,0 +1,21 @@
1
+ export { buildTask } from './builds/build.task.mjs'
2
+ export { cleanTask } from './cleans/clean.task.mjs'
3
+ export { docTask } from './docs/doc.task.mjs'
4
+ export { helpTask } from './helps/help.task.mjs'
5
+ export { lintTask } from './lints/lint.task.mjs'
6
+ export { releaseTask } from './releases/release.task.mjs'
7
+ export { runTestsTask } from './tests/run-tests.task.mjs'
8
+ export { computeUnitTestsTask } from './tests/units/compute-unit-tests.task.mjs'
9
+ export { runUnitTestsTask } from './tests/units/run-unit-tests.task.mjs'
10
+ export { runUnitTestsForBackendTask } from './tests/units/run-unit-tests-for-backend.task.mjs'
11
+ export { runUnitTestsForFrontendTask } from './tests/units/run-unit-tests-for-frontend.task.mjs'
12
+ export { checkBundlingFromEsmBuildImportTask } from './tests/bundlings/check-bundling-from-esm-build-import.task.mjs'
13
+ export { checkBundlingFromEsmFilesDirectTask } from './tests/bundlings/check-bundling-from-esm-files-direct.task.mjs'
14
+ export { checkBundlingFromEsmFilesImportTask } from './tests/bundlings/check-bundling-from-esm-files-import.task.mjs'
15
+ export { checkBundlingTask } from './tests/bundlings/check-bundling.task.mjs'
16
+ export { computeBenchmarksTask } from './tests/benchmarks/compute-benchmarks.task.mjs'
17
+ export { runBenchmarksTestsTask } from './tests/benchmarks/run-benchmarks.task.mjs'
18
+ export { runBenchmarksForBackendTask } from './tests/benchmarks/run-benchmarks-for-backend.task.mjs'
19
+ export { runBenchmarksForFrontendTask } from './tests/benchmarks/run-benchmarks-for-frontend.task.mjs'
20
+
21
+ export * from './_utils.mjs'
@@ -0,0 +1,47 @@
1
+ import colors from 'ansi-colors'
2
+ import log from 'fancy-log'
3
+ import child_process from 'node:child_process'
4
+ import { promisify } from 'node:util'
5
+ import { join } from 'path'
6
+ import {
7
+ getConfigurationPathFor,
8
+ logLoadingTask
9
+ } from '../_utils.mjs'
10
+
11
+ const execFile = promisify( child_process.execFile )
12
+ const { red } = colors
13
+
14
+ const configurationLocation = join( 'lints', 'lint.conf.mjs' )
15
+ const configurationPath = getConfigurationPathFor( configurationLocation )
16
+
17
+ /**
18
+ * @method npm run lint
19
+ * @global
20
+ * @description Will lint the sources files and try to fix the style when possible
21
+ */
22
+ const lintTask = async ( done ) => {
23
+
24
+ try {
25
+
26
+ const { stdout } = await execFile( 'npx', [ 'eslint', '--config', configurationPath, '--fix' ] )
27
+ if ( stdout !== '' ) {
28
+ log( stdout )
29
+ }
30
+
31
+ done()
32
+
33
+ } catch ( error ) {
34
+
35
+ log( error.stdout )
36
+ done( red( error.message ) )
37
+
38
+ }
39
+
40
+ }
41
+ lintTask.displayName = 'lint'
42
+ lintTask.description = 'Will lint the sources files and try to fix the style when possible.'
43
+ lintTask.flags = null
44
+
45
+ logLoadingTask( import.meta.filename, lintTask, configurationPath )
46
+
47
+ export { lintTask }
@@ -0,0 +1,100 @@
1
+ import colors from 'ansi-colors'
2
+ import log from 'fancy-log'
3
+ import { writeFileSync } from 'fs'
4
+ import {
5
+ basename,
6
+ join,
7
+ relative
8
+ } from 'path'
9
+ import {
10
+ getConfigurationFrom,
11
+ getConfigurationPathFor,
12
+ getFilesFrom,
13
+ iteePackageRootDirectory,
14
+ iteePackageSourcesDirectory,
15
+ packageNodeModulesDirectory,
16
+ packageRootDirectory,
17
+ packageTasksDirectory
18
+ } from './_utils.mjs'
19
+
20
+ const {
21
+ green,
22
+ yellow
23
+ } = colors
24
+
25
+ const configurationPath = getConfigurationPathFor( 'refresh.conf.mjs' )
26
+ const configuration = await getConfigurationFrom( configurationPath )
27
+
28
+ // Get and filter tasks to expose
29
+ const defaultTaskPattern = join( iteePackageSourcesDirectory, '/{*.task.mjs,**/*.task.mjs,**/**/*.task.mjs}' )
30
+ const defaultTaskFiles = getFilesFrom(
31
+ defaultTaskPattern,
32
+ filePath => {
33
+ const relativeFilepath = relative( iteePackageSourcesDirectory, filePath )
34
+ const filename = basename( filePath )
35
+ const included = !configuration.includes( filename )
36
+
37
+ included
38
+ ? log( 'Include default task from', green( relativeFilepath ) )
39
+ : log( 'Exclude default task from', yellow( relativeFilepath ) )
40
+
41
+ return included
42
+ }
43
+ )
44
+
45
+ const userTaskPattern = join( packageTasksDirectory, '/{*.task.mjs,**/*.task.mjs,**/**/*.task.mjs}' )
46
+ const userTaskFiles = getFilesFrom(
47
+ userTaskPattern,
48
+ filePath => {
49
+ const relativeFilepath = relative( packageRootDirectory, filePath )
50
+ const filename = basename( filePath )
51
+ const included = !configuration.includes( filename )
52
+
53
+ included
54
+ ? log( 'Include user task from', green( relativeFilepath ) )
55
+ : log( 'Exclude user task from', yellow( relativeFilepath ) )
56
+
57
+ return included
58
+ }
59
+ )
60
+
61
+ // Prepare gulpfile content with header
62
+ let gulpfileContent = '' +
63
+ '/**\n' +
64
+ ' * This file is auto-generated by internal gulp command.\n' +
65
+ ' * If you want to customize the available gulp tasks, create your own in .tasks folder\n' +
66
+ ' * and run "gulp refresh"\n' +
67
+ ' */\n\n'
68
+
69
+ // Generate default tasks exports and append to gulpfile content
70
+ gulpfileContent += '// Default Itee tasks\n'
71
+ for ( const taskFile of defaultTaskFiles ) {
72
+
73
+ // we are calling from client and use relative path from it
74
+ if ( iteePackageRootDirectory.includes( 'node_modules' ) ) {
75
+
76
+ const relativeTaskFile = relative( packageNodeModulesDirectory, taskFile )
77
+ gulpfileContent += `export * from '${ relativeTaskFile }'\n`
78
+
79
+ } else { // we are refreshing itee-tasks package internally
80
+
81
+ const relativeTaskFile = relative( iteePackageRootDirectory, taskFile )
82
+ gulpfileContent += `export * from './${ relativeTaskFile }'\n`
83
+
84
+ }
85
+
86
+ }
87
+
88
+ gulpfileContent += '\n'
89
+
90
+ // Generate user tasks exports and append to gulpfile content
91
+ gulpfileContent += '// User defined tasks\n'
92
+ for ( const taskFile of userTaskFiles ) {
93
+ const relativeTaskFile = relative( packageRootDirectory, taskFile )
94
+ gulpfileContent += `export * from './${ relativeTaskFile }'\n`
95
+ }
96
+
97
+ // Create gulpfile file
98
+ const gulpfilePath = join( packageRootDirectory, 'gulpfile.mjs' )
99
+ log( 'Refresh', green( gulpfilePath ) )
100
+ writeFileSync( gulpfilePath, gulpfileContent )
@@ -0,0 +1,31 @@
1
+ import { series } from 'gulp'
2
+ import { logLoadingTask } from '../_utils.mjs'
3
+ import { buildTask } from '../builds/build.task.mjs'
4
+ import { cleanTask } from '../cleans/clean.task.mjs'
5
+ import { docTask } from '../docs/doc.task.mjs'
6
+ import { lintTask } from '../lints/lint.task.mjs'
7
+ import { computeBenchmarksTask } from '../tests/benchmarks/compute-benchmarks.task.mjs'
8
+ import { runTestsTask } from '../tests/run-tests.task.mjs'
9
+ import { computeUnitTestsTask } from '../tests/units/compute-unit-tests.task.mjs'
10
+
11
+ /**
12
+ * @method npm run release
13
+ * @global
14
+ * @description Will perform a complete release of the library including 'clean', 'lint', 'doc', 'build-tests', 'test' and finally 'build'.
15
+ */
16
+ const releaseTask = series(
17
+ cleanTask,
18
+ buildTask,
19
+ computeBenchmarksTask,
20
+ computeUnitTestsTask,
21
+ runTestsTask,
22
+ lintTask,
23
+ docTask,
24
+ )
25
+ releaseTask.displayName = 'release'
26
+ releaseTask.description = 'Will perform a complete release of the library including \'clean\', \'lint\', \'doc\', \'test\' and finally \'build\'.'
27
+ releaseTask.flags = null
28
+
29
+ logLoadingTask( import.meta.filename, releaseTask )
30
+
31
+ export { releaseTask }
@@ -0,0 +1,224 @@
1
+ import colors from 'ansi-colors'
2
+ import childProcess from 'child_process'
3
+ import log from 'fancy-log'
4
+ import {
5
+ basename,
6
+ dirname,
7
+ extname,
8
+ join,
9
+ relative
10
+ } from 'path'
11
+ import {
12
+ createDirectoryIfNotExist,
13
+ createFile,
14
+ getConfigurationFrom,
15
+ getConfigurationPathFor,
16
+ logLoadingTask,
17
+ packageName,
18
+ packageNodeModulesDirectory,
19
+ packageSourcesDirectory as sourcesDir,
20
+ packageTestsBenchmarksDirectory as benchesDir,
21
+ packageTestsDirectory
22
+ } from '../../_utils.mjs'
23
+
24
+ const {
25
+ red,
26
+ yellow,
27
+ } = colors
28
+
29
+ const configurationLocation = join( 'tests', 'benchmarks', 'compute-benchmarks.conf.mjs' )
30
+ const configurationPath = getConfigurationPathFor( configurationLocation )
31
+ const configuration = await getConfigurationFrom( configurationPath )
32
+
33
+ /**
34
+ * @description Will generate benchmarks files from source code against provided alternatives
35
+ */
36
+ const computeBenchmarksTask = ( done ) => {
37
+
38
+ createDirectoryIfNotExist( benchesDir )
39
+
40
+ const benchRootImports = []
41
+ for ( let sourceFile of configuration ) {
42
+
43
+ const specificFilePath = sourceFile.replace( sourcesDir, '' )
44
+ const specificDir = dirname( specificFilePath )
45
+
46
+ const fileName = basename( sourceFile, extname( sourceFile ) )
47
+ const benchFileName = `${ fileName }.bench.js`
48
+ const benchDirPath = join( benchesDir, specificDir )
49
+ const benchFilePath = join( benchDirPath, benchFileName )
50
+
51
+ const nsName = `${ fileName }Namespace`
52
+ const importDirPath = relative( benchDirPath, sourcesDir )
53
+ const importFilePath = join( importDirPath, specificFilePath ).replace( /\\/g, '/' )
54
+
55
+ try {
56
+
57
+ const jsdocPath = join( packageNodeModulesDirectory, '/jsdoc/jsdoc.js' )
58
+ const jsdocOutput = childProcess.execFileSync( 'node', [ jsdocPath, '-X', sourceFile ] ).toString()
59
+
60
+ const classNames = []
61
+ const usedLongnames = []
62
+ const jsonData = JSON.parse( jsdocOutput ).filter( data => {
63
+
64
+ const longName = data.longname
65
+
66
+ const kind = data.kind
67
+ if ( kind !== 'function' ) {
68
+ if ( kind === 'class' && !classNames.includes( longName ) ) {
69
+ classNames.push( longName )
70
+ }
71
+ return false
72
+ }
73
+
74
+ // We don't care that data bloc have comment they are unused to generate benchmarks
75
+ // const undocumented = data.undocumented
76
+ // if ( undocumented ) {
77
+ // return false
78
+ // }
79
+
80
+ const scope = data.scope
81
+ if ( ![ 'global', 'static' ].includes( scope ) ) {
82
+ return false
83
+ }
84
+
85
+ if ( longName.includes( ' ' ) || longName.includes( '~' ) || usedLongnames.includes( longName ) ) {
86
+ return false
87
+ }
88
+
89
+ for ( let className of classNames ) {
90
+ if ( longName.includes( className ) ) {
91
+ return false
92
+ }
93
+ }
94
+
95
+ usedLongnames.push( longName )
96
+
97
+ return true
98
+
99
+ } )
100
+
101
+ if ( jsonData.length === 0 ) {
102
+ log( 'Ignoring', yellow( `${ sourceFile }, no usable exports found` ) )
103
+ continue
104
+ }
105
+
106
+ // Compute benchmark suites by grouping logically function by name[_x]
107
+ const suiteGroups = {}
108
+ for ( let docData of jsonData ) {
109
+
110
+ try {
111
+
112
+ const functionName = docData.name
113
+ const nameSplits = functionName.split( '_' )
114
+ const rootName = nameSplits[ 0 ]
115
+
116
+ if ( !( rootName in suiteGroups ) ) {
117
+ suiteGroups[ rootName ] = []
118
+ }
119
+
120
+ suiteGroups[ rootName ].push( functionName )
121
+
122
+ } catch ( error ) {
123
+
124
+ log( red( error.message ) )
125
+
126
+ }
127
+
128
+ }
129
+
130
+ // Generate suites
131
+ let benchSuites = ''
132
+ const suitesToExports = []
133
+ for ( let suiteGroupName in suiteGroups ) {
134
+ suitesToExports.push( `${ suiteGroupName }Suite` )
135
+ benchSuites += `const ${ suiteGroupName }Suite = Benchmark.Suite( '${ nsName }.${ suiteGroupName }', Testing.createSuiteOptions() )` + '\n'
136
+
137
+ for ( let suiteGroupValue of suiteGroups[ suiteGroupName ] ) {
138
+ benchSuites += ` .add( '${ suiteGroupValue }()', Testing.iterateOverDataMap( ${ nsName }.${ suiteGroupValue } ), Testing.createBenchmarkOptions() )` + '\n'
139
+ }
140
+
141
+ benchSuites += '\n'
142
+ }
143
+
144
+ // compute relative level to get import wrappers
145
+ const wrapperDirPath = relative( benchDirPath, packageTestsDirectory )
146
+ const importBenchmarkFilePath = join( wrapperDirPath, 'import.benchmarks.js' )
147
+ const importTestingFilePath = join( wrapperDirPath, 'import.testing.js' )
148
+
149
+ const template = '' +
150
+ `import * as ${ nsName } from '${ importFilePath }'` + '\n' +
151
+ `import { getBenchmarkPackage } from '${ importBenchmarkFilePath }'` + '\n' +
152
+ `import { getTestingPackage } from '${ importTestingFilePath }'` + '\n' +
153
+ '\n' +
154
+ `const Benchmark = await getBenchmarkPackage()` + '\n' +
155
+ `const Testing = await getTestingPackage()` + '\n' +
156
+ '\n' +
157
+ `${ benchSuites }` +
158
+ // '\n' +
159
+ `export { ${ suitesToExports } }` + '\n' +
160
+ '\n'
161
+
162
+ const importBenchFilePath = relative( benchesDir, benchFilePath ).replace( /\\/g, '/' )
163
+ benchRootImports.push( {
164
+ path: importBenchFilePath,
165
+ exports: suitesToExports
166
+ } )
167
+
168
+ createDirectoryIfNotExist( benchDirPath )
169
+ createFile( benchFilePath, template )
170
+
171
+ } catch ( error ) {
172
+
173
+ log( red( error.message ) )
174
+
175
+ }
176
+
177
+ }
178
+
179
+ let templateImports = ''
180
+ let suites = []
181
+ for ( let i = 0 ; i < benchRootImports.length ; i++ ) {
182
+
183
+ const currentBench = benchRootImports[ i ]
184
+ const namedExports = currentBench.exports
185
+ const imports = namedExports.join( ', ' )
186
+ suites.push( ...namedExports )
187
+
188
+ templateImports += `import {${ imports }} from './${ currentBench.path }'` + '\n'
189
+
190
+ }
191
+
192
+ // Use a fallback in case no benches were found at all
193
+ if ( benchRootImports.length === 0 ) {
194
+ log( 'Warning ', yellow( 'No usable exports found, generate default file to avoid frontend breakage.' ) )
195
+ const defaultBenchesDir = join( benchesDir, 'default' )
196
+ const defaultBenchesPath = join( defaultBenchesDir, 'default.bench.js' )
197
+
198
+ createDirectoryIfNotExist( defaultBenchesDir )
199
+ createFile( defaultBenchesPath, '// Avoid web test runner crash on empty benches' )
200
+ }
201
+
202
+ const benchesTemplate = '' +
203
+ `${ templateImports }` + '\n' +
204
+ 'const suites = [' + '\n' +
205
+ `${ suites.map( suite => `\t${ suite }` ).join( ',\n' ) }` + '\n' +
206
+ ']' + '\n' +
207
+ '\n' +
208
+ `for ( const suite of suites ) {` + '\n' +
209
+ `\tsuite.run()` + '\n' +
210
+ `}` + '\n'
211
+
212
+ const benchesFilePath = join( benchesDir, `${ packageName }.benchmarks.js` )
213
+ createFile( benchesFilePath, benchesTemplate )
214
+
215
+ done()
216
+
217
+ }
218
+ computeBenchmarksTask.displayName = 'compute-benchmarks'
219
+ computeBenchmarksTask.description = 'Will generate benchmarks files from source code against provided alternatives.'
220
+ computeBenchmarksTask.flags = null
221
+
222
+ logLoadingTask( import.meta.filename, computeBenchmarksTask, configurationPath )
223
+
224
+ export { computeBenchmarksTask }
@@ -0,0 +1,42 @@
1
+ import colors from 'ansi-colors'
2
+ import log from 'fancy-log'
3
+ import { existsSync } from 'fs'
4
+ import { join } from 'path'
5
+ import {
6
+ logLoadingTask,
7
+ packageName,
8
+ packageTestsBenchmarksDirectory
9
+ } from '../../_utils.mjs'
10
+
11
+ const {
12
+ red,
13
+ yellow
14
+ } = colors
15
+
16
+ /**
17
+ * @description Will run benchmarks with node
18
+ */
19
+ const runBenchmarksForBackendTask = async ( done ) => {
20
+
21
+ const benchesPath = join( packageTestsBenchmarksDirectory, `/${ packageName }.benchmarks.js` )
22
+ if ( !existsSync( benchesPath ) ) {
23
+ log( yellow( `${ benchesPath } does not exist, skip backend benchmarks...` ) )
24
+ done()
25
+ return
26
+ }
27
+
28
+ try {
29
+ await import(benchesPath)
30
+ done()
31
+ } catch ( error ) {
32
+ done( red( error ) )
33
+ }
34
+
35
+ }
36
+ runBenchmarksForBackendTask.displayName = 'run-benchmarks-for-backend'
37
+ runBenchmarksForBackendTask.description = 'Will run benchmarks with node'
38
+ runBenchmarksForBackendTask.flags = null
39
+
40
+ logLoadingTask( import.meta.filename, runBenchmarksForBackendTask )
41
+
42
+ export { runBenchmarksForBackendTask }
@@ -0,0 +1,52 @@
1
+ import { startTestRunner } from '@web/test-runner'
2
+ import colors from 'ansi-colors'
3
+ import { join } from 'path'
4
+ import {
5
+ getConfigurationFrom,
6
+ getConfigurationPathFor,
7
+ logLoadingTask
8
+ } from '../../_utils.mjs'
9
+
10
+ const { red } = colors
11
+
12
+ const configurationLocation = join( 'tests', 'benchmarks', 'run-benchmarks-for-frontend.conf.mjs' )
13
+ const configurationPath = getConfigurationPathFor( configurationLocation )
14
+
15
+ /**
16
+ * @description Will run benchmarks with web-test-runner
17
+ */
18
+ const runBenchmarksForFrontendTask = () => {
19
+ return new Promise( async ( resolve, reject ) => {
20
+
21
+ const configuration = await getConfigurationFrom( configurationPath )
22
+ const testRunner = await startTestRunner( {
23
+ config: configuration,
24
+ readCliArgs: false,
25
+ readFileConfig: false,
26
+ autoExitProcess: false,
27
+ } )
28
+
29
+ if ( !testRunner ) {
30
+ reject( red( 'Internal test runner error.' ) )
31
+ return
32
+ }
33
+
34
+ // To ensure that testRunner exit event won't be used by other instance of test runner,
35
+ // we need to be sure that current test runner is ended
36
+ testRunner.on( 'finished', () => {
37
+ testRunner.stop()
38
+ } )
39
+
40
+ testRunner.on( 'stopped', () => {
41
+ resolve()
42
+ } )
43
+
44
+ } )
45
+ }
46
+ runBenchmarksForFrontendTask.displayName = 'run-benchmarks-for-frontend'
47
+ runBenchmarksForFrontendTask.description = 'Will run benchmarks with web-test-runner.'
48
+ runBenchmarksForFrontendTask.flags = null
49
+
50
+ logLoadingTask( import.meta.filename, runBenchmarksForFrontendTask, configurationPath )
51
+
52
+ export { runBenchmarksForFrontendTask }