@travetto/test 5.0.0-rc.0 → 5.0.0-rc.10

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 (43) hide show
  1. package/README.md +12 -13
  2. package/package.json +8 -8
  3. package/src/assert/capture.ts +5 -4
  4. package/src/assert/check.ts +24 -33
  5. package/src/assert/util.ts +32 -17
  6. package/src/consumer/registry.ts +2 -3
  7. package/src/consumer/{error.ts → serialize.ts} +13 -22
  8. package/src/consumer/types/cumulative.ts +15 -22
  9. package/src/consumer/types/delegating.ts +58 -0
  10. package/src/consumer/types/event.ts +2 -4
  11. package/src/consumer/types/execution.ts +2 -4
  12. package/src/consumer/types/runnable.ts +12 -41
  13. package/src/consumer/types/tap-streamed.ts +9 -6
  14. package/src/consumer/types/tap.ts +5 -5
  15. package/src/consumer/types/xunit.ts +4 -2
  16. package/src/decorator/suite.ts +5 -7
  17. package/src/decorator/test.ts +2 -1
  18. package/src/execute/console.ts +1 -1
  19. package/src/execute/executor.ts +84 -104
  20. package/src/execute/phase.ts +20 -30
  21. package/src/execute/promise.ts +4 -4
  22. package/src/execute/runner.ts +34 -24
  23. package/src/execute/types.ts +12 -10
  24. package/src/execute/util.ts +61 -34
  25. package/src/execute/watcher.ts +34 -36
  26. package/src/fixture.ts +7 -2
  27. package/src/model/common.ts +11 -7
  28. package/src/model/event.ts +9 -5
  29. package/src/model/suite.ts +14 -4
  30. package/src/model/test.ts +30 -4
  31. package/src/registry/suite.ts +42 -39
  32. package/src/trv.d.ts +3 -3
  33. package/src/worker/child.ts +11 -18
  34. package/src/worker/standard.ts +18 -21
  35. package/src/worker/types.ts +13 -10
  36. package/support/cli.test.ts +20 -6
  37. package/support/cli.test_child.ts +1 -1
  38. package/support/cli.test_digest.ts +43 -0
  39. package/support/cli.test_direct.ts +10 -3
  40. package/support/cli.test_watch.ts +1 -1
  41. package/support/transformer.assert.ts +12 -12
  42. package/support/cli.test_count.ts +0 -39
  43. package/support/transformer.annotate.ts +0 -103
@@ -1,9 +1,8 @@
1
- import { Class, ConcreteClass } from '@travetto/base';
2
- import { RuntimeIndex, RuntimeContext } from '@travetto/manifest';
1
+ import { Class, Runtime, classConstruct, describeFunction, asFull } from '@travetto/runtime';
3
2
  import { MetadataRegistry } from '@travetto/registry';
4
3
 
5
4
  import { SuiteConfig } from '../model/suite';
6
- import { TestConfig } from '../model/test';
5
+ import { TestConfig, TestRun } from '../model/test';
7
6
 
8
7
  /**
9
8
  * Test Suite registry
@@ -14,18 +13,18 @@ class $SuiteRegistry extends MetadataRegistry<SuiteConfig, TestConfig> {
14
13
  * Find all valid tests (ignoring abstract)
15
14
  */
16
15
  getValidClasses(): Class[] {
17
- return this.getClasses().filter(c => !RuntimeIndex.getFunctionMetadata(c)?.abstract);
16
+ return this.getClasses().filter(c => !describeFunction(c).abstract);
18
17
  }
19
18
 
