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.
<!--
What's included in this PR?
-->

### 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.
<!--
Are there any minor or drive-by changes also included?
-->

### Related issues

<!--
- Fixes [#[issue number
here]](https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/4754)
-->
Fixes
[#[4754]](https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/4754)

### Backward compatibility
Yes
<!--
Are these changes backward compatible? Are there any infrastructure
implications, e.g. changes that would prohibit deploying older commits
using this infra tooling?

Yes/No
-->

### 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.
<!--
What kind of testing have these changes undergone?

None/Manual/Unit Tests
-->
pull/4772/head
Tien Dao 4 weeks ago committed by GitHub
parent 892a1d8282
commit 04108155d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      .changeset/healthy-boats-lie.md
  2. 48
      typescript/utils/src/math.test.ts
  3. 2
      typescript/utils/src/math.ts

@ -0,0 +1,5 @@
---
'@hyperlane-xyz/utils': patch
---
fix median utils func + add test

@ -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
});
});
});

@ -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;
}

Loading…
Cancel
Save