From 0889e092afe774d0e8db6885e5962c4a8278b6cf Mon Sep 17 00:00:00 2001 From: Christian Baroni <7061887+christianbaroni@users.noreply.github.com> Date: Mon, 27 May 2024 15:56:18 -0400 Subject: [PATCH] Swaps: fix safe math negative number support, add comparison functions (#5776) * Fix negative number support, add number comparison functions * Add Worklet suffix to safe math functions --- src/__swaps__/safe-math/SafeMath.ts | 199 ++++++++++++------ .../safe-math/__tests__/SafeMath.test.ts | 174 +++++++++++---- 2 files changed, 270 insertions(+), 103 deletions(-) diff --git a/src/__swaps__/safe-math/SafeMath.ts b/src/__swaps__/safe-math/SafeMath.ts index 017ed7a22b2..c98ea7536fa 100644 --- a/src/__swaps__/safe-math/SafeMath.ts +++ b/src/__swaps__/safe-math/SafeMath.ts @@ -1,16 +1,19 @@ // Utility function to remove the decimal point and keep track of the number of decimal places -const removeDecimal = (num: string): [bigint, number] => { +const removeDecimalWorklet = (num: string): [bigint, number] => { + 'worklet'; const parts = num.split('.'); const decimalPlaces = parts.length === 2 ? parts[1].length : 0; const bigIntNum = BigInt(parts.join('')); return [bigIntNum, decimalPlaces]; }; -const isNumberString = (value: string): boolean => { - return /^\d+(\.\d+)?$/.test(value); +const isNumberStringWorklet = (value: string): boolean => { + 'worklet'; + return /^-?\d+(\.\d+)?$/.test(value); }; -const isZero = (value: string): boolean => { +const isZeroWorklet = (value: string): boolean => { + 'worklet'; if (parseFloat(value) === 0) { return true; } @@ -18,125 +21,201 @@ const isZero = (value: string): boolean => { }; // Utility function to scale the number up to 20 decimal places -const scaleUp = (bigIntNum: bigint, decimalPlaces: number): bigint => { - const scaleFactor = BigInt(10) ** (BigInt(20) - BigInt(decimalPlaces)); - return bigIntNum * scaleFactor; +const scaleUpWorklet = (bigIntNum: bigint, decimalPlaces: number): bigint => { + 'worklet'; + const scaleFactor = BigInt(10) ** BigInt(20); + return (bigIntNum * scaleFactor) / BigInt(10) ** BigInt(decimalPlaces); }; // Utility function to format the result with 20 decimal places and remove trailing zeros -const formatResult = (result: bigint): string => { - const resultStr = result.toString().padStart(21, '0'); // 20 decimal places + at least 1 integer place +const formatResultWorklet = (result: bigint): string => { + 'worklet'; + const isNegative = result < 0; + const absResult = isNegative ? -result : result; + const resultStr = absResult.toString().padStart(21, '0'); // 20 decimal places + at least 1 integer place const integerPart = resultStr.slice(0, -20) || '0'; let fractionalPart = resultStr.slice(-20); fractionalPart = fractionalPart.replace(/0+$/, ''); // Remove trailing zeros - return fractionalPart.length > 0 ? `${integerPart}.${fractionalPart}` : integerPart; + const formattedResult = fractionalPart.length > 0 ? `${integerPart}.${fractionalPart}` : integerPart; + return isNegative ? `-${formattedResult}` : formattedResult; }; // Sum function -export function sum(num1: string, num2: string): string { - if (!isNumberString(num1) || !isNumberString(num2)) { +export function sumWorklet(num1: string, num2: string): string { + 'worklet'; + if (!isNumberStringWorklet(num1) || !isNumberStringWorklet(num2)) { throw new Error('Arguments must be a numeric string'); } - if (isZero(num1)) { + if (isZeroWorklet(num1)) { return num2; } - if (isZero(num2)) { + if (isZeroWorklet(num2)) { return num1; } - const [bigInt1, decimalPlaces1] = removeDecimal(num1); - const [bigInt2, decimalPlaces2] = removeDecimal(num2); - const scaledBigInt1 = scaleUp(bigInt1, decimalPlaces1); - const scaledBigInt2 = scaleUp(bigInt2, decimalPlaces2); + const [bigInt1, decimalPlaces1] = removeDecimalWorklet(num1); + const [bigInt2, decimalPlaces2] = removeDecimalWorklet(num2); + const scaledBigInt1 = scaleUpWorklet(bigInt1, decimalPlaces1); + const scaledBigInt2 = scaleUpWorklet(bigInt2, decimalPlaces2); const result = scaledBigInt1 + scaledBigInt2; - return formatResult(result); + return formatResultWorklet(result); } // Subtract function -export function sub(num1: string, num2: string): string { - if (!isNumberString(num1) || !isNumberString(num2)) { +export function subWorklet(num1: string, num2: string): string { + 'worklet'; + if (!isNumberStringWorklet(num1) || !isNumberStringWorklet(num2)) { throw new Error('Arguments must be a numeric string'); } - if (isZero(num2)) { + if (isZeroWorklet(num2)) { return num1; } - const [bigInt1, decimalPlaces1] = removeDecimal(num1); - const [bigInt2, decimalPlaces2] = removeDecimal(num2); - const scaledBigInt1 = scaleUp(bigInt1, decimalPlaces1); - const scaledBigInt2 = scaleUp(bigInt2, decimalPlaces2); + const [bigInt1, decimalPlaces1] = removeDecimalWorklet(num1); + const [bigInt2, decimalPlaces2] = removeDecimalWorklet(num2); + const scaledBigInt1 = scaleUpWorklet(bigInt1, decimalPlaces1); + const scaledBigInt2 = scaleUpWorklet(bigInt2, decimalPlaces2); const result = scaledBigInt1 - scaledBigInt2; - return formatResult(result); + return formatResultWorklet(result); } // Multiply function -export function mul(num1: string, num2: string): string { - if (!isNumberString(num1) || !isNumberString(num2)) { +export function mulWorklet(num1: string, num2: string): string { + 'worklet'; + if (!isNumberStringWorklet(num1) || !isNumberStringWorklet(num2)) { throw new Error('Arguments must be a numeric string'); } - if (isZero(num1) || isZero(num2)) { + if (isZeroWorklet(num1) || isZeroWorklet(num2)) { return '0'; } - const [bigInt1, decimalPlaces1] = removeDecimal(num1); - const [bigInt2, decimalPlaces2] = removeDecimal(num2); - const scaledBigInt1 = scaleUp(bigInt1, decimalPlaces1); - const scaledBigInt2 = scaleUp(bigInt2, decimalPlaces2); + const [bigInt1, decimalPlaces1] = removeDecimalWorklet(num1); + const [bigInt2, decimalPlaces2] = removeDecimalWorklet(num2); + const scaledBigInt1 = scaleUpWorklet(bigInt1, decimalPlaces1); + const scaledBigInt2 = scaleUpWorklet(bigInt2, decimalPlaces2); const result = (scaledBigInt1 * scaledBigInt2) / BigInt(10) ** BigInt(20); - return formatResult(result); + return formatResultWorklet(result); } // Divide function -export function div(num1: string, num2: string): string { - if (!isNumberString(num1) || !isNumberString(num2)) { +export function divWorklet(num1: string, num2: string): string { + 'worklet'; + if (!isNumberStringWorklet(num1) || !isNumberStringWorklet(num2)) { throw new Error('Arguments must be a numeric string'); } - if (isZero(num2)) { + if (isZeroWorklet(num2)) { throw new Error('Division by zero'); } - if (isZero(num1)) { + if (isZeroWorklet(num1)) { return '0'; } - const [bigInt1, decimalPlaces1] = removeDecimal(num1); - const [bigInt2, decimalPlaces2] = removeDecimal(num2); - const scaledBigInt1 = scaleUp(bigInt1, decimalPlaces1); - const scaledBigInt2 = scaleUp(bigInt2, decimalPlaces2); + const [bigInt1, decimalPlaces1] = removeDecimalWorklet(num1); + const [bigInt2, decimalPlaces2] = removeDecimalWorklet(num2); + const scaledBigInt1 = scaleUpWorklet(bigInt1, decimalPlaces1); + const scaledBigInt2 = scaleUpWorklet(bigInt2, decimalPlaces2); const result = (scaledBigInt1 * BigInt(10) ** BigInt(20)) / scaledBigInt2; - return formatResult(result); + return formatResultWorklet(result); } // Modulus function -export function mod(num1: string, num2: string): string { - if (!isNumberString(num1) || !isNumberString(num2)) { +export function modWorklet(num1: string, num2: string): string { + 'worklet'; + if (!isNumberStringWorklet(num1) || !isNumberStringWorklet(num2)) { throw new Error('Arguments must be a numeric string'); } - if (isZero(num2)) { + if (isZeroWorklet(num2)) { throw new Error('Division by zero'); } - if (isZero(num1)) { + if (isZeroWorklet(num1)) { return '0'; } - const [bigInt1, decimalPlaces1] = removeDecimal(num1); - const [bigInt2, decimalPlaces2] = removeDecimal(num2); - const scaledBigInt1 = scaleUp(bigInt1, decimalPlaces1); - const scaledBigInt2 = scaleUp(bigInt2, decimalPlaces2); + const [bigInt1, decimalPlaces1] = removeDecimalWorklet(num1); + const [bigInt2, decimalPlaces2] = removeDecimalWorklet(num2); + const scaledBigInt1 = scaleUpWorklet(bigInt1, decimalPlaces1); + const scaledBigInt2 = scaleUpWorklet(bigInt2, decimalPlaces2); const result = scaledBigInt1 % scaledBigInt2; - return formatResult(result); + return formatResultWorklet(result); } // Power function -export function pow(base: string, exponent: string): string { - if (!isNumberString(base) || !isNumberString(exponent)) { +export function powWorklet(base: string, exponent: string): string { + 'worklet'; + if (!isNumberStringWorklet(base) || !isNumberStringWorklet(exponent)) { throw new Error('Arguments must be a numeric string'); } - if (isZero(base)) { + if (isZeroWorklet(base)) { return '0'; } - if (isZero(exponent)) { + if (isZeroWorklet(exponent)) { return '1'; } - const [bigIntBase, decimalPlaces] = removeDecimal(base); - const scaledBigIntBase = scaleUp(bigIntBase, decimalPlaces); + const [bigIntBase, decimalPlaces] = removeDecimalWorklet(base); + const scaledBigIntBase = scaleUpWorklet(bigIntBase, decimalPlaces); const result = scaledBigIntBase ** BigInt(exponent) / BigInt(10) ** BigInt(20); - return formatResult(result); + return formatResultWorklet(result); +} + +// Equality function +export function equalWorklet(num1: string, num2: string): boolean { + 'worklet'; + if (!isNumberStringWorklet(num1) || !isNumberStringWorklet(num2)) { + throw new Error('Arguments must be a numeric string'); + } + const [bigInt1, decimalPlaces1] = removeDecimalWorklet(num1); + const [bigInt2, decimalPlaces2] = removeDecimalWorklet(num2); + const scaledBigInt1 = scaleUpWorklet(bigInt1, decimalPlaces1); + const scaledBigInt2 = scaleUpWorklet(bigInt2, decimalPlaces2); + return scaledBigInt1 === scaledBigInt2; +} + +// Greater than function +export function greaterThanWorklet(num1: string, num2: string): boolean { + 'worklet'; + if (!isNumberStringWorklet(num1) || !isNumberStringWorklet(num2)) { + throw new Error('Arguments must be a numeric string'); + } + const [bigInt1, decimalPlaces1] = removeDecimalWorklet(num1); + const [bigInt2, decimalPlaces2] = removeDecimalWorklet(num2); + const scaledBigInt1 = scaleUpWorklet(bigInt1, decimalPlaces1); + const scaledBigInt2 = scaleUpWorklet(bigInt2, decimalPlaces2); + return scaledBigInt1 > scaledBigInt2; +} + +// Greater than or equal to function +export function greaterThanOrEqualToWorklet(num1: string, num2: string): boolean { + 'worklet'; + if (!isNumberStringWorklet(num1) || !isNumberStringWorklet(num2)) { + throw new Error('Arguments must be a numeric string'); + } + const [bigInt1, decimalPlaces1] = removeDecimalWorklet(num1); + const [bigInt2, decimalPlaces2] = removeDecimalWorklet(num2); + const scaledBigInt1 = scaleUpWorklet(bigInt1, decimalPlaces1); + const scaledBigInt2 = scaleUpWorklet(bigInt2, decimalPlaces2); + return scaledBigInt1 >= scaledBigInt2; +} + +// Less than function +export function lessThanWorklet(num1: string, num2: string): boolean { + 'worklet'; + if (!isNumberStringWorklet(num1) || !isNumberStringWorklet(num2)) { + throw new Error('Arguments must be a numeric string'); + } + const [bigInt1, decimalPlaces1] = removeDecimalWorklet(num1); + const [bigInt2, decimalPlaces2] = removeDecimalWorklet(num2); + const scaledBigInt1 = scaleUpWorklet(bigInt1, decimalPlaces1); + const scaledBigInt2 = scaleUpWorklet(bigInt2, decimalPlaces2); + return scaledBigInt1 < scaledBigInt2; +} + +// Less than or equal to function +export function lessThanOrEqualToWorklet(num1: string, num2: string): boolean { + 'worklet'; + if (!isNumberStringWorklet(num1) || !isNumberStringWorklet(num2)) { + throw new Error('Arguments must be a numeric string'); + } + const [bigInt1, decimalPlaces1] = removeDecimalWorklet(num1); + const [bigInt2, decimalPlaces2] = removeDecimalWorklet(num2); + const scaledBigInt1 = scaleUpWorklet(bigInt1, decimalPlaces1); + const scaledBigInt2 = scaleUpWorklet(bigInt2, decimalPlaces2); + return scaledBigInt1 <= scaledBigInt2; } diff --git a/src/__swaps__/safe-math/__tests__/SafeMath.test.ts b/src/__swaps__/safe-math/__tests__/SafeMath.test.ts index ee2c4b55beb..a80196afeec 100644 --- a/src/__swaps__/safe-math/__tests__/SafeMath.test.ts +++ b/src/__swaps__/safe-math/__tests__/SafeMath.test.ts @@ -1,5 +1,17 @@ -import { sum, sub, mul, div, mod, pow } from '../SafeMath'; import BigNumber from 'bignumber.js'; +import { + divWorklet, + equalWorklet, + greaterThanOrEqualToWorklet, + greaterThanWorklet, + lessThanOrEqualToWorklet, + lessThanWorklet, + modWorklet, + mulWorklet, + powWorklet, + subWorklet, + sumWorklet, +} from '../SafeMath'; const RESULTS = { sum: '1247244.585', @@ -13,62 +25,110 @@ const RESULTS = { const VALUE_A = '1243425.345'; const VALUE_B = '3819.24'; const VALUE_C = '2'; +const NEGATIVE_VALUE = '-2412.12'; const ZERO = '0'; const ONE = '1'; const NON_NUMERIC_STRING = 'abc'; describe('SafeMath', () => { - test('sum', () => { - expect(() => sum(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); - expect(() => sum(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); - expect(sum(ZERO, ZERO)).toBe(ZERO); - expect(sum(VALUE_A, ZERO)).toBe(VALUE_A); - expect(sum(ZERO, VALUE_B)).toBe(VALUE_B); - expect(sum(VALUE_A, VALUE_B)).toBe(RESULTS.sum); + test('sumWorklet', () => { + expect(() => sumWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => sumWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(sumWorklet(ZERO, ZERO)).toBe(ZERO); + expect(sumWorklet(VALUE_A, ZERO)).toBe(VALUE_A); + expect(sumWorklet(ZERO, VALUE_B)).toBe(VALUE_B); + expect(sumWorklet(VALUE_A, VALUE_B)).toBe(RESULTS.sum); }); - test('sub', () => { - expect(() => sub(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); - expect(() => sub(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); - expect(sub(ZERO, ZERO)).toBe(ZERO); - expect(sub(VALUE_A, ZERO)).toBe(VALUE_A); - expect(sub(ZERO, VALUE_B)).toBe(`-${VALUE_B}`); - expect(sub(VALUE_A, VALUE_B)).toBe(RESULTS.sub); + test('subWorklet', () => { + expect(() => subWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => subWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(subWorklet(ZERO, ZERO)).toBe(ZERO); + expect(subWorklet(VALUE_A, ZERO)).toBe(VALUE_A); + expect(subWorklet(ZERO, VALUE_B)).toBe(`-${VALUE_B}`); + expect(subWorklet(NEGATIVE_VALUE, ZERO)).toBe(NEGATIVE_VALUE); + expect(subWorklet(VALUE_A, VALUE_B)).toBe(RESULTS.sub); }); - test('mul', () => { - expect(() => mul(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); - expect(() => mul(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); - expect(mul(ZERO, ZERO)).toBe(ZERO); - expect(mul(VALUE_A, ZERO)).toBe(ZERO); - expect(mul(ZERO, VALUE_B)).toBe(ZERO); - expect(mul(VALUE_A, VALUE_B)).toBe(RESULTS.mul); + test('mulWorklet', () => { + expect(() => mulWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => mulWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(mulWorklet(ZERO, ZERO)).toBe(ZERO); + expect(mulWorklet(VALUE_A, ZERO)).toBe(ZERO); + expect(mulWorklet(ZERO, VALUE_B)).toBe(ZERO); + expect(mulWorklet(VALUE_A, VALUE_B)).toBe(RESULTS.mul); }); - test('div', () => { - expect(() => div(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); - expect(() => div(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); - expect(() => div(ZERO, ZERO)).toThrow('Division by zero'); - expect(() => div(VALUE_A, ZERO)).toThrow('Division by zero'); - expect(div(ZERO, VALUE_B)).toBe(ZERO); - expect(div(VALUE_A, VALUE_B)).toBe(RESULTS.div); + test('divWorklet', () => { + expect(() => divWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => divWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(() => divWorklet(ZERO, ZERO)).toThrow('Division by zero'); + expect(() => divWorklet(VALUE_A, ZERO)).toThrow('Division by zero'); + expect(divWorklet(ZERO, VALUE_B)).toBe(ZERO); + expect(divWorklet(VALUE_A, VALUE_B)).toBe(RESULTS.div); }); - test('mod', () => { - expect(() => mod(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); - expect(() => mod(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); - expect(() => mod(ZERO, ZERO)).toThrow('Division by zero'); - expect(() => mod(VALUE_A, ZERO)).toThrow('Division by zero'); - expect(mod(ZERO, VALUE_B)).toBe(ZERO); - expect(mod(VALUE_A, VALUE_B)).toBe(RESULTS.mod); + test('modWorklet', () => { + expect(() => modWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => modWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(() => modWorklet(ZERO, ZERO)).toThrow('Division by zero'); + expect(() => modWorklet(VALUE_A, ZERO)).toThrow('Division by zero'); + expect(modWorklet(ZERO, VALUE_B)).toBe(ZERO); + expect(modWorklet(VALUE_A, VALUE_B)).toBe(RESULTS.mod); }); - test('pow', () => { - expect(() => pow(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); - expect(() => pow(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); - expect(pow(ZERO, VALUE_B)).toBe(ZERO); - expect(pow(VALUE_A, ZERO)).toBe(ONE); - expect(pow(ZERO, VALUE_B)).toBe(ZERO); - expect(pow(VALUE_A, VALUE_C)).toBe(RESULTS.pow); + + test('powWorklet', () => { + expect(() => powWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => powWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(powWorklet(ZERO, VALUE_B)).toBe(ZERO); + expect(powWorklet(VALUE_A, ZERO)).toBe(ONE); + expect(powWorklet(ZERO, VALUE_B)).toBe(ZERO); + expect(powWorklet(VALUE_A, VALUE_C)).toBe(RESULTS.pow); + }); + + test('equalWorklet', () => { + expect(() => equalWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => equalWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(equalWorklet(ZERO, ZERO)).toBe(true); + expect(equalWorklet(VALUE_A, VALUE_A)).toBe(true); + expect(equalWorklet(VALUE_A, VALUE_B)).toBe(false); + expect(equalWorklet(NEGATIVE_VALUE, NEGATIVE_VALUE)).toBe(true); + }); + + test('greaterThanWorklet', () => { + expect(() => greaterThanWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => greaterThanWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(greaterThanWorklet(VALUE_A, VALUE_B)).toBe(true); + expect(greaterThanWorklet(VALUE_B, VALUE_A)).toBe(false); + expect(greaterThanWorklet(VALUE_A, VALUE_A)).toBe(false); + expect(greaterThanWorklet(NEGATIVE_VALUE, VALUE_A)).toBe(false); + }); + + test('greaterThanOrEqualToWorklet', () => { + expect(() => greaterThanOrEqualToWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => greaterThanOrEqualToWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(greaterThanOrEqualToWorklet(VALUE_A, VALUE_B)).toBe(true); + expect(greaterThanOrEqualToWorklet(VALUE_B, VALUE_A)).toBe(false); + expect(greaterThanOrEqualToWorklet(VALUE_A, VALUE_A)).toBe(true); + expect(greaterThanOrEqualToWorklet(NEGATIVE_VALUE, VALUE_A)).toBe(false); + }); + + test('lessThanWorklet', () => { + expect(() => lessThanWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => lessThanWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(lessThanWorklet(VALUE_A, VALUE_B)).toBe(false); + expect(lessThanWorklet(VALUE_B, VALUE_A)).toBe(true); + expect(lessThanWorklet(VALUE_A, VALUE_A)).toBe(false); + expect(lessThanWorklet(NEGATIVE_VALUE, VALUE_A)).toBe(true); + }); + + test('lessThanOrEqualToWorklet', () => { + expect(() => lessThanOrEqualToWorklet(NON_NUMERIC_STRING, VALUE_B)).toThrow('Arguments must be a numeric string'); + expect(() => lessThanOrEqualToWorklet(VALUE_A, NON_NUMERIC_STRING)).toThrow('Arguments must be a numeric string'); + expect(lessThanOrEqualToWorklet(VALUE_A, VALUE_B)).toBe(false); + expect(lessThanOrEqualToWorklet(VALUE_B, VALUE_A)).toBe(true); + expect(lessThanOrEqualToWorklet(VALUE_A, VALUE_A)).toBe(true); + expect(lessThanOrEqualToWorklet(NEGATIVE_VALUE, VALUE_A)).toBe(true); }); }); @@ -92,7 +152,35 @@ describe('BigNumber', () => { test('mod', () => { expect(new BigNumber(VALUE_A).mod(VALUE_B).toString()).toBe(RESULTS.mod); }); + test('pow', () => { expect(new BigNumber(VALUE_A).pow(VALUE_C).toString()).toBe(RESULTS.pow); }); + + test('equal', () => { + expect(new BigNumber(VALUE_A).eq(VALUE_B)).toBe(false); + expect(new BigNumber(VALUE_A).eq(VALUE_A)).toBe(true); + }); + + test('greaterThan', () => { + expect(new BigNumber(VALUE_A).gt(VALUE_B)).toBe(true); + expect(new BigNumber(VALUE_B).gt(VALUE_A)).toBe(false); + }); + + test('greaterThanOrEqualTo', () => { + expect(new BigNumber(VALUE_A).gte(VALUE_B)).toBe(true); + expect(new BigNumber(VALUE_B).gte(VALUE_A)).toBe(false); + expect(new BigNumber(VALUE_A).gte(VALUE_A)).toBe(true); + }); + + test('lessThan', () => { + expect(new BigNumber(VALUE_A).lt(VALUE_B)).toBe(false); + expect(new BigNumber(VALUE_B).lt(VALUE_A)).toBe(true); + }); + + test('lessThanOrEqualTo', () => { + expect(new BigNumber(VALUE_A).lte(VALUE_B)).toBe(false); + expect(new BigNumber(VALUE_B).lte(VALUE_A)).toBe(true); + expect(new BigNumber(VALUE_A).lte(VALUE_A)).toBe(true); + }); });