Skip to content
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

feat: support BigInt for jest assertions #742

Merged
merged 8 commits into from Feb 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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