From a8dbdba9caafd75e626df3fe2f15d5a2d1417810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Fr=C4=85cz?= Date: Wed, 8 Jan 2020 15:31:13 +0100 Subject: [PATCH 01/11] Specs! --- .../pl/edu/agh/mwo/invoice/InvoiceTest.java | 107 ++++++++++++++++++ .../agh/mwo/invoice/product/ProductTest.java | 57 ++++++++++ 2 files changed, 164 insertions(+) create mode 100644 src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java create mode 100644 src/test/java/pl/edu/agh/mwo/invoice/product/ProductTest.java diff --git a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java new file mode 100644 index 000000000..8dce08e28 --- /dev/null +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -0,0 +1,107 @@ +package pl.edu.agh.mwo.invoice; + +import java.math.BigDecimal; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import pl.edu.agh.mwo.invoice.Invoice; +import pl.edu.agh.mwo.invoice.product.DairyProduct; +import pl.edu.agh.mwo.invoice.product.OtherProduct; +import pl.edu.agh.mwo.invoice.product.Product; +import pl.edu.agh.mwo.invoice.product.TaxFreeProduct; + +public class InvoiceTest { + private Invoice invoice; + + @Before + public void createEmptyInvoiceForTheTest() { + invoice = new Invoice(); + } + + @Test + public void testEmptyInvoiceHasEmptySubtotal() { + Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getSubtotal())); + } + + @Test + public void testEmptyInvoiceHasEmptyTaxAmount() { + Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getTax())); + } + + @Test + public void testEmptyInvoiceHasEmptyTotal() { + Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getTotal())); + } + + @Test + public void testInvoiceHasTheSameSubtotalAndTotalIfTaxIsZero() { + Product taxFreeProduct = new TaxFreeProduct("Warzywa", new BigDecimal("199.99")); + invoice.addProduct(taxFreeProduct); + Assert.assertThat(invoice.getTotal(), Matchers.comparesEqualTo(invoice.getSubtotal())); + } + + @Test + public void testInvoiceHasProperSubtotalForManyProducts() { + invoice.addProduct(new TaxFreeProduct("Owoce", new BigDecimal("200"))); + invoice.addProduct(new DairyProduct("Maslanka", new BigDecimal("100"))); + invoice.addProduct(new OtherProduct("Wino", new BigDecimal("10"))); + Assert.assertThat(new BigDecimal("310"), Matchers.comparesEqualTo(invoice.getSubtotal())); + } + + @Test + public void testInvoiceHasProperTaxValueForManyProduct() { + // tax: 0 + invoice.addProduct(new TaxFreeProduct("Pampersy", new BigDecimal("200"))); + // tax: 8 + invoice.addProduct(new DairyProduct("Kefir", new BigDecimal("100"))); + // tax: 2.30 + invoice.addProduct(new OtherProduct("Piwko", new BigDecimal("10"))); + Assert.assertThat(new BigDecimal("10.30"), Matchers.comparesEqualTo(invoice.getTax())); + } + + @Test + public void testInvoiceHasProperTotalValueForManyProduct() { + // price with tax: 200 + invoice.addProduct(new TaxFreeProduct("Maskotki", new BigDecimal("200"))); + // price with tax: 108 + invoice.addProduct(new DairyProduct("Maslo", new BigDecimal("100"))); + // price with tax: 12.30 + invoice.addProduct(new OtherProduct("Chipsy", new BigDecimal("10"))); + Assert.assertThat(new BigDecimal("320.30"), Matchers.comparesEqualTo(invoice.getTotal())); + } + + @Test + public void testInvoiceHasPropoerSubtotalWithQuantityMoreThanOne() { + // 2x kubek - price: 10 + invoice.addProduct(new TaxFreeProduct("Kubek", new BigDecimal("5")), 2); + // 3x kozi serek - price: 30 + invoice.addProduct(new DairyProduct("Kozi Serek", new BigDecimal("10")), 3); + // 1000x pinezka - price: 10 + invoice.addProduct(new OtherProduct("Pinezka", new BigDecimal("0.01")), 1000); + Assert.assertThat(new BigDecimal("50"), Matchers.comparesEqualTo(invoice.getSubtotal())); + } + + @Test + public void testInvoiceHasPropoerTotalWithQuantityMoreThanOne() { + // 2x chleb - price with tax: 10 + invoice.addProduct(new TaxFreeProduct("Chleb", new BigDecimal("5")), 2); + // 3x chedar - price with tax: 32.40 + invoice.addProduct(new DairyProduct("Chedar", new BigDecimal("10")), 3); + // 1000x pinezka - price with tax: 12.30 + invoice.addProduct(new OtherProduct("Pinezka", new BigDecimal("0.01")), 1000); + Assert.assertThat(new BigDecimal("54.70"), Matchers.comparesEqualTo(invoice.getTotal())); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvoiceWithZeroQuantity() { + invoice.addProduct(new TaxFreeProduct("Tablet", new BigDecimal("1678")), 0); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvoiceWithNegativeQuantity() { + invoice.addProduct(new DairyProduct("Zsiadle mleko", new BigDecimal("5.55")), -1); + } +} diff --git a/src/test/java/pl/edu/agh/mwo/invoice/product/ProductTest.java b/src/test/java/pl/edu/agh/mwo/invoice/product/ProductTest.java new file mode 100644 index 000000000..9b3c5bd6e --- /dev/null +++ b/src/test/java/pl/edu/agh/mwo/invoice/product/ProductTest.java @@ -0,0 +1,57 @@ +package pl.edu.agh.mwo.invoice.product; + +import java.math.BigDecimal; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; + +import pl.edu.agh.mwo.invoice.product.Product; + +public class ProductTest { + @Test + public void testProductNameIsCorrect() { + Product product = new OtherProduct("buty", new BigDecimal("100.0")); + Assert.assertEquals("buty", product.getName()); + } + + @Test + public void testProductPriceAndTaxWithDefaultTax() { + Product product = new OtherProduct("Ogorki", new BigDecimal("100.0")); + Assert.assertThat(new BigDecimal("100"), Matchers.comparesEqualTo(product.getPrice())); + Assert.assertThat(new BigDecimal("0.23"), Matchers.comparesEqualTo(product.getTaxPercent())); + } + + @Test + public void testProductPriceAndTaxWithDairyProduct() { + Product product = new DairyProduct("Szarlotka", new BigDecimal("100.0")); + Assert.assertThat(new BigDecimal("100"), Matchers.comparesEqualTo(product.getPrice())); + Assert.assertThat(new BigDecimal("0.08"), Matchers.comparesEqualTo(product.getTaxPercent())); + } + + @Test + public void testPriceWithTax() { + Product product = new DairyProduct("Oscypek", new BigDecimal("100.0")); + Assert.assertThat(new BigDecimal("108"), Matchers.comparesEqualTo(product.getPriceWithTax())); + } + + @Test(expected = IllegalArgumentException.class) + public void testProductWithNullName() { + new OtherProduct(null, new BigDecimal("100.0")); + } + + @Test(expected = IllegalArgumentException.class) + public void testProductWithEmptyName() { + new TaxFreeProduct("", new BigDecimal("100.0")); + } + + @Test(expected = IllegalArgumentException.class) + public void testProductWithNullPrice() { + new DairyProduct("Banany", null); + } + + @Test(expected = IllegalArgumentException.class) + public void testProductWithNegativePrice() { + new TaxFreeProduct("Mandarynki", new BigDecimal("-1.00")); + } +} From 005f93bf3c60f18d725e58063bea02709c4a6b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Fr=C4=85cz?= Date: Sat, 5 Feb 2022 12:23:34 +0100 Subject: [PATCH 02/11] New invoice tests --- .../java/pl/edu/agh/mwo/invoice/InvoiceTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java index 8dce08e28..93666ea8c 100644 --- a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -36,6 +36,22 @@ public void testEmptyInvoiceHasEmptyTotal() { Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getTotal())); } + @Test + public void testInvoiceSubtotalWithTwoDifferentProducts() { + Product onions = new TaxFreeProduct("Warzywa", new BigDecimal("10")); + Product apples = new TaxFreeProduct("Owoce", new BigDecimal("10")); + invoice.addProduct(onions); + invoice.addProduct(apples); + Assert.assertThat(new BigDecimal("20"), Matchers.comparesEqualTo(invoice.getSubtotal())); + } + + @Test + public void testInvoiceSubtotalWithManySameProducts() { + Product onions = new TaxFreeProduct("Warzywa", new BigDecimal("10")); + invoice.addProduct(onions, 100); + Assert.assertThat(new BigDecimal("1000"), Matchers.comparesEqualTo(invoice.getSubtotal())); + } + @Test public void testInvoiceHasTheSameSubtotalAndTotalIfTaxIsZero() { Product taxFreeProduct = new TaxFreeProduct("Warzywa", new BigDecimal("199.99")); From d0b574259095f3391a1875e5a8e6414cfe4d0a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Fr=C4=85cz?= Date: Sat, 26 Feb 2022 16:22:29 +0100 Subject: [PATCH 03/11] Add test for null product check --- src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java index 93666ea8c..7f4b6f795 100644 --- a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -47,7 +47,7 @@ public void testInvoiceSubtotalWithTwoDifferentProducts() { @Test public void testInvoiceSubtotalWithManySameProducts() { - Product onions = new TaxFreeProduct("Warzywa", new BigDecimal("10")); + Product onions = new TaxFreeProduct("Warzywa", BigDecimal.valueOf(10)); invoice.addProduct(onions, 100); Assert.assertThat(new BigDecimal("1000"), Matchers.comparesEqualTo(invoice.getSubtotal())); } @@ -120,4 +120,9 @@ public void testInvoiceWithZeroQuantity() { public void testInvoiceWithNegativeQuantity() { invoice.addProduct(new DairyProduct("Zsiadle mleko", new BigDecimal("5.55")), -1); } + + @Test(expected = IllegalArgumentException.class) + public void testAddingNullProduct() { + invoice.addProduct(null); + } } From 38393a36ce5cf745c61f8cfed4e9fe133ae72a07 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Sun, 15 Feb 2026 21:25:13 +0100 Subject: [PATCH 04/11] =?UTF-8?q?Product:=20implementacja=20getter=C3=B3w?= =?UTF-8?q?=20i=20priceWithTax=20=E2=80=93=204=20testy=20przechodz=C4=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pl/edu/agh/mwo/invoice/product/Product.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java index 318de9ac9..ed232d636 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java @@ -16,18 +16,18 @@ protected Product(String name, BigDecimal price, BigDecimal tax) { } public String getName() { - return null; + return name; } public BigDecimal getPrice() { - return null; + return price; } public BigDecimal getTaxPercent() { - return null; + return taxPercent; } public BigDecimal getPriceWithTax() { - return null; + return price.add(price.multiply(taxPercent)); } } From 81c7a81ec609fd5c034dd4e67655e481f812a66e Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Sun, 15 Feb 2026 21:52:26 +0100 Subject: [PATCH 05/11] =?UTF-8?q?Product:=20pe=C5=82na=20implementacja=20z?= =?UTF-8?q?godna=20z=20ProductTest=20=E2=80=93=20wszystkie=20testy=20przec?= =?UTF-8?q?hodz=C4=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/pl/edu/agh/mwo/invoice/product/Product.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java index ed232d636..ee782a311 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java @@ -10,6 +10,15 @@ public abstract class Product { private final BigDecimal taxPercent; protected Product(String name, BigDecimal price, BigDecimal tax) { + + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("Product name cannot be null or blank"); + } + + if (price == null || price.compareTo(BigDecimal.ZERO) < 0) { + throw new IllegalArgumentException("Product price cannot be null or negative"); + } + this.name = name; this.price = price; this.taxPercent = tax; From 36b97c5c286ef72179fd784528293a9dc8cc246e Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Mon, 16 Feb 2026 00:47:39 +0100 Subject: [PATCH 06/11] =?UTF-8?q?Invoice:=20obs=C5=82uga=20pustej=20faktur?= =?UTF-8?q?y?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pl/edu/agh/mwo/invoice/Invoice.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index 56fe02359..053c99cf2 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -17,11 +17,11 @@ public void addProduct(Product product, Integer quantity) { } public BigDecimal getSubtotal() { - return null; + return BigDecimal.ZERO; } public BigDecimal getTax() { - return null; + return BigDecimal.ZERO; } public BigDecimal getTotal() { From b59e320e8421f9e48082dc5a6f5bbaedee7b9213 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Mon, 16 Feb 2026 00:59:04 +0100 Subject: [PATCH 07/11] =?UTF-8?q?Invoice:=20implementacja=20addProduct()?= =?UTF-8?q?=20i=20subtotal=20dla=20pojedynczych=20produkt=C3=B3w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pl/edu/agh/mwo/invoice/Invoice.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index 053c99cf2..85f5b3288 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -1,15 +1,16 @@ package pl.edu.agh.mwo.invoice; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Collection; import pl.edu.agh.mwo.invoice.product.Product; public class Invoice { - private Collection products; + private Collection products = new ArrayList<>(); public void addProduct(Product product) { - // TODO: implement + products.add(product); } public void addProduct(Product product, Integer quantity) { @@ -17,7 +18,13 @@ public void addProduct(Product product, Integer quantity) { } public BigDecimal getSubtotal() { - return BigDecimal.ZERO; + + BigDecimal subtotal = BigDecimal.ZERO; + + for (Product product : products) { + subtotal = subtotal.add(product.getPrice()); + } + return subtotal; } public BigDecimal getTax() { @@ -25,6 +32,6 @@ public BigDecimal getTax() { } public BigDecimal getTotal() { - return null; + return BigDecimal.ZERO; } } From d7ee446fa3c93ffff7ad3312e48de103e0f79615 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Mon, 16 Feb 2026 18:32:37 +0100 Subject: [PATCH 08/11] =?UTF-8?q?Invoice:=20obs=C5=82uga=20quantity=20w=20?= =?UTF-8?q?subtotal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/pl/edu/agh/mwo/invoice/Invoice.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index 85f5b3288..08ec3b4d7 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -3,26 +3,32 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import pl.edu.agh.mwo.invoice.product.Product; public class Invoice { - private Collection products = new ArrayList<>(); + private Map products = new HashMap<>(); public void addProduct(Product product) { - products.add(product); + products.put(product, 1); } public void addProduct(Product product, Integer quantity) { - // TODO: implement + products.put(product, quantity); } public BigDecimal getSubtotal() { BigDecimal subtotal = BigDecimal.ZERO; - for (Product product : products) { - subtotal = subtotal.add(product.getPrice()); + for (Map.Entry entry : products.entrySet()) { + Product product = entry.getKey(); + Integer quantity = entry.getValue(); + + subtotal = subtotal.add( + product.getPrice().multiply(BigDecimal.valueOf(quantity))); } return subtotal; } From 390eaab134f11b732566e0ae6ca38ae778abc645 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Mon, 16 Feb 2026 18:46:09 +0100 Subject: [PATCH 09/11] Invoice: implementacja getTotal() jako subtotal + tax --- src/main/java/pl/edu/agh/mwo/invoice/Invoice.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index 08ec3b4d7..e59b48fac 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -38,6 +38,6 @@ public BigDecimal getTax() { } public BigDecimal getTotal() { - return BigDecimal.ZERO; + return getSubtotal().add(getTax()); } } From 1356fce522be6ef422c6e1ad61013f9c5e0d1316 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Mon, 16 Feb 2026 18:53:51 +0100 Subject: [PATCH 10/11] =?UTF-8?q?Invoice:=20implementacja=20getTax()=20dla?= =?UTF-8?q?=20wielu=20produkt=C3=B3w=20i=20quantity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pl/edu/agh/mwo/invoice/Invoice.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index e59b48fac..0eee191f5 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -34,7 +34,18 @@ public BigDecimal getSubtotal() { } public BigDecimal getTax() { - return BigDecimal.ZERO; + BigDecimal tax = BigDecimal.ZERO; + for (Map.Entry entry : products.entrySet()) { + Product product = entry.getKey(); + Integer quantity = entry.getValue(); + + BigDecimal productTax = + product.getPrice() + .multiply(product.getTaxPercent()) + .multiply(BigDecimal.valueOf(quantity)); + tax = tax.add(productTax); + } + return tax; } public BigDecimal getTotal() { From 4516585aa0895424c7f223f6355e3a4500cec875 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Wed, 18 Feb 2026 08:35:17 +0100 Subject: [PATCH 11/11] Invoice: implementacja zgodna z InvoiceTest --- src/main/java/pl/edu/agh/mwo/invoice/Invoice.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index 0eee191f5..3fd0def7a 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -12,10 +12,18 @@ public class Invoice { private Map products = new HashMap<>(); public void addProduct(Product product) { - products.put(product, 1); + addProduct(product, 1); } public void addProduct(Product product, Integer quantity) { + + if (product == null) { + throw new IllegalArgumentException("Product cannot be null"); + } + + if (quantity == null || quantity <= 0) { + throw new IllegalArgumentException("Quantity must be positive"); + } products.put(product, quantity); }