Skip to content

Commit

Permalink
Support bigints
Browse files Browse the repository at this point in the history
  • Loading branch information
iliocatallo committed May 9, 2024
1 parent 6bef1cd commit b159ba1
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 9 deletions.
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
</p>

<p align="center">
<a href="https://www.npmjs.com/package/@gucciogucci/contented">
<img alt="NPM" src="https://badge.fury.io/js/@gucciogucci%2Fcontented.svg"/>
</a>
<a href="https://www.npmjs.com/package/@gucciogucci/contented"><img alt="NPM" src="https://badge.fury.io/js/@gucciogucci%2Fcontented.svg"/></a>
<a href="https://github.com/GuccioGucci/contented/actions/workflows/test.yml"><img alt="Test" src="https://github.com/GuccioGucci/contented/actions/workflows/test.yml/badge.svg"></a>
<a href="https://bundlephobia.com/package/@gucciogucci/contented"><img alt="Bundlephobia Minified" src="https://img.shields.io/bundlephobia/min/@gucciogucci/contented.svg"></a>
</p>
Expand All @@ -24,6 +22,7 @@
- [Primitive types](#primitive-types)
- [`string`](#string)
- [`number`](#number)
- [`bigint`](#bigint)
- [`boolean`](#boolean)
- [`null_`](#null\_)
- [Literal types](#literal-types)
Expand Down Expand Up @@ -138,6 +137,20 @@ explain(number, 'hello');
// { value: 'hello', isNot: 'number' }
```

#### `bigint`

A run-time representation of the `bigint` type.

```typescript
import { bigint, isValid, explain } from '@gucciogucci/contented';

isValid(bigint, 1024n);
// true

explain(bigint, 'hello');
// { value: 'hello', isNot: 'bigint' }
```

#### `boolean`

A run-time representation of the `boolean` type.
Expand Down
4 changes: 2 additions & 2 deletions src/Type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ export type Schema = PrimitiveSchema | LiteralSchema | ObjectSchema | OneOfSchem
// ----------------------------------------------------------------------
// Primitive
// ----------------------------------------------------------------------
export type PrimitiveSchema = 'string' | 'boolean' | 'number' | 'null'
export type PrimitiveSchema = 'string' | 'boolean' | 'number' | 'null' | 'bigint'

export function isPrimitiveSchema(schema: Schema): schema is PrimitiveSchema {
return schema === 'string' || schema === 'boolean' || schema === 'number' || schema === 'null'
return schema === 'string' || schema === 'boolean' || schema === 'number' || schema === 'null' || schema === 'bigint'
}

// ----------------------------------------------------------------------
Expand Down
51 changes: 51 additions & 0 deletions src/bigint.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { test } from 'uvu'
import { is, equal } from 'uvu/assert'
import fc, { assert, property } from 'fast-check'
import { bigint } from './bigint'
import { isValid } from './isValid'
import { explain } from './explain'

test(`bigint accepts bigint values`, function () {
assert(
property(fc.bigInt(), (value) => {
const res = isValid(bigint, value)
is(res, true)
})
)
})

test(`bigint rejects all but bigint values`, function () {
assert(
property(notABigint, (value) => {
const res = isValid(bigint, value)
is(res, false)
})
)
})

test(`there is an explanation why a value is not a bigint`, function () {
assert(
property(notABigint, (value) => {
const exp = explain(bigint, value)
equal(exp, {
value,
isNot: 'bigint',
})
})
)
})

test(`there is no need for an explanation if the value is indeed a bigint`, function () {
assert(
property(fc.bigInt(), (value) => {
const exp = explain(bigint, value)
is(exp, undefined)
})
)
})

test.run()

const fcSymbol = fc.string().map((str) => Symbol(str))
const fcNumber = fc.oneof(fc.integer(), fc.float(), fc.double())
const notABigint = fc.oneof(fcNumber, fc.boolean(), fc.constant(null), fc.constant(undefined), fcSymbol)
3 changes: 3 additions & 0 deletions src/bigint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Type } from './Type'

export const bigint: Type<bigint> = { schema: 'bigint' }
2 changes: 1 addition & 1 deletion src/boolean.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ test.run()

const fcSymbol = fc.string().map((str) => Symbol(str))
const fcNumber = fc.oneof(fc.integer(), fc.float(), fc.double())
const notABoolean = fc.oneof(fcNumber, fc.string(), fc.constant(null), fc.constant(undefined), fcSymbol)
const notABoolean = fc.oneof(fcNumber, fc.bigInt(), fc.string(), fc.constant(null), fc.constant(undefined), fcSymbol)
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export { allOf } from './allOf'
export { arrayOf } from './arrayOf'
export { bigint } from './bigint'
export { boolean } from './boolean'
export { explain } from './explain'
export { Infer } from './Type'
Expand Down
10 changes: 10 additions & 0 deletions src/literal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,14 @@ test(`there is an explanation why a value is not of the expected literal type`,
})
})

test('bigint literals are recognized as literals', function () {
const ten = literal(10n)

const res1 = isValid(ten, 10n)
const res2 = isValid(ten, 10)

assert.is(res1, true)
assert.is(res2, false)
})

test.run()
2 changes: 1 addition & 1 deletion src/literal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Type } from './Type'

export function literal<R extends string | number | boolean>(value: Narrow<R>): Type<Narrow<R>> {
export function literal<R extends string | number | boolean | bigint>(value: Narrow<R>): Type<Narrow<R>> {
return { schema: { literal: value } }
}

Expand Down
2 changes: 1 addition & 1 deletion src/null.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ test.run()

const fcSymbol = fc.string().map((str) => Symbol(str))
const fcNumber = fc.oneof(fc.integer(), fc.float(), fc.double())
const notNull = fc.oneof(fcNumber, fc.boolean(), fc.string(), fc.constant(undefined), fcSymbol)
const notNull = fc.oneof(fcNumber, fc.bigInt(), fc.boolean(), fc.string(), fc.constant(undefined), fcSymbol)
2 changes: 1 addition & 1 deletion src/number.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ test.run()

const fcSymbol = fc.string().map((str) => Symbol(str))
const fcNumber = fc.oneof(fc.integer(), fc.float(), fc.double()).filter((x) => !Number.isNaN(x))
const notANumber = fc.oneof(fc.string(), fc.boolean(), fc.constant(null), fc.constant(undefined), fcSymbol)
const notANumber = fc.oneof(fc.string(), fc.bigInt(), fc.boolean(), fc.constant(null), fc.constant(undefined), fcSymbol)

0 comments on commit b159ba1

Please sign in to comment.