UNPKG

@ply-ct/ply

Version:

REST API Automated Testing

117 lines (100 loc) 3.58 kB
import { Step, StepInstance } from '../flowbee'; import { ExecContext } from './context'; import { RunOptions } from '../options'; import { Values } from '../values'; import { ResultData, Outcome, Verifier } from '../result'; import { Runtime } from '../runtime'; import { Log } from '../log'; import { replace, replaceLine } from '../replace'; import { lines } from '../util'; import { ExecResult, StepExec } from './exec'; /** * Wraps a legacy PlyExecBase implementation */ export class LegacyExec extends StepExec { constructor(private plyExecBase: PlyExecBase) { super(); } async run(context: ExecContext): Promise<ExecResult> { return this.plyExecBase.run(context.runtime, context.values, context.runOptions); } } /** * @deprecated Extend StepExec or implement PlyExec directly */ export abstract class PlyExecBase { static legacy = true; constructor(readonly step: Step, readonly instance: StepInstance, readonly logger: Log) {} abstract run(runtime: Runtime, values: Values, runOptions?: RunOptions): Promise<ExecResult>; protected evaluateToString(expr: string, values: Values, trusted = false): string { return replaceLine(expr, values, { trusted, logger: this.logger }); } /** * Returns a substituted attribute value */ protected getAttribute( name: string, values: Values, options?: { trusted?: boolean; required?: boolean } ): string | undefined { if (this.step.attributes) { const val = this.step.attributes[name]; if (val) { return replace(val, values, { logger: this.logger, trusted: options?.trusted }); } } if (options?.required) throw new Error(`Missing required attribute: ${name}`); } isTrustRequired(): boolean { return true; } isExpression(input: string): boolean { return input.startsWith('${') && input.endsWith('}'); } async verifyData( runtime: Runtime, data: ResultData, values: Values, runOptions?: RunOptions ): Promise<Outcome> { if (runOptions?.submit) return { status: 'Submitted', data }; if (runOptions?.createExpected) return { status: 'Passed', data }; const indent = runtime.options.prettyIndent; const actualYaml = runtime.results.getActualYaml(this.step.id); let actualYamlText = actualYaml.text + 'data: |\n'.padStart(8 + indent); for (const line of lines(JSON.stringify(data, null, indent))) { actualYamlText += line.padStart(line.length + 2 * indent) + '\n'; } const expectedYaml = await runtime.results.getExpectedYaml(this.step.id); const verifier = new Verifier( this.step.name.replace(/\r?\n/g, ' '), expectedYaml, this.logger ); const outcome = verifier.verify( { ...actualYaml, text: actualYamlText }, values, runOptions ); outcome.data = data; return outcome; } /** * Tagged log at info level */ logInfo(message: string, obj?: any) { this.logger.info(`${this.step.id} => ${message}`, obj); } /** * Tagged log at error level */ logError(message: string, obj?: any) { this.logger.error(`${this.step.id} => ${message}`, obj); } /** * Tagged log at debug level */ logDebug(message: string, obj?: any) { this.logger.debug(`${this.step.id} => ${message}`, obj); } }