commit d6e078bf3d2823f40dc20f41ab6d6d2b8b77c0cc Author: Thomas Clavier Date: Thu Mar 8 13:40:27 2018 +0100 Initial commit diff --git a/README b/README new file mode 100644 index 0000000..6b57481 --- /dev/null +++ b/README @@ -0,0 +1,34 @@ +Movie Rental +=========== + +This source code follows Martin Fowler's book " Refactoring, Improving the Design of Existing Code". + +When you find you have to add a feature to a program, and the program's code is not +structured in a convenient way to add the feature, first refactor the program to make it +easy to add the feature, then add the feature. + +Whenever you do refactoring, the first step is always the same. +You need to build a solid set of tests for that section of code. The tests are essential because even +though you follow refactorings structured to avoid most of the opportunities for introducing bugs, +you are still human and still make mistakes. Thus you need solid tests. + +Usage +----- + +The purpose of this is to provide good examples for the refactoring workshop. + +Build +----- + +All you need to build this project is Java 6.0 (Java SDK 1.6) or later, Maven 3.0 or later. + +Testing +------- + +Unit tests can be run using maven[1]: + + $ mvn test + +[1]: http://maven.apache.org/ + +Tests are located in the test directory and run using Junit. diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..85d0850 --- /dev/null +++ b/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + com.refactoring + movie-rental + 0.1 + + + + junit + junit + 4.11 + test + + + + \ No newline at end of file diff --git a/src/main/java/movierental/Customer.java b/src/main/java/movierental/Customer.java new file mode 100644 index 0000000..6d9b9ea --- /dev/null +++ b/src/main/java/movierental/Customer.java @@ -0,0 +1,64 @@ +package movierental; +import java.util.ArrayList; +import java.util.List; + +public class Customer { + + private String _name; + private List _rentals = new ArrayList(); + + public Customer(String name) { + _name = name; + } + + public void addRental(Rental arg) { + _rentals.add(arg); + } + + public String getName() { + return _name; + } + + public String statement() { + 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; + } + + // add footer lines + result += "Amount owed is " + String.valueOf(totalAmount) + "\n"; + result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; + + return result; + } +} diff --git a/src/main/java/movierental/Movie.java b/src/main/java/movierental/Movie.java new file mode 100644 index 0000000..7e9c14c --- /dev/null +++ b/src/main/java/movierental/Movie.java @@ -0,0 +1,29 @@ +package movierental; + +public class Movie { + + public static final int CHILDRENS = 2; + public static final int NEW_RELEASE = 1; + public static final int REGULAR = 0; + + private String _title; + private int _priceCode; + + public Movie(String title, int priceCode) { + _title = title; + _priceCode = priceCode; + } + + public int getPriceCode() { + return _priceCode; + } + + public void setPriceCode(int arg) { + _priceCode = arg; + } + public String getTitle() { + return _title; + } + + +} diff --git a/src/main/java/movierental/Rental.java b/src/main/java/movierental/Rental.java new file mode 100644 index 0000000..2c8d889 --- /dev/null +++ b/src/main/java/movierental/Rental.java @@ -0,0 +1,23 @@ +package movierental; + +/** + * The rental class represents a customer renting a movie. + */ +public class Rental { + + private Movie _movie; + private int _daysRented; + + public Rental(Movie movie, int daysRented) { + _movie = movie; + _daysRented = daysRented; + } + + public int getDaysRented() { + return _daysRented; + } + + public Movie getMovie() { + return _movie; + } +} diff --git a/src/test/java/movierental/CustomerBuilder.java b/src/test/java/movierental/CustomerBuilder.java new file mode 100644 index 0000000..87597e4 --- /dev/null +++ b/src/test/java/movierental/CustomerBuilder.java @@ -0,0 +1,30 @@ +package movierental; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class CustomerBuilder { + + public static final String NAME = "Gregroire"; + private String name = NAME; + private List rentals = new ArrayList(); + + public Customer build() { + Customer result = new Customer(name); + for (Rental rental : rentals) { + result.addRental(rental); + } + return result; + } + + public CustomerBuilder withName(String name) { + this.name = name; + return this; + } + + public CustomerBuilder withRentals(Rental... rentals) { + Collections.addAll(this.rentals, rentals); + return this; + } +} diff --git a/src/test/java/movierental/CustomerTest.java b/src/test/java/movierental/CustomerTest.java new file mode 100644 index 0000000..a16d715 --- /dev/null +++ b/src/test/java/movierental/CustomerTest.java @@ -0,0 +1,104 @@ +package movierental; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; + +import org.junit.Test; + +public class CustomerTest { + + @Test + public void testCustomer() { + Customer c = new CustomerBuilder().build(); + assertNotNull(c); + } + + @Test + public void testAddRental() { + Customer customer2 = new CustomerBuilder().withName("Sallie").build(); + Movie movie1 = new Movie("Gone with the Wind", Movie.REGULAR); + Rental rental1 = new Rental(movie1, 3); // 3 day rental + customer2.addRental(rental1); + } + + @Test + public void testGetName() { + Customer c = new Customer("David"); + assertEquals("David", c.getName()); + } + + @Test + public void statementForRegularMovie() { + Movie movie1 = new Movie("Gone with the Wind", Movie.REGULAR); + Rental rental1 = new Rental(movie1, 3); // 3 day rental + Customer customer2 = + new CustomerBuilder() + .withName("Sallie") + .withRentals(rental1) + .build(); + String expected = "Rental Record for Sallie\n" + + "\tGone with the Wind\t3.5\n" + + "Amount owed is 3.5\n" + + "You earned 1 frequent renter points"; + String statement = customer2.statement(); + assertEquals(expected, statement); + } + + @Test + public void statementForNewReleaseMovie() { + Movie movie1 = new Movie("Star Wars", Movie.NEW_RELEASE); + Rental rental1 = new Rental(movie1, 3); // 3 day rental + Customer customer2 = + new CustomerBuilder() + .withName("Sallie") + .withRentals(rental1) + .build(); + String expected = "Rental Record for Sallie\n" + + "\tStar Wars\t9.0\n" + + "Amount owed is 9.0\n" + + "You earned 2 frequent renter points"; + String statement = customer2.statement(); + assertEquals(expected, statement); + } + + @Test + public void statementForChildrensMovie() { + Movie movie1 = new Movie("Madagascar", Movie.CHILDRENS); + Rental rental1 = new Rental(movie1, 3); // 3 day rental + Customer customer2 + = new CustomerBuilder() + .withName("Sallie") + .withRentals(rental1) + .build(); + String expected = "Rental Record for Sallie\n" + + "\tMadagascar\t1.5\n" + + "Amount owed is 1.5\n" + + "You earned 1 frequent renter points"; + String statement = customer2.statement(); + assertEquals(expected, statement); + } + + @Test + public void statementForManyMovies() { + Movie movie1 = new Movie("Madagascar", Movie.CHILDRENS); + Rental rental1 = new Rental(movie1, 6); // 6 day rental + Movie movie2 = new Movie("Star Wars", Movie.NEW_RELEASE); + Rental rental2 = new Rental(movie2, 2); // 2 day rental + Movie movie3 = new Movie("Gone with the Wind", Movie.REGULAR); + Rental rental3 = new Rental(movie3, 8); // 8 day rental + Customer customer1 + = new CustomerBuilder() + .withName("David") + .withRentals(rental1, rental2, rental3) + .build(); + String expected = "Rental Record for David\n" + + "\tMadagascar\t6.0\n" + + "\tStar Wars\t6.0\n" + + "\tGone with the Wind\t11.0\n" + + "Amount owed is 23.0\n" + + "You earned 4 frequent renter points"; + String statement = customer1.statement(); + assertEquals(expected, statement); + } + + //TODO make test for price breaks in code. +}