From 1c30860c3cbbc928bb8b9efd64d8e536fb9830b2 Mon Sep 17 00:00:00 2001 From: Alexandre Aquiles Date: Sat, 3 Jul 2010 22:44:30 -0300 Subject: [PATCH] Initial (procedural) implementation and unit tests. --- .gitignore | 4 + src/com/aquiles/alexandre/Customer.java | 64 +++++++ src/com/aquiles/alexandre/Movie.java | 32 ++++ src/com/aquiles/alexandre/Rental.java | 24 +++ src/com/aquiles/alexandre/RentalTest.java | 194 ++++++++++++++++++++++ 5 files changed, 318 insertions(+) create mode 100644 .gitignore create mode 100644 src/com/aquiles/alexandre/Customer.java create mode 100644 src/com/aquiles/alexandre/Movie.java create mode 100644 src/com/aquiles/alexandre/Rental.java create mode 100644 src/com/aquiles/alexandre/RentalTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e86b18e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +bin +.classpath +.project +.settings diff --git a/src/com/aquiles/alexandre/Customer.java b/src/com/aquiles/alexandre/Customer.java new file mode 100644 index 0000000..17b15fd --- /dev/null +++ b/src/com/aquiles/alexandre/Customer.java @@ -0,0 +1,64 @@ +package com.aquiles.alexandre; + +import java.util.ArrayList; +import java.util.Collection; + +public class Customer { + + private String name; + private Collection rentals; + + public Customer(String name) { + super(); + rentals = new ArrayList(); + this.name = name; + } + + public String getName() { + return name; + } + + public void addRental(Rental rental) { + rentals.add(rental); + } + + public String statement() { + double totalAmount = 0; + int frequentRenterPoints = 0; + String result = "Rental record for " + getName() + "\n"; + for(Rental rental : rentals) { + double thisAmount = 0; + switch(rental.getMovie().getPriceCode()) { + case Movie.REGULAR: + thisAmount += 2; + if(rental.getDaysRented() > 2) + thisAmount += (rental.getDaysRented() - 2) * 1.5; + break; + case Movie.NEW_RELEASE: + thisAmount += rental.getDaysRented() * 3; + break; + case Movie.CHILDRENS: + thisAmount += 1.5; + if(rental.getDaysRented() > 3) + thisAmount += (rental.getDaysRented() - 3) * 1.5; + break; + } + + //add frequent renter points + frequentRenterPoints++; + + //add bonus for a two day new release rental + if(rental.getMovie().getPriceCode() == Movie.NEW_RELEASE && rental.getDaysRented() > 1) + frequentRenterPoints++; + + //show figures for this rental + result += "\t" + rental.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/com/aquiles/alexandre/Movie.java b/src/com/aquiles/alexandre/Movie.java new file mode 100644 index 0000000..0649aae --- /dev/null +++ b/src/com/aquiles/alexandre/Movie.java @@ -0,0 +1,32 @@ +package com.aquiles.alexandre; + +public class Movie { + + public static final int REGULAR = 0; + public static final int NEW_RELEASE = 1; + public static final int CHILDRENS = 2; + + private String title; + private Integer priceCode; + + public Movie(String title, Integer priceCode) { + super(); + this.title = title; + this.priceCode = priceCode; + } + + public Integer getPriceCode() { + return priceCode; + } + + public void setPriceCode(Integer priceCode) { + this.priceCode = priceCode; + } + + public String getTitle() { + return title; + } + + + +} diff --git a/src/com/aquiles/alexandre/Rental.java b/src/com/aquiles/alexandre/Rental.java new file mode 100644 index 0000000..39bbf66 --- /dev/null +++ b/src/com/aquiles/alexandre/Rental.java @@ -0,0 +1,24 @@ +package com.aquiles.alexandre; + + +public class Rental { + + private Movie movie; + private Integer daysRented; + + public Rental(Movie movie, Integer daysRented) { + super(); + this.movie = movie; + this.daysRented = daysRented; + } + + public Movie getMovie() { + return movie; + } + + public Integer getDaysRented() { + return daysRented; + } + + +} diff --git a/src/com/aquiles/alexandre/RentalTest.java b/src/com/aquiles/alexandre/RentalTest.java new file mode 100644 index 0000000..67a7ab8 --- /dev/null +++ b/src/com/aquiles/alexandre/RentalTest.java @@ -0,0 +1,194 @@ +package com.aquiles.alexandre; + +import java.util.Formatter; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +public class RentalTest { + + @Test + public void shortRegularRental() { + Customer customer = createCustomer(); + addRental(customer, "Groundhog Day", Movie.REGULAR, 2); + + String expected = + new StatementConfig() + .addPartialAmount("Groundhog Day", 2.0) + .addTotalAmount(2.0) + .addFrequentRenterPoints(1) + .expectedStatement(); + + Assert.assertEquals(expected, customer.statement()); + } + + @Test + public void longRegularRental() { + Customer customer = createCustomer(); + addRental(customer, "Groundhog Day", Movie.REGULAR, 3); + + String expected = + new StatementConfig() + .addPartialAmount("Groundhog Day", 3.5) + .addTotalAmount(3.5) + .addFrequentRenterPoints(1) + .expectedStatement(); + + Assert.assertEquals(expected, customer.statement()); + } + + @Test + public void shortNewReleaseRental() { + Customer customer = createCustomer(); + addRental(customer, "X-Men X", Movie.NEW_RELEASE, 1); + + String expected = + new StatementConfig() + .addPartialAmount("X-Men X", 3.0) + .addTotalAmount(3.0) + .addFrequentRenterPoints(1) + .expectedStatement(); + + Assert.assertEquals(expected, customer.statement()); + } + + @Test + public void longNewReleaseRental() { + Customer customer = createCustomer(); + addRental(customer, "X-Men X", Movie.NEW_RELEASE, 2); + + String expected = + new StatementConfig() + .addPartialAmount("X-Men X", 6.0) + .addTotalAmount(6.0) + .addFrequentRenterPoints(2) + .expectedStatement(); + + Assert.assertEquals(expected, customer.statement()); + } + + @Test + public void shortChildrensRental() { + Customer customer = createCustomer(); + addRental(customer, "Toy Story", Movie.CHILDRENS, 3); + + String expected = + new StatementConfig() + .addPartialAmount("Toy Story", 1.5) + .addTotalAmount(1.5) + .addFrequentRenterPoints(1) + .expectedStatement(); + + Assert.assertEquals(expected, customer.statement()); + } + + @Test + public void longChildrensRental() { + Customer customer = createCustomer(); + addRental(customer, "Toy Story", Movie.CHILDRENS, 4); + + String expected = + new StatementConfig() + .addPartialAmount("Toy Story", 3.0) + .addTotalAmount(3.0) + .addFrequentRenterPoints(1) + .expectedStatement(); + + Assert.assertEquals(expected, customer.statement()); + } + + @Test + public void variousRentals() { + Customer customer = createCustomer(); + addRental(customer, "Groundhog Day", Movie.REGULAR, 3); + addRental(customer, "X-Men X", Movie.NEW_RELEASE, 2); + addRental(customer, "Toy Story", Movie.CHILDRENS, 4); + + String expected = + new StatementConfig() + .addPartialAmount("Groundhog Day", 3.5) + .addPartialAmount("X-Men X", 6.0) + .addPartialAmount("Toy Story", 3.0) + .addTotalAmount(12.5) + .addFrequentRenterPoints(4) + .expectedStatement(); + + Assert.assertEquals(expected, customer.statement()); + } + + @Test + public void expectedStatementTest() { + String result = new StatementConfig().addPartialAmount("Groundhog Day", 3.0).addTotalAmount(3.0).addFrequentRenterPoints(1).expectedStatement(); + String expected = "Rental record for Luke\n"; + expected += "\tGroundhog Day\t3.0\n"; + expected += "Amount owed is 3.0\n"; + expected += "You earned 1 frequent renter points"; + Assert.assertEquals(expected, result); + } + + private Customer createCustomer(){ + return new Customer("Luke"); + } + + private void addRental(Customer customer, String movieName, Integer priceCode, Integer daysRented) { + Movie movie = new Movie(movieName, priceCode); + Rental rental = new Rental(movie, daysRented); + customer.addRental(rental); + } + +} + +class StatementConfig { + private Map partialAmountsByMovieName; + private Double totalAmount; + private Integer frequentRenterPoints; + + public StatementConfig() { + this.partialAmountsByMovieName = new LinkedHashMap(); + } + + public StatementConfig addPartialAmount(String movieName, Double partialAmount) { + partialAmountsByMovieName.put(movieName, partialAmount); + return this; + } + + public StatementConfig addTotalAmount(Double totalAmount) { + this.totalAmount = totalAmount; + return this; + } + + public StatementConfig addFrequentRenterPoints(Integer frequentRenterPoints) { + this.frequentRenterPoints = frequentRenterPoints; + return this; + } + + public String expectedStatement() { + String format = "Rental record for Luke\n"; + for (int i= 0; i < partialAmountsByMovieName.size(); i++) { + format += "\t%s\t%.1f\n"; + } + format += "Amount owed is %.1f\n"; + format += "You earned %d frequent renter points"; + + Formatter formatter = new Formatter(); + formatter.format(Locale.US, format, getParameters()); + + return formatter.toString(); + } + + private Object[] getParameters() { + Object[] parameters = new Object[2*partialAmountsByMovieName.size()+2]; + int i = -1; + for(String movieName : partialAmountsByMovieName.keySet()) { + parameters[++i] = movieName; + parameters[++i] = partialAmountsByMovieName.get(movieName); + } + parameters[++i] = totalAmount; + parameters[++i] = frequentRenterPoints; + return parameters; + } + +}