@travetto/test 6.0.0-rc.2 → 6.0.0
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 +1 -0
- package/package.json +7 -7
- package/src/assert/check.ts +3 -2
- package/src/assert/util.ts +1 -1
- package/src/consumer/types/tap.ts +7 -3
- package/src/consumer/types/xunit.ts +7 -2
- package/src/execute/console.ts +13 -10
- package/src/execute/executor.ts +2 -2
- package/src/model/test.ts +4 -2
package/README.md
CHANGED
|
@@ -122,6 +122,7 @@ The equivalences for all of the [assert](https://nodejs.org/api/assert.html) ope
|
|
|
122
122
|
* `assert(a instanceof b)` as `assert.instanceOf(a, b)`
|
|
123
123
|
* `assert(a.includes(b))` as `assert.ok(a.includes(b))`
|
|
124
124
|
* `assert(/a/.test(b))` as `assert.ok(/a/.test(b))`
|
|
125
|
+
|
|
125
126
|
In addition to the standard operations, there is support for throwing/rejecting errors (or the inverse). This is useful for testing error states or ensuring errors do not occur.
|
|
126
127
|
|
|
127
128
|
### Throws
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/test",
|
|
3
|
-
"version": "6.0.0
|
|
3
|
+
"version": "6.0.0",
|
|
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/registry": "^6.0.0
|
|
31
|
-
"@travetto/runtime": "^6.0.0
|
|
32
|
-
"@travetto/terminal": "^6.0.0
|
|
33
|
-
"@travetto/worker": "^6.0.0
|
|
30
|
+
"@travetto/registry": "^6.0.0",
|
|
31
|
+
"@travetto/runtime": "^6.0.0",
|
|
32
|
+
"@travetto/terminal": "^6.0.0",
|
|
33
|
+
"@travetto/worker": "^6.0.0",
|
|
34
34
|
"yaml": "^2.7.1"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@travetto/cli": "^6.0.0
|
|
38
|
-
"@travetto/transformer": "^6.0.0
|
|
37
|
+
"@travetto/cli": "^6.0.0",
|
|
38
|
+
"@travetto/transformer": "^6.0.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependenciesMeta": {
|
|
41
41
|
"@travetto/transformer": {
|
package/src/assert/check.ts
CHANGED
|
@@ -156,10 +156,11 @@ export class AssertCheck {
|
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
158
|
} else if (typeof shouldThrow === 'function') {
|
|
159
|
+
const target = shouldThrow.name ? `("${shouldThrow.name}")` : '';
|
|
159
160
|
try {
|
|
160
161
|
const res = shouldThrow(err);
|
|
161
162
|
if (res === false) {
|
|
162
|
-
return new assert.AssertionError({ message: `Checking
|
|
163
|
+
return new assert.AssertionError({ message: `Checking function ${target} indicated an invalid error`, actual: err });
|
|
163
164
|
} else if (typeof res === 'string') {
|
|
164
165
|
return new assert.AssertionError({ message: res, actual: err });
|
|
165
166
|
}
|
|
@@ -167,7 +168,7 @@ export class AssertCheck {
|
|
|
167
168
|
if (checkErr instanceof assert.AssertionError) {
|
|
168
169
|
return checkErr;
|
|
169
170
|
} else {
|
|
170
|
-
return new assert.AssertionError({ message: `Checking
|
|
171
|
+
return new assert.AssertionError({ message: `Checking function ${target} threw an error`, actual: checkErr });
|
|
171
172
|
}
|
|
172
173
|
}
|
|
173
174
|
}
|
package/src/assert/util.ts
CHANGED
|
@@ -105,7 +105,7 @@ export class AssertUtil {
|
|
|
105
105
|
};
|
|
106
106
|
const testResult: TestResult = {
|
|
107
107
|
...coreAll,
|
|
108
|
-
status: 'failed', error, duration: 0, durationTotal: 0, assertions: [assert], output:
|
|
108
|
+
status: 'failed', error, duration: 0, durationTotal: 0, assertions: [assert], output: []
|
|
109
109
|
};
|
|
110
110
|
const test: TestConfig = {
|
|
111
111
|
...coreAll,
|
|
@@ -10,7 +10,7 @@ import { TestConsumer } from '../registry.ts';
|
|
|
10
10
|
import { TestResultsEnhancer, CONSOLE_ENHANCER } from '../enhancer.ts';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
|
|
13
|
+
* TAP Format consumer
|
|
14
14
|
*/
|
|
15
15
|
@TestConsumer()
|
|
16
16
|
export class TapEmitter implements TestConsumerShape {
|
|
@@ -134,9 +134,13 @@ export class TapEmitter implements TestConsumerShape {
|
|
|
134
134
|
|
|
135
135
|
// Track output
|
|
136
136
|
if (test.output) {
|
|
137
|
+
const groupedByLevel: Record<string, string[]> = {};
|
|
138
|
+
for (const log of test.output) {
|
|
139
|
+
(groupedByLevel[log.level] ??= []).push(log.message);
|
|
140
|
+
}
|
|
137
141
|
for (const key of ['log', 'info', 'error', 'debug', 'warn']) {
|
|
138
|
-
if (
|
|
139
|
-
this.logMeta({ [key]:
|
|
142
|
+
if (groupedByLevel[key]) {
|
|
143
|
+
this.logMeta({ [key]: groupedByLevel[key].join('\n') });
|
|
140
144
|
}
|
|
141
145
|
}
|
|
142
146
|
}
|
|
@@ -63,6 +63,11 @@ export class XunitEmitter implements TestConsumerShape {
|
|
|
63
63
|
body = `<failure type="${assertErr.text}" message="${encodeURIComponent(assertErr.message!)}"><![CDATA[${assertErr.error!.stack}]]></failure>`;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
const groupedByLevel: Record<string, string[]> = {};
|
|
67
|
+
for (const log of test.output) {
|
|
68
|
+
(groupedByLevel[log.level] ??= []).push(log.message);
|
|
69
|
+
}
|
|
70
|
+
|
|
66
71
|
this.#tests.push(`
|
|
67
72
|
<testcase
|
|
68
73
|
name="${name}"
|
|
@@ -70,8 +75,8 @@ export class XunitEmitter implements TestConsumerShape {
|
|
|
70
75
|
classname="${test.classId}"
|
|
71
76
|
>
|
|
72
77
|
${body}
|
|
73
|
-
<system-out>${this.buildMeta({ log:
|
|
74
|
-
<system-err>${this.buildMeta({ error:
|
|
78
|
+
<system-out>${this.buildMeta({ log: groupedByLevel.log, info: groupedByLevel.info, debug: groupedByLevel.debug })}</system-out>
|
|
79
|
+
<system-err>${this.buildMeta({ error: groupedByLevel.error, warn: groupedByLevel.warn })}</system-err>
|
|
75
80
|
</testcase>`
|
|
76
81
|
);
|
|
77
82
|
} else if (e.type === 'suite' && e.phase === 'after') {
|
package/src/execute/console.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import util from 'node:util';
|
|
2
2
|
|
|
3
3
|
import { ConsoleEvent, ConsoleListener, ConsoleManager } from '@travetto/runtime';
|
|
4
|
+
import { TestLog } from '../model/test';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Console capturer. Hooks into the Console manager, and collects the
|
|
@@ -9,26 +10,28 @@ import { ConsoleEvent, ConsoleListener, ConsoleManager } from '@travetto/runtime
|
|
|
9
10
|
export class ConsoleCapture implements ConsoleListener {
|
|
10
11
|
static #listener: ConsoleListener = ConsoleManager.get();
|
|
11
12
|
|
|
12
|
-
out:
|
|
13
|
+
out: TestLog[];
|
|
13
14
|
|
|
14
15
|
start(): this {
|
|
15
|
-
this.out =
|
|
16
|
+
this.out = [];
|
|
16
17
|
ConsoleManager.set(this);
|
|
17
18
|
return this;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
log({ level, args }: ConsoleEvent): void {
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
log({ level, line, args }: ConsoleEvent): void {
|
|
22
|
+
this.out.push({
|
|
23
|
+
line,
|
|
24
|
+
level,
|
|
25
|
+
message: args
|
|
23
26
|
.map((x => typeof x === 'string' ? x : util.inspect(x, false, 5)))
|
|
24
27
|
.join(' ')
|
|
25
|
-
);
|
|
28
|
+
});
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
end():
|
|
29
|
-
const result = this.out ??
|
|
30
|
-
this.out =
|
|
31
|
+
end(): TestLog[] {
|
|
32
|
+
const result = this.out ?? [];
|
|
33
|
+
this.out = [];
|
|
31
34
|
ConsoleManager.set(ConsoleCapture.#listener);
|
|
32
|
-
return
|
|
35
|
+
return result;
|
|
33
36
|
}
|
|
34
37
|
}
|
package/src/execute/executor.ts
CHANGED
|
@@ -82,7 +82,7 @@ export class TestExecutor {
|
|
|
82
82
|
// Mark test start
|
|
83
83
|
this.#consumer.onEvent({ type: 'test', phase: 'before', test });
|
|
84
84
|
result.skipped++;
|
|
85
|
-
this.#consumer.onEvent({ type: 'test', phase: 'after', test: { ...test, assertions: [], duration: 0, durationTotal: 0, output:
|
|
85
|
+
this.#consumer.onEvent({ type: 'test', phase: 'after', test: { ...test, assertions: [], duration: 0, durationTotal: 0, output: [], status: 'skipped' } });
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
/**
|
|
@@ -126,7 +126,7 @@ export class TestExecutor {
|
|
|
126
126
|
assertions: [],
|
|
127
127
|
duration: 0,
|
|
128
128
|
durationTotal: 0,
|
|
129
|
-
output:
|
|
129
|
+
output: [],
|
|
130
130
|
};
|
|
131
131
|
|
|
132
132
|
// Emit every assertion as it occurs
|
package/src/model/test.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { Class, TimeSpan } from '@travetto/runtime';
|
|
1
|
+
import type { Class, ConsoleEvent, TimeSpan } from '@travetto/runtime';
|
|
2
|
+
|
|
2
3
|
import { Skip, TestCore } from './common.ts';
|
|
3
4
|
|
|
4
5
|
export type ThrowableError = string | RegExp | Class<Error> | ((e: Error | string) => boolean | void | undefined);
|
|
6
|
+
export type TestLog = { level: ConsoleEvent['level'], line: number, message: string };
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Specific configuration for a test
|
|
@@ -106,7 +108,7 @@ export interface TestResult extends TestCore {
|
|
|
106
108
|
/**
|
|
107
109
|
* Logging output
|
|
108
110
|
*/
|
|
109
|
-
output:
|
|
111
|
+
output: TestLog[];
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
/**
|