﻿1
00:00:04,440 --> 00:00:07,500
Our worldle clone
is getting better and better,

2
00:00:07,653 --> 00:00:10,010
but there is still an elephant in the room

3
00:00:10,033 --> 00:00:13,000
that we have been ignoring
up to this point.

4
00:00:13,467 --> 00:00:18,367
A player is meant to be able
to try guessing the word multiple times.

5
00:00:18,520 --> 00:00:22,250
More precisely,
a player is allowed six tries.

6
00:00:22,467 --> 00:00:25,867
Today we'll modify our app
to allow just that.

7
00:00:27,350 --> 00:00:30,633
This test here will have to be changed

8
00:00:30,667 --> 00:00:33,800
to now require the user
to make six guesses

9
00:00:33,825 --> 00:00:36,200
before the defeat message is rendered.

10
00:00:37,510 --> 00:00:41,667
Maybe we could make use
of another .each function for this.

11
00:00:41,886 --> 00:00:45,208
Let's turn this test
into a series of mini tests

12
00:00:45,233 --> 00:00:48,833
where we go from making zero wrong guesses

13
00:00:48,967 --> 00:00:52,400
all the way up
to making six wrong guesses.

14
00:00:52,567 --> 00:00:57,933
We should only see the defeat message
when we make six wrong guesses.

15
00:01:05,470 --> 00:01:06,937
So as you can see over here,

16
00:01:06,962 --> 00:01:09,367
I'm providing a series of data

17
00:01:09,400 --> 00:01:12,200
that goes from zero guesses
to six guesses,

18
00:01:12,225 --> 00:01:16,200
and only in the last case
we should be seeing a defeat message.

19
00:01:19,316 --> 00:01:24,867
A good name for this describe block
could be a defeat message

20
00:01:24,892 --> 00:01:30,567
should appear if the player makes
incorrect guesses six times in a row.

21
00:01:32,067 --> 00:01:34,767
Now the body of this describe block

22
00:01:34,767 --> 00:01:42,267
is going to contain a series
of automated tests for each scenario.

23
00:01:43,267 --> 00:01:46,833
I think a good name for each one
of these individual tests

24
00:01:46,833 --> 00:01:51,767
could be therefore for x guesses

25
00:01:51,792 --> 00:01:56,433
a defeat message should
or should not appear.

26
00:01:58,662 --> 00:02:02,667
Now what are we going to be populating
in this dynamic title here?

27
00:02:02,713 --> 00:02:04,233
Well it's going to be something

28
00:02:04,258 --> 00:02:07,600
that is going to be calculated
based on the number of guesses

29
00:02:07,667 --> 00:02:10,700
and whether or not
the defeat message should be visible.

30
00:02:11,633 --> 00:02:15,786
Here we can just add the number
of guesses directly to the test name,

31
00:02:15,811 --> 00:02:18,431
but in here I want to render

32
00:02:20,864 --> 00:02:22,864
the word not

33
00:02:23,255 --> 00:02:26,433
only if the defeat message is false.

34
00:02:27,633 --> 00:02:33,300
Great and what would be the arrange,
act, and assert of this test?

35
00:02:33,433 --> 00:02:37,843
Well the arrange is already done
for us because of our beforeEach,

36
00:02:38,039 --> 00:02:41,667
which is mount the component
with a word of the day.

37
00:02:41,847 --> 00:02:45,533
For the act we're going to be typing
a wrong guess

38
00:02:45,667 --> 00:02:48,103
a number of guesses amount of time.

39
00:02:55,263 --> 00:02:56,643
And for the assert phase

40
00:02:56,668 --> 00:03:00,000
we're going to search
that the defeat message is on the screen

41
00:03:00,067 --> 00:03:01,467
or is not on the screen.

42
00:03:12,497 --> 00:03:14,633
Now if we run our tests,

43
00:03:15,823 --> 00:03:20,010
we can see that we're passing on the case
of not showing a victory message

44
00:03:20,035 --> 00:03:21,500
if no wrong guess was done,

