From fbf919acb0b43999f4c4dd097796e1d1ab4bb245 Mon Sep 17 00:00:00 2001 From: Marie Helene Hansen Date: Mon, 11 Aug 2025 14:45:24 +0200 Subject: [PATCH 1/7] domain model + tests --- src/main/java/com/booleanuk/core/Bagel.java | 26 +++ src/main/java/com/booleanuk/core/Basket.java | 48 +++++ src/main/java/com/booleanuk/core/Coffee.java | 8 + .../java/com/booleanuk/core/Customer.java | 26 +++ src/main/java/com/booleanuk/core/Filling.java | 8 + src/main/java/com/booleanuk/core/Guest.java | 33 +++ .../java/com/booleanuk/core/Inventory.java | 4 + src/main/java/com/booleanuk/core/Item.java | 31 +++ src/main/java/com/booleanuk/core/Manager.java | 16 ++ .../java/com/booleanuk/core/class-diagram.md | 50 +++++ .../java/com/booleanuk/core/domain-model.md | 41 ++++ .../java/com/booleanuk/core/CoreTest.java | 195 ++++++++++++++++++ 12 files changed, 486 insertions(+) create mode 100644 src/main/java/com/booleanuk/core/Bagel.java create mode 100644 src/main/java/com/booleanuk/core/Basket.java create mode 100644 src/main/java/com/booleanuk/core/Coffee.java create mode 100644 src/main/java/com/booleanuk/core/Customer.java create mode 100644 src/main/java/com/booleanuk/core/Filling.java create mode 100644 src/main/java/com/booleanuk/core/Guest.java create mode 100644 src/main/java/com/booleanuk/core/Inventory.java create mode 100644 src/main/java/com/booleanuk/core/Item.java create mode 100644 src/main/java/com/booleanuk/core/Manager.java create mode 100644 src/main/java/com/booleanuk/core/class-diagram.md create mode 100644 src/main/java/com/booleanuk/core/domain-model.md create mode 100644 src/test/java/com/booleanuk/core/CoreTest.java diff --git a/src/main/java/com/booleanuk/core/Bagel.java b/src/main/java/com/booleanuk/core/Bagel.java new file mode 100644 index 000000000..9eb44edb7 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Bagel.java @@ -0,0 +1,26 @@ +package com.booleanuk.core; + +import java.util.ArrayList; +import java.util.List; + +public class Bagel extends Item { + + private List fillingList; + + public Bagel(String SKU, float price, String name, String variant) { + super(SKU, price, name, variant); + fillingList = new ArrayList<>(); + } + + public boolean addFilling(Filling f) { + return false; + } + + public List getFillingList() { + return null; + } + + public float getPriceWithFillings() { + return 0; + } +} diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java new file mode 100644 index 000000000..1c240e061 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -0,0 +1,48 @@ +package com.booleanuk.core; + +import java.util.HashMap; +import java.util.Map; + +public class Basket { + + private int capacity; + private Map items; + + public Basket(int capacity) { + this.capacity = capacity; + items = new HashMap<>(); + } + + public Map getItems() { + return items; + } + + public boolean add(Item item) { + return false; + } + + public boolean remove(String SKU) { + return false; + } + + public float getTotalCost() { + return 0; + } + + public int getCapacity() { + return 0; + } + + public int getAvailableCapacity() { + // available after items are added + // getCapacity if items-map is empty + // check this first, make sure Manager does not screw it up + return 0; + } + + public boolean isFull() { + return false; + } + + +} diff --git a/src/main/java/com/booleanuk/core/Coffee.java b/src/main/java/com/booleanuk/core/Coffee.java new file mode 100644 index 000000000..97d69f726 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Coffee.java @@ -0,0 +1,8 @@ +package com.booleanuk.core; + +public class Coffee extends Item { + public Coffee(String SKU, float price, String name, String variant) { + super(SKU, price, name, variant); + } + +} diff --git a/src/main/java/com/booleanuk/core/Customer.java b/src/main/java/com/booleanuk/core/Customer.java new file mode 100644 index 000000000..1e4237e57 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Customer.java @@ -0,0 +1,26 @@ +package com.booleanuk.core; + +import java.util.List; + +public class Customer extends Guest { + + public Customer(String name) { + super(name); + } + + public float getTotalPriceBasket() { + return 0; + } + + public float getPriceBagel(Bagel b) { + return 0; + } + + public float getPriceFilling(Filling f) { + return 0; + } + + public boolean setFillings(List fillingList) { + return false; + } +} diff --git a/src/main/java/com/booleanuk/core/Filling.java b/src/main/java/com/booleanuk/core/Filling.java new file mode 100644 index 000000000..9fac31603 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Filling.java @@ -0,0 +1,8 @@ +package com.booleanuk.core; + +public class Filling extends Item { + public Filling(String SKU, float price, String name, String variant) { + super(SKU, price, name, variant); + } + +} diff --git a/src/main/java/com/booleanuk/core/Guest.java b/src/main/java/com/booleanuk/core/Guest.java new file mode 100644 index 000000000..b2dc73a73 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Guest.java @@ -0,0 +1,33 @@ +package com.booleanuk.core; + +public class Guest { + // "MEMBER OF PUBLIC" + private String name; + private Basket basket; + private int defaultCap = 10; + + public Guest(String name) { + this.name = name; + this.basket = new Basket(defaultCap); + } + + public Basket getBasket() { + return null; + } + + public boolean addToBasket(Item it) { + return false; + } + + public boolean removeFromBasket(Item it) { + return false; + } + + public boolean isBasketFull() { + return false; + } + + public boolean hasItemInBasket(Item it) { + return false; + } +} diff --git a/src/main/java/com/booleanuk/core/Inventory.java b/src/main/java/com/booleanuk/core/Inventory.java new file mode 100644 index 000000000..e5a9a90bf --- /dev/null +++ b/src/main/java/com/booleanuk/core/Inventory.java @@ -0,0 +1,4 @@ +package com.booleanuk.core; + +public enum Inventory { +} diff --git a/src/main/java/com/booleanuk/core/Item.java b/src/main/java/com/booleanuk/core/Item.java new file mode 100644 index 000000000..c0d5ecdf3 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Item.java @@ -0,0 +1,31 @@ +package com.booleanuk.core; + +abstract public class Item { + private String SKU; + private float price; + private String name; + private String variant; + + public Item(String SKU, float price, String name, String variant) { + this.SKU = SKU; + this.price = price; + this.name = name; + this.variant = variant; + } + + public String getSKU() { + return null; + } + + public float getPrice() { + return 0; + } + + public String getName() { + return null; + } + + public String getVariant() { + return null; + } +} diff --git a/src/main/java/com/booleanuk/core/Manager.java b/src/main/java/com/booleanuk/core/Manager.java new file mode 100644 index 000000000..d62a179f5 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Manager.java @@ -0,0 +1,16 @@ +package com.booleanuk.core; + +public class Manager { + + public Manager() { + + } + + public int setCapacity(Basket b, int cap) { + return 0; + } + + public boolean isInItems(Basket b) { + return false; + } +} diff --git a/src/main/java/com/booleanuk/core/class-diagram.md b/src/main/java/com/booleanuk/core/class-diagram.md new file mode 100644 index 000000000..828256090 --- /dev/null +++ b/src/main/java/com/booleanuk/core/class-diagram.md @@ -0,0 +1,50 @@ +## UUUUPDATE don't forget pls + +```mermaid +classDiagram + Inventory <|-- Item + Item <|-- Bagel + Item <|-- Filling + Customer <|-- Manager + + + class Item { + - SKU: String + - price: float + - name: String + + getSKU(): String + + getPrice(): float + + getName(): String + } + + class Bagel { + - fillings: List + + getFillings(): List + } + + class Filling { + + getPrice(): float + } + + enum Inventory { + + SKU: List + } + + class Basket { + - items: Map + - capacity: int + + add(Item): boolean + + remove(Item): boolean + + getTotalCost(): float + } + + class Customer { + + } + + class Manager { + + changeCapacity(Basket, int): boolean + + orderIsInItems(): boolean + } + +``` \ No newline at end of file diff --git a/src/main/java/com/booleanuk/core/domain-model.md b/src/main/java/com/booleanuk/core/domain-model.md new file mode 100644 index 000000000..94ec9f779 --- /dev/null +++ b/src/main/java/com/booleanuk/core/domain-model.md @@ -0,0 +1,41 @@ +| Classes | Members | Methods | Scenarios | Outputs | +|-----------|------------------------------------|-------------------------------------|-----------------------------|----------------------------| +| Basket | Map, int capacity | add(Item it) | it not an Item | false | +| | | | it is an Item | true | +| | | remove(Item it) | it not an Item | false | +| | | | it is an Item & in Basket | true | +| | | | it is an Item not in Basket | false (+ print message?) | +| | | getTotalCost() | Basket empty | 0 | +| | | | Basket not empty | totalCost | +| Item | String SKU, int price, String name | getSKU() | item not in inventory | null | +| | | | item in inventory | String | +| | | getPrice() | item not in inventory | null | +| | | | item in inventory | float | +| | | getName() | item not in inventory | null | +| | | | item in inventory | String | +| Bagel | List | setFilling(Filling[] f) | empty f | false (error: must choose) | +| | | | f not empty | true | +| Filling | | getPrice() | not a Filling | null | +| | | | is a Filling | price | +| Manager | | changeCapacity(Basket b, int cap) | b not a Basket | null | +| | | isInItems() | all items in Item | true | +| | | | not all items in Item | false | +| | | | b is a Basket | capacity += cap | +| Guest | String name | addToBasket(Bagel bagel) | bagel is in inventory | true | +| | | | bagel not in inventory | false | +| | | removeFromBasket(Bagel bagel) | bagel is in Basket | true | +| | | | bagel not in Basket | false | +| | | isBasketFull() | basket is full | true | +| | | | basket not full | false | +| | | hasItemInBasket(Item item) | basket has item | true | +| | | | basket does not have item | false | +| Customer | | getTotalCostBasket() | basket empty | 0 | +| | | | basket not empty | float | +| | | getPriceBagel(Bagel bagel) | bagel in inventory | float | +| | | | bagel not in inventory | 0 | +| | | setFillings(List fillings) | filling in inventory | true | +| | | | filling not in inventory | false | +| | | getPriceFilling(Filling filling) | filling in inventory | float | +| | | | filling not in inventory | false | +| Inventory | enum! how to list it here | | | | + diff --git a/src/test/java/com/booleanuk/core/CoreTest.java b/src/test/java/com/booleanuk/core/CoreTest.java new file mode 100644 index 000000000..1be9756b2 --- /dev/null +++ b/src/test/java/com/booleanuk/core/CoreTest.java @@ -0,0 +1,195 @@ +package com.booleanuk.core; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; + +public class CoreTest { + + // GUEST + @Test + public void shouldAddToBasket() { + Basket b = new Basket(2); + Bagel bg = new Bagel("A", 20, "Aa", "Ab"); + b.add(bg); + Assertions.assertTrue(b.getItems().containsKey(bg)); + } + + @Test + public void shouldRemoveFromBasket() { + Basket b = new Basket(2); + Bagel bg = new Bagel("A", 20, "Aa", "Ab"); + b.add(bg); + b.remove(bg.getSKU()); + Assertions.assertFalse(b.getItems().containsKey(bg)); + } + + @Test + public void shouldBeFull() { + Basket b = new Basket(2); + b.add(new Bagel("A", 20, "Aa", "Ab")); + b.add(new Bagel("B", 20, "Bb", "Bc")); + Assertions.assertTrue(b.isFull()); + } + + @Test + public void shouldNotHaveItemToRemove() { + Basket b = new Basket(2); + b.add(new Bagel("A", 20, "Aa", "Ab")); + b.add(new Bagel("B", 20, "Bb", "Bc")); + Assertions.assertFalse(b.remove("C")); + } + + // CUSTOMER + @Test + public void shouldGetTotalPriceBasket() { + Customer c = new Customer("Dave"); + Bagel a = new Bagel("A", 20, "Aa", "Ab"); + Bagel b = new Bagel("B", 20, "Bb", "Bc"); + c.getBasket().add(a); + c.getBasket().add(b); + Assertions.assertEquals(a.getPrice()+b.getPrice(), c.getBasket().getTotalCost()); + } + + @Test + public void shouldGetBagelPrice() { + Customer c = new Customer("Dave"); + Bagel a = new Bagel("A", 20, "Aa", "Ab"); + a.addFilling(new Filling("F", 20, "Ff", "Fg")); + c.getBasket().add(a); + } + + @Test + public void shouldGetFillingPrice() { + Customer c = new Customer("Dave"); + Bagel a = new Bagel("A", 20, "Aa", "Ab"); + Filling f = new Filling("F", 20, "Ff", "Fg"); + Assertions.assertEquals(f.getPrice(), c.getPriceFilling(f)); + } + + @Test + public void shouldSetFillings() { + Customer c = new Customer("Dave"); + Bagel a = new Bagel("A", 20, "Aa", "Ab"); + a.addFilling(new Filling("F", 20, "Ff", "Fg")); + Assertions.assertEquals(List.of(new Filling("F", 20, "Ff", "Fg")), a.getFillingList()); + } + + // ITEM: Bagel, Coffee, Filling + @Test + public void shouldGetSKUItem() { + Item b = new Bagel("B", 20, "Aa", "Ab"); + Coffee c = new Coffee("C", 100, "Cc", "Cd"); + Filling f = new Filling("F", 20, "Ff", "Fg"); + Assertions.assertEquals("F", f.getSKU()); + Assertions.assertEquals("B", b.getSKU()); + Assertions.assertEquals("C", c.getSKU()); + } + + @Test + public void shouldGetPriceItem() { + Item b = new Bagel("B", 20, "Aa", "Ab"); + Coffee c = new Coffee("C", 30, "Cc", "Cd"); + Filling f = new Filling("F", 10, "Ff", "Fg"); + Assertions.assertEquals(20, b.getPrice()); + Assertions.assertEquals(30, c.getPrice()); + Assertions.assertEquals(10, f.getPrice()); + } + + @Test + public void shouldGetNameItem() { + Item b = new Bagel("B", 20, "Aa", "Ab"); + Coffee c = new Coffee("C", 20, "Cc", "Cd"); + Filling f = new Filling("F", 5, "Ff", "Fg"); + Assertions.assertEquals("Aa", b.getName()); + Assertions.assertEquals("Cc", c.getName()); + Assertions.assertEquals("Ff", f.getName()); + } + + @Test + public void shouldGetVariant() { + Item b = new Bagel("B", 20, "Aa", "Ab"); + Coffee c = new Coffee("C", 30, "Cc", "Cd"); + Filling f = new Filling("F", 20, "Ff", "Fg"); + Assertions.assertEquals("Ab", b.getVariant()); + Assertions.assertEquals("Cd", c.getVariant()); + Assertions.assertEquals("Fg", f.getVariant()); + } + + // MANAGER + @Test + public void shouldSetNewCapacity() { + Manager m = new Manager(); + Basket b = new Basket(10); + Assertions.assertEquals(10, b.getCapacity()); + m.setCapacity(b, 5); + Assertions.assertEquals(5, b.getCapacity()); + } + + @Test + public void shouldFindInItems() { + Manager m = new Manager(); + Basket bas = new Basket(10); + Item b = new Bagel("B", 20, "Aa", "Ab"); + Coffee c = new Coffee("C", 30, "Cc", "Cd"); + Filling f = new Filling("F", 10, "Ff", "Fg"); + bas.add(b); bas.add(c); bas.add(f); + // FIX THIS + // think I may need a map or something like in the Scrabble exercise + // predefined inventory to "match" if item is valid + } + + // BASKET + @Test + public void shouldAdd() { + Basket bas = new Basket(10); + Item b = new Bagel("B", 20, "Aa", "Ab"); + Coffee c = new Coffee("C", 30, "Cc", "Cd"); + Filling f = new Filling("F", 10, "Ff", "Fg"); + Assertions.assertTrue(bas.add(b)); + bas.add(b); bas.add(c); bas.add(f); + Assertions.assertEquals(3, bas.getItems().size()); + } + + @Test + public void shouldRemove() { + Basket bas = new Basket(10); + Item b = new Bagel("B", 20, "Aa", "Ab"); + Coffee c = new Coffee("C", 30, "Cc", "Cd"); + Filling f = new Filling("F", 10, "Ff", "Fg"); + bas.add(b); bas.add(c); bas.add(f); + bas.remove("C"); + Assertions.assertEquals(2, bas.getItems().size()); + } + + @Test + public void shouldGetTotalCost() { + Basket bas = new Basket(10); + Item b = new Bagel("B", 20, "Aa", "Ab"); + Coffee c = new Coffee("C", 30, "Cc", "Cd"); + Filling f = new Filling("F", 10, "Ff", "Fg"); + bas.add(b); bas.add(c); bas.add(f); + Assertions.assertEquals(60, bas.getTotalCost()); + } + + @Test + public void shouldGetCap() { + Basket bas = new Basket(10); + Assertions.assertEquals(10, bas.getCapacity()); + Manager m = new Manager(); + m.setCapacity(bas, 100); + Assertions.assertEquals(100, bas.getCapacity()); + } + + @Test + public void shouldGetAvailableCap() { + Basket bas = new Basket(10); + Item b = new Bagel("B", 20, "Aa", "Ab"); + bas.add(b); + Assertions.assertEquals(9, bas.getAvailableCapacity()); + Manager m = new Manager(); + m.setCapacity(bas, 100); + Assertions.assertEquals(99, bas.getAvailableCapacity()); + } +} From 7f59aeb6cbf4331080c6af9d6b294f25ea400e78 Mon Sep 17 00:00:00 2001 From: Marie Helene Hansen Date: Mon, 11 Aug 2025 16:00:47 +0200 Subject: [PATCH 2/7] domain model + tests --- src/main/java/com/booleanuk/core/Bagel.java | 12 +++- src/main/java/com/booleanuk/core/Basket.java | 37 +++++++++-- .../java/com/booleanuk/core/Customer.java | 15 ++++- src/main/java/com/booleanuk/core/Guest.java | 18 ++--- src/main/java/com/booleanuk/core/Item.java | 8 +-- src/main/java/com/booleanuk/core/Manager.java | 5 +- .../java/com/booleanuk/core/CoreTest.java | 65 +++++++++++-------- 7 files changed, 105 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/booleanuk/core/Bagel.java b/src/main/java/com/booleanuk/core/Bagel.java index 9eb44edb7..8520e66c2 100644 --- a/src/main/java/com/booleanuk/core/Bagel.java +++ b/src/main/java/com/booleanuk/core/Bagel.java @@ -13,14 +13,20 @@ public Bagel(String SKU, float price, String name, String variant) { } public boolean addFilling(Filling f) { - return false; + // make void? or keep boolean and set max number of fillings? + fillingList.add(f); + return true; } public List getFillingList() { - return null; + return this.fillingList; } public float getPriceWithFillings() { - return 0; + float updatedPrice = this.getPrice(); + for (Filling f : this.getFillingList()) { + updatedPrice += f.getPrice(); + } + return updatedPrice; } } diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java index 1c240e061..e86cf2826 100644 --- a/src/main/java/com/booleanuk/core/Basket.java +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -17,12 +17,36 @@ public Map getItems() { return items; } + public boolean setCapacity(int newCap) { + if (newCap < 0 || newCap > 100) { + return false; + } + this.capacity = newCap; + return true; + } + public boolean add(Item item) { - return false; + if (this.isFull()) { + return false; + } + else { + if (this.items.containsKey(item)) { + int amount = this.items.get(item) + 1; + this.items.put(item, amount); + } + else { + this.items.put(item, 1); + } + return true; + } } - public boolean remove(String SKU) { - return false; + public boolean remove(Item item) { + if (!this.items.containsKey(item)) { + return false; + } + this.items.remove(item); + return true; } public float getTotalCost() { @@ -30,19 +54,18 @@ public float getTotalCost() { } public int getCapacity() { - return 0; + return this.capacity - this.items.size(); } public int getAvailableCapacity() { // available after items are added // getCapacity if items-map is empty // check this first, make sure Manager does not screw it up + return 0; } public boolean isFull() { - return false; + return getCapacity() < this.items.size(); } - - } diff --git a/src/main/java/com/booleanuk/core/Customer.java b/src/main/java/com/booleanuk/core/Customer.java index 1e4237e57..7c95184fd 100644 --- a/src/main/java/com/booleanuk/core/Customer.java +++ b/src/main/java/com/booleanuk/core/Customer.java @@ -9,15 +9,24 @@ public Customer(String name) { } public float getTotalPriceBasket() { - return 0; + float total = 0; + for (Item i : this.getBasket().getItems().keySet()) { + if (i instanceof Bagel) { + total += ((Bagel) i).getPriceWithFillings(); + } + else { + total += i.getPrice(); + } + } + return total; } public float getPriceBagel(Bagel b) { - return 0; + return b.getPriceWithFillings(); } public float getPriceFilling(Filling f) { - return 0; + return f.getPrice(); } public boolean setFillings(List fillingList) { diff --git a/src/main/java/com/booleanuk/core/Guest.java b/src/main/java/com/booleanuk/core/Guest.java index b2dc73a73..41d8290ac 100644 --- a/src/main/java/com/booleanuk/core/Guest.java +++ b/src/main/java/com/booleanuk/core/Guest.java @@ -12,22 +12,22 @@ public Guest(String name) { } public Basket getBasket() { - return null; + return this.basket; } - public boolean addToBasket(Item it) { - return false; + public boolean addToBasket(Item item) { + return this.basket.add(item); } - public boolean removeFromBasket(Item it) { - return false; + public boolean removeFromBasket(Item item) { + return this.basket.remove(item); } - public boolean isBasketFull() { - return false; + public boolean guestBasketIsFull() { + return this.basket.isFull(); } - public boolean hasItemInBasket(Item it) { - return false; + public boolean hasItemInBasket(Item item) { + return this.basket.getItems().containsKey(item); } } diff --git a/src/main/java/com/booleanuk/core/Item.java b/src/main/java/com/booleanuk/core/Item.java index c0d5ecdf3..41ab4ec0f 100644 --- a/src/main/java/com/booleanuk/core/Item.java +++ b/src/main/java/com/booleanuk/core/Item.java @@ -14,18 +14,18 @@ public Item(String SKU, float price, String name, String variant) { } public String getSKU() { - return null; + return this.SKU; } public float getPrice() { - return 0; + return this.price; } public String getName() { - return null; + return this.name; } public String getVariant() { - return null; + return this.variant; } } diff --git a/src/main/java/com/booleanuk/core/Manager.java b/src/main/java/com/booleanuk/core/Manager.java index d62a179f5..093eb0f92 100644 --- a/src/main/java/com/booleanuk/core/Manager.java +++ b/src/main/java/com/booleanuk/core/Manager.java @@ -6,11 +6,12 @@ public Manager() { } - public int setCapacity(Basket b, int cap) { - return 0; + public boolean setCapacity(Basket b, int cap) { + return b.setCapacity(cap); } public boolean isInItems(Basket b) { + // make a map for inventory, check here return false; } } diff --git a/src/test/java/com/booleanuk/core/CoreTest.java b/src/test/java/com/booleanuk/core/CoreTest.java index 1be9756b2..738a8944e 100644 --- a/src/test/java/com/booleanuk/core/CoreTest.java +++ b/src/test/java/com/booleanuk/core/CoreTest.java @@ -10,27 +10,28 @@ public class CoreTest { // GUEST @Test public void shouldAddToBasket() { - Basket b = new Basket(2); + Guest g = new Guest("Gio"); Bagel bg = new Bagel("A", 20, "Aa", "Ab"); - b.add(bg); - Assertions.assertTrue(b.getItems().containsKey(bg)); + g.addToBasket(bg); + Assertions.assertTrue(g.getBasket().getItems().containsKey(bg)); } @Test public void shouldRemoveFromBasket() { - Basket b = new Basket(2); + Guest g = new Guest("Gio"); Bagel bg = new Bagel("A", 20, "Aa", "Ab"); - b.add(bg); - b.remove(bg.getSKU()); - Assertions.assertFalse(b.getItems().containsKey(bg)); + g.removeFromBasket(bg); + Assertions.assertFalse(g.getBasket().getItems().containsKey(bg)); } @Test public void shouldBeFull() { - Basket b = new Basket(2); - b.add(new Bagel("A", 20, "Aa", "Ab")); - b.add(new Bagel("B", 20, "Bb", "Bc")); - Assertions.assertTrue(b.isFull()); + Guest g = new Guest("Gio"); + Manager m = new Manager(); + m.setCapacity(g.getBasket(), 2); + g.addToBasket(new Bagel("A", 20, "Aa", "Ab")); + g.addToBasket(new Bagel("B", 20, "Bb", "Bc")); + Assertions.assertTrue(g.getBasket().isFull()); } @Test @@ -38,7 +39,8 @@ public void shouldNotHaveItemToRemove() { Basket b = new Basket(2); b.add(new Bagel("A", 20, "Aa", "Ab")); b.add(new Bagel("B", 20, "Bb", "Bc")); - Assertions.assertFalse(b.remove("C")); + Item c = new Bagel("C", 100, "Cc", "Cd"); + Assertions.assertFalse(b.remove(c)); } // CUSTOMER @@ -49,7 +51,7 @@ public void shouldGetTotalPriceBasket() { Bagel b = new Bagel("B", 20, "Bb", "Bc"); c.getBasket().add(a); c.getBasket().add(b); - Assertions.assertEquals(a.getPrice()+b.getPrice(), c.getBasket().getTotalCost()); + Assertions.assertEquals(a.getPrice()+b.getPrice(), c.getTotalPriceBasket()); } @Test @@ -117,6 +119,15 @@ public void shouldGetVariant() { Assertions.assertEquals("Fg", f.getVariant()); } + @Test + public void getPriceBagelWithFilling() { + Bagel b = new Bagel("B", 20, "Aa", "Ab"); + Filling f1 = new Filling("F", 10, "Ff", "Fg"); + Filling f2 = new Filling("F", 10, "Ff", "Fg"); + b.addFilling(f1); b.addFilling(f2); + Assertions.assertEquals(40, b.getPriceWithFillings()); + } + // MANAGER @Test public void shouldSetNewCapacity() { @@ -142,13 +153,24 @@ public void shouldFindInItems() { // BASKET @Test - public void shouldAdd() { + public void shouldNotBeFull() { Basket bas = new Basket(10); + Assertions.assertFalse(bas.isFull()); Item b = new Bagel("B", 20, "Aa", "Ab"); Coffee c = new Coffee("C", 30, "Cc", "Cd"); Filling f = new Filling("F", 10, "Ff", "Fg"); - Assertions.assertTrue(bas.add(b)); bas.add(b); bas.add(c); bas.add(f); + Assertions.assertFalse(bas.isFull()); + } + @Test + public void shouldAdd() { + Basket bas = new Basket(10); + Item b = new Bagel("B", 20, "Aa", "Ab"); + Coffee c = new Coffee("C", 30, "Cc", "Cd"); + Filling f = new Filling("F", 10, "Ff", "Fg"); + bas.add(b); + bas.add(c); + bas.add(f); Assertions.assertEquals(3, bas.getItems().size()); } @@ -159,7 +181,7 @@ public void shouldRemove() { Coffee c = new Coffee("C", 30, "Cc", "Cd"); Filling f = new Filling("F", 10, "Ff", "Fg"); bas.add(b); bas.add(c); bas.add(f); - bas.remove("C"); + bas.remove(c); Assertions.assertEquals(2, bas.getItems().size()); } @@ -181,15 +203,4 @@ public void shouldGetCap() { m.setCapacity(bas, 100); Assertions.assertEquals(100, bas.getCapacity()); } - - @Test - public void shouldGetAvailableCap() { - Basket bas = new Basket(10); - Item b = new Bagel("B", 20, "Aa", "Ab"); - bas.add(b); - Assertions.assertEquals(9, bas.getAvailableCapacity()); - Manager m = new Manager(); - m.setCapacity(bas, 100); - Assertions.assertEquals(99, bas.getAvailableCapacity()); - } } From 4061c65883f0d95d6e5d068a7391b562ea8f62b0 Mon Sep 17 00:00:00 2001 From: Marie Helene Hansen Date: Tue, 12 Aug 2025 08:27:08 +0200 Subject: [PATCH 3/7] passed tests --- src/main/java/com/booleanuk/core/Basket.java | 11 ++++++++++- src/main/java/com/booleanuk/core/Customer.java | 11 +---------- src/test/java/com/booleanuk/core/CoreTest.java | 5 +++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java index e86cf2826..d1febd1b5 100644 --- a/src/main/java/com/booleanuk/core/Basket.java +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -50,9 +50,18 @@ public boolean remove(Item item) { } public float getTotalCost() { - return 0; + float total = 0; + for (Item i : this.getItems().keySet()) { + if (i instanceof Bagel) { + total += ((Bagel) i).getPriceWithFillings(); + } else { + total += i.getPrice(); + } + } + return total; } + public int getCapacity() { return this.capacity - this.items.size(); } diff --git a/src/main/java/com/booleanuk/core/Customer.java b/src/main/java/com/booleanuk/core/Customer.java index 7c95184fd..0554e7bb6 100644 --- a/src/main/java/com/booleanuk/core/Customer.java +++ b/src/main/java/com/booleanuk/core/Customer.java @@ -9,16 +9,7 @@ public Customer(String name) { } public float getTotalPriceBasket() { - float total = 0; - for (Item i : this.getBasket().getItems().keySet()) { - if (i instanceof Bagel) { - total += ((Bagel) i).getPriceWithFillings(); - } - else { - total += i.getPrice(); - } - } - return total; + return this.getBasket().getTotalCost(); } public float getPriceBagel(Bagel b) { diff --git a/src/test/java/com/booleanuk/core/CoreTest.java b/src/test/java/com/booleanuk/core/CoreTest.java index 738a8944e..a536c2291 100644 --- a/src/test/java/com/booleanuk/core/CoreTest.java +++ b/src/test/java/com/booleanuk/core/CoreTest.java @@ -74,8 +74,9 @@ public void shouldGetFillingPrice() { public void shouldSetFillings() { Customer c = new Customer("Dave"); Bagel a = new Bagel("A", 20, "Aa", "Ab"); - a.addFilling(new Filling("F", 20, "Ff", "Fg")); - Assertions.assertEquals(List.of(new Filling("F", 20, "Ff", "Fg")), a.getFillingList()); + Filling f = new Filling("F", 20, "Ff", "Fg"); + a.addFilling(f); + Assertions.assertEquals(List.of(f), a.getFillingList()); } // ITEM: Bagel, Coffee, Filling From 7fcd8a4d1d8301a1167b21933f8621aa9fdb2247 Mon Sep 17 00:00:00 2001 From: Marie Helene Hansen Date: Tue, 12 Aug 2025 09:49:44 +0200 Subject: [PATCH 4/7] passed tests --- src/main/java/com/booleanuk/core/Customer.java | 13 +++++++++++-- src/test/java/com/booleanuk/core/CoreTest.java | 6 ++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/booleanuk/core/Customer.java b/src/main/java/com/booleanuk/core/Customer.java index 0554e7bb6..1f54be123 100644 --- a/src/main/java/com/booleanuk/core/Customer.java +++ b/src/main/java/com/booleanuk/core/Customer.java @@ -20,7 +20,16 @@ public float getPriceFilling(Filling f) { return f.getPrice(); } - public boolean setFillings(List fillingList) { - return false; + public boolean setFillings(Bagel b, List fillingList) { + if (this.getBasket().isFull()) { + return false; + } + else if (!this.getBasket().getItems().containsKey(b)) { + return false; + } + for (Filling f : fillingList) { + b.addFilling(f); + } + return true; } } diff --git a/src/test/java/com/booleanuk/core/CoreTest.java b/src/test/java/com/booleanuk/core/CoreTest.java index a536c2291..e3a580ba4 100644 --- a/src/test/java/com/booleanuk/core/CoreTest.java +++ b/src/test/java/com/booleanuk/core/CoreTest.java @@ -75,8 +75,10 @@ public void shouldSetFillings() { Customer c = new Customer("Dave"); Bagel a = new Bagel("A", 20, "Aa", "Ab"); Filling f = new Filling("F", 20, "Ff", "Fg"); - a.addFilling(f); - Assertions.assertEquals(List.of(f), a.getFillingList()); + Filling g = new Filling("F", 20, "Ff", "Fg"); + c.getBasket().add(a); + c.setFillings(a, List.of(f, g)); + Assertions.assertEquals(List.of(f, g), a.getFillingList()); } // ITEM: Bagel, Coffee, Filling From 92f30805554315953d7942db6c93aee49da79ee0 Mon Sep 17 00:00:00 2001 From: Marie Helene Hansen Date: Tue, 12 Aug 2025 09:55:25 +0200 Subject: [PATCH 5/7] passed tests --- src/main/java/com/booleanuk/core/Item.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/booleanuk/core/Item.java b/src/main/java/com/booleanuk/core/Item.java index 41ab4ec0f..36b3367a6 100644 --- a/src/main/java/com/booleanuk/core/Item.java +++ b/src/main/java/com/booleanuk/core/Item.java @@ -1,10 +1,10 @@ package com.booleanuk.core; abstract public class Item { - private String SKU; - private float price; - private String name; - private String variant; + private final String SKU; + private final float price; // methods for basketPrice for discounts + private final String name; + private final String variant; public Item(String SKU, float price, String name, String variant) { this.SKU = SKU; From fd5fafef7798f066201a42df65e798d339561662 Mon Sep 17 00:00:00 2001 From: Marie Helene Hansen Date: Tue, 12 Aug 2025 10:02:52 +0200 Subject: [PATCH 6/7] add bagel price test in customer --- src/test/java/com/booleanuk/core/CoreTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/com/booleanuk/core/CoreTest.java b/src/test/java/com/booleanuk/core/CoreTest.java index e3a580ba4..a4935a7b0 100644 --- a/src/test/java/com/booleanuk/core/CoreTest.java +++ b/src/test/java/com/booleanuk/core/CoreTest.java @@ -81,6 +81,17 @@ public void shouldSetFillings() { Assertions.assertEquals(List.of(f, g), a.getFillingList()); } + @Test + public void shouldGetPriceWithFillings() { + Customer c = new Customer("Dave"); + Bagel a = new Bagel("A", 20, "Aa", "Ab"); + Filling f = new Filling("F", 20, "Ff", "Fg"); + Filling g = new Filling("F", 20, "Ff", "Fg"); + c.getBasket().add(a); + c.setFillings(a, List.of(f, g)); + Assertions.assertEquals(a.getPrice()+f.getPrice()+g.getPrice(), c.getPriceBagel(a)); + } + // ITEM: Bagel, Coffee, Filling @Test public void shouldGetSKUItem() { From dc3ea1da51f82df40f99c554793c57f724777b72 Mon Sep 17 00:00:00 2001 From: Marie Helene Hansen Date: Tue, 12 Aug 2025 21:12:39 +0200 Subject: [PATCH 7/7] extension task 1 --- src/main/java/com/booleanuk/core/Basket.java | 157 +++++++++++++++++- src/main/java/com/booleanuk/core/Manager.java | 4 - .../java/com/booleanuk/core/domain-model.md | 90 +++++----- .../java/com/booleanuk/core/CoreTest.java | 47 +++++- 4 files changed, 245 insertions(+), 53 deletions(-) diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java index d1febd1b5..9fbd5eba2 100644 --- a/src/main/java/com/booleanuk/core/Basket.java +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -1,5 +1,6 @@ package com.booleanuk.core; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -13,11 +14,127 @@ public Basket(int capacity) { items = new HashMap<>(); } + private boolean hasBGL6Offer() { + + if (this.items.isEmpty()) { + return false; + } + + int numBagels = 0; + for (Map.Entry entry : this.items.entrySet()) { + if (entry.getKey() instanceof Bagel) { + numBagels += entry.getValue(); + } + } + return numBagels >= 6; + } + + private boolean hasCOFBOffer() { + if (items.isEmpty() || items.size() < 2 || getCapacity() < 2) { + return false; + } + return this.items.keySet().stream().anyMatch(Coffee.class::isInstance) && this.items.keySet().stream().anyMatch(Bagel.class::isInstance); + } + + private boolean hasBGL12Offer() { + if (this.items.isEmpty()) { + return false; + } + + int numBagels = 0; + for (Map.Entry entry : this.items.entrySet()) { + + if (entry.getKey() instanceof Bagel) { + numBagels += entry.getValue(); + } + } + return numBagels >= 12; + } + + private int getDozens(Map items) { + + int bagelCount = 0; + for (Map.Entry entry : items.entrySet()) { + + if (entry.getKey() instanceof Bagel) { + bagelCount += entry.getValue(); + } + } + return bagelCount / 12; + } + + private int getSixes(Map items) { + + int bagelCount = 0; + for (Map.Entry entry : items.entrySet()) { + + if (entry.getKey() instanceof Bagel) { + bagelCount += entry.getValue(); + } + } + return bagelCount / 6; + } + + private int getCoffeeBagelCombos(Map items) { + + int bagelCount = 0; + for (Item it : items.keySet()) { + if (it instanceof Bagel) { + bagelCount ++; + } + } + + int coffeeCount = 0; + for (Item it : items.keySet()) { + if (it instanceof Coffee) { + coffeeCount ++; + } + } + return Math.min(bagelCount, coffeeCount); + } + + private void removeBagels(Map its, int countToRemove) { + + // have to make sure countToRemove and current count is checked!! + for (Item it : new ArrayList<>(its.keySet())) { + + if (it instanceof Bagel && countToRemove > 0) { + + int thisCount = its.get(it); + int remove = Math.min(thisCount, countToRemove); + its.put(it, thisCount - remove); + + if (its.get(it) == 0) { + its.remove(it); + } + } + } + } + + private void removeCoffeeAndBagels(Map its, int combos) { + + removeBagels(its, combos); + for (Item it : new ArrayList<>(its.keySet())) { + + if (it instanceof Coffee && combos > 0) { + + int thisCount = its.get(it); + int remove = Math.min(thisCount, combos); + its.put(it, thisCount - remove); + + if (its.get(it) == 0) { + its.remove(it); + } + } + } + } + public Map getItems() { return items; } public boolean setCapacity(int newCap) { + if (newCap < 0 || newCap > 100) { return false; } @@ -50,18 +167,46 @@ public boolean remove(Item item) { } public float getTotalCost() { - float total = 0; - for (Item i : this.getItems().keySet()) { - if (i instanceof Bagel) { - total += ((Bagel) i).getPriceWithFillings(); + float total = 0f; + Map remainingItems = new HashMap<>(this.items); // copy of this.items + + // check 12 bagel offer + if (this.hasBGL12Offer()) { + + int dozens = getDozens(remainingItems); + total += dozens * 3.99f; + + removeBagels(remainingItems, dozens * 12); + } + // check 6 bagel offer + if (this.hasBGL6Offer()) { + + int sixes = getSixes(remainingItems); + total += sixes * 2.49f; + + removeBagels(remainingItems, sixes * 6); + } + + // check if remaining items can get coffee+bagel offer + if (hasCOFBOffer()) { + + int combos = getCoffeeBagelCombos(remainingItems); + total += combos * 1.25f; + + removeCoffeeAndBagels(remainingItems, combos); + } + + for (Item it : remainingItems.keySet()) { + + if (it instanceof Bagel) { + total += ((Bagel) it).getPriceWithFillings(); } else { - total += i.getPrice(); + total += it.getPrice(); } } return total; } - public int getCapacity() { return this.capacity - this.items.size(); } diff --git a/src/main/java/com/booleanuk/core/Manager.java b/src/main/java/com/booleanuk/core/Manager.java index 093eb0f92..e9700a247 100644 --- a/src/main/java/com/booleanuk/core/Manager.java +++ b/src/main/java/com/booleanuk/core/Manager.java @@ -2,10 +2,6 @@ public class Manager { - public Manager() { - - } - public boolean setCapacity(Basket b, int cap) { return b.setCapacity(cap); } diff --git a/src/main/java/com/booleanuk/core/domain-model.md b/src/main/java/com/booleanuk/core/domain-model.md index 94ec9f779..2bbbe09be 100644 --- a/src/main/java/com/booleanuk/core/domain-model.md +++ b/src/main/java/com/booleanuk/core/domain-model.md @@ -1,41 +1,49 @@ -| Classes | Members | Methods | Scenarios | Outputs | -|-----------|------------------------------------|-------------------------------------|-----------------------------|----------------------------| -| Basket | Map, int capacity | add(Item it) | it not an Item | false | -| | | | it is an Item | true | -| | | remove(Item it) | it not an Item | false | -| | | | it is an Item & in Basket | true | -| | | | it is an Item not in Basket | false (+ print message?) | -| | | getTotalCost() | Basket empty | 0 | -| | | | Basket not empty | totalCost | -| Item | String SKU, int price, String name | getSKU() | item not in inventory | null | -| | | | item in inventory | String | -| | | getPrice() | item not in inventory | null | -| | | | item in inventory | float | -| | | getName() | item not in inventory | null | -| | | | item in inventory | String | -| Bagel | List | setFilling(Filling[] f) | empty f | false (error: must choose) | -| | | | f not empty | true | -| Filling | | getPrice() | not a Filling | null | -| | | | is a Filling | price | -| Manager | | changeCapacity(Basket b, int cap) | b not a Basket | null | -| | | isInItems() | all items in Item | true | -| | | | not all items in Item | false | -| | | | b is a Basket | capacity += cap | -| Guest | String name | addToBasket(Bagel bagel) | bagel is in inventory | true | -| | | | bagel not in inventory | false | -| | | removeFromBasket(Bagel bagel) | bagel is in Basket | true | -| | | | bagel not in Basket | false | -| | | isBasketFull() | basket is full | true | -| | | | basket not full | false | -| | | hasItemInBasket(Item item) | basket has item | true | -| | | | basket does not have item | false | -| Customer | | getTotalCostBasket() | basket empty | 0 | -| | | | basket not empty | float | -| | | getPriceBagel(Bagel bagel) | bagel in inventory | float | -| | | | bagel not in inventory | 0 | -| | | setFillings(List fillings) | filling in inventory | true | -| | | | filling not in inventory | false | -| | | getPriceFilling(Filling filling) | filling in inventory | float | -| | | | filling not in inventory | false | -| Inventory | enum! how to list it here | | | | - +| Classes | Members | Methods | Scenarios | Outputs | +|-----------|------------------------------------|-------------------------------------|-----------------------------------|----------------------------| +| Basket | Map, int capacity | add(Item it) | it not an Item | false | +| | | | it is an Item | true | +| | | remove(Item it) | it not an Item | false | +| | | | it is an Item & in Basket | true | +| | | | it is an Item not in Basket | false (+ print message?) | +| | | getTotalCost() | Basket empty | 0 | +| | | | Basket not empty | totalCost | +| | | getTotal(Basket b) | b qualified for special offer | float | +| | | | b not qualified for special offer | b.getTotalCost() | +| | | hasBGL6Offer(Basket b) | Basket has 6 bagels | true | +| | | | Basket has not 6 bagels | false | +| | | hasBGL12Offer(Basket b) | Basket has 12 bagels | true | +| | | | Basket has not 12 bagels | false | +| | | hasCOFBOffer(Basket b) | Basket has coffee && bagel | true | +| | | | Basket has not coffee && bagel | false | +| Item | String SKU, int price, String name | getSKU() | item not in inventory | null | +| | | | item in inventory | String | +| | | getPrice() | item not in inventory | null | +| | | | item in inventory | float | +| | | getName() | item not in inventory | null | +| | | | item in inventory | String | +| Bagel | List | setFilling(Filling[] f) | empty f | false (error: must choose) | +| | | | f not empty | true | +| Filling | | getPrice() | not a Filling | null | +| | | | is a Filling | price | +| Manager | | changeCapacity(Basket b, int cap) | b not a Basket | null | +| | | isInItems() | all items in Item | true | +| | | | not all items in Item | false | +| | | | b is a Basket | capacity += cap | +| Guest | String name | addToBasket(Bagel bagel) | bagel is in inventory | true | +| | | | bagel not in inventory | false | +| | | removeFromBasket(Bagel bagel) | bagel is in Basket | true | +| | | | bagel not in Basket | false | +| | | isBasketFull() | basket is full | true | +| | | | basket not full | false | +| | | hasItemInBasket(Item item) | basket has item | true | +| | | | basket does not have item | false | +| Customer | | getTotalCostBasket() | basket empty | 0 | +| | | | basket not empty | float | +| | | getPriceBagel(Bagel bagel) | bagel in inventory | float | +| | | | bagel not in inventory | 0 | +| | | setFillings(List fillings) | filling in inventory | true | +| | | | filling not in inventory | false | +| | | getPriceFilling(Filling filling) | filling in inventory | float | +| | | | filling not in inventory | false | +| Inventory | enum! how to list it here | ----- createInventory() maybe? | | | +| Receipt | String receipt | printReceipt() | at checkout | String | \ No newline at end of file diff --git a/src/test/java/com/booleanuk/core/CoreTest.java b/src/test/java/com/booleanuk/core/CoreTest.java index a4935a7b0..09e0103bc 100644 --- a/src/test/java/com/booleanuk/core/CoreTest.java +++ b/src/test/java/com/booleanuk/core/CoreTest.java @@ -205,8 +205,10 @@ public void shouldGetTotalCost() { Item b = new Bagel("B", 20, "Aa", "Ab"); Coffee c = new Coffee("C", 30, "Cc", "Cd"); Filling f = new Filling("F", 10, "Ff", "Fg"); - bas.add(b); bas.add(c); bas.add(f); - Assertions.assertEquals(60, bas.getTotalCost()); + bas.add(b); + bas.add(c); + bas.add(f); + Assertions.assertEquals(10+1.25f, bas.getTotalCost()); } @Test @@ -217,4 +219,45 @@ public void shouldGetCap() { m.setCapacity(bas, 100); Assertions.assertEquals(100, bas.getCapacity()); } + + @Test + public void shouldHave12Offer() { + Basket b = new Basket(100); + for (int i = 0; i < 12; i ++) { + Bagel x = new Bagel("a", 0.5f, " ", " "); + b.add(x); + } + Assertions.assertEquals(3.99f, b.getTotalCost()); + } + + /* + // tested initially, but made the methods private only to use in basket.getTotalCost() + @Test + public void shouldHave6Offer() { + Basket b = new Basket(61); + for (int i = 0; i < 6; i ++) { + Bagel x = new Bagel("a", 0.5f, " ", " "); + b.add(x); + } + Assertions.assertTrue(b.hasBGL6Offer()); + } + + @Test + public void shouldHave12Offer() { + Basket b = new Basket(100); + for (int i = 0; i < 12; i ++) { + Bagel x = new Bagel("a", 0.5f, " ", " "); + b.add(x); + } + Assertions.assertTrue(b.hasBGL12Offer()); + } + + @Test + public void shouldHaveCOFBOffer() { + Basket b = new Basket(10); + b.add(new Bagel("a", 0.5f, " ", " ")); + b.add(new Coffee("a", 1.5f, " ", " ")); + Assertions.assertTrue(b.hasCOFBOffer()); + } + */ }