- So far, we've seen how to define
a custom jest matcher that receives a single parameter
which specifies the value to test.
It's also possible to define a jest matcher
that receives several parameters.
The first parameter is always the value
that you're trying to test, and then additional parameters
help you specify constraints such as minimum value
and the maximum value within which the number should be.
So what we'll do now we'll see how to define
a custom matcher that receives additional parameters.
Here's our custom matcher,
it's in the custom jest matchers folder.
And I defined a file called setuptests.js,
which contains my custom matchers.
Okay. So let's have a look at that on the file system.
If you go into jstdd, lesson two, custom jest matchers.
And if you open that folder in the code editor,
this is what it looks like.
As you can see, we have a setuptest.js,
and in here I define two custom jest matchers.
Remember how it works when you define custom matcher.
You have to call the expect extend function
and then you have to pass it an object.
And then in that object,
you can define your custom matchers.
So I defined, well, first of all, the example from before,
a simple jest matcher that just received the value to test
to be between zero and a hundred.
And now I've got a more general jest matcher
where the constraints, the minimum and maximum
aren't hard coded, but they're parameterized.
Okay. So you can specify the minimum
and the maximum value within which that number should lie.
So here's the code in my PowerPoint,
highlighting the relevant bits.
As you can see the number, you always receive
at least one parameter in a custom matcher
the value that you are testing,
plus any other parameters
which help you formulate your test condition.
So similar to the example from earlier, first of all,
let's make sure that the number
or the parameter really is a number.
And if it isn't, we fail immediately, it's unconditional,
you know, it has to be a number that we're checking.
Then if it is a number, we establish, if it's in range.
If it is, then we return true.
If the test condition from the user
was hoping that it wasn't in range,
then this would then fail, okay.
Because they were hoping the number wasn't in range,
but in fact, it is in the range of minimum or maximum.
Alternatively, if the number is too small or too large,
we come down here, we return false,
the test condition wasn't satisfied.
And if the user was hoping it was satisfied,
they'll get this error message.
We expected the number to be in this range, and it wasn't.
Oh, do you like my mathematical notation here?
In the print message, I use square brackets to indicate
an inclusive min, lower bound and easy for me to say.
And I use a long bracket here
to express an exclusive upper bound.
That's a mathematical way of saying inclusive lower bound,
exclusive upper bound.
So anyway that's my custom matcher defined in setuptests.js.
And if you remember, there isn't any automatic naming
convention for these files.
We happen to define our custom matchers in this file
but jest doesn't look there instinctively.
You have to tell it where to look
to find your custom matchers.
So as before, we have to define the jest config JS file
and in there, we have to basically tell it what file
or files contain our custom matchers.
Okay? So in my project, I've also defined that file as well.
And you can see it here.
So jest will know where to look to find my custom matchers.
So the last thing to do is to actually use
our custom matchers in a test.
So here's my test suite using to be in range
to be in range, being my custom matcher.
So in this file, in this test suite,
I've defined various functions that check
or that use that custom matcher.
So let's take a look at those tests.
So an example test JS, and in the last suite,
the first three suites I check in the exam mark
custom matcher.
We've seen that already,
now we'll focus on the new one.
The parameterized custom matcher.
Okay. So as you can see, when you call the function,
the function itself receives three parameters.
The first parameter is always the value
that you're trying to check.
And then the other two parameters
are the additional parameters.
So jest will actually call that function,
it'll pass 10 as the first parameter
and that as the minimum, and that as the maximum, okay.
So if my custom matcher is correct, then it should
successfully indicate that 10 is within that range.
Inclusive, lower bound,
up 19 is also within that range,
hopefully my custom matcher will say yes,
nine should not be in the range because it's too small.
And 20 shouldn't be in the range either
because it's too large.
Because if my custom matcher is correct,
it's exclusive on the upper bound.
So my custom matcher should indicate
that 20 isn't in the range.
Okay. So all of these tests should pass.
Likewise, these tests, each of these tests should fail.
Okay. So if the user passed in a number,
hoping it was within range,
my custom matcher should realize,
well it isn't, and it should raise an error
or it should gimme back an error message.
I should say, it should fail the test.
My custom matcher should fail because the number
the user was hoping to be in range isn't
and my custom matcher should tell me that it isn't in range.
So it's the same thing for these.
If the user was hoping that this test was in range,
my custom matcher should fail.
In other words, it should return false, I mean.
Likewise, if the user was hoping a number
wasn't in range, well, that number is in range
and my custom matcher should say,
no, no that number actually is in range
and you were hoping it wasn't.
If you get the pulliam logic.
When you have a test with multiple assertions,
if one of those assertion fails,
it doesn't get any further in the test.
So if this first statement failed,
it wouldn't bother executing the other tests.
So what I could do is I could run this test
four times, kind of uncomment
in each one of these one at a time.
And for the sake of the demo,
I just comment out the other three.
Okay. So when it runs this test,
that expectation should fail with an error message.
So we'll run these tests.
To run the tests, usual arrangement, you run yarn or npm
and you specify a partial string
which selects the suite that we're trying to execute.
Okay. So let's do that now and see what happens.
So npm run test parameters at minus t
and good to be specify in using to be in range.
Okay. So pluck out my, using to be in range suite,
it'll run my two test functions.
The first test function will pass
and the second test function should fail
because the user inadvertently, there we go.
So using to be in range,
the first test passed and the second test failed.
There we go.
Okay, so that's the failure there.
And the error message that we get,
expected nine to be in range 10 20.
Well, that's what the user hoped for,
they passed in that number,
hoping it would be in that range.
My matcher successfully realized that it wasn't actually
and it gave me an error message.
I'm gonna try that one more time.
This time with one of the kind of opposite condition tests
if you understand.
So if I come back in here, I'll comment that one out
and I'll comment, uncomment this one.
I want to see what the error message is
if the user is expecting something
not to be in range when in fact it is.
I want to see that the error message is appropriate.
In that case, you were expecting it not to be in range
and it actually is in range.
Let's see what happens when I run that test.
So I'll run that test again.
As before the first test will pass
and the second test will fail
but I'm looking for a different error message now.
So let's see what happens.
Okay. So the first test function passed,
that's good.
And the second test function failed,
which is also good in our condition.
We were hoping it would fail, weren't we?
And the error message, according to what the user specified,
they were hoping that that number would be in range.
Okay. But the number they passed in...
Oh, sorry,
they were hoping that the number wouldn't be in range.
In fact, it is.
So what's the error message that we get back.
You were expecting 10 not to be in the range.
Weren't you?
You were expecting 10 not to be in range.
In fact it was, therefore the test fails.
So right then custom matchers is relatively straightforward.
The only tricky thing is to understand the, you know
are you testing whether there's a true condition
or false condition
and then return in a suitable error message
if it's the opposite to what you expect.