feat: Extend automated ingredient validation to include argSelector ingredients (#2641) (#2643)

This commit is contained in:
MAN$I VERMA 2026-07-25 12:47:08 +05:30 committed by GitHub
parent f6a4631130
commit 8e19b7e402
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 77 additions and 1 deletions

View File

@ -86,6 +86,9 @@ class Ingredient {
if (this.type === "option" && Array.isArray(checkVal)) { if (this.type === "option" && Array.isArray(checkVal)) {
checkVal = checkVal[this.defaultIndex ?? 0]; checkVal = checkVal[this.defaultIndex ?? 0];
} }
if (this.type === "argSelector" && Array.isArray(checkVal)) {
checkVal = checkVal[this.defaultIndex ?? 0]?.name || "";
}
// 1. check if empty // 1. check if empty
let isEmpty = false; let isEmpty = false;
@ -99,8 +102,10 @@ class Ingredient {
let isAllowedOptionEmpty = false; let isAllowedOptionEmpty = false;
if (this.type === "option" && Array.isArray(this.defaultValue)) { if (this.type === "option" && Array.isArray(this.defaultValue)) {
isAllowedOptionEmpty = this.defaultValue.includes(""); isAllowedOptionEmpty = this.defaultValue.includes("");
} else if (this.type === "argSelector" && Array.isArray(this.defaultValue)) {
isAllowedOptionEmpty = this.defaultValue.some(opt => opt.name === "");
} }
if (this.allowEmpty === false || (this.type === "option" && !isAllowedOptionEmpty)) { if (this.allowEmpty === false || ((this.type === "option" || this.type === "argSelector") && !isAllowedOptionEmpty)) {
throw new OperationError(`${this.name} cannot be empty.`); throw new OperationError(`${this.name} cannot be empty.`);
} }
return true; return true;
@ -150,6 +155,23 @@ class Ingredient {
} }
} }
// 5. argSelector checks
if (this.type === "argSelector") {
if (Array.isArray(this.defaultValue)) {
const permittedOptions = this.defaultValue
.map(opt => opt.name)
.filter(optName => {
if (typeof optName !== "string") return false;
return !optName.match(/^\[\/?[a-z0-9 -()^]+\]$/i);
});
const valStr = (checkVal !== null && checkVal !== undefined) ? String(checkVal).toLowerCase() : "";
const matchedOption = permittedOptions.find(opt => opt.toLowerCase() === valStr);
if (!matchedOption) {
throw new OperationError(`${this.name} must be one of the following: ${permittedOptions.join(", ")}.`);
}
}
}
return true; return true;
} }

View File

@ -66,6 +66,23 @@ class AutomatedValidationTestOp extends Operation {
"type": "option", "type": "option",
"value": ["[Group 1]", "Option 1", "Option 2", "[/Group 1]", "[Group 2]", "Option 3", "[/Group 2]"], "value": ["[Group 1]", "Option 1", "Option 2", "[/Group 1]", "[Group 2]", "Option 3", "[/Group 2]"],
"allowEmpty": false "allowEmpty": false
},
{
"name": "Arg Selector Ingredient",
"type": "argSelector",
"value": [
{
name: "Option 1",
on: [0],
off: [1]
},
{
name: "Option 2",
on: [1],
off: [0]
}
],
"allowEmpty": false
} }
]; ];
} }

View File

@ -77,6 +77,10 @@ function transformArgs(opArgsList, newArgs) {
return !Array.isArray(arg.value) ? arg.value : arg.value[arg.defaultIndex ?? 0]; return !Array.isArray(arg.value) ? arg.value : arg.value[arg.defaultIndex ?? 0];
} }
if (arg.type === "argSelector") {
return !Array.isArray(arg.value) ? arg.value : (arg.value[arg.defaultIndex ?? 0]?.name || "");
}
if (arg.type === "editableOption") { if (arg.type === "editableOption") {
return typeof arg.value === "string" ? arg.value : arg.value[arg.defaultIndex ?? 0].value; return typeof arg.value === "string" ? arg.value : arg.value[arg.defaultIndex ?? 0].value;
} }

View File

@ -150,5 +150,38 @@ TestRegister.addTests([
args: [5, 1.5, "hello", "", { "option": "Option A", "string": "test" }, ""] args: [5, 1.5, "hello", "", { "option": "Option A", "string": "test" }, ""]
} }
] ]
},
{
name: "Automated Validation: Valid Arg Selector value",
input: "test",
expectedOutput: "Success",
recipeConfig: [
{
op: "Automated Validation Test Op",
args: [5, 1.5, "hello", "", { "option": "Option A", "string": "test" }, "Option 1", "Option 2"]
}
]
},
{
name: "Automated Validation: Invalid Arg Selector value",
input: "test",
expectedOutput: "Arg Selector Ingredient must be one of the following: Option 1, Option 2.",
recipeConfig: [
{
op: "Automated Validation Test Op",
args: [5, 1.5, "hello", "", { "option": "Option A", "string": "test" }, "Option 1", "Option 3"]
}
]
},
{
name: "Automated Validation: Arg Selector value empty (invalid)",
input: "test",
expectedOutput: "Arg Selector Ingredient cannot be empty.",
recipeConfig: [
{
op: "Automated Validation Test Op",
args: [5, 1.5, "hello", "", { "option": "Option A", "string": "test" }, "Option 1", ""]
}
]
} }
]); ]);