From ea2048f993cb54e163c6bbe13a3fee0843039116 Mon Sep 17 00:00:00 2001 From: Andrew Telnov Date: Wed, 5 Jun 2024 16:51:00 +0300 Subject: [PATCH] The filtering condition without apostrophes doesn't work for the countInArray function fix #8371 --- src/expressions/expressions.ts | 3 +- src/functionsfactory.ts | 45 +++++++++++++---------- tests/expressions/expressionParserTest.ts | 10 +++++ 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/expressions/expressions.ts b/src/expressions/expressions.ts index 9ff45d9e17..2197e270c4 100644 --- a/src/expressions/expressions.ts +++ b/src/expressions/expressions.ts @@ -379,7 +379,8 @@ export class FunctionOperand extends Operand { return FunctionFactory.Instance.run( this.originalValue, this.parameters.evaluate(processValue), - processValue.properties + processValue.properties, + this.parameters.values ); } diff --git a/src/functionsfactory.ts b/src/functionsfactory.ts index ffb19d5de4..d706ece887 100644 --- a/src/functionsfactory.ts +++ b/src/functionsfactory.ts @@ -5,12 +5,12 @@ import { ConditionRunner } from "./conditions"; export class FunctionFactory { public static Instance: FunctionFactory = new FunctionFactory(); - private functionHash: HashTable<(params: any[]) => any> = {}; + private functionHash: HashTable<(params: any[], originalParams?: any[]) => any> = {}; private isAsyncHash: HashTable = {}; public register( name: string, - func: (params: any[]) => any, + func: (params: any[], originalParams?: any[]) => any, isAsync: boolean = false ): void { this.functionHash[name] = func; @@ -40,7 +40,8 @@ export class FunctionFactory { public run( name: string, params: any[], - properties: HashTable = null + properties: HashTable = null, + originalParams: any[] ): any { var func = this.functionHash[name]; if (!func) { @@ -56,7 +57,7 @@ export class FunctionFactory { (classRunner)[key] = properties[key]; } } - return classRunner.func(params); + return classRunner.func(params, originalParams); } } @@ -129,17 +130,23 @@ function avg(params: any[]): any { } FunctionFactory.Instance.register("avg", avg); -function getInArrayParams(params: any[]): any { +function getInArrayParams(params: any[], originalParams: any[]): any { if (params.length < 2 || params.length > 3) return null; const arr = params[0]; if (!arr) return null; if (!Array.isArray(arr) && !Array.isArray(Object.keys(arr))) return null; const name = params[1]; if (typeof name !== "string" && !(name instanceof String)) return null; - let expression = params.length === 3 ? params[2] : undefined; + let expression = params.length > 2 ? params[2] : undefined; if (typeof expression !== "string" && !(expression instanceof String)) { expression = undefined; } + if(!expression) { + const operand = Array.isArray(originalParams) && originalParams.length > 2 ? originalParams[2] : undefined; + if(operand && !!operand.toString()) { + expression = operand.toString(); + } + } return { data: arr, name: name, expression: expression }; } @@ -155,10 +162,10 @@ function processItemInArray(item: any, name: string, res: number, return func(res, val); } function calcInArray( - params: any[], + params: any[], originalParams: any[], func: (res: number, val: number) => number, needToConvert: boolean = true ): any { - var v = getInArrayParams(params); + var v = getInArrayParams(params, originalParams); if (!v) return undefined; let condition = !!v.expression ? new ConditionRunner(v.expression) : undefined; if(condition && condition.isAsync) { @@ -177,8 +184,8 @@ function calcInArray( return res; } -function sumInArray(params: any[]): any { - var res = calcInArray(params, function(res: number, val: number): number { +function sumInArray(params: any[], originalParams: any[]): any { + var res = calcInArray(params, originalParams, function(res: number, val: number): number { if (res == undefined) res = 0; if(val == undefined || val == null) return res; return Helpers.correctAfterPlusMinis(res, val, res + val); @@ -187,8 +194,8 @@ function sumInArray(params: any[]): any { } FunctionFactory.Instance.register("sumInArray", sumInArray); -function minInArray(params: any[]): any { - return calcInArray(params, function(res: number, val: number): number { +function minInArray(params: any[], originalParams: any[]): any { + return calcInArray(params, originalParams, function(res: number, val: number): number { if (res == undefined) return val; if(val == undefined || val == null) return res; return res < val ? res : val; @@ -196,8 +203,8 @@ function minInArray(params: any[]): any { } FunctionFactory.Instance.register("minInArray", minInArray); -function maxInArray(params: any[]): any { - return calcInArray(params, function(res: number, val: number): number { +function maxInArray(params: any[], originalParams: any[]): any { + return calcInArray(params, originalParams, function(res: number, val: number): number { if (res == undefined) return val; if(val == undefined || val == null) return res; return res > val ? res : val; @@ -205,8 +212,8 @@ function maxInArray(params: any[]): any { } FunctionFactory.Instance.register("maxInArray", maxInArray); -function countInArray(params: any[]): any { - var res = calcInArray(params, function(res: number, val: number): number { +function countInArray(params: any[], originalParams: any[]): any { + var res = calcInArray(params, originalParams, function(res: number, val: number): number { if (res == undefined) res = 0; if(val == undefined || val == null) return res; return res + 1; @@ -215,10 +222,10 @@ function countInArray(params: any[]): any { } FunctionFactory.Instance.register("countInArray", countInArray); -function avgInArray(params: any[]): any { - var count = countInArray(params); +function avgInArray(params: any[], originalParams: any[]): any { + var count = countInArray(params, originalParams); if (count == 0) return 0; - return sumInArray(params) / count; + return sumInArray(params, originalParams) / count; } FunctionFactory.Instance.register("avgInArray", avgInArray); diff --git a/tests/expressions/expressionParserTest.ts b/tests/expressions/expressionParserTest.ts index fa9fb0eb04..36c9d6cdcc 100644 --- a/tests/expressions/expressionParserTest.ts +++ b/tests/expressions/expressionParserTest.ts @@ -721,6 +721,16 @@ QUnit.test("ExpressionRunner: sumInArray with conditional logic", function(asser var values = { a: [{ val1: 1, val2: 4 }, { val1: 2, val2: 3 }, { val1: 3, val2: 5 }] }; assert.equal(runner.run(values), 4, "1 + 3"); }); +QUnit.test("ExpressionRunner: sumInArray with conditional logic as operand", function(assert) { + var runner = new ExpressionRunner("sumInArray({a}, 'val1', {val2} > 3)"); + var values = { a: [{ val1: 1, val2: 4 }, { val1: 2, val2: 3 }, { val1: 3, val2: 5 }] }; + assert.equal(runner.run(values), 4, "1 + 3"); +}); +QUnit.test("ExpressionRunner: countInArray with conditional logic & strings", function(assert) { + var runner = new ExpressionRunner("sumInArray({a}, 'val1', {val2} <> 'item1')"); + var values = { a: [{ val1: 1, val2: "item2" }, { val1: 2, val2: "item1" }, { val1: 3, val2: "item3" }] }; + assert.equal(runner.run(values), 4, "1 + 3"); +}); QUnit.test("ExpressionRunner: countInArray", function(assert) { var runner = new ExpressionRunner("countInArray({a}, 'val1')");