Skip to content

Commit

Permalink
feat: support BigInt for jest assertions (#742)
Browse files Browse the repository at this point in the history
  • Loading branch information
togami2864 committed Feb 13, 2022
1 parent af9ceab commit d1df0e0
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 19 deletions.
12 changes: 6 additions & 6 deletions docs/api/index.md
Expand Up @@ -460,7 +460,7 @@ TODO

### toBeGreaterThan

- **Type:** `(n: number) => Awaitable<void>`
- **Type:** `(n: number | bigint) => Awaitable<void>`

`toBeGreaterThan` asserts if actual value is greater than received one. Equal values will fail the test.

Expand All @@ -475,7 +475,7 @@ TODO

### toBeGreaterThanOrEqual

- **Type:** `(n: number) => Awaitable<void>`
- **Type:** `(n: number | bigint) => Awaitable<void>`

`toBeGreaterThanOrEqual` asserts if actual value is greater than received one or equal to it.

Expand All @@ -490,7 +490,7 @@ TODO

### toBeLessThan

- **Type:** `(n: number) => Awaitable<void>`
- **Type:** `(n: number | bigint) => Awaitable<void>`

`toBeLessThan` asserts if actual value is less than received one. Equal values will fail the test.

Expand All @@ -505,7 +505,7 @@ TODO

### toBeLessThanOrEqual

- **Type:** `(n: number) => Awaitable<void>`
- **Type:** `(n: number | bigint) => Awaitable<void>`

`toBeLessThanOrEqual` asserts if actual value is less than received one or equal to it.

Expand Down Expand Up @@ -596,7 +596,7 @@ TODO

- **Type:** `(received: any) => Awaitable<void>`

`toContainEqual` asserts if an item with a specific structure and values is contained in an array.
`toContainEqual` asserts if an item with a specific structure and values is contained in an array.
It works like [`toEqual`](#toequal) inside for each element.

```ts
Expand Down Expand Up @@ -761,7 +761,7 @@ TODO

```ts
import { test, expect } from 'vitest'

function getFruitStock(type) {
if (type === 'pineapples') {
throw new DiabetesError('Pineapples is not good for people with diabetes')
Expand Down
8 changes: 4 additions & 4 deletions packages/vitest/src/index.ts
Expand Up @@ -84,10 +84,10 @@ declare global {
toContainEqual<E>(item: E): void
toBeTruthy(): void
toBeFalsy(): void
toBeGreaterThan(num: number): void
toBeGreaterThanOrEqual(num: number): void
toBeLessThan(num: number): void
toBeLessThanOrEqual(num: number): void
toBeGreaterThan(num: number | bigint): void
toBeGreaterThanOrEqual(num: number | bigint): void
toBeLessThan(num: number | bigint): void
toBeLessThanOrEqual(num: number | bigint): void
toBeNaN(): void
toBeUndefined(): void
toBeNull(): void
Expand Down
53 changes: 45 additions & 8 deletions packages/vitest/src/integrations/chai/jest-expect.ts
Expand Up @@ -2,6 +2,7 @@ import type { EnhancedSpy } from '../jest-mock'
import { isMockFunction } from '../jest-mock'
import { addSerializer } from '../snapshot/port/plugins'
import type { Constructable } from '../../types'
import { assertTypes } from '../../utils'
import type { ChaiPlugin, MatcherState } from './types'
import { arrayBufferEquality, iterableEquality, equals as jestEquals, sparseArrayEquality, subsetEquality, typeEquality } from './jest-utils'
import type { AsymmetricMatcher } from './jest-asymmetric-matchers'
Expand Down Expand Up @@ -160,17 +161,53 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
obj,
)
})
def('toBeGreaterThan', function(expected: number) {
return this.to.greaterThan(expected)
def('toBeGreaterThan', function(expected: number | bigint) {
const actual = this._obj
assertTypes(actual, 'actual', ['number', 'bigint'])
assertTypes(expected, 'expected', ['number', 'bigint'])
return this.assert(
actual > expected,
`expected ${actual} to be above ${expected}`,
`expected ${actual} not to be above ${expected}`,
actual,
expected,
)
})
def('toBeGreaterThanOrEqual', function(expected: number) {
return this.to.greaterThanOrEqual(expected)
def('toBeGreaterThanOrEqual', function(expected: number | bigint) {
const actual = this._obj
assertTypes(actual, 'actual', ['number', 'bigint'])
assertTypes(expected, 'expected', ['number', 'bigint'])
return this.assert(
actual >= expected,
`expected ${actual} to be above ${expected}`,
`expected ${actual} not to be above ${expected}`,
actual,
expected,
)
})
def('toBeLessThan', function(expected: number) {
return this.to.lessThan(expected)
def('toBeLessThan', function(expected: number | bigint) {
const actual = this._obj
assertTypes(actual, 'actual', ['number', 'bigint'])
assertTypes(expected, 'expected', ['number', 'bigint'])
return this.assert(
actual < expected,
`expected ${actual} to be above ${expected}`,
`expected ${actual} not to be above ${expected}`,
actual,
expected,
)
})
def('toBeLessThanOrEqual', function(expected: number) {
return this.to.lessThanOrEqual(expected)
def('toBeLessThanOrEqual', function(expected: number | bigint) {
const actual = this._obj
assertTypes(actual, 'actual', ['number', 'bigint'])
assertTypes(expected, 'expected', ['number', 'bigint'])
return this.assert(
actual <= expected,
`expected ${actual} to be above ${expected}`,
`expected ${actual} not to be above ${expected}`,
actual,
expected,
)
})
def('toBeNaN', function() {
return this.be.NaN
Expand Down
6 changes: 6 additions & 0 deletions packages/vitest/src/utils/base.ts
Expand Up @@ -99,3 +99,9 @@ export function deepMerge<T extends object = object, S extends object = T>(targe
function isMergableObject(item: any): item is Object {
return isPlainObject(item) && !Array.isArray(item)
}

export function assertTypes(value: unknown, name: string, types: string[]): void {
const receivedType = typeof value
const pass = types.includes(receivedType)
if (!pass) throw new TypeError(`${name} value must be ${types.join(' or ')}, received "${receivedType}"`)
}
19 changes: 19 additions & 0 deletions test/core/test/jest-expect.test.ts
Expand Up @@ -22,11 +22,30 @@ describe('jest-expect', () => {
expect([{ text: 'Hello' }]).toContainEqual({ text: 'Hello' })
expect([{ text: 'Bye' }]).not.toContainEqual({ text: 'Hello' })
expect(1).toBeGreaterThan(0)

expect(BigInt(1)).toBeGreaterThan(BigInt(0))
expect(1).toBeGreaterThan(BigInt(0))
expect(BigInt(1)).toBeGreaterThan(0)

expect(1).toBeGreaterThanOrEqual(1)
expect(1).toBeGreaterThanOrEqual(0)

expect(BigInt(1)).toBeGreaterThanOrEqual(BigInt(1))
expect(BigInt(1)).toBeGreaterThanOrEqual(BigInt(0))
expect(BigInt(1)).toBeGreaterThanOrEqual(1)
expect(1).toBeGreaterThanOrEqual(BigInt(1))

expect(0).toBeLessThan(1)
expect(BigInt(0)).toBeLessThan(BigInt(1))
expect(BigInt(0)).toBeLessThan(1)

expect(1).toBeLessThanOrEqual(1)
expect(0).toBeLessThanOrEqual(1)
expect(BigInt(1)).toBeLessThanOrEqual(BigInt(1))
expect(BigInt(0)).toBeLessThanOrEqual(BigInt(1))
expect(BigInt(1)).toBeLessThanOrEqual(1)
expect(1).toBeLessThanOrEqual(BigInt(1))

expect(() => {
throw new Error('this is the error message')
}).toThrow('this is the error message')
Expand Down
20 changes: 19 additions & 1 deletion test/core/test/utils.spec.ts
@@ -1,7 +1,25 @@
import { describe, expect, test } from 'vitest'
import { deepMerge } from '../../../packages/vitest/src/utils'
import { assertTypes, deepMerge } from '../../../packages/vitest/src/utils'
import { deepMergeSnapshot } from '../../../packages/vitest/src/integrations/snapshot/port/utils'

describe('assertTypes', () => {
test('the type of value should be number', () => {
const value = 5
const value_string = '5'
assertTypes(value, 'value', ['number'])
expect(() => assertTypes(value_string, 'value_string', ['number'])).toThrow()
})

test('the type of value should be number or BigInt', () => {
const value_number = 5
const value_bigint = BigInt(5)
const value_string = '5'
assertTypes(value_number, 'value_number', ['number', 'bigint'])
assertTypes(value_bigint, 'value_bigint', ['number', 'bigint'])
expect(() => assertTypes(value_string, 'value_string', ['number', 'bigint'])).toThrow()
})
})

describe('deepMerge', () => {
test('non plain objects retain their prototype, arrays are not merging, plain objects are merging', () => {
class Test {
Expand Down

0 comments on commit d1df0e0

Please sign in to comment.