1 00:00:06,510 --> 00:00:08,970 - So far in the examples we've been looking at, 2 00:00:08,970 --> 00:00:11,610 we've been using the standard Jest matchers, 3 00:00:11,610 --> 00:00:15,570 like toBe and toThrow, greater than and less than, 4 00:00:15,570 --> 00:00:17,130 and that's fine. 5 00:00:17,130 --> 00:00:18,720 But it's also possible to define 6 00:00:18,720 --> 00:00:21,060 higher level custom matchers, 7 00:00:21,060 --> 00:00:24,570 which give you a more semantic test. 8 00:00:24,570 --> 00:00:27,480 You can encapsulate complicated business logic 9 00:00:27,480 --> 00:00:29,160 in a custom matcher, 10 00:00:29,160 --> 00:00:32,010 and then reuse that custom marcher many times. 11 00:00:32,010 --> 00:00:34,770 It gives you like a higher level of vocabulary 12 00:00:34,770 --> 00:00:36,330 for doing your tests. 13 00:00:36,330 --> 00:00:38,550 So you could write a custom matcher 14 00:00:38,550 --> 00:00:41,280 to be valid UK post code, 15 00:00:41,280 --> 00:00:44,130 or to be valid international dialing code. 16 00:00:44,130 --> 00:00:46,080 You know, semantically richer 17 00:00:46,080 --> 00:00:48,510 makes it easier to write high level tests. 18 00:00:48,510 --> 00:00:50,460 So in this section, 19 00:00:50,460 --> 00:00:53,430 we'll see how to write a simple Jest marcher, 20 00:00:53,430 --> 00:00:56,100 that just takes a single value, single parameter 21 00:00:56,100 --> 00:00:58,320 and checks that it's okay. 22 00:00:58,320 --> 00:01:01,830 So to define a custom test matcher for Jest, 23 00:01:01,830 --> 00:01:05,220 you, first of all you have to call the expect function, 24 00:01:05,220 --> 00:01:08,160 the expect extend function. 25 00:01:08,160 --> 00:01:11,160 And into that function, you pass an object. 26 00:01:11,160 --> 00:01:15,000 Another object contains your custom matchers. 27 00:01:15,000 --> 00:01:18,330 Each matcher will receive at least one value, 28 00:01:18,330 --> 00:01:19,893 the value that you're testing, 29 00:01:21,060 --> 00:01:22,740 possibly other parameters as well. 30 00:01:22,740 --> 00:01:25,710 But initially we'll just pass in one parameter 31 00:01:25,710 --> 00:01:27,420 into our first example. 32 00:01:27,420 --> 00:01:30,210 And what you have to return is an object. 33 00:01:30,210 --> 00:01:31,320 So it's quite strict. 34 00:01:31,320 --> 00:01:34,260 You return an object that has a pass property 35 00:01:34,260 --> 00:01:36,030 which is either true or false, 36 00:01:36,030 --> 00:01:39,060 and then a message which will be displayed by Jest, 37 00:01:39,060 --> 00:01:41,220 if you know, if it fails. 38 00:01:41,220 --> 00:01:43,770 So that's the error message that the user will see 39 00:01:43,770 --> 00:01:45,303 if the test fails. 40 00:01:46,200 --> 00:01:47,033 Okay, right. 41 00:01:47,033 --> 00:01:49,320 So the examples, I've got some examples. 42 00:01:49,320 --> 00:01:52,623 If you go into the custom Jest matchers folder, 43 00:01:53,460 --> 00:01:54,941 the examples in there. 44 00:01:54,941 --> 00:01:59,610 Okay, so in JsTdd lesson two, custom Jest matchers. 45 00:01:59,610 --> 00:02:03,330 If you open that folder in the text editor, 46 00:02:03,330 --> 00:02:04,710 it looks like this. 47 00:02:04,710 --> 00:02:08,550 And what I've done is I've put my custom matcher 48 00:02:08,550 --> 00:02:10,970 into a file called setupTests.js. 49 00:02:10,970 --> 00:02:13,620 It actually doesn't matter what you call this file name. 50 00:02:13,620 --> 00:02:16,483 So I've just called it that, setupTests.js. 51 00:02:18,450 --> 00:02:19,770 And as you can see here, 52 00:02:19,770 --> 00:02:22,530 I've called the expect extend function. 53 00:02:22,530 --> 00:02:24,600 You give it an object. 54 00:02:24,600 --> 00:02:28,680 And in that object, you define your custom matchers. 55 00:02:28,680 --> 00:02:31,830 So in this example, I've got two custom matchers. 56 00:02:31,830 --> 00:02:35,250 One that checks if a number is a valid exam mark, 57 00:02:35,250 --> 00:02:36,660 you know, zero to a hundred. 58 00:02:36,660 --> 00:02:38,700 We'll have a look at that one in this section. 59 00:02:38,700 --> 00:02:40,470 And then in the next section, 60 00:02:40,470 --> 00:02:43,080 we'll have a look at a more complicated custom matcher 61 00:02:43,080 --> 00:02:45,060 that takes multiple parameters. 62 00:02:45,060 --> 00:02:47,250 Okay, where it's a bit more complicated. 63 00:02:47,250 --> 00:02:49,410 The test is a bit more involved. 64 00:02:49,410 --> 00:02:51,390 So first of all, our simple Jest matcher, 65 00:02:51,390 --> 00:02:53,940 it'll take a parameter, hopefully a number. 66 00:02:53,940 --> 00:02:56,640 And it'll tell us if it's a valid exam mark. 67 00:02:56,640 --> 00:02:58,353 Okay, so here's the code. 68 00:02:59,250 --> 00:03:01,500 It, first of all, checks the incoming parameter. 69 00:03:01,500 --> 00:03:02,790 It's gotta be a number. 70 00:03:02,790 --> 00:03:06,720 If it isn't a number, fail immediately, throw an error. 71 00:03:06,720 --> 00:03:09,360 We were expecting the value to be a number. 72 00:03:09,360 --> 00:03:11,621 Okay, assuming it is a number. 73 00:03:11,621 --> 00:03:14,370 If the number is between zero and a hundred 74 00:03:14,370 --> 00:03:18,390 then we return true, it is a valid exam mark. 75 00:03:18,390 --> 00:03:22,560 Now the message is kind of the opposite condition. 76 00:03:22,560 --> 00:03:27,060 We've just established that the number is valid, 77 00:03:27,060 --> 00:03:28,740 a valid exam mark. 78 00:03:28,740 --> 00:03:33,203 But if the user was checking to see if it wasn't valid, 79 00:03:34,080 --> 00:03:36,600 then it fails that test, okay? 80 00:03:36,600 --> 00:03:39,930 So we've just, we know that the number's valid 81 00:03:39,930 --> 00:03:42,660 but if the user was testing for it not to be valid, 82 00:03:42,660 --> 00:03:45,420 then that's the error message to display, 83 00:03:45,420 --> 00:03:49,110 the user was expecting the number not to be a valid mark, 84 00:03:49,110 --> 00:03:50,280 but it actually is. 85 00:03:50,280 --> 00:03:52,440 So this is kind of the opposite condition 86 00:03:52,440 --> 00:03:53,760 of what we just established. 87 00:03:53,760 --> 00:03:55,560 That's what we know it is 88 00:03:55,560 --> 00:03:57,870 but that's what the user was trying to test for. 89 00:03:57,870 --> 00:04:00,070 And that's the error message they would get. 90 00:04:01,080 --> 00:04:04,890 However, if the number isn't between zero and a hundred, 91 00:04:04,890 --> 00:04:06,600 then we return false, 92 00:04:06,600 --> 00:04:09,210 an object that returns the false property. 93 00:04:09,210 --> 00:04:12,060 And so it's not a valid mark. 94 00:04:12,060 --> 00:04:13,920 If the user was hoping it was, 95 00:04:13,920 --> 00:04:16,200 then this is the error message they'll get back. 96 00:04:16,200 --> 00:04:18,480 We were expecting it to be a valid number 97 00:04:18,480 --> 00:04:20,490 and it isn't, is it? 98 00:04:20,490 --> 00:04:25,410 So that's our custom tests in setupTest.js. 99 00:04:25,410 --> 00:04:28,950 Like I said, there's nothing special about this file name. 100 00:04:28,950 --> 00:04:32,220 You have to tell Jest to look in this file 101 00:04:32,220 --> 00:04:34,770 to find the custom matcher, okay? 102 00:04:34,770 --> 00:04:35,760 So there we go. 103 00:04:35,760 --> 00:04:37,383 Here's my custom file. 104 00:04:38,400 --> 00:04:42,090 It contains my custom matchers or however many I've got. 105 00:04:42,090 --> 00:04:45,300 In order for Jest to know to look in this file, 106 00:04:45,300 --> 00:04:47,190 you have a configuration file. 107 00:04:47,190 --> 00:04:51,063 A special config file for Jest, Jest.config.Jest. 108 00:04:51,063 --> 00:04:53,250 This file name does matter. 109 00:04:53,250 --> 00:04:56,010 And in there you just basically export 110 00:04:56,010 --> 00:04:57,630 the names of the files 111 00:04:57,630 --> 00:04:59,640 where you use to find your custom matchers. 112 00:04:59,640 --> 00:05:02,670 So you say exports, you give it, 113 00:05:02,670 --> 00:05:06,480 you set the setupFilesAfterEnv property. 114 00:05:06,480 --> 00:05:11,480 And then you give it an array of file names, possibly many, 115 00:05:11,610 --> 00:05:14,310 where you've defined your custom matchers, okay? 116 00:05:14,310 --> 00:05:17,010 And that ensures that when Jest get started, 117 00:05:17,010 --> 00:05:21,330 it'll load these custom matchers into its system. 118 00:05:21,330 --> 00:05:25,410 So you can then use those custom matchers in your tests. 119 00:05:25,410 --> 00:05:27,330 Okay, so that's the next thing for us to do 120 00:05:27,330 --> 00:05:28,980 is to actually write some tests 121 00:05:28,980 --> 00:05:32,850 that use this custom matcher. 122 00:05:32,850 --> 00:05:37,080 So to use that Jest matcher, you'd say this, 123 00:05:37,080 --> 00:05:41,880 you'd say, I'm expecting some number to be an exam mark. 124 00:05:41,880 --> 00:05:44,160 And, so what Jest will do, 125 00:05:44,160 --> 00:05:46,260 is it'll take that parameter or that value, 126 00:05:46,260 --> 00:05:48,420 and it'll automatically pass that parameter 127 00:05:48,420 --> 00:05:50,700 into your custom matcher, okay? 128 00:05:50,700 --> 00:05:53,970 You don't pass it in yourself, you just write it like this. 129 00:05:53,970 --> 00:05:56,040 Jest will automatically take that parameter 130 00:05:56,040 --> 00:05:57,900 and pass it into your matcher. 131 00:05:57,900 --> 00:06:01,380 And then your matcher returns, you know, true or false. 132 00:06:01,380 --> 00:06:04,650 You can check if it isn't a valid exam mark like this. 133 00:06:04,650 --> 00:06:08,700 So again, Jest will pass in value into your matcher. 134 00:06:08,700 --> 00:06:09,690 And it knows this time, 135 00:06:09,690 --> 00:06:12,840 you're hoping that it isn't a valid exam mark, okay? 136 00:06:12,840 --> 00:06:14,430 So it kind of knows whether you're looking 137 00:06:14,430 --> 00:06:16,770 for a positive outcome or negative outcome 138 00:06:16,770 --> 00:06:19,263 based on whether it sees the not, keyword here. 139 00:06:20,280 --> 00:06:24,990 Right, so what I've done is I've defined three suites 140 00:06:24,990 --> 00:06:28,410 that show how to use my matcher 141 00:06:28,410 --> 00:06:30,930 when a good value is expected. 142 00:06:30,930 --> 00:06:34,320 How to use the matcher when a bad value is expected, 143 00:06:34,320 --> 00:06:35,790 and how to use the matcher 144 00:06:35,790 --> 00:06:40,790 if the user accidentally passes in a non-numeric exam mark, 145 00:06:40,920 --> 00:06:42,540 like widdle. 146 00:06:42,540 --> 00:06:44,700 So let's take a look at that. 147 00:06:44,700 --> 00:06:46,140 And what we'll do, is we'll, 148 00:06:46,140 --> 00:06:50,940 well we could run all the tests at once, like this. 149 00:06:50,940 --> 00:06:55,940 npm run test -t "Using toBeExamMark". 150 00:06:56,209 --> 00:06:59,370 I think what I'll do is I'll run the tests a few times 151 00:06:59,370 --> 00:07:00,840 as we go through the code 152 00:07:00,840 --> 00:07:04,890 just to show the progressive experience. 153 00:07:04,890 --> 00:07:09,890 So in my example test here, the first test suite 154 00:07:09,900 --> 00:07:11,973 I've got in there a few functions. 155 00:07:13,290 --> 00:07:16,950 The first function, I'm expecting the value to be good 156 00:07:16,950 --> 00:07:21,950 and my custom matcher should pass when it sees a good mark. 157 00:07:22,320 --> 00:07:26,100 So I'm given in, I'm expecting that to be valid. 158 00:07:26,100 --> 00:07:29,700 But what I'm actually doing here is I'm testing my matcher. 159 00:07:29,700 --> 00:07:31,380 I'm testing that my matcher 160 00:07:31,380 --> 00:07:34,770 successfully determines that to be valid, 161 00:07:34,770 --> 00:07:36,570 and that one and that one. 162 00:07:36,570 --> 00:07:39,213 Okay, so all of these should work fine. 163 00:07:40,440 --> 00:07:42,510 Okay, good. 164 00:07:42,510 --> 00:07:44,340 Now have a look at this. 165 00:07:44,340 --> 00:07:46,743 I've got some here, I'm expecting a good value. 166 00:07:48,120 --> 00:07:49,830 That's what I'm hoping for, 167 00:07:49,830 --> 00:07:52,710 but my custom matcher should fail 168 00:07:52,710 --> 00:07:54,460 if we don't get a valid mark. 169 00:07:54,460 --> 00:07:56,820 Okay, so imagine this was some matcher. 170 00:07:56,820 --> 00:07:58,110 We thought it was valid 171 00:07:58,110 --> 00:08:00,720 and we were hoping it was gonna be valid. 172 00:08:00,720 --> 00:08:03,750 If I passed that value into the matcher, 173 00:08:03,750 --> 00:08:06,270 my matcher should fail, it, 174 00:08:06,270 --> 00:08:09,150 I was hoping it was gonna be good, but it should fail. 175 00:08:09,150 --> 00:08:12,041 It should realize that that is actually not valid. 176 00:08:12,041 --> 00:08:14,580 Okay, and so if I uncomment that statement, 177 00:08:14,580 --> 00:08:17,550 then this test should fail. 178 00:08:17,550 --> 00:08:19,290 My custom matcher should realize 179 00:08:19,290 --> 00:08:22,680 that this is not a valid exam mark. 180 00:08:22,680 --> 00:08:26,370 So let's try running the tests. 181 00:08:26,370 --> 00:08:31,370 npm run test -- -t. 182 00:08:34,710 --> 00:08:38,910 And we're going to give it this, "Using toBeExamMark". 183 00:08:43,470 --> 00:08:47,100 Okay, so that select the string there 184 00:08:47,100 --> 00:08:51,093 will pull in my three first suites. 185 00:08:52,380 --> 00:08:53,213 Okay. 186 00:08:55,457 --> 00:08:57,470 toBeExamMark, toBeExamMark, toBeExamMark. 187 00:09:02,940 --> 00:09:05,490 Okay, and I think I probably need a capital U here. 188 00:09:07,320 --> 00:09:11,010 Okay, so it'll find this test suite and it run those tests, 189 00:09:11,010 --> 00:09:13,320 and those ones and those ones. 190 00:09:13,320 --> 00:09:14,880 I might run it again in a moment, 191 00:09:14,880 --> 00:09:16,860 just with some other parameters. 192 00:09:16,860 --> 00:09:19,560 So remember what we're expecting, 193 00:09:19,560 --> 00:09:22,470 I'm expecting these tests to all succeed 194 00:09:22,470 --> 00:09:24,030 because the marks are valid, 195 00:09:24,030 --> 00:09:26,640 and the matcher should say, "Yeah, they're good." 196 00:09:26,640 --> 00:09:27,960 I'm expecting this one. 197 00:09:27,960 --> 00:09:31,830 I'm expecting my custom matcher to fail this test 198 00:09:31,830 --> 00:09:33,570 because the value that the user passed in 199 00:09:33,570 --> 00:09:35,130 isn't valid actually, 200 00:09:35,130 --> 00:09:37,410 and my custom matcher should detect 201 00:09:37,410 --> 00:09:39,213 the fact that it's not valid. 202 00:09:40,980 --> 00:09:42,750 Success. 203 00:09:42,750 --> 00:09:44,190 Now, when you get errors 204 00:09:44,190 --> 00:09:46,170 the messages tend to be quite verbose. 205 00:09:46,170 --> 00:09:48,450 In fact, there's a few failures here. 206 00:09:48,450 --> 00:09:50,070 It was expecting a good value, 207 00:09:50,070 --> 00:09:51,720 but it failed if it didn't get it. 208 00:09:51,720 --> 00:09:55,890 That error there is because of this test here. 209 00:09:55,890 --> 00:09:58,080 Okay, and what I should do as well, 210 00:09:58,080 --> 00:10:00,510 I won't bother running this but what I should do, 211 00:10:00,510 --> 00:10:03,510 is I should also run this test. 212 00:10:03,510 --> 00:10:08,510 Okay, that should also fail because 101 isn't valid. 213 00:10:08,580 --> 00:10:11,790 My custom matcher should realize that it isn't valid 214 00:10:11,790 --> 00:10:13,353 and basically fail. 215 00:10:14,340 --> 00:10:17,040 Right, I'll just comment that back up again. 216 00:10:17,040 --> 00:10:19,593 Let's have a look at the second suite. 217 00:10:20,700 --> 00:10:21,843 In the second suite. 218 00:10:23,100 --> 00:10:25,500 Oh, uncomment one of these following tests. 219 00:10:25,500 --> 00:10:30,500 I'm expecting a bad value, pass if we get a bad value, okay? 220 00:10:31,830 --> 00:10:33,450 So in this case here, 221 00:10:33,450 --> 00:10:38,450 I'm saying I'm expecting -1 not to be a valid exam mark. 222 00:10:38,820 --> 00:10:43,050 Okay, so I'm expecting my custom matcher 223 00:10:43,050 --> 00:10:45,480 will actually pass. 224 00:10:45,480 --> 00:10:48,690 It'll say, okay, so that -1, 225 00:10:48,690 --> 00:10:51,480 I'm expecting it not to be valid mark. 226 00:10:51,480 --> 00:10:54,540 My custom matcher should confirm the fact 227 00:10:54,540 --> 00:10:57,990 that that really isn't, is not a valid mark. 228 00:10:57,990 --> 00:11:01,770 And likewise with this one, if I pass that in 229 00:11:01,770 --> 00:11:05,010 I'm expecting my custom matcher to also realize 230 00:11:05,010 --> 00:11:07,230 and be successful indicating 231 00:11:07,230 --> 00:11:09,123 that that is not a valid exam mark. 232 00:11:11,490 --> 00:11:13,530 What about this one here? 233 00:11:13,530 --> 00:11:15,960 I'm expecting a bad value. 234 00:11:15,960 --> 00:11:18,630 Okay, I've got not, here, to say, 235 00:11:18,630 --> 00:11:20,520 I don't think this is valid. 236 00:11:20,520 --> 00:11:22,740 So whatever parameter in here I pass in, 237 00:11:22,740 --> 00:11:26,170 I'm expecting that parameter not to be a mark, a valid mark. 238 00:11:26,170 --> 00:11:29,617 Okay, so generally this would be a number here nnn. 239 00:11:30,990 --> 00:11:33,180 So I'm expecting it not to be a valid mark 240 00:11:33,180 --> 00:11:35,940 but the thing is, it is a valid mark. 241 00:11:35,940 --> 00:11:40,500 So again, my custom matcher should detect that. 242 00:11:40,500 --> 00:11:41,940 According to the test here, 243 00:11:41,940 --> 00:11:44,430 I was expecting it not to be valid. 244 00:11:44,430 --> 00:11:49,320 It fails the test, okay, because it is not invalid. 245 00:11:49,320 --> 00:11:50,153 It's actually valid. 246 00:11:50,153 --> 00:11:52,500 As you have to think about Boolean logic here. 247 00:11:52,500 --> 00:11:54,960 So these tests should work. 248 00:11:54,960 --> 00:11:56,823 Okay, because those are not valid, 249 00:11:57,906 --> 00:12:00,630 and it detects that they're not valid. 250 00:12:00,630 --> 00:12:04,230 This one should fail because it is valid 251 00:12:04,230 --> 00:12:06,080 but I was checking if it was invalid. 252 00:12:07,290 --> 00:12:08,280 That kinda makes sense to me. 253 00:12:08,280 --> 00:12:12,273 So I'm gonna save that and I'm gonna run my tests again. 254 00:12:16,110 --> 00:12:20,550 So in this case, I'm expecting that test to pass 255 00:12:20,550 --> 00:12:23,190 and we're gonna be expecting that test to fail. 256 00:12:23,190 --> 00:12:24,290 Let's see what we get. 257 00:12:27,720 --> 00:12:30,630 Okay, so in my second suite here, 258 00:12:30,630 --> 00:12:35,160 the first test successfully detected invalid numbers. 259 00:12:35,160 --> 00:12:38,460 And this one here, the fact that the test failed 260 00:12:38,460 --> 00:12:40,290 is actually the correct outcome here, isn't it? 261 00:12:40,290 --> 00:12:44,430 My custom matcher realized that the expectation here 262 00:12:44,430 --> 00:12:46,860 has not been met, okay? 263 00:12:46,860 --> 00:12:48,510 I was expecting it not to be valid. 264 00:12:48,510 --> 00:12:51,150 Well, that expectation hasn't been met, 265 00:12:51,150 --> 00:12:54,183 my custom matcher is intelligent enough to find that. 266 00:12:55,380 --> 00:12:58,110 And finally, have a look at this. 267 00:12:58,110 --> 00:13:00,690 So what I'll do is I'll just comment that test out again, 268 00:13:00,690 --> 00:13:03,040 so we don't keep on getting errors on that one. 269 00:13:05,040 --> 00:13:08,010 In my custom matcher, the first thing it did 270 00:13:08,010 --> 00:13:11,880 was to check if the parameter was a number. 271 00:13:11,880 --> 00:13:16,880 Okay, so if the user accidentally passed in a non-number, 272 00:13:18,630 --> 00:13:20,910 my custom matcher should realize, 273 00:13:20,910 --> 00:13:24,850 it should say, "Hang on, this isn't a valid number." 274 00:13:26,100 --> 00:13:28,803 So that should cause my test to fail. 275 00:13:29,670 --> 00:13:33,603 So let's see if that does indeed cause my test to fail. 276 00:13:35,490 --> 00:13:37,740 We're almost done with this example now. 277 00:13:37,740 --> 00:13:39,120 I think the most difficult thing here 278 00:13:39,120 --> 00:13:41,010 is trying to figure out the logic 279 00:13:41,010 --> 00:13:43,280 of whether it's meant to be true or meant to be false. 280 00:13:43,280 --> 00:13:46,830 So you have to understand what test the user's trying to do. 281 00:13:46,830 --> 00:13:50,100 Are they looking for a good outcome or not a good outcome? 282 00:13:50,100 --> 00:13:51,210 And the test has to be written 283 00:13:51,210 --> 00:13:53,060 in the correct kind of Boolean logic. 284 00:13:54,060 --> 00:13:58,320 Okay, so fail if the value is non-numeric. 285 00:13:58,320 --> 00:14:02,010 That actually is the correct outcome. 286 00:14:02,010 --> 00:14:05,400 Okay, when you give it non-numeric input, 287 00:14:05,400 --> 00:14:07,773 okay, that should fail. 288 00:14:08,880 --> 00:14:11,070 Now what about the next one? 289 00:14:11,070 --> 00:14:13,410 This one should also fail. 290 00:14:13,410 --> 00:14:15,900 Okay, because it doesn't even get us far 291 00:14:15,900 --> 00:14:16,860 but let's see what it does. 292 00:14:16,860 --> 00:14:19,343 Should we actually see what happens when we run this? 293 00:14:25,500 --> 00:14:27,960 Okay, so this last one here, 294 00:14:27,960 --> 00:14:30,480 it should fail if it's non-numeric. 295 00:14:30,480 --> 00:14:33,840 The, to be a valid exam mark 296 00:14:33,840 --> 00:14:36,240 only makes sense if it's a number. 297 00:14:36,240 --> 00:14:37,830 If you pass in a string 298 00:14:37,830 --> 00:14:40,410 then it doesn't even bother check in the range, 299 00:14:40,410 --> 00:14:41,880 it just fails immediately. 300 00:14:41,880 --> 00:14:44,490 So whether you're expecting it to be an exam mark 301 00:14:44,490 --> 00:14:47,820 or not an exam mark, the correct behavior is, I think, 302 00:14:47,820 --> 00:14:50,460 if you pass in a string, that doesn't make sense 303 00:14:50,460 --> 00:14:53,100 so it should fail in any case. 304 00:14:53,100 --> 00:14:58,100 Okay, so that did fail and I would expect it to fail. 305 00:14:58,260 --> 00:15:00,930 I would only expect it to pass if it was a number. 306 00:15:00,930 --> 00:15:03,180 So a bit tricky. 307 00:15:03,180 --> 00:15:04,680 Like I said, the key point 308 00:15:04,680 --> 00:15:07,050 is you have to understand the Boolean logic. 309 00:15:07,050 --> 00:15:09,120 In your custom matcher, 310 00:15:09,120 --> 00:15:11,760 you have to know is the user looking for a positive outcome 311 00:15:11,760 --> 00:15:13,140 or a negative outcome. 312 00:15:13,140 --> 00:15:15,660 And then you kind of return the appropriate error message 313 00:15:15,660 --> 00:15:17,200 from your custom matcher.