-
Notifications
You must be signed in to change notification settings - Fork 11
/
customMatchers.ts
110 lines (103 loc) · 2.74 KB
/
customMatchers.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* eslint-disable @typescript-eslint/no-namespace */
/* eslint-disable @typescript-eslint/interface-name-prefix */
import Complex from '../src/Complex'
import Vector from '../src/Vector'
import Operator from '../src/Operator'
export {}
declare global {
namespace jest {
interface Matchers<R> {
myMatcher: (received: string) => CustomMatcherResult
vectorCloseTo: (received: Vector, eps?: number) => CustomMatcherResult
vectorCloseToNumbers: (received: Complex[], eps?: number) => CustomMatcherResult
operatorCloseToNumbers: (received: Complex[][], eps?: number) => CustomMatcherResult
}
}
}
/**
* An example, from https://stackoverflow.com/questions/43667085/extending-third-party-module-that-is-globally-exposed.
* @param this
* @param received
* @param expected
*/
function myMatcher<T>(this: jest.MatcherUtils, received: string, expected: string): jest.CustomMatcherResult {
const pass = received === expected
return {
pass,
message: (): string => `Expected ${received}\nReceived: ${expected}`,
}
}
/**
*
* @param this
* @param received
* @param expected
*/
function vectorCloseTo<T>(
this: jest.MatcherUtils,
received: Vector,
expected: Vector,
eps = 1e-6,
): jest.CustomMatcherResult {
const pass = received.sub(expected).norm < eps
return {
pass,
message: (): string => `Expected ${received.toString()}\nReceived: ${expected.toString()}`,
}
}
/**
*
* @param this
* @param received
* @param expected
*/
function vectorCloseToNumbers<T>(
this: jest.MatcherUtils,
received: Vector,
expected: Complex[],
eps = 1e-6,
): jest.CustomMatcherResult {
const receivedDense = received.toDense()
let pass: boolean
if (receivedDense.length !== expected.length) {
pass = false
} else {
pass = receivedDense.map((c, i) => c.isCloseTo(expected[i], eps)).reduce((a, b) => a && b, true)
}
return {
pass,
message: (): string => `Expected ${receivedDense.toString()}\nReceived: ${expected.toString()}`,
}
}
/**
*
* @param this
* @param received
* @param expected
*/
function operatorCloseToNumbers<T>(
this: jest.MatcherUtils,
received: Operator,
expected: Complex[][],
eps = 1e-6,
): jest.CustomMatcherResult {
const receivedDense = received.toDense()
let pass: boolean
if (receivedDense.length !== expected.length || receivedDense[0].length !== expected[0].length) {
pass = false
} else {
pass = receivedDense
.flatMap((row, i) => row.map((c, j) => c.isCloseTo(expected[i][j], eps)))
.reduce((a, b) => a && b, true)
}
return {
pass,
message: (): string => `Expected ${receivedDense.toString()}\nReceived: ${expected.toString()}`,
}
}
expect.extend({
myMatcher,
vectorCloseTo,
vectorCloseToNumbers,
operatorCloseToNumbers,
})