Skip to content

Commit a94927e

Browse files
committed
test_runner: fix linting issues
1 parent ff44806 commit a94927e

File tree

8 files changed

+417
-334
lines changed

8 files changed

+417
-334
lines changed

doc/api/errors.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2678,6 +2678,25 @@ An unspecified or non-specific system error has occurred within the Node.js
26782678
process. The error object will have an `err.info` object property with
26792679
additional details.
26802680

2681+
<a id="ERR_TAP_VALIDATOR_ERROR"></a>
2682+
2683+
### `ERR_TAP_VALIDATOR_ERROR`
2684+
2685+
This error represents a failed TAP validation.
2686+
2687+
<a id="ERR_TAP_LEXER_ERROR"></a>
2688+
2689+
### `ERR_TAP_LEXER_ERROR`
2690+
2691+
An error representing a failing lexer state.
2692+
2693+
<a id="ERR_TAP_PARSER_ERROR"></a>
2694+
2695+
### `ERR_TAP_PARSER_ERROR`
2696+
2697+
An error representing a failing parser state. Additional information about the token
2698+
causing the error is available via the `cause` property.
2699+
26812700
<a id="ERR_TEST_FAILURE"></a>
26822701

26832702
### `ERR_TEST_FAILURE`

lib/internal/errors.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ const {
6060
URIError,
6161
} = primordials;
6262

63+
const { console } = require('internal/console/global');
64+
6365
const kIsNodeError = Symbol('kIsNodeError');
6466

6567
const isWindows = process.platform === 'win32';
@@ -851,6 +853,22 @@ class AbortError extends Error {
851853
}
852854
}
853855

