1 00:00:00,270 --> 00:00:03,180 We're starting to get the hang of Mocha and BDD and 2 00:00:03,180 --> 00:00:05,930 we're using it to write more interesting functions. 3 00:00:05,930 --> 00:00:11,360 So let's expand our test suite and see some other things Chai and Mocha can do. 4 00:00:11,360 --> 00:00:15,640 Now that we can check for a ship, we also need to register damage on a ship. 5 00:00:15,640 --> 00:00:16,670 Currently, check for 6 00:00:16,670 --> 00:00:21,320 ship only reports true or false depending where ships are located, but 7 00:00:21,320 --> 00:00:25,840 we need to actually keep track of the damage each ship has sustained, too. 8 00:00:25,840 --> 00:00:29,820 So let's start a new test suite to describe the damage ship function. 9 00:00:29,820 --> 00:00:33,720 We introduce a test suite and mocha using describe. 10 00:00:33,720 --> 00:00:38,490 So right below the check for ship suite we'll add describe. 11 00:00:40,820 --> 00:00:46,092 Then we'll pass two arguments, 12 00:00:46,092 --> 00:00:53,070 the string, damageShip, and a function. 13 00:00:53,070 --> 00:00:57,923 Then, we'll import the damageShip function from the ship methods.js file at the top 14 00:00:57,923 --> 00:00:58,730 of our suite. 15 00:01:15,657 --> 00:01:20,290 So what do we definitely know about the way damageShip should work? 16 00:01:20,290 --> 00:01:23,660 Well, It should probably take a ship, and a given coordinate of the ship, 17 00:01:23,660 --> 00:01:24,980 as arguments. 18 00:01:24,980 --> 00:01:29,610 And we need to know which ship to damage and which spot to register damage on. 19 00:01:29,610 --> 00:01:32,760 So, that sounds like a good expectation of damage ship. 20 00:01:32,760 --> 00:01:37,683 So we'll create a test spec that says it should register damage on 21 00:01:37,683 --> 00:01:40,202 a given ship at a given location. 22 00:01:53,635 --> 00:01:56,198 So now that we're dealing with a given ship, 23 00:01:56,198 --> 00:02:00,810 this function doesn't need any information about the player object. 24 00:02:00,810 --> 00:02:05,430 So I'll set up the simplest ship I need to conduct the test. 25 00:02:05,430 --> 00:02:08,802 I'll add one ship, one location. 26 00:02:16,184 --> 00:02:19,660 Then I'll add a damage array to keep track of the damage that's taken. 27 00:02:22,330 --> 00:02:25,140 So now I'm going to write the minimum function I need 28 00:02:25,140 --> 00:02:26,510 to get the test to run correctly. 29 00:02:27,620 --> 00:02:30,740 So damaged ship is different than check for 30 00:02:30,740 --> 00:02:33,730 ship in that it doesn't return anything. 31 00:02:33,730 --> 00:02:36,740 So we can't just plug it into our expect method. 32 00:02:36,740 --> 00:02:41,430 Instead we have to test the side effects of damage ship after we call it. 33 00:02:41,430 --> 00:02:46,950 So inside our spec, if we call, 34 00:02:46,950 --> 00:02:51,810 damageShip, then past ship and 35 00:02:51,810 --> 00:02:57,000 the coordinate zero, zero, what should we expect to be different? 36 00:02:58,310 --> 00:03:01,420 Well, we should expect the ship's damage array to be different, 37 00:03:01,420 --> 00:03:02,910 it should not be empty. 38 00:03:03,960 --> 00:03:08,040 Remember earlier when we wrote our title case function, I mentioned that Chai has 39 00:03:08,040 --> 00:03:11,270 a lot of assertion methods for making our test easy to write. 40 00:03:11,270 --> 00:03:15,360 So let's go to the documentation and see what's available for us to use. 41 00:03:15,360 --> 00:03:19,740 I've linked to the BDD API docs in the teacher's notes of this video. 42 00:03:19,740 --> 00:03:25,650 So, looking through the available methods, the very first one I see is not. 43 00:03:25,650 --> 00:03:27,450 And the docs even give me an example. 44 00:03:27,450 --> 00:03:31,560 So here it says expect foo to not equal bar. 45 00:03:31,560 --> 00:03:33,410 Well, that seems useful. 46 00:03:33,410 --> 00:03:36,390 I've already described my expectation to myself so 47 00:03:36,390 --> 00:03:39,310 the damage array should not be empty. 48 00:03:39,310 --> 00:03:43,610 So I'll just search the page for empty and see what I get. 49 00:03:45,520 --> 00:03:49,130 Great, it looks like Chai has a built in method that checks for 50 00:03:49,130 --> 00:03:51,620 empty objects, arrays, or strings. 51 00:03:51,620 --> 00:03:52,800 Cool. 52 00:03:52,800 --> 00:03:55,840 So this will make it really easy to write our expectation 53 00:03:55,840 --> 00:03:58,070 without worrying about how the real code will work. 54 00:03:59,120 --> 00:04:04,640 So back inside our spec, right after damageShip, I'll add 55 00:04:04,640 --> 00:04:14,150 expect (ship.damage).to.not.be.empty. 56 00:04:14,150 --> 00:04:16,430 All right, so now, if we save our file and 57 00:04:16,430 --> 00:04:21,660 run npm test in the console, we get a type error. 58 00:04:21,660 --> 00:04:24,700 It says, damageShip is not a function. 59 00:04:24,700 --> 00:04:28,885 Well, of course because the damage ship function is missing so let's create it. 60 00:04:33,512 --> 00:04:39,455 So back inside shipmethod.js, I'll define the damageShip function. 61 00:04:44,159 --> 00:04:49,540 And the function will accept the parameters, ship and coordinates. 62 00:04:53,320 --> 00:05:02,050 And we'll need to export the function at the bottom of our file, 63 00:05:02,050 --> 00:05:10,010 by typing module.exports.damageShip = damageShip. 64 00:05:10,010 --> 00:05:13,220 Remember, without these module.export statements, 65 00:05:13,220 --> 00:05:17,390 the test files won't have access to the functions we wrote. 66 00:05:17,390 --> 00:05:19,210 And they'll fail when we run the tests. 67 00:05:21,320 --> 00:05:25,840 Alright, so now let's go over to the console and run npm test. 68 00:05:29,030 --> 00:05:31,630 So now the test reports a new error, 69 00:05:31,630 --> 00:05:35,170 it says assertion error, expected brackets not to be empty. 70 00:05:36,830 --> 00:05:44,170 So inside the damaged ship function, we'll say ship.damage.push. 71 00:05:44,170 --> 00:05:45,574 Then we'll pass coordinates. 72 00:05:48,886 --> 00:05:51,788 So let's go to the console and run the test again. 73 00:05:54,818 --> 00:05:56,758 And great, now the test passes, 74 00:05:56,758 --> 00:06:00,859 proving that damaged ship can change the given ship's damage array. 75 00:06:04,944 --> 00:06:09,267 So now we should add an expectation that proves we actually added the right thing 76 00:06:09,267 --> 00:06:10,570 to the array. 77 00:06:10,570 --> 00:06:13,140 So let's see if Chai can help us out with this too. 78 00:06:13,140 --> 00:06:15,360 So once again, I'll search the docs. 79 00:06:15,360 --> 00:06:19,160 Now I'm not exactly sure what to call the method I'm looking for here. 80 00:06:19,160 --> 00:06:23,190 But I do know that I want to check whether an array has specific members. 81 00:06:23,190 --> 00:06:27,243 Unfortunately I can't just expect the first member to equal zero, 82 00:06:27,243 --> 00:06:32,190 zero because two unique arrays are never truly equal in JavaScript 83 00:06:32,190 --> 00:06:34,640 even when they store the same values. 84 00:06:34,640 --> 00:06:39,730 Every array is a distinct object, but JavaScript uses strict identity for 85 00:06:39,730 --> 00:06:45,240 equals, so two arrays could only be equal if they were really the very same object. 86 00:06:45,240 --> 00:06:49,070 Not just two objects with all the same property values. 87 00:06:49,070 --> 00:06:53,560 We call arrays that look the same deeply equal, because their deep 88 00:06:53,560 --> 00:06:58,170 interval values are equal, even though the arrays themselves are different objects. 89 00:06:58,170 --> 00:07:01,910 So I'll try searching the page for array and see what turns up. 90 00:07:03,530 --> 00:07:06,940 All right, so the first thing I see is a method called include 91 00:07:06,940 --> 00:07:11,620 which looks like it checks for an array for a given value, this is perfect. 92 00:07:11,620 --> 00:07:16,650 All right, so back inside ship_test.js, I'll add a new expectation to my spec 93 00:07:16,650 --> 00:07:20,620 by simply copying this one and pasting a new one below. 94 00:07:20,620 --> 00:07:25,150 And this one will say, 95 00:07:25,150 --> 00:07:33,497 expect(ship.damage).to.include 96 00:07:33,497 --> 00:07:36,370 zero,zero. 97 00:07:36,370 --> 00:07:39,920 So now when i go over to the console and 98 00:07:39,920 --> 00:07:45,410 run the test again, I see that the test doesn't pass. 99 00:07:45,410 --> 00:07:51,095 It says expected [ [0, 0 ] ] to include [ 0, 0 ]. 100 00:07:51,095 --> 00:07:55,720 So I can see that the ships.damage array includes the array I want, but 101 00:07:55,720 --> 00:07:56,890 Chai doesn't seem to believe it. 102 00:07:56,890 --> 00:07:59,570 It must be that include doesn't 103 00:07:59,570 --> 00:08:02,410 really solve our deep equality problem from before. 104 00:08:03,490 --> 00:08:05,630 So let's check the docs again. 105 00:08:05,630 --> 00:08:08,590 Now the problem seems to be deep equality. 106 00:08:08,590 --> 00:08:12,610 So I'll try searching the page for deep and see what comes up. 107 00:08:14,090 --> 00:08:18,660 Great, so this method here looks good because it allows 108 00:08:18,660 --> 00:08:22,640 us to make deep equality comparisons, which is exactly what we need. 109 00:08:24,050 --> 00:08:28,730 So now I can write an expectation about the first member of the damage array, 110 00:08:28,730 --> 00:08:34,204 by changing this expectation here at the bottom to expect ship.damage 111 00:08:34,204 --> 00:08:38,690 zero to.deep.equal zero, zero. 112 00:08:38,690 --> 00:08:42,680 So I'll say to.deep.equal. 113 00:08:42,680 --> 00:08:43,560 So, basically, 114 00:08:43,560 --> 00:08:47,100 just check that the first element of the damage array looks like this. 115 00:08:48,970 --> 00:08:54,740 All right so now if we save this file and run npm test in the console. 116 00:08:56,890 --> 00:08:59,390 Great, it looks like everything is passing. 117 00:08:59,390 --> 00:09:02,760 Now we could complicate the damage ship function by first 118 00:09:02,760 --> 00:09:06,970 making sure that the ship hasn't already taken damage at the given location, 119 00:09:06,970 --> 00:09:11,740 by making sure the location is valid and so on, but this will do for now. 120 00:09:11,740 --> 00:09:15,470 Now we need a method that players can call during the game in order to 121 00:09:15,470 --> 00:09:16,860 fire on their opponent. 122 00:09:16,860 --> 00:09:21,060 It should use check for ship to confirm the attacking player's guess. 123 00:09:21,060 --> 00:09:24,620 And it should use damage ship to register damage on their opponent. 124 00:09:25,760 --> 00:09:27,220 Try and write a test suite for 125 00:09:27,220 --> 00:09:30,625 this fire function using some of the assertion methods you learned. 126 00:09:30,625 --> 00:09:35,830 Like equal, not.equal, deep.equal, .include and so on. 127 00:09:35,830 --> 00:09:39,180 You might even check the documentation to find something more useful for 128 00:09:39,180 --> 00:09:40,750 your test spec idea. 129 00:09:40,750 --> 00:09:44,240 The link to that documentation is in the teacher's notes of this video. 130 00:09:44,240 --> 00:09:48,010 And if you're feeling confident you can even try implementing the function 131 00:09:48,010 --> 00:09:48,860 based on your test suite. 132 00:09:50,320 --> 00:09:54,220 We've already been using BDD this whole time, I think you can do it. 133 00:09:54,220 --> 00:09:56,710 And when you're done, I'll show you my approach in the next video.