Skip to content

Commit

Permalink
Merge branch 'main' into feat/shuffle-options
Browse files Browse the repository at this point in the history
  • Loading branch information
fenghan34 committed Feb 26, 2024
2 parents e6e182a + 9abef3d commit 88f2cf0
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/api/expect.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ test('stocks are not the same', () => {
```

:::warning
A _deep equality_ will not be performed for `Error` objects. To test if something was thrown, use [`toThrowError`](#tothrowerror) assertion.
A _deep equality_ will not be performed for `Error` objects. Only the `message` property of an Error is considered for equality. To customize equality to check properties other than `message`, use [`expect.addEqualityTesters`](#expect-addequalitytesters). To test if something was thrown, use [`toThrowError`](#tothrowerror) assertion.
:::

## toStrictEqual
Expand Down
122 changes: 121 additions & 1 deletion test/core/test/expect.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import nodeAssert from 'node:assert'
import type { Tester } from '@vitest/expect'
import { getCurrentTest } from '@vitest/runner'
import { describe, expect, expectTypeOf, test, vi } from 'vitest'
import { assert, describe, expect, expectTypeOf, test, vi } from 'vitest'

describe('expect.soft', () => {
test('types', () => {
Expand Down Expand Up @@ -271,3 +272,122 @@ describe('recursive custom equality tester', () => {
expect(mockFn).toHaveNthReturnedWith(1, [person1, person2])
})
})

describe('Error equality', () => {
class MyError extends Error {
constructor(message: string, public custom: string) {
super(message)
}
}

class YourError extends Error {
constructor(message: string, public custom: string) {
super(message)
}
}

test('basic', () => {
//
// default behavior
//

{
// different custom property
const e1 = new MyError('hi', 'a')
const e2 = new MyError('hi', 'b')
expect(e1).toEqual(e2)
expect(e1).toStrictEqual(e2)
assert.deepEqual(e1, e2)
nodeAssert.notDeepStrictEqual(e1, e2)
}

{
// different message
const e1 = new MyError('hi', 'a')
const e2 = new MyError('hello', 'a')
expect(e1).not.toEqual(e2)
expect(e1).not.toStrictEqual(e2)
assert.notDeepEqual(e1, e2)
nodeAssert.notDeepStrictEqual(e1, e2)
}

{
// different class
const e1 = new MyError('hello', 'a')
const e2 = new YourError('hello', 'a')
expect(e1).toEqual(e2)
expect(e1).not.toStrictEqual(e2) // toStrictEqual checks constructor already
assert.deepEqual(e1, e2)
nodeAssert.notDeepStrictEqual(e1, e2)
}

{
// same
const e1 = new MyError('hi', 'a')
const e2 = new MyError('hi', 'a')
expect(e1).toEqual(e2)
expect(e1).toStrictEqual(e2)
assert.deepEqual(e1, e2)
nodeAssert.deepStrictEqual(e1, e2)
}

//
// stricter behavior with custom equality tester
//

expect.addEqualityTesters(
[
function tester(a, b, customTesters) {
const aOk = a instanceof Error
const bOk = b instanceof Error
if (aOk && bOk) {
// cf. assert.deepStrictEqual https://nodejs.org/api/assert.html#comparison-details_1
// > [[Prototype]] of objects are compared using the === operator.
// > Only enumerable "own" properties are considered.
// > Error names and messages are always compared, even if these are not enumerable properties.
return (
Object.getPrototypeOf(a) === Object.getPrototypeOf(b)
&& a.name === b.name
&& a.message === b.message
&& this.equals({ ...a }, { ...b }, customTesters)
)
}
return aOk !== bOk ? false : undefined
},
],
)

{
// different custom property
const e1 = new MyError('hi', 'a')
const e2 = new MyError('hi', 'b')
expect(e1).not.toEqual(e2) // changed
expect(e1).not.toStrictEqual(e2) // changed
assert.deepEqual(e1, e2) // chai assert is still same
}

{
// different message
const e1 = new MyError('hi', 'a')
const e2 = new MyError('hello', 'a')
expect(e1).not.toEqual(e2)
expect(e1).not.toStrictEqual(e2)
}

{
// different class
const e1 = new MyError('hello', 'a')
const e2 = new YourError('hello', 'a')
expect(e1).not.toEqual(e2) // changed
expect(e1).not.toStrictEqual(e2)
}

{
// same
const e1 = new MyError('hi', 'a')
const e2 = new MyError('hi', 'a')
expect(e1).toEqual(e2)
expect(e1).toStrictEqual(e2)
}
})
})

0 comments on commit 88f2cf0

Please sign in to comment.