Skip to content

Commit 097797e

Browse files
committed
test_runner: fix linting issues
1 parent 67c77a8 commit 097797e

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
@@ -2617,6 +2617,25 @@ An unspecified or non-specific system error has occurred within the Node.js
26172617
process. The error object will have an `err.info` object property with
26182618
additional details.
26192619

2620+
<a id="ERR_TAP_VALIDATOR_ERROR"></a>
2621+
2622+
### `ERR_TAP_VALIDATOR_ERROR`
2623+
2624+
This error represents a failed TAP validation.
2625+
2626+
<a id="ERR_TAP_LEXER_ERROR"></a>
2627+
2628+
### `ERR_TAP_LEXER_ERROR`
2629+
2630+
An error representing a failing lexer state.
2631+
2632+
<a id="ERR_TAP_PARSER_ERROR"></a>
2633+
2634+
### `ERR_TAP_PARSER_ERROR`
2635+
2636+
An error representing a failing parser state. Additional information about the token
2637+
causing the error is available via the `cause` property.
2638+
26202639
<a id="ERR_TEST_FAILURE"></a>
26212640

26222641
### `ERR_TEST_FAILURE`

lib/internal/errors.js

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

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

6668
const isWindows = process.platform === 'win32';
@@ -844,6 +846,22 @@ class AbortError extends Error {
844846
}
845847
}
846848

849+
// TAP Validation Error used by the TAP checker/parser.
850+
class TAPValidationError extends Error {
851+
constructor(message) {
852+
super(message);
853+
this.name = 'TAPValidationError';
854+
}
855+
}
856+
857+
// TAP Lexical Error used by the TAP lexer.
858+
class LexerError extends Error {
859+
constructor(message) {
860+
super(message);
861+
this.name = 'LexerError';
862+
}
863+
}
864+
847865
/**
848866
* This creates a generic Node.js error.
849867
*
@@ -1577,6 +1595,62 @@ E('ERR_STREAM_WRAP', 'Stream has StringDecoder set or is in objectMode', Error);
15771595
E('ERR_STREAM_WRITE_AFTER_END', 'write after end', Error);
15781596
E('ERR_SYNTHETIC', 'JavaScript Callstack', Error);
15791597
E('ERR_SYSTEM_ERROR', 'A system error occurred', SystemError);
1598+
E('ERR_TAP_LEXER_ERROR', function(errorMsg) {
1599+
hideInternalStackFrames(this);
1600+
return errorMsg;
1601+
}, LexerError);
1602+
E('ERR_TAP_PARSER_ERROR', function(errorMsg, details, tokenCausedError, source) {
1603+
hideInternalStackFrames(this);
1604+
this.cause = tokenCausedError;
1605+
1606+
const COLOR_UNDERLINE = '\u001b[4m';
1607+
const COLOR_WHITE = '\u001b[30;1m';
1608+
const COLOR_RED = '\u001b[31m';
1609+
const COLOR_RESET = '\u001b[0m';
1610+
const COLOR_YELLOW_BG = '\u001b[43m';
1611+
1612+
const { column, line, start, end } = tokenCausedError.location;
1613+
const indent = column + ('' + line).length + 1;
1614+
1615+
const sourceLines = source.split('\n');
1616+
const sourceLine = sourceLines[line - 1];
1617+
1618+
const errorDetails = `${details} at line ${line}, column ${column} (start ${start}, end ${end})`;
1619+
1620+
// Highlight the errored token in red
1621+
const sourceLineWithToken =
1622+
sourceLine.slice(0, column - 1) +
1623+
COLOR_UNDERLINE +
1624+
COLOR_RED +
1625+
sourceLine.slice(column - 1, column + (tokenCausedError.value.length - 1)) +
1626+
COLOR_RESET +
1627+
sourceLine.slice(column + (tokenCausedError.value.length - 1));
1628+
1629+
console.error(`\n${COLOR_YELLOW_BG + COLOR_RED}TAP Syntax Error:${COLOR_RESET}`);
1630+
1631+
for (let index = 0; index < line - 1; index++) {
1632+
const leadingZero = index < 9 ? '0' : '';
1633+
const line = sourceLines[index];
1634+
console.error(
1635+
`${COLOR_WHITE}${leadingZero}${
1636+
index + 1
1637+
}:${COLOR_RESET} ${line}`
1638+
);
1639+
}
1640+
1641+
const indentString = ' '.repeat(indent) + (line < 9 ? ' ' : '');
1642+
console.error(`${COLOR_WHITE}${
1643+
(line < 9 ? '0' : '') + line
1644+
}:${COLOR_RESET} ${sourceLineWithToken}
1645+
${COLOR_RED}${indentString}\u2502${COLOR_RESET}
1646+
${COLOR_RED}${indentString}\u2514\u2524${errorMsg}${errorDetails}${COLOR_RESET}
1647+
`);
1648+
return errorMsg + errorDetails;
1649+
}, SyntaxError);
1650+
E('ERR_TAP_VALIDATOR_ERROR', function(errorMsg) {
1651+
hideInternalStackFrames(this);
1652+
return errorMsg;
1653+
}, TAPValidationError);
15801654
E('ERR_TEST_FAILURE', function(error, failureType) {
15811655
hideInternalStackFrames(this);
15821656
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)