diff --git a/EXERCISE1.md b/EXERCISE1.md index 3af2ea2..4169c99 100644 --- a/EXERCISE1.md +++ b/EXERCISE1.md @@ -24,7 +24,7 @@ Here is how one might design a domain model for the above user story: > **Time to analyse** > > Evaluate the user story and the domain model above. What assumptions did the developer have to make and what would you do differently? -> +> > Create your own domain model for the user story above, try to come up with a different solution than the model provided. You can use a table like the one above, a spreadsheet, pen and paper, whatever you'd like. Share your work in your cohorts classroom channel when you're done. ### Exercise @@ -36,6 +36,16 @@ As a supermarket shopper, So that I can pay for products at checkout, I'd like to be able to know the total cost of items in my basket. ``` +| Classes | Member Variables | Methods | Scenario | Outputs | +|----------|-------------------------|----------------------------------------------------|-------------------------------------|---------| +| | List Inventory | `sumBasket(HashMap basketItems)` | If list is empty | 0.00 | +| | | (key=product, value=amountPurchased) | If list is not empty | Double | +| | | | Partial check-out (returned items?) | Double | +| | | `addToBasket(Product product)` | If name is in inventory list | true | +| `Basket` | | | If name is not in inventory list | false | +| | | `removeFromBasket(Product product)` | If name is in buyer's list | true | +| | | | If name is not in buyer's list | false | + ``` As an organised individual, @@ -43,6 +53,11 @@ So that I can evaluate my shopping habits, I'd like to see an itemised receipt that includes the name and price of the products I bought as well as the quantity, and a total cost of my basket. ``` +| Classes | Member Variables | Methods | Scenario | Outputs | +|-------------|----------------------------------------|---------------|--------------------------------------------------------------|---------| +| `Receipt` | HashMap basketItems | `viewItems()` | If list is empty | String | +| | | | If list is not empty | String | +| | | | Partial check-out (returned items? reimbursements? bonuses?) | String | - Add your domain models to this repository as a file named `domain-model`. This should either be a `.md` file like this one, or a screenshot / picture of your work. - Your model doesn't have to look like the example provided in this file. If you feel like you need more or less columns, feel free to go with that. There is no "right way" to do this kind of thing, we're just designing a system to make our lives easier when it comes to the coding part. \ No newline at end of file diff --git a/EXERCISE2.md b/EXERCISE2.md index 2141e72..44adecd 100644 --- a/EXERCISE2.md +++ b/EXERCISE2.md @@ -1,10 +1,12 @@ # 2. Use the Red Green Refactor workflow to implement a solution -There is a class in `./src/main/java/com.booleanuk/code/CohortManager.java` and a test class in `./src/test/java/com.booleanuk/core/CohortManagerTest.java`. Your morning teacher will demonstrate the process of creating tests from the domain model below, and then using those tests to develop robust source code. +There is a class in `./src/main/java/com.booleanuk/code/CohortManager.java` and a test class in `./src/test/java/com.booleanuk/core/CohortManagerTest.java`. +Your morning teacher will demonstrate the process of creating tests from the domain model below, and then using those tests to develop robust source code. This is known as the **Red, Green, Refactor** workflow; an important discipline to practice. Simple to learn yet difficult to master. -When writing software using this Test Driven Development approach, we don't write a complete test or complete method at a time. We write *just enough* of a test for it to fail, then write *just enough* source code to make the test pass, then refactor until the test fails and repeat this cycle. +When writing software using this Test Driven Development approach, we don't write a complete test or complete method at a time. +We write *just enough* of a test for it to fail, then write *just enough* source code to make the test pass, then refactor until the test fails and repeat this cycle. What we are creating here are known as *unit tests*, tests that verify a single unit of our application is working correctly. They should be as small as possible, usually broken down into three parts: 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 0000000..3f62077 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -0,0 +1,24 @@ +package com.booleanuk.core; + +import java.util.HashMap; + +public class Basket { + public HashMap items; + + public Basket() { + this.items = new HashMap(); + } + + public boolean add(String product, int price) { + return price >= 0 && product.strip().length() != 0 + && this.items.putIfAbsent(product, price) == null; + } + + public int total() { + return this.items.values() + .stream() + .mapToInt(Integer::intValue) + .sum(); + + } +} diff --git a/src/test/java/com/booleanuk/core/BasketTest.java b/src/test/java/com/booleanuk/core/BasketTest.java new file mode 100644 index 0000000..60587ff --- /dev/null +++ b/src/test/java/com/booleanuk/core/BasketTest.java @@ -0,0 +1,60 @@ +package com.booleanuk.core; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class BasketTest { + @Test + public void testAddProductToBasket() { + Basket basket = new Basket(); + Assertions.assertTrue(basket.add("Apple", 2)); + Assertions.assertEquals(1, basket.items.size()); + Assertions.assertTrue(basket.items.containsKey("Apple")); + Assertions.assertEquals(2, basket.items.get("Apple").intValue()); + } + + @Test + public void testAddDuplicateProductToBasket() { + Basket basket = new Basket(); + basket.add("Banana", 3); + Assertions.assertFalse(basket.add("Banana", 2)); + Assertions.assertEquals(1, basket.items.size()); + Assertions.assertTrue(basket.items.containsKey("Banana")); + Assertions.assertEquals(3, basket.items.get("Banana").intValue()); + } + + @Test + public void testAddMultipleProductsToBasket() { + Basket basket = new Basket(); + Assertions.assertTrue(basket.add("Orange", 4)); + Assertions.assertTrue(basket.add("Grapes", 5)); + Assertions.assertEquals(2, basket.items.size()); + } + + @Test + public void testAddAndGetTotalWithEmptyBasket() { + Basket basket = new Basket(); + Assertions.assertEquals(0, basket.total()); + } + + @Test + public void testTotalWithProductsInBasket() { + Basket basket = new Basket(); + basket.add("Orange", 4); + basket.add("Grapes", 5); + Assertions.assertEquals(9, basket.total()); + } + + @Test + public void testAddProductWithNegativePriceToBasket() { + Basket basket = new Basket(); + Assertions.assertFalse(basket.add("Chips", -2)); // Negative price should not be accepted + Assertions.assertEquals(0, basket.items.size()); + } + @Test + public void testAddProductWithMissingNameInBasket() { + Basket basket = new Basket(); + Assertions.assertFalse(basket.add(" ", 2)); // Negative price should not be accepted + Assertions.assertEquals(0, basket.items.size()); + } +} \ No newline at end of file