@travetto/test 3.3.6 → 3.4.0-rc.1

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/README.md CHANGED
@@ -79,6 +79,7 @@ would translate to:
79
79
  "use strict";
80
80
  Object.defineProperty(exports, "__esModule", { value: true });
81
81
  const tslib_1 = require("tslib");
82
+ const Ⲑ_util_1 = tslib_1.__importStar(require("@travetto/test/src/execute/util.js"));
82
83
  const Ⲑ_check_1 = tslib_1.__importStar(require("@travetto/test/src/assert/check.js"));
83
84
  const Ⲑ_root_index_1 = tslib_1.__importStar(require("@travetto/manifest/src/root-index.js"));
84
85
  const Ⲑ_decorator_1 = tslib_1.__importStar(require("@travetto/registry/src/decorator.js"));
@@ -88,6 +89,8 @@ const test_1 = require("@travetto/test");
88
89
  let SimpleTest = class SimpleTest {
89
90
  static Ⲑinit = Ⲑ_root_index_1.RootIndex.registerFunction(SimpleTest, ᚕf, 1887908328, { test: { hash: 102834457 } }, false, false);
90
91
  async test() {
92
+ if (Ⲑ_util_1.RunnerUtil.tryDebugger)
93
+ debugger;
91
94
  Ⲑ_check_1.AssertCheck.check({ file: ᚕf, line: 10, text: "{ size: 20, address: { state: 'VA' } }", operator: "deepStrictEqual" }, true, { size: 20, address: { state: 'VA' } }, {});
92
95
  }
93
96
  };
@@ -224,7 +227,7 @@ Usage: test [options] [first:string] [regexes...:string]
224
227
 
225
228
  Options:
226
229
  -f, --format <string> Output format for test results (default: "tap")
227
- -c, --concurrency <number> Number of tests to run concurrently (default: 7)
230
+ -c, --concurrency <number> Number of tests to run concurrently (default: 4)
228
231
  -m, --mode <single|standard> Test run mode (default: "standard")
229
232
  -h, --help display help for command
230
233
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/test",
3
- "version": "3.3.6",
3
+ "version": "3.4.0-rc.1",
4
4
  "description": "Declarative test framework",
5
5
  "keywords": [
6
6
  "unit-testing",
@@ -27,15 +27,15 @@
27
27
  "directory": "module/test"
28
28
  },
29
29
  "dependencies": {
30
- "@travetto/base": "^3.3.4",
31
- "@travetto/registry": "^3.3.4",
32
- "@travetto/terminal": "^3.3.1",
33
- "@travetto/worker": "^3.3.4",
34
- "@travetto/yaml": "^3.3.4"
30
+ "@travetto/base": "^3.4.0-rc.1",
31
+ "@travetto/registry": "^3.4.0-rc.1",
32
+ "@travetto/terminal": "^3.4.0-rc.0",
33
+ "@travetto/worker": "^3.4.0-rc.1",
34
+ "@travetto/yaml": "^3.4.0-rc.1"
35
35
  },
36
36
  "peerDependencies": {
37
- "@travetto/cli": "^3.3.6",
38
- "@travetto/transformer": "^3.3.2"
37
+ "@travetto/cli": "^3.4.0-rc.2",
38
+ "@travetto/transformer": "^3.4.0-rc.1"
39
39
  },
