Skip to content

Commit

Permalink
test_runner: fix linting issues
Browse files Browse the repository at this point in the history
  • Loading branch information
manekinekko committed Sep 16, 2022
1 parent ff44806 commit a94927e
Show file tree
Hide file tree
Showing 8 changed files with 417 additions and 334 deletions.
19 changes: 19 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -2678,6 +2678,25 @@ An unspecified or non-specific system error has occurred within the Node.js
process. The error object will have an `err.info` object property with
additional details.

<a id="ERR_TAP_VALIDATOR_ERROR"></a>

### `ERR_TAP_VALIDATOR_ERROR`

This error represents a failed TAP validation.

<a id="ERR_TAP_LEXER_ERROR"></a>

### `ERR_TAP_LEXER_ERROR`

An error representing a failing lexer state.

<a id="ERR_TAP_PARSER_ERROR"></a>

### `ERR_TAP_PARSER_ERROR`

An error representing a failing parser state. Additional information about the token
causing the error is available via the `cause` property.

<a id="ERR_TEST_FAILURE"></a>

### `ERR_TEST_FAILURE`
Expand Down
74 changes: 74 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const {
URIError,
} = primordials;

const { console } = require('internal/console/global');

const kIsNodeError = Symbol('kIsNodeError');

const isWindows = process.platform === 'win32';
Expand Down Expand Up @@ -851,6 +853,22 @@ class AbortError extends Error {
}
}

// TAP Validation Error used by the TAP checker/parser.
class TAPValidationError extends Error {
constructor(message) {
super(message);
this.name = 'TAPValidationError';
}
}

// TAP Lexical Error used by the TAP lexer.
class LexerError extends Error {
constructor(message) {
super(message);
this.name = 'LexerError';
}
}