20
19
  createPending(cls: Class): Partial<SuiteConfig> {
21
- const meta = RuntimeIndex.getFunctionMetadata(cls)!;
20
+ const lines = describeFunction(cls)?.lines;
22
21
  return {
23
22
  class: cls,
24
- module: RuntimeContext.main.name,
25
23
  classId: cls.Ⲑid,
26
- file: meta.source,
27
- lineStart: meta.lines[0],
28
- lineEnd: meta.lines[1],
24
+ tags: [],
25
+ import: Runtime.getImport(cls),
26
+ lineStart: lines?.[0],
27
+ lineEnd: lines?.[1],
29
28
  tests: [],
30
29
  beforeAll: [],
31
30
  beforeEach: [],
@@ -35,14 +34,14 @@ class $SuiteRegistry extends MetadataRegistry<SuiteConfig, TestConfig> {
35
34
  }
36
35
 
37
36
  override createPendingField(cls: Class, fn: Function): Partial<TestConfig> {
38
- const meta = RuntimeIndex.getFunctionMetadata(cls)!;
39
- const meth = meta.methods![fn.name];
37
+ const lines = describeFunction(cls)?.methods?.[fn.name].lines;
40
38
  return {
41
39
  class: cls,
42
- module: RuntimeContext.main.name,
43
- file: meta.source,
44
- lineStart: meth?.lines[0],
45
- lineEnd: meth?.lines[1],
40
+ tags: [],
41
+ import: Runtime.getImport(cls),
42
+ lineStart: lines?.[0],
43
+ lineEnd: lines?.[1],
44
+ lineBodyStart: lines?.[2],
46
45
  methodName: fn.name
47
46
  };
48
47
  }
@@ -60,8 +59,7 @@ class $SuiteRegistry extends MetadataRegistry<SuiteConfig, TestConfig> {
60
59
  * a full projection of all listeners and tests.
61
60
  */
62
61
  onInstallFinalize<T>(cls: Class<T>): SuiteConfig {
63
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
64
- const config = this.getOrCreatePending(cls) as SuiteConfig;
62
+ const config = asFull(this.getOrCreatePending(cls));
65
63
  const tests = [...this.pendingFields.get(cls.Ⲑid)!.values()];
66
64
 
67
65
  const parent = this.getParentClass(cls);
@@ -74,20 +72,19 @@ class $SuiteRegistry extends MetadataRegistry<SuiteConfig, TestConfig> {
74
72
  config.beforeEach.push(...pConf.beforeEach);
75
73
  tests.push(...[...pConf.tests.values()].map(t => ({
76
74
  ...t,
75
+ sourceImport: pConf.import,
77
76
  class: cls
78
77
  })));
79
78
  }
80
79
 
81
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
82
- config.instance = new (config.class as ConcreteClass)();
83
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
84
- config.tests = tests as TestConfig[];
80
+ config.instance = classConstruct(config.class);
81
+ config.tests = tests!.map(x => asFull(x));
82
+ config.description ||= config.classId;
85
83
 
86
- if (!config.description) {
87
- config.description = config.classId;
88
- }
89
84
  for (const t of config.tests) {
90
85
  t.classId = config.classId;
86
+ t.import = config.import;
87
+ t.tags = [...t.tags!, ...config.tags!];
91
88
  }
92
89
  return config;
93
90
  }
@@ -95,33 +92,39 @@ class $SuiteRegistry extends MetadataRegistry<SuiteConfig, TestConfig> {
95
92
  /**
96
93
  * Get run parameters from provided input
97
94
  */
98
- getRunParams(file: string, clsName?: string, method?: string): { suites: SuiteConfig[] } | { suite: SuiteConfig, test?: TestConfig } {
99
- if (clsName && /^\d+$/.test(clsName)) { // If we only have a line number
100
- const line = parseInt(clsName, 10);
101
- const suites = this.getValidClasses().filter(cls => RuntimeIndex.getFunctionMetadata(cls)!.source === file).map(x => this.get(x)).filter(x => !x.skip);
95
+ getSuiteTests(run: TestRun): { suite: SuiteConfig, tests: TestConfig[] }[] {
96
+ const clsId = run.classId;
97
+ const imp = run.import;
98
+ const methodNames = run.methodNames ?? [];
99
+
100
+ if (clsId && /^\d+$/.test(clsId)) { // If we only have a line number
101
+ const line = parseInt(clsId, 10);
102
+ const suites = this.getValidClasses()
103
+ .filter(cls => Runtime.getImport(cls) === imp)
104
+ .map(x => this.get(x)).filter(x => !x.skip);
102
105
  const suite = suites.find(x => line >= x.lineStart && line <= x.lineEnd);
103
106
 
104
107
  if (suite) {
105
108
  const test = suite.tests.find(x => line >= x.lineStart && line <= x.lineEnd);
106
- return test ? { suite, test } : { suite };
109
+ return test ? [{ suite, tests: [test] }] : [{ suite, tests: suite.tests }];
107
110
  } else {
108
- return { suites };
111
+ return suites.map(x => ({ suite: x, tests: x.tests }));
109
112
  }
110
113
  } else { // Else lookup directly
111
- if (method) {
112
- const cls = this.getValidClasses().find(x => x.name === clsName)!;
114
+ if (methodNames.length) {
115
+ const cls = this.getValidClasses().find(x => x.Ⲑid === clsId)!;
113
116
  const suite = this.get(cls);
114
- const test = suite.tests.find(x => x.methodName === method)!;
115
- return { suite, test };
116
- } else if (clsName) {
117
- const cls = this.getValidClasses().find(x => x.name === clsName)!;
117
+ const tests = suite.tests.filter(x => methodNames.includes(x.methodName))!;
118
+ return [{ suite, tests }];
119
+ } else if (clsId) {
120
+ const cls = this.getValidClasses().find(x => x.Ⲑid === clsId)!;
118
121
  const suite = this.get(cls);
119
- return { suite };
122
+ return [{ suite, tests: suite.tests }];
120
123
  } else {
121
124
  const suites = this.getValidClasses()
122
125
  .map(x => this.get(x))
123
- .filter(x => !RuntimeIndex.getFunctionMetadata(x.class)?.abstract); // Do not run abstract suites
124
- return { suites };
126
+ .filter(x => !describeFunction(x.class).abstract); // Do not run abstract suites
127
+ return suites.map(x => ({ suite: x, tests: x.tests }));
125
128
  }
126
129
  }
127
130
  }
package/src/trv.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { TimeSpan } from '@travetto/base';
1
+ import { TimeSpan } from '@travetto/runtime';
2
2
 
3
3
  declare global {
4
4
  interface TravettoEnv {
@@ -13,8 +13,8 @@ declare global {
13
13
  */
14
14
  TRV_TEST_TIMEOUT: TimeSpan | number;
15
15
  /**
16
- * Should the test break on the first line of debugging
16
+ * The tags to include or exclude during testing
17
17
  */
18
- TRV_TEST_BREAK_ENTRY: boolean;
18
+ TRV_TEST_TAGS: string[];
19
19
  }
20
20
  }
@@ -1,19 +1,19 @@
1
1
  import { createWriteStream } from 'node:fs';
2
2
 
3
- import { RuntimeContext } from '@travetto/manifest';
4
- import { ConsoleManager, Env, Util } from '@travetto/base';
3
+ import { ConsoleManager, Env, Util, Runtime } from '@travetto/runtime';
5
4
  import { ChildCommChannel } from '@travetto/worker';
6
5
 
7
- import { ErrorUtil } from '../consumer/error';
6
+ import { SerializeUtil } from '../consumer/serialize';
8
7
  import { RunnerUtil } from '../execute/util';
9
8
  import { Runner } from '../execute/runner';
10
- import { Events, RunEvent } from './types';
9
+ import { Events } from './types';
10
+ import { TestRun } from '../model/test';
11
11
 
12
12
  /**
13
13
  * Child Worker for the Test Runner. Receives events as commands
14
14
  * to run specific tests
15
15
  */
16
- export class TestChildWorker extends ChildCommChannel<RunEvent> {
16
+ export class TestChildWorker extends ChildCommChannel<TestRun> {
17
17
 
18
18
  #done = Util.resolvablePromise();
19
19
 
@@ -26,7 +26,7 @@ export class TestChildWorker extends ChildCommChannel<RunEvent> {
26
26
  throw err;
27
27
  }
28
28
  // Mark as errored out
29
- this.send(type, { error: ErrorUtil.serializeError(err) });
29
+ this.send(type, { error: SerializeUtil.serializeError(err) });
30
30
  }
31
31
  }
32
32
 
@@ -35,7 +35,7 @@ export class TestChildWorker extends ChildCommChannel<RunEvent> {
35
35
  */
36
36
  async activate(): Promise<void> {
37
37
  if (/\b@travetto[/]test\b/.test(Env.DEBUG.val ?? '')) {
38
- const file = RuntimeContext.toolPath(`test-worker.${process.pid}.log`);
38
+ const file = Runtime.toolPath(`test-worker.${process.pid}.log`);
39
39
  const stdout = createWriteStream(file, { flags: 'a' });
40
40
  const c = new console.Console({ stdout, inspectOptions: { depth: 4, colors: false } });
41
41
  ConsoleManager.set({ log: (ev) => c[ev.level](process.pid, ...ev.args) });
@@ -57,7 +57,7 @@ export class TestChildWorker extends ChildCommChannel<RunEvent> {
57
57
  /**
58
58
  * When we receive a command from the parent
59
59
  */
60
- async onCommand(event: RunEvent & { type: string }): Promise<boolean> {
60
+ async onCommand(event: TestRun & { type: string }): Promise<boolean> {
61
61
  console.debug('on message', { ...event });
62
62
 
63
63
  if (event.type === Events.INIT) { // On request to init, start initialization
@@ -77,18 +77,11 @@ export class TestChildWorker extends ChildCommChannel<RunEvent> {
77
77
  /**
78
78
  * Run a specific test/suite
79
79
  */
80
- async onRunCommand(event: RunEvent): Promise<void> {
81
- console.debug('Run');
82
-
83
- console.debug('Running', { file: event.file });
80
+ async onRunCommand(run: TestRun): Promise<void> {
81
+ console.debug('Running', { import: run.import });
84
82
 
85
83
  try {
86
- await new Runner({
87
- format: 'exec',
88
- mode: 'single',
89
- args: [event.file!, event.class!, event.method!],
90
- concurrency: 1
91
- }).run();
84
+ await new Runner({ format: 'exec', target: run }).run();
92
85
  } finally {
93
86
  this.#done.resolve();
94
87
  }
@@ -1,39 +1,36 @@
1
1
  import { fork } from 'node:child_process';
2
2
 
3
- import { RuntimeIndex } from '@travetto/manifest';
4
- import { Env } from '@travetto/base';
3
+ import { Env, RuntimeIndex } from '@travetto/runtime';
5
4
  import { ParentCommChannel } from '@travetto/worker';
6
5
 
7
- import { Events, RunEvent } from './types';
6
+ import { Events, TestLogEvent } from './types';
8
7
  import { TestConsumer } from '../consumer/types';
9
- import { ErrorUtil } from '../consumer/error';
8
+ import { SerializeUtil } from '../consumer/serialize';
10
9
  import { TestEvent } from '../model/event';
10
+ import { TestRun } from '../model/test';
11
+
12
+ const log = (message: string): void => {
13
+ process.send?.({ type: 'log', message } satisfies TestLogEvent);
14
+ };
11
15
 
12
16
  /**
13
17
  * Produce a handler for the child worker
14
18
  */
15
- export async function buildStandardTestManager(consumer: TestConsumer, file: string): Promise<void> {
16
- process.send?.({ type: 'log', message: `Worker Executing ${file}` });
17
-
18
- let event: RunEvent;
19
- if (file.includes('#')) {
20
- const [f, cls, method] = file.split('#');
21
- event = { file: f, class: cls, method };
22
- } else {
23
- event = { file };
24
- }
19
+ export async function buildStandardTestManager(consumer: TestConsumer, run: TestRun): Promise<void> {
20
+ log(`Worker Input ${JSON.stringify(run)}`);
21
+ log(`Worker Executing ${run.import}`);
25
22
 
26
- const { module } = RuntimeIndex.getEntry(event.file!)!;
27
- const cwd = RuntimeIndex.getModule(module)!.sourcePath;
23
+ const { module } = RuntimeIndex.getFromImport(run.import)!;
24
+ const suiteMod = RuntimeIndex.getModule(module)!;
28
25
 
29
26
  const channel = new ParentCommChannel<TestEvent & { error?: Error }>(
30
27
  fork(
31
28
  RuntimeIndex.resolveFileImport('@travetto/cli/support/entry.trv'), ['test:child'],
32
29
  {
33
- cwd,
30
+ cwd: suiteMod.sourcePath,
34
31
  env: {
35
32
  ...process.env,
36
- ...Env.TRV_MANIFEST.export(RuntimeIndex.getModule(module)!.outputPath),
33
+ ...Env.TRV_MANIFEST.export(suiteMod.outputPath),
37
34
  ...Env.TRV_QUIET.export(true)
38
35
  },
39
36
  stdio: ['ignore', 'ignore', 2, 'ipc']
@@ -56,7 +53,7 @@ export async function buildStandardTestManager(consumer: TestConsumer, file: str
56
53
  // Listen for child to complete
57
54
  const complete = channel.once(Events.RUN_COMPLETE);
58
55
  // Start test
59
- channel.send(Events.RUN, event);
56
+ channel.send(Events.RUN, run);
60
57
 
61
58
  // Wait for complete
62
59
  const { error } = await complete;
@@ -64,10 +61,10 @@ export async function buildStandardTestManager(consumer: TestConsumer, file: str
64
61
  // Kill on complete
65
62
  await channel.destroy();
66
63
 
67
- process.send?.({ type: 'log', message: `Worker Finished ${file}` });
64
+ log(`Worker Finished ${run.import}`);
68
65
 
69
66
  // If we received an error, throw it
70
67
  if (error) {
71
- throw ErrorUtil.deserializeError(error);
68
+ throw SerializeUtil.deserializeError(error);
72
69
  }
73
70
  }
@@ -1,12 +1,5 @@
1
- /**
2
- * Test Run Event
3
- */
4
- export type RunEvent = {
5
- file?: string;
6
- error?: unknown;
7
- class?: string;
8
- method?: string;
9
- };
1
+ import { TestEvent } from '../model/event';
2
+ import { TestRun } from '../model/test';
10
3
 
11
4
  /**
12
5
  * Test Run Event Keys
@@ -17,4 +10,14 @@ export const Events = {
17
10
  INIT: 'init',
18
11
  INIT_COMPLETE: 'initComplete',
19
12
  READY: 'ready'
20
- };
13
+ };
14
+
15
+ export type TestRemovedEvent = { type: 'removeTest', method?: string } & TestRun;
16
+ export type TestReadyEvent = { type: 'ready' };
17
+ export type TestLogEvent = { type: 'log', message: string };
18
+
19
+ export type TestWatchEvent =
20
+ TestEvent |
21
+ TestRemovedEvent |
22
+ TestReadyEvent |
23
+ TestLogEvent;
@@ -2,7 +2,7 @@ import { EventEmitter } from 'node:events';
2
2
  import fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
 
5
- import { Env } from '@travetto/base';
5
+ import { Env } from '@travetto/runtime';
6
6
  import { CliCommandShape, CliCommand, CliValidationError } from '@travetto/cli';
7
7
  import { WorkPool } from '@travetto/worker';
8
8
  import { Max, Min } from '@travetto/schema';
@@ -21,6 +21,11 @@ export class TestCommand implements CliCommandShape {
21
21
  concurrency: number = WorkPool.DEFAULT_SIZE;
22
22
  /** Test run mode */
23
23
  mode: TestMode = 'standard';
24
+ /**
25
+ * Tags to target or exclude
26
+ * @alias env.TRV_TEST_TAGS
27
+ */
28
+ tags?: string[];
24
29
 
25
30
  preMain(): void {
26
31
  EventEmitter.defaultMaxListeners = 1000;
@@ -39,7 +44,7 @@ export class TestCommand implements CliCommandShape {
39
44
  return (await this.isFirstFile(first)) && rest.length === 0 ? 'single' : this.mode;
40
45
  }
41
46
 
42
- async validate(first: string = 'test/.*', rest: string[]): Promise<CliValidationError | undefined> {
47
+ async validate(first: string = '**/*', rest: string[]): Promise<CliValidationError | undefined> {
43
48
 
44
49
  const mode = await this.resolvedMode(first, rest);
45
50
 
@@ -48,14 +53,23 @@ export class TestCommand implements CliCommandShape {
48
53
  }
49
54
  }
50
55
 
51
- async main(first: string = 'test/.*', regexes: string[] = []): Promise<void> {
56
+ async main(first: string = '**/*', globs: string[] = []): Promise<void> {
52
57
  const { runTests } = await import('./bin/run');
53
58
 
59
+ const isFirst = await this.isFirstFile(first);
60
+ const isSingle = this.mode === 'single' || (isFirst && globs.length === 0);
61
+
54
62
  return runTests({
55
- args: [first, ...regexes],
56
- mode: await this.resolvedMode(first, regexes),
57
63
  concurrency: this.concurrency,
58
- format: this.format
64
+ format: this.format,
65
+ tags: this.tags,
66
+ target: isSingle ?
67
+ {
68
+ import: first,
69
+ classId: globs[0],
70
+ methodNames: globs.slice(1),
71
+ } :
72
+ { globs: [first, ...globs], }
59
73
  });
60
74
  }
61
75
  }
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
 
3
- import { Env } from '@travetto/base';
3
+ import { Env } from '@travetto/runtime';
4
4
  import { CliCommand } from '@travetto/cli';
5
5
 
6
6
  /** Test child worker target */
@@ -0,0 +1,43 @@
1
+ import { CliCommand } from '@travetto/cli';
2
+ import { Env, Runtime, describeFunction } from '@travetto/runtime';
3
+
4
+ import { SuiteRegistry } from '../src/registry/suite';
5
+ import { RunnerUtil } from '../src/execute/util';
6
+
7
+ @CliCommand({ hidden: true })
8
+ export class TestDigestCommand {
9
+
10
+ output: 'json' | 'text' = 'text';
11
+
12
+ preMain(): void {
13
+ Env.TRV_ROLE.set('test');
14
+ Env.DEBUG.set(false);
15
+ }
16
+
17
+ async main(globs: string[] = ['**/*.ts']) {
18
+ // Load all tests
19
+ for await (const imp of await RunnerUtil.getTestImports(globs)) {
20
+ try {
21
+ await Runtime.importFrom(imp);
22
+ } catch (err) {
23
+ console.error('Failed to import', imp, err);
24
+ }
25
+ }
26
+
27
+ await SuiteRegistry.init();
28
+
29
+ const suites = SuiteRegistry.getClasses();
30
+ const all = suites
31
+ .map(c => SuiteRegistry.get(c))
32
+ .filter(c => !describeFunction(c.class).abstract)
33
+ .flatMap(c => c.tests);
34
+
35
+ if (this.output === 'json') {
36
+ console.log(JSON.stringify(all));
37
+ } else {
38
+ for (const item of all) {
39
+ console.log(`${item.classId}#${item.methodName}`, item.tags?.join('|') ?? '');
40
+ }
41
+ }
42
+ }
43
+ }
@@ -1,4 +1,4 @@
1
- import { Env } from '@travetto/base';
1
+ import { Env, RuntimeIndex } from '@travetto/runtime';
2
2
  import { CliCommand } from '@travetto/cli';
3
3
 
4
4
  import { runTests } from './bin/run';
@@ -17,7 +17,14 @@ export class TestDirectCommand {
17
17
  Env.TRV_LOG_TIME.clear();
18
18
  }
19
19
 
20
- main(file: string, args: string[]): Promise<void> {
21
- return runTests({ args: [file, ...args], format: this.format, mode: 'single', concurrency: 1 });
20
+ main(importOrFile: string, clsId?: string, methodsNames: string[] = []): Promise<void> {
21
+ return runTests({
22
+ format: this.format,
23
+ target: {
24
+ import: importOrFile,
25
+ classId: clsId,
26
+ methodNames: methodsNames,
27
+ }
28
+ });
22
29
  }
23
30
  }
@@ -1,4 +1,4 @@
1
- import { Env } from '@travetto/base';
1
+ import { Env } from '@travetto/runtime';
2
2
  import { CliCommand, CliUtil } from '@travetto/cli';
3
3
 
4
4
  import { TestFormat } from './bin/types';
@@ -93,7 +93,7 @@ export class AssertTransformer {
93
93
  /**
94
94
  * Resolves optoken to syntax kind. Relies on `ts`
95
95
  */
96
- static lookupOpToken(key: number): string {
96
+ static lookupOpToken(key: number): string | undefined {
97
97
  if (OP_TOKEN_TO_NAME.size === 0) {
98
98
  Object.keys(ts.SyntaxKind)
99
99
  .filter(x => !/^\d+$/.test(x))
@@ -106,7 +106,7 @@ export class AssertTransformer {
106
106
  if (name in OPTOKEN_ASSERT) {
107
107
  return OPTOKEN_ASSERT[name];
108
108
  } else {
109
- throw new Error(`Unknown optoken: ${name}:${key}`);
109
+ return;
110
110
  }
111
111
  }
112
112
 
@@ -137,12 +137,12 @@ export class AssertTransformer {
137
137
  */
138
138
  static initState(state: TransformerState & AssertState): void {
139
139
  if (!state[AssertⲐ]) {
140
- const assrt = state.importFile('@travetto/test/src/assert/check').ident;
140
+ const asrt = state.importFile('@travetto/test/src/assert/check').ident;
141
141
  state[AssertⲐ] = {
142
- assert: assrt,
143
- assertCheck: CoreUtil.createAccess(state.factory, assrt, ASSERT_UTIL, 'check'),
144
- checkThrow: CoreUtil.createAccess(state.factory, assrt, ASSERT_UTIL, 'checkThrow'),
145
- checkThrowAsync: CoreUtil.createAccess(state.factory, assrt, ASSERT_UTIL, 'checkThrowAsync'),
142
+ assert: asrt,
143
+ assertCheck: CoreUtil.createAccess(state.factory, asrt, ASSERT_UTIL, 'check'),
144
+ checkThrow: CoreUtil.createAccess(state.factory, asrt, ASSERT_UTIL, 'checkThrow'),
145
+ checkThrowAsync: CoreUtil.createAccess(state.factory, asrt, ASSERT_UTIL, 'checkThrowAsync'),
146
146
  };
147
147
  }
148
148
  }
@@ -153,13 +153,13 @@ export class AssertTransformer {
153
153
  static doAssert(state: TransformerState & AssertState, node: ts.CallExpression, cmd: Command): ts.CallExpression {
154
154
  this.initState(state);
155
155
 
156
- const first = CoreUtil.getArgument<ts.CallExpression>(node);
156
+ const first = CoreUtil.firstArgument(node);
157
157
  const firstText = first!.getText();
158
158
 
159
159
  cmd.args = cmd.args.filter(x => x !== undefined && x !== null);
160
160
  const check = state.factory.createCallExpression(state[AssertⲐ]!.assertCheck, undefined, state.factory.createNodeArray([
161
161
  state.fromLiteral({
162
- file: state.getFilenameIdentifier(),
162
+ module: state.getModuleIdentifier(),
163
163
  line: state.fromLiteral(ts.getLineAndCharacterOfPosition(state.source, node.getStart()).line + 1),
164
164
  text: state.fromLiteral(firstText),
165
165
  operator: state.fromLiteral(cmd.fn)
@@ -175,8 +175,8 @@ export class AssertTransformer {
175
175
  * Convert `assert.(throws|rejects|doesNotThrow|doesNotReject)` to the appropriate structure
176
176
  */
177
177
  static doThrows(state: TransformerState & AssertState, node: ts.CallExpression, key: string, args: ts.Expression[]): ts.CallExpression {
178
- const first = CoreUtil.getArgument<ts.CallExpression>(node);
179
- const firstText = first!.getText();
178
+ const first = CoreUtil.firstArgument(node)!;
179
+ const firstText = first.getText();
180
180
 
181
181
  this.initState(state);
182
182
  return state.factory.createCallExpression(
@@ -184,7 +184,7 @@ export class AssertTransformer {
184
184
  undefined,
185
185
  state.factory.createNodeArray([
186
186
  state.fromLiteral({
187
- file: state.getFilenameIdentifier(),
187
+ module: state.getModuleIdentifier(),
188
188
  line: state.fromLiteral(ts.getLineAndCharacterOfPosition(state.source, node.getStart()).line + 1),
189
189
  text: state.fromLiteral(`${key} ${firstText}`),
190
190
  operator: state.fromLiteral(`${key}`)
@@ -1,39 +0,0 @@
1
- import { CliCommand } from '@travetto/cli';
2
- import { RuntimeIndex } from '@travetto/manifest';
3
- import { Env } from '@travetto/base';
4
-
5
- import { SuiteRegistry } from '../src/registry/suite';
6
- import { RunnerUtil } from '../src/execute/util';
7
-
8
- @CliCommand({ hidden: true })
9
- export class TestCountCommand {
10
-
11
- preMain(): void {
12
- Env.TRV_ROLE.set('test');
13
- Env.DEBUG.set(false);
14
- }
15
-
16
- async main(patterns: string[]) {
17
- const regexes = patterns.map(x => new RegExp(x));
18
- const files = await RunnerUtil.getTestFiles(regexes);
19
-
20
- // Load all tests
21
- for (const file of files) {
22
- try {
23
- await import(file.import);
24
- } catch (err) {
25
- console.error('Failed to import', file.sourceFile, err);
26
- }
27
- }
28
-
29
- await SuiteRegistry.init();
30
-
31
- const suites = SuiteRegistry.getClasses();
32
- const total = suites
33
- .map(c => SuiteRegistry.get(c))
34
- .filter(c => !RuntimeIndex.getFunctionMetadata(c.class)?.abstract)
35
- .reduce((acc, c) => acc + (c.tests?.length ?? 0), 0);
36
-
37
- console.log(total);
38
- }
39
- }