Skip to content

Commit 2b6a5a3

Browse files
committed
Proposed Solution Day 22.
1 parent 6bc0615 commit 2b6a5a3

16 files changed

+1160
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ A solution proposal will be published here every day during the `Advent Of Craft
9393
- [Day 19: Loosing up dead weight.](solution/day19/docs/step-by-step.md)
9494
- [Day 20: No more exceptions in our domain.](solution/day20/docs/step-by-step.md)
9595
- [Day 21: Refactor the tests and production code to Output-Based tests.](solution/day21/docs/step-by-step.md)
96+
- [Day 22: Design a diamond program using T.D.D and Property-Based Testing.](solution/day22/docs/step-by-step.md)
9697

9798
## Contributors
9899

solution/day22/.tcr/config.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
config:
2+
git:
3+
auto-push: false
4+
polling-period: 2s
5+
mob-timer:
6+
duration: 5m0s
7+
tcr:
8+
language: java
9+
toolchain: maven

solution/day22/.tcr/language/java.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
toolchains:
2+
default: maven
3+
compatible-with: [ maven ]
4+
source-files:
5+
directories: [ src/main ]
6+
patterns: [ '(?i)^.*\.java$' ]
7+
test-files:
8+
directories: [ src/test ]
9+
patterns: [ '(?i)^.*\.java$' ]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
build:
2+
- os: [ darwin, linux, windows ]
3+
arch: [ "386", amd64, arm64 ]
4+
command: mvn
5+
arguments: [ test-compile ]
6+
test:
7+
- os: [ darwin, linux, windows ]
8+
arch: [ "386", amd64, arm64 ]
9+
command: mvn
10+
arguments: [ test ]
11+
test-result-dir: target/surefire-reports

solution/day22/docs/challenge-done.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
## Day 22: Design a diamond program using T.D.D and Property-Based Testing.
2+
3+
We think about a possible contract for our class:
4+
- It may contain a `print` method taking the `endCharacter` as parameter
5+
- It could look like `Character` -> `Option<String>`
6+
- We could use an `Option` because there are some cases that are not supported (ex: '^', '1', ...)
7+
8+
Let's design and implement it starting from less to more complex properties.
9+
10+
### None for invalid characters
11+
12+
```text
13+
for all (invalidEndCharacter)
14+
such that print(invalidEndCharacter) fail
15+
```
16+
17+
🔴 We start by creating this first property
18+
19+
- We can generate production code from the `property`
20+
- We work on how to generate `invalidEndCharacters`
21+
- We check the generation of random characters
22+
- Here is an example of values
23+
24+
🟢 We make it pass by `hardcoding` the result
25+
26+
🔵 We clean a little bit the test
27+
28+
### Horizontally symmetric
29+
30+
```text
31+
for all (validEndCharacter)
32+
such that diamond(validEndCharacter) == reverse(diamond(validEndCharacter))
33+
```
34+
35+
🔴 We add a first version of the property
36+
37+
🟢 We make it pass by `hardcoding` the return value
38+
39+
🔵 We extract the guard and use ternary operator
40+
41+
### Is a square (height = width)
42+
43+
```text
44+
for all (validEndCharacter)
45+
such that diamond(validEndCharacter) is a square
46+
```
47+
48+
The result `String` should a square meaning that each line contains the same number of characters than the number of lines.
49+
50+
🔴 Let's identify if it is a square
51+
52+
🟢 We can make it pass by simply returning 'A'
53+
54+
🔵 We have plenty of duplication in our tests
55+
56+
### Contain 2 identical letters per line
57+
58+
```text
59+
for all (validEndCharacter)
60+
such that each line in diamond(validEndCharacter) contains 2 identical letters except first and last
61+
```
62+
63+
😬 It is already green...
64+
65+
It is maybe a signal that we need to iterate on the implementation
66+
67+
- We design from the implementation
68+
69+
🔴 Our properties are now failing, we can triangulate the algorithm
70+
71+
- We experiment and learn from the properties
72+
- We fix the property `be_horizontally_symmetric` by iterating on the code
73+
- We fix `contains_2_letters_per_line` by fixing the `toLine` method
74+
- We fix the property `be_a_square` by fixing the `generateEmptyCharacters`
75+
76+
🟢 All our properties are green again 🤩
77+
78+
🔵 Let's refactor our `Diamond` to extract some method and give business names
79+
80+
### Lines have a decreasing number of left spaces
81+
82+
```text
83+
for all (validEndCharacter)
84+
such that Lines have a decreasing number of left white spaces until end character
85+
```
86+
87+
🟢 Not that easy to create...
88+
89+
🔵 We refactor the test to make it more clear what we do in it
90+
91+
### Lines have a decreasing number of right spaces
92+
93+
🟢 As you may expect the property is green
94+
95+
🔵 We can remove duplications in the test
96+
97+
- We create a new `method` to centralize this logic
98+
99+
> All our properties are green 🤩. Are we confident enough?
100+
101+
### Add an `Approval` test
102+
103+
To increase our confidence we secure our implementation with a `Unit Test`.
104+
We choose to use an `Approval` one.
105+
106+
🔴 It fails because we need to approve the result
107+
108+
🟢 It seems pretty good
109+
110+
We approve the file, and we're done, for now 😉.
111+
112+
Our `Diamond` is complete!
113+
114+
>**Tip of the day: Property based testing with TDD can help you design a more robust implementation.**
115+
116+
### Share your experience
117+
118+
How does your code look like?
119+
120+
Please let everyone know in the discord.
124 KB
Loading
Loading
212 KB
Loading

solution/day22/docs/snippet.png

2.27 MB
Loading

0 commit comments

Comments
 (0)