856+
// TAP Validation Error used by the TAP checker/parser.
857+
class TAPValidationError extends Error {
858+
constructor(message) {
859+
super(message);
860+
this.name = 'TAPValidationError';
861+
}
862+
}
863+
864+
// TAP Lexical Error used by the TAP lexer.
865+
class LexerError extends Error {
866+
constructor(message) {
867+
super(message);
868+
this.name = 'LexerError';
869+
}
870+
}
871+
854872
/**
855873
* This creates a generic Node.js error.
856874
*
@@ -1591,6 +1609,62 @@ E('ERR_STREAM_WRAP', 'Stream has StringDecoder set or is in objectMode', Error);
15911609
E('ERR_STREAM_WRITE_AFTER_END', 'write after end', Error);
15921610
E('ERR_SYNTHETIC', 'JavaScript Callstack', Error);
15931611
E('ERR_SYSTEM_ERROR', 'A system error occurred', SystemError);
1612+
E('ERR_TAP_LEXER_ERROR', function(errorMsg) {
1613+
hideInternalStackFrames(this);
1614+
return errorMsg;
1615+
}, LexerError);
1616+
E('ERR_TAP_PARSER_ERROR', function(errorMsg, details, tokenCausedError, source) {
1617+
hideInternalStackFrames(this);
1618+
this.cause = tokenCausedError;
1619+
1620+
const COLOR_UNDERLINE = '\u001b[4m';
1621+
const COLOR_WHITE = '\u001b[30;1m';
1622+
const COLOR_RED = '\u001b[31m';
1623+
const COLOR_RESET = '\u001b[0m';
1624+
const COLOR_YELLOW_BG = '\u001b[43m';
1625+
1626+
const { column, line, start, end } = tokenCausedError.location;
1627+
const indent = column + ('' + line).length + 1;
1628+
1629+
const sourceLines = source.split('\n');
1630+
const sourceLine = sourceLines[line - 1];
1631+
1632+
const errorDetails = `${details} at line ${line}, column ${column} (start ${start}, end ${end})`;
1633+
1634+
// Highlight the errored token in red
1635+
const sourceLineWithToken =
1636+
sourceLine.slice(0, column - 1) +
1637+
COLOR_UNDERLINE +
1638+
COLOR_RED +
1639+
sourceLine.slice(column - 1, column + (tokenCausedError.value.length - 1)) +
1640+
COLOR_RESET +
1641+
sourceLine.slice(column + (tokenCausedError.value.length - 1));
1642+
1643+
console.error(`\n${COLOR_YELLOW_BG + COLOR_RED}TAP Syntax Error:${COLOR_RESET}`);
1644+
1645+
for (let index = 0; index < line - 1; index++) {
1646+
const leadingZero = index < 9 ? '0' : '';
1647+
const line = sourceLines[index];
1648+
console.error(
1649+
`${COLOR_WHITE}${leadingZero}${
1650+
index + 1
1651+
}:${COLOR_RESET} ${line}`
1652+
);
1653+
}
1654+
1655+
const indentString = ' '.repeat(indent) + (line < 9 ? ' ' : '');
1656+
console.error(`${COLOR_WHITE}${
1657+
(line < 9 ? '0' : '') + line
1658+
}:${COLOR_RESET} ${sourceLineWithToken}
1659+
${COLOR_RED}${indentString}\u2502${COLOR_RESET}
1660+
${COLOR_RED}${indentString}\u2514\u2524${errorMsg}${errorDetails}${COLOR_RESET}
1661+
`);
1662+
return errorMsg + errorDetails;
1663+
}, SyntaxError);
1664+
E('ERR_TAP_VALIDATOR_ERROR', function(errorMsg) {
1665+
hideInternalStackFrames(this);
1666+
return errorMsg;
1667+
}, TAPValidationError);
15941668
E('ERR_TEST_FAILURE', function(error, failureType) {
15951669
hideInternalStackFrames(this);
15961670
assert(typeof failureType === 'string',

lib/internal/test_runner/tap_checker.js

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
'use strict';
22

3-
4-
class TAPValidationError extends Error {
5-
constructor(message) {
6-
super(message);
7-
this.name = 'TAPValidationError';
8-
}
9-
}
3+
const { NumberParseInt } = primordials;
4+
const {
5+
codes: { ERR_TAP_VALIDATOR_ERROR },
6+
} = require('internal/errors');
107

118
class TAPValidationStrategy {
129
validate(ast) {
@@ -22,7 +19,7 @@ class TAPValidationStrategy {
2219
const { documents } = ast.root;
2320

2421
if (documents.length > 1) {
25-
throw new TAPValidationError('Found more than one TAP documents');
22+
throw new ERR_TAP_VALIDATOR_ERROR('Found more than one TAP documents');
2623
}
2724
}
2825

@@ -31,42 +28,42 @@ class TAPValidationStrategy {
3128

3229
// TAP14 specification is compatible with observed behavior of existing TAP13 consumers and producers
3330
if (version !== '14' && version !== '13') {
34-
throw new TAPValidationError('TAP version should be 14');
31+
throw new ERR_TAP_VALIDATOR_ERROR('TAP version should be 14');
3532
}
3633
}
3734

3835
#validatePlan(ast) {
3936
const { plan } = ast.root.documents[0];
4037

4138
if (!plan) {
42-
throw new TAPValidationError('Missing Plan');
39+
throw new ERR_TAP_VALIDATOR_ERROR('Missing Plan');
4340
}
4441

4542
if (!plan.start) {
46-
throw new TAPValidationError('Missing Plan start');
43+
throw new ERR_TAP_VALIDATOR_ERROR('Missing Plan start');
4744
}
4845

4946
if (!plan.end) {
50-
throw new TAPValidationError('Missing Plan end');
47+
throw new ERR_TAP_VALIDATOR_ERROR('Missing Plan end');
5148
}
5249

53-
const planStart = parseInt(plan.start, 10);
54-
const planEnd = parseInt(plan.end, 10);
50+
const planStart = NumberParseInt(plan.start, 10);
51+
const planEnd = NumberParseInt(plan.end, 10);
5552

5653
if (planEnd !== 0 && planStart > planEnd) {
57-
throw new TAPValidationError(
54+
throw new ERR_TAP_VALIDATOR_ERROR(
5855
`Plan start ${planStart} is greater than Plan end ${planEnd}`
5956
);
6057
}
6158
}
6259

6360
#validateTestPoints(ast) {
6461
const { tests, plan, bailout } = ast.root.documents[0];
65-
const planStart = parseInt(plan.start, 10);
66-
const planEnd = parseInt(plan.end, 10);
62+
const planStart = NumberParseInt(plan.start, 10);
63+
const planEnd = NumberParseInt(plan.end, 10);
6764

6865
if (planEnd === 0 && tests && tests.length > 0) {
69-
throw new TAPValidationError(
66+
throw new ERR_TAP_VALIDATOR_ERROR(
7067
`Found ${tests.length} Test Point${
7168
tests.length > 1 ? 's' : ''
7269
} but Plan is ${planStart}..0`
@@ -75,21 +72,21 @@ class TAPValidationStrategy {
7572

7673
if (planEnd > 0) {
7774
if (!tests || tests.length === 0) {
78-
throw new TAPValidationError('Missing Test Points');
75+
throw new ERR_TAP_VALIDATOR_ERROR('Missing Test Points');
7976
}
8077

8178
if (!bailout && tests.length !== planEnd) {
82-
throw new TAPValidationError(
79+
throw new ERR_TAP_VALIDATOR_ERROR(
8380
`Test Points count ${tests.length} does not match Plan count ${planEnd}`
8481
);
8582
}
8683

8784
for (let i = 0; i < tests.length; i++) {
8885
const test = tests.at(i);
89-
const testId = parseInt(test.id, 10);
86+
const testId = NumberParseInt(test.id, 10);
9087

9188
if (testId < planStart || testId > planEnd) {
92-
throw new TAPValidationError(
89+
throw new ERR_TAP_VALIDATOR_ERROR(
9390
`Test ${testId} is out of Plan range ${planStart}..${planEnd}`
9491
);
9592
}
@@ -103,7 +100,6 @@ class TAP13ValidationStrategy extends TAPValidationStrategy {}
103100
class TAP14ValidationStrategy extends TAPValidationStrategy {}
104101

105102
class TapChecker {
106-
107103
static TAP13 = '13';
108104
static TAP14 = '14';
109105

0 commit comments

Comments
 (0)