Skip to content
Snippets Groups Projects
Commit 69ebe58e authored by Colin DAMON's avatar Colin DAMON
Browse files

Merge branch '19-gidedrose' into 'master'

Resolve "GidedRose"

Closes #19

See merge request !16
parents 6e5cab8e 5934e9d4
No related branches found
No related tags found
1 merge request!16Resolve "GidedRose"
...@@ -6,3 +6,4 @@ include: ...@@ -6,3 +6,4 @@ include:
- local: "/word-wrap/.gitlab-ci.yml" - local: "/word-wrap/.gitlab-ci.yml"
- local: "/roman-numerals/.gitlab-ci.yml" - local: "/roman-numerals/.gitlab-ci.yml"
- local: "/string-calculator/.gitlab-ci.yml" - local: "/string-calculator/.gitlab-ci.yml"
- local: "/gilded-rose/.gitlab-ci.yml"
package-gilded-rose:
variables:
PROJECT_FOLDER: "gilded-rose"
extends: .java
only:
refs:
- master
- merge_requests
changes:
- ".gitlab-ci.yml"
- ".gitlab-common-ci.yml"
- "gilded-rose/**/*"
<?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>gilded-rose</artifactId>
<name>GildedRose</name>
<developers>
<developer>
<email>cdamon@ippon.fr</email>
<name>Colin DAMON</name>
</developer>
</developers>
</project>
# Gilded Rose
Résolution préparée du kata [GildedRose](https://github.com/emilybache/GildedRose-Refactoring-Kata).
- **Auteur** : Colin DAMON
- **Date** : 12:08/2020
- **Langage** : Java
- **Niveau** : Enervé
- **Replay** : [twitch (temporaire)](https://www.twitch.tv/videos/707923490)
# Spécification de la Rose dorée (Gilded Rose)
Bonjour et bienvenue dans l'équipe de la Rose dorée.
Comme vous le savez, notre petite taverne située à proximité d'une cité importante est dirigée par l'amicale aubergiste Allison.
Nous achetons et vendons uniquement les meilleurs produits.
Malheureusement, la qualité de nos marchandises se dégrade constamment à l'approche de leur date de péremption.
Un système a été mis en place pour mettre à jour notre inventaire.
Il a été développé par Leeroy, une personne pleine de bon sens qui est parti pour de nouvelles aventures.
Votre mission est d'ajouter une nouvelle fonctionnalité à notre système pour que nous puissions commencer à vendre un nouveau type de produit.
Mais d'abord, laissez-moi vous présenter notre système :
- Tous les éléments ont une valeur `sellIn` qui désigne le nombre de jours restant pour vendre l'article.
- Tous les articles ont une valeur `quality` qui dénote combien l'article est précieux.
- A la fin de chaque journée, notre système diminue ces deux valeurs pour chaque produit.
Plutôt simple, non ?
Attendez, ça devient intéressant :
- Une fois que la date de péremption est passée, la qualité se dégrade deux fois plus rapidement.
- La qualité (`quality`) d'un produit ne peut jamais être négative.
- "Aged Brie" augmente sa qualité (`quality`) plus le temps passe.
- La qualité d'un produit n'est jamais de plus de 50.
- "Sulfuras", étant un objet légendaire, n'a pas de date de péremption et ne perd jamais en qualité (`quality`)
- "Backstage passes", comme le "Aged Brie", augmente sa qualité (`quality`) plus le temps passe (`sellIn`) ; La qualité augmente de 2 quand il reste 10 jours ou moins et de 3 quand il reste 5 jours ou moins, mais la qualité tombe à 0 après le concert.
Nous avons récemment signé un partenariat avec un fournisseur de produit invoqué ("Conjured").
Cela nécessite une mise à jour de notre système :
- les éléments "Conjured" voient leur qualité se dégrader de deux fois plus vite que les objets normaux.
Vous pouvez faire les changements que vous voulez à la méthode `updateQuality` et ajouter autant de code que vous voulez, tant que tout fonctionne correctement.
Cependant, nous devons vous prévenir, ne devez modifier en aucun cas la classe `Item` ou ses propriétés car cette classe appartient au gobelin de l'étage et il rentrera dans du rage instantanée et vous tuera sans délai : il ne croit pas dans le partage du code.
(Vous pouvez ajouter une méthode `updateQuality` et des propriétés statiques dans la classe `Item` si vous voulez, nous vous couvrirons)
Juste une précision, un produit ne peut jamais voir sa qualité augmenter au-dessus de 50, cependant "Sulfuras" est un objet légendaire et comme tel sa qualité est de 80 et il ne change jamais.
package com.gildedrose;
class GildedRose {
private static final String SULFURAS_NAME = "Sulfuras, Hand of Ragnaros";
private static final String BACKSTAGE_PASSES_NAME = "Backstage passes to a TAFKAL80ETC concert";
private static final String AGED_BRIE_NAME = "Aged Brie";
Item[] items;
public GildedRose(Item[] items) {
this.items = items;
}
public void updateQuality() {
for (Item item : items) {
if (SULFURAS_NAME.equals(item.name)) {
continue;
}
item.sellIn = item.sellIn - 1;
if (AGED_BRIE_NAME.equals(item.name)) {
updateAgedBrie(item);
} else if (BACKSTAGE_PASSES_NAME.equals(item.name)) {
updateBackstagePass(item);
} else {
updateNormalItem(item);
}
}
}
private void updateAgedBrie(Item item) {
increaseQuality(item);
if (item.sellIn < 0) {
increaseQuality(item);
}
}
private void updateBackstagePass(Item item) {
increaseQuality(item);
if (item.sellIn < 10) {
increaseQuality(item);
}
if (item.sellIn < 5) {
increaseQuality(item);
}
if (item.sellIn < 0) {
item.quality = 0;
}
}
private void updateNormalItem(Item item) {
decreaseQuality(item);
if (item.sellIn < 0) {
decreaseQuality(item);
}
}
private void increaseQuality(Item item) {
if (item.quality < 50) {
item.quality = item.quality + 1;
}
}
private void decreaseQuality(Item item) {
if (item.quality > 0) {
item.quality = item.quality - 1;
}
}
}
package com.gildedrose;
public class Item {
public String name;
public int sellIn;
public int quality;
public Item(String name, int sellIn, int quality) {
this.name = name;
this.sellIn = sellIn;
this.quality = quality;
}
@Override
public String toString() {
return this.name + ", " + this.sellIn + ", " + this.quality;
}
}
package com.gildedrose;
class GildedRoseGolden {
Item[] items;
public GildedRoseGolden(Item[] items) {
this.items = items;
}
public void updateQuality() {
for (int i = 0; i < items.length; i++) {
if (!items[i].name.equals("Aged Brie") && !items[i].name.equals("Backstage passes to a TAFKAL80ETC concert")) {
if (items[i].quality > 0) {
if (!items[i].name.equals("Sulfuras, Hand of Ragnaros")) {
items[i].quality = items[i].quality - 1;
}
}
} else {
if (items[i].quality < 50) {
items[i].quality = items[i].quality + 1;
if (items[i].name.equals("Backstage passes to a TAFKAL80ETC concert")) {
if (items[i].sellIn < 11) {
if (items[i].quality < 50) {
items[i].quality = items[i].quality + 1;
}
}
if (items[i].sellIn < 6) {
if (items[i].quality < 50) {
items[i].quality = items[i].quality + 1;
}
}
}
}
}
if (!items[i].name.equals("Sulfuras, Hand of Ragnaros")) {
items[i].sellIn = items[i].sellIn - 1;
}
if (items[i].sellIn < 0) {
if (!items[i].name.equals("Aged Brie")) {
if (!items[i].name.equals("Backstage passes to a TAFKAL80ETC concert")) {
if (items[i].quality > 0) {
if (!items[i].name.equals("Sulfuras, Hand of Ragnaros")) {
items[i].quality = items[i].quality - 1;
}
}
} else {
items[i].quality = items[i].quality - items[i].quality;
}
} else {
if (items[i].quality < 50) {
items[i].quality = items[i].quality + 1;
}
}
}
}
}
}
package com.gildedrose;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
class GildedRoseTest {
@Test
void shouldUpdateForOneDay() {
GildedRose rose = new GildedRose(ItemsProvider.get());
rose.updateQuality();
assertThat(rose.items).extracting(item -> item.sellIn).containsExactly(9, 1, 4, 0, -1, 14, 9, 4);
assertThat(rose.items).extracting(item -> item.quality).containsExactly(19, 1, 6, 80, 80, 21, 50, 50);
}
@Test
void shouldUpdateForTwoDays() {
GildedRose rose = new GildedRose(ItemsProvider.get());
rose.updateQuality();
rose.updateQuality();
assertThat(rose.items).extracting(item -> item.sellIn).containsExactly(8, 0, 3, 0, -1, 13, 8, 3);
assertThat(rose.items).extracting(item -> item.quality).containsExactly(18, 2, 5, 80, 80, 22, 50, 50);
}
@Test
void shouldBehaveLikeGoldenMaster() {
GildedRose rose = new GildedRose(ItemsProvider.get());
GildedRoseGolden golden = new GildedRoseGolden(ItemsProvider.get());
for (int day = 0; day < 100; day++) {
rose.updateQuality();
golden.updateQuality();
assertThat(rose.items)
.extracting(item -> item.sellIn)
.containsExactly(Arrays.stream(golden.items).map(item -> item.sellIn).toArray(Integer[]::new));
assertThat(rose.items)
.extracting(item -> item.quality)
.containsExactly(Arrays.stream(golden.items).map(item -> item.quality).toArray(Integer[]::new));
}
}
}
package com.gildedrose;
public final class ItemsProvider {
static Item[] get() {
Item[] items = new Item[] {
new Item("+5 Dexterity Vest", 10, 20),
new Item("Aged Brie", 2, 0),
new Item("Elixir of the Mongoose", 5, 7),
new Item("Sulfuras, Hand of Ragnaros", 0, 80),
new Item("Sulfuras, Hand of Ragnaros", -1, 80),
new Item("Backstage passes to a TAFKAL80ETC concert", 15, 20),
new Item("Backstage passes to a TAFKAL80ETC concert", 10, 49),
new Item("Backstage passes to a TAFKAL80ETC concert", 5, 49)
};
return items;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment