Skip to content

Commit

Permalink
Core-1327 Adds bigint type support #2
Browse files Browse the repository at this point in the history
Co-authored-by: Mehdi Raza Jaffery <[email protected]>
  • Loading branch information
wajahatiqbal and thehappybug authored Feb 22, 2021
1 parent f918d34 commit 99b9e00
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 0 deletions.
17 changes: 17 additions & 0 deletions packages/schema/src/types/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
isNumericString,
toValidator,
coerceNumericStringToNumber,
coerceBigIntStringToNumber,
} from '../utils';

function isValidStringValue(value: unknown): value is string {
Expand Down Expand Up @@ -44,3 +45,19 @@ export function boolean(): Schema<boolean, boolean> {
map: value => (typeof value === 'boolean' ? value : value === 'true'),
});
}

function isValidBigIntValue(value: unknown): value is bigint {
return (
typeof value === 'bigint' ||
(typeof value === 'string' && /^-?\d+$/.test(value))
);
}

/** Create a bigint schema */
export function bigint(): Schema<bigint, bigint> {
return createSymmetricSchema({
type: 'bigint',
validate: toValidator(isValidBigIntValue),
map: coerceBigIntStringToNumber,
});
}
4 changes: 4 additions & 0 deletions packages/schema/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ export function coerceNumericStringToNumber(value: number | string): number {
return typeof value === 'number' ? value : +value;
}

export function coerceBigIntStringToNumber(value: bigint | string): bigint {
return typeof value === 'bigint' ? value : BigInt(value);
}

export function once<Args extends any[], R>(
func: (...args: Args) => R
): (...args: Args) => R {
Expand Down
120 changes: 120 additions & 0 deletions packages/schema/test/types/bigInt.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { bigint, validateAndMap, validateAndUnmap } from '../../src';
describe('bigint', () => {
describe('Mapping', () => {
it('should accept bigint', () => {
const input = BigInt(9532532599932);
const schema = bigint();
const output = validateAndMap(input, schema);
expect(output.errors).toBeFalsy();
expect((output as any).result).toBe(input);
});

it('should accept negative bigint', () => {
const input = BigInt(-9532532599932);
const schema = bigint();
const output = validateAndMap(input, schema);
expect(output.errors).toBeFalsy();
expect((output as any).result).toBe(input);
});

it('should accept bigint string', () => {
const input = '9532532599932';
const schema = bigint();
const output = validateAndMap(input as any, schema);
expect(output.errors).toBeFalsy();
expect((output as any).result).toBe(BigInt(input));
});

it('should accept negative bigint string', () => {
const input = '-9532532599932';
const schema = bigint();
const output = validateAndMap(input as any, schema);
expect(output.errors).toBeFalsy();
expect((output as any).result).toBe(BigInt(input));
});

it('should fail on other types', () => {
const input = true;
const schema = bigint();
const output = validateAndMap(input as any, schema);
expect((output as any).result).toBeUndefined();
expect(output.errors).toHaveLength(1);
expect(output.errors).toMatchInlineSnapshot(`
Array [
Object {
"branch": Array [
true,
],
"message": "Expected value to be of type 'bigint' but found 'boolean'.
Given value: true
Type: 'boolean'
Expected type: 'bigint'",
"path": Array [],
"type": "bigint",
"value": true,
},
]
`);
});
});

describe('Unmapping', () => {
it('should accept bigint', () => {
const input = BigInt(9532532599932);
const schema = bigint();
const output = validateAndUnmap(input, schema);
expect(output.errors).toBeFalsy();
expect((output as any).result).toBe(input);
});

it('should accept negative bigint', () => {
const input = BigInt(-9532532599932);
const schema = bigint();
const output = validateAndUnmap(input, schema);
expect(output.errors).toBeFalsy();
expect((output as any).result).toBe(input);
});

it('should accept bigint string', () => {
const input = '9532532599932';
const schema = bigint();
const output = validateAndUnmap(input as any, schema);
expect(output.errors).toBeFalsy();
expect((output as any).result).toBe(BigInt(input));
});

it('should accept negative bigint string', () => {
const input = '-9532532599932';
const schema = bigint();
const output = validateAndUnmap(input as any, schema);
expect(output.errors).toBeFalsy();
expect((output as any).result).toBe(BigInt(input));
});

it('should fail on other types', () => {
const input = true;
const schema = bigint();
const output = validateAndUnmap(input as any, schema);
expect((output as any).result).toBeUndefined();
expect(output.errors).toHaveLength(1);
expect(output.errors).toMatchInlineSnapshot(`
Array [
Object {
"branch": Array [
true,
],
"message": "Expected value to be of type 'bigint' but found 'boolean'.
Given value: true
Type: 'boolean'
Expected type: 'bigint'",
"path": Array [],
"type": "bigint",
"value": true,
},
]
`);
});
});
});

0 comments on commit 99b9e00

Please sign in to comment.