From af528d26c4b303b5b9e9b24c3c58110c39dc31c3 Mon Sep 17 00:00:00 2001 From: Severin Kaderli Date: Wed, 30 Mar 2022 19:17:43 +0200 Subject: [PATCH] Finish assignment Signed-off-by: Severin Kaderli --- pom.xml | 23 +++++++++--- src/main/kotlin/Invoice.kt | 24 ++++++------- src/main/kotlin/Main.kt | 2 +- src/main/kotlin/ParseException.kt | 1 + src/main/kotlin/Product.kt | 11 +++--- src/test/kotlin/InvoiceTest.kt | 35 +++++++++++++++++++ src/test/kotlin/ProductTest.kt | 26 ++++++++++++++ src/test/resources/invoice1.txt | 12 +++++++ src/test/resources/invoice2.txt | 12 +++++++ src/test/resources/invoice3.txt | 12 +++++++ .../resources/invoice_with_invalid_column.txt | 12 +++++++ 11 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 src/main/kotlin/ParseException.kt create mode 100644 src/test/kotlin/InvoiceTest.kt create mode 100644 src/test/kotlin/ProductTest.kt create mode 100644 src/test/resources/invoice1.txt create mode 100644 src/test/resources/invoice2.txt create mode 100644 src/test/resources/invoice3.txt create mode 100644 src/test/resources/invoice_with_invalid_column.txt diff --git a/pom.xml b/pom.xml index 0c40b80..caaabb5 100644 --- a/pom.xml +++ b/pom.xml @@ -4,12 +4,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - consoleApp + Assessment-2 dev.kaderli 1.0-SNAPSHOT jar - consoleApp + Assessment-2 UTF-8 @@ -65,6 +65,15 @@ MainKt + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 8 + 8 + + @@ -72,7 +81,7 @@ org.jetbrains.kotlin kotlin-test-junit5 - 1.5.10 + 1.6.10 test @@ -81,10 +90,16 @@ 5.6.0 test + + org.junit.jupiter + junit-jupiter-params + 5.6.3 + test + org.jetbrains.kotlin kotlin-stdlib-jdk8 - 1.5.10 + 1.6.10 diff --git a/src/main/kotlin/Invoice.kt b/src/main/kotlin/Invoice.kt index f8a182d..32db916 100644 --- a/src/main/kotlin/Invoice.kt +++ b/src/main/kotlin/Invoice.kt @@ -1,4 +1,5 @@ import java.io.File +import java.util.* class Invoice { /** @@ -7,18 +8,12 @@ class Invoice { var products = ArrayList() /** - * Adds a product to the invoice + * Total price of all products. */ - fun addProduct(product: Product) { - products.add(product) - } - - /** - * Returns the total price of all products. - */ - fun getTotalPrice(): Float { - return products.map { it.totalPrice }.sum() - } + val totalPrice: Float + get() { + return products.map { it.totalPrice }.sum() + } companion object { /** @@ -51,11 +46,11 @@ class Invoice { "Quantity" -> product.quantity = value.toFloat().toInt() // "More information about a product is possible, e.g. description, but can be ignored." "Description", "Pos", "Amount" -> {} - else -> throw Exception("Unknown column: $column") + else -> throw ParseException("Unknown column: $column") } } - invoice.addProduct(product) + invoice.products.add(product) } return invoice @@ -65,6 +60,9 @@ class Invoice { return line.trim().trim('|').split('|').map { it.trim() } } + /** + * Checks if the given line is a divider in the table. + */ private fun isDivider(line: String): Boolean { return line.trim().startsWith("|*") } diff --git a/src/main/kotlin/Main.kt b/src/main/kotlin/Main.kt index 726c4dd..aaeec95 100644 --- a/src/main/kotlin/Main.kt +++ b/src/main/kotlin/Main.kt @@ -7,7 +7,7 @@ fun main() { println(invoice.products.size) // "...and calculates the total price of the purchased products (per file) without using the amount column." - println(invoice.getTotalPrice()) + println(invoice.totalPrice) // "It should be also possible to get an array or arraylist of all purchased products in a file" println(invoice.products) diff --git a/src/main/kotlin/ParseException.kt b/src/main/kotlin/ParseException.kt new file mode 100644 index 0000000..bcc132b --- /dev/null +++ b/src/main/kotlin/ParseException.kt @@ -0,0 +1 @@ +class ParseException(message: String) : RuntimeException(message) {} \ No newline at end of file diff --git a/src/main/kotlin/Product.kt b/src/main/kotlin/Product.kt index f41dcd7..1ead6a6 100644 --- a/src/main/kotlin/Product.kt +++ b/src/main/kotlin/Product.kt @@ -1,13 +1,10 @@ /** * This class represents a row in the invoice text files. - * - * Using product.totalPrice to total price of the product can be retrieved. */ -data class Product( - var name: String = "", - var price: Float = 0f, - var quantity: Int = 0 -) { +data class Product(var name: String = "", var price: Float = 0f, var quantity: Int = 0) { + /** + * The total price of the product. + */ val totalPrice: Float get() { return quantity * price diff --git a/src/test/kotlin/InvoiceTest.kt b/src/test/kotlin/InvoiceTest.kt new file mode 100644 index 0000000..e2f81a9 --- /dev/null +++ b/src/test/kotlin/InvoiceTest.kt @@ -0,0 +1,35 @@ +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource +import java.util.stream.Stream + +internal class InvoiceTest { + + @ParameterizedTest(name = "Test that the invoice has {0} products and a total price of {1}") + @MethodSource("provideValidInvoices") + fun getTotalPrice(numberOfProducts: Int, totalPrice: Float, invoice: Invoice) { + assertEquals(numberOfProducts, invoice.products.size) + assertEquals(totalPrice, invoice.totalPrice) + } + + @Test + fun `test invalid columns`() { + assertThrows { + Invoice.fromFile("src/test/resources/invoice_with_invalid_column.txt") + } + } + + companion object { + @JvmStatic + fun provideValidInvoices(): Stream { + return Stream.of( + Arguments.of(6, 3950.3f, Invoice.fromFile("src/test/resources/invoice1.txt")), + Arguments.of(6, 3950.3f, Invoice.fromFile("src/test/resources/invoice2.txt")), + Arguments.of(6, 3950.3f, Invoice.fromFile("src/test/resources/invoice3.txt")) + ) + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/ProductTest.kt b/src/test/kotlin/ProductTest.kt new file mode 100644 index 0000000..70cafea --- /dev/null +++ b/src/test/kotlin/ProductTest.kt @@ -0,0 +1,26 @@ +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource +import java.util.stream.Stream + +internal class ProductTest { + @ParameterizedTest(name = "Test that the product has a total price of {0}") + @MethodSource("provideProducts") + fun getTotalPrice(totalPrice: Float, product: Product) { + assertEquals(totalPrice, product.totalPrice) + } + + companion object { + @JvmStatic + fun provideProducts(): Stream { + return Stream.of( + Arguments.of(2f, Product(quantity = 1, price = 2f)), + Arguments.of(3f, Product(quantity = 2, price = 1.5f)), + Arguments.of(4.5f, Product(quantity = 3, price = 1.5f)), + Arguments.of(20f, Product(quantity = 10, price = 2f)), + Arguments.of(0f, Product(quantity = 0, price = 99f)), + ) + } + } +} \ No newline at end of file diff --git a/src/test/resources/invoice1.txt b/src/test/resources/invoice1.txt new file mode 100644 index 0000000..378b7c7 --- /dev/null +++ b/src/test/resources/invoice1.txt @@ -0,0 +1,12 @@ + + |****************************************|****************|**********|*********| + | Item | Unit Price | Quantity | Amount | + |****************************************|****************|**********|*********| + | Table | 699.00 | 1.00 | 699.00 | + | Dining chairs | 79.95 | 10.00 | 799.50 | + | Sofa | 329.00 | 2.00 | 658.00 | + | footstool | 199.00 | 3.00 | 597.00 | + | Armchair | 279.00 | 3.00 | 837.00 | + | Lamp | 89.95 | 4.00 | 359.80 | + |****************************************|****************|**********|*********| + diff --git a/src/test/resources/invoice2.txt b/src/test/resources/invoice2.txt new file mode 100644 index 0000000..25dd375 --- /dev/null +++ b/src/test/resources/invoice2.txt @@ -0,0 +1,12 @@ + + |*****************************************|****************|**********|*********| + | Item | Description | Unit Price | Quantity | Amount | + |*****************************************|****************|**********|*********| + | Table | acacia235x100 cm | 699.00 | 1.00 | 699.00 | + | Dining chairs | white/in/outdoor | 79.95 | 10.00 | 799.50 | + | Sofa | 3-seat sofa, dark grey| 329.00 | 2.00 | 658.00 | + | footstool | Bomstad dark brown | 199.00 | 3.00 | 597.00 | + | Armchair | Idhult black | 279.00 | 3.00 | 837.00 | + | Lamp | Floor lamp, white | 89.95 | 4.00 | 359.80 | + |*****************************************|****************|**********|*********| + diff --git a/src/test/resources/invoice3.txt b/src/test/resources/invoice3.txt new file mode 100644 index 0000000..2aef405 --- /dev/null +++ b/src/test/resources/invoice3.txt @@ -0,0 +1,12 @@ + + |********|********************************|****************|**********|*********| + | Pos | Item | Unit Price | Quantity | Amount | + |********|********************************|****************|**********|*********| + | 1 | Table | 699.00 | 1.00 | 699.00 | + | 2 | Dining chairs | 79.95 | 10.00 | 799.50 | + | 3 | Sofa | 329.00 | 2.00 | 658.00 | + | 4 | footstool | 199.00 | 3.00 | 597.00 | + | 5 | Armchair | 279.00 | 3.00 | 837.00 | + | 6 | Lamp | 89.95 | 4.00 | 359.80 | + |********|********************************|****************|**********|*********| + diff --git a/src/test/resources/invoice_with_invalid_column.txt b/src/test/resources/invoice_with_invalid_column.txt new file mode 100644 index 0000000..a80e3a9 --- /dev/null +++ b/src/test/resources/invoice_with_invalid_column.txt @@ -0,0 +1,12 @@ + + |****************************************|****************|**********|*********| + | Test | Unit Price | Quantity | Amount | + |****************************************|****************|**********|*********| + | Table | 699.00 | 1.00 | 699.00 | + | Dining chairs | 79.95 | 10.00 | 799.50 | + | Sofa | 329.00 | 2.00 | 658.00 | + | footstool | 199.00 | 3.00 | 597.00 | + | Armchair | 279.00 | 3.00 | 837.00 | + | Lamp | 89.95 | 4.00 | 359.80 | + |****************************************|****************|**********|*********| +