Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 87a0e86

Browse filesBrowse files
MoLowjuanarbol
authored andcommitted
test_runner: parse yaml
PR-URL: #45815 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 874f6c3 commit 87a0e86
Copy full SHA for 87a0e86

File tree

Expand file treeCollapse file tree

6 files changed

+785
-19
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+785
-19
lines changed
Open diff view settings
Collapse file

‎lib/internal/test_runner/runner.js‎

Copy file name to clipboardExpand all lines: lib/internal/test_runner/runner.js
+3-15Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const {
44
ArrayPrototypeFilter,
55
ArrayPrototypeForEach,
66
ArrayPrototypeIncludes,
7-
ArrayPrototypeJoin,
87
ArrayPrototypePush,
98
ArrayPrototypeSlice,
109
ArrayPrototypeSort,
@@ -35,6 +34,7 @@ const { kEmptyObject } = require('internal/util');
3534
const { createTestTree } = require('internal/test_runner/harness');
3635
const { kDefaultIndent, kSubtestsFailed, Test } = require('internal/test_runner/test');
3736
const { TapParser } = require('internal/test_runner/tap_parser');
37+
const { YAMLToJs } = require('internal/test_runner/yaml_parser');
3838
const { TokenKind } = require('internal/test_runner/tap_lexer');
3939

4040
const {
@@ -129,18 +129,6 @@ class FileTest extends Test {
129129
#handleReportItem({ kind, node, nesting = 0 }) {
130130
const indent = StringPrototypeRepeat(kDefaultIndent, nesting + 1);
131131

132-
const details = (diagnostic) => {
133-
return (
134-
diagnostic && {
135-
__proto__: null,
136-
yaml:
137-
`${indent} ` +
138-
ArrayPrototypeJoin(diagnostic, `\n${indent} `) +
139-
'\n',
140-
}
141-
);
142-
};
143-
144132
switch (kind) {
145133
case TokenKind.TAP_VERSION:
146134
// TODO(manekinekko): handle TAP version coming from the parser.
@@ -174,15 +162,15 @@ class FileTest extends Test {
174162
indent,
175163
node.id,
176164
node.description,
177-
details(node.diagnostics),
165+
YAMLToJs(node.diagnostics),
178166
directive
179167
);
180168
} else {
181169
this.reporter.fail(
182170
indent,
183171
node.id,
184172
node.description,
185-
details(node.diagnostics),
173+
YAMLToJs(node.diagnostics),
186174
directive
187175
);
188176
}
Collapse file

‎lib/internal/test_runner/tap_stream.js‎

Copy file name to clipboardExpand all lines: lib/internal/test_runner/tap_stream.js
+2-3Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,10 @@ class TapStream extends Readable {
8383
}
8484

8585
#details(indent, data = kEmptyObject) {
86-
const { error, duration, yaml } = data;
86+
const { error, duration_ms } = data;
8787
let details = `${indent} ---\n`;
8888

89-
details += `${yaml ? yaml : ''}`;
90-
details += jsToYaml(indent, 'duration_ms', duration);
89+
details += jsToYaml(indent, 'duration_ms', duration_ms);
9190
details += jsToYaml(indent, null, error);
9291
details += `${indent} ...\n`;
9392
this.#tryPush(details);
Collapse file

‎lib/internal/test_runner/test.js‎

Copy file name to clipboardExpand all lines: lib/internal/test_runner/test.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ class Test extends AsyncResource {
680680
this.reportSubtest();
681681
}
682682
let directive;
683-
const details = { __proto__: null, duration: this.#duration() };
683+
const details = { __proto__: null, duration_ms: this.#duration() };
684684

685685
if (this.skipped) {
686686
directive = this.reporter.getSkip(this.message);
Collapse file
+119Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
'use strict';
2+
const {
3+
codes: {
4+
ERR_TEST_FAILURE,
5+
}
6+
} = require('internal/errors');
7+
const AssertionError = require('internal/assert/assertion_error');
8+
const {
9+
ArrayPrototypeJoin,
10+
ArrayPrototypePush,
11+
Error,
12+
Number,
13+
NumberIsNaN,
14+
RegExpPrototypeExec,
15+
StringPrototypeEndsWith,
16+
StringPrototypeRepeat,
17+
StringPrototypeSlice,
18+
StringPrototypeStartsWith,
19+
StringPrototypeSubstring,
20+
} = primordials;
21+
22+
const kYamlKeyRegex = /^(\s+)?(\w+):(\s)+([>|][-+])?(.*)$/;
23+
const kStackDelimiter = ' at ';
24+
25+
function reConstructError(parsedYaml) {
26+
if (!('error' in parsedYaml)) {
27+
return parsedYaml;
28+
}
29+
const isAssertionError = parsedYaml.code === 'ERR_ASSERTION' ||
30+
'actual' in parsedYaml || 'expected' in parsedYaml || 'operator' in parsedYaml;
31+
const isTestFailure = parsedYaml.code === 'ERR_TEST_FAILURE' || 'failureType' in parsedYaml;
32+
const stack = parsedYaml.stack ? kStackDelimiter + ArrayPrototypeJoin(parsedYaml.stack, `\n${kStackDelimiter}`) : '';
33+
let error, cause;
34+
35+
if (isAssertionError) {
36+
cause = new AssertionError({
37+
message: parsedYaml.error,
38+
actual: parsedYaml.actual,
39+
expected: parsedYaml.expected,
40+
operator: parsedYaml.operator
41+
});
42+
} else {
43+
// eslint-disable-next-line no-restricted-syntax
44+
cause = new Error(parsedYaml.error);
45+
cause.code = parsedYaml.code;
46+
}
47+
cause.stack = stack;
48+
49+
if (isTestFailure) {
50+
error = new ERR_TEST_FAILURE(cause, parsedYaml.failureType);
51+
error.stack = stack;
52+
}
53+
54+
parsedYaml.error = error ?? cause;
55+
delete parsedYaml.stack;
56+
delete parsedYaml.code;
57+
delete parsedYaml.failureType;
58+
delete parsedYaml.actual;
59+
delete parsedYaml.expected;
60+
delete parsedYaml.operator;
61+
62+
return parsedYaml;
63+
}
64+
65+
function getYamlValue(value) {
66+
if (StringPrototypeStartsWith(value, "'") && StringPrototypeEndsWith(value, "'")) {
67+
return StringPrototypeSlice(value, 1, -1);
68+
}
69+
if (value === 'true') {
70+
return true;
71+
}
72+
if (value === 'false') {
73+
return false;
74+
}
75+
if (value !== '') {
76+
const valueAsNumber = Number(value);
77+
return NumberIsNaN(valueAsNumber) ? value : valueAsNumber;
78+
}
79+
return value;
80+
}
81+
82+
// This parses the YAML generated by the built-in TAP reporter,
83+
// which is a subset of the full YAML spec. There are some
84+
// YAML features that won't be parsed here. This function should not be exposed publicly.
85+
function YAMLToJs(lines) {
86+
if (lines == null) {
87+
return undefined;
88+
}
89+
const result = { __proto__: null };
90+
let isInYamlBlock = false;
91+
for (let i = 0; i < lines.length; i++) {
92+
const line = lines[i];
93+
if (isInYamlBlock && !StringPrototypeStartsWith(line, StringPrototypeRepeat(' ', isInYamlBlock.indent))) {
94+
result[isInYamlBlock.key] = isInYamlBlock.key === 'stack' ?
95+
result[isInYamlBlock.key] : ArrayPrototypeJoin(result[isInYamlBlock.key], '\n');
96+
isInYamlBlock = false;
97+
}
98+
if (isInYamlBlock) {
99+
const blockLine = StringPrototypeSubstring(line, isInYamlBlock.indent);
100+
ArrayPrototypePush(result[isInYamlBlock.key], blockLine);
101+
continue;
102+
}
103+
const match = RegExpPrototypeExec(kYamlKeyRegex, line);
104+
if (match !== null) {
105+
const { 1: leadingSpaces, 2: key, 4: block, 5: value } = match;
106+
if (block) {
107+
isInYamlBlock = { key, indent: (leadingSpaces?.length ?? 0) + 2 };
108+
result[key] = [];
109+
} else {
110+
result[key] = getYamlValue(value);
111+
}
112+
}
113+
}
114+
return reConstructError(result);
115+
}
116+
117+
module.exports = {
118+
YAMLToJs,
119+
};
Collapse file
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Flags: --no-warnings
2+
'use strict';
3+
require('../common');
4+
const spawn = require('node:child_process').spawn;
5+
spawn(process.execPath,
6+
['--no-warnings', '--test', 'test/message/test_runner_output.js'], { stdio: 'inherit' });

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.