@travetto/test 4.0.0-rc.6 → 4.0.0-rc.8

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
@@ -21,7 +21,7 @@ This module provides unit testing functionality that integrates with the framewo
21
21
  **Note**: All tests should be under the `test/.*` folders. The pattern for tests is defined as a regex and not standard globbing.
22
22
 
23
23
  ## Definition
24
- A test suite is a collection of individual tests. All test suites are classes with the [@Suite](https://github.com/travetto/travetto/tree/main/module/test/src/decorator/suite.ts#L14) decorator. Tests are defined as methods on the suite class, using the [@Test](https://github.com/travetto/travetto/tree/main/module/test/src/decorator/test.ts#L20) decorator. All tests intrinsically support `async`/`await`.
24
+ A test suite is a collection of individual tests. All test suites are classes with the [@Suite](https://github.com/travetto/travetto/tree/main/module/test/src/decorator/suite.ts#L14) decorator. Tests are defined as methods on the suite class, using the [@Test](https://github.com/travetto/travetto/tree/main/module/test/src/decorator/test.ts#L19) decorator. All tests intrinsically support `async`/`await`.
25
25
 
26
26
  A simple example would be:
27
27
 
@@ -87,7 +87,7 @@ var ᚕf = "@travetto/test/doc/assert-example.js";
87
87
  const node_assert_1 = tslib_1.__importDefault(require("node:assert"));
88
88
  const test_1 = require("@travetto/test");
89
89
  let SimpleTest = class SimpleTest {
90
- static Ⲑinit = Ⲑ_runtime_1.RuntimeIndex.registerFunction(SimpleTest, ᚕf, 1887908328, { test: { hash: 102834457 } }, false, false);
90
+ static Ⲑinit = Ⲑ_runtime_1.RuntimeIndex.registerFunction(SimpleTest, ᚕf, { hash: 1887908328, lines: [5, 12] }, { test: { hash: 102834457, lines: [8, 11] } }, false, false);
91
91
  async test() {
92
92
  if (Ⲑ_util_1.RunnerUtil.tryDebugger)
93
93
  debugger;
@@ -95,11 +95,11 @@ let SimpleTest = class SimpleTest {
95
95
  }
96
96
  };
97
97
  tslib_1.__decorate([
98
- (0, test_1.Test)({ ident: "@Test()", lines: { start: 8, end: 11, codeStart: 10 } })
98
+ (0, test_1.Test)({ ident: "@Test()", lineBodyStart: 10 })
99
99
  ], SimpleTest.prototype, "test", null);
100
100
  SimpleTest = tslib_1.__decorate([
101
101
  Ⲑ_decorator_1.Register(),
102
- (0, test_1.Suite)({ ident: "@Suite()", lines: { start: 5, end: 12 } })
102
+ (0, test_1.Suite)({ ident: "@Suite()" })
103
103
  ], SimpleTest);
104
104
  ```
105
105
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/test",
3
- "version": "4.0.0-rc.6",
3
+ "version": "4.0.0-rc.8",
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": "^4.0.0-rc.6",
31
- "@travetto/registry": "^4.0.0-rc.6",
32
- "@travetto/terminal": "^4.0.0-rc.6",
33
- "@travetto/worker": "^4.0.0-rc.6",
34
- "@travetto/yaml": "^4.0.0-rc.6"
30
+ "@travetto/base": "^4.0.0-rc.8",
31
+ "@travetto/registry": "^4.0.0-rc.8",
32
+ "@travetto/terminal": "^4.0.0-rc.8",
33
+ "@travetto/worker": "^4.0.0-rc.8",
34
+ "@travetto/yaml": "^4.0.0-rc.8"
35
35
  },
36
36
  "peerDependencies": {
37
- "@travetto/cli": "^4.0.0-rc.6",
38
- "@travetto/transformer": "^4.0.0-rc.5"
37
+ "@travetto/cli": "^4.0.0-rc.8",
38
+ "@travetto/transformer": "^4.0.0-rc.7"
39
39
  },
40
40
  "peerDependenciesMeta": {
41
41
  "@travetto/transformer": {
@@ -300,7 +300,7 @@ export class AssertCheck {
300
300
  static checkUnhandled(test: TestConfig, err: Error | assert.AssertionError): void {
301
301
  let line = AssertUtil.getPositionOfError(err, test.file).line;
302
302
  if (line === 1) {
303
- line = test.lines.start;
303
+ line = test.lineStart;
304
304
  }
305
305
 
306
306
  AssertCapture.add({
@@ -88,14 +88,14 @@ export class AssertUtil {
88
88
  const { file, ...pos } = this.getPositionOfError(error, suite.file);
89
89
  let line = pos.line;
90
90
 
91
- if (line === 1 && suite.lines) {
92
- line = suite.lines.start;
91
+ if (line === 1 && suite.lineStart) {
92
+ line = suite.lineStart;
93
93
  }
94
94
 
95
95
  const msg = error.message.split(/\n/)[0];
96
96
 
97
97
  const core = { file, classId: suite.classId, methodName, module: RuntimeContext.main.name };
98
- const coreAll = { ...core, description: msg, lines: { start: line, end: line, codeStart: line } };
98
+ const coreAll = { ...core, description: msg, lineStart: line, lineEnd: line, lineBodyStart: line };
99
99
 
100
100
  const assert: Assertion = {
101
101
  ...core,
@@ -1,5 +1,4 @@
1
1
  import { ClassInstance } from '@travetto/base';
2
- import { RuntimeIndex } from '@travetto/manifest';
3
2
 
4
3
  import { SuiteRegistry } from '../registry/suite';
5
4
  import { TestConfig } from '../model/test';
@@ -26,15 +25,11 @@ export function Test(description?: string | Partial<TestConfig>, ...rest: Partia
26
25
  Object.assign(extra, description).description :
27
26
  description;
28
27
 
29
- for (const r of rest) {
28
+ for (const r of [...rest, { description: descriptionString }]) {
30
29
  Object.assign(extra, r);
31
30
  }
32
31
  return (inst: ClassInstance, prop: string | symbol, descriptor: PropertyDescriptor) => {
33
- SuiteRegistry.registerField(inst.constructor, descriptor.value, {
34
- ...extra,
35
- file: RuntimeIndex.getFunctionMetadata(inst.constructor)!.source,
36
- description: descriptionString
37
- });
32
+ SuiteRegistry.registerField(inst.constructor, descriptor.value, extra);
38
33
  return descriptor;
39
34
  };
40
35
  }
@@ -18,7 +18,7 @@ export class ConsoleCapture {
18
18
  static onLog({ level, args }: ConsoleEvent): void {
19
19
  (this.out[level] = this.out[level] ?? []).push(
20
20
  args
21
- .map((x => typeof x === 'string' ? x : util.inspect(x, false, 4)))
21
+ .map((x => typeof x === 'string' ? x : util.inspect(x, false, 5)))
22
22
  .join(' ')
23
23
  );
24
24
  }
@@ -71,7 +71,7 @@ export class TestExecutor {
71
71
  const name = path.basename(file);
72
72
  const classId = RuntimeIndex.getId(file, name);
73
73
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
74
- const suite = { class: { name }, classId, duration: 0, lines: { start: 1, end: 1 }, file, } as SuiteConfig & SuiteResult;
74
+ const suite = { class: { name }, classId, duration: 0, lineStart: 1, lineEnd: 1, file, } as SuiteConfig & SuiteResult;
75
75
  err.message = err.message.replaceAll(RuntimeIndex.mainModule.sourcePath, '.');
76
76
  const res = AssertUtil.generateSuiteError(suite, 'require', err);
77
77
  consumer.onEvent({ type: 'suite', phase: 'before', suite });
@@ -90,7 +90,8 @@ export class TestExecutor {
90
90
  failed: 0,
91
91
  skipped: 0,
92
92
  total: 0,
93
- lines: { ...suite.lines },
93
+ lineStart: suite.lineStart,
94
+ lineEnd: suite.lineEnd,
94
95
  file: suite.file,
95
96
  classId: suite.classId,
96
97
  duration: 0,
@@ -113,7 +114,9 @@ export class TestExecutor {
113
114
  module: RuntimeContext.main.name,
114
115
  description: test.description,
115
116
  classId: test.classId,
116
- lines: { ...test.lines },
117
+ lineStart: test.lineStart,
118
+ lineEnd: test.lineEnd,
119
+ lineBodyStart: test.lineBodyStart,
117
120
  file: test.file,
118
121
  status: 'skipped',
119
122
  assertions: [],
@@ -22,17 +22,21 @@ export interface SuiteCore {
22
22
  */
23
23
  file: string;
24
24
  /**
25
- * The lines within the file the tests overlaps
25
+ * The first line of the unit
26
26
  */
27
- lines: { start: number, end: number };
27
+ lineStart: number;
28
+ /**
29
+ * The last line of the unit
30
+ */
31
+ lineEnd: number;
28
32
  }
29
33
 
30
34
  /**
31
- * Test core definition, adds codeStart
35
+ * Test core definition, adds start of body
32
36
  */
33
37
  export interface TestCore extends SuiteCore {
34
38
  /**
35
- * The lines within the file the tests overlaps
39
+ * The first line of the unit body
36
40
  */
37
- lines: { start: number, end: number, codeStart: number };
41
+ lineBodyStart: number;
38
42
  }
@@ -64,9 +64,13 @@ export interface SuiteResult extends Counts {
64
64
  */
65
65
  file: string;
66
66
  /**
67
- * Lines of the suite
67
+ * Start of the suite
68
68
  */
69
- lines: { start: number, end: number };
69
+ lineStart: number;
70
+ /**
71
+ * End of the suite
72
+ */
73
+ lineEnd: number;
70
74
  /**
71
75
  * ALl test results
72
76
  */
@@ -18,11 +18,14 @@ class $SuiteRegistry extends MetadataRegistry<SuiteConfig, TestConfig> {
18
18
  }
19
19
 
20
20
  createPending(cls: Class): Partial<SuiteConfig> {
21
+ const meta = RuntimeIndex.getFunctionMetadata(cls)!;
21
22
  return {
22
23
  class: cls,
23
24
  module: RuntimeContext.main.name,
24
25
  classId: cls.Ⲑid,
25
- file: RuntimeIndex.getFunctionMetadata(cls)!.source,
26
+ file: meta.source,
27
+ lineStart: meta.lines[0],
28
+ lineEnd: meta.lines[1],
26
29
  tests: [],
27
30
  beforeAll: [],
28
31
  beforeEach: [],
@@ -32,10 +35,14 @@ class $SuiteRegistry extends MetadataRegistry<SuiteConfig, TestConfig> {
32
35
  }
33
36
 
34
37
  override createPendingField(cls: Class, fn: Function): Partial<TestConfig> {
38
+ const meta = RuntimeIndex.getFunctionMetadata(cls)!;
39
+ const meth = meta.methods![fn.name];
35
40
  return {
36
41
  class: cls,
37
42
  module: RuntimeContext.main.name,
38
- file: RuntimeIndex.getFunctionMetadata(cls)!.source,
43
+ file: meta.source,
44
+ lineStart: meth?.lines[0],
45
+ lineEnd: meth?.lines[1],
39
46
  methodName: fn.name
40
47
  };
41
48
  }
@@ -92,10 +99,10 @@ class $SuiteRegistry extends MetadataRegistry<SuiteConfig, TestConfig> {
92
99
  if (clsName && /^\d+$/.test(clsName)) { // If we only have a line number
93
100
  const line = parseInt(clsName, 10);
94
101
  const suites = this.getValidClasses().filter(cls => RuntimeIndex.getFunctionMetadata(cls)!.source === file).map(x => this.get(x)).filter(x => !x.skip);
95
- const suite = suites.find(x => x.lines && (line >= x.lines.start && line <= x.lines.end));
102
+ const suite = suites.find(x => line >= x.lineStart && line <= x.lineEnd);
96
103
 
97
104
  if (suite) {
98
- const test = suite.tests.find(x => x.lines && (line >= x.lines.start && line <= x.lines.end));
105
+ const test = suite.tests.find(x => line >= x.lineStart && line <= x.lineEnd);
99
106
  return test ? { suite, test } : { suite };
100
107
  } else {
101
108
  return { suites };
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
 
3
- import { Env } from '@travetto/base';
3
+ import { Env, ExecUtil } from '@travetto/base';
4
4
  import { CliCommand } from '@travetto/cli';
5
5
 
6
6
  /** Test child worker target */
@@ -17,7 +17,7 @@ export class TestChildWorkerCommand {
17
17
  }
18
18
 
19
19
  async main(): Promise<void> {
20
- process.once('disconnect', () => process.exit());
20
+ ExecUtil.exitOnDisconnect();
21
21
  const { TestChildWorker } = await import('../src/worker/child.js');
22
22
  return new TestChildWorker().activate();
23
23
  }
@@ -18,12 +18,10 @@ export class TestWatcherCommand {
18
18
  }
19
19
 
20
20
  async main(): Promise<void> {
21
- if (await CliUtil.runWithRestart(this)) {
21
+ if (await CliUtil.runWithRestart(this, true)) {
22
22
  return;
23
23
  }
24
24
 
25
- process.once('disconnect', () => process.exit());
26
-
27
25
  try {
28
26
  const { TestWatcher } = await import('../src/execute/watcher.js');
29
27
  await TestWatcher.watch(this.format, this.mode === 'all');
@@ -50,10 +50,7 @@ export class AnnotationTransformer {
50
50
  ...(expression.arguments ?? []),
51
51
  state.fromLiteral({
52
52
  ident: `@${DecoratorUtil.getDecoratorIdent(dec).text}()`,
53
- lines: {
54
- ...CoreUtil.getRangeOf(state.source, node),
55
- codeStart: CoreUtil.getRangeOf(state.source, n?.body?.statements[0])?.start
56
- }
53
+ lineBodyStart: CoreUtil.getRangeOf(state.source, n?.body?.statements[0])?.[0]
57
54
  })
58
55
  ]
59
56
  )