diff --git a/CHANGELOG.md b/CHANGELOG.md index e56922581d..54a7ea572e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed an issue with matrixDetection + number parsing. (#686) - Fixed an issue with NOW and TODAY functions. (#709) - Fixed an issue with MIN/MAX function caches. (#711) +- Fixed an issue with caching and order of evaluation. (#735) ## [0.6.2] - 2021-05-26 diff --git a/src/interpreter/plugin/NumericAggregationPlugin.ts b/src/interpreter/plugin/NumericAggregationPlugin.ts index 8a12d79abf..7cc2200478 100644 --- a/src/interpreter/plugin/NumericAggregationPlugin.ts +++ b/src/interpreter/plugin/NumericAggregationPlugin.ts @@ -537,7 +537,7 @@ export class NumericAggregationPlugin extends FunctionPlugin implements Function * * @param args * @param state - * @param initialAccValue - initial accumulator value for reducing function + * @param initialAccValue - "neutral" value (equivalent of 0) * @param functionName - function name to use as cache key * @param reducingFunction - reducing function * @param mapFunction @@ -552,7 +552,11 @@ export class NumericAggregationPlugin extends FunctionPlugin implements Function return acc } if (arg.type === AstNodeType.CELL_RANGE || arg.type === AstNodeType.COLUMN_RANGE || arg.type === AstNodeType.ROW_RANGE) { - return this.evaluateRange(arg, state, acc, functionName, reducingFunction, mapFunction, coercionFunction) + const val = this.evaluateRange(arg, state, initialAccValue, functionName, reducingFunction, mapFunction, coercionFunction) + if(val instanceof CellError) { + return val + } + return reducingFunction(val, acc) } let value value = this.evaluateAst(arg, state) diff --git a/test/cache-order.spec.ts b/test/cache-order.spec.ts new file mode 100644 index 0000000000..0ad965b155 --- /dev/null +++ b/test/cache-order.spec.ts @@ -0,0 +1,28 @@ +import {HyperFormula} from '../src' +import {adr} from './testUtils' + +describe('cache order invariance', () => { + it('should evaluate properly #1', () => { + const engine = HyperFormula.buildFromArray([[1, 2, 3], ['=SUM(A1,B1:C1)', '=SUM(B1:C1)']]) + expect(engine.getCellValue(adr('A2'))).toEqual(6) + expect(engine.getCellValue(adr('B2'))).toEqual(5) + }) + + it('should evaluate properly #2', () => { + const engine = HyperFormula.buildFromArray([[1, 2, 3], ['=SUM(B1:C1,A1)', '=SUM(B1:C1)']]) + expect(engine.getCellValue(adr('A2'))).toEqual(6) + expect(engine.getCellValue(adr('B2'))).toEqual(5) + }) + + it('should evaluate properly #3', () => { + const engine = HyperFormula.buildFromArray([[1, 2, 3], ['=SUM(B1:C1)', '=SUM(A1,B1:C1)']]) + expect(engine.getCellValue(adr('A2'))).toEqual(5) + expect(engine.getCellValue(adr('B2'))).toEqual(6) + }) + + it('should evaluate properly #4', () => { + const engine = HyperFormula.buildFromArray([[1, 2, 3], ['=SUM(B1:C1)', '=SUM(B1:C1,A1)']]) + expect(engine.getCellValue(adr('A2'))).toEqual(5) + expect(engine.getCellValue(adr('B2'))).toEqual(6) + }) +})