From 753ee91bb641c24f7e154f54c5a9b35e5b25b502 Mon Sep 17 00:00:00 2001 From: Colin DAMON <cdamon@ippon.fr> Date: Fri, 29 Jan 2021 19:40:41 +0100 Subject: [PATCH] Kata resolution --- .../java/fr/ippon/rental/ChildrensMovie.java | 16 +++++ .../java/fr/ippon/rental/ConsoleRenderer.java | 26 ++++++++ .../main/java/fr/ippon/rental/Customer.java | 63 +++++++------------ .../java/fr/ippon/rental/HtmlRenderer.java | 26 ++++++++ .../src/main/java/fr/ippon/rental/Movie.java | 26 +++----- .../src/main/java/fr/ippon/rental/Movies.java | 16 +++++ .../java/fr/ippon/rental/NewReleaseMovie.java | 17 +++++ .../java/fr/ippon/rental/RegularMovie.java | 16 +++++ .../main/java/fr/ippon/rental/Renderer.java | 9 +++ .../src/main/java/fr/ippon/rental/Rental.java | 24 +++++-- .../java/fr/ippon/rental/CustomerTest.java | 43 ++++++++++--- 11 files changed, 209 insertions(+), 73 deletions(-) create mode 100644 movie-rental/src/main/java/fr/ippon/rental/ChildrensMovie.java create mode 100644 movie-rental/src/main/java/fr/ippon/rental/ConsoleRenderer.java create mode 100644 movie-rental/src/main/java/fr/ippon/rental/HtmlRenderer.java create mode 100644 movie-rental/src/main/java/fr/ippon/rental/Movies.java create mode 100644 movie-rental/src/main/java/fr/ippon/rental/NewReleaseMovie.java create mode 100644 movie-rental/src/main/java/fr/ippon/rental/RegularMovie.java create mode 100644 movie-rental/src/main/java/fr/ippon/rental/Renderer.java diff --git a/movie-rental/src/main/java/fr/ippon/rental/ChildrensMovie.java b/movie-rental/src/main/java/fr/ippon/rental/ChildrensMovie.java new file mode 100644 index 00000000..e22bc1e1 --- /dev/null +++ b/movie-rental/src/main/java/fr/ippon/rental/ChildrensMovie.java @@ -0,0 +1,16 @@ +package fr.ippon.rental; + +public class ChildrensMovie extends Movie { + + public ChildrensMovie(String title) { + super(title); + } + + public double getAmount(int daysRented) { + if (daysRented > 3) { + return 1.5 + (daysRented - 3) * 1.5; + } + + return 1.5; + } +} diff --git a/movie-rental/src/main/java/fr/ippon/rental/ConsoleRenderer.java b/movie-rental/src/main/java/fr/ippon/rental/ConsoleRenderer.java new file mode 100644 index 00000000..2417fb2d --- /dev/null +++ b/movie-rental/src/main/java/fr/ippon/rental/ConsoleRenderer.java @@ -0,0 +1,26 @@ +package fr.ippon.rental; + +public class ConsoleRenderer implements Renderer { + + @Override + public String header(String name) { + return "Rental Record for " + name + "\n"; + } + + @Override + public String movie(Rental rental, double amount) { + return "\t" + rental.getMovie().getTitle() + "\t" + String.valueOf(amount) + "\n"; + } + + @Override + public String footer(double totalAmount, int frequentRenterPoints) { + return new StringBuilder() + .append("Amount owed is ") + .append(totalAmount) + .append("\n") + .append("You earned ") + .append(frequentRenterPoints) + .append(" frequent renter points") + .toString(); + } +} diff --git a/movie-rental/src/main/java/fr/ippon/rental/Customer.java b/movie-rental/src/main/java/fr/ippon/rental/Customer.java index bfe16efc..39fc4e02 100644 --- a/movie-rental/src/main/java/fr/ippon/rental/Customer.java +++ b/movie-rental/src/main/java/fr/ippon/rental/Customer.java @@ -4,59 +4,42 @@ import java.util.ArrayList; import java.util.List; public class Customer { - private String _name; - private List<Rental> _rentals = new ArrayList<Rental>(); + private final String name; + private final List<Rental> rentals = new ArrayList<Rental>(); public Customer(String name) { - _name = name; + this.name = name; } public void addRental(Rental arg) { - _rentals.add(arg); + rentals.add(arg); } public String getName() { - return _name; + return name; } - public String statement() { + public String statement(Renderer renderer) { + StringBuilder result = new StringBuilder(renderer.header(name)); + double totalAmount = 0; - int frequentRenterPoints = 0; - String result = "Rental Record for " + getName() + "\n"; - - for (Rental each : _rentals) { - double thisAmount = 0; - - //determine amounts for each line - switch (each.getMovie().getPriceCode()) { - case Movie.REGULAR: - thisAmount += 2; - if (each.getDaysRented() > 2) thisAmount += (each.getDaysRented() - 2) * 1.5; - break; - case Movie.NEW_RELEASE: - thisAmount += each.getDaysRented() * 3; - break; - case Movie.CHILDRENS: - thisAmount += 1.5; - if (each.getDaysRented() > 3) thisAmount += (each.getDaysRented() - 3) * 1.5; - break; - } - - // add frequent renter points - frequentRenterPoints++; - - // add bonus for a two day new release rental - if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDaysRented() > 1) frequentRenterPoints++; - - // show figures for this rental - result += "\t" + each.getMovie().getTitle() + "\t" + String.valueOf(thisAmount) + "\n"; - totalAmount += thisAmount; + for (Rental rental : rentals) { + double amount = calculateAmount(rental); + + result.append(renderer.movie(rental, amount)); + totalAmount += amount; } - // add footer lines - result += "Amount owed is " + String.valueOf(totalAmount) + "\n"; - result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; + result.append(renderer.footer(totalAmount, calculateFrequentRenterPoints())); + + return result.toString(); + } + + private int calculateFrequentRenterPoints() { + return rentals.stream().mapToInt(Rental::getRenterPoints).sum(); + } - return result; + private double calculateAmount(Rental rental) { + return rental.amount(); } } diff --git a/movie-rental/src/main/java/fr/ippon/rental/HtmlRenderer.java b/movie-rental/src/main/java/fr/ippon/rental/HtmlRenderer.java new file mode 100644 index 00000000..71e69168 --- /dev/null +++ b/movie-rental/src/main/java/fr/ippon/rental/HtmlRenderer.java @@ -0,0 +1,26 @@ +package fr.ippon.rental; + +public class HtmlRenderer implements Renderer { + + @Override + public String header(String name) { + return "<h1>Rental Record for " + name + "</h1>\n<table>"; + } + + @Override + public String movie(Rental rental, double amount) { + return "<tr><td>" + rental.getMovie().getTitle() + "</td><td>" + String.valueOf(amount) + "</td></tr>\n"; + } + + @Override + public String footer(double totalAmount, int frequentRenterPoints) { + return new StringBuilder() + .append("</table><p>Amount owed is <em>") + .append(totalAmount) + .append("</em></p>\n") + .append("<p>You earned <em>") + .append(frequentRenterPoints) + .append("</em> frequent renter points</p>") + .toString(); + } +} diff --git a/movie-rental/src/main/java/fr/ippon/rental/Movie.java b/movie-rental/src/main/java/fr/ippon/rental/Movie.java index 6727cb4b..e545ba30 100644 --- a/movie-rental/src/main/java/fr/ippon/rental/Movie.java +++ b/movie-rental/src/main/java/fr/ippon/rental/Movie.java @@ -1,27 +1,19 @@ package fr.ippon.rental; -public class Movie { - public static final int CHILDRENS = 2; - public static final int NEW_RELEASE = 1; - public static final int REGULAR = 0; +public abstract class Movie { + private final String title; - private String _title; - private int _priceCode; - - public Movie(String title, int priceCode) { - _title = title; - _priceCode = priceCode; + public Movie(String title) { + this.title = title; } - public int getPriceCode() { - return _priceCode; + public String getTitle() { + return title; } - public void setPriceCode(int arg) { - _priceCode = arg; - } + public abstract double getAmount(int daysRented); - public String getTitle() { - return _title; + public boolean isNewRelease() { + return false; } } diff --git a/movie-rental/src/main/java/fr/ippon/rental/Movies.java b/movie-rental/src/main/java/fr/ippon/rental/Movies.java new file mode 100644 index 00000000..b9767585 --- /dev/null +++ b/movie-rental/src/main/java/fr/ippon/rental/Movies.java @@ -0,0 +1,16 @@ +package fr.ippon.rental; + +public class Movies { + + public static Movie regular(String title) { + return new RegularMovie(title); + } + + public static Movie newRelease(String title) { + return new NewReleaseMovie(title); + } + + public static Movie childrens(String title) { + return new ChildrensMovie(title); + } +} diff --git a/movie-rental/src/main/java/fr/ippon/rental/NewReleaseMovie.java b/movie-rental/src/main/java/fr/ippon/rental/NewReleaseMovie.java new file mode 100644 index 00000000..6f3e6c0d --- /dev/null +++ b/movie-rental/src/main/java/fr/ippon/rental/NewReleaseMovie.java @@ -0,0 +1,17 @@ +package fr.ippon.rental; + +public class NewReleaseMovie extends Movie { + + public NewReleaseMovie(String title) { + super(title); + } + + public double getAmount(int daysRented) { + return daysRented * 3; + } + + @Override + public boolean isNewRelease() { + return true; + } +} diff --git a/movie-rental/src/main/java/fr/ippon/rental/RegularMovie.java b/movie-rental/src/main/java/fr/ippon/rental/RegularMovie.java new file mode 100644 index 00000000..1db4e079 --- /dev/null +++ b/movie-rental/src/main/java/fr/ippon/rental/RegularMovie.java @@ -0,0 +1,16 @@ +package fr.ippon.rental; + +public class RegularMovie extends Movie { + + public RegularMovie(String title) { + super(title); + } + + public double getAmount(int daysRented) { + if (daysRented > 2) { + return 2 + (daysRented - 2) * 1.5; + } + + return 2; + } +} diff --git a/movie-rental/src/main/java/fr/ippon/rental/Renderer.java b/movie-rental/src/main/java/fr/ippon/rental/Renderer.java new file mode 100644 index 00000000..28898108 --- /dev/null +++ b/movie-rental/src/main/java/fr/ippon/rental/Renderer.java @@ -0,0 +1,9 @@ +package fr.ippon.rental; + +public interface Renderer { + String header(String name); + + String movie(Rental rental, double amount); + + String footer(double totalAmount, int frequentRenterPoints); +} diff --git a/movie-rental/src/main/java/fr/ippon/rental/Rental.java b/movie-rental/src/main/java/fr/ippon/rental/Rental.java index d0188617..b7938892 100644 --- a/movie-rental/src/main/java/fr/ippon/rental/Rental.java +++ b/movie-rental/src/main/java/fr/ippon/rental/Rental.java @@ -4,19 +4,31 @@ package fr.ippon.rental; * The rental class represents a customer renting a movie. */ public class Rental { - private Movie _movie; - private int _daysRented; + private final Movie movie; + private final int daysRented; public Rental(Movie movie, int daysRented) { - _movie = movie; - _daysRented = daysRented; + this.movie = movie; + this.daysRented = daysRented; } public int getDaysRented() { - return _daysRented; + return daysRented; } public Movie getMovie() { - return _movie; + return movie; + } + + public int getRenterPoints() { + if (movie.isNewRelease() && daysRented > 1) { + return 2; + } + + return 1; + } + + public double amount() { + return movie.getAmount(daysRented); } } diff --git a/movie-rental/src/test/java/fr/ippon/rental/CustomerTest.java b/movie-rental/src/test/java/fr/ippon/rental/CustomerTest.java index ca193508..7b78d858 100644 --- a/movie-rental/src/test/java/fr/ippon/rental/CustomerTest.java +++ b/movie-rental/src/test/java/fr/ippon/rental/CustomerTest.java @@ -1,5 +1,6 @@ package fr.ippon.rental; +import static fr.ippon.rental.Movies.*; import static org.assertj.core.api.Assertions.*; import org.junit.jupiter.api.Test; @@ -7,15 +8,7 @@ import org.junit.jupiter.api.Test; public class CustomerTest { @Test - public void test() { - Customer customer = new Customer("Bob"); - customer.addRental(new Rental(new Movie("Jaws", Movie.REGULAR), 2)); - customer.addRental(new Rental(new Movie("Golden Eye", Movie.REGULAR), 3)); - customer.addRental(new Rental(new Movie("Short New", Movie.NEW_RELEASE), 1)); - customer.addRental(new Rental(new Movie("Long New", Movie.NEW_RELEASE), 2)); - customer.addRental(new Rental(new Movie("Bambi", Movie.CHILDRENS), 3)); - customer.addRental(new Rental(new Movie("Toy Story", Movie.CHILDRENS), 4)); - + public void shouldRenderConsole() { String expected = "" + "Rental Record for Bob\n" + @@ -28,6 +21,36 @@ public class CustomerTest { "Amount owed is 19.0\n" + "You earned 7 frequent renter points"; - assertThat(customer.statement()).isEqualTo(expected); + assertThat(customer().statement(new ConsoleRenderer())).isEqualTo(expected); + } + + @Test + void shouldRenderHtml() { + String expected = + "" + + "<h1>Rental Record for Bob</h1>\n" + + "<table>" + + "<tr><td>Jaws</td><td>2.0</td></tr>\n" + + "<tr><td>Golden Eye</td><td>3.5</td></tr>\n" + + "<tr><td>Short New</td><td>3.0</td></tr>\n" + + "<tr><td>Long New</td><td>6.0</td></tr>\n" + + "<tr><td>Bambi</td><td>1.5</td></tr>\n" + + "<tr><td>Toy Story</td><td>3.0</td></tr>\n" + + "</table>" + + "<p>Amount owed is <em>19.0</em></p>\n" + + "<p>You earned <em>7</em> frequent renter points</p>"; + + assertThat(customer().statement(new HtmlRenderer())).isEqualTo(expected); + } + + private Customer customer() { + Customer customer = new Customer("Bob"); + customer.addRental(new Rental(regular("Jaws"), 2)); + customer.addRental(new Rental(regular("Golden Eye"), 3)); + customer.addRental(new Rental(newRelease("Short New"), 1)); + customer.addRental(new Rental(newRelease("Long New"), 2)); + customer.addRental(new Rental(childrens("Bambi"), 3)); + customer.addRental(new Rental(childrens("Toy Story"), 4)); + return customer; } } -- GitLab