Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/utils/__tests__/priceChange.utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// src/utils/__tests__/priceChange.utils.test.ts
import { describe, expect, it } from 'vitest';
import { computePriceChange } from '../priceChange.utils';

describe('computePriceChange', () => {
describe('price up', () => {
it('returns positive percent and direction up when price increases', () => {
const result = computePriceChange(112n, 100n);
expect(result.direction).toBe('up');
expect(result.percent).toBeCloseTo(12);
});

it('handles a large price increase', () => {
const result = computePriceChange(200n, 100n);
expect(result.direction).toBe('up');
expect(result.percent).toBeCloseTo(100);
});
});

describe('price down', () => {
it('returns negative percent and direction down when price decreases', () => {
const result = computePriceChange(88n, 100n);
expect(result.direction).toBe('down');
expect(result.percent).toBeCloseTo(-12);
});

it('handles a large price decrease', () => {
const result = computePriceChange(1n, 100n);
expect(result.direction).toBe('down');
expect(result.percent).toBeCloseTo(-99);
});
});

describe('flat — no change', () => {
it('returns flat with 0 percent when current equals previous', () => {
const result = computePriceChange(100n, 100n);
expect(result.direction).toBe('flat');
expect(result.percent).toBe(0);
});
});

describe('flat — zero previous value', () => {
it('returns flat with 0 percent when previous is zero', () => {
const result = computePriceChange(100n, 0n);
expect(result.direction).toBe('flat');
expect(result.percent).toBe(0);
});

it('returns flat when both current and previous are zero', () => {
const result = computePriceChange(0n, 0n);
expect(result.direction).toBe('flat');
expect(result.percent).toBe(0);
});
});
});
46 changes: 46 additions & 0 deletions src/utils/priceChange.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// src/utils/priceChange.utils.ts

/**
* Result of a price change computation between two key price values.
*/
export interface PriceChangeResult {
/** Percentage change as a number, e.g. 12.4 or -3.1. Always 0 when direction is 'flat'. */
percent: number;
/** Direction of the price movement relative to the previous value. */
direction: 'up' | 'down' | 'flat';
}

/**
* Computes the percentage price change between two key price values expressed
* in stroops (bigint).
*
* Returns `flat` with `percent: 0` when:
* - `previous` is zero (division by zero is undefined)
* - `current` equals `previous` (no change)
*
* @param current - The current key price in stroops
* @param previous - The previous key price in stroops
* @returns PriceChangeResult with percent and direction
*
* @example
* computePriceChange(112n, 100n) // { percent: 12, direction: 'up' }
* computePriceChange(88n, 100n) // { percent: -12, direction: 'down' }
* computePriceChange(100n, 100n) // { percent: 0, direction: 'flat' }
* computePriceChange(100n, 0n) // { percent: 0, direction: 'flat' }
*/
export function computePriceChange(
current: bigint,
previous: bigint
): PriceChangeResult {
if (previous === 0n || current === previous) {
return { percent: 0, direction: 'flat' };
}

const percent =
(Number(current - previous) / Number(previous)) * 100;

return {
percent,
direction: percent > 0 ? 'up' : 'down',
};
}
Loading