Add type validation for parameters and fix types
This commit introduces type validation for parameter values within the parser/compiler, aligning with the YAML schema. It aims to eliminate dependencies on side effects in the collection files. This update changes the treatment of data types in the Windows collection, moving away from unintended type casting by the compiler. Previously, numeric and boolean values were used even though only string types were supported. This behavior was unstable and untested, and has now been adjusted to use strings exclusively. Changes ensure that parameter values are correctly validated as strings, enhancing stability and maintainability.
This commit is contained in:
@@ -1,22 +1,22 @@
|
||||
import type { ProjectDetails } from '@/domain/Project/ProjectDetails';
|
||||
import type { ICodeSubstituter } from '@/application/Parser/ScriptingDefinition/ICodeSubstituter';
|
||||
import type { CodeSubstituter } from '@/application/Parser/ScriptingDefinition/CodeSubstituter';
|
||||
|
||||
export class CodeSubstituterStub implements ICodeSubstituter {
|
||||
export class CodeSubstituterStub {
|
||||
private readonly scenarios = new Array<{
|
||||
code: string, projectDetails: ProjectDetails, result: string }>();
|
||||
|
||||
public substitute(code: string, projectDetails: ProjectDetails): string {
|
||||
public setup(code: string, projectDetails: ProjectDetails, result: string) {
|
||||
this.scenarios.push({ code, projectDetails, result });
|
||||
return this;
|
||||
}
|
||||
|
||||
public substitute: CodeSubstituter = (code: string, projectDetails: ProjectDetails) => {
|
||||
const scenario = this.scenarios.find(
|
||||
(s) => s.code === code && s.projectDetails === projectDetails,
|
||||
);
|
||||
if (scenario) {
|
||||
return scenario.result;
|
||||
}
|
||||
return `[CodeSubstituterStub] - code: ${code}`;
|
||||
}
|
||||
|
||||
public setup(code: string, projectDetails: ProjectDetails, result: string) {
|
||||
this.scenarios.push({ code, projectDetails, result });
|
||||
return this;
|
||||
}
|
||||
return `[${CodeSubstituterStub.name}] - code: ${code}`;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { IFunctionCallArgument } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgument';
|
||||
import type { FunctionCallArgument } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/FunctionCallArgument';
|
||||
import type { IFunctionCallArgumentCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
|
||||
import { FunctionCallArgumentStub } from './FunctionCallArgumentStub';
|
||||
|
||||
export class FunctionCallArgumentCollectionStub implements IFunctionCallArgumentCollection {
|
||||
private args = new Array<IFunctionCallArgument>();
|
||||
private args = new Array<FunctionCallArgument>();
|
||||
|
||||
public withEmptyArguments(): this {
|
||||
this.args.length = 0;
|
||||
@@ -36,7 +36,7 @@ export class FunctionCallArgumentCollectionStub implements IFunctionCallArgument
|
||||
return this.args.some((a) => a.parameterName === parameterName);
|
||||
}
|
||||
|
||||
public addArgument(argument: IFunctionCallArgument): void {
|
||||
public addArgument(argument: FunctionCallArgument): void {
|
||||
this.args.push(argument);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ export class FunctionCallArgumentCollectionStub implements IFunctionCallArgument
|
||||
return this.args.map((a) => a.parameterName);
|
||||
}
|
||||
|
||||
public getArgument(parameterName: string): IFunctionCallArgument {
|
||||
public getArgument(parameterName: string): FunctionCallArgument {
|
||||
const arg = this.args.find((a) => a.parameterName === parameterName);
|
||||
if (!arg) {
|
||||
throw new Error(`no argument exists for parameter "${parameterName}"`);
|
||||
|
||||
10
tests/unit/shared/Stubs/FunctionCallArgumentFactoryStub.ts
Normal file
10
tests/unit/shared/Stubs/FunctionCallArgumentFactoryStub.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { FunctionCallArgumentFactory } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/FunctionCallArgument';
|
||||
import { FunctionCallArgumentStub } from './FunctionCallArgumentStub';
|
||||
|
||||
export class FunctionCallArgumentFactoryStub {
|
||||
public factory: FunctionCallArgumentFactory = (parameterName, argumentValue) => {
|
||||
return new FunctionCallArgumentStub()
|
||||
.withParameterName(parameterName)
|
||||
.withArgumentValue(argumentValue);
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { IFunctionCallArgument } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgument';
|
||||
import type { FunctionCallArgument } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/FunctionCallArgument';
|
||||
|
||||
export class FunctionCallArgumentStub implements IFunctionCallArgument {
|
||||
export class FunctionCallArgumentStub implements FunctionCallArgument {
|
||||
public parameterName = 'stub-parameter-name';
|
||||
|
||||
public argumentValue = 'stub-arg-name';
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import type { IFunctionParameter } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/IFunctionParameter';
|
||||
import type { IFunctionParameterCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
|
||||
import type { FunctionParameter } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/FunctionParameter';
|
||||
import { FunctionParameterStub } from './FunctionParameterStub';
|
||||
|
||||
export class FunctionParameterCollectionStub implements IFunctionParameterCollection {
|
||||
private parameters = new Array<IFunctionParameter>();
|
||||
private parameters = new Array<FunctionParameter>();
|
||||
|
||||
public addParameter(parameter: IFunctionParameter): void {
|
||||
public addParameter(parameter: FunctionParameter): void {
|
||||
this.parameters.push(parameter);
|
||||
}
|
||||
|
||||
public get all(): readonly IFunctionParameter[] {
|
||||
public get all(): readonly FunctionParameter[] {
|
||||
return this.parameters;
|
||||
}
|
||||
|
||||
|
||||
8
tests/unit/shared/Stubs/FunctionParameterParserStub.ts
Normal file
8
tests/unit/shared/Stubs/FunctionParameterParserStub.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { FunctionParameterParser } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/FunctionParameterParser';
|
||||
import { FunctionParameterStub } from './FunctionParameterStub';
|
||||
|
||||
export const createFunctionParameterParserStub: FunctionParameterParser = (parameters) => {
|
||||
return new FunctionParameterStub()
|
||||
.withName(parameters.name)
|
||||
.withOptional(parameters.optional || false);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { IFunctionParameter } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/IFunctionParameter';
|
||||
import type { FunctionParameter } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/FunctionParameter';
|
||||
|
||||
export class FunctionParameterStub implements IFunctionParameter {
|
||||
export class FunctionParameterStub implements FunctionParameter {
|
||||
public name = 'function-parameter-stub';
|
||||
|
||||
public isOptional = true;
|
||||
|
||||
12
tests/unit/shared/Stubs/ParameterNameValidatorStub.ts
Normal file
12
tests/unit/shared/Stubs/ParameterNameValidatorStub.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { ParameterNameValidator } from '@/application/Parser/Executable/Script/Compiler/Function/Shared/ParameterNameValidator';
|
||||
|
||||
export const createParameterNameValidatorStub = () => {
|
||||
const validatedNames = new Array<string>();
|
||||
const validator: ParameterNameValidator = (name) => {
|
||||
validatedNames.push(name);
|
||||
};
|
||||
return {
|
||||
validator,
|
||||
validatedNames,
|
||||
};
|
||||
};
|
||||
@@ -1,4 +1,7 @@
|
||||
import type { NonEmptyCollectionAssertion, ObjectAssertion, TypeValidator } from '@/application/Parser/Common/TypeValidator';
|
||||
import type {
|
||||
NonEmptyCollectionAssertion, NonEmptyStringAssertion,
|
||||
ObjectAssertion, TypeValidator,
|
||||
} from '@/application/Parser/Common/TypeValidator';
|
||||
import type { FunctionKeys } from '@/TypeHelpers';
|
||||
import { expectDeepIncludes } from '@tests/shared/Assertions/ExpectDeepIncludes';
|
||||
import { StubWithObservableMethodCalls } from './StubWithObservableMethodCalls';
|
||||
@@ -22,6 +25,13 @@ export class TypeValidatorStub
|
||||
});
|
||||
}
|
||||
|
||||
public assertNonEmptyString(assertion: NonEmptyStringAssertion): void {
|
||||
this.registerMethodCall({
|
||||
methodName: 'assertNonEmptyString',
|
||||
args: [assertion],
|
||||
});
|
||||
}
|
||||
|
||||
public expectObjectAssertion<T>(
|
||||
expectedAssertion: ObjectAssertion<T>,
|
||||
): void {
|
||||
@@ -34,6 +44,12 @@ export class TypeValidatorStub
|
||||
this.expectAssertion('assertNonEmptyCollection', expectedAssertion);
|
||||
}
|
||||
|
||||
public expectNonEmptyStringAssertion(
|
||||
expectedAssertion: NonEmptyStringAssertion,
|
||||
): void {
|
||||
this.expectAssertion('assertNonEmptyString', expectedAssertion);
|
||||
}
|
||||
|
||||
private expectAssertion<T extends FunctionKeys<TypeValidator>>(
|
||||
methodName: T,
|
||||
expectedAssertion: Parameters<TypeValidator[T]>[0],
|
||||
|
||||
Reference in New Issue
Block a user