@amiceli/vitest-cucumber
Version:
vitest tools to use Gherkin feature in unit tests
88 lines (87 loc) • 3.06 kB
JavaScript
import path from 'node:path';
import { Project, SyntaxKind, } from 'ts-morph';
import { AstUtils } from './AstUtils';
export class BaseAst {
options;
project;
sourceFile;
onDeleteAction;
formatCommand;
constructor(options) {
this.options = options;
this.onDeleteAction = options.onDeleteAction || 'delete';
this.formatCommand = options.formatCommand;
this.project = new Project({});
this.project.addSourceFilesAtPaths(options.specFilePath);
this.sourceFile = this.checkSourceFile();
}
resetProject() {
this.project.removeSourceFile(this.sourceFile);
this.project.addSourceFilesAtPaths(this.options.specFilePath);
this.sourceFile = this.checkSourceFile();
}
checkSourceFile() {
const realSpecPath = path.resolve(process.cwd(), this.options.specFilePath);
const sourceFile = this.project.getSourceFiles(realSpecPath).at(0);
if (sourceFile) {
return sourceFile;
}
throw new Error(`sourcefile not found : ${realSpecPath}`);
}
callExpressionMatchRegExp(parent, regex) {
return AstUtils.fromArrowFunction(parent)
.listDescendantCallExpressions()
.textMatchRegex(regex)
.getAll()
.map((callExpression) => {
return {
name: this.getFirstArgumentAsString(callExpression),
callExpression,
};
})
.filter((step) => {
return step?.name !== undefined;
});
}
getFirstArgumentAsString(callExpression) {
return callExpression
.getArguments()
.find((arg) => AstUtils.isString(arg.getKind()))
?.getText()
.replace(/^['"`]|['"`]$/g, '');
}
removeChildFromParent(parent, child) {
const childParentNode = child.getParentIfKind(SyntaxKind.ExpressionStatement);
if (childParentNode) {
parent.removeStatement(childParentNode.getChildIndex());
}
}
commentExpression(parent, child) {
const code = child
.getText()
.split('\n')
.map((line) => `// ${line}`)
.join('\n');
this.removeChildFromParent(parent, child);
parent.addStatements(code);
}
updateSyntaxListChild(arrow, newArgs) {
const syntaxListChild = arrow.getFirstChildByKind(SyntaxKind.SyntaxList);
if (syntaxListChild) {
const currentArgs = [
...syntaxListChild
.getText()
.matchAll(/\b(BeforeEachScenario|BeforeAllScenarios|AfterAllScenarios|AfterEachScenario)\b/g),
].map((match) => match[0]);
syntaxListChild.replaceWithText(`{ ${newArgs.concat(currentArgs).join(',')} }`);
}
else {
arrow.insertParameter(0, {
name: `{ ${newArgs.join(',')} }`,
});
}
}
get shouldComment() {
return this.onDeleteAction === 'comment';
}
}