refactor script compilation to make it easy to add new expressions #41 #53

This commit is contained in:
undergroundwires
2021-03-05 15:52:49 +01:00
parent 1f8a0cf9ab
commit 646db90585
42 changed files with 1312 additions and 582 deletions

View File

@@ -0,0 +1,17 @@
import { IProjectInformation } from '@/domain/IProjectInformation';
import { ICodeSubstituter } from '@/application/Parser/ScriptingDefinition/ICodeSubstituter';
export class CodeSubstituterStub implements ICodeSubstituter {
private readonly scenarios = new Array<{ code: string, info: IProjectInformation, result: string}>();
public substitute(code: string, info: IProjectInformation): string {
const scenario = this.scenarios.find((s) => s.code === code && s.info === info);
if (scenario) {
return scenario.result;
}
return `[CodeSubstituterStub] - code: ${code}`;
}
public setup( code: string, info: IProjectInformation, result: string) {
this.scenarios.push({ code, info, result});
return this;
}
}

View File

@@ -1,15 +1,24 @@
import { IEnumParser } from '@/application/Common/Enum';
export function mockEnumParser<T>(inputName: string, inputValue: string, outputValue: T): IEnumParser<T> {
return {
parseEnum: (value, name) => {
if (name !== inputName) {
throw new Error(`Unexpected name: "${name}"`);
}
if (value !== inputValue) {
throw new Error(`Unexpected value: "${value}"`);
}
return outputValue;
},
};
export class EnumParserStub<T> implements IEnumParser<T> {
private readonly scenarios = new Array<{ inputName: string, inputValue: string, outputValue: T }>();
private defaultValue: T;
public setup(inputName: string, inputValue: string, outputValue: T) {
this.scenarios.push({inputName, inputValue, outputValue});
return this;
}
public setupDefaultValue(outputValue: T) {
this.defaultValue = outputValue;
return this;
}
public parseEnum(value: string, propertyName: string): T {
const scenario = this.scenarios.find((s) => s.inputName === propertyName && s.inputValue === value);
if (scenario) {
return scenario.outputValue;
}
if (this.defaultValue) {
return this.defaultValue;
}
throw new Error('enum parser is not set up');
}
}

View File

@@ -0,0 +1,15 @@
import { IExpression } from '@/application/Parser/Script/Compiler/Expressions/Expression/IExpression';
import { IExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/IExpressionParser';
export class ExpressionParserStub implements IExpressionParser {
public callHistory = new Array<string>();
private result: IExpression[] = [];
public withResult(result: IExpression[]) {
this.result = result;
return this;
}
public findExpressions(code: string): IExpression[] {
this.callHistory.push(code);
return this.result;
}
}

View File

@@ -0,0 +1,26 @@
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { ExpressionArguments, IExpression } from '@/application/Parser/Script/Compiler/Expressions/Expression/IExpression';
export class ExpressionStub implements IExpression {
public callHistory = new Array<ExpressionArguments>();
public position = new ExpressionPosition(0, 5);
public parameters = [];
private result: string;
public withParameters(...parameters: string[]) {
this.parameters = parameters;
return this;
}
public withPosition(start: number, end: number) {
this.position = new ExpressionPosition(start, end);
return this;
}
public withEvaluatedResult(result: string) {
this.result = result;
return this;
}
public evaluate(args?: ExpressionArguments): string {
this.callHistory.push(args);
const result = this.result || `[expression-stub] args: ${args ? Object.keys(args).map((key) => `${key}: ${args[key]}`).join('", "') : 'none'}`;
return result;
}
}

View File

@@ -3,12 +3,14 @@ import { IExpressionsCompiler, ParameterValueDictionary } from '@/application/Pa
interface Scenario { code: string; parameters: ParameterValueDictionary; result: string; }
export class ExpressionsCompilerStub implements IExpressionsCompiler {
public readonly callHistory = new Array<{code: string, parameters?: ParameterValueDictionary}>();
private readonly scenarios = new Array<Scenario>();
public setup(code: string, parameters: ParameterValueDictionary, result: string) {
this.scenarios.push({ code, parameters, result });
return this;
}
public compileExpressions(code: string, parameters?: ParameterValueDictionary): string {
this.callHistory.push({ code, parameters});
const scenario = this.scenarios.find((s) => s.code === code && deepEqual(s.parameters, parameters));
if (scenario) {
return scenario.result;

View File

@@ -0,0 +1,29 @@
import { ScriptingDefinitionData } from 'js-yaml-loader!@/*';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
export class ScriptingDefinitionDataStub implements ScriptingDefinitionData {
public language = ScriptingLanguage[ScriptingLanguage.batchfile];
public fileExtension = 'bat';
public startCode = 'startCode';
public endCode = 'endCode';
public withLanguage(language: string): ScriptingDefinitionDataStub {
this.language = language;
return this;
}
public withStartCode(startCode: string): ScriptingDefinitionDataStub {
this.startCode = startCode;
return this;
}
public withEndCode(endCode: string): ScriptingDefinitionDataStub {
this.endCode = endCode;
return this;
}
public withExtension(extension: string): ScriptingDefinitionDataStub {
this.fileExtension = extension;
return this;
}
}