diff --git a/kont2020/src/main/java/food/Customer.java b/kont2020/src/main/java/food/Customer.java index 084ce320e2ba6654ff3a7626470a7ac6d8a6f0d3..4b16c92f6a00a4348f19826deb3961b6e4d187f4 100644 --- a/kont2020/src/main/java/food/Customer.java +++ b/kont2020/src/main/java/food/Customer.java @@ -1,6 +1,8 @@ package food; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import food.def.ICustomer; @@ -8,6 +10,8 @@ public class Customer implements ICustomer { // Add internal variables here: + private String name; + private List<MealOrder> orders; /** @@ -16,6 +20,8 @@ public class Customer implements ICustomer { * @param name The name of the customer */ public Customer(String name) { + orders = new ArrayList<>(); + this.name = name; } @@ -24,7 +30,7 @@ public class Customer implements ICustomer { * @return A list containing all meals bought by this customer */ public Collection<MealOrder> getMealsOrdered() { - return null; // Dummy return value + return new ArrayList<>(orders); } /** @@ -35,6 +41,7 @@ public class Customer implements ICustomer { */ @Override public void buyMeal(String meal, double price) { + orders.add(new MealOrder(meal, price)); } @@ -43,7 +50,7 @@ public class Customer implements ICustomer { */ @Override public int getNumberOfOrderedMeals() { - return 0; // Dummy return value + return orders.size(); } /** @@ -51,7 +58,7 @@ public class Customer implements ICustomer { */ @Override public String getName() { - return null; // Dummy return value + return name; } /** @@ -59,7 +66,7 @@ public class Customer implements ICustomer { */ @Override public String toString() { - return null; // dummy return value + return name + ": " + Integer.toString(getNumberOfOrderedMeals()); } /** @@ -68,7 +75,10 @@ public class Customer implements ICustomer { */ @Override public MealOrder getLastOrderedMeal() { - return null; // Dummy return value + if (getNumberOfOrderedMeals() == 0) { + return null; + } + return orders.get(orders.size() - 1); } /** @@ -80,7 +90,7 @@ public class Customer implements ICustomer { */ @Override public int timesEaten(String meal) { - return 0; // Dummy return value + return (int)(orders.stream().filter(m -> m.getMeal().equals(meal)).count()); // Can easily be done by a for-loop as well } public static void main(String[] args) { @@ -88,6 +98,6 @@ public class Customer implements ICustomer { customer.buyMeal("pancakes", 100); customer.buyMeal("pancakes", 75); System.out.println("Skal være 2 kjøp: " + customer.getMealsOrdered().size()); -// System.out.println("Skal være pris 75: " + customer.getLastOrderedMeal().getPrice()); // Som definert i README. + System.out.println("Skal være pris 75: " + customer.getLastOrderedMeal().getPrice()); // Som definert i README. } } diff --git a/kont2020/src/main/java/food/Kitchen.java b/kont2020/src/main/java/food/Kitchen.java index dfd14d53bc7f7b97e828fe178e825e2ff229984e..89f865813a39733985ce4c806624846fc682198e 100644 --- a/kont2020/src/main/java/food/Kitchen.java +++ b/kont2020/src/main/java/food/Kitchen.java @@ -1,5 +1,6 @@ package food; +import java.util.ArrayList; import java.util.Collection; import food.def.IKitchen; @@ -10,9 +11,21 @@ import food.def.PriceProvider; public class Kitchen implements IKitchen { // Add internal variables here: + private Collection<String> recipes; + private Collection<Customer> customers; + + private Collection<PriceProvider> priceProviders; + private Collection<KitchenObserver> observers; + + private double turnover; public Kitchen() { super(); + recipes = new ArrayList<>(); + customers = new ArrayList<>(); + priceProviders = new ArrayList<>(); + observers = new ArrayList<>(); + turnover = 0; } @@ -24,6 +37,8 @@ public class Kitchen implements IKitchen { */ @Override public void addCustomer(Customer customer) { + if (customers.contains(customer)) throw new IllegalArgumentException("Customer already registered"); + customers.add(customer); } /** @@ -32,6 +47,7 @@ public class Kitchen implements IKitchen { */ @Override public void addRecipe(String recipe) { + recipes.add(recipe); } /** @@ -41,7 +57,7 @@ public class Kitchen implements IKitchen { */ @Override public double getTurnover() { - return 0; // Dummy return value + return turnover; } @@ -50,7 +66,7 @@ public class Kitchen implements IKitchen { */ @Override public Collection<String> getRecipes() { - return null; // Dummy return value + return new ArrayList<>(recipes); } /** @@ -59,8 +75,11 @@ public class Kitchen implements IKitchen { * @return The customer with the given name, or null if no such customer is registered */ public Customer getCustomer(String name) { - return null; // dummy return value - } + return customers.stream() + .filter(c -> c.getName().equals(name)) + .findAny() + .orElse(null); + } // A nice exercise would be to make this with a for loop instead. /** * Make a meal, with a given (standard)price and to a given customer. @@ -78,11 +97,22 @@ public class Kitchen implements IKitchen { */ @Override public void provideMeal(String meal, double price, String customerName) { - } + Customer customer = getCustomer(customerName); + if (customer == null || !recipes.contains(meal)) throw new IllegalStateException("Couldn't make meal!"); + + price = computeActualPrice(meal, price, customer); // Added for task 2.3 + turnover += price; // updating the turnover, ya'know. + customer.buyMeal(meal, price); + + for (var obs : observers) { + obs.mealOrder(meal, price); // For task 2.4: inform all observers! + } +} /** * Exercise 2.3 - Delegation - * Calculate the total rebate of the given meal, using the priceDelegates of this Kitchen + * Calculate the total rebate of the given meal, using the PriceProviders (said + * priceDelegates in the exam, fixed afterwards) of this Kitchen * If more than one rebate exist, each of them applies. See README for example. * * @param meal The name of the meal @@ -91,19 +121,27 @@ public class Kitchen implements IKitchen { * @return The resulting price after all rebates have been considered. */ double computeActualPrice(String meal, double price, Customer customer) { - return 0; // Dummy return value + double rebate = 1; + for (PriceProvider priceProvider : this.priceProviders) { + rebate = rebate * priceProvider.providePrice(meal, price, customer); + } + return rebate * price; } // Exercise 2.3 - Delegation - these may not be all methods you need to create! @Override public void addPriceProvider(PriceProvider pp) { - + priceProviders.add(pp); } - // Exercise 2.4 - Observerer - these may not be all methods you need to create! + public void removePriceProvider(PriceProvider pp) { + priceProviders.remove(pp); + } + + // Oppgave 4 - observatør-observert @Override public void addObserver(KitchenObserver ko) { - + observers.add(ko); } diff --git a/kont2020/src/main/java/food/MealOrder.java b/kont2020/src/main/java/food/MealOrder.java index 964b60a7bac0522169fd111410056dd1d9e28d73..3e60965eaaf1cd8def456b11d81dc3858f7b8f67 100644 --- a/kont2020/src/main/java/food/MealOrder.java +++ b/kont2020/src/main/java/food/MealOrder.java @@ -11,4 +11,20 @@ public class MealOrder { // Consult the README for a description of requirements. + private String meal; + private double price; + + public MealOrder(String meal, double price) { + this.meal = meal; + this.price = price; + } + + public String getMeal() { + return meal; + } + + public double getPrice() { + return price; + } + } diff --git a/kont2020/src/main/java/food/ObserveToPrintTopRevenue.java b/kont2020/src/main/java/food/ObserveToPrintTopRevenue.java index 8f7e49b14d1d776330634d279430403e5f4ec798..fe83eeb38b52a49db5b3aa07d2e3e836fe3a7915 100644 --- a/kont2020/src/main/java/food/ObserveToPrintTopRevenue.java +++ b/kont2020/src/main/java/food/ObserveToPrintTopRevenue.java @@ -21,7 +21,8 @@ import food.def.KitchenObserver; public class ObserveToPrintTopRevenue implements KitchenObserver { // Internal variables go here: - + Map<String, Double> meals = new HashMap<>(); + /** * @@ -30,7 +31,29 @@ public class ObserveToPrintTopRevenue implements KitchenObserver { * If no meal has been sold: returns an empty string. */ public String getTopSellers() { - return null; // dummy return value + if (meals.size() == 0) return ""; + List<String> highestMeals = new ArrayList<>(); + double highestPrice = 0.0; + + for (var entry : meals.entrySet()) { + if (entry.getValue() > highestPrice) { + highestMeals.clear(); + highestMeals.add(entry.getKey()); + highestPrice = entry.getValue(); + } else if (entry.getValue() == highestPrice) { + highestMeals.add(entry.getKey()); + } + } + Collections.sort(highestMeals); + + StringBuilder sb = new StringBuilder(); + for (String meal : highestMeals) { + sb.append(meal); + sb.append(": "); + sb.append(highestPrice); + sb.append("\n"); + } + return sb.substring(0, sb.length() - 1).toString(); } @@ -42,6 +65,8 @@ public class ObserveToPrintTopRevenue implements KitchenObserver { */ @Override public void mealOrder(String meal, double price) { + meals.put(meal, meals.getOrDefault(meal, 0.0) + price); + System.out.println(getTopSellers()); } diff --git a/kont2020/src/main/java/food/RebateEveryFifthBuyFromSameCustomer.java b/kont2020/src/main/java/food/RebateEveryFifthBuyFromSameCustomer.java index d76c4b6487544e9575d79a8a21fe7f74666a39d0..cfd8b06e466156df7002d44070c7becd63dbacd1 100644 --- a/kont2020/src/main/java/food/RebateEveryFifthBuyFromSameCustomer.java +++ b/kont2020/src/main/java/food/RebateEveryFifthBuyFromSameCustomer.java @@ -16,7 +16,7 @@ public class RebateEveryFifthBuyFromSameCustomer implements PriceProvider { */ @Override public double providePrice(String meal, double price, Customer customer) { - return 0; // dummy return value + return customer.timesEaten(meal) % 5 == 0 ? 0.5 : 1.0; } } diff --git a/kont2020/src/main/java/food/RebateFreeEveryThousandSale.java b/kont2020/src/main/java/food/RebateFreeEveryThousandSale.java index 074fae0edfb91b62f6fe6dd6baad792ad6a4ee1d..c7fbc9dbcc0935aebd22e1e3270645282b6e5bfa 100644 --- a/kont2020/src/main/java/food/RebateFreeEveryThousandSale.java +++ b/kont2020/src/main/java/food/RebateFreeEveryThousandSale.java @@ -7,10 +7,22 @@ import food.def.PriceProvider; * is given away for free. Not the first buy! */ public class RebateFreeEveryThousandSale implements PriceProvider { - + + // Need an internal counter. We don't need Kithchen to keep track of number + // sales, since providePrice is called once every sale! + int counter; + @Override public double providePrice(String meal, double price, Customer customer) { - return 0; // dummy return value + + + if (counter++ != 0 && counter % 1000 == 0) { + return 0; + } + return 1; + + + // return counter++ > 0 && (counter % 1000 == 0) ? 0.0 : 1.0; // This is rather ugly, should perhaps be done on several lines for legibility... } diff --git a/kont2020/src/main/java/stuff/AverageComputerTest.java b/kont2020/src/main/java/stuff/AverageComputerTest.java index bb82e5d8738760ca249e4c37d24969523aa78772..8749c3af3b9aeb439ee9dfe4838f58a19a382572 100644 --- a/kont2020/src/main/java/stuff/AverageComputerTest.java +++ b/kont2020/src/main/java/stuff/AverageComputerTest.java @@ -1,14 +1,43 @@ package stuff; +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; + import org.junit.Assert; import org.junit.Test; public class AverageComputerTest { - @Test - public void testComputeAverage() { - final AverageComputer ac = new AverageComputer(Arrays.asList(3, 4, 5)); - Assert.assertEquals(4.0, ac.computeAverage(), 0.0000001); - } + private static final double epsilon = 1e-8; + + @Test + public void testComputeAverage() { + final AverageComputer ac = new AverageComputer(Arrays.asList(3, 4, 5)); + Assert.assertEquals(4.0, ac.computeAverage(), epsilon); + } + + // We can manipulate the list by adding to it from outside after + // it has been added to the method. + @Test + public void testNewComputerNotModifiedByChangingList() { + List<Integer> intVals = new ArrayList<>(); + intVals.addAll(Arrays.asList(2, 3, 1, 4)); + AverageComputer avg = new AverageComputer(intVals); + + assertEquals(2.5, avg.computeAverage(), epsilon); + intVals.add(5); + assertEquals(2.5, avg.computeAverage(), epsilon); + } + + // No cast from integer, thereby messing up those numbers... + @Test + public void testRetValIsCastBeforeDivide() { + AverageComputer ac = new AverageComputer(Arrays.asList(3, 4)); + + assertEquals(3.5, ac.computeAverage(), epsilon); + } + } diff --git a/kont2020/src/main/java/stuff/MathController.java b/kont2020/src/main/java/stuff/MathController.java index 47c33887194f2f60eb8e8df3c42636d05e67f01e..de7ad1e8a499b4231c4fef7b02d754b777fd4d41 100644 --- a/kont2020/src/main/java/stuff/MathController.java +++ b/kont2020/src/main/java/stuff/MathController.java @@ -45,8 +45,34 @@ public class MathController { */ @FXML private void onCalculate() { + double res; + double val1 = Double.parseDouble(firstField.getText()); + double val2 = Double.parseDouble(secondField.getText()); + switch (typeSelector.getValue()) { // Could use chained if-elseif-else instead of switch + case '+': + res = val1 + val2; + break; + case '-': + res = val1 - val2; + break; + case '*': + res = val1 * val2; + break; + case '/': + res = val1 / val2; + break; + default: + throw new IllegalArgumentException("Unexpected value: " + typeSelector.getValue()); + } + + resultArea.setText(Double.toString(res)); } // Is there a method missing here? Where could it be? + @FXML + private void randomizeNumbers() { + firstField.setText(Integer.toString(rand.nextInt(100) + 1)); + secondField.setText(Integer.toString(rand.nextInt(100) + 1)); + } } diff --git a/kont2020/src/main/java/stuff/Movie.java b/kont2020/src/main/java/stuff/Movie.java index 4b0d88f6b09224ce2b5e5a63e1d08265552c7541..93f5fbe3137c013408a3e7a3d16f07c435ec88a2 100644 --- a/kont2020/src/main/java/stuff/Movie.java +++ b/kont2020/src/main/java/stuff/Movie.java @@ -5,6 +5,36 @@ import static org.junit.Assert.assertEquals; public class Movie { // See the README file for a description of what is required for this file. + private String title; + private int timesWatched; + private Integer rating; + + public Movie(String title) { + if (title == null) throw new IllegalArgumentException("Title must not be null"); + this.title = title; + this.timesWatched = 0; + this.rating = null; + } + + public String getTitle() { + return title; + } + + public int getTimesWatched() { + return timesWatched; + } + + public Integer getRating() { + return rating; + } + + public void setRating(Integer rating) { + this.rating = rating; + } + + public void watch() { + timesWatched += 1; + } public static void main(String[] args) { diff --git a/kont2020/src/main/java/stuff/MovieRegister.java b/kont2020/src/main/java/stuff/MovieRegister.java index e901cca813c730550ac31fb70032f7ae29237199..ceec6549b89182d3a4397e02ccddeb160dc81d37 100644 --- a/kont2020/src/main/java/stuff/MovieRegister.java +++ b/kont2020/src/main/java/stuff/MovieRegister.java @@ -1,57 +1,67 @@ package stuff; +import java.util.ArrayList; import java.util.Collection; import java.util.function.Predicate; +import java.util.stream.Collectors; public class MovieRegister { // Add internal variables - + private Collection<Movie> movies = new ArrayList<>(); + + /** * Add movie to register * @param movie */ public void addMovie(Movie movie) { + movies.add(movie); } - + /** * * @param title * @return the movie with matching title, or null if no such movie exists. */ Movie findMovie(String title) { - return null; // dummy return value + return movies.stream().filter(m -> m.getTitle().equals(title)).findAny().orElse(null); } - + /** * Filter all registered movies based on a Predicate, and return them as a Collection. * @param pred is the filter for which movies to watch * @return A collection of movies testing true to pred. */ Collection<Movie> filterMovies(Predicate<Movie> pred) { - return null; // dummy return value + return movies.stream().filter(pred).collect(Collectors.toList()); } - + /** * Watch movie 'title'. * @param title * @throws IllegalStateException if the title does not exist. */ public void watch(String title) { + try { + findMovie(title).watch(); + } catch (NullPointerException e) { + throw new IllegalStateException("Movie does not exsits!"); + } } - + /** * Small example of use of the class. Does NOT necessarily cover all uses of methods specified in assignment. * @param args */ public static void main(String[] args) { - -// MovieRegister cb = new MovieRegister(); -// cb.addMovie(new Movie("Das Boot")); -// cb.watch("Das Boot"); -// System.out.println("Should be 1: " + cb.findMovie("Das Boot").getTimesWatched()); - + + MovieRegister cb = new MovieRegister(); + cb.addMovie(new Movie("Das Boot")); + cb.watch("Das Boot"); + System.out.println("Should be 1: " + cb.findMovie("Das Boot").getTimesWatched()); + } } diff --git a/kont2020/src/test/java/food/CustomerTest.java b/kont2020/src/test/java/food/CustomerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..945234adb84394c29323467ccb12bb1d35453650 --- /dev/null +++ b/kont2020/src/test/java/food/CustomerTest.java @@ -0,0 +1,75 @@ +package food; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Collection; + +import org.junit.Test; + +import food.def.ICustomer; + +public class CustomerTest { + + @Test + public void testAddOrdered() { + ICustomer c = new Customer("Per"); + c.buyMeal("pancakes", 99.50); + } + + @Test + public void testGetMealsOrdered() { + ICustomer c = new Customer("Per"); + c.buyMeal("pancakes", 99.50); + Collection<String> tmp = new ArrayList<>(); + MealOrder mealOrder = c.getMealsOrdered().iterator().next(); + assertEquals("pancakes", mealOrder.getMeal()); + } + + @Test + public void testGetNumberOfOrderedRecipes() { + ICustomer c = new Customer("Per"); + assertEquals(0, c.getNumberOfOrderedMeals()); + c.buyMeal("pancakes", 99.50); + assertEquals(1, c.getNumberOfOrderedMeals()); + } + + @Test + public void testGetName() { + ICustomer c = new Customer("Per"); + assertEquals("Per", c.getName()); + } + + @Test + public void testToString() { + ICustomer c = new Customer("Per"); + assertEquals("Per: 0", c.toString()); + } + + @Test + public void testCustomerCanBeConstructedWithName() { + ICustomer c = new Customer("Per"); + } + + @Test + public void testHowManyTimesHaveIEaten() { + ICustomer c = new Customer("Per"); + assertEquals(0, c.timesEaten("pancakes")); + c.buyMeal("pancakes", 99.50); + assertEquals(1, c.timesEaten("pancakes")); + c.buyMeal("pancakes", 99.50); + assertEquals(2, c.timesEaten("pancakes")); + } + + + @Test + public void testLastBoughtMeal() { + ICustomer c = new Customer("Per"); + c.buyMeal("pancakes", 99.50); + assertEquals("pancakes", c.getLastOrderedMeal().getMeal()); + c.buyMeal("waffles", 49.50); + assertEquals("waffles", c.getLastOrderedMeal().getMeal()); + } + + +} diff --git a/kont2020/src/test/java/food/GatherStatisticsTest.java b/kont2020/src/test/java/food/GatherStatisticsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c7a8d6068c192cef17d4249d16d680971dcd3280 --- /dev/null +++ b/kont2020/src/test/java/food/GatherStatisticsTest.java @@ -0,0 +1,35 @@ +package food; + +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.Collection; + +import org.junit.Test; + +public class GatherStatisticsTest { + + @Test + public void GatherMostSoldIsCalculated() { + Kitchen k = new Kitchen(); + k.addCustomer(new Customer("Per")); + k.addCustomer(new Customer("Ida")); + k.addRecipe("pancakes"); + k.addRecipe("waffles"); + ObserveToPrintTopRevenue gs = new ObserveToPrintTopRevenue(); + k.addObserver(gs); + k.provideMeal("pancakes", 50, "Per"); + assertEquals("pancakes: 50.0", gs.getTopSellers()); + k.provideMeal("pancakes", 50, "Per"); + assertEquals("pancakes: 100.0", gs.getTopSellers()); + k.provideMeal("waffles", 50, "Ida"); + assertEquals("pancakes: 100.0", gs.getTopSellers()); + k.provideMeal("waffles", 50, "Ida"); + Collection<String> top = Arrays.asList(gs.getTopSellers().split("\n")); + System.out.println(top); + assertTrue(top.contains("pancakes: 100.0")); + assertTrue(top.contains("waffles: 100.0")); + + } + +} diff --git a/kont2020/src/test/java/food/KitchenObserverTest.java b/kont2020/src/test/java/food/KitchenObserverTest.java new file mode 100644 index 0000000000000000000000000000000000000000..65028a280a21061af2ec52a7bdf3bd2ff8317fee --- /dev/null +++ b/kont2020/src/test/java/food/KitchenObserverTest.java @@ -0,0 +1,98 @@ +package food; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.junit.Test; +import org.mockito.Mockito; + +import food.def.KitchenObserver; + + +public class KitchenObserverTest { + + + double delta = 0.000001; + + + private boolean matchAll(String source, String...strings) { + for (String string : strings) { + if (!source.contains(string)) { + return false; + } + } + return true; + } + + @Test + public void testMakeMealsCallsObservers() { + Kitchen k = new Kitchen(); + k.addRecipe("Pancakes"); + k.addCustomer(new Customer("Per")); + KitchenObserver mock = Mockito.mock(KitchenObserver.class) ; + k.addObserver(mock); + k.provideMeal("Pancakes", 60.0, "Per"); + Mockito.verify(mock, Mockito.times(1)).mealOrder(Mockito.any(String.class), Mockito.any(double.class)); + } + + + @Test + public void testGatherStatisticsFreshHasZeroValue() { + ObserveToPrintTopRevenue statistics = new ObserveToPrintTopRevenue(); + assertEquals("", statistics.getTopSellers()); + } + + @Test + public void testGatherStatisticsOneAddedHasValue() { + ObserveToPrintTopRevenue statistics = new ObserveToPrintTopRevenue(); + statistics.mealOrder("pancakes", 50.0); + assertTrue(statistics.getTopSellers().contains("pancakes")); + assertTrue(statistics.getTopSellers().contains("50")); + } + + @Test + public void testGatherStatisticsTwoAddedHasCorrectValue() { + ObserveToPrintTopRevenue statistics = new ObserveToPrintTopRevenue(); + statistics.mealOrder("pancakes", 50); + statistics.mealOrder("pancakes", 40); + assertTrue(matchAll(statistics.getTopSellers(), "pancakes", "90")); + } + + @Test + public void testGatherStatisticsTwoDifferentAddedHasCorrectValue() { + + ObserveToPrintTopRevenue statistics = new ObserveToPrintTopRevenue(); + statistics.mealOrder("pancakes", 50); + statistics.mealOrder("waffles", 40); + assertTrue(matchAll(statistics.getTopSellers(), "pancakes", "50")); + } + + @Test + public void testGatherStatisticsTwoDifferentEqualAmountShowsBoth() { + + ObserveToPrintTopRevenue statistics = new ObserveToPrintTopRevenue(); + statistics.mealOrder("waffles", 100); + statistics.mealOrder("pancakes", 50); + statistics.mealOrder("pancakes", 50); + List<String> tmp = Arrays.asList(statistics.getTopSellers().split("\n")); + assertEquals(2, tmp.size()); + assertTrue(matchAll(tmp.get(0), "pancakes", "100")); + assertTrue(matchAll(tmp.get(1), "waffles", "100")); + } + + @Test + public void testGatherStatisticsTwoDifferentDifferentAmountShowsOne() { + + ObserveToPrintTopRevenue statistics = new ObserveToPrintTopRevenue(); + statistics.mealOrder("pancakes", 50); + statistics.mealOrder("pancakes", 50); + statistics.mealOrder("waffles", 100); + statistics.mealOrder("pancakes", 50); + assertTrue(matchAll(statistics.getTopSellers(), "pancakes", "150")); + } +} diff --git a/kont2020/src/test/java/food/KitchenTest.java b/kont2020/src/test/java/food/KitchenTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3c5b5244cab48a8a4acd4b90fb18506311a7e349 --- /dev/null +++ b/kont2020/src/test/java/food/KitchenTest.java @@ -0,0 +1,122 @@ +package food; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; + +import org.junit.Test; +import org.mockito.Mockito; + +import food.Customer; +import food.Kitchen; +import food.RebateEveryFifthBuyFromSameCustomer; +import food.RebateFreeEveryThousandSale; +import food.def.IKitchen; +import food.def.KitchenObserver; +import food.def.PriceProvider; + +public class KitchenTest { + + double delta = 0.000001; + + @Test + public void testEmptyConstructor() { + IKitchen k = new Kitchen(); + } + + @Test + public void testAddRecipe() { + IKitchen k = new Kitchen(); + k.addRecipe("Pannekaker"); + assertEquals(1, k.getRecipes().size()); + } + + @Test + public void testGetRecipes() { + IKitchen k = new Kitchen(); + k.addRecipe("Waffles"); + k.addRecipe("Pancakes"); + Collection<String> tmp = new HashSet<>(); + tmp.add("Waffles"); + tmp.add("Pancakes"); + assertEquals(tmp, new HashSet<>(k.getRecipes())); + } + + @Test + public void testAddCustomer() { + IKitchen k = new Kitchen(); + k.addCustomer(new Customer("Per")); + } + + @Test + public void testFindCustomer() { + IKitchen k = new Kitchen(); + k.addCustomer(new Customer("Per")); + assertEquals("Per", k.getCustomer("Per").getName()); + } + + @Test + public void testCustomerOrdersRecipeWorksWhenInitiated() { + IKitchen k = new Kitchen(); + k.addRecipe("Pancakes"); + k.addCustomer(new Customer("Per")); + k.provideMeal("Pancakes", 99.50, "Per"); + assertEquals(1, k.getCustomer("Per").getNumberOfOrderedMeals()); + } + + @Test + public void testCustomerOrdersRecipeWorksFailsOnNonexistentRecipe() { + IKitchen k = new Kitchen(); + k.addRecipe("Pancakes"); + Customer customer = new Customer("Per"); + k.addCustomer(customer); + try { + k.provideMeal("PanKakes", 99.50, "Per"); + fail("Meal should not be successfully made with unknown recipe 'PanKakes'."); + } catch (IllegalStateException e) { + assertEquals("Unsuccessful meal should not be registered to customer.", 0, customer.getNumberOfOrderedMeals()); + } + } + + @Test + public void testCustomerOrdersRecipeWorksFailsOnNonexistentCustomer() { + IKitchen k = new Kitchen(); + k.addRecipe("Pancakes"); + Customer c = new Customer("Per"); + k.addCustomer(c); + try { + k.provideMeal("Pancakes", 99.50, "Finns_inte"); + fail("Meal should not be successfully made with unknown customer 'Finns_inte'."); + } catch (IllegalStateException e) { + assertEquals("Unsuccessful meal should not be registered to customer.", 0, c.getNumberOfOrderedMeals()); + } + } + + @Test + public void testEmptyKitchenHasZeroTurnover() { + IKitchen k = new Kitchen(); + assertEquals(0.0, k.getTurnover(), delta); + } + + @Test + public void testMakingDishIncreasesTurnover() { + IKitchen k = new Kitchen(); + k.addRecipe("Pancakes"); + k.addCustomer(new Customer("Per")); + k.provideMeal("Pancakes", 99.50, "Per"); + assertEquals(99.50, k.getTurnover(), delta); + } + + @Test + public void testMakingDishWithSpecialPriceHasCorrectTurnover() { + IKitchen k = new Kitchen(); + k.addRecipe("Pancakes"); + k.addCustomer(new Customer("Per")); + k.provideMeal("Pancakes", 60.0, "Per"); + assertEquals(60.0, k.getTurnover(), delta); + } + + +} diff --git a/kont2020/src/test/java/food/PriceProviderTest.java b/kont2020/src/test/java/food/PriceProviderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ca55e10e4854f1cc3585fc9e2443f7c2bc9463f2 --- /dev/null +++ b/kont2020/src/test/java/food/PriceProviderTest.java @@ -0,0 +1,125 @@ +package food; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.mockito.Mockito; + +import food.Customer; +import food.Kitchen; +import food.RebateEveryFifthBuyFromSameCustomer; +import food.def.KitchenObserver; +import food.def.PriceProvider; + +public class PriceProviderTest { + + double delta = 0.000001; + + @Test + public void testCanAddDelegates() { + Kitchen k = new Kitchen(); + k.addRecipe("pancakes"); + k.addCustomer(new Customer("per")); + PriceProvider delegate = Mockito.mock(PriceProvider.class); + k.addPriceProvider(delegate ); + k.provideMeal("pancakes", 100, "per"); + Mockito.verify(delegate, Mockito.times(1)).providePrice(Mockito.any(String.class), Mockito.anyDouble(), Mockito.any(Customer.class)); + } + + + @Test + public void testCanAddTwoDelegates() { + Kitchen k = new Kitchen(); + k.addRecipe("pancakes"); + k.addCustomer(new Customer("per")); + + PriceProvider delegate1 = Mockito.mock(PriceProvider.class) ; + k.addPriceProvider(delegate1); + + PriceProvider delegate2 = Mockito.mock(PriceProvider.class) ; + k.addPriceProvider(delegate2); + + k.provideMeal("pancakes", 100, "per"); + + Mockito.verify(delegate1, Mockito.times(1)).providePrice(Mockito.any(String.class), Mockito.anyDouble(), Mockito.any(Customer.class)); + Mockito.verify(delegate2, Mockito.times(1)).providePrice(Mockito.any(String.class), Mockito.anyDouble(), Mockito.any(Customer.class)); + } + + + @Test + public void testDelegateWorksViaKitchen() { + Kitchen k = new Kitchen(); + k.addPriceProvider(new RebateEveryFifthBuyFromSameCustomer()); + k.addRecipe("Pancakes"); + k.addCustomer(new Customer("Per")); + k.provideMeal("Pancakes", 100, "Per"); + assertEquals(50, k.getTurnover(), delta); + } + + + @Test + public void testEveryFifthBuysRebateFirstBuyGivesRebate() { + Customer customer = new Customer("Per"); + RebateEveryFifthBuyFromSameCustomer rebate = new RebateEveryFifthBuyFromSameCustomer(); + assertEquals(0.5, rebate.providePrice("pancakes", 100, customer), delta); + } + @Test + public void testEveryFifthBuysRebateSecondBuyNoRebate() { + Customer customer = new Customer("Per"); + RebateEveryFifthBuyFromSameCustomer rebate = new RebateEveryFifthBuyFromSameCustomer(); + assertEquals(0.5, rebate.providePrice("pancakes", 100, customer), delta); + customer.buyMeal("pancakes", 50); + assertEquals(1, rebate.providePrice("pancakes", 100, customer), delta); + customer.buyMeal("pancakes", 100); + } + + @Test + public void testEveryFifthBuysRebateSixthBuyGivesRebate() { + Customer customer = new Customer("Per"); + RebateEveryFifthBuyFromSameCustomer rebate = new RebateEveryFifthBuyFromSameCustomer(); + + double fac = rebate.providePrice("pancakes", 100, customer); + assertEquals(.5, fac, delta); + customer.buyMeal("pancakes", 100); + + for (int i = 0; i < 4; i++) { + fac = rebate.providePrice("pancakes", 100, customer); + assertEquals(1.0, fac, delta); + customer.buyMeal("pancakes", 100); + } + assertEquals(0.5, rebate.providePrice("pancakes", 100, customer), delta); + } + + @Test + public void testFreeEveryThousandNoRebateOnFirst() { + Customer customer = new Customer("Per"); + RebateFreeEveryThousandSale rebate = new RebateFreeEveryThousandSale(); + assertEquals(1, rebate.providePrice("pancakes", 100, customer), delta); + } + + @Test + public void testFreeEveryThousandRebateOnThousand() { + RebateFreeEveryThousandSale rebate = new RebateFreeEveryThousandSale(); + Customer customer = new Customer("Per"); + assertEquals(1, rebate.providePrice("pancakes", 100, customer), delta); + customer.buyMeal("pancakes", 100); + for (int i = 0; i < 999; i++) { + rebate.providePrice("Pancakes", 100, customer); + assertEquals(1, rebate.providePrice("pancakes", 100, customer), delta); + customer.buyMeal("pancakes", 100); + } + assertEquals(0, rebate.providePrice("pancakes", 100, customer), delta); + } + + @Test + public void testTwoRebatesWorkOneTriggersOneDoesnt() { + Kitchen k = new Kitchen(); + k.addPriceProvider(new RebateEveryFifthBuyFromSameCustomer()); + k.addPriceProvider(new RebateFreeEveryThousandSale()); + k.addRecipe("Pancakes"); + k.addCustomer(new Customer("Per")); + k.provideMeal("Pancakes", 100, "Per"); + assertEquals(50, k.getTurnover(), delta); + } + +} diff --git a/kont2020/src/test/java/stuff/MovieRegisterTest.java b/kont2020/src/test/java/stuff/MovieRegisterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0f33a7c4e339735c511da548e2b1d2504ebaab2e --- /dev/null +++ b/kont2020/src/test/java/stuff/MovieRegisterTest.java @@ -0,0 +1,60 @@ +package stuff; + +import static org.junit.Assert.*; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class MovieRegisterTest extends MovieRegister { + + + @Test + public void NewRegisterNoMovies() { + MovieRegister mr = new MovieRegister(); + assertEquals(null, mr.findMovie("Das Boot")); + } + + @Test + public void RegisterCanAddMovies() { + MovieRegister mr = new MovieRegister(); + Movie movie = new Movie("Das Boot"); + mr.addMovie(movie); + assertEquals(movie, mr.findMovie("Das Boot")); + } + + @Test + public void RegisterWatchOnce() { + MovieRegister cb = new MovieRegister(); + cb.addMovie(new Movie("Das Boot")); + cb.watch("Das Boot"); + assertEquals(1, cb.findMovie("Das Boot").getTimesWatched()); + } + + @Test(expected=IllegalStateException.class) + public void RegisterWatchNonExistingMovie() { + MovieRegister cb = new MovieRegister(); + cb.addMovie(new Movie("Das Boot")); + cb.watch("The cars that ate Paris"); + } + + @Test + public void RegisterWatchTwice() { + MovieRegister cb = new MovieRegister(); + cb.addMovie(new Movie("Das Boot")); + cb.watch("Das Boot"); + cb.watch("Das Boot"); + assertEquals(2, cb.findMovie("Das Boot").getTimesWatched()); + } + + + @Test + public void RegisterAddTwoMovies() { + MovieRegister cb = new MovieRegister(); + cb.addMovie(new Movie("Das Boot")); + cb.addMovie(new Movie("The cars that ate Paris")); + cb.watch("Das Boot"); + cb.watch("Das Boot"); + assertEquals(2, cb.findMovie("Das Boot").getTimesWatched()); + } + +} diff --git a/kont2020/src/test/java/stuff/MovieTest.java b/kont2020/src/test/java/stuff/MovieTest.java new file mode 100644 index 0000000000000000000000000000000000000000..614f1852569664ce7444ed079cacf5c847ce0689 --- /dev/null +++ b/kont2020/src/test/java/stuff/MovieTest.java @@ -0,0 +1,53 @@ +package stuff; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class MovieTest extends Movie { + + public MovieTest() { + super("test"); + } + + @Test + public void nameIsStored() { + Movie movie = new Movie("Das Boot"); + assertEquals("Das Boot", movie.getTitle()); + } + + @Test + public void newRecipeZeroEaten() { + Movie movie = new Movie("cheese"); + assertEquals(0, movie.getTimesWatched()); + } + + @Test + public void newRecipeOnceEaten() { + Movie movie = new Movie("cheese"); + movie.watch(); + assertEquals(1, movie.getTimesWatched()); + } + + @Test + public void newRecipeTwiceEaten() { + Movie recipe = new Movie("cheese"); + recipe.watch(); + recipe.watch(); + assertEquals(2, recipe.getTimesWatched()); + } + + @Test + public void newRecipeNullRating() { + Movie recipe = new Movie("cheese"); + assertEquals(null, recipe.getRating()); + } + + @Test + public void newRecipeRatedWorks() { + Movie recipe = new Movie("cheese"); + recipe.setRating(3); + assertEquals(3, (int)recipe.getRating()); + } + +}