Skip to content

Commit

Permalink
feat: tap parser
Browse files Browse the repository at this point in the history
add node parallel tests for lexer
  • Loading branch information
manekinekko committed Jun 21, 2022
1 parent 791c410 commit 3eec379
Show file tree
Hide file tree
Showing 4 changed files with 494 additions and 452 deletions.
81 changes: 41 additions & 40 deletions lib/internal/test_runner/tap_lexer.js
Expand Up @@ -24,8 +24,8 @@ const TokenKind = {
};

class Token {
constructor({ type, value, stream }) {
this.type = type;
constructor({ kind, value, stream }) {
this.kind = kind;
this.value = value;
this.location = {
line: stream.line,
Expand Down Expand Up @@ -150,7 +150,7 @@ class TapLexer {
this.escapeStack = [];

this.lastScannedToken = new Token({
type: TokenKind.EOL,
kind: TokenKind.EOL,
value: TokenKind.EOL,
stream: this.source,
});
Expand All @@ -161,7 +161,7 @@ class TapLexer {
let token = this.scanToken();

// remember the last scanned token (except for whitespace)
if (token.type !== TokenKind.WHITESPACE) {
if (token.kind !== TokenKind.WHITESPACE) {
this.lastScannedToken = token;
}
yield token;
Expand Down Expand Up @@ -223,27 +223,28 @@ class TapLexer {
// escape chars from the stack and start fresh for the next line
this.escapeStack = [];
return new Token({
type: TokenKind.EOL,
kind: TokenKind.EOL,
value: char,
stream: this.source,
});
}

scanEOF() {
return new Token({
type: TokenKind.EOF,
kind: TokenKind.EOF,
value: TokenKind.EOF,
stream: this.source,
});
}

scanEscapeSymbol(char) {
// if the escape symbol has been escaped, then it is not an escape symbol
// consume it as a literal.
if (this.hasTheCurrentCharacterBeenEscaped(char)) {
// if the escape symbol has been escaped (by previous symbol),
// or if the next symbol is a whitespace symbol,
// then consume it as a literal.
if (this.hasTheCurrentCharacterBeenEscaped() || this.source.peek(1) === TokenKind.WHITESPACE) {
this.escapeStack.pop();
return new Token({
type: TokenKind.LITERAL,
kind: TokenKind.LITERAL,
value: char,
stream: this.source,
});
Expand All @@ -254,15 +255,15 @@ class TapLexer {
// and consume the next character as a literal (done in the next turn)
this.escapeStack.push(char);
return new Token({
type: TokenKind.ESCAPE,
kind: TokenKind.ESCAPE,
value: char,
stream: this.source,
});
}

scanWhitespace(char) {
return new Token({
type: TokenKind.WHITESPACE,
kind: TokenKind.WHITESPACE,
value: char,
stream: this.source,
});
Expand All @@ -279,15 +280,15 @@ class TapLexer {
}

return new Token({
type: TokenKind.DASH,
kind: TokenKind.DASH,
value: char,
stream: this.source,
});
}

scanPlus(char) {
return new Token({
type: TokenKind.PLUS,
kind: TokenKind.PLUS,
value: char,
stream: this.source,
});
Expand All @@ -296,25 +297,25 @@ class TapLexer {
scanHash(char) {
// if last token is whitespace or EOL, we consume it as a comment
if (
this.lastScannedToken.type === TokenKind.WHITESPACE ||
this.lastScannedToken.type === TokenKind.EOL
this.lastScannedToken.kind === TokenKind.WHITESPACE ||
this.lastScannedToken.kind === TokenKind.EOL
) {
this.isComment = true;
return new Token({
type: TokenKind.COMMENT,
kind: TokenKind.COMMENT,
value: char,
stream: this.source,
});
}

const charHasBeenEscaped = this.hasTheCurrentCharacterBeenEscaped(char);
const charHasBeenEscaped = this.hasTheCurrentCharacterBeenEscaped();
if (this.isComment || charHasBeenEscaped) {
if (charHasBeenEscaped) {
this.escapeStack.pop();
}

return new Token({
type: TokenKind.LITERAL,
kind: TokenKind.LITERAL,
value: char,
stream: this.source,
});
Expand All @@ -323,7 +324,7 @@ class TapLexer {
// when a hash is found, we assume the rest of the line is a comment
this.isComment = true;
return new Token({
type: TokenKind.HASH,
kind: TokenKind.HASH,
value: char,
stream: this.source,
});
Expand All @@ -349,7 +350,7 @@ class TapLexer {
this.error(
`Exepcted YAML end block: ...`,
new Token({
type: TokenKind.EOF,
kind: TokenKind.EOF,
value: TokenKind.EOF,
stream: this.source,
})
Expand All @@ -358,7 +359,7 @@ class TapLexer {
}

return new Token({
type: TokenKind.TAP_YAML,
kind: TokenKind.TAP_YAML,
value: yaml, // don't trim on purpose!
stream: this.source,
});
Expand All @@ -377,7 +378,7 @@ class TapLexer {
comment = comment.replace(/^# /, '');

return new Token({
type: TokenKind.COMMENT,
kind: TokenKind.COMMENT,
value: comment,
stream: this.source,
});
Expand All @@ -397,7 +398,7 @@ class TapLexer {
description = description.replace(/^- /, '');

return new Token({
type: TokenKind.COMMENT,
kind: TokenKind.COMMENT,
value: description.trim(),
stream: this.source,
});
Expand Down Expand Up @@ -444,60 +445,60 @@ class TapLexer {
}

return new Token({
type: TokenKind.LITERAL,
kind: TokenKind.LITERAL,
value: word,
stream: this.source,
});
}

scanTAPkeyword(word) {
if (word === 'TAP' && this.lastScannedToken.type === TokenKind.EOL) {
if (word === 'TAP' && this.lastScannedToken.kind === TokenKind.EOL) {
return new Token({
type: TokenKind.TAP,
kind: TokenKind.TAP,
value: word,
stream: this.source,
});
}

if (word === 'version' && this.lastScannedToken.type === TokenKind.TAP) {
if (word === 'version' && this.lastScannedToken.kind === TokenKind.TAP) {
return new Token({
type: TokenKind.TAP_VERSION,
kind: TokenKind.TAP_VERSION,
value: word,
stream: this.source,
});
}

if (word === '..' && this.lastScannedToken.type === TokenKind.NUMERIC) {
if (word === '..' && this.lastScannedToken.kind === TokenKind.NUMERIC) {
return new Token({
type: TokenKind.TAP_PLAN,
kind: TokenKind.TAP_PLAN,
value: word,
stream: this.source,
});
}

if (word === 'not' && this.lastScannedToken.type === TokenKind.EOL) {
if (word === 'not' && this.lastScannedToken.kind === TokenKind.EOL) {
return new Token({
type: TokenKind.TAP_TEST_NOTOK,
kind: TokenKind.TAP_TEST_NOTOK,
value: word,
stream: this.source,
});
}

if (
word === 'ok' &&
(this.lastScannedToken.type === TokenKind.TAP_TEST_NOTOK ||
this.lastScannedToken.type === TokenKind.EOL)
(this.lastScannedToken.kind === TokenKind.TAP_TEST_NOTOK ||
this.lastScannedToken.kind === TokenKind.EOL)
) {
return new Token({
type: TokenKind.TAP_TEST_OK,
kind: TokenKind.TAP_TEST_OK,
value: word,
stream: this.source,
});
}

if (word === 'pragma' && this.lastScannedToken.type === TokenKind.EOL) {
if (word === 'pragma' && this.lastScannedToken.kind === TokenKind.EOL) {
return new Token({
type: TokenKind.TAP_PRAGMA,
kind: TokenKind.TAP_PRAGMA,
value: word,
stream: this.source,
});
Expand All @@ -518,13 +519,13 @@ class TapLexer {
}
}
return new Token({
type: TokenKind.NUMERIC,
kind: TokenKind.NUMERIC,
value: number,
stream: this.source,
});
}

hasTheCurrentCharacterBeenEscaped(char) {
hasTheCurrentCharacterBeenEscaped() {
// use the escapeStack to keep track of the escape characters
return this.escapeStack.length > 0;
}
Expand Down

0 comments on commit 3eec379

Please sign in to comment.