Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions lib/internal/test_runner/tap_stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,18 @@ class TapStream extends Readable {

// In certain places, # and \ need to be escaped as \# and \\.
function tapEscape(input) {
return StringPrototypeReplaceAll(
StringPrototypeReplaceAll(input, '\\', '\\\\'), '#', '\\#'
);
[{ escapeChar: '\\', tappedEscape: '\\\\' },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though the resulting code will not look as nice as this, I'm inclined to use a series of StringPrototypeReplaceAll() calls here instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cjihrig like this... right?

return StringPrototypeReplaceAll(StringPrototypeReplaceAll(
    StringPrototypeReplaceAll(StringPrototypeReplaceAll(
      StringPrototypeReplaceAll(StringPrototypeReplaceAll(
        StringPrototypeReplaceAll(StringPrototypeReplaceAll(input, '\\', '\\\\'), '#', '\\#'),
        '\b', '\\b'), '\f', '\\f'), '\t', '\\t'), '\n', '\\n'), '\r', '\\r'), '\v', '\\v');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could do it that way. You could also do something like this to maintain more readability:

let result = StringPrototypeReplaceAll(...);
result = StringPrototypeReplaceAll(...);
result = StringPrototypeReplaceAll(...);
return result;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it 👍🏽
Thanks

{ escapeChar: '#', tappedEscape: '\\#' },
{ escapeChar: '\n', tappedEscape: '\\n' },
{ escapeChar: '\t', tappedEscape: '\\t' },
{ escapeChar: '\r', tappedEscape: '\\r' },
{ escapeChar: '\f', tappedEscape: '\\f' },
{ escapeChar: '\b', tappedEscape: '\\b' },
{ escapeChar: '\v', tappedEscape: '\\v' },
].forEach(({ escapeChar, tappedEscape }) => {
input = StringPrototypeReplaceAll(input, escapeChar, tappedEscape);
});
return input;
}

function jsToYaml(indent, name, value) {
Expand Down Expand Up @@ -261,4 +270,4 @@ function isAssertionLike(value) {
return value && typeof value === 'object' && 'expected' in value && 'actual' in value;
}

module.exports = { TapStream };
module.exports = { TapStream, tapEscape };
15 changes: 15 additions & 0 deletions test/parallel/test-runner-tap-parser-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const common = require('../common');
const assert = require('node:assert');
const { TapParser } = require('internal/test_runner/tap_parser');
const { TapChecker } = require('internal/test_runner/tap_checker');
const { tapEscape } = require('internal/test_runner/tap_stream');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I don't think this file is the best place for testing this. This file is more about the TAP parser.

I would test this by doing the following:

  • Undo the changes in this file.
  • Remove the tapEscape export that this PR adds to lib/internal/test_runner/tap_stream.js.
  • Add a test to test/message/test_runner_output.js that uses \n, \r, etc (# and \ are already tested IIRC).
  • Update test/message/test_runner_output.out to reflect the changes in the test output.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updating this 👍🏽 🚀


const cases = [
{
Expand Down Expand Up @@ -627,3 +628,17 @@ ok 1 - test 1
expected.map((item) => ({ __proto__: null, ...item }))
);
})().then(common.mustCall());

(async () => {
[{ escapeChar: '\\', tappedEscape: '\\\\' },
{ escapeChar: '#', tappedEscape: '\\#' },
{ escapeChar: '\n', tappedEscape: '\\n' },
{ escapeChar: '\t', tappedEscape: '\\t' },
{ escapeChar: '\r', tappedEscape: '\\r' },
{ escapeChar: '\f', tappedEscape: '\\f' },
{ escapeChar: '\b', tappedEscape: '\\b' },
{ escapeChar: '\v', tappedEscape: '\\v' },
].forEach(({ escapeChar, tappedEscape }) => {
assert.strictEqual(tapEscape(escapeChar), tappedEscape);
});
})().then(common.mustCall());