UNPKG

@amiceli/vitest-cucumber

Version:

vitest tools to use Gherkin feature in unit tests

102 lines (101 loc) 3.88 kB
import { exec } from 'node:child_process'; import { promisify } from 'node:util'; import { SyntaxKind } from 'ts-morph'; import { writeSpecFile } from '../../../scripts/generateFile'; import { VitestsCucumberError } from '../../errors/errors'; import { FeatureFileReader } from '../../parser/readfile'; import { getVitestCucumberConfiguration } from '../../vitest/configuration'; import { AstUtils } from './AstUtils'; import { BackgroundAst } from './BackgroundAst'; import { BaseAst } from './BaseAst'; import { RuleAst } from './RuleAst'; import { ScenarioAst } from './ScenarioAst'; export class FeatureAst extends BaseAst { feature = null; constructor(options) { super(options); } static fromOptions(options) { return new FeatureAst(options); } async loadFeautreFromFile() { const [feature] = await FeatureFileReader.fromPath({ featureFilePath: this.options.featureFilePath, callerFileDir: null, options: getVitestCucumberConfiguration(), }).parseFile(); return feature; } async updateSpecFile() { try { this.feature = await this.loadFeautreFromFile(); await this.handleDescribeFeature(); this.handleFeature(); await this.formatAndSave(); if (this.options.formatCommand) { const execPromise = promisify(exec); await execPromise(`${this.options.formatCommand} ${this.options.specFilePath}`); } } catch (e) { throw new VitestsCucumberError(`FeatureAst error: ${e.message}`); } } async handleDescribeFeature() { if (!this.describeFeature && this.feature) { await writeSpecFile({ feature: this.feature, specFilePath: this.options.specFilePath, featureFilePath: this.options.featureFilePath, }); this.resetProject(); } } handleFeature() { if (this.describeFeatureCallback && this.feature) { ScenarioAst.fromOptions({ ...this.options, stepableParent: this.feature, stepableParentFunction: this.describeFeatureCallback, }).handleScenarii(); RuleAst.fromOptions({ ...this.options, ruleParent: this.feature, ruleParentFunction: this.describeFeatureCallback, }).handleRules(); BackgroundAst.fromOptions({ ...this.options, stepableParent: this.feature, stepableParentFunction: this.describeFeatureCallback, }).handleBackground(); this.updateFeatureArguments(this.feature, this.describeFeatureCallback); } } updateFeatureArguments(feature, featureArrowFunction) { const featureRequiredArgs = [ feature.background !== null ? 'Background' : undefined, feature.hasScenarioOutline ? 'ScenarioOutline' : undefined, feature.hasScenario ? 'Scenario' : undefined, feature.rules.length > 0 ? 'Rule' : undefined, ].filter((a) => a !== undefined); this.updateSyntaxListChild(featureArrowFunction, featureRequiredArgs); } async formatAndSave() { this.sourceFile.formatText(); await this.sourceFile.save(); } get describeFeature() { return AstUtils.fromSourceFile(this.sourceFile) .listDescendantCallExpressions() .matchExpressionName('describeFeature') .getOne(); } get describeFeatureCallback() { if (this.describeFeature) { return this.describeFeature .getArguments() .find((arg) => arg.isKind(SyntaxKind.ArrowFunction)); } return undefined; } }