-
-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add coercion utils #38
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import type { Hex } from '../hex'; | ||
|
||
export const POSITIVE_INTEGERS = [0, 1, 10, 100, 1000, 123456789, 2147483647]; | ||
export const NEGATIVE_INTEGERS = [ | ||
-1, -10, -100, -1000, -123456789, -2147483647, | ||
]; | ||
export const DECIMAL_NUMBERS = [ | ||
1.1, 1.123456789, 1.123456789123456789, -1.1, -1.123456789, | ||
-1.123456789123456789, | ||
]; | ||
|
||
export const HEX_STRINGS: Hex[] = [ | ||
'0x', | ||
'0x00', | ||
'0x1a', | ||
'0x2b', | ||
'0x3c', | ||
'0xff', | ||
'0xff00ff', | ||
'0x1234567890abcdef', | ||
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', | ||
]; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
export * from './bytes'; | ||
export * from './coercions'; | ||
export * from './json'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import { | ||
DECIMAL_NUMBERS, | ||
HEX_STRINGS, | ||
NEGATIVE_INTEGERS, | ||
POSITIVE_INTEGERS, | ||
} from './__fixtures__'; | ||
import { createBigInt, createBytes, createHex, createNumber } from './coercers'; | ||
import { add0x } from './hex'; | ||
import { bytesToHex, hexToBytes } from './bytes'; | ||
|
||
describe('createNumber', () => { | ||
it.each(POSITIVE_INTEGERS)( | ||
'creates a number from a positive number-like value', | ||
(value) => { | ||
expect(createNumber(value)).toBe(value); | ||
expect(createNumber(BigInt(value))).toBe(value); | ||
expect(createNumber(add0x(value.toString(16)))).toBe(value); | ||
expect(createNumber(value.toString(10))).toBe(value); | ||
}, | ||
); | ||
|
||
it.each(NEGATIVE_INTEGERS)( | ||
'creates a number from a negative number-like value', | ||
(value) => { | ||
expect(createNumber(value)).toBe(value); | ||
expect(createNumber(BigInt(value))).toBe(value); | ||
expect(createNumber(value.toString(10))).toBe(value); | ||
}, | ||
); | ||
|
||
it.each(DECIMAL_NUMBERS)( | ||
'creates a number from a positive number-like value with decimals', | ||
(value) => { | ||
expect(createNumber(value)).toBe(value); | ||
expect(createNumber(value.toString(10))).toBe(value); | ||
}, | ||
); | ||
|
||
it('handles -0', () => { | ||
expect(createNumber('-0')).toBe(-0); | ||
expect(createNumber(BigInt('-0'))).toBe(0); | ||
}); | ||
|
||
it('throws if the result is not finite', () => { | ||
expect(() => createNumber(Infinity)).toThrow( | ||
'Expected a number-like value, got "Infinity".', | ||
); | ||
|
||
expect(() => createNumber(-Infinity)).toThrow( | ||
'Expected a number-like value, got "-Infinity".', | ||
); | ||
}); | ||
|
||
it.each([true, false, null, undefined, NaN, {}, []])( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens with negative zero? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. console.log(createNumber(-0)); // -0
console.log(createNumber('-0')); // -0
console.log(createNumber(BigInt(-0))); // 0 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think it is worth adding tests for these cases? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's literally 1 line change, why not. But not that important if you want to just merge |
||
'throws if the value is not a number-like value', | ||
(value) => { | ||
// @ts-expect-error Invalid type. | ||
expect(() => createNumber(value)).toThrow( | ||
/Expected a number-like value, got "(.*)"\./u, | ||
); | ||
}, | ||
); | ||
}); | ||
|
||
describe('createBigInt', () => { | ||
Mrtenz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
it.each(POSITIVE_INTEGERS)( | ||
'creates a bigint from a positive number-like value', | ||
(value) => { | ||
expect(createBigInt(value)).toBe(BigInt(value)); | ||
expect(createBigInt(add0x(value.toString(16)))).toBe(BigInt(value)); | ||
expect(createBigInt(value.toString(10))).toBe(BigInt(value)); | ||
}, | ||
); | ||
|
||
it.each(NEGATIVE_INTEGERS)( | ||
'creates a bigint from a negative number-like value', | ||
(value) => { | ||
expect(createBigInt(value)).toBe(BigInt(value)); | ||
expect(createBigInt(value.toString(10))).toBe(BigInt(value)); | ||
}, | ||
); | ||
|
||
it.each([true, false, null, undefined, NaN, {}, []])( | ||
'throws if the value is not a number-like value', | ||
(value) => { | ||
// @ts-expect-error Invalid type. | ||
expect(() => createBigInt(value)).toThrow( | ||
/Expected a number-like value, got "(.*)"\./u, | ||
); | ||
}, | ||
); | ||
|
||
it('handles -0', () => { | ||
expect(createBigInt('-0')).toBe(BigInt(0)); | ||
expect(createBigInt(-0)).toBe(BigInt(0)); | ||
}); | ||
}); | ||
|
||
describe('createHex', () => { | ||
it.each(HEX_STRINGS)( | ||
'creates a hex string from a byte-like value', | ||
(value) => { | ||
const bytes = hexToBytes(value); | ||
|
||
expect(createHex(value)).toBe(value); | ||
expect(createHex(bytesToHex(bytes))).toBe(value); | ||
}, | ||
); | ||
|
||
it.each([true, false, null, undefined, NaN, {}, [], '', '11ff'])( | ||
'throws if the value is not a bytes-like value', | ||
(value) => { | ||
// @ts-expect-error Invalid type. | ||
expect(() => createHex(value)).toThrow( | ||
/Expected a bytes-like value, got "(.*)"\./u, | ||
); | ||
}, | ||
); | ||
|
||
it('handles empty byte arrays', () => { | ||
expect(createHex('0x')).toBe('0x'); | ||
expect(createHex(new Uint8Array())).toBe('0x'); | ||
}); | ||
}); | ||
|
||
describe('createBytes', () => { | ||
it.each(HEX_STRINGS)( | ||
'creates a byte array from a byte-like value', | ||
(value) => { | ||
const bytes = hexToBytes(value); | ||
|
||
expect(createBytes(value)).toStrictEqual(bytes); | ||
expect(createBytes(bytesToHex(bytes))).toStrictEqual(bytes); | ||
}, | ||
); | ||
|
||
it.each([true, false, null, undefined, NaN, {}, [], '', '11ff'])( | ||
'throws if the value is not a bytes-like value', | ||
(value) => { | ||
// @ts-expect-error Invalid type. | ||
expect(() => createBytes(value)).toThrow( | ||
/Expected a bytes-like value, got "(.*)"\./u, | ||
); | ||
}, | ||
); | ||
|
||
it('handles empty byte arrays', () => { | ||
expect(createBytes('0x')).toStrictEqual(new Uint8Array()); | ||
expect(createBytes(new Uint8Array())).toStrictEqual(new Uint8Array()); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we test that this accepts 0x-prefixed hex strings? And also treats strings that look like numbers as decimals?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utils/src/coercers.test.ts
Lines 17 to 18 in d77e1c5