sxy-test-runner 1.0.4 → 1.0.7

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 (108) hide show
  1. package/dist/cli/init.js +170 -0
  2. package/dist/cli/init.unitTest.js +0 -0
  3. package/dist/cli/lib/addBasePath.js +15 -0
  4. package/dist/cli/lib/addBasePath.unitTest.js +31 -0
  5. package/dist/cli/lib/addExports.js +12 -0
  6. package/dist/cli/lib/addExports.unitTest.js +29 -0
  7. package/dist/cli/lib/applyConfigDefaults.js +41 -0
  8. package/dist/cli/lib/applyConfigDefaults.unitTest.js +25 -0
  9. package/dist/cli/lib/buildDependencyTree.js +32 -0
  10. package/dist/cli/lib/buildDependencyTree.unitTest.js +15 -0
  11. package/dist/cli/lib/buildDependencyTrees.js +34 -0
  12. package/dist/cli/lib/buildDependencyTrees.unitTest.js +17 -0
  13. package/dist/cli/lib/configBeforeAfterFuncs.js +35 -0
  14. package/dist/cli/lib/configBeforeAfterFuncs.unitTest.js +0 -0
  15. package/dist/cli/lib/defaultConfig.js +22 -0
  16. package/dist/cli/lib/defaultConfig.test.js +7 -0
  17. package/dist/cli/lib/doUserSetup.js +30 -0
  18. package/dist/cli/lib/doUserSetup.unitTest.js +39 -0
  19. package/dist/cli/lib/doUserTeardown.js +30 -0
  20. package/dist/cli/lib/doUserTeardown.unitTest.js +39 -0
  21. package/dist/cli/lib/findTestFiles.js +24 -0
  22. package/dist/cli/lib/findTestFiles.unitTest.js +22 -0
  23. package/dist/cli/lib/getAllowedFlags.js +11 -0
  24. package/dist/cli/lib/getAllowedFlags.unitTest.js +20 -0
  25. package/dist/cli/lib/globArgCombine.js +1 -0
  26. package/dist/cli/lib/globArgCombine.unitTest.js +18 -0
  27. package/dist/cli/lib/injectProperties.js +11 -0
  28. package/dist/cli/lib/injectProperties.unitTest.js +75 -0
  29. package/dist/cli/lib/load.js +3 -0
  30. package/dist/cli/lib/load.unitTest.js +7 -0
  31. package/dist/cli/lib/loadConfig.js +21 -0
  32. package/dist/cli/lib/loadConfig.unitTest.js +15 -0
  33. package/dist/cli/lib/loadTestFile.js +75 -0
  34. package/dist/cli/lib/loadTestFile.unitTest.js +45 -0
  35. package/dist/cli/lib/loadTestFileStatic.js +40 -0
  36. package/dist/cli/lib/loadTestFileStatic.unitTest.js +29 -0
  37. package/dist/cli/lib/overrideConsoleLog.js +20 -0
  38. package/dist/cli/lib/overrideConsoleLog.unitTest.js +0 -0
  39. package/dist/cli/lib/parseCommandLineArguments.js +57 -0
  40. package/dist/cli/lib/parseCommandLineArguments.unitTest.js +21 -0
  41. package/dist/cli/lib/parseDescribe.js +88 -0
  42. package/dist/cli/lib/parseDescribe.unitTest.js +17 -0
  43. package/dist/cli/lib/processWatchEvent.js +0 -0
  44. package/dist/cli/lib/processWatchEvent.unitTest.js +7 -0
  45. package/dist/cli/lib/reservedExportKeys.js +1 -0
  46. package/dist/cli/lib/reservedExportKeys.unitTest.js +7 -0
  47. package/dist/cli/lib/runDescribe.js +29 -0
  48. package/dist/cli/lib/runDescribe.old.js +115 -0
  49. package/dist/cli/lib/runDescribe.old.unitTest.js +440 -0
  50. package/dist/cli/lib/runDescribe.unitTest.js +287 -0
  51. package/dist/cli/lib/runDescribeRun.js +59 -0
  52. package/dist/cli/lib/runDescribeRun.unitTest.js +293 -0
  53. package/dist/cli/lib/runIt.js +79 -0
  54. package/dist/cli/lib/runIt.unitTest.js +294 -0
  55. package/dist/cli/lib/runTasks.js +42 -0
  56. package/dist/cli/lib/runTasks.unitTest.js +30 -0
  57. package/dist/cli/lib/runTest-old.js +159 -0
  58. package/dist/cli/lib/runTest-old.unitTest.js +183 -0
  59. package/dist/cli/lib/runTest.js +71 -0
  60. package/dist/cli/lib/runTest.unitTest.js +269 -0
  61. package/dist/cli/lib/runTestFile copy.js +292 -0
  62. package/dist/cli/lib/runTestFile-old.js +348 -0
  63. package/dist/cli/lib/runTestFile.js +105 -0
  64. package/dist/cli/lib/runTestFile.unitTest.js +264 -0
  65. package/dist/cli/lib/runTestFiles.js +141 -0
  66. package/dist/cli/lib/runTestFiles.unitTest.js +147 -0
  67. package/dist/cli/lib/runTests.js +137 -0
  68. package/dist/cli/lib/runTests.unitTest.js +59 -0
  69. package/dist/cli/lib/shouldCaptureConsoleLog.js +24 -0
  70. package/dist/cli/lib/shouldCaptureConsoleLog.unitTest.js +31 -0
  71. package/dist/cli/lib/showTestLoadingError.js +22 -0
  72. package/dist/cli/lib/showTestLoadingError.unitTest.js +25 -0
  73. package/dist/cli/lib/showTestResult.js +87 -0
  74. package/dist/cli/lib/showTestResult.unitTest.js +180 -0
  75. package/dist/cli/lib/timeProfier.js +7 -0
  76. package/dist/cli/lib/validateConfig.js +29 -0
  77. package/dist/cli/lib/validateConfig.unitTest.js +22 -0
  78. package/dist/cli/lib/watchFiles.js +1 -0
  79. package/dist/cli/lib/watchFiles.unitTest.js +48 -0
  80. package/dist/cli/lib/watchFilesAndRunTests.js +2 -0
  81. package/dist/cli/lib/watchFilesAndRunTests.unitTest.js +129 -0
  82. package/dist/cli/lib/watchFilesAndRunTestsChokidar.js +142 -0
  83. package/dist/cli/lib/watchFilesAndRunTestsChokidar.unitTest.js +133 -0
  84. package/dist/cli/lib/watchFilesAndRunTestsNodeWatch.js +162 -0
  85. package/dist/cli/lib/watchFilesAndRunTestsNodeWatch.unitTest.js +131 -0
  86. package/dist/cli/lib/watchFilesChokidar.js +56 -0
  87. package/dist/cli/lib/watchFilesChokidar.unitTest.js +85 -0
  88. package/dist/cli/lib/watchFilesNodeWatch.js +42 -0
  89. package/dist/cli/lib/watchFilesNodeWatch.unitTest.js +48 -0
  90. package/dist/cli/once.js +47 -0
  91. package/dist/cli/once.unitTest.js +39 -0
  92. package/dist/cli/watch.js +100 -0
  93. package/dist/cli/watch.unitTest.js +117 -0
  94. package/dist/config.js +7 -0
  95. package/dist/describe-old.js +257 -0
  96. package/dist/describe-old.unitTest.js +21 -0
  97. package/dist/describe.js +24 -0
  98. package/dist/describe.unitTest.js +27 -0
  99. package/dist/exported.eslintrc.cjs +7 -0
  100. package/dist/exported.eslintrc.js +7 -0
  101. package/dist/index.js +1 -0
  102. package/dist/indexNumberToLetters.js +13 -0
  103. package/dist/load.js +3 -0
  104. package/dist/output.js +17 -0
  105. package/dist/testsState.js +4 -0
  106. package/dist/timeProfiling.js +9 -0
  107. package/package.json +3 -2
  108. package/sxy-loader.config.js +10 -0
