Refactor code to comply with ESLint rules

Major refactoring using ESLint with rules from AirBnb and Vue.

Enable most of the ESLint rules and do necessary linting in the code.
Also add more information for rules that are disabled to describe what
they are and why they are disabled.

Allow logging (`console.log`) in test files, and in development mode
(e.g. when working with `npm run serve`), but disable it when
environment is production (as pre-configured by Vue). Also add flag
(`--mode production`) in `lint:eslint` command so production linting is
executed earlier in lifecycle.

Disable rules that requires a separate work. Such as ESLint rules that
are broken in TypeScript: no-useless-constructor (eslint/eslint#14118)
and no-shadow (eslint/eslint#13014).
This commit is contained in:
undergroundwires
2022-01-02 18:20:14 +01:00
parent 96265b75de
commit 5b1fbe1e2f
341 changed files with 16126 additions and 15101 deletions

View File

@@ -4,6 +4,7 @@ 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: string = '';
public changed: IEventSource<ICodeChangedEvent> = new EventSource<ICodeChangedEvent>();
public current = '';
}

View File

@@ -5,24 +5,30 @@ 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;
}
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;
}
}

View File

@@ -5,15 +5,17 @@ import { ScriptCompilerStub } from './ScriptCompilerStub';
import { LanguageSyntaxStub } from './LanguageSyntaxStub';
export class CategoryCollectionParseContextStub implements ICategoryCollectionParseContext {
public compiler: IScriptCompiler = new ScriptCompilerStub();
public syntax: ILanguageSyntax = new LanguageSyntaxStub();
public compiler: IScriptCompiler = new ScriptCompilerStub();
public withCompiler(compiler: IScriptCompiler) {
this.compiler = compiler;
return this;
}
public withSyntax(syntax: ILanguageSyntax) {
this.syntax = syntax;
return this;
}
public syntax: ILanguageSyntax = new LanguageSyntaxStub();
public withCompiler(compiler: IScriptCompiler) {
this.compiler = compiler;
return this;
}
public withSyntax(syntax: ILanguageSyntax) {
this.syntax = syntax;
return this;
}
}

View File

@@ -2,29 +2,35 @@ import { IApplicationCode } from '@/application/Context/State/Code/IApplicationC
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 { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
import { IScript } from '@/domain/IScript';
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;
}
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;
}
}

View File