45
00:03:22,850 --> 00:03:27,497
but we are failing
on all the different retries

46
00:03:27,533 --> 00:03:29,417
that the player
should have the right to do.

47
00:03:29,433 --> 00:03:31,967
You can see
that when we make one wrong guess

48
00:03:31,992 --> 00:03:35,667
we are already displaying
the defeat message to the player.

49
00:03:36,890 --> 00:03:39,100
Okay let's get this test to pass

50
00:03:39,125 --> 00:03:42,837
and of course we should remove
this previous test over here

51
00:03:42,862 --> 00:03:45,300
because it's no longer
relevant to the project.

52
00:03:45,513 --> 00:03:48,133
It has been replaced by our new test.

53
00:03:52,183 --> 00:03:53,863
To get the test to pass,

54
00:03:53,888 --> 00:03:55,730
we're going to have to be keeping track

55
00:03:55,755 --> 00:03:58,467
of all the previous guesses
the player has submitted.

56
00:03:58,767 --> 00:04:02,133
Well guess submitted right now
is just a single string.

57
00:04:02,273 --> 00:04:09,333
Let's turn this into guesses submitted
that is now an array of strings.

58
00:04:13,123 --> 00:04:14,997
If the player is submitting a guess

59
00:04:15,022 --> 00:04:17,997
then instead of simply assigning
the guess to guesseSubmitted

60
00:04:18,033 --> 00:04:21,200
we're going to be pushing
this guess into it.

61
00:04:23,120 --> 00:04:27,633
Another change that we have to do
is what counts as the game ending.

62
00:04:28,159 --> 00:04:31,233
Before we had that it just had to be

63
00:04:31,267 --> 00:04:34,067
guessSubmitted
having a length greater than zero,

64
00:04:34,133 --> 00:04:40,890
but now guess submitted has to have
a length of six or guesses submitted

65
00:04:40,900 --> 00:04:43,200
includes the word of the day.

66
00:04:44,263 --> 00:04:46,457
And we're going to render
the victory message

67
00:04:46,467 --> 00:04:49,200
when guesses submitted
includes the word of the day.

68
00:04:51,103 --> 00:04:55,167
Well notice that TypeScript
is complaining over here

69
00:04:55,267 --> 00:05:00,833
because word of the day
can be either a string or undefined.

70
00:05:01,067 --> 00:05:06,800
The reason behind this is that
our word of the day prop is not required.

71
00:05:07,433 --> 00:05:11,193
We can make it required by providing
an extra key here,

72
00:05:12,640 --> 00:05:15,270
called required, and set it to true.

73
00:05:16,330 --> 00:05:19,367
And there you go. You can see
that TypeScript has stopped complaining

74
00:05:19,392 --> 00:05:23,667
because now the word of the day
is considered a string.

75
00:05:24,367 --> 00:05:27,700
Great! I think this should be enough
to get this test to pass.

76
00:05:27,733 --> 00:05:29,533
Let's try to run all the tests

77
00:05:30,737 --> 00:05:34,367
and we can see
that we have green across the board.

78
00:05:36,243 --> 00:05:38,967
Awesome! Let's make a commit.

79
00:05:40,983 --> 00:05:44,600
Allow player to make 6 guesses.

80
00:05:46,943 --> 00:05:51,090
To refactor,
I think a nice quick win for us over here

81
00:05:51,137 --> 00:05:54,267
would be to extract this number 6.

82
00:05:54,633 --> 00:05:59,167
It's a magic number.
And what does it represent?

83
00:05:59,233 --> 00:06:02,200
Well, it represents the,

84
00:06:03,077 --> 00:06:06,510
MAX_GUESSES_COUNT, right?

85
00:06:08,183 --> 00:06:10,933
Let's use this in our test.

86
00:06:17,857 --> 00:06:20,633
And in our worldeBoard.

87
00:06:23,590 --> 00:06:27,467
Awesome! If we run our tests,
we can see that we're still passing.