/**
* This creates a generic Node.js error.
*
Expand Down Expand Up @@ -1591,6 +1609,62 @@ E('ERR_STREAM_WRAP', 'Stream has StringDecoder set or is in objectMode', Error);
E('ERR_STREAM_WRITE_AFTER_END', 'write after end', Error);
E('ERR_SYNTHETIC', 'JavaScript Callstack', Error);
E('ERR_SYSTEM_ERROR', 'A system error occurred', SystemError);
E('ERR_TAP_LEXER_ERROR', function(errorMsg) {
hideInternalStackFrames(this);
return errorMsg;
}, LexerError);
E('ERR_TAP_PARSER_ERROR', function(errorMsg, details, tokenCausedError, source) {
hideInternalStackFrames(this);
this.cause = tokenCausedError;

const COLOR_UNDERLINE = '\u001b[4m';
const COLOR_WHITE = '\u001b[30;1m';
const COLOR_RED = '\u001b[31m';
const COLOR_RESET = '\u001b[0m';
const COLOR_YELLOW_BG = '\u001b[43m';

const { column, line, start, end } = tokenCausedError.location;
const indent = column + ('' + line).length + 1;

const sourceLines = source.split('\n');
const sourceLine = sourceLines[line - 1];

const errorDetails = `${details} at line ${line}, column ${column} (start ${start}, end ${end})`;

// Highlight the errored token in red
const sourceLineWithToken =
sourceLine.slice(0, column - 1) +
COLOR_UNDERLINE +
COLOR_RED +
sourceLine.slice(column - 1, column + (tokenCausedError.value.length - 1)) +
COLOR_RESET +
sourceLine.slice(column + (tokenCausedError.value.length - 1));

console.error(`\n${COLOR_YELLOW_BG + COLOR_RED}TAP Syntax Error:${COLOR_RESET}`);

for (let index = 0; index < line - 1; index++) {
const leadingZero = index < 9 ? '0' : '';
const line = sourceLines[index];
console.error(
`${COLOR_WHITE}${leadingZero}${
index + 1
}:${COLOR_RESET} ${line}`
);
}

const indentString = ' '.repeat(indent) + (line < 9 ? ' ' : '');
console.error(`${COLOR_WHITE}${
(line < 9 ? '0' : '') + line
}:${COLOR_RESET} ${sourceLineWithToken}
${COLOR_RED}${indentString}\u2502${COLOR_RESET}
${COLOR_RED}${indentString}\u2514\u2524${errorMsg}${errorDetails}${COLOR_RESET}
`);
return errorMsg + errorDetails;
}, SyntaxError);
E('ERR_TAP_VALIDATOR_ERROR', function(errorMsg) {
hideInternalStackFrames(this);
return errorMsg;
}, TAPValidationError);
E('ERR_TEST_FAILURE', function(error, failureType) {
hideInternalStackFrames(this);
assert(typeof failureType === 'string',
Expand Down
42 changes: 19 additions & 23 deletions lib/internal/test_runner/tap_checker.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
'use strict';


class TAPValidationError extends Error {
constructor(message) {
super(message);
this.name = 'TAPValidationError';
}
}
const { NumberParseInt } = primordials;
const {
codes: { ERR_TAP_VALIDATOR_ERROR },
} = require('internal/errors');

class TAPValidationStrategy {
validate(ast) {
Expand All @@ -22,7 +19,7 @@ class TAPValidationStrategy {
const { documents } = ast.root;

if (documents.length > 1) {
throw new TAPValidationError('Found more than one TAP documents');
throw new ERR_TAP_VALIDATOR_ERROR('Found more than one TAP documents');
}
}

Expand All @@ -31,42 +28,42 @@ class TAPValidationStrategy {

// TAP14 specification is compatible with observed behavior of existing TAP13 consumers and producers
if (version !== '14' && version !== '13') {
throw new TAPValidationError('TAP version should be 14');
throw new ERR_TAP_VALIDATOR_ERROR('TAP version should be 14');
}
}

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

if (!plan) {
throw new TAPValidationError('Missing Plan');
throw new ERR_TAP_VALIDATOR_ERROR('Missing Plan');
}

if (!plan.start) {
throw new TAPValidationError('Missing Plan start');
throw new ERR_TAP_VALIDATOR_ERROR('Missing Plan start');
}

if (!plan.end) {
throw new TAPValidationError('Missing Plan end');
throw new ERR_TAP_VALIDATOR_ERROR('Missing Plan end');
}

const planStart = parseInt(plan.start, 10);
const planEnd = parseInt(plan.end, 10);
const planStart = NumberParseInt(plan.start, 10);
const planEnd = NumberParseInt(plan.end, 10);

if (planEnd !== 0 && planStart > planEnd) {
throw new TAPValidationError(
throw new ERR_TAP_VALIDATOR_ERROR(
`Plan start ${planStart} is greater than Plan end ${planEnd}`
);
}
}

#validateTestPoints(ast) {
const { tests, plan, bailout } = ast.root.documents[0];
const planStart = parseInt(plan.start, 10);
const planEnd = parseInt(plan.end, 10);
const planStart = NumberParseInt(plan.start, 10);
const planEnd = NumberParseInt(plan.end, 10);

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

if (planEnd > 0) {
if (!tests || tests.length === 0) {
throw new TAPValidationError('Missing Test Points');
throw new ERR_TAP_VALIDATOR_ERROR('Missing Test Points');
}

if (!bailout && tests.length !== planEnd) {
throw new TAPValidationError(
throw new ERR_TAP_VALIDATOR_ERROR(
`Test Points count ${tests.length} does not match Plan count ${planEnd}`
);
}

for (let i = 0; i < tests.length; i++) {
const test = tests.at(i);
const testId = parseInt(test.id, 10);
const testId = NumberParseInt(test.id, 10);

if (testId < planStart || testId > planEnd) {
throw new TAPValidationError(
throw new ERR_TAP_VALIDATOR_ERROR(
`Test ${testId} is out of Plan range ${planStart}..${planEnd}`
);
}
Expand All @@ -103,7 +100,6 @@ class TAP13ValidationStrategy extends TAPValidationStrategy {}
class TAP14ValidationStrategy extends TAPValidationStrategy {}

class TapChecker {

static TAP13 = '13';
static TAP14 = '14';

Expand Down
Loading

0 comments on commit a94927e

Please sign in to comment.