diff --git a/src/common/aggregators.ts b/src/common/aggregators.ts index b62fe75ccfd..5d35f9cd2bd 100644 --- a/src/common/aggregators.ts +++ b/src/common/aggregators.ts @@ -31,8 +31,8 @@ export const numericAggregators: IdMap> = mapNew([ (numbers: number[], length: number): number => arraySum(numbers) / length, (metric: number, add: number, length: number): number => metric + (add - metric) / (length + 1), - (metric: number, remove: number, length: number): number => - metric + (metric - remove) / (length - 1), + (metric: number, remove: number, length: number): number | undefined => + length > 1 ? metric + (metric - remove) / (length - 1) : undefined, (metric: number, add: number, remove: number, length: number): number => metric + (add - remove) / length, ], diff --git a/test/unit/core/other/metrics.test.ts b/test/unit/core/other/metrics.test.ts index 3b7e733a5cc..5c163b177c5 100644 --- a/test/unit/core/other/metrics.test.ts +++ b/test/unit/core/other/metrics.test.ts @@ -65,6 +65,24 @@ describe('Sets', () => { expect(metrics.getMetric('m1')).toBeUndefined(); }); + test('avg after replacing all rows in a transaction', () => { + store.setCell('t1', 'r1', 'c1', 1); + metrics.setMetricDefinition('m1', 't1', 'avg', 'c1'); + const listener = vi.fn(); + metrics.addMetricListener('m1', listener); + + store.transaction(() => { + store.delRow('t1', 'r1'); + store.setCell('t1', 'r2', 'c1', 2); + store.setCell('t1', 'r3', 'c1', 4); + }); + + expect(metrics.getMetric('m1')).toBe(3); + expect(listener).toHaveBeenCalledExactlyOnceWith(metrics, 'm1', 3, 1); + store.setCell('t1', 'r3', 'c1', 6); + expect(metrics.getMetric('m1')).toBe(4); + }); + test('min', () => { setCells(); metrics.setMetricDefinition('m1', 't1', 'min', 'c1');