Skip to content

Commit 27b106b

Browse files
committed
Proposed Solution Day 21.
1 parent 057f507 commit 27b106b

22 files changed

+981
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Here are the different challenges :
6666
- [Day 18: Automatically detect Linguistic Anti-Patterns (LAP).](exercise/day18/docs/challenge.md)
6767
- [Day 19: Loosing up dead weight.](exercise/day19/docs/challenge.md)
6868
- [Day 20: No more exceptions in our domain.](exercise/day20/docs/challenge.md)
69-
- [Day 21: Refactor the tests and production code to Output-based tests.](exercise/day21/docs/challenge.md)
69+
- [Day 21: Refactor the tests and production code to Output-Based tests.](exercise/day21/docs/challenge.md)
7070

7171
### Solutions
7272
A solution proposal will be published here every day during the `Advent Of Craft` containing `the code` and a `step by step` guide.
@@ -91,6 +91,7 @@ A solution proposal will be published here every day during the `Advent Of Craft
9191
- [Day 18: Automatically detect Linguistic Anti-Patterns (LAP).](solution/day18/docs/step-by-step.md)
9292
- [Day 19: Loosing up dead weight.](solution/day19/docs/step-by-step.md)
9393
- [Day 20: No more exceptions in our domain.](solution/day20/docs/step-by-step.md)
94+
- [Day 21: Refactor the tests and production code to Output-Based tests.](solution/day21/docs/step-by-step.md)
9495

9596
## Contributors
9697

exercise/day21/docs/challenge.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Today's exercise is about fixing tests and fixing code.
1111
A refactoring is needed but a first step needs to be made
1212
in the tests.
1313

14-
> **Challenge of day 21: Refactor the tests and production code to Output-based tests.**
14+
> **Challenge of day 21: Refactor the tests and production code to Output-Based tests.**
1515
1616
Before refactoring the code, here are some explanations regarding the different kind of tests as explained by Vladimir
1717
Khorikov in his book [Unit Testing Principles, Practices and Patterns.](https://www.manning.com/books/unit-testing).

solution/day21/docs/challenge-done.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
## Day 21: Refactor the tests and production code to Output-based tests.
2+
3+
### Refactor to Output-Based
4+
- Instead of hiding side effects behind an interface and injecting that interface into `AuditManager`, we can move those side effects out of the class entirely :
5+
- `AuditManager`: responsible for making a decision about what to do with the files
6+
- A new class, `Persister` acts on that decision and applies updates to the filesystem
7+
8+
#### AuditManager
9+
In terms of contract we would like something like this:
10+
- `FileUpdate addRecord(FileContent[] files, String visitorName, LocalDateTime timeOfVisit)`
11+
- We choose to write the code `from scratch` aside from existing code
12+
- When we do it on legacy code, it's called [`Sprout Class`](https://understandlegacycode.com/blog/key-points-of-working-effectively-with-legacy-code/#1-the-sprout-technique)
13+
14+
🔴 Let's express this expectation from a test
15+
16+
- Of course, we do not compile here...
17+
- We have just prototyped a first version of what we might want (it can evolve while writing the code)
18+
- We generate the classes from our test
19+
- Here is the generated skeleton
20+
21+
🔴 The test is still red but for a good reason: because of the assertion (no compilation error anymore)
22+
23+
🟢 Make it pass as fast as possible
24+
25+
- We hard code the value for now
26+
- We can check that our flow is correct
27+
28+
🔵 Let's refactor it
29+
30+
- Based on the existing logic we would like to design something that looks like this:
31+
- sortFiles -> formatDate -> createRecord -> createFileUpdate (based on maxEntriesPerFile)
32+
- We will iterate on the code
33+
- Our test is still green, so let's move on
34+
- We improved the algorithm
35+
- Other tests are missing to `triangulate` the rest of the implementation
36+
- Let's add them incrementally
37+
38+
> It is the same logic here for this test case
39+
40+
- We refactor the tests before adding a new test case
41+
42+
🔴 Let's add a test that writes in the `Current Audit File`
43+
44+
- Of course, we need to triangulate our algorithm with this test
45+
46+
🟢 Iterate on the `addRecord` method
47+
48+
🔴 By incrementing on the code, we have broken a test `addsNewVisitorToANewFileBecauseNoFileToday`
49+
50+
- We fix it as fast as possible to go back in a safe state
51+
52+
🔵 It's time to play 🥳
53+
54+
- We extract some methods and rename some variables
55+
- We can definitely improve the `createNewFileOrUpdate` method
56+
- We have lost some features in the battle
57+
- Let's implement the `Persister` class
58+
59+
#### Persister - Bonus
60+
The Persister is responsible for
61+
- accessing files from a given Directory
62+
- applying update instruction (a.k.a update the file content)
63+
64+
#### AddRecordUseCase
65+
We need to have some glue to control the flow of our application. Let's create a `UseCase` for that.
66+
67+
Our logic is now in a class of its own using the Persister as a dependency.
68+
69+
>**Tip of the day: Isolate your business logic from dependencies outside your system.**
70+
71+
### Share your experience
72+
73+
How does your code look like?
74+
75+
Please let everyone know in the discord.
106 KB
Loading
33.2 KB
Loading
64.4 KB
Loading

solution/day21/docs/img/failure2.png

242 KB
Loading
184 KB
Loading
71.6 KB
Loading
216 KB
Loading

0 commit comments

Comments
 (0)