Add optionality for parameters
This commit allows for parameters that does not require any arguments to be provided in function calls. It changes collection syntax where parameters are list of objects instead of primitive strings. A parameter has now 'name' and 'optional' properties. 'name' is required and used in same way as older strings as parameter definitions. 'Optional' property is optional, 'false' is the default behavior if undefined. It also adds additional validation to restrict parameter names to alphanumeric strings to have a clear syntax in expressions.
This commit is contained in:
@@ -1,30 +1,56 @@
|
||||
import { IExpressionsCompiler, ParameterValueDictionary } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
|
||||
import { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
|
||||
import { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/FunctionCall/Argument/IFunctionCallArgumentCollection';
|
||||
import { scrambledEqual } from '@/application/Common/Array';
|
||||
|
||||
interface Scenario { code: string; parameters: ParameterValueDictionary; result: string; }
|
||||
|
||||
export class ExpressionsCompilerStub implements IExpressionsCompiler {
|
||||
public readonly callHistory = new Array<{code: string, parameters?: ParameterValueDictionary}>();
|
||||
private readonly scenarios = new Array<Scenario>();
|
||||
public setup(code: string, parameters: ParameterValueDictionary, result: string) {
|
||||
public readonly callHistory = new Array<{code: string, parameters: IReadOnlyFunctionCallArgumentCollection}>();
|
||||
|
||||
private readonly scenarios = new Array<ITestScenario>();
|
||||
|
||||
public setup(
|
||||
code: string,
|
||||
parameters: IReadOnlyFunctionCallArgumentCollection,
|
||||
result: string): ExpressionsCompilerStub {
|
||||
this.scenarios.push({ code, parameters, result });
|
||||
return this;
|
||||
}
|
||||
public compileExpressions(code: string, parameters?: ParameterValueDictionary): string {
|
||||
public compileExpressions(
|
||||
code: string,
|
||||
parameters: IReadOnlyFunctionCallArgumentCollection): string {
|
||||
this.callHistory.push({ code, parameters});
|
||||
const scenario = this.scenarios.find((s) => s.code === code && deepEqual(s.parameters, parameters));
|
||||
if (scenario) {
|
||||
return scenario.result;
|
||||
}
|
||||
return `[ExpressionsCompilerStub] code: "${code}"` +
|
||||
`| parameters: ${Object.keys(parameters || {}).map((p) => p + '=' + parameters[p]).join(',')}`;
|
||||
const parametersAndValues = parameters
|
||||
.getAllParameterNames()
|
||||
.map((name) => `${name}=${parameters.getArgument(name).argumentValue}`)
|
||||
.join('", "');
|
||||
return `[ExpressionsCompilerStub] code: "${code}" | parameters: "${parametersAndValues}"`;
|
||||
}
|
||||
}
|
||||
|
||||
function deepEqual(dict1: ParameterValueDictionary, dict2: ParameterValueDictionary) {
|
||||
const dict1Keys = Object.keys(dict1 || {});
|
||||
const dict2Keys = Object.keys(dict2 || {});
|
||||
if (dict1Keys.length !== dict2Keys.length) {
|
||||
interface ITestScenario {
|
||||
readonly code: string;
|
||||
readonly parameters: 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 dict1Keys.every((key) => dict2.hasOwnProperty(key) && dict2[key] === dict1[key]);
|
||||
for (const parameterName of expectedParameterNames) {
|
||||
const expectedValue = expected.getArgument(parameterName);
|
||||
const actualValue = expected.getArgument(parameterName);
|
||||
if (expectedValue !== actualValue) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user