From 28b8fb901ab44fe4ee77fcb2b946c54bc44684e2 Mon Sep 17 00:00:00 2001
From: Colin DAMON <cdamon@ippon.fr>
Date: Wed, 13 Oct 2021 18:27:17 +0200
Subject: [PATCH] Employee report 2

---
 .gitlab-ci.yml                                |  1 +
 employee-report-2/.gitlab-ci.yml              | 11 ++++++
 employee-report-2/pom.xml                     | 29 ++++++++++++++
 employee-report-2/readme.md                   |  9 +++++
 .../main/java/fr/ippon/employee/Employee.java | 39 +++++++++++++++++++
 .../java/fr/ippon/employee/Employees.java     | 27 +++++++++++++
 .../fr/ippon/employee/EmployeeReportTest.java | 37 ++++++++++++++++++
 .../java/fr/ippon/employee/EmployeeTest.java  | 30 ++++++++++++++
 readme.md                                     |  1 +
 9 files changed, 184 insertions(+)
 create mode 100644 employee-report-2/.gitlab-ci.yml
 create mode 100644 employee-report-2/pom.xml
 create mode 100644 employee-report-2/readme.md
 create mode 100644 employee-report-2/src/main/java/fr/ippon/employee/Employee.java
 create mode 100644 employee-report-2/src/main/java/fr/ippon/employee/Employees.java
 create mode 100644 employee-report-2/src/test/java/fr/ippon/employee/EmployeeReportTest.java
 create mode 100644 employee-report-2/src/test/java/fr/ippon/employee/EmployeeTest.java

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index dd665353..9e8543f8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -42,3 +42,4 @@ include:
   - local: "/java-memoizers/.gitlab-ci.yml"
   - local: "/markov-chain/.gitlab-ci.yml"
   - local: "/names/.gitlab-ci.yml"
