Skip to content

Commit 87c9203

Browse files
committed
03/03: fix measurement instanceof check
1 parent 075e872 commit 87c9203

File tree

3 files changed

+19
-74
lines changed

3 files changed

+19
-74
lines changed

exercises/03.assertions/03.problem.custom-quality-testers/vitest.setup.ts

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,10 @@ import { Measurement } from './src/measurement'
88
// called `measurementTester`. It accepts two parameters: `received` and `expected`.
99
// 💰 function measurementTester(received, expected) {}
1010

11-
// 🐨 First, check that the `expected` argument is an instance of the `Measurement` class.
12-
// This makes sure that you provide the equality tester with the correct input.
13-
// If `expected` is not an instance of `Measurement`, print the argument to the console
14-
// and throw a developer-friendly error.
15-
// 💰 a instanceof Measurement
16-
// 💰 console.log(expected
17-
// 💰 throw new Error('Failed to compare Measurement: expected is not a Measurement')
11+
// 🐨 Then, check that both the `received` and `expected` values are instances
12+
// of the `Measurement` class.
13+
// 💰 if (one instanceof Measurement && another instanceof Measurement) {}
1814

19-
// 🐨 Next, add a similar instance check for the `received` argument.
20-
// In this case, if `received` is not an instance of `Measurement`, simply
21-
// return false. This will fail the equality comparison, which is what you want.
22-
23-
// 🐨 Finally, at this point, both `expected` and `received` are measurements,
24-
// which means you can use the `.equals()` method of the `Measurement` class
25-
// to compare two measurements. Return the result of that comparison from the
26-
// equality tester function.
27-
// 💰 expected.equals(received)
15+
// 🐨 Next, if both values are measurements, compare them using the `.equals()`
16+
// method of the `Measurement` class. Return the result of that comparison.
17+
// 💰 return expected.equals(received)

exercises/03.assertions/03.solution.custom-equality-testers/README.mdx

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -37,29 +37,23 @@ expect(new Measurement(1, 'in')).toEqual(new Measurement(2.54, 'cm'))
3737

3838
Vitest will automatically provide these two values to your equality tester function and expect it to _return a boolean_ indicating whether these two values are equal.
3939

40-
But before I get to the comparison part, it's good to have some input validation in place.
41-
A check that I am actually providing a `Measurement` instance as the `expected` value (i.e. using the equality correctly).
40+
Measurement comparison only becomes relevant if both the `received` and `expected` values are instances of the `Measurement` class. Let's make sure to check that:
4241

43-
```ts file=vitest.setup.ts add=5-10
42+
```ts file=vitest.setup.ts add=5-7
4443
import { Measurement } from './src/measurement'
4544

4645
expect.addEqualityTesters([
4746
function measurementTester(received, expected) {
48-
if (!(expected instanceof Measurement)) {
49-
console.log(expected)
50-
throw new Error(
51-
'Failed to compare Measurement: expected is not a Measurement',
52-
)
47+
if (received instanceof Measurement && expected instanceof Measurement) {
48+
// ...
5349
}
5450
},
5551
])
5652
```
5753

58-
This check exists solely for myself to guard me against mechanical mistakes and typos. I print the invalid `expected` value to the console and throw a message to fail the test.
59-
6054
Now, to the equality!
6155

62-
If you take a closer look at the `Measurement` class, it already implements an `.equal()` method to help with the comparison.
56+
If you take a closer look at the implementation of the `Measurement` class, it already has an `.equals()` method to help with the comparison.
6357

6458
```ts filename=src/measurement.ts nonumber nocopy highlight=3
6559
export class Measurement {
@@ -68,53 +62,23 @@ export class Measurement {
6862
}
6963
```
7064

71-
For us to use that method, both the `expected` and `received` values have to be an instance of that class. I've already checked that with the `expected` value, and now what remains is to add a similar check for the `received` one:
65+
So the actual value comparison becomes a matter of invoking that `.equals()` method on any of the measurements provided by the tester:
7266

73-
```ts filename=vitest.setup.ts add=12-14
67+
```ts filename=vitest.setup.ts add=6
7468
import { Measurement } from './src/measurement'
7569

7670
expect.addEqualityTesters([
7771
function measurementTester(received, expected) {
78-
if (!(expected instanceof Measurement)) {
79-
console.log(expected)
80-
throw new Error(
81-
'Failed to compare Measurement: expected is not a Measurement',
82-
)
83-
}
84-
85-
if (!(received instanceof Measurement)) {
86-
return false
72+
if (received instanceof Measurement && expected instanceof Measurement) {
73+
return expected.equals(received)
8774
}
8875
},
8976
])
9077
```
9178

92-
Notice that in this case, if `received` isn't an instance of `Measurement`, I return `false` from the equality tester instead. That is because when this condition met, _the tested value is incorrect_, not my usage of this tester. As a result, I want the equality to fail, which I can do by returning `false` from my tester function at any point.
93-
94-
And, finally, let's use the `.equals()` method to compare the two measurements:
95-
96-
```ts filename=vitest.setup.ts add=16
97-
import { Measurement } from './src/measurement'
98-
99-
expect.addEqualityTesters([
100-
function measurementTester(received, expected) {
101-
if (!(expected instanceof Measurement)) {
102-
console.log(expected)
103-
throw new Error(
104-
'Failed to compare Measurement: expected is not a Measurement',
105-
)
106-
}
107-
108-
if (!(received instanceof Measurement)) {
109-
return false
110-
}
111-
112-
return expected.equals(received)
113-
},
114-
])
115-
```
79+
> The values you will be comparing might not have the `.equals()` method (or not be classed at all!). Feel free to implement the comparison logic directly in your custom equality tester if that's the case.
11680
117-
Once this is done, you don't have to do anything extra for Vitest to respect your custom equality tester. In fact, if you run tests now, you will see them passing, which means Vitest can compare measurements correctly!
81+
Once this is done, I don't have to do anything extra for Vitest to respect my custom equality tester. In fact, if I run tests now, I will see them passing, which means Vitest can compare measurements correctly!
11882

11983
## Equality testers vs Matchers
12084

exercises/03.assertions/03.solution.custom-equality-testers/vitest.setup.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,8 @@ import { Measurement } from './src/measurement'
22

33
expect.addEqualityTesters([
44
function measurementTester(received, expected) {
5-
if (!(expected instanceof Measurement)) {
6-
console.log(expected)
7-
throw new Error(
8-
'Failed to compare Measurement: expected is not a Measurement',
9-
)
5+
if (received instanceof Measurement && expected instanceof Measurement) {
6+
return expected.equals(received)
107
}
11-
12-
if (!(received instanceof Measurement)) {
13-
return false
14-
}
15-
16-
return expected.equals(received)
178
},
189
])

0 commit comments

Comments
 (0)