@@ -3,92 +3,104 @@ 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';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
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 scripting: IScriptingDefinition = new ScriptingDefinitionStub();
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 os = OperatingSystem.Linux;
public findCategory(categoryId: number): ICategory {
return this.getAllCategories()
.find((category) => category.id === categoryId);
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> {
const scripts = [];
for (const category of this.actions) {
const categoryScripts = getScriptsRecursively(category);
scripts.push(...categoryScripts);
}
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> {
const scripts = [];
for (const category of this.actions) {
const categoryScripts = getScriptsRecursively(category);
scripts.push(...categoryScripts);
}
return scripts;
}
public getAllCategories(): ReadonlyArray<ICategory> {
const categories = [];
categories.push(...this.actions);
for (const category of this.actions) {
const subCategories = getSubCategoriesRecursively(category);
categories.push(...subCategories);
}
return categories;
return scripts;
}
public getAllCategories(): ReadonlyArray<ICategory> {
const categories = [];
categories.push(...this.actions);
for (const category of this.actions) {
const subCategories = getSubCategoriesRecursively(category);
categories.push(...subCategories);
}
return categories;
}
}
function getSubCategoriesRecursively(category: ICategory): ReadonlyArray<ICategory> {
const subCategories = [];
if (category.subCategories) {
for (const subCategory of category.subCategories) {
subCategories.push(subCategory);
subCategories.push(...getSubCategoriesRecursively(subCategory));
}
const subCategories = [];
if (category.subCategories) {
for (const subCategory of category.subCategories) {
subCategories.push(subCategory);
subCategories.push(...getSubCategoriesRecursively(subCategory));
}
return subCategories;
}
return subCategories;
}
function getScriptsRecursively(category: ICategory): ReadonlyArray<IScript> {
const categoryScripts = [];
if (category.scripts) {
categoryScripts.push(...category.scripts);
const categoryScripts = [];
if (category.scripts) {
categoryScripts.push(...category.scripts);
}
if (category.subCategories) {
for (const subCategory of category.subCategories) {
const subCategoryScripts = getScriptsRecursively(subCategory);
categoryScripts.push(...subCategoryScripts);
}
if (category.subCategories) {
for (const subCategory of category.subCategories) {
const subCategoryScripts = getScriptsRecursively(subCategory);
categoryScripts.push(...subCategoryScripts);
}
}
return categoryScripts;
}
return categoryScripts;
}

View File

@@ -2,20 +2,24 @@ import { CategoryData, CategoryOrScriptData, DocumentationUrlsData } from 'js-ya
import { ScriptDataStub } from './ScriptDataStub';
export class CategoryDataStub implements CategoryData {
public children: readonly CategoryOrScriptData[] = [ ScriptDataStub.createWithCode() ];
public category = 'category name';
public docs?: DocumentationUrlsData;
public children: readonly CategoryOrScriptData[] = [ScriptDataStub.createWithCode()];
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;
}
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;
}
}

View File

@@ -2,55 +2,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>();
export class CategoryStub extends BaseEntity<number> implements ICategory {
public name = `category-with-id-${this.id}`;
constructor(id: number) {
super(id);
}
public readonly subCategories = new Array<ICategory>();
public includes(script: IScript): boolean {
return this.getAllScriptsRecursively().some((s) => s.id === script.id);
}
public readonly scripts = new Array<IScript>();
public getAllScriptsRecursively(): readonly IScript[] {
return [
...this.scripts,
...this.subCategories.flatMap((c) => c.getAllScriptsRecursively()),
];
}
public readonly documentationUrls = new Array<string>();
public withScriptIds(...scriptIds: string[]): CategoryStub {
for (const scriptId of scriptIds) {
this.withScript(new ScriptStub(scriptId));
}
return this;
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 {
for (const scriptId of scriptIds) {
this.withScript(new ScriptStub(scriptId));
}
public withScripts(...scripts: IScript[]): CategoryStub {
for (const script of scripts) {
this.withScript(script);
}
return this;
return this;
}
public withScripts(...scripts: IScript[]): CategoryStub {
for (const script of scripts) {
this.withScript(script);
}
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;
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;
}
}

View File

@@ -2,16 +2,19 @@ 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;
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,56 +1,67 @@
import {
CategoryData, ScriptData, CollectionData, ScriptingDefinitionData, FunctionData,
} from 'js-yaml-loader!@/*';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { CategoryData, ScriptData, CollectionData, ScriptingDefinitionData, FunctionData } from 'js-yaml-loader!@/*';
export class CollectionDataStub implements CollectionData {
public os = 'windows';
public actions: readonly CategoryData[] = [ getCategoryStub() ];
public scripting: ScriptingDefinitionData = getTestDefinitionStub();
public functions?: ReadonlyArray<FunctionData>;
public os = 'windows';
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;
}
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),
],
};
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',
};
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,
};
function getScriptStub(
scriptName: string,
level: RecommendationLevel = RecommendationLevel.Standard,
): ScriptData {
return {
name: scriptName,
code: 'script code',
revertCode: 'revert code',
recommend: RecommendationLevel[level].toLowerCase(),
call: undefined,
};
}

View File

@@ -1,24 +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;
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;
}
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');
if (this.defaultValue) {
return this.defaultValue;
}
throw new Error('enum parser is not set up');
}
}

View File

@@ -2,10 +2,12 @@ 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;
}
public isDesktop = true;
public os = OperatingSystem.Windows;
public withOs(os: OperatingSystem): EnvironmentStub {
this.os = os;
return this;
}
}

View File