+  - local: "/employee-report-2/.gitlab-ci.yml"
diff --git a/employee-report-2/.gitlab-ci.yml b/employee-report-2/.gitlab-ci.yml
new file mode 100644
index 00000000..d5bc9b43
--- /dev/null
+++ b/employee-report-2/.gitlab-ci.yml
@@ -0,0 +1,11 @@
+package-employee-report-2:
+  variables:
+    PROJECT_FOLDER: "employee-report-2"
+  extends: .java
+  only:
+    refs:
+      - master
+      - merge_requests
+    changes:
+      - ".gitlab-common-ci.yml"
+      - "employee-report-2/**/*"
diff --git a/employee-report-2/pom.xml b/employee-report-2/pom.xml
new file mode 100644
index 00000000..aaf29090
--- /dev/null
+++ b/employee-report-2/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  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>
+    <version>1.0.0</version>
+    <groupId>fr.ippon.kata</groupId>
+    <artifactId>java-parent</artifactId>
+    <relativePath>../java-parent</relativePath>
+  </parent>
+
+  <version>1.0.0-SNAPSHOT</version>
+  <artifactId>employee-report-2</artifactId>
+
+  <name>EmployeeReport2</name>
+
+  <developers>
+    <developer>
+      <email>kgrammont@ippon.fr</email>
+      <name>Ketil GRAMMONT</name>
+    </developer>
+    <developer>
+      <email>cdamon@ippon.fr</email>
+      <name>Colin DAMON</name>
+    </developer>
+  </developers>
+</project>
diff --git a/employee-report-2/readme.md b/employee-report-2/readme.md
new file mode 100644
index 00000000..52685b5b
--- /dev/null
+++ b/employee-report-2/readme.md
@@ -0,0 +1,9 @@
+# Employee report
+
+Résolution en TDD et en Java du kata [EmployeeReport](https://codingdojo.org/kata/Employee-Report/).
+
+-   **Auteurs** : Ketil GRAMMONT et Colin DAMON
+-   **Date** : 13/10/2021
+-   **Langage** : Java
+-   **Niveau** : Facile
+-   **Replay** : [Twitch](https://www.twitch.tv/videos/1175612810)
diff --git a/employee-report-2/src/main/java/fr/ippon/employee/Employee.java b/employee-report-2/src/main/java/fr/ippon/employee/Employee.java
new file mode 100644
index 00000000..1b79f5d8
--- /dev/null
+++ b/employee-report-2/src/main/java/fr/ippon/employee/Employee.java
@@ -0,0 +1,39 @@
+package fr.ippon.employee;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public record Employee(String name, int age) {
+
+  private static Pattern NAME_PATTERN = Pattern
+      .compile("(\\p{L}+)(\\P{L}*)");
+
+  public Employee(String name, int age) {
+    this.name = format(name);
+    this.age = age;
+  }
+
+  private String format(String name) {
+    Matcher matcher = NAME_PATTERN.matcher(name);
+
+    StringBuilder result = new StringBuilder();
+    while (matcher.find()) {
+      result.append(capitalize(matcher.group(1)))
+          .append(matcher.group(2));
+    }
+
+    return result.toString();
+  }
+
+  private String capitalize(String word) {
+    return word.substring(0, 1)
+        .toUpperCase()
+        + word.substring(1, word.length())
+            .toLowerCase();
+  }
+
+  boolean isAdult() {
+    return age >= 18;
+  }
+
+}
diff --git a/employee-report-2/src/main/java/fr/ippon/employee/Employees.java b/employee-report-2/src/main/java/fr/ippon/employee/Employees.java
new file mode 100644
index 00000000..31b7d581
--- /dev/null
+++ b/employee-report-2/src/main/java/fr/ippon/employee/Employees.java
@@ -0,0 +1,27 @@
+package fr.ippon.employee;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+
+public class Employees {
+
+  private final List<Employee> employees;
+
+  public Employees(Employee... employees) {
+    this.employees = List.of(employees);
+  }
+
+  public Collection<Employee> get() {
+    return employees;
+  }
+
+  public Collection<String> sundayWorkers() {
+    return employees.stream()
+        .filter(Employee::isAdult)
+        .map(Employee::name)
+        .sorted(Comparator.reverseOrder())
+        .toList();
+  }
+
+}
diff --git a/employee-report-2/src/test/java/fr/ippon/employee/EmployeeReportTest.java b/employee-report-2/src/test/java/fr/ippon/employee/EmployeeReportTest.java
new file mode 100644
index 00000000..8b696535
--- /dev/null
+++ b/employee-report-2/src/test/java/fr/ippon/employee/EmployeeReportTest.java
@@ -0,0 +1,37 @@
+package fr.ippon.employee;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+class EmployeeReportTest {
+
+  @Test
+  void shouldGetEmployees() {
+    Employees employees = new Employees(mike());
+
+    assertThat(employees.get()).containsExactly(mike());
+  }
+
+  @Test
+  void shouldGetUnmodifiableEmployees() {
+    assertThatThrownBy(() -> new Employees().get()
+        .clear()).isExactlyInstanceOf(
+            UnsupportedOperationException.class);
+  }
+
+  @Test
+  void shouldGetSundayWorkers() {
+    Employees employees = new Employees(
+        new Employee("Max", 17), mike(),
+        new Employee("jean charles", 18));
+
+    assertThat(employees.sundayWorkers())
+        .containsExactly("Mike", "Jean Charles");
+  }
+
+  private Employee mike() {
+    return new Employee("MIKE", 51);
+  }
+
+}
diff --git a/employee-report-2/src/test/java/fr/ippon/employee/EmployeeTest.java b/employee-report-2/src/test/java/fr/ippon/employee/EmployeeTest.java
new file mode 100644
index 00000000..793b991e
--- /dev/null
+++ b/employee-report-2/src/test/java/fr/ippon/employee/EmployeeTest.java
@@ -0,0 +1,30 @@
+package fr.ippon.employee;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+class EmployeeTest {
+
+  @Test
+  void shouldCapitalizeSimpleName() {
+    Employee employee = new Employee("jeaN", 14);
+
+    assertThat(employee.name()).isEqualTo("Jean");
+  }
+
+  @Test
+  void shouldCapitalizeComposedName() {
+    Employee employee = new Employee("jean-charles", 14);
+
+    assertThat(employee.name()).isEqualTo("Jean-Charles");
+  }
+
+  @Test
+  void shouldCapitalizeComposedNameWithAccents() {
+    Employee employee = new Employee("jean jérémie", 14);
+
+    assertThat(employee.name()).isEqualTo("Jean Jérémie");
+  }
+
+}
diff --git a/readme.md b/readme.md
index fbf83144..de0fbc4d 100644
--- a/readme.md
+++ b/readme.md
@@ -27,6 +27,7 @@ Un kata de code est un petit exercice pensé pour s'entrainer jusqu'à maitriser
 -   [Fizz Buzz](/fizz-buzz)
 -   [Leap years](/leap-years)
 -   [Employee report](/employee-report)
+-   [Employee report 2](/employee-report-2)
 
 ### Moyen
 
-- 
GitLab