Skip to content

Commit

Permalink
test_runner: add test for TAP stream parser
Browse files Browse the repository at this point in the history
  • Loading branch information
manekinekko committed Oct 12, 2022
1 parent d97256a commit c0c9bc0
Show file tree
Hide file tree
Showing 3 changed files with 301 additions and 24 deletions.
71 changes: 50 additions & 21 deletions lib/internal/test_runner/tap_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,22 @@ class TapParser extends Transform {
this.#lexer = new TapLexer(chunkAsString);

try {
this.#tokens = this.#lexer.scan();
this.#tokens = this.#scanTokens();
this.#parseTokens(callback);
} catch (error) {
callback(null, error);
}
}

parseSync(input = '', callback = null) {
if (typeof input !== 'string' || input === '') {
return [];
}

this.#isSyncParsingEnabled = true;
this.input = input;
this.#lexer = new TapLexer(input);
this.#tokens = this.#lexer.scan();
this.#tokens = this.#scanTokens();

this.#parseTokens(callback);

Expand Down Expand Up @@ -170,6 +174,10 @@ class TapParser extends Transform {
// ----------------------------- Private API ----------------------------//
// ----------------------------------------------------------------------//

#scanTokens() {
return this.#lexer.scan();
}

#parseTokens(callback = null) {
for (let index = 0; index < this.#tokens.length; index++) {
const chunk = this.#tokens[index];
Expand Down Expand Up @@ -200,12 +208,14 @@ class TapParser extends Transform {

const astNode = this.#TAPDocument(chunk);

callback?.({
...astNode,
nesting: this.#subTestNestingLevel,
lexeme: ArrayPrototypeMap(chunk, (token) => token.value).join(''),
tokens: chunk,
});
// Mark the current chunk as processed
// only when there is data to emit
if (astNode) {
callback?.({
...astNode,
lexeme: this.#serializeChunk(chunk),
});
}

// Move pointers to the next chunk and reset the current token index
this.#currentTokenChunk++;
Expand Down Expand Up @@ -322,6 +332,14 @@ class TapParser extends Transform {
nesting: this.#subTestNestingLevel,
};

// If we find invalid TAP content, don't add it to AST
if (
value.kind === TokenKind.UNKNOWN &&
value.node.value.includes('nesting:')
) {
return value;
}

// If we are emitting a YAML block, we need to update the last node in the
// AST to include the YAML block as diagnostic.
// We only do this to produce an AST with fewer nodes.
Expand All @@ -337,9 +355,16 @@ class TapParser extends Transform {
lastNode.node.diagnostics ||= [];

ArrayPrototypeForEach(value.node.diagnostics, (diagnostic) => {
ArrayPrototypePush(lastNode.node.diagnostics, diagnostic);
// Avoid adding empty diagnostics
if (diagnostic) {
ArrayPrototypePush(lastNode.node.diagnostics, diagnostic);
}
});

// no need to pass this node to the stream interface
// because diagnostics are already added to the last test node
return;

// eslint-disable-next-line brace-style
}

Expand Down Expand Up @@ -427,21 +452,25 @@ class TapParser extends Transform {
break;
case TokenKind.EOL:
case TokenKind.EOF:
// Read and ignore token
this.#next(false);
break;
// Consume and ignore token
return this.#next(false);
default:
// Read token because error needs the last token details
this.#next(false);
this.#error('Expected a valid token');
}
}
return {

const node = {
kind: TokenKind.UNKNOWN,
node: {
value: tokenChunksAsString,
},
};

// We make sure the emitted node has the same shape
// both in sync and async parsing (for the stream interface)
return this.#emit(node);
}

// ----------------Version----------------
Expand Down Expand Up @@ -699,14 +728,13 @@ class TapParser extends Transform {

this.#isYAMLBlock = true;
this.#yamlCurrentIndentationLevel = this.#subTestNestingLevel;

// Consume the YAML start marker
this.#next(false); // skip "---"

return {
kind: TokenKind.TAP_YAML_START,
node: {
diagnostics: this.#yamlBlockBuffer,
},
};
// No need to pass this token to the stream interface
return;

} else if (yamlBlockSymbol.kind === TokenKind.TAP_YAML_END) {
this.#next(false); // skip "..."

Expand All @@ -733,12 +761,12 @@ class TapParser extends Transform {
if (this.#isYAMLBlock) {
this.#YAMLLine();
} else {
return {
return this.#emit({
kind: TokenKind.UNKNOWN,
node: {
value: yamlBlockSymbol.value,
},
};
});
}
}

Expand All @@ -752,6 +780,7 @@ class TapParser extends Transform {
case 'duration_ms':
this.#lastTestPointDuration = Number(value);
break;
// TODO(@manekinekko): should we handle other diagnostics data?
}

ArrayPrototypePush(this.#yamlBlockBuffer, yamlLiteral);
Expand Down
Loading

0 comments on commit c0c9bc0

Please sign in to comment.