gherkin-ast
Version:
JS model for Gherkin feature files
174 lines • 7.79 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GherkinCommentHandler = exports.replaceArray = exports.cloneArray = exports.replaceAll = exports.prefixString = exports.normalizeString = exports.safeString = void 0;
const comment_1 = require("./ast/comment");
const debug_1 = require("./debug");
const debug = (0, debug_1.getDebugger)("common");
const safeString = (s = "") => {
const safe = s.replace(/\s/g, "_");
debug("safeString(s: '%s') => '%s'", s, safe);
return safe;
};
exports.safeString = safeString;
const normalizeString = (s = "") => {
const normal = s.split("\n")
.map((line) => line.trim())
.join("\n");
debug("normalizeString(s: '%s') => '%s'", s, normal);
return normal;
};
exports.normalizeString = normalizeString;
const prefixString = (s = "", prefix = "", delimiter = " ") => {
const prefixed = s.split("\n")
.map((line) => !line || line.startsWith(prefix) ? line : `${prefix}${delimiter}${line}`)
.join("\n");
debug("prefixString(s: '%s', prefix: '%s', delimiter: '%s') => '%s'", s, prefix, delimiter, prefixed);
return prefixed;
};
exports.prefixString = prefixString;
const replaceAll = (s, key, value) => {
if (!(key instanceof RegExp)) {
key = new RegExp(key, "g");
}
if (!s || typeof s !== "string") {
debug("replaceAll(s: '%s', key: '%s', value: '%s') => '%s'", s, key, value, s);
return s;
}
const result = s.replace(key, value.replace(/\$/g, "$$$$"));
debug("replaceAll(s: '%s', key: '%s', value: '%s') => '%s'", s, key, value, result);
return result;
};
exports.replaceAll = replaceAll;
const cloneArray = (array) => {
debug("cloneArray(array: %d)", array === null || array === void 0 ? void 0 : array.length);
return Array.isArray(array) ? array.map((e) => e.clone()) : [];
};
exports.cloneArray = cloneArray;
const replaceArray = (array, key, value) => {
debug("replaceArray(array: %d, key: '%s', value: '%s')", array === null || array === void 0 ? void 0 : array.length, key, value);
Array.isArray(array) && array.forEach((e) => {
e.replace(key, value);
});
};
exports.replaceArray = replaceArray;
class GherkinCommentHandler {
constructor(comments) {
this.comments = comments;
this.debug = (0, debug_1.getDebugger)('GherkinCommentHandler');
this.debug('constructor(comments: %d)', comments === null || comments === void 0 ? void 0 : comments.length);
this.comments = comments ? [...comments] : [];
this.firstLine = Infinity;
this.lastLine = 0;
if (this.comments.length) {
this.comments.sort((c1, c2) => c1.location.line - c2.location.line);
}
this.debug('constructor(this: {comments: %d, firstLine: %d, lastLine: %d})', this.comments.length, this.firstLine, this.lastLine);
}
storeLine(line) {
this.firstLine = Math.min(this.firstLine, line);
this.lastLine = Math.max(this.lastLine, line);
this.debug('storeLine(line: %d) => {firstLine: %d, lastLine: %d}', line, this.firstLine, this.lastLine);
}
findCommentIndexBefore(location) {
for (let i = 0; i < this.comments.length; ++i) {
if (this.comments[i].location.line == location.line - 1) {
this.debug('findCommentIndexBefore(location: %d) => %d', location === null || location === void 0 ? void 0 : location.line, i);
return i;
}
}
this.debug('findCommentIndexBefore(location: %d) => NOT FOUND', location === null || location === void 0 ? void 0 : location.line);
return -1;
}
popFromIndex(i) {
this.debug('popFromIndex(i: %d)', i);
return this.comments.splice(i, 1)[0];
}
popCommentsRightBefore(location) {
this.storeLine(location.line);
let i = this.findCommentIndexBefore(location);
const comments = [];
if (i > -1) {
comments.push(this.popFromIndex(i));
for (--i; i >= 0; --i) {
if (this.comments[i].location.line < comments[0].location.line - 1) {
break;
}
comments.unshift(this.popFromIndex(i));
}
}
this.debug('popCommentsRightBefore(location: %d) => %d', location === null || location === void 0 ? void 0 : location.line, comments.length);
return comments;
}
parseComment(location, from) {
if (from) {
return this.parseCommentBetween(from, location);
}
const comments = this.popCommentsRightBefore(location);
if (comments.length) {
this.debug('parseComment(location: %d) => %d', location === null || location === void 0 ? void 0 : location.line, comments.length);
return comment_1.Comment.parse(...comments);
}
this.debug('parseComment(location: %d) => NOT FOUND', location === null || location === void 0 ? void 0 : location.line);
return null;
}
parseTagComment(tags) {
if (!Array.isArray(tags) || !tags.length) {
this.debug('parseTagComment(tags: %d) => NOT TAGS', tags === null || tags === void 0 ? void 0 : tags.length);
return null;
}
this.debug('parseTagComment(tags: %d) => %d', tags.length, tags[0].location.line);
return this.parseComment(tags[0].location);
}
parseCommentBetween(locA, locB) {
if (!locA || !locB) {
this.debug('parseCommentBetween(locA: %d, locB: %d) => NO LOCS', locA === null || locA === void 0 ? void 0 : locA.line, locB === null || locB === void 0 ? void 0 : locB.line);
return null;
}
this.storeLine(locA.line);
this.storeLine(locB.line);
let i = 0;
const comments = [];
for (; i < this.comments.length && this.comments[i].location.line < locA.line; ++i)
;
for (; i < this.comments.length && this.comments[i].location.line < locB.line;) {
comments.push(this.popFromIndex(i));
}
this.debug('parseCommentBetween(locA: %d, locB: %d) => %d', locA === null || locA === void 0 ? void 0 : locA.line, locB === null || locB === void 0 ? void 0 : locB.line, comments.length);
return this.parseMultiLineComment(comments);
}
parseStartingComment() {
const comments = [];
for (let i = 0; i < this.comments.length && this.comments[i].location.line < this.firstLine;) {
comments.push(this.popFromIndex(i));
}
this.debug('parseStartingComment() => %d', comments.length);
return this.parseMultiLineComment(comments);
}
parseEndingComment() {
const comments = [];
let i = 0;
for (; i < this.comments.length && this.comments[i].location.line < this.lastLine; ++i)
;
for (; i < this.comments.length;) {
comments.push(this.popFromIndex(i));
}
this.debug('parseEndingComment() => %d', comments.length);
return this.parseMultiLineComment(comments);
}
parseMultiLineComment(comments) {
if (!comments.length) {
this.debug('parseMultiLineComment(comments: %d) => NO COMMENTS', comments.length);
return null;
}
const lines = [];
const firstLine = comments[0].location.line;
for (const comment of comments) {
lines[comment.location.line - firstLine] = comment.text;
}
const comment = new comment_1.Comment(lines.join("\n"));
this.debug("parseMultiLineComment(comments: %d) => '%s'", comments.length, comment.text);
return comment;
}
}
exports.GherkinCommentHandler = GherkinCommentHandler;
//# sourceMappingURL=common.js.map