From 04108155d84d6ad09b130ff7451b6a42f03e749b Mon Sep 17 00:00:00 2001 From: Tien Dao <15717476+tiendn@users.noreply.github.com> Date: Sun, 27 Oct 2024 21:10:00 +0700 Subject: [PATCH] fix: Add unit tests for math utility functions and fix median calculation (#4753) ### Description This pull request introduces the following changes to the math utility functions: #### Fix Median Calculation: Corrected the median function to handle even-length arrays properly by averaging the two middle numbers. #### Add Unit Tests: Implemented unit tests for the math utility functions using Chai to ensure their correctness and reliability. The functions tested include: - `median`: Tests for both odd and even-length arrays. - `sum`: Verifies the sum of an array of numbers. - `mean`: Checks the calculation of the mean. - `stdDev`: Validates the standard deviation calculation, including cases with negative numbers. - `randomInt`: Ensures the generated random integer falls within the specified range. ### Drive-by changes - Code: Updated the median function in math.ts to correctly calculate the median for even-length arrays. - Tests: Added a new test file math.test.ts with comprehensive test cases for each function. ### Related issues Fixes [#[4754]](https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/4754) ### Backward compatibility Yes ### Testing - All tests have been executed and passed successfully, confirming the correctness of the functions. - Special attention was given to edge cases, such as arrays with negative numbers and random integer generation. --- .changeset/healthy-boats-lie.md | 5 ++++ typescript/utils/src/math.test.ts | 48 +++++++++++++++++++++++++++++++ typescript/utils/src/math.ts | 2 +- 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 .changeset/healthy-boats-lie.md create mode 100644 typescript/utils/src/math.test.ts diff --git a/.changeset/healthy-boats-lie.md b/.changeset/healthy-boats-lie.md new file mode 100644 index 0000000000..2eb1bb0a46 --- /dev/null +++ b/.changeset/healthy-boats-lie.md @@ -0,0 +1,5 @@ +--- +'@hyperlane-xyz/utils': patch +--- + +fix median utils func + add test diff --git a/typescript/utils/src/math.test.ts b/typescript/utils/src/math.test.ts new file mode 100644 index 0000000000..e2f484d656 --- /dev/null +++ b/typescript/utils/src/math.test.ts @@ -0,0 +1,48 @@ +import { expect } from 'chai'; + +import { mean, median, randomInt, stdDev, sum } from './math.js'; + +describe('Math Utility Functions', () => { + describe('median', () => { + it('should return the median of an odd-length array', () => { + expect(median([1, 3, 2])).to.equal(2); + }); + + it('should return the median of an even-length array', () => { + expect(median([1, 2, 3, 4])).to.equal(2.5); + }); + + it('should return the median of an even-length array with non sorted numbers', () => { + expect(median([1, 2, 0, 4, 5, 6])).to.equal(3); + }); + }); + + describe('sum', () => { + it('should return the sum of an array', () => { + expect(sum([1, 2, 3, 4])).to.equal(10); + }); + }); + + describe('mean', () => { + it('should return the mean of an array', () => { + expect(mean([1, 2, 3, 4])).to.equal(2.5); + }); + }); + + describe('stdDev', () => { + it('should return the standard deviation of an array', () => { + expect(stdDev([1, 2, 3, 4])).to.be.closeTo(1.118, 0.001); + }); + }); + + describe('randomInt', () => { + it('should return a random integer within the specified range', () => { + const min = 1; + const max = 10; + const result = randomInt(max, min); + expect(result).to.be.at.least(min); + expect(result).to.be.below(max); + expect(result % 1).to.equal(0); // its an integer + }); + }); +}); diff --git a/typescript/utils/src/math.ts b/typescript/utils/src/math.ts index ebca6e75ef..4cc71bf80f 100644 --- a/typescript/utils/src/math.ts +++ b/typescript/utils/src/math.ts @@ -2,7 +2,7 @@ export function median(a: number[]): number { const sorted = a.slice().sort(); const mid = Math.floor(sorted.length / 2); const median = - sorted.length % 2 == 0 ? (sorted[mid] + sorted[mid + 1]) / 2 : sorted[mid]; + sorted.length % 2 == 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid]; return median; }