Commit b678b080 authored by Colin DAMON's avatar Colin DAMON

Greenfield tennis 2

parent c80310c8
......@@ -31,3 +31,4 @@ include:
- local: "/java-concurrence/.gitlab-ci.yml"
- local: "/tennis/refactoring/.gitlab-ci.yml"
- local: "/bowling-game/.gitlab-ci.yml"
- local: "/tennis/greenfield-2/.gitlab-ci.yml"
package-greenfield-tennis-2:
variables:
PROJECT_FOLDER: "tennis/greenfield-2"
extends: .java
only:
refs:
- master
- merge_requests
changes:
- ".gitlab-common-ci.yml"
- "tennis/greenfield-2/**/*"
<?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>tennis-grennfield-2</artifactId>
<name>TennisGreenField2</name>
<developers>
<developer>
<email>msauboua@ippon.fr</email>
<name>Matthieu SAUBOUA-BENELUZ</name>
</developer>
<developer>
<email>cdamon@ippon.fr</email>
<name>Colin DAMON</name>
</developer>
</developers>
</project>
# Greenfield tennis seconde tentative
Seconde tentative de résolution en greenfield du tennis kata que nous avons échoué avec succès !
- **Auteurs** : Matthieu SAUBOUA-BENELUZ et Colin DAMON
- **Date** : 08/04/2021
- **Langage** : Java
- **Niveau** : Moyen
- **Replay** : TODO
package fr.ippon.tennis;
public class Game {
private static final String STARTING_DISPLAY = "LOVE - ALL";
private static final String SEPARATOR = " - ";
private Score playerOne = Score.LOVE;
private Score playerTwo = Score.LOVE;
public void playerOneScores() {
if (playerOne == Score.FOURTY && playerTwo == Score.ENDING) {
thisIsADeuce();
} else {
playerOne = playerOne.scores();
}
}
public void playerTwoScores() {
if (playerOne == Score.ENDING && playerTwo == Score.FOURTY) {
thisIsADeuce();
} else {
playerTwo = playerTwo.scores();
}
}
private void thisIsADeuce() {
playerOne = Score.FOURTY;
playerTwo = Score.FOURTY;
}
public String score() {
if (playerHasScored()) {
return displayScore();
}
return STARTING_DISPLAY;
}
private String displayScore() {
if (playerOne == Score.ENDING && playerTwo == Score.FOURTY) {
return "ADVANTAGE PLAYER 1";
}
if (playerTwo == Score.ENDING && playerOne == Score.FOURTY) {
return "ADVANTAGE PLAYER 2";
}
if (playerOne == Score.ENDING) {
return "GAME PLAYER 1";
}
if (playerTwo == Score.ENDING) {
return "GAME PLAYER 2";
}
if (equality()) {
return equalityDisplay();
}
return playerOne.display() + SEPARATOR + playerTwo.display();
}
private boolean equality() {
return playerOne == playerTwo;
}
private String equalityDisplay() {
if (playerOne == Score.FOURTY) {
return "DEUCE";
}
return playerOne.display() + SEPARATOR + "ALL";
}
private boolean playerHasScored() {
return playerOne.hasScored() || playerTwo.hasScored();
}
}
package fr.ippon.tennis;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public enum Score {
LOVE(0, "0"), //
FIFTEEN(1, "15"), //
THIRTY(2, "30"), //
FOURTY(3, "40"), //
ENDING(4, "GAME");
private static final Map<Integer, Score> SCORES = buildScores();
private final int index;
private final String display;
Score(int index, String display) {
this.index = index;
this.display = display;
}
private static Map<Integer, Score> buildScores() {
return Arrays.stream(values()).collect(Collectors.toMap(Score::index, Function.identity()));
}
private int index() {
return index;
}
Score scores() {
return Score.of(index + 1);
}
private static Score of(int index) {
return SCORES.getOrDefault(index, ENDING);
}
boolean hasScored() {
return this != LOVE;
}
String display() {
return display;
}
}
package fr.ippon.tennis;
import static org.assertj.core.api.Assertions.*;
import java.util.stream.IntStream;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
class GameTest {
private final Game game = new Game();
@Test
void shouldStartAtLoveAll() {
assertThat(game.score()).isEqualTo("LOVE - ALL");
}
@Test
void playerOneScoresFirstPoint() {
game.playerOneScores();
assertThat(game.score()).isEqualTo("15 - 0");
}
@Test
void playerOneScoresTwoPoints() {
playerOneScores(2);
assertThat(game.score()).isEqualTo("30 - 0");
}
@Test
void playerOneScoresThreePoints() {
playerOneScores(3);
assertThat(game.score()).isEqualTo("40 - 0");
}
@Test
void playerTwoScoreFirstPoint() {
game.playerTwoScores();
assertThat(game.score()).isEqualTo("0 - 15");
}
@Test
void playerOneAndTwoScoresFirstPoint() {
game.playerOneScores();
game.playerTwoScores();
assertThat(game.score()).isEqualTo("15 - ALL");
}
@Test
void shouldHaveDeuce() {
deuce();
assertThat(game.score()).isEqualTo("DEUCE");
}
@Test
void playerOneShouldHaveAdvantage() {
deuce();
game.playerOneScores();
assertThat(game.score()).isEqualTo("ADVANTAGE PLAYER 1");
}
@Test
void playerTwoShouldHaveAdvantage() {
deuce();
game.playerTwoScores();
assertThat(game.score()).isEqualTo("ADVANTAGE PLAYER 2");
}
@Test
void playerTwoShouldComeBackToDeuce() {
deuce();
game.playerOneScores();
game.playerTwoScores();
assertThat(game.score()).isEqualTo("DEUCE");
}
@Test
void playerOneShouldComeBackToDeuce() {
deuce();
game.playerTwoScores();
game.playerOneScores();
assertThat(game.score()).isEqualTo("DEUCE");
}
@Test
void playerOneShouldWinGame() {
playerOneScores(4);
assertThat(game.score()).isEqualTo("GAME PLAYER 1");
}
@Test
void playerTwoShouldWinGame() {
playerTwoScores(4);
assertThat(game.score()).isEqualTo("GAME PLAYER 2");
}
@Test
@Disabled("This is the test proving that we where wrong from the beginning!")
void playerOneShouldWinAfterAdvantage() {
deuce();
game.playerOneScores();
game.playerOneScores();
assertThat(game.score()).isEqualTo("GAME PLAYER 1");
}
private void deuce() {
playerOneScores(3);
playerTwoScores(3);
}
private void playerOneScores(int times) {
IntStream.range(0, times).forEach(d -> game.playerOneScores());
}
private void playerTwoScores(int times) {
IntStream.range(0, times).forEach(d -> game.playerTwoScores());
}
}
# Tennis coding and refactoring katas
- [refactoring](refactoring)
- [Greenfield attempt 2](greenfield-2)
This katas is inspired and uses starting code
from [this great github repository](https://github.com/emilybache/Tennis-Refactoring-Kata) from Emily Bache
......@@ -44,11 +47,11 @@ book, ["The Coding Dojo Handbook"](https://leanpub.com/codingdojohandbook)
## Questions to discuss afterwards
* How did it feel to work with such fast, comprehensive tests?
* Did you make mistakes while refactoring that were caught by the tests?
* If you used a tool to record your test runs, review it. Could you have taken smaller steps? Made fewer refactoring
mistakes?
* Did you ever make any refactoring mistakes and then back out your changes? How did it feel to throw away code?
* What would you say to your colleague if they had written this code?
* What would you say to your boss about the value of this refactoring work? Was there more reason to do it over and
above the extra billable hour or so?
- How did it feel to work with such fast, comprehensive tests?
- Did you make mistakes while refactoring that were caught by the tests?
- If you used a tool to record your test runs, review it. Could you have taken smaller steps? Made fewer refactoring
mistakes?
- Did you ever make any refactoring mistakes and then back out your changes? How did it feel to throw away code?
- What would you say to your colleague if they had written this code?
- What would you say to your boss about the value of this refactoring work? Was there more reason to do it over and
above the extra billable hour or so?
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment