Skip to content

Commit

Permalink
Day 16: Withstanding the change of time.
Browse files Browse the repository at this point in the history
  • Loading branch information
ythirion committed Dec 16, 2023
1 parent ec9f56a commit c5fe181
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Here are the different challenges :
- [Day 13: Find a way to eliminate the irrelevant, and amplify the essentials of those tests.](exercise/day13/docs/challenge.md)
- [Day 14: Do not use exceptions anymore.](exercise/day14/docs/challenge.md)
- [Day 15: Put a code under tests.](exercise/day15/docs/challenge.md)
- [Day 16: Make this code immutable.](exercise/day16/docs/challenge.md)

### Solutions
A solution proposal will be published here every day during the `Advent Of Craft` containing `the code` and a `step by step` guide.
Expand Down
25 changes: 25 additions & 0 deletions exercise/day16/docs/challenge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## Day 16: Withstanding the change of time.

Today, you are passing through a agitated sea.
A tornado is raging not far from your area, and you have to change course.

Today's exercise is about sustaining code.
A code that is robust and that will weather changes.

There are different avenues for code improvement:

- We looked at breaking conditions, better naming, avoiding complexity
and even dependency check.

But we are not talking about these refactoring steps.
No, today we focus our effort into a simple question:

_Is my code better mutable or immutable?_

> **Day 16: Make this code immutable.**
May you be protected on your crafting journey!

- <u>💡HINT:</u> Code from usage for this one.

![snippet of the day](snippet.png)
Binary file added exercise/day16/docs/snippet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions exercise/day16/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.advent-of-craft</groupId>
<artifactId>advent-of-craft2023</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>blog-part3</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<instancio-junit.version>3.0.0</instancio-junit.version>
</properties>

<dependencies>
<dependency>
<groupId>org.instancio</groupId>
<artifactId>instancio-junit</artifactId>
<version>${instancio-junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
37 changes: 37 additions & 0 deletions exercise/day16/src/main/java/blog/Article.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package blog;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class Article {
private final String name;
private final String content;
private final ArrayList<Comment> comments;

public Article(String name, String content) {
this.name = name;
this.content = content;
this.comments = new ArrayList<>();
}

private void addComment(
String text,
String author,
LocalDate creationDate) throws CommentAlreadyExistException {
var comment = new Comment(text, author, creationDate);

if (comments.contains(comment)) {
throw new CommentAlreadyExistException();
} else comments.add(comment);
}

public void addComment(String text, String author) throws CommentAlreadyExistException {
addComment(text, author, LocalDate.now());
}

public List<Comment> getComments() {
return comments;
}
}

6 changes: 6 additions & 0 deletions exercise/day16/src/main/java/blog/Comment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package blog;

import java.time.LocalDate;

public record Comment(String text, String author, LocalDate creationDate) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package blog;

public class CommentAlreadyExistException extends Exception {
}
34 changes: 34 additions & 0 deletions exercise/day16/src/test/java/blog/ArticleBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package blog;

import java.util.HashMap;
import java.util.Map;

public class ArticleBuilder {
public static final String AUTHOR = "Pablo Escobar";
public static final String COMMENT_TEXT = "Amazing article !!!";
private final HashMap<String, String> comments;

public ArticleBuilder() {
comments = new HashMap<>();
}

public static ArticleBuilder anArticle() {
return new ArticleBuilder();
}

public ArticleBuilder commented() {
this.comments.put(COMMENT_TEXT, AUTHOR);
return this;
}

public Article build() throws CommentAlreadyExistException {
var article = new Article(
"Lorem Ipsum",
"consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore"
);
for (Map.Entry<String, String> comment : comments.entrySet()) {
article.addComment(comment.getKey(), comment.getValue());
}
return article;
}
}
73 changes: 73 additions & 0 deletions exercise/day16/src/test/java/blog/ArticleTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package blog;

import org.assertj.core.api.ThrowingConsumer;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.function.Function;

import static blog.ArticleBuilder.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.instancio.Instancio.create;

class ArticleTests {
private Article article;

@Test
void should_add_comment_in_an_article() throws CommentAlreadyExistException {
when(article -> article.addComment(COMMENT_TEXT, AUTHOR));
then(article -> {
assertThat(article.getComments()).hasSize(1);
assertComment(article.getComments().get(0), COMMENT_TEXT, AUTHOR);
});
}

@Test
void should_add_comment_in_an_article_containing_already_a_comment() throws Throwable {
final var newComment = create(String.class);
final var newAuthor = create(String.class);

when(ArticleBuilder::commented, article -> article.addComment(newComment, newAuthor));
then(article -> {
assertThat(article.getComments()).hasSize(2);
assertComment(article.getComments().getLast(), newComment, newAuthor);
});
}

@Nested
class Fail {
@Test
void when__adding_an_existing_comment() throws CommentAlreadyExistException {
var article = anArticle()
.commented()
.build();

assertThatThrownBy(() -> {
article.addComment(article.getComments().get(0).text(), article.getComments().get(0).author());
}).isInstanceOf(CommentAlreadyExistException.class);
}
}

private static void assertComment(Comment comment, String commentText, String author) {
assertThat(comment.text()).isEqualTo(commentText);
assertThat(comment.author()).isEqualTo(author);
}

private void when(ArticleBuilder articleBuilder, ThrowingConsumer<Article> act) throws CommentAlreadyExistException {
article = articleBuilder.build();
act.accept(article);
}

private void when(ThrowingConsumer<Article> act) throws CommentAlreadyExistException {
when(anArticle(), act);
}

private void when(Function<ArticleBuilder, ArticleBuilder> options, ThrowingConsumer<Article> act) throws Throwable {
when(options.apply(anArticle()), act);
}

private void then(ThrowingConsumer<Article> act) {
act.accept(article);
}
}
1 change: 1 addition & 0 deletions exercise/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<module>day13</module>
<module>day14</module>
<module>day15</module>
<module>day16</module>
</modules>

<properties>
Expand Down

0 comments on commit c5fe181

Please sign in to comment.