40
40
  "peerDependenciesMeta": {
41
41
  "@travetto/transformer": {
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "travetto": {
49
49
  "displayName": "Testing",
50
- "profiles": [
50
+ "roles": [
51
51
  "test"
52
52
  ]
53
53
  },
@@ -1,4 +1,4 @@
1
- import fs from 'fs';
1
+ import { existsSync } from 'fs';
2
2
 
3
3
  import { Class } from '@travetto/base';
4
4
 
@@ -28,7 +28,7 @@ export class CumulativeSummaryConsumer implements TestConsumer {
28
28
  */
29
29
  summarizeSuite(test: TestResult): SuiteResult {
30
30
  // Was only loading to verify existence (TODO: double-check)
31
- if (fs.existsSync(test.file)) {
31
+ if (existsSync(test.file)) {
32
32
  this.#state[test.classId] = this.#state[test.classId] ?? {};
33
33
  this.#state[test.classId][test.methodName] = test.status;
34
34
  const SuiteCls = SuiteRegistry.getClasses().find(x =>
@@ -30,7 +30,7 @@ export class Runner {
30
30
  async runFiles(): Promise<boolean> {
31
31
  const consumer = await RunnableTestConsumer.get(this.#state.consumer ?? this.#state.format);
32
32
 
33
- const files = (await RunnerUtil.getTestFiles(this.patterns));
33
+ const files = (await RunnerUtil.getTestFiles(this.patterns)).map(f => f.sourceFile);
34
34
 
35
35
  console.debug('Running', { files, patterns: this.patterns });
36
36
 
@@ -2,7 +2,7 @@ import { createReadStream } from 'fs';
2
2
  import readline from 'readline';
3
3
 
4
4
  import { ExecUtil, ShutdownManager, TimeUtil } from '@travetto/base';
5
- import { RootIndex } from '@travetto/manifest';
5
+ import { IndexedFile, RootIndex } from '@travetto/manifest';
6
6
 
7
7
  /**
8
8
  * Simple Test Utilities
@@ -36,12 +36,16 @@ export class RunnerUtil {
36
36
  /**
37
37
  * Find all valid test files given the globs
38
38
  */
39
- static async getTestFiles(globs: RegExp[]): Promise<string[]> {
40
- const files = RootIndex.findTest({})
41
- .filter(f => globs.some(g => g.test(f.import)));
39
+ static async getTestFiles(globs?: RegExp[]): Promise<IndexedFile[]> {
40
+ const files = RootIndex.find({
41
+ module: m => m.roles.includes('test') || m.roles.includes('std'),
42
+ folder: f => f === 'test',
43
+ file: f => f.role === 'test'
44
+ })
45
+ .filter(f => globs?.some(g => g.test(f.import)) ?? true);
42
46
 
43
47
  const validFiles = files
44
- .map(f => this.isTestFile(f.sourceFile).then(valid => ({ file: f.sourceFile, valid })));
48
+ .map(f => this.isTestFile(f.sourceFile).then(valid => ({ file: f, valid })));
45
49
 
46
50
  return (await Promise.all(validFiles))
47
51
  .filter(x => x.valid)
@@ -61,4 +65,14 @@ export class RunnerUtil {
61
65
  }
62
66
  return countRes.valid ? +countRes.stdout : 0;
63
67
  }
68
+
69
+ /**
70
+ * Determine if we should invoke the debugger
71
+ */
72
+ static get tryDebugger(): boolean {
73
+ if (process.env.TRV_TEST_BREAK_ENTRY === '1') {
74
+ return true;
75
+ }
76
+ return false;
77
+ }
64
78
  }
@@ -8,6 +8,7 @@ import { buildStandardTestManager } from '../worker/standard';
8
8
  import { TestConsumerRegistry } from '../consumer/registry';
9
9
  import { CumulativeSummaryConsumer } from '../consumer/types/cumulative';
10
10
  import { RunEvent } from '../worker/types';
11
+ import { RunnerUtil } from './util';
11
12
 
12
13
  function isRunEvent(ev: unknown): ev is RunEvent {
13
14
  return ObjectUtil.isPlainObject(ev) && 'type' in ev && typeof ev.type === 'string' && ev.type === 'run-test';
@@ -78,7 +79,7 @@ export class TestWatcher {
78
79
  process.send?.('ready');
79
80
 
80
81
  if (runAllOnStart) {
81
- for (const test of await RootIndex.findTest({})) {
82
+ for (const test of await RunnerUtil.getTestFiles()) {
82
83
  await import(test.import);
83
84
  itr.add(test.sourceFile);
84
85
  }
@@ -1,6 +1,6 @@
1
- import fs from 'fs/promises';
1
+ import { createWriteStream } from 'fs';
2
2
 
3
- import { path } from '@travetto/manifest';
3
+ import { ManifestFileUtil, RootIndex } from '@travetto/manifest';
4
4
  import { ConsoleManager, ErrorUtil, TimeUtil } from '@travetto/base';
5
5
  import { ChildCommChannel } from '@travetto/worker';
6
6
 
@@ -32,9 +32,7 @@ export class TestChildWorker extends ChildCommChannel<RunEvent> {
32
32
  */
33
33
  async activate(): Promise<void> {
34
34
  if (/\b@travetto[/]test\b/.test(process.env.DEBUG ?? '')) {
35
- const handle = await fs.open(path.resolve(`.trv-test-worker.${process.pid}.log`), 'a');
36
- const stdout = handle.createWriteStream();
37
-
35
+ const stdout = createWriteStream(ManifestFileUtil.toolPath(RootIndex, `test-worker.${process.pid}.log`), { flags: 'a' });
38
36
  const c = new console.Console({ stdout, inspectOptions: { depth: 4, colors: false } });
39
37
  ConsoleManager.set({ onLog: (ev) => c[ev.level](process.pid, ...ev.args) });
40
38
  } else {
@@ -61,7 +59,6 @@ export class TestChildWorker extends ChildCommChannel<RunEvent> {
61
59
  if (event.type === Events.INIT) { // On request to init, start initialization
62
60
  await this.#exec(() => this.onInitCommand(), Events.INIT_COMPLETE);
63
61
  } else if (event.type === Events.RUN) { // On request to run, start running
64
- console.log!(process.stdout.isTTY && process.stdout.getColorDepth());
65
62
  await this.#exec(() => this.onRunCommand(event), Events.RUN_COMPLETE);
66
63
  }
67
64
 
@@ -39,7 +39,7 @@ export function buildStandardTestManager(consumer: TestConsumer): () => Worker<s
39
39
 
40
40
  const channel = new ParentCommChannel<TestEvent & { error?: Error }>(
41
41
  ExecUtil.fork(
42
- RootIndex.resolveFileImport('@travetto/cli/support/entry.cli'),
42
+ RootIndex.resolveFileImport('@travetto/cli/support/entry.trv'),
43
43
  ['test:child'],
44
44
  {
45
45
  cwd,
@@ -18,7 +18,7 @@ export class TestCommand implements CliCommandShape {
18
18
  format: TestFormat = 'tap';
19
19
  /** Number of tests to run concurrently */
20
20
  @Min(1) @Max(WorkPool.MAX_SIZE)
21
- concurrency: number = WorkPool.MAX_SIZE;
21
+ concurrency: number = WorkPool.DEFAULT_SIZE;
22
22
  /** Test run mode */
23
23
  mode: TestMode = 'standard';
24
24
 
@@ -19,9 +19,9 @@ export class TestCountCommand {
19
19
  // Load all tests
20
20
  for (const file of files) {
21
21
  try {
22
- await import(RootIndex.getFromSource(file)!.import);
22
+ await import(file.import);
23
23
  } catch (err) {
24
- console.error('Failed to import', file, err);
24
+ console.error('Failed to import', file.sourceFile, err);
25
25
  }
26
26
  }
27
27
 
@@ -1,5 +1,5 @@
1
1
  import { GlobalEnvConfig } from '@travetto/base';
2
- import { CliCommand } from '@travetto/cli';
2
+ import { CliCommand, CliUtil } from '@travetto/cli';
3
3
 
4
4
  import { TestFormat } from './bin/types';
5
5
 
@@ -17,6 +17,10 @@ export class TestWatcherCommand {
17
17
  }
18
18
 
19
19
  async main(): Promise<void> {
20
+ if (await CliUtil.runWithRestart(this)) {
21
+ return;
22
+ }
23
+
20
24
  // Quit on parent disconnect
21
25
  if (process.send) {
22
26
  process.on('disconnect', () => process.exit(0));
@@ -24,9 +28,7 @@ export class TestWatcherCommand {
24
28
 
25
29
  try {
26
30
  const { TestWatcher } = await import('../src/execute/watcher.js');
27
- console.log('Starting');
28
31
  await TestWatcher.watch(this.format, this.mode === 'all');
29
- console.log('Done');
30
32
  } catch (err) {
31
33
  console.error(err);
32
34
  }
@@ -4,18 +4,40 @@ import {
4
4
  TransformerState, DecoratorMeta, OnMethod, OnClass, CoreUtil, DecoratorUtil
5
5
  } from '@travetto/transformer';
6
6
 
7
+ const RUN_UTIL = 'RunnerUtil';
8
+
9
+ const RunUtilⲐ = Symbol.for('@travetto/test:runner');
10
+
11
+ /**
12
+ * Annotate transformation state
13
+ */
14
+ interface AnnotateState {
15
+ [RunUtilⲐ]?: ts.Expression;
16
+ }
17
+
7
18
  /**
8
19
  * Annotate tests and suites for better diagnostics
9
20
  */
10
21
  export class AnnotationTransformer {
11
22
 
23
+
24
+ /**
25
+ * Initialize transformer state
26
+ */
27
+ static initState(state: TransformerState & AnnotateState): void {
28
+ if (!state[RunUtilⲐ]) {
29
+ const runUtil = state.importFile('@travetto/test/src/execute/util').ident;
30
+ state[RunUtilⲐ] = CoreUtil.createAccess(state.factory, runUtil, RUN_UTIL, 'tryDebugger');
31
+ }
32
+ }
33
+
12
34
  /**
13
35
  * Build source annotation, indicating line ranges
14
36
  * @param state
15
37
  * @param node
16
38
  * @param dec
17
39
  */
18
- static buildAnnotation(state: TransformerState, node: ts.Node, dec: ts.Decorator, expression: ts.CallExpression): ts.Decorator {
40
+ static buildAnnotation(state: TransformerState & AnnotateState, node: ts.Node, dec: ts.Decorator, expression: ts.CallExpression): ts.Decorator {
19
41
  const ogN = (CoreUtil.hasOriginal(node) ? node.original : node);
20
42
  const n = ts.isMethodDeclaration(ogN) ? ogN : undefined;
21
43
 
@@ -40,7 +62,7 @@ export class AnnotationTransformer {
40
62
  }
41
63
 
42
64
  @OnClass('Suite')
43
- static annotateSuiteDetails(state: TransformerState, node: ts.ClassDeclaration, dm?: DecoratorMeta): ts.ClassDeclaration {
65
+ static annotateSuiteDetails(state: TransformerState & AnnotateState, node: ts.ClassDeclaration, dm?: DecoratorMeta): ts.ClassDeclaration {
44
66
  const dec = dm?.dec;
45
67
 
46
68
  if (dec && ts.isCallExpression(dec.expression)) {
@@ -57,7 +79,9 @@ export class AnnotationTransformer {
57
79
  }
58
80
 
59
81
  @OnMethod('Test')
60
- static annotateTestDetails(state: TransformerState, node: ts.MethodDeclaration, dm?: DecoratorMeta): ts.MethodDeclaration {
82
+ static annotateTestDetails(state: TransformerState & AnnotateState, node: ts.MethodDeclaration, dm?: DecoratorMeta): ts.MethodDeclaration {
83
+ this.initState(state);
84
+
61
85
  const dec = dm?.dec;
62
86
 
63
87
  if (dec && ts.isCallExpression(dec.expression)) {
@@ -70,7 +94,11 @@ export class AnnotationTransformer {
70
94
  node.typeParameters,
71
95
  node.parameters,
72
96
  node.type,
73
- node.body
97
+ node.body ? state.factory.updateBlock(node.body, [
98
+ state.factory.createIfStatement(state[RunUtilⲐ]!,
99
+ state.factory.createExpressionStatement(state.factory.createIdentifier('debugger'))),
100
+ ...node.body.statements
101
+ ]) : node.body
74
102
  );
75
103
  }
76
104
  return node;