Skip to content

Commit f8892c1

Browse files
committed
CLI: Fix TAP compliance for colon in unquoted YAML diag
When an assertion message contained a colon followed by a space, and otherwise is a single line of ASCII characters, we formatted it as an unquoted string. This is invalid in YAML 1.2, and thus tap-parser would ignore the diagnostic block. This does not affect the TAP result itself (the test name and failure status are separate from this), and it does not affect the QUnit CLI output where the information is shown either way. When passing the CLI output to tap-parser (such as in QTap), it silently ignored the "diag" block containing the assertion message/actual/expected value, because it is not valid YAML. Note that YAML 1.2 does allow literal colons and hash tags in unquoted strings, when they are not followed by or preceded by a space, but I'm keeping our version simpler by erring toward quoted strings when these appear. Just because we could squeeze one more edge case with plain unquoted strings, doesn't mean we have to. This way keeps our format a bit more intuitive by making it predictable and easy to deduce why a string is quoted or not, based solely on the chars used and not based on obscure YAML internals. Ref https://yaml.org/spec/1.2.2/#733-plain-style
1 parent e114e63 commit f8892c1

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

src/core/reporters/TapReporter.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ function prettyYamlValue (value, indent = 2) {
6161
// cause data loss or invalid YAML syntax.
6262
//
6363
// - Quotes, escapes, line breaks, or JSON-like stuff.
64-
const rSpecialJson = /['"\\/[{}\]\r\n]/;
64+
// - Not allowed in YAML unquoted strings per https://yaml.org/spec/1.2.2/#733-plain-style
65+
// * ": " (colon followed by space)
66+
// * " #" (space followed by hash)
67+
const rSpecialJson = /['"\\/[{}\]\r\n|:#]/;
6568

6669
// - Characters that are special at the start of a YAML value
6770
const rSpecialYaml = /[-?:,[\]{}#&*!|=>'"%@`]/;

test/cli/TapReporter-to-TapParser.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,40 @@ QUnit.module('TapReporter-to-TapParser', hooks => {
118118
});
119119
});
120120

121+
QUnit.test('Quoting [colon]', async (assert) => {
122+
emitter.emit('runStart');
123+
emitter.emit('testEnd', {
124+
fullName: ['example'],
125+
status: 'failed',
126+
runtime: 0,
127+
errors: [{
128+
message: 'behold: the colon'
129+
}]
130+
});
131+
emitter.emit('runEnd', {
132+
testCounts: {
133+
total: 1,
134+
passed: 0,
135+
failed: 1,
136+
skipped: 0,
137+
todo: 0
138+
}
139+
});
140+
141+
assert.propContains(await getParseResult(), {
142+
ok: false,
143+
failures: [
144+
{
145+
ok: false,
146+
name: 'example',
147+
diag: {
148+
message: 'behold: the colon'
149+
}
150+
}
151+
]
152+
});
153+
});
154+
121155
QUnit.test('Deep equal failure', async (assert) => {
122156
emitter.emit('runStart');
123157
emitter.emit('testEnd', {

test/main/TapReporter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ QUnit.module('TapReporter', function (hooks) {
182182

183183
assert.strictEqual(buffer, 'not ok 1 global failure\n'
184184
+ ' ---\n'
185-
+ ' message: ReferenceError: Boo is not defined\n'
185+
+ ' message: "ReferenceError: Boo is not defined"\n'
186186
+ ' severity: failed\n'
187187
+ ' stack: |\n'
188188
+ ' at Object.<anonymous> (/dev/null/test/unit/data.js:6:5)\n'

0 commit comments

Comments
 (0)