@@ -5,15 +5,18 @@ import { FunctionCallArgumentCollectionStub } from './FunctionCallArgumentCollec
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;
}
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;
}
}

View File

@@ -2,14 +2,17 @@ import { IExpression } from '@/application/Parser/Script/Compiler/Expressions/Ex
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;
}
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

@@ -1,35 +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 { FunctionParameterCollectionStub } from './FunctionParameterCollectionStub';
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.args;
this.callHistory.push(context);
const result = this.result || `[expression-stub] args: ${args ? Object.keys(args).map((key) => `${key}: ${args[key]}`).join('", "') : 'none'}`;
return result;
}
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;
}
}

View File

@@ -4,57 +4,66 @@ import { scrambledEqual } from '@/application/Common/Array';
import { ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import { FunctionCallArgumentCollectionStub } from '@tests/unit/stubs/FunctionCallArgumentCollectionStub';
export class ExpressionsCompilerStub implements IExpressionsCompiler {
public readonly callHistory = new Array<{code: string, parameters: IReadOnlyFunctionCallArgumentCollection}>();
public readonly callHistory =
new Array<{ code: string, parameters: IReadOnlyFunctionCallArgumentCollection }>();
private readonly scenarios = new Array<ITestScenario>();
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}`;
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;
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;
expected: IReadOnlyFunctionCallArgumentCollection,
actual: IReadOnlyFunctionCallArgumentCollection,
): boolean {
const expectedParameterNames = expected.getAllParameterNames();
const actualParameterNames = actual.getAllParameterNames();
if (!scrambledEqual(expectedParameterNames, actualParameterNames)) {
return false;
}
for (const parameterName of expectedParameterNames) {
const expectedValue = expected.getArgument(parameterName).argumentValue;
const actualValue = actual.getArgument(parameterName).argumentValue;
if (expectedValue !== actualValue) {
return false;
}
for (const parameterName of expectedParameterNames) {
const expectedValue = expected.getArgument(parameterName).argumentValue;
const actualValue = actual.getArgument(parameterName).argumentValue;
if (expectedValue !== actualValue) {
return false;
}
}
return true;
}
return true;
}

View File

@@ -3,36 +3,41 @@ import { IFunctionCallArgumentCollection } from '@/application/Parser/Script/Com
import { FunctionCallArgumentStub } from './FunctionCallArgumentStub';
export class FunctionCallArgumentCollectionStub implements IFunctionCallArgumentCollection {
private args = new Array<IFunctionCallArgument>();
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 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 parameterName of Object.keys(args)) {
const parameterValue = args[parameterName];
this.withArgument(parameterName, parameterValue);
}
public withArguments(args: { readonly [index: string]: string }) {
for (const parameterName of Object.keys(args)) {
const parameterValue = args[parameterName];
this.withArgument(parameterName, parameterValue);
}
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;
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;
}
}

View File

@@ -1,14 +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;
}
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;
}
}

View File

@@ -4,37 +4,45 @@ import { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/
import { IFunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/IFunctionCall';
interface IScenario {
calls: IFunctionCall[];
functions: ISharedFunctionCollection;
result: ICompiledCode;
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]',
};
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);
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);
}

View File

@@ -1,15 +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 function = 'callDatStubCalleeFunction';
public withName(functionName: string) {
this.function = functionName;
return this;
}
public withParameters(parameters: FunctionCallParametersData) {
this.parameters = parameters;
return this;
}
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;
}
}

View File

@@ -2,23 +2,27 @@ import { IFunctionCall } from '@/application/Parser/Script/Compiler/Function/Cal
import { FunctionCallArgumentCollectionStub } from './FunctionCallArgumentCollectionStub';
export class FunctionCallStub implements IFunctionCall {
public functionName = 'functionCallStub';
public args = new FunctionCallArgumentCollectionStub();
public functionName = 'functionCallStub';
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;
}
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;
}
}

View File

@@ -1,14 +1,17 @@
import { IFunctionCode } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
export class FunctionCodeStub implements IFunctionCode {
public do: string = 'do code (function-code-stub)';
public revert?: string = 'revert code (function-code-stub)';
public withDo(code: string) {
this.do = code;
return this;
}
public withRevert(revert: string) {
this.revert = revert;
return this;
}
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;
}
}

View File

@@ -2,57 +2,69 @@ import { FunctionData, ParameterDefinitionData, FunctionCallsData } from 'js-yam
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 static createWithCode() {
return new FunctionDataStub()
.withCode('stub-code')
.withRevertCode('stub-revert-code');
}
public name = 'functionDataStub';
public code: string;
public revertCode: string;
public call?: FunctionCallsData;
public parameters?: readonly ParameterDefinitionData[];
public static createWithCall(call?: FunctionCallsData) {
let instance = new FunctionDataStub();
if (call) {
instance = instance.withCall(call);
} else {
instance = instance.withMockCall();
}
return instance;
}
private constructor() { /* use static factory methods to create an instance */ }
public static createWithoutCallOrCodes() {
return new FunctionDataStub();
}
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;
}
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;
}
}

View File

@@ -3,25 +3,28 @@ import { IFunctionParameterCollection } from '@/application/Parser/Script/Compil
import { FunctionParameterStub } from './FunctionParameterStub';
export class FunctionParameterCollectionStub implements IFunctionParameterCollection {
private parameters = new Array<IFunctionParameter>();
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;
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;
}
}

View File

@@ -1,14 +1,17 @@
import { IFunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameter';
export class FunctionParameterStub implements IFunctionParameter {
public name: string = 'function-parameter-stub';
public isOptional: boolean = true;
public withName(name: string) {
this.name = name;
return this;
}
public withOptionality(isOptional: boolean) {
this.isOptional = isOptional;
return this;
}
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;
}
}

View File

@@ -1,15 +1,17 @@
import { ILanguageSyntax } from '@/domain/ScriptCode';
export class LanguageSyntaxStub implements ILanguageSyntax {
public commentDelimiters = [];
public commonCodeParts = [];
public commentDelimiters = [];
public withCommentDelimiters(...delimiters: string[]) {
this.commentDelimiters = delimiters;
return this;
}
public withCommonCodeParts(...codeParts: string[]) {
this.commonCodeParts = codeParts;
return this;
}
public commonCodeParts = [];
public withCommentDelimiters(...delimiters: string[]) {
this.commentDelimiters = delimiters;
return this;
}
public withCommonCodeParts(...codeParts: string[]) {
this.commonCodeParts = codeParts;
return this;
}
}

View File

@@ -1,12 +1,14 @@
import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
export class NumericEntityStub extends BaseEntity<number> {
public customProperty = 'customProperty';
constructor(id: number) {
super(id);
}
public withCustomProperty(value: string): NumericEntityStub {
this.customProperty = value;
return this;
}
public customProperty = 'customProperty';
public constructor(id: number) {
super(id);
}
public withCustomProperty(value: string): NumericEntityStub {
this.customProperty = value;
return this;
}
}

View File

@@ -1,14 +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;
}
public name: string;
public optional?: boolean;
public withName(name: string) {
this.name = name;
return this;
}
public withOptionality(isOptional: boolean) {
this.optional = isOptional;
return this;
}
}

View File

@@ -2,27 +2,28 @@ import { IPipe } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IP
import { IPipeFactory } from '@/application/Parser/Script/Compiler/Expressions/Pipes/PipeFactory';
export class PipeFactoryStub implements IPipeFactory {
private readonly pipes = new Array<IPipe>();
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 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('undefined pipe');
}
this.pipes.push(pipe);
return this;
public withPipe(pipe: IPipe) {
if (!pipe) {
throw new Error('undefined pipe');
}
public withPipes(pipes: IPipe[]) {
for (const pipe of pipes) {
this.withPipe(pipe);
}
return this;
this.pipes.push(pipe);
return this;
}
public withPipes(pipes: IPipe[]) {
for (const pipe of pipes) {
this.withPipe(pipe);
}
return this;
}
}

View File

@@ -1,16 +1,19 @@
import { IPipe } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipe';
export class PipeStub implements IPipe {
public name: string = '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;
}
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;
}
}

View File

@@ -1,9 +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}`;
}
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}`;
}
}

View File

@@ -1,8 +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',
};
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',
};
}

View File

@@ -1,43 +1,58 @@
import { IProjectInformation } from '@/domain/IProjectInformation';
import { OperatingSystem } from '@/domain/OperatingSystem';
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 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(os: OperatingSystem): string {
throw new Error('Method not implemented.');
}
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;
}
}

View File

@@ -1,15 +1,17 @@
import { IScriptCode } from '@/domain/IScriptCode';
export class ScriptCodeStub implements IScriptCode {
public execute = 'default execute code';
public revert = 'default revert code';
public execute = 'default execute code';
public withExecute(code: string) {
this.execute = code;
return this;
}
public withRevert(revert: string) {
this.revert = revert;
return this;
}
public revert = 'default revert code';
public withExecute(code: string) {
this.execute = code;
return this;
}
public withRevert(revert: string) {
this.revert = revert;
return this;
}
}

View File

@@ -1,18 +1,23 @@
import { ScriptData } from 'js-yaml-loader!@/*';
import { IScriptCompiler } from '@/application/Parser/Script/Compiler/IScriptCompiler';
import { IScriptCode } from '@/domain/IScriptCode';
import { ScriptData } from 'js-yaml-loader!@/*';
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;
}
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;
}
}

View File

@@ -1,65 +1,79 @@
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import { FunctionCallData, ScriptData } from 'js-yaml-loader!@/*';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import { FunctionCallDataStub } from '@tests/unit/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 static createWithCode(): ScriptDataStub {
return new ScriptDataStub()
.withCode('stub-code')
.withRevertCode('stub-revert-code');
}
public name = 'valid-name';
public code = undefined;
public revertCode = undefined;
public call = undefined;
public recommend = RecommendationLevel[RecommendationLevel.Standard].toLowerCase();
public docs = ['hello.com'];
public static createWithCall(call?: FunctionCallData): ScriptDataStub {
let instance = new ScriptDataStub();
if (call) {
instance = instance.withCall(call);
} else {
instance = instance.withMockCall();
}
return instance;
}
private constructor() { /* use static methods for constructing */ }
public static createWithoutCallOrCodes(): ScriptDataStub {
return new ScriptDataStub();
}
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;
}
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;
}
}

View File

@@ -4,43 +4,46 @@ 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;
public name = `name${this.id}`;
constructor(public readonly id: string) {
super(id);
}
public code = {
execute: `REM execute-code (${this.id})`,
revert: `REM revert-code (${this.id})`,
};
public canRevert(): boolean {
return Boolean(this.code.revert);
}
public readonly documentationUrls = new Array<string>();
public withLevel(value: RecommendationLevel): ScriptStub {
this.level = value;
return this;
}
public level = RecommendationLevel.Standard;
public withCode(value: string): ScriptStub {
this.code.execute = value;
return this;
}
constructor(public readonly id: string) {
super(id);
}
public withName(name: string): ScriptStub {
this.name = name;
return this;
}
public canRevert(): boolean {
return Boolean(this.code.revert);
}
public withRevertCode(revertCode: string): ScriptStub {
this.code.revert = revertCode;
return this;
}
public withLevel(value: RecommendationLevel): ScriptStub {
this.level = value;
return this;
}
public toSelectedScript(isReverted = false): SelectedScript {
return new SelectedScript(this, isReverted);
}
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);
}
}

View File

@@ -2,28 +2,31 @@ 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 language = ScriptingLanguage[ScriptingLanguage.batchfile];
public withLanguage(language: string): ScriptingDefinitionDataStub {
this.language = language;
return this;
}
public fileExtension = 'bat';
public withStartCode(startCode: string): ScriptingDefinitionDataStub {
this.startCode = startCode;
return this;
}
public startCode = 'startCode';
public withEndCode(endCode: string): ScriptingDefinitionDataStub {
this.endCode = endCode;
return this;
}
public endCode = 'endCode';
public withExtension(extension: string): ScriptingDefinitionDataStub {
this.fileExtension = extension;
return this;
}
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;
}
}

View File

@@ -2,21 +2,26 @@ import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
export class ScriptingDefinitionStub implements IScriptingDefinition {
public fileExtension: string = '.bat';
public language = ScriptingLanguage.batchfile;
public startCode = 'REM start code';
public endCode = 'REM end code';
public fileExtension = '.bat';
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;
}
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;
}
}

View File

@@ -2,7 +2,7 @@ import { SelectedScript } from '@/application/Context/State/Selection/SelectedSc
import { ScriptStub } from './ScriptStub';
export class SelectedScriptStub extends SelectedScript {
constructor(id: string, revert = false) {
super(new ScriptStub(id), revert);
}
constructor(id: string, revert = false) {
super(new ScriptStub(id), revert);
}
}

View File

@@ -1,23 +1,24 @@
import { ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import { ISharedFunction, FunctionBodyType } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
import { SharedFunctionStub } from './SharedFunctionStub';
import { FunctionBodyType } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
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;
private readonly functions = new Map<string, ISharedFunction>();
public withFunction(...funcs: readonly ISharedFunction[]) {
for (const func of funcs) {
this.functions.set(func.name, func);
}
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');
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');
}
}

View File

@@ -1,59 +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';
import { IFunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/IFunctionCall';
export class SharedFunctionStub implements ISharedFunction {
public name = 'shared-function-stub-name';
public parameters: IReadOnlyFunctionParameterCollection = new FunctionParameterCollectionStub()
.withParameterName('shared-function-stub-parameter-name');
public name = 'shared-function-stub-name';
private code = 'shared-function-stub-code';
private revertCode = 'shared-function-stub-revert-code';
private bodyType: FunctionBodyType = FunctionBodyType.Code;
private calls: IFunctionCall[] = [ new FunctionCallStub() ];
public parameters: IReadOnlyFunctionParameterCollection = new FunctionParameterCollectionStub()
.withParameterName('shared-function-stub-parameter-name');
constructor(type: FunctionBodyType) {
this.bodyType = type;
}
private code = 'shared-function-stub-code';
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,
};
}
private revertCode = 'shared-function-stub-revert-code';
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);
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);
}
}

View File

@@ -1,30 +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 { FunctionData } from 'js-yaml-loader!@/*';
import { SharedFunctionCollectionStub } from './SharedFunctionCollectionStub';
export class SharedFunctionsParserStub implements ISharedFunctionsParser {
private setupResults = new Array<{
functions: readonly FunctionData[],
result: ISharedFunctionCollection,
}>();
private setupResults = new Array<{
functions: readonly FunctionData[],
result: ISharedFunctionCollection,
}>();
public setup(functions: readonly FunctionData[], result: ISharedFunctionCollection) {
this.setupResults.push( { functions, result });
}
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();
}
public parseFunctions(functions: readonly FunctionData[]): ISharedFunctionCollection {
const result = this.findResult(functions);
return result || new SharedFunctionCollectionStub();
}
private findResult(functions: readonly FunctionData[]): ISharedFunctionCollection {
for (const result of this.setupResults) {
if (sequenceEqual(result.functions, functions)) {
return result.result;
}
}
return undefined;
}
private findResult(functions: readonly FunctionData[]): ISharedFunctionCollection {
return this.setupResults
.find((result) => sequenceEqual(result.functions, functions))
?.result;
}
}

View File

@@ -3,13 +3,17 @@ 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.');
}
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.');
}
}

View File

@@ -5,45 +5,60 @@ 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 readonly changed: IEventSource<readonly SelectedScript[]> =
new EventSource<readonly SelectedScript[]>();
}
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 = [];
}
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 = [];
}
}