gherkin
Version:
207 lines • 8.98 kB
JavaScript
"use strict";
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var gherkin_languages_json_1 = __importDefault(require("./gherkin-languages.json"));
var Errors_1 = require("./Errors");
var Parser_1 = require("./Parser");
var DIALECT_DICT = gherkin_languages_json_1.default;
var LANGUAGE_PATTERN = /^\s*#\s*language\s*:\s*([a-zA-Z\-_]+)\s*$/;
var TokenMatcher = /** @class */ (function () {
function TokenMatcher(defaultDialectName) {
if (defaultDialectName === void 0) { defaultDialectName = 'en'; }
this.defaultDialectName = defaultDialectName;
this.reset();
}
TokenMatcher.prototype.changeDialect = function (newDialectName, location) {
var newDialect = DIALECT_DICT[newDialectName];
if (!newDialect) {
throw Errors_1.NoSuchLanguageException.create(newDialectName, location);
}
this.dialectName = newDialectName;
this.dialect = newDialect;
};
TokenMatcher.prototype.reset = function () {
if (this.dialectName !== this.defaultDialectName) {
this.changeDialect(this.defaultDialectName);
}
this.activeDocStringSeparator = null;
this.indentToRemove = 0;
};
TokenMatcher.prototype.match_TagLine = function (token) {
if (token.line.startsWith('@')) {
this.setTokenMatched(token, Parser_1.TokenType.TagLine, null, null, null, token.line.getTags());
return true;
}
return false;
};
TokenMatcher.prototype.match_FeatureLine = function (token) {
return this.matchTitleLine(token, Parser_1.TokenType.FeatureLine, this.dialect.feature);
};
TokenMatcher.prototype.match_ScenarioLine = function (token) {
return (this.matchTitleLine(token, Parser_1.TokenType.ScenarioLine, this.dialect.scenario) ||
this.matchTitleLine(token, Parser_1.TokenType.ScenarioLine, this.dialect.scenarioOutline));
};
TokenMatcher.prototype.match_BackgroundLine = function (token) {
return this.matchTitleLine(token, Parser_1.TokenType.BackgroundLine, this.dialect.background);
};
TokenMatcher.prototype.match_ExamplesLine = function (token) {
return this.matchTitleLine(token, Parser_1.TokenType.ExamplesLine, this.dialect.examples);
};
TokenMatcher.prototype.match_RuleLine = function (token) {
return this.matchTitleLine(token, Parser_1.TokenType.RuleLine, this.dialect.rule);
};
TokenMatcher.prototype.match_TableRow = function (token) {
if (token.line.startsWith('|')) {
// TODO: indent
this.setTokenMatched(token, Parser_1.TokenType.TableRow, null, null, null, token.line.getTableCells());
return true;
}
return false;
};
TokenMatcher.prototype.match_Empty = function (token) {
if (token.line.isEmpty) {
this.setTokenMatched(token, Parser_1.TokenType.Empty, null, null, 0);
return true;
}
return false;
};
TokenMatcher.prototype.match_Comment = function (token) {
if (token.line.startsWith('#')) {
var text = token.line.getLineText(0); // take the entire line, including leading space
this.setTokenMatched(token, Parser_1.TokenType.Comment, text, null, 0);
return true;
}
return false;
};
TokenMatcher.prototype.match_Language = function (token) {
var match = token.line.trimmedLineText.match(LANGUAGE_PATTERN);
if (match) {
var newDialectName = match[1];
this.setTokenMatched(token, Parser_1.TokenType.Language, newDialectName);
this.changeDialect(newDialectName, token.location);
return true;
}
return false;
};
TokenMatcher.prototype.match_DocStringSeparator = function (token) {
return this.activeDocStringSeparator == null
? // open
this._match_DocStringSeparator(token, '"""', true) ||
this._match_DocStringSeparator(token, '```', true)
: // close
this._match_DocStringSeparator(token, this.activeDocStringSeparator, false);
};
TokenMatcher.prototype._match_DocStringSeparator = function (token, separator, isOpen) {
if (token.line.startsWith(separator)) {
var contentType = null;
if (isOpen) {
contentType = token.line.getRestTrimmed(separator.length);
this.activeDocStringSeparator = separator;
this.indentToRemove = token.line.indent;
}
else {
this.activeDocStringSeparator = null;
this.indentToRemove = 0;
}
// TODO: Use the separator as keyword. That's needed for pretty printing.
this.setTokenMatched(token, Parser_1.TokenType.DocStringSeparator, contentType);
return true;
}
return false;
};
TokenMatcher.prototype.match_EOF = function (token) {
if (token.isEof) {
this.setTokenMatched(token, Parser_1.TokenType.EOF);
return true;
}
return false;
};
TokenMatcher.prototype.match_StepLine = function (token) {
var e_1, _a;
var keywords = []
.concat(this.dialect.given)
.concat(this.dialect.when)
.concat(this.dialect.then)
.concat(this.dialect.and)
.concat(this.dialect.but);
try {
for (var keywords_1 = __values(keywords), keywords_1_1 = keywords_1.next(); !keywords_1_1.done; keywords_1_1 = keywords_1.next()) {
var keyword = keywords_1_1.value;
if (token.line.startsWith(keyword)) {
var title = token.line.getRestTrimmed(keyword.length);
this.setTokenMatched(token, Parser_1.TokenType.StepLine, title, keyword);
return true;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (keywords_1_1 && !keywords_1_1.done && (_a = keywords_1.return)) _a.call(keywords_1);
}
finally { if (e_1) throw e_1.error; }
}
return false;
};
TokenMatcher.prototype.match_Other = function (token) {
var text = token.line.getLineText(this.indentToRemove); // take the entire line, except removing DocString indents
this.setTokenMatched(token, Parser_1.TokenType.Other, this.unescapeDocString(text), null, 0);
return true;
};
TokenMatcher.prototype.matchTitleLine = function (token, tokenType, keywords) {
var e_2, _a;
try {
for (var keywords_2 = __values(keywords), keywords_2_1 = keywords_2.next(); !keywords_2_1.done; keywords_2_1 = keywords_2.next()) {
var keyword = keywords_2_1.value;
if (token.line.startsWithTitleKeyword(keyword)) {
var title = token.line.getRestTrimmed(keyword.length + ':'.length);
this.setTokenMatched(token, tokenType, title, keyword);
return true;
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (keywords_2_1 && !keywords_2_1.done && (_a = keywords_2.return)) _a.call(keywords_2);
}
finally { if (e_2) throw e_2.error; }
}
return false;
};
TokenMatcher.prototype.setTokenMatched = function (token, matchedType, text, keyword, indent, items) {
token.matchedType = matchedType;
token.matchedText = text;
token.matchedKeyword = keyword;
token.matchedIndent =
typeof indent === 'number'
? indent
: token.line == null
? 0
: token.line.indent;
token.matchedItems = items || [];
token.location.column = token.matchedIndent + 1;
token.matchedGherkinDialect = this.dialectName;
};
TokenMatcher.prototype.unescapeDocString = function (text) {
return this.activeDocStringSeparator != null
? text.replace('\\"\\"\\"', '"""')
: text;
};
return TokenMatcher;
}());
exports.default = TokenMatcher;
//# sourceMappingURL=TokenMatcher.js.map