@travetto/test 4.0.0-rc.6 → 4.0.0-rc.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.
- package/README.md +4 -4
- package/package.json +8 -8
- package/src/assert/check.ts +1 -1
- package/src/assert/util.ts +3 -3
- package/src/decorator/test.ts +2 -7
- package/src/execute/executor.ts +6 -3
- package/src/model/common.ts +9 -5
- package/src/model/suite.ts +6 -2
- package/src/registry/suite.ts +11 -4
- package/support/cli.test_child.ts +2 -2
- package/support/cli.test_watch.ts +1 -3
- package/support/transformer.annotate.ts +1 -4
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#
|
|
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()",
|
|
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()"
|
|
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.
|
|
3
|
+
"version": "4.0.0-rc.7",
|
|
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.
|
|
31
|
-
"@travetto/registry": "^4.0.0-rc.
|
|
32
|
-
"@travetto/terminal": "^4.0.0-rc.
|
|
33
|
-
"@travetto/worker": "^4.0.0-rc.
|
|
34
|
-
"@travetto/yaml": "^4.0.0-rc.
|
|
30
|
+
"@travetto/base": "^4.0.0-rc.7",
|
|
31
|
+
"@travetto/registry": "^4.0.0-rc.7",
|
|
32
|
+
"@travetto/terminal": "^4.0.0-rc.7",
|
|
33
|
+
"@travetto/worker": "^4.0.0-rc.7",
|
|
34
|
+
"@travetto/yaml": "^4.0.0-rc.7"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@travetto/cli": "^4.0.0-rc.
|
|
38
|
-
"@travetto/transformer": "^4.0.0-rc.
|
|
37
|
+
"@travetto/cli": "^4.0.0-rc.7",
|
|
38
|
+
"@travetto/transformer": "^4.0.0-rc.6"
|
|
39
39
|
},
|
|
40
40
|
"peerDependenciesMeta": {
|
|
41
41
|
"@travetto/transformer": {
|
package/src/assert/check.ts
CHANGED
|
@@ -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.
|
|
303
|
+
line = test.lineStart;
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
AssertCapture.add({
|
package/src/assert/util.ts
CHANGED
|
@@ -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.
|
|
92
|
-
line = suite.
|
|
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,
|
|
98
|
+
const coreAll = { ...core, description: msg, lineStart: line, lineEnd: line, lineBodyStart: line };
|
|
99
99
|
|
|
100
100
|
const assert: Assertion = {
|
|
101
101
|
...core,
|
package/src/decorator/test.ts
CHANGED
|
@@ -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
|
}
|
package/src/execute/executor.ts
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
-
|
|
117
|
+
lineStart: test.lineStart,
|
|
118
|
+
lineEnd: test.lineEnd,
|
|
119
|
+
lineBodyStart: test.lineBodyStart,
|
|
117
120
|
file: test.file,
|
|
118
121
|
status: 'skipped',
|
|
119
122
|
assertions: [],
|
package/src/model/common.ts
CHANGED
|
@@ -22,17 +22,21 @@ export interface SuiteCore {
|
|
|
22
22
|
*/
|
|
23
23
|
file: string;
|
|
24
24
|
/**
|
|
25
|
-
* The
|
|
25
|
+
* The first line of the unit
|
|
26
26
|
*/
|
|
27
|
-
|
|
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
|
|
35
|
+
* Test core definition, adds start of body
|
|
32
36
|
*/
|
|
33
37
|
export interface TestCore extends SuiteCore {
|
|
34
38
|
/**
|
|
35
|
-
* The
|
|
39
|
+
* The first line of the unit body
|
|
36
40
|
*/
|
|
37
|
-
|
|
41
|
+
lineBodyStart: number;
|
|
38
42
|
}
|
package/src/model/suite.ts
CHANGED
|
@@ -64,9 +64,13 @@ export interface SuiteResult extends Counts {
|
|
|
64
64
|
*/
|
|
65
65
|
file: string;
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
* Start of the suite
|
|
68
68
|
*/
|
|
69
|
-
|
|
69
|
+
lineStart: number;
|
|
70
|
+
/**
|
|
71
|
+
* End of the suite
|
|
72
|
+
*/
|
|
73
|
+
lineEnd: number;
|
|
70
74
|
/**
|
|
71
75
|
* ALl test results
|
|
72
76
|
*/
|
package/src/registry/suite.ts
CHANGED
|
@@ -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:
|
|
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:
|
|
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 =>
|
|
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 =>
|
|
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
|
-
|
|
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
|
-
|
|
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
|
)
|