88
00:06:27,493 --> 00:06:29,267
So let's make another commit.

89
00:06:29,300 --> 00:06:31,383
Extract constant.

90
00:06:34,077 --> 00:06:38,570
Another thing that I believe would
increase the readability of this component

91
00:06:38,733 --> 00:06:43,500
is to extract this conditional over here
into a computed property.

92
00:06:43,753 --> 00:06:46,433
Again, what does this represent?

93
00:06:46,606 --> 00:06:50,433
It's effectively checking to see
if the game has ended.

94
00:06:50,600 --> 00:06:53,700
So let's make a computed property
that represents it.

95
00:06:54,650 --> 00:07:01,700
I like to have my boolean variables,
start their names with either is or has.

96
00:07:02,367 --> 00:07:05,400
In this case,
I want to call it isGameOver.

97
00:07:06,100 --> 00:07:09,977
And we're going to know
whether or not the game is over

98
00:07:10,033 --> 00:07:13,967
when the player has exhausted
their guess count

99
00:07:13,992 --> 00:07:16,800
or if they made a successful guess.

100
00:07:22,123 --> 00:07:25,133
For me to access
the word of the day as a prop,

101
00:07:25,200 --> 00:07:28,467
I need to capture
the return value of defineProps

102
00:07:29,433 --> 00:07:30,913
and use it in here.

103
00:07:37,286 --> 00:07:39,933
Great! Let's try running our tests again.

104
00:07:41,026 --> 00:07:43,600
And we can see that we're still passing.

105
00:07:44,367 --> 00:07:48,200
I want to make a commit
and call it extractConditional.

106
00:07:51,096 --> 00:07:52,150
Awesome!

107
00:07:53,777 --> 00:07:59,167
If we want, we can also make our test
generator not have as much repetition.

108
00:07:59,446 --> 00:08:01,080
A way for us to do this is,

109
00:08:01,100 --> 00:08:04,780
by creating this array
of entries over here, dynamically,

110
00:08:04,833 --> 00:08:07,470
via Array.from, like this.

111
00:08:11,817 --> 00:08:14,923
Array.from receives,
as the first argument,

112
00:08:14,933 --> 00:08:16,790
anything that looks like an array.

113
00:08:17,167 --> 00:08:19,567
So an object with a property of length

114
00:08:20,067 --> 00:08:22,933
is going to be something
that Array.from can work with.

115
00:08:23,067 --> 00:08:26,433
And the second argument is a map callback

116
00:08:26,567 --> 00:08:31,200
where you can define what are going
to be the final values of that array.

117
00:08:31,293 --> 00:08:33,900
The first argument is the current value.

118
00:08:33,967 --> 00:08:36,067
The second argument is the index.

119
00:08:37,903 --> 00:08:40,067
With that said though, honestly,

120
00:08:40,092 --> 00:08:44,967
I would prefer the previous version
on how we had the test.

121
00:08:45,917 --> 00:08:51,300
I think tests were reading better
with that repetition that we had before.

122
00:08:51,967 --> 00:08:56,897
So if you also think the same way as I do,
keep it with the repetition.

123
00:08:56,922 --> 00:09:01,216
Not all repetition is bad,
especially when we're talking about tests.

124
00:09:01,241 --> 00:09:05,233
Our focus here is increasing
the readability of the code base.

125
00:09:05,333 --> 00:09:06,800
I just wanted to show you

126
00:09:06,825 --> 00:09:12,867
that it is possible for you to create
dynamic data sets for the describe each.

127
00:09:14,623 --> 00:09:18,700
If I run all my tests,
I can see that they are still passing.

128
00:09:19,000 --> 00:09:21,333
Therefore, I can make another commit,

129
00:09:21,358 --> 00:09:24,567
and I'm going to call it
reduceRepetitionsInTests.

130
00:09:26,977 --> 00:09:30,570
Great, together we have expanded
the rules of the game

131
00:09:30,595 --> 00:09:33,867
to allow our players
to have up to six guesses.


