Move stubs from ./stubs to ./shared/Stubs
Gathers all shared test code in single place.
This commit is contained in:
10
tests/unit/shared/Stubs/ApplicationCodeStub.ts
Normal file
10
tests/unit/shared/Stubs/ApplicationCodeStub.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { ICodeChangedEvent } from '@/application/Context/State/Code/Event/ICodeChangedEvent';
|
||||
import { IApplicationCode } from '@/application/Context/State/Code/IApplicationCode';
|
||||
import { IEventSource } from '@/infrastructure/Events/IEventSource';
|
||||
import { EventSource } from '@/infrastructure/Events/EventSource';
|
||||
|
||||
export class ApplicationCodeStub implements IApplicationCode {
|
||||
public changed: IEventSource<ICodeChangedEvent> = new EventSource<ICodeChangedEvent>();
|
||||
|
||||
public current = '';
|
||||
}
|
||||
34
tests/unit/shared/Stubs/ApplicationStub.ts
Normal file
34
tests/unit/shared/Stubs/ApplicationStub.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { IApplication } from '@/domain/IApplication';
|
||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { IProjectInformation } from '@/domain/IProjectInformation';
|
||||
import { ProjectInformationStub } from './ProjectInformationStub';
|
||||
|
||||
export class ApplicationStub implements IApplication {
|
||||
public info: IProjectInformation = new ProjectInformationStub();
|
||||
|
||||
public collections: ICategoryCollection[] = [];
|
||||
|
||||
public getCollection(operatingSystem: OperatingSystem): ICategoryCollection {
|
||||
return this.collections.find((collection) => collection.os === operatingSystem);
|
||||
}
|
||||
|
||||
public getSupportedOsList(): OperatingSystem[] {
|
||||
return this.collections.map((collection) => collection.os);
|
||||
}
|
||||
|
||||
public withCollection(collection: ICategoryCollection): ApplicationStub {
|
||||
this.collections.push(collection);
|
||||
return this;
|
||||
}
|
||||
|
||||
public withProjectInformation(info: IProjectInformation): ApplicationStub {
|
||||
this.info = info;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCollections(...collections: readonly ICategoryCollection[]): ApplicationStub {
|
||||
this.collections.push(...collections);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { ICategoryCollectionParseContext } from '@/application/Parser/Script/ICategoryCollectionParseContext';
|
||||
import { IScriptCompiler } from '@/application/Parser/Script/Compiler/IScriptCompiler';
|
||||
import { ILanguageSyntax } from '@/domain/ScriptCode';
|
||||
import { ScriptCompilerStub } from './ScriptCompilerStub';
|
||||
import { LanguageSyntaxStub } from './LanguageSyntaxStub';
|
||||
|
||||
export class CategoryCollectionParseContextStub implements ICategoryCollectionParseContext {
|
||||
public compiler: IScriptCompiler = new ScriptCompilerStub();
|
||||
|
||||
public syntax: ILanguageSyntax = new LanguageSyntaxStub();
|
||||
|
||||
public withCompiler(compiler: IScriptCompiler) {
|
||||
this.compiler = compiler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withSyntax(syntax: ILanguageSyntax) {
|
||||
this.syntax = syntax;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
36
tests/unit/shared/Stubs/CategoryCollectionStateStub.ts
Normal file
36
tests/unit/shared/Stubs/CategoryCollectionStateStub.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { IApplicationCode } from '@/application/Context/State/Code/IApplicationCode';
|
||||
import { IUserFilter } from '@/application/Context/State/Filter/IUserFilter';
|
||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
|
||||
import { IScript } from '@/domain/IScript';
|
||||
import { CategoryCollectionStub } from './CategoryCollectionStub';
|
||||
import { UserSelectionStub } from './UserSelectionStub';
|
||||
import { UserFilterStub } from './UserFilterStub';
|
||||
import { ApplicationCodeStub } from './ApplicationCodeStub';
|
||||
import { CategoryStub } from './CategoryStub';
|
||||
|
||||
export class CategoryCollectionStateStub implements ICategoryCollectionState {
|
||||
public readonly code: IApplicationCode = new ApplicationCodeStub();
|
||||
|
||||
public readonly filter: IUserFilter = new UserFilterStub();
|
||||
|
||||
public readonly os = OperatingSystem.Windows;
|
||||
|
||||
public readonly collection: CategoryCollectionStub;
|
||||
|
||||
public readonly selection: UserSelectionStub;
|
||||
|
||||
constructor(readonly allScripts: IScript[]) {
|
||||
this.selection = new UserSelectionStub(allScripts);
|
||||
this.collection = new CategoryCollectionStub()
|
||||
.withOs(this.os)
|
||||
.withTotalScripts(this.allScripts.length)
|
||||
.withAction(new CategoryStub(0).withScripts(...allScripts));
|
||||
}
|
||||
|
||||
public withSelectedScripts(initialScripts: readonly SelectedScript[]) {
|
||||
this.selection.withSelectedScripts(initialScripts);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
87
tests/unit/shared/Stubs/CategoryCollectionStub.ts
Normal file
87
tests/unit/shared/Stubs/CategoryCollectionStub.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
||||
import { IScript } from '@/domain/IScript';
|
||||
import { ICategory } from '@/domain/ICategory';
|
||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||
import { RecommendationLevel } from '@/domain/RecommendationLevel';
|
||||
import { ScriptStub } from './ScriptStub';
|
||||
import { ScriptingDefinitionStub } from './ScriptingDefinitionStub';
|
||||
|
||||
export class CategoryCollectionStub implements ICategoryCollection {
|
||||
public scripting: IScriptingDefinition = new ScriptingDefinitionStub();
|
||||
|
||||
public os = OperatingSystem.Linux;
|
||||
|
||||
public initialScript: IScript = new ScriptStub('55');
|
||||
|
||||
public totalScripts = 0;
|
||||
|
||||
public totalCategories = 0;
|
||||
|
||||
public readonly actions = new Array<ICategory>();
|
||||
|
||||
public withAction(category: ICategory): CategoryCollectionStub {
|
||||
this.actions.push(category);
|
||||
return this;
|
||||
}
|
||||
|
||||
public withOs(os: OperatingSystem): CategoryCollectionStub {
|
||||
this.os = os;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withScripting(scripting: IScriptingDefinition): CategoryCollectionStub {
|
||||
this.scripting = scripting;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withInitialScript(script: IScript): CategoryCollectionStub {
|
||||
this.initialScript = script;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withTotalScripts(totalScripts: number) {
|
||||
this.totalScripts = totalScripts;
|
||||
return this;
|
||||
}
|
||||
|
||||
public findCategory(categoryId: number): ICategory {
|
||||
return this.getAllCategories()
|
||||
.find((category) => category.id === categoryId);
|
||||
}
|
||||
|
||||
public getScriptsByLevel(level: RecommendationLevel): readonly IScript[] {
|
||||
return this.getAllScripts()
|
||||
.filter((script) => script.level !== undefined && script.level <= level);
|
||||
}
|
||||
|
||||
public findScript(scriptId: string): IScript {
|
||||
return this.getAllScripts()
|
||||
.find((script) => scriptId === script.id);
|
||||
}
|
||||
|
||||
public getAllScripts(): ReadonlyArray<IScript> {
|
||||
return this.actions.flatMap((category) => getScriptsRecursively(category));
|
||||
}
|
||||
|
||||
public getAllCategories(): ReadonlyArray<ICategory> {
|
||||
return this.actions.flatMap(
|
||||
(category) => [category, ...getSubCategoriesRecursively(category)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getSubCategoriesRecursively(category: ICategory): ReadonlyArray<ICategory> {
|
||||
return (category.subCategories || []).flatMap(
|
||||
(subCategory) => [subCategory, ...getSubCategoriesRecursively(subCategory)],
|
||||
);
|
||||
}
|
||||
|
||||
function getScriptsRecursively(category: ICategory): ReadonlyArray<IScript> {
|
||||
return [
|
||||
...(category.scripts || []),
|
||||
...(category.subCategories || []).flatMap(
|
||||
(subCategory) => getScriptsRecursively(subCategory),
|
||||
),
|
||||
];
|
||||
}
|
||||
25
tests/unit/shared/Stubs/CategoryDataStub.ts
Normal file
25
tests/unit/shared/Stubs/CategoryDataStub.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { CategoryData, CategoryOrScriptData, DocumentationUrlsData } from 'js-yaml-loader!@/*';
|
||||
import { ScriptDataStub } from './ScriptDataStub';
|
||||
|
||||
export class CategoryDataStub implements CategoryData {
|
||||
public children: readonly CategoryOrScriptData[] = [ScriptDataStub.createWithCode()];
|
||||
|
||||
public category = 'category name';
|
||||
|
||||
public docs?: DocumentationUrlsData;
|
||||
|
||||
public withChildren(children: readonly CategoryOrScriptData[]) {
|
||||
this.children = children;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withName(name: string) {
|
||||
this.category = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withDocs(docs: DocumentationUrlsData) {
|
||||
this.docs = docs;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
63
tests/unit/shared/Stubs/CategoryStub.ts
Normal file
63
tests/unit/shared/Stubs/CategoryStub.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
|
||||
import { ICategory, IScript } from '@/domain/ICategory';
|
||||
import { ScriptStub } from './ScriptStub';
|
||||
|
||||
export class CategoryStub extends BaseEntity<number> implements ICategory {
|
||||
public name = `category-with-id-${this.id}`;
|
||||
|
||||
public readonly subCategories = new Array<ICategory>();
|
||||
|
||||
public readonly scripts = new Array<IScript>();
|
||||
|
||||
public readonly documentationUrls = new Array<string>();
|
||||
|
||||
public constructor(id: number) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public includes(script: IScript): boolean {
|
||||
return this.getAllScriptsRecursively().some((s) => s.id === script.id);
|
||||
}
|
||||
|
||||
public getAllScriptsRecursively(): readonly IScript[] {
|
||||
return [
|
||||
...this.scripts,
|
||||
...this.subCategories.flatMap((c) => c.getAllScriptsRecursively()),
|
||||
];
|
||||
}
|
||||
|
||||
public withScriptIds(...scriptIds: string[]): CategoryStub {
|
||||
return this.withScripts(
|
||||
...scriptIds.map((id) => new ScriptStub(id)),
|
||||
);
|
||||
}
|
||||
|
||||
public withScripts(...scripts: IScript[]): CategoryStub {
|
||||
for (const script of scripts) {
|
||||
this.withScript(script);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCategories(...categories: ICategory[]): CategoryStub {
|
||||
for (const category of categories) {
|
||||
this.withCategory(category);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCategory(category: ICategory): CategoryStub {
|
||||
this.subCategories.push(category);
|
||||
return this;
|
||||
}
|
||||
|
||||
public withScript(script: IScript): CategoryStub {
|
||||
this.scripts.push(script);
|
||||
return this;
|
||||
}
|
||||
|
||||
public withName(categoryName: string) {
|
||||
this.name = categoryName;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
20
tests/unit/shared/Stubs/CodeSubstituterStub.ts
Normal file
20
tests/unit/shared/Stubs/CodeSubstituterStub.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
67
tests/unit/shared/Stubs/CollectionDataStub.ts
Normal file
67
tests/unit/shared/Stubs/CollectionDataStub.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import {
|
||||
CategoryData, ScriptData, CollectionData, ScriptingDefinitionData, FunctionData,
|
||||
} from 'js-yaml-loader!@/*';
|
||||
import { RecommendationLevel } from '@/domain/RecommendationLevel';
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
|
||||
export class CollectionDataStub implements CollectionData {
|
||||
public os = 'windows';
|
||||
|
||||
public actions: readonly CategoryData[] = [getCategoryStub()];
|
||||
|
||||
public scripting: ScriptingDefinitionData = getTestDefinitionStub();
|
||||
|
||||
public functions?: ReadonlyArray<FunctionData>;
|
||||
|
||||
public withActions(actions: readonly CategoryData[]): CollectionDataStub {
|
||||
this.actions = actions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withOs(os: string): CollectionDataStub {
|
||||
this.os = os;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withScripting(scripting: ScriptingDefinitionData): CollectionDataStub {
|
||||
this.scripting = scripting;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withFunctions(functions: ReadonlyArray<FunctionData>) {
|
||||
this.functions = functions;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export function getCategoryStub(scriptPrefix = 'testScript'): CategoryData {
|
||||
return {
|
||||
category: 'category name',
|
||||
children: [
|
||||
getScriptStub(`${scriptPrefix}-standard`, RecommendationLevel.Standard),
|
||||
getScriptStub(`${scriptPrefix}-strict`, RecommendationLevel.Strict),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
function getTestDefinitionStub(): ScriptingDefinitionData {
|
||||
return {
|
||||
fileExtension: '.bat',
|
||||
language: ScriptingLanguage[ScriptingLanguage.batchfile],
|
||||
startCode: 'start',
|
||||
endCode: 'end',
|
||||
};
|
||||
}
|
||||
|
||||
function getScriptStub(
|
||||
scriptName: string,
|
||||
level: RecommendationLevel = RecommendationLevel.Standard,
|
||||
): ScriptData {
|
||||
return {
|
||||
name: scriptName,
|
||||
code: 'script code',
|
||||
revertCode: 'revert code',
|
||||
recommend: RecommendationLevel[level].toLowerCase(),
|
||||
call: undefined,
|
||||
};
|
||||
}
|
||||
31
tests/unit/shared/Stubs/EnumParserStub.ts
Normal file
31
tests/unit/shared/Stubs/EnumParserStub.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { IEnumParser } from '@/application/Common/Enum';
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
13
tests/unit/shared/Stubs/EnvironmentStub.ts
Normal file
13
tests/unit/shared/Stubs/EnvironmentStub.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { IEnvironment } from '@/application/Environment/IEnvironment';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
|
||||
export class EnvironmentStub implements IEnvironment {
|
||||
public isDesktop = true;
|
||||
|
||||
public os = OperatingSystem.Windows;
|
||||
|
||||
public withOs(os: OperatingSystem): EnvironmentStub {
|
||||
this.os = os;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
22
tests/unit/shared/Stubs/ExpressionEvaluationContextStub.ts
Normal file
22
tests/unit/shared/Stubs/ExpressionEvaluationContextStub.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { IExpressionEvaluationContext } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
|
||||
import { IPipelineCompiler } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
|
||||
import { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
|
||||
import { FunctionCallArgumentCollectionStub } from './FunctionCallArgumentCollectionStub';
|
||||
import { PipelineCompilerStub } from './PipelineCompilerStub';
|
||||
|
||||
export class ExpressionEvaluationContextStub implements IExpressionEvaluationContext {
|
||||
public args: IReadOnlyFunctionCallArgumentCollection = new FunctionCallArgumentCollectionStub()
|
||||
.withArgument('test-arg', 'test-value');
|
||||
|
||||
public pipelineCompiler: IPipelineCompiler = new PipelineCompilerStub();
|
||||
|
||||
public withArgs(args: IReadOnlyFunctionCallArgumentCollection) {
|
||||
this.args = args;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withPipelineCompiler(pipelineCompiler: IPipelineCompiler) {
|
||||
this.pipelineCompiler = pipelineCompiler;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
18
tests/unit/shared/Stubs/ExpressionParserStub.ts
Normal file
18
tests/unit/shared/Stubs/ExpressionParserStub.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
43
tests/unit/shared/Stubs/ExpressionStub.ts
Normal file
43
tests/unit/shared/Stubs/ExpressionStub.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
|
||||
import { IExpression } from '@/application/Parser/Script/Compiler/Expressions/Expression/IExpression';
|
||||
import { IReadOnlyFunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
|
||||
import { IExpressionEvaluationContext } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
|
||||
import { FunctionParameterCollectionStub } from './FunctionParameterCollectionStub';
|
||||
|
||||
export class ExpressionStub implements IExpression {
|
||||
public callHistory = new Array<IExpressionEvaluationContext>();
|
||||
|
||||
public position = new ExpressionPosition(0, 5);
|
||||
|
||||
public parameters: IReadOnlyFunctionParameterCollection = new FunctionParameterCollectionStub();
|
||||
|
||||
private result: string;
|
||||
|
||||
public withParameters(parameters: IReadOnlyFunctionParameterCollection) {
|
||||
this.parameters = parameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withParameterNames(parameterNames: readonly string[], isOptional = false) {
|
||||
const collection = new FunctionParameterCollectionStub()
|
||||
.withParameterNames(parameterNames, isOptional);
|
||||
return this.withParameters(collection);
|
||||
}
|
||||
|
||||
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(context: IExpressionEvaluationContext): string {
|
||||
const { args } = context;
|
||||
this.callHistory.push(context);
|
||||
const result = this.result || `[expression-stub] args: ${args ? Object.keys(args).map((key) => `${key}: ${args[key]}`).join('", "') : 'none'}`;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
66
tests/unit/shared/Stubs/ExpressionsCompilerStub.ts
Normal file
66
tests/unit/shared/Stubs/ExpressionsCompilerStub.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
|
||||
import { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
|
||||
import { scrambledEqual } from '@/application/Common/Array';
|
||||
import { ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
|
||||
import { FunctionCallArgumentCollectionStub } from '@tests/unit/shared/Stubs/FunctionCallArgumentCollectionStub';
|
||||
|
||||
export class ExpressionsCompilerStub implements IExpressionsCompiler {
|
||||
public readonly callHistory =
|
||||
new Array<{ code: string, parameters: IReadOnlyFunctionCallArgumentCollection }>();
|
||||
|
||||
private readonly scenarios = new Array<ITestScenario>();
|
||||
|
||||
public setup(scenario: ITestScenario): ExpressionsCompilerStub {
|
||||
this.scenarios.push(scenario);
|
||||
return this;
|
||||
}
|
||||
|
||||
public setupToReturnFunctionCode(
|
||||
func: ISharedFunction,
|
||||
givenArgs: FunctionCallArgumentCollectionStub,
|
||||
) {
|
||||
return this
|
||||
.setup({ givenCode: func.body.code.do, givenArgs, result: func.body.code.do })
|
||||
.setup({ givenCode: func.body.code.revert, givenArgs, result: func.body.code.revert });
|
||||
}
|
||||
|
||||
public compileExpressions(
|
||||
code: string,
|
||||
parameters: IReadOnlyFunctionCallArgumentCollection,
|
||||
): string {
|
||||
this.callHistory.push({ code, parameters });
|
||||
const scenario = this.scenarios.find(
|
||||
(s) => s.givenCode === code && deepEqual(s.givenArgs, parameters),
|
||||
);
|
||||
if (scenario) {
|
||||
return scenario.result;
|
||||
}
|
||||
const parametersAndValues = parameters
|
||||
.getAllParameterNames()
|
||||
.map((name) => `${name}=${parameters.getArgument(name).argumentValue}`)
|
||||
.join('\n\t');
|
||||
return `[ExpressionsCompilerStub]\ncode: "${code}"\nparameters: ${parametersAndValues}`;
|
||||
}
|
||||
}
|
||||
|
||||
interface ITestScenario {
|
||||
readonly givenCode: string;
|
||||
readonly givenArgs: IReadOnlyFunctionCallArgumentCollection;
|
||||
readonly result: string;
|
||||
}
|
||||
|
||||
function deepEqual(
|
||||
expected: IReadOnlyFunctionCallArgumentCollection,
|
||||
actual: IReadOnlyFunctionCallArgumentCollection,
|
||||
): boolean {
|
||||
const expectedParameterNames = expected.getAllParameterNames();
|
||||
const actualParameterNames = actual.getAllParameterNames();
|
||||
if (!scrambledEqual(expectedParameterNames, actualParameterNames)) {
|
||||
return false;
|
||||
}
|
||||
return expectedParameterNames.every((parameterName) => {
|
||||
const expectedValue = expected.getArgument(parameterName).argumentValue;
|
||||
const actualValue = actual.getArgument(parameterName).argumentValue;
|
||||
return expectedValue === actualValue;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { IFunctionCallArgument } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgument';
|
||||
import { IFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
|
||||
import { FunctionCallArgumentStub } from './FunctionCallArgumentStub';
|
||||
|
||||
export class FunctionCallArgumentCollectionStub implements IFunctionCallArgumentCollection {
|
||||
private args = new Array<IFunctionCallArgument>();
|
||||
|
||||
public withArgument(parameterName: string, argumentValue: string) {
|
||||
const arg = new FunctionCallArgumentStub()
|
||||
.withParameterName(parameterName)
|
||||
.withArgumentValue(argumentValue);
|
||||
this.addArgument(arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
public withArguments(args: { readonly [index: string]: string }) {
|
||||
for (const [name, value] of Object.entries(args)) {
|
||||
this.withArgument(name, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public hasArgument(parameterName: string): boolean {
|
||||
return this.args.some((a) => a.parameterName === parameterName);
|
||||
}
|
||||
|
||||
public addArgument(argument: IFunctionCallArgument): void {
|
||||
this.args.push(argument);
|
||||
}
|
||||
|
||||
public getAllParameterNames(): string[] {
|
||||
return this.args.map((a) => a.parameterName);
|
||||
}
|
||||
|
||||
public getArgument(parameterName: string): IFunctionCallArgument {
|
||||
const arg = this.args.find((a) => a.parameterName === parameterName);
|
||||
if (!arg) {
|
||||
throw new Error(`no argument exists for parameter "${parameterName}"`);
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
17
tests/unit/shared/Stubs/FunctionCallArgumentStub.ts
Normal file
17
tests/unit/shared/Stubs/FunctionCallArgumentStub.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { IFunctionCallArgument } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgument';
|
||||
|
||||
export class FunctionCallArgumentStub implements IFunctionCallArgument {
|
||||
public parameterName = 'stub-parameter-name';
|
||||
|
||||
public argumentValue = 'stub-arg-name';
|
||||
|
||||
public withParameterName(parameterName: string) {
|
||||
this.parameterName = parameterName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withArgumentValue(argumentValue: string) {
|
||||
this.argumentValue = argumentValue;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
48
tests/unit/shared/Stubs/FunctionCallCompilerStub.ts
Normal file
48
tests/unit/shared/Stubs/FunctionCallCompilerStub.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { ICompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/ICompiledCode';
|
||||
import { IFunctionCallCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/IFunctionCallCompiler';
|
||||
import { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
|
||||
import { IFunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/IFunctionCall';
|
||||
|
||||
interface IScenario {
|
||||
calls: IFunctionCall[];
|
||||
functions: ISharedFunctionCollection;
|
||||
result: ICompiledCode;
|
||||
}
|
||||
|
||||
export class FunctionCallCompilerStub implements IFunctionCallCompiler {
|
||||
public scenarios = new Array<IScenario>();
|
||||
|
||||
public setup(
|
||||
calls: IFunctionCall[],
|
||||
functions: ISharedFunctionCollection,
|
||||
result: ICompiledCode,
|
||||
) {
|
||||
this.scenarios.push({ calls, functions, result });
|
||||
}
|
||||
|
||||
public compileCall(
|
||||
calls: IFunctionCall[],
|
||||
functions: ISharedFunctionCollection,
|
||||
): ICompiledCode {
|
||||
const predefined = this.scenarios
|
||||
.find((s) => areEqual(s.calls, calls) && s.functions === functions);
|
||||
if (predefined) {
|
||||
return predefined.result;
|
||||
}
|
||||
return {
|
||||
code: 'function code [FunctionCallCompilerStub]',
|
||||
revertCode: 'function revert code [FunctionCallCompilerStub]',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function areEqual(
|
||||
first: readonly IFunctionCall[],
|
||||
second: readonly IFunctionCall[],
|
||||
) {
|
||||
const comparer = (a: IFunctionCall, b: IFunctionCall) => a.functionName
|
||||
.localeCompare(b.functionName);
|
||||
const printSorted = (calls: readonly IFunctionCall[]) => JSON
|
||||
.stringify([...calls].sort(comparer));
|
||||
return printSorted(first) === printSorted(second);
|
||||
}
|
||||
17
tests/unit/shared/Stubs/FunctionCallDataStub.ts
Normal file
17
tests/unit/shared/Stubs/FunctionCallDataStub.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { FunctionCallData, FunctionCallParametersData } from 'js-yaml-loader!@/*';
|
||||
|
||||
export class FunctionCallDataStub implements FunctionCallData {
|
||||
public function = 'callDatStubCalleeFunction';
|
||||
|
||||
public parameters: { [index: string]: string } = { testParameter: 'testArgument' };
|
||||
|
||||
public withName(functionName: string) {
|
||||
this.function = functionName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withParameters(parameters: FunctionCallParametersData) {
|
||||
this.parameters = parameters;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
28
tests/unit/shared/Stubs/FunctionCallStub.ts
Normal file
28
tests/unit/shared/Stubs/FunctionCallStub.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { IFunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/IFunctionCall';
|
||||
import { FunctionCallArgumentCollectionStub } from './FunctionCallArgumentCollectionStub';
|
||||
|
||||
export class FunctionCallStub implements IFunctionCall {
|
||||
public functionName = 'functionCallStub';
|
||||
|
||||
public args = new FunctionCallArgumentCollectionStub();
|
||||
|
||||
public withFunctionName(functionName: string) {
|
||||
this.functionName = functionName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withArgument(parameterName: string, argumentValue: string) {
|
||||
this.args.withArgument(parameterName, argumentValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public withArguments(args: { readonly [index: string]: string }) {
|
||||
this.args.withArguments(args);
|
||||
return this;
|
||||
}
|
||||
|
||||
public withArgumentCollection(args: FunctionCallArgumentCollectionStub) {
|
||||
this.args = args;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
17
tests/unit/shared/Stubs/FunctionCodeStub.ts
Normal file
17
tests/unit/shared/Stubs/FunctionCodeStub.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { IFunctionCode } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
|
||||
|
||||
export class FunctionCodeStub implements IFunctionCode {
|
||||
public do = 'do code (function-code-stub)';
|
||||
|
||||
public revert? = 'revert code (function-code-stub)';
|
||||
|
||||
public withDo(code: string) {
|
||||
this.do = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRevert(revert: string) {
|
||||
this.revert = revert;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
70
tests/unit/shared/Stubs/FunctionDataStub.ts
Normal file
70
tests/unit/shared/Stubs/FunctionDataStub.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { FunctionData, ParameterDefinitionData, FunctionCallsData } from 'js-yaml-loader!@/*';
|
||||
import { FunctionCallDataStub } from './FunctionCallDataStub';
|
||||
|
||||
export class FunctionDataStub implements FunctionData {
|
||||
public static createWithCode() {
|
||||
return new FunctionDataStub()
|
||||
.withCode('stub-code')
|
||||
.withRevertCode('stub-revert-code');
|
||||
}
|
||||
|
||||
public static createWithCall(call?: FunctionCallsData) {
|
||||
let instance = new FunctionDataStub();
|
||||
if (call) {
|
||||
instance = instance.withCall(call);
|
||||
} else {
|
||||
instance = instance.withMockCall();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static createWithoutCallOrCodes() {
|
||||
return new FunctionDataStub();
|
||||
}
|
||||
|
||||
public name = 'functionDataStub';
|
||||
|
||||
public code: string;
|
||||
|
||||
public revertCode: string;
|
||||
|
||||
public call?: FunctionCallsData;
|
||||
|
||||
public parameters?: readonly ParameterDefinitionData[];
|
||||
|
||||
private constructor() { /* use static factory methods to create an instance */ }
|
||||
|
||||
public withName(name: string) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withParameters(...parameters: readonly ParameterDefinitionData[]) {
|
||||
return this.withParametersObject(parameters);
|
||||
}
|
||||
|
||||
public withParametersObject(parameters: readonly ParameterDefinitionData[]) {
|
||||
this.parameters = parameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCode(code: string) {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRevertCode(revertCode: string) {
|
||||
this.revertCode = revertCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCall(call: FunctionCallsData) {
|
||||
this.call = call;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withMockCall() {
|
||||
this.call = new FunctionCallDataStub();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
30
tests/unit/shared/Stubs/FunctionParameterCollectionStub.ts
Normal file
30
tests/unit/shared/Stubs/FunctionParameterCollectionStub.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { IFunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameter';
|
||||
import { IFunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
|
||||
import { FunctionParameterStub } from './FunctionParameterStub';
|
||||
|
||||
export class FunctionParameterCollectionStub implements IFunctionParameterCollection {
|
||||
private parameters = new Array<IFunctionParameter>();
|
||||
|
||||
public addParameter(parameter: IFunctionParameter): void {
|
||||
this.parameters.push(parameter);
|
||||
}
|
||||
|
||||
public get all(): readonly IFunctionParameter[] {
|
||||
return this.parameters;
|
||||
}
|
||||
|
||||
public withParameterName(parameterName: string, isOptional = true) {
|
||||
const parameter = new FunctionParameterStub()
|
||||
.withName(parameterName)
|
||||
.withOptionality(isOptional);
|
||||
this.addParameter(parameter);
|
||||
return this;
|
||||
}
|
||||
|
||||
public withParameterNames(parameterNames: readonly string[], isOptional = true) {
|
||||
for (const parameterName of parameterNames) {
|
||||
this.withParameterName(parameterName, isOptional);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
17
tests/unit/shared/Stubs/FunctionParameterStub.ts
Normal file
17
tests/unit/shared/Stubs/FunctionParameterStub.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { IFunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameter';
|
||||
|
||||
export class FunctionParameterStub implements IFunctionParameter {
|
||||
public name = 'function-parameter-stub';
|
||||
|
||||
public isOptional = true;
|
||||
|
||||
public withName(name: string) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withOptionality(isOptional: boolean) {
|
||||
this.isOptional = isOptional;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
17
tests/unit/shared/Stubs/LanguageSyntaxStub.ts
Normal file
17
tests/unit/shared/Stubs/LanguageSyntaxStub.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { ILanguageSyntax } from '@/domain/ScriptCode';
|
||||
|
||||
export class LanguageSyntaxStub implements ILanguageSyntax {
|
||||
public commentDelimiters = [];
|
||||
|
||||
public commonCodeParts = [];
|
||||
|
||||
public withCommentDelimiters(...delimiters: string[]) {
|
||||
this.commentDelimiters = delimiters;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCommonCodeParts(...codeParts: string[]) {
|
||||
this.commonCodeParts = codeParts;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
14
tests/unit/shared/Stubs/NumericEntityStub.ts
Normal file
14
tests/unit/shared/Stubs/NumericEntityStub.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
|
||||
|
||||
export class NumericEntityStub extends BaseEntity<number> {
|
||||
public customProperty = 'customProperty';
|
||||
|
||||
public constructor(id: number) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public withCustomProperty(value: string): NumericEntityStub {
|
||||
this.customProperty = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
17
tests/unit/shared/Stubs/ParameterDefinitionDataStub.ts
Normal file
17
tests/unit/shared/Stubs/ParameterDefinitionDataStub.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { ParameterDefinitionData } from 'js-yaml-loader!@/*';
|
||||
|
||||
export class ParameterDefinitionDataStub implements ParameterDefinitionData {
|
||||
public name: string;
|
||||
|
||||
public optional?: boolean;
|
||||
|
||||
public withName(name: string) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withOptionality(isOptional: boolean) {
|
||||
this.optional = isOptional;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
29
tests/unit/shared/Stubs/PipeFactoryStub.ts
Normal file
29
tests/unit/shared/Stubs/PipeFactoryStub.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { IPipe } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipe';
|
||||
import { IPipeFactory } from '@/application/Parser/Script/Compiler/Expressions/Pipes/PipeFactory';
|
||||
|
||||
export class PipeFactoryStub implements IPipeFactory {
|
||||
private readonly pipes = new Array<IPipe>();
|
||||
|
||||
public get(pipeName: string): IPipe {
|
||||
const result = this.pipes.find((pipe) => pipe.name === pipeName);
|
||||
if (!result) {
|
||||
throw new Error(`pipe not registered: "${pipeName}"`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public withPipe(pipe: IPipe) {
|
||||
if (!pipe) {
|
||||
throw new Error('missing pipe');
|
||||
}
|
||||
this.pipes.push(pipe);
|
||||
return this;
|
||||
}
|
||||
|
||||
public withPipes(pipes: IPipe[]) {
|
||||
for (const pipe of pipes) {
|
||||
this.withPipe(pipe);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
19
tests/unit/shared/Stubs/PipeStub.ts
Normal file
19
tests/unit/shared/Stubs/PipeStub.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { IPipe } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipe';
|
||||
|
||||
export class PipeStub implements IPipe {
|
||||
public name = 'pipeStub';
|
||||
|
||||
public apply(raw: string): string {
|
||||
return raw;
|
||||
}
|
||||
|
||||
public withName(name: string): PipeStub {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withApplier(applier: (input: string) => string): PipeStub {
|
||||
this.apply = applier;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
10
tests/unit/shared/Stubs/PipelineCompilerStub.ts
Normal file
10
tests/unit/shared/Stubs/PipelineCompilerStub.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { IPipelineCompiler } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
|
||||
|
||||
export class PipelineCompilerStub implements IPipelineCompiler {
|
||||
public compileHistory: Array<{ value: string, pipeline: string }> = [];
|
||||
|
||||
public compile(value: string, pipeline: string): string {
|
||||
this.compileHistory.push({ value, pipeline });
|
||||
return `value: ${value}"\n${pipeline}: ${pipeline}`;
|
||||
}
|
||||
}
|
||||
8
tests/unit/shared/Stubs/ProcessEnvironmentStub.ts
Normal file
8
tests/unit/shared/Stubs/ProcessEnvironmentStub.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export function getProcessEnvironmentStub(): NodeJS.ProcessEnv {
|
||||
return {
|
||||
VUE_APP_VERSION: 'stub-version',
|
||||
VUE_APP_NAME: 'stub-name',
|
||||
VUE_APP_REPOSITORY_URL: 'stub-repository-url',
|
||||
VUE_APP_HOMEPAGE_URL: 'stub-homepage-url',
|
||||
};
|
||||
}
|
||||
58
tests/unit/shared/Stubs/ProjectInformationStub.ts
Normal file
58
tests/unit/shared/Stubs/ProjectInformationStub.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { IProjectInformation } from '@/domain/IProjectInformation';
|
||||
|
||||
export class ProjectInformationStub implements IProjectInformation {
|
||||
public name = 'name';
|
||||
|
||||
public version = 'version';
|
||||
|
||||
public repositoryUrl = 'repositoryUrl';
|
||||
|
||||
public homepage = 'homepage';
|
||||
|
||||
public feedbackUrl = 'feedbackUrl';
|
||||
|
||||
public releaseUrl = 'releaseUrl';
|
||||
|
||||
public repositoryWebUrl = 'repositoryWebUrl';
|
||||
|
||||
public downloadUrl = 'downloadUrl';
|
||||
|
||||
public withName(name: string): ProjectInformationStub {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withVersion(version: string): ProjectInformationStub {
|
||||
this.version = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRepositoryUrl(repositoryUrl: string): ProjectInformationStub {
|
||||
this.repositoryUrl = repositoryUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withHomepageUrl(homepageUrl: string): ProjectInformationStub {
|
||||
this.homepage = homepageUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withFeedbackUrl(feedbackUrl: string): ProjectInformationStub {
|
||||
this.feedbackUrl = feedbackUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withReleaseUrl(releaseUrl: string): ProjectInformationStub {
|
||||
this.releaseUrl = releaseUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRepositoryWebUrl(repositoryWebUrl: string): ProjectInformationStub {
|
||||
this.repositoryWebUrl = repositoryWebUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public getDownloadUrl(): string {
|
||||
return this.downloadUrl;
|
||||
}
|
||||
}
|
||||
17
tests/unit/shared/Stubs/ScriptCodeStub.ts
Normal file
17
tests/unit/shared/Stubs/ScriptCodeStub.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { IScriptCode } from '@/domain/IScriptCode';
|
||||
|
||||
export class ScriptCodeStub implements IScriptCode {
|
||||
public execute = 'default execute code';
|
||||
|
||||
public revert = 'default revert code';
|
||||
|
||||
public withExecute(code: string) {
|
||||
this.execute = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRevert(revert: string) {
|
||||
this.revert = revert;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
23
tests/unit/shared/Stubs/ScriptCompilerStub.ts
Normal file
23
tests/unit/shared/Stubs/ScriptCompilerStub.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ScriptData } from 'js-yaml-loader!@/*';
|
||||
import { IScriptCompiler } from '@/application/Parser/Script/Compiler/IScriptCompiler';
|
||||
import { IScriptCode } from '@/domain/IScriptCode';
|
||||
|
||||
export class ScriptCompilerStub implements IScriptCompiler {
|
||||
public compilables = new Map<ScriptData, IScriptCode>();
|
||||
|
||||
public canCompile(script: ScriptData): boolean {
|
||||
return this.compilables.has(script);
|
||||
}
|
||||
|
||||
public compile(script: ScriptData): IScriptCode {
|
||||
return this.compilables.get(script);
|
||||
}
|
||||
|
||||
public withCompileAbility(script: ScriptData, result?: IScriptCode): ScriptCompilerStub {
|
||||
this.compilables.set(
|
||||
script,
|
||||
result || { execute: `compiled code of ${script.name}`, revert: `compiled revert code of ${script.name}` },
|
||||
);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
79
tests/unit/shared/Stubs/ScriptDataStub.ts
Normal file
79
tests/unit/shared/Stubs/ScriptDataStub.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { FunctionCallData, ScriptData } from 'js-yaml-loader!@/*';
|
||||
import { RecommendationLevel } from '@/domain/RecommendationLevel';
|
||||
import { FunctionCallDataStub } from '@tests/unit/shared/Stubs/FunctionCallDataStub';
|
||||
|
||||
export class ScriptDataStub implements ScriptData {
|
||||
public static createWithCode(): ScriptDataStub {
|
||||
return new ScriptDataStub()
|
||||
.withCode('stub-code')
|
||||
.withRevertCode('stub-revert-code');
|
||||
}
|
||||
|
||||
public static createWithCall(call?: FunctionCallData): ScriptDataStub {
|
||||
let instance = new ScriptDataStub();
|
||||
if (call) {
|
||||
instance = instance.withCall(call);
|
||||
} else {
|
||||
instance = instance.withMockCall();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static createWithoutCallOrCodes(): ScriptDataStub {
|
||||
return new ScriptDataStub();
|
||||
}
|
||||
|
||||
public name = 'valid-name';
|
||||
|
||||
public code = undefined;
|
||||
|
||||
public revertCode = undefined;
|
||||
|
||||
public call = undefined;
|
||||
|
||||
public recommend = RecommendationLevel[RecommendationLevel.Standard].toLowerCase();
|
||||
|
||||
public docs = ['hello.com'];
|
||||
|
||||
private constructor() { /* use static methods for constructing */ }
|
||||
|
||||
public withName(name: string): ScriptDataStub {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withDocs(docs: string[]): ScriptDataStub {
|
||||
this.docs = docs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCode(code: string): ScriptDataStub {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRevertCode(revertCode: string): ScriptDataStub {
|
||||
this.revertCode = revertCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withMockCall(): ScriptDataStub {
|
||||
this.call = new FunctionCallDataStub();
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCall(call: FunctionCallData): ScriptDataStub {
|
||||
this.call = call;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRecommend(recommend: string): ScriptDataStub {
|
||||
this.recommend = recommend;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRecommendationLevel(level: RecommendationLevel): ScriptDataStub {
|
||||
this.recommend = RecommendationLevel[level].toLowerCase();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
49
tests/unit/shared/Stubs/ScriptStub.ts
Normal file
49
tests/unit/shared/Stubs/ScriptStub.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
|
||||
import { IScript } from '@/domain/IScript';
|
||||
import { RecommendationLevel } from '@/domain/RecommendationLevel';
|
||||
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
|
||||
|
||||
export class ScriptStub extends BaseEntity<string> implements IScript {
|
||||
public name = `name${this.id}`;
|
||||
|
||||
public code = {
|
||||
execute: `REM execute-code (${this.id})`,
|
||||
revert: `REM revert-code (${this.id})`,
|
||||
};
|
||||
|
||||
public readonly documentationUrls = new Array<string>();
|
||||
|
||||
public level? = RecommendationLevel.Standard;
|
||||
|
||||
constructor(public readonly id: string) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public canRevert(): boolean {
|
||||
return Boolean(this.code.revert);
|
||||
}
|
||||
|
||||
public withLevel(value?: RecommendationLevel): ScriptStub {
|
||||
this.level = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCode(value: string): ScriptStub {
|
||||
this.code.execute = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withName(name: string): ScriptStub {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRevertCode(revertCode: string): ScriptStub {
|
||||
this.code.revert = revertCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public toSelectedScript(isReverted = false): SelectedScript {
|
||||
return new SelectedScript(this, isReverted);
|
||||
}
|
||||
}
|
||||
32
tests/unit/shared/Stubs/ScriptingDefinitionDataStub.ts
Normal file
32
tests/unit/shared/Stubs/ScriptingDefinitionDataStub.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
27
tests/unit/shared/Stubs/ScriptingDefinitionStub.ts
Normal file
27
tests/unit/shared/Stubs/ScriptingDefinitionStub.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
|
||||
export class ScriptingDefinitionStub implements IScriptingDefinition {
|
||||
public fileExtension = '.bat';
|
||||
|
||||
public language = ScriptingLanguage.batchfile;
|
||||
|
||||
public startCode = 'REM start code';
|
||||
|
||||
public endCode = 'REM end code';
|
||||
|
||||
public withStartCode(startCode: string): ScriptingDefinitionStub {
|
||||
this.startCode = startCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withEndCode(endCode: string): ScriptingDefinitionStub {
|
||||
this.endCode = endCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withLanguage(language: ScriptingLanguage): ScriptingDefinitionStub {
|
||||
this.language = language;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
8
tests/unit/shared/Stubs/SelectedScriptStub.ts
Normal file
8
tests/unit/shared/Stubs/SelectedScriptStub.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
|
||||
import { ScriptStub } from './ScriptStub';
|
||||
|
||||
export class SelectedScriptStub extends SelectedScript {
|
||||
constructor(id: string, revert = false) {
|
||||
super(new ScriptStub(id), revert);
|
||||
}
|
||||
}
|
||||
24
tests/unit/shared/Stubs/SharedFunctionCollectionStub.ts
Normal file
24
tests/unit/shared/Stubs/SharedFunctionCollectionStub.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { ISharedFunction, FunctionBodyType } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
|
||||
import { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
|
||||
import { SharedFunctionStub } from './SharedFunctionStub';
|
||||
|
||||
export class SharedFunctionCollectionStub implements ISharedFunctionCollection {
|
||||
private readonly functions = new Map<string, ISharedFunction>();
|
||||
|
||||
public withFunction(...funcs: readonly ISharedFunction[]) {
|
||||
for (const func of funcs) {
|
||||
this.functions.set(func.name, func);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public getFunctionByName(name: string): ISharedFunction {
|
||||
if (this.functions.has(name)) {
|
||||
return this.functions.get(name);
|
||||
}
|
||||
return new SharedFunctionStub(FunctionBodyType.Code)
|
||||
.withName(name)
|
||||
.withCode('code by SharedFunctionCollectionStub')
|
||||
.withRevertCode('revert-code by SharedFunctionCollectionStub');
|
||||
}
|
||||
}
|
||||
68
tests/unit/shared/Stubs/SharedFunctionStub.ts
Normal file
68
tests/unit/shared/Stubs/SharedFunctionStub.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { ISharedFunction, ISharedFunctionBody, FunctionBodyType } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
|
||||
import { IReadOnlyFunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
|
||||
import { IFunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/IFunctionCall';
|
||||
import { FunctionParameterCollectionStub } from './FunctionParameterCollectionStub';
|
||||
import { FunctionCallStub } from './FunctionCallStub';
|
||||
|
||||
export class SharedFunctionStub implements ISharedFunction {
|
||||
public name = 'shared-function-stub-name';
|
||||
|
||||
public parameters: IReadOnlyFunctionParameterCollection = new FunctionParameterCollectionStub()
|
||||
.withParameterName('shared-function-stub-parameter-name');
|
||||
|
||||
private code = 'shared-function-stub-code';
|
||||
|
||||
private revertCode = 'shared-function-stub-revert-code';
|
||||
|
||||
private bodyType: FunctionBodyType = FunctionBodyType.Code;
|
||||
|
||||
private calls: IFunctionCall[] = [new FunctionCallStub()];
|
||||
|
||||
constructor(type: FunctionBodyType) {
|
||||
this.bodyType = type;
|
||||
}
|
||||
|
||||
public get body(): ISharedFunctionBody {
|
||||
return {
|
||||
type: this.bodyType,
|
||||
code: this.bodyType === FunctionBodyType.Code ? {
|
||||
do: this.code,
|
||||
revert: this.revertCode,
|
||||
} : undefined,
|
||||
calls: this.bodyType === FunctionBodyType.Calls ? this.calls : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
public withName(name: string) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCode(code: string) {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withRevertCode(revertCode: string) {
|
||||
this.revertCode = revertCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withParameters(parameters: IReadOnlyFunctionParameterCollection) {
|
||||
this.parameters = parameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
public withCalls(...calls: readonly IFunctionCall[]) {
|
||||
this.calls = [...calls];
|
||||
return this;
|
||||
}
|
||||
|
||||
public withParameterNames(...parameterNames: readonly string[]) {
|
||||
let collection = new FunctionParameterCollectionStub();
|
||||
for (const name of parameterNames) {
|
||||
collection = collection.withParameterName(name);
|
||||
}
|
||||
return this.withParameters(collection);
|
||||
}
|
||||
}
|
||||
27
tests/unit/shared/Stubs/SharedFunctionsParserStub.ts
Normal file
27
tests/unit/shared/Stubs/SharedFunctionsParserStub.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { FunctionData } from 'js-yaml-loader!@/*';
|
||||
import { sequenceEqual } from '@/application/Common/Array';
|
||||
import { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
|
||||
import { ISharedFunctionsParser } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionsParser';
|
||||
import { SharedFunctionCollectionStub } from './SharedFunctionCollectionStub';
|
||||
|
||||
export class SharedFunctionsParserStub implements ISharedFunctionsParser {
|
||||
private setupResults = new Array<{
|
||||
functions: readonly FunctionData[],
|
||||
result: ISharedFunctionCollection,
|
||||
}>();
|
||||
|
||||
public setup(functions: readonly FunctionData[], result: ISharedFunctionCollection) {
|
||||
this.setupResults.push({ functions, result });
|
||||
}
|
||||
|
||||
public parseFunctions(functions: readonly FunctionData[]): ISharedFunctionCollection {
|
||||
const result = this.findResult(functions);
|
||||
return result || new SharedFunctionCollectionStub();
|
||||
}
|
||||
|
||||
private findResult(functions: readonly FunctionData[]): ISharedFunctionCollection {
|
||||
return this.setupResults
|
||||
.find((result) => sequenceEqual(result.functions, functions))
|
||||
?.result;
|
||||
}
|
||||
}
|
||||
19
tests/unit/shared/Stubs/UserFilterStub.ts
Normal file
19
tests/unit/shared/Stubs/UserFilterStub.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { IFilterResult } from '@/application/Context/State/Filter/IFilterResult';
|
||||
import { IUserFilter } from '@/application/Context/State/Filter/IUserFilter';
|
||||
import { IEventSource } from '@/infrastructure/Events/IEventSource';
|
||||
|
||||
export class UserFilterStub implements IUserFilter {
|
||||
public currentFilter: IFilterResult;
|
||||
|
||||
public filtered: IEventSource<IFilterResult>;
|
||||
|
||||
public filterRemoved: IEventSource<void>;
|
||||
|
||||
public setFilter(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public removeFilter(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
64
tests/unit/shared/Stubs/UserSelectionStub.ts
Normal file
64
tests/unit/shared/Stubs/UserSelectionStub.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { IUserSelection } from '@/application/Context/State/Selection/IUserSelection';
|
||||
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
|
||||
import { IScript } from '@/domain/IScript';
|
||||
import { IEventSource } from '@/infrastructure/Events/IEventSource';
|
||||
import { EventSource } from '@/infrastructure/Events/EventSource';
|
||||
|
||||
export class UserSelectionStub implements IUserSelection {
|
||||
public readonly changed: IEventSource<readonly SelectedScript[]> =
|
||||
new EventSource<readonly SelectedScript[]>();
|
||||
|
||||
public selectedScripts: readonly SelectedScript[] = [];
|
||||
|
||||
constructor(private readonly allScripts: readonly IScript[]) {
|
||||
|
||||
}
|
||||
|
||||
public withSelectedScripts(selectedScripts: readonly SelectedScript[]) {
|
||||
this.selectedScripts = selectedScripts;
|
||||
}
|
||||
|
||||
public areAllSelected(): boolean {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public isAnySelected(): boolean {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public removeAllInCategory(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public addOrUpdateAllInCategory(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public addSelectedScript(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public addOrUpdateSelectedScript(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public removeSelectedScript(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public selectOnly(scripts: ReadonlyArray<IScript>): void {
|
||||
this.selectedScripts = scripts.map((s) => new SelectedScript(s, false));
|
||||
}
|
||||
|
||||
public isSelected(): boolean {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public selectAll(): void {
|
||||
this.selectOnly(this.allScripts);
|
||||
}
|
||||
|
||||
public deselectAll(): void {
|
||||
this.selectedScripts = [];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user