@@ -0,0 +1,170 @@
1
+ import { join } from 'path';
2
+ import chalk from 'chalk-extensions';
3
+ import { packageName, cliName, configFileName, configLocations } from '../config.js';
4
+ import { out, log, debug } from '../output.js';
5
+ import fs from 'fs';
6
+ export async function init() {
7
+ const projectDir = await process.cwd();
8
+
9
+ for (const configLocation of configLocations) {
10
+ let loc;
11
+ loc = await join(projectDir, configLocation, configFileName + '.js');
12
+
13
+ if (await fs.existsSync(loc)) {
14
+ await configAlreadyExists(loc);
15
+ }
16
+
17
+ loc = await join(projectDir, configLocation, configFileName + '.cjs');
18
+
19
+ if (await fs.existsSync(loc)) {
20
+ await configAlreadyExists(loc);
21
+ }
22
+
23
+ loc = await join(projectDir, configLocation, configFileName + '.mjs');
24
+
25
+ if (await fs.existsSync(loc)) {
26
+ await configAlreadyExists(loc);
27
+ }
28
+ }
29
+
30
+ async function configAlreadyExists(loc) {
31
+ await out(chalk.orange`[${packageName}] A matching config already exists at ${loc}` + `\nPlease remove this config before generating a new one with \`${cliName} init\``);
32
+ }
33
+
34
+ const projectPackageJsonLocation = await join(projectDir, 'package.json');
35
+
36
+ if (!(await fs.existsSync(projectPackageJsonLocation))) {
37
+ await out(chalk.orange`[${packageName}] No package.json exists in this location` + `\nPlease initialise the package with \`yarn init\` on \`npm init\`` + ` before running this command, and run this command from the project root folder`);
38
+ } //const packageJsonRaw = await fs.promises.readFile( projectPackageJsonLocation )
39
+
40
+
41
+ const packageJsonRaw = await fs.readFileSync(projectPackageJsonLocation);
42
+ const packageJson = await JSON.parse(packageJsonRaw);
43
+ let targetConfigName;
44
+
45
+ if (packageJson.type === 'module') {
46
+ // ES6 module
47
+ targetConfigName = await join(projectDir, configLocations[0], configFileName + '.js');
48
+ } else {
49
+ // common
50
+ targetConfigName = await join(projectDir, configLocations[0], configFileName + '.mjs');
51
+ }
52
+
53
+ const defaultConfig = `export default {
54
+
55
+ // base folder for tests match and ignore patterns
56
+ testsBase: '.',
57
+
58
+ // glob pattern or array of glob patterns of test files
59
+ tests: [
60
+ '**/*.test.{js,mjs,jsx}',
61
+ '**/*.spec.{js,mjs,jsx}',
62
+ '**/tests?/*.{js,mjs,jsx}',
63
+ '**/__tests?__/*.{js,mjs,jsx}'
64
+ ],
65
+
66
+ // glob pattern or array of patterns of test files to ignore
67
+ testsIgnore: ['**/node_modules/**/*'],
68
+
69
+ // whether to show the full error trace when an error occurs in a test file
70
+ showErrorTrace: false,
71
+
72
+ // tasks to run on startup
73
+ // accepts a function, file location (relative to project base), or array of functions and or files
74
+ setup: undefined,
75
+
76
+ // tasks to run before each test file is run
77
+ beforeEachFile: undefined,
78
+
79
+ // tasks to run after each test file is run
80
+ afterEachFile: undefined,
81
+
82
+ // tasks to run before each describe block is processed
83
+ // if the function returns an object with named properties, or the file exports named exports,
84
+ // these will be passed to the callback function in argument 0, and can be access by destructruing e.g.
85
+ // describe('thing', ({exportA, exportB}) => { it('should', ...) })
86
+ beforeEachDescribe: undefined,
87
+
88
+ // tasks to run after each describe block
89
+ afterEachDescribe: undefined,
90
+
91
+ // tasks to run before each it/test block
92
+ // function returns and file exports will be passed to the it/test block as with describe above, e.g.
93
+ // it('should', ({exportA, exportB}) => { assert('something') })
94
+ beforeEachTest: undefined,
95
+
96
+ // tasks to run after each it/test block
97
+ afterEachTest: undefined,
98
+
99
+ // how to execute the different parts of test files
100
+ execution: {
101
+
102
+ // run test files in 'parallel' or 'sequential'ly
103
+ files: 'parallel',
104
+
105
+ // run describe blocks within a test file in 'parallel' or 'sequential'ly
106
+ describes: 'sequential',
107
+
108
+ // run it/test blocks within a describe blocks in 'parallel' or 'sequential'ly
109
+ tests: 'sequential'
110
+
111
+ },
112
+
113
+ // watch mode configurations
114
+ watch: {
115
+
116
+ //// the base directory to watch files in
117
+ watchFilesBase: '.',
118
+
119
+ //// glob filter or array of glob filters of files to watch
120
+ watchFiles: '**/*.js',
121
+
122
+ //// glob filter or array of globl filters of files to ignore
123
+ watchFilesIgnore: '**/node_modules/**/*',
124
+
125
+ // run all tests when starting the watcher
126
+ runAllOnStartup: true,
127
+
128
+ // re run all previously failed tests on each test run, until they pass
129
+ reRunFailingTests: true,
130
+
131
+ },
132
+
133
+ }`; // `export default {
134
+ // // base folder for tests match and ignore patterns
135
+ // testsBase: '.',
136
+ // // glob pattern or array of glob patterns of test files
137
+ // tests: [
138
+ // '**/*.test.{js,mjs,jsx}',
139
+ // '**/*.spec.{js,mjs,jsx}',
140
+ // '**/tests?/*.{js,mjs,jsx}',
141
+ // '**/__tests?__/*.{js,mjs,jsx}'
142
+ // ],
143
+ // // glob pattern or array of patterns of test files to ignore
144
+ // testsIgnore: ['**/node_modules/**/*'],
145
+ // // function to run on startup
146
+ // setup: undefined,
147
+ // // function to run before each test file
148
+ // setupEach: undefined,
149
+ // // function to run after test run
150
+ // teardown: undefined,
151
+ // // function to run after each test file
152
+ // teardownEach: undefined,
153
+ // // watch mode configurations
154
+ // watch: {
155
+ // //// the base directory to watch files in
156
+ // watchFilesBase: '.',
157
+ // //// glob filter or array of glob filters of files to watch
158
+ // watchFiles: '**/*.js',
159
+ // //// glob filter or array of globl filters of files to ignore
160
+ // watchFilesIgnore: '**/node_modules/**/*',
161
+ // // run all tests when starting the watcher
162
+ // runAllOnStartup: true,
163
+ // // re run all previously failed tests on each test run, until they pass
164
+ // reRunFailingTests: true,
165
+ // },
166
+ // }`
167
+
168
+ await fs.writeFileSync(targetConfigName, defaultConfig);
169
+ await out(chalk.mediumgreen`[${packageName}] Created config at ` + (await chalk.blue(targetConfigName)));
170
+ }
File without changes
@@ -0,0 +1,15 @@
1
+ import { createTimeProfiler } from 'sxy-dev-tools';
2
+ import { showTimeProfiling } from '../../config.js';
3
+ import { out, log, debug } from '../../output.js';
4
+ const {
5
+ timeProfileAsync
6
+ } = await createTimeProfiler(showTimeProfiling);
7
+ export async function addBasePath(base, items) {
8
+ return await timeProfileAsync('add base to globs', async () => {
9
+ if (base !== undefined && base !== '.' && base !== '') {
10
+ items = (await Array.isArray(items)) ? await items.map(item => `${base}/${item}`) : `${base}/${items}`;
11
+ }
12
+
13
+ return items;
14
+ });
15
+ }
@@ -0,0 +1,31 @@
1
+ import { addBasePath } from './addBasePath.js';
2
+ import { join } from 'path'; // addBaseToGlobs(base, globs)
3
+ // base: string
4
+ // globs: string or array of strings
5
+
6
+ await mochaDescribe('addBaseToGlobs() function', async function () {
7
+ await mochaIt('adds a base to a glob string', async function () {
8
+ const result = await addBasePath('src', '**/*.js');
9
+ await result.should.equal('src/**/*.js');
10
+ });
11
+ await mochaIt('adds a base to an array of glob strings', async function () {
12
+ const result = await addBasePath('src', ['**/*.test.js', '**/*.mocha.js']);
13
+ await result.should.have.members(['src/**/*.test.js', 'src/**/*.mocha.js']);
14
+ });
15
+ await mochaIt('it handles an empty string base', async function () {
16
+ const result = await addBasePath('', ['**/*.test.js', '**/*.mocha.js']);
17
+ await result.should.have.members(['**/*.test.js', '**/*.mocha.js']);
18
+ });
19
+ await mochaIt('it handles a . base', async function () {
20
+ const result = await addBasePath('.', ['**/*.test.js', '**/*.mocha.js']);
21
+ await result.should.have.members(['**/*.test.js', '**/*.mocha.js']);
22
+ });
23
+ await mochaIt('it handles an undefined base', async function () {
24
+ const result = await addBasePath(undefined, ['**/*.test.js', '**/*.mocha.js']);
25
+ await result.should.have.members(['**/*.test.js', '**/*.mocha.js']);
26
+ });
27
+ await mochaIt('it handles adding a base to a file path', async function () {
28
+ const result = await addBasePath('base', 'test/file.js');
29
+ await result.should.equal('base/test/file.js');
30
+ });
31
+ });
@@ -0,0 +1,12 @@
1
+ import { out as mainOut, log, debug, out } from '../../output.js';
2
+ export async function addExports(exports, newProperties, event, from, customOut = undefined) {
3
+ for (const key in newProperties) {
4
+ if (key in exports) {
5
+ const message = `Error loading '${event}' task exports, key '${key}' has already been exported`;
6
+ await out(message);
7
+ throw new Error(message);
8
+ } else {
9
+ exports[key] = newProperties[key];
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,29 @@
1
+ import { expect } from 'chai';
2
+ import { defaultConfig } from './defaultConfig.js';
3
+ import { addExports } from './addExports.js'; // applyConfigDefaults( userConfig: {} )
4
+
5
+ import { makeCustomOut } from '../../../unitTesting/makeCustomOut.js';
6
+ await mochaDescribe('addExports() function', async function () {
7
+ await mochaIt('should add passed properties to a base object', async function () {
8
+ const exports = {};
9
+ const newProperties = {
10
+ a: 1,
11
+ b: 2
12
+ };
13
+ await addExports(exports, newProperties);
14
+ await exports.should.have.keys(['a', 'b']);
15
+ });
16
+ await mochaIt('should complain about duplicates', async function () {
17
+ //const { customOut, getOutBuffer, setOutBuffer } = makeCustomOut()
18
+ const exports = {
19
+ a: 1,
20
+ b: 2
21
+ };
22
+ const newProperties = {
23
+ a: 3,
24
+ b: 4
25
+ };
26
+ const errorText = 'already been exported';
27
+ await addExports(exports, newProperties, 'placeholder', 'placeholder').should.be.rejectedWith(errorText);
28
+ });
29
+ });
@@ -0,0 +1,41 @@
1
+ import { mergeStructuredConfig, createTimeProfiler } from 'sxy-dev-tools';
2
+ import { packageName, cliName, configFileName, configLocations, showTimeProfiling } from '../../config.js';
3
+ import chalk from 'chalk-extensions';
4
+ import { out, log, debug } from '../../output.js';
5
+ import { defaultConfig } from './defaultConfig.js';
6
+ const {
7
+ timeProfileAsync
8
+ } = await createTimeProfiler(showTimeProfiling);
9
+ export async function applyConfigDefaults(userConfig) {
10
+ return await timeProfileAsync('apply config defaults', async () => {
11
+ const configStructure = {
12
+ execution: {},
13
+ watch: {}
14
+ }; //const config = mergeConfig(configStructure, defaultConfig, userConfig)
15
+
16
+ const config = await mergeStructuredConfig(configStructure, defaultConfig, userConfig); // I don't think we need to do these - the glob combine func can handle it
17
+ //if ( ! Array.isArray(config.tests) ) config.tests = [config.tests]
18
+ //if ( ! Array.isArray(config.testsIgnore) ) config.tests = [config.testsIgnore]
19
+ // watchFiles
20
+ // watchFilesIgnore
21
+ //log('final config', config)
22
+
23
+ return config;
24
+ });
25
+ }
26
+
27
+ async function mergeConfig(structure, baseConfig, ...extraConfigs) {
28
+ const finalConfig = await Object.copy(baseConfig);
29
+
30
+ for (const extraConfig of extraConfigs) {
31
+ for (const key in extraConfig) {
32
+ if (key in structure) {
33
+ finalConfig[key] = await mergeConfig(structure[key], finalConfig[key], extraConfig[key]);
34
+ } else {
35
+ finalConfig[key] = extraConfig[key];
36
+ }
37
+ }
38
+ }
39
+
40
+ return finalConfig;
41
+ }
@@ -0,0 +1,25 @@
1
+ import { defaultConfig } from './defaultConfig.js';
2
+ import { applyConfigDefaults } from './applyConfigDefaults.js'; // applyConfigDefaults( userConfig: {} )
3
+
4
+ await mochaDescribe('applyConfigDefaults() function', async function () {
5
+ await mochaIt('has sensible defaults when passed an empty user config', async function () {
6
+ const finalConfig = await applyConfigDefaults({});
7
+ await finalConfig.should.include.keys(['tests', 'testsIgnore', 'watch']);
8
+ });
9
+ await mochaIt('retains a passed config setting', async function () {
10
+ const finalConfig = await applyConfigDefaults({
11
+ tests: 'foo'
12
+ }); //console.log(finalConfig)
13
+
14
+ await finalConfig.tests.should.equal('foo');
15
+ });
16
+ await mochaIt('fills in defaults in a watch object with missing params', async function () {
17
+ const finalConfig = await applyConfigDefaults({
18
+ watch: {
19
+ watchFilesBase: 'src'
20
+ }
21
+ }); //console.log(finalConfig)
22
+
23
+ await finalConfig.watch.watchFiles.should.equal(defaultConfig.watch.watchFiles);
24
+ });
25
+ });
@@ -0,0 +1,32 @@
1
+ import dependencyTree from 'dependency-tree';
2
+ import { out, log, debug } from '../../output.js';
3
+ import slash from 'slash';
4
+ import 'sxy-standard/light.js';
5
+ export async function buildDependencyTree(config, filename) {
6
+ filename = await slash(filename); // convert to forward slashes
7
+ // const filter = path =>
8
+ // minimatch(path, watchFiles)
9
+ // && ! minimatch(path, watchFilesIgnores)
10
+
11
+ const dependencyTreeConfig = {
12
+ filename,
13
+ isListForm: true,
14
+ //directory: './src',
15
+ directory: config.watch.watchFilesBase,
16
+ filter: path => path.indexOf('node_modules') === -1
17
+ }; //// this filter needs to be replaced
18
+
19
+ const dt = await dependencyTree(dependencyTreeConfig); // process the results into final format
20
+ // (forward slashes and convert full path to rel path)
21
+
22
+ const cwd = await process.cwd();
23
+ await dt.process(file => slash(file).slice(cwd.length + 1)); // remove the current file
24
+
25
+ await dt.forEach(file => {
26
+ if (file === filename) {
27
+ dt.remove(file);
28
+ }
29
+ });
30
+ await debug('found dep tree', dt);
31
+ return dt;
32
+ }
@@ -0,0 +1,15 @@
1
+ import { applyConfigDefaults } from './applyConfigDefaults.js';
2
+ import { buildDependencyTree } from './buildDependencyTree.js';
3
+ import { join } from 'path'; // buildDependencyTree(config, file)
4
+ // config:
5
+ // file: relative to config.watch.watchFilesBase
6
+
7
+ await mochaDescribe('buildDependencyTree() function', async function () {
8
+ await mochaIt('identifies the dependencies for a js file passed to it', async function () {
9
+ // get the default configs
10
+ const config = await applyConfigDefaults({});
11
+ const sampleFile = await join('unitTesting/sampleFiles/c.js');
12
+ const depTree = await buildDependencyTree(config, sampleFile);
13
+ await depTree.should.have.members(['unitTesting/sampleFiles/a.js', 'unitTesting/sampleFiles/b.js']);
14
+ });
15
+ });
@@ -0,0 +1,34 @@
1
+ import { loadConfig as sxyLoadConfig, createTimeProfiler } from 'sxy-dev-tools';
2
+ import { packageName, cliName, configFileName, configLocations, showTimeProfiling } from '../../config.js';
3
+ import chalk from 'chalk-extensions';
4
+ import slash from 'slash';
5
+ import { out, log, debug } from '../../output.js';
6
+ import { buildDependencyTree } from './buildDependencyTree.js';
7
+ const {
8
+ timeProfileAsync
9
+ } = await createTimeProfiler(showTimeProfiling);
10
+ export async function buildDependencyTrees(config, testFiles) {
11
+ return await timeProfileAsync('build dependency trees', async () => {
12
+ const projectDir = await process.cwd();
13
+ const dependencyTrees = {};
14
+
15
+ for (const testFile of testFiles) {
16
+ //newTest(testFile.replace('./', ''))
17
+ const dependencyTree = await buildDependencyTree(config, testFile);
18
+ dependencyTrees[testFile] = dependencyTree; // .map ( sync( file => immed(immed(slash(file)).slice(projectDir.length + 1) )) )
19
+ // .filter( sync(f => immed(f !== testFile)) )
20
+
21
+ await debug('final dep tree', dependencyTrees[testFile]);
22
+ }
23
+
24
+ return dependencyTrees;
25
+ });
26
+ } // function newTest(testFile) {
27
+ // debug('new test', testFile)
28
+ // const dependencyTree = buildDependencyTree(testFile)
29
+ // //out('AA dependencyTree', testFile, dependencyTree)
30
+ // dependencyTrees[testFile]
31
+ // = dependencyTree
32
+ // .map ( file => slash(file).slice(projectDir.length + 1) )
33
+ // .filter(f => f !== testFile)
34
+ // }
@@ -0,0 +1,17 @@
1
+ import { applyConfigDefaults } from './applyConfigDefaults.js';
2
+ import { buildDependencyTrees } from './buildDependencyTrees.js';
3
+ import { join } from 'path'; // buildDependencyTrees(config, files)
4
+ // config:
5
+ // files: relative to config.watch.watchFilesBase
6
+
7
+ await mochaDescribe('buildDependencyTrees() function', async function () {
8
+ await mochaIt('identifies the dependencies for multiple js files', async function () {
9
+ // get the default configs
10
+ const config = await applyConfigDefaults({});
11
+ const sampleFiles = ['unitTesting/sampleFiles/c.js', 'unitTesting/sampleFiles/d.js'];
12
+ const depTrees = await buildDependencyTrees(config, sampleFiles);
13
+ await depTrees.should.have.keys(sampleFiles);
14
+ await depTrees[sampleFiles[0]].should.have.members(['unitTesting/sampleFiles/a.js', 'unitTesting/sampleFiles/b.js']);
15
+ await depTrees[sampleFiles[1]].should.have.members(['unitTesting/sampleFiles/a.js']);
16
+ });
17
+ });
@@ -0,0 +1,35 @@
1
+ import { runTasks } from './runTasks.js';
2
+ import { addExports } from './addExports.js';
3
+ export async function configBeforeEachFile(config, exports) {
4
+ if (config.beforeEachFile) {
5
+ const theExports = await runTasks(config.beforeEachFile, undefined);
6
+ await addExports(exports, theExports);
7
+ }
8
+ }
9
+ export async function configAfterEachFile(config, exports) {
10
+ if (config.afterEachFile) {
11
+ await runTasks(config.afterEachFile, exports);
12
+ }
13
+ }
14
+ export async function configBeforeEachDescribe(config, exports) {
15
+ if (config.beforeEachDescribe) {
16
+ const theExports = await runTasks(config.beforeEachDescribe, undefined);
17
+ await addExports(exports, theExports);
18
+ }
19
+ }
20
+ export async function configAfterEachDescribe(config, exports) {
21
+ if (config.afterEachDescribe) {
22
+ await runTasks(config.afterEachDescribe, exports);
23
+ }
24
+ }
25
+ export async function configBeforeEachTest(config, exports) {
26
+ if (config.beforeEachTest) {
27
+ const theExports = await runTasks(config.beforeEachTest, undefined);
28
+ await addExports(exports, theExports);
29
+ }
30
+ }
31
+ export async function configAfterEachTest(config, exports) {
32
+ if (config.afterEachTest) {
33
+ await runTasks(config.afterEachTest, exports);
34
+ }
35
+ }
@@ -0,0 +1,22 @@
1
+ export const defaultConfig = {
2
+ testsBase: '.',
3
+ tests: ['**/*.test.{js,mjs,jsx}', '**/*.spec.{js,mjs,jsx}', '**/tests?/*.{js,mjs,jsx}', '**/__tests?__/*.{js,mjs,jsx}'],
4
+ testsIgnore: ['node_modules'],
5
+ showErrorTrace: false,
6
+ //setup
7
+ //setupEach
8
+ //teardown
9
+ //teardownEach
10
+ execution: {
11
+ files: 'parallel',
12
+ describes: 'sequential',
13
+ tests: 'sequential'
14
+ },
15
+ watch: {
16
+ watchFilesBase: '.',
17
+ watchFiles: '**/*',
18
+ watchFilesIgnore: '**/node_modules/**/*',
19
+ runAllOnStart: true,
20
+ reRunFailingTests: true
21
+ }
22
+ };
@@ -0,0 +1,7 @@
1
+ import { defaultConfig } from './defaultConfig.js'; // applyConfigDefaults( userConfig: {} )
2
+
3
+ await mochaDescribe('the defaultConfig', async function () {
4
+ await mochaIt('has sensible defaults', async function () {
5
+ await defaultConfig.should.include.keys(['tests', 'testsIgnore', 'watch']);
6
+ });
7
+ });
@@ -0,0 +1,30 @@
1
+ import { join } from 'path';
2
+ import { out, log, debug } from '../../output.js';
3
+ export async function doUserSetup(config) {
4
+ if (config.setup) {
5
+ const setupTasks = (await Array.isArray(config.setup)) ? config.setup : [config.setup];
6
+
7
+ for (const setupTask of setupTasks) {
8
+ //console.log( typeof setupTask, setupTask)
9
+ switch (typeof setupTask) {
10
+ case 'function':
11
+ {
12
+ await setupTask();
13
+ break;
14
+ }
15
+
16
+ case 'string':
17
+ {
18
+ await import(`file://${await join(await process.cwd(), setupTask)}`);
19
+ break;
20
+ }
21
+
22
+ default:
23
+ {
24
+ await out(`Error: setup entry has an invalid type, expected 'function' or 'string' of an file to import.`);
25
+ await out(`Received ${typeof setupTask}.`);
26
+ }
27
+ }
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,39 @@
1
+ import { applyConfigDefaults } from './applyConfigDefaults.js';
2
+ import { doUserSetup } from './doUserSetup.js'; // applyConfigDefaults( userConfig: {} )
3
+
4
+ await mochaDescribe('the doUserSetup() function', async function () {
5
+ await mochaIt('executes a user setup function', async function () {
6
+ let setupFunctionHasRun = false;
7
+ const config = await applyConfigDefaults({
8
+ setup: async function () {
9
+ setupFunctionHasRun = true;
10
+ }
11
+ });
12
+ await doUserSetup(config);
13
+ await setupFunctionHasRun.should.equal(true);
14
+ }), await mochaIt('runs a user specified file', async function () {
15
+ global.setupFileHasRun = false;
16
+ const config = await applyConfigDefaults({
17
+ setup: 'unitTesting/setupFiles/setup.js'
18
+ });
19
+ await doUserSetup(config);
20
+ await global.setupFileHasRun.should.equal(true);
21
+ }), await mochaIt('runs an array of functions and or files', async function () {
22
+ let setupFunction1HasRun = false;
23
+ let setupFunction2HasRun = false;
24
+ global.setupFile1HasRun = false;
25
+ global.setupFile2HasRun = false;
26
+ const config = await applyConfigDefaults({
27
+ setup: [async function setup1() {
28
+ setupFunction1HasRun = true;
29
+ }, async function setup2() {
30
+ setupFunction2HasRun = true;
31
+ }, 'unitTesting/setupFiles/setup-1.js', 'unitTesting/setupFiles/setup-2.js']
32
+ });
33
+ await doUserSetup(config);
34
+ await setupFunction1HasRun.should.equal(true);
35
+ await setupFunction2HasRun.should.equal(true);
36
+ await global.setupFile1HasRun.should.equal(true);
37
+ await global.setupFile2HasRun.should.equal(true);
38
+ });
39
+ });
@@ -0,0 +1,30 @@
1
+ import { join } from 'path';
2
+ import { out, log, debug } from '../../output.js';
3
+ export async function doUserTeardown(config) {
4
+ if (config.teardown) {
5
+ const teardownTasks = (await Array.isArray(config.teardown)) ? config.teardown : [config.teardown];
6
+
7
+ for (const teardownTask of teardownTasks) {
8
+ //console.log( typeof teardownTask, teardownTask)
9
+ switch (typeof teardownTask) {
10
+ case 'function':
11
+ {
12
+ await teardownTask();
13
+ break;
14
+ }
15
+
16
+ case 'string':
17
+ {
18
+ await import(`file://${await join(await process.cwd(), teardownTask)}`);
19
+ break;
20
+ }
21
+
22
+ default:
23
+ {
24
+ await out(`Error: teardown entry has an invalid type, expected 'function' or 'string' of an file to import.`);
25
+ await out(`Received ${typeof teardownTask}.`);
26
+ }
27
+ }
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,39 @@
1
+ import { applyConfigDefaults } from './applyConfigDefaults.js';
2
+ import { doUserTeardown } from './doUserTeardown.js'; // applyConfigDefaults( userConfig: {} )
3
+
4
+ await mochaDescribe('the doUserTeardown() function', async function () {
5
+ await mochaIt('executes a user teardown function', async function () {
6
+ let teardownFunctionHasRun = false;
7
+ const config = await applyConfigDefaults({
8
+ teardown: async function () {
9
+ teardownFunctionHasRun = true;
10
+ }
11
+ });
12
+ await doUserTeardown(config);
13
+ await teardownFunctionHasRun.should.equal(true);
14
+ }), await mochaIt('runs a user specified file', async function () {
15
+ global.teardownFileHasRun = false;
16
+ const config = await applyConfigDefaults({
17
+ teardown: 'unitTesting/teardownFiles/teardown.js'
18
+ });
19
+ await doUserTeardown(config);
20
+ await global.teardownFileHasRun.should.equal(true);
21
+ }), await mochaIt('runs an array of functions and or files', async function () {
22
+ let teardownFunction1HasRun = false;
23
+ let teardownFunction2HasRun = false;
24
+ global.teardownFile1HasRun = false;
25
+ global.teardownFile2HasRun = false;
26
+ const config = await applyConfigDefaults({
27
+ teardown: [async function teardown1() {
28
+ teardownFunction1HasRun = true;
29
+ }, async function teardown2() {
30
+ teardownFunction2HasRun = true;
31
+ }, 'unitTesting/teardownFiles/teardown-1.js', 'unitTesting/teardownFiles/teardown-2.js']
32
+ });
33
+ await doUserTeardown(config);
34
+ await teardownFunction1HasRun.should.equal(true);
35
+ await teardownFunction2HasRun.should.equal(true);
36
+ await global.teardownFile1HasRun.should.equal(true);
37
+ await global.teardownFile2HasRun.should.equal(true);
38
+ });
39
+ });