From 59d9ae29644b90c0fdb20c0e6993c5a48feb8264 Mon Sep 17 00:00:00 2001
From: HSoreide <sofie.scisly@gmail.com>
Date: Mon, 13 Mar 2023 18:01:22 +0100
Subject: [PATCH] Write unit tests for the Ingredient class

---
 .../demo/data/recipes/Ingredient.java         | 22 +++++-
 .../demo/data/recipes/MeasuringUnit.java      |  3 +-
 .../demo/data/recipes/IngredientTest.java     | 76 +++++++++++++++++++
 3 files changed, 99 insertions(+), 2 deletions(-)
 create mode 100644 src/test/java/no/ntnu/idatt1002/demo/data/recipes/IngredientTest.java

diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/Ingredient.java b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/Ingredient.java
index 575c5f53..12e49cb5 100644
--- a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/Ingredient.java
+++ b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/Ingredient.java
@@ -1,5 +1,7 @@
 package no.ntnu.idatt1002.demo.data.recipes;
 
+import java.util.Objects;
+
 /**
  * The Ingredient class represents an ingredient that can be part of a recipe in real life and/or
  * be available to the user in real life. When the ingredient is part of a recipe, the subclass called
@@ -24,7 +26,7 @@ public class Ingredient {
      * @param unit The unit of measure of the given amount of the ingredient.
      */
     public Ingredient(FoodItem ingredient, double amount, MeasuringUnit unit) {
-        if(ingredient == null | amount < 0.0f | unit == null) {
+        if(ingredient == null | amount <= 0.0f | unit == null) {
             throw new IllegalArgumentException("The ingredient must have a type, amount and measuring unit.");
         }
         this.foodType = ingredient;
@@ -100,4 +102,22 @@ public class Ingredient {
                 '}';
     }
 
+    /**
+     * The method checks if a given object is equal to the ingredient object.
+     * If the object is of the same class as well as having the same value for each class field,
+     * the object is equal to the Ingredient.
+     * @param o An Object to which the Ingredient should be compared.
+     * @return True if the object is equivalent to the Ingredient, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof Ingredient that)) return false;
+        return Double.compare(that.amount, amount) == 0 && foodType == that.foodType && unit == that.unit;
+    }
+
+/*    @Override
+    public int hashCode() {
+        return Objects.hash(foodType, amount, unit);
+    }*/
 }
diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/MeasuringUnit.java b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/MeasuringUnit.java
index 50d75dde..83f664cd 100644
--- a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/MeasuringUnit.java
+++ b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/MeasuringUnit.java
@@ -7,7 +7,8 @@ public enum MeasuringUnit {
     TSP("tsp."),
     TBS("tbs."),
     GR("gr."),
-    KG("kg.");
+    KG("kg."),
+    PC("pieces");
 
     public final String label;
 
diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/recipes/IngredientTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/recipes/IngredientTest.java
new file mode 100644
index 00000000..78a715ed
--- /dev/null
+++ b/src/test/java/no/ntnu/idatt1002/demo/data/recipes/IngredientTest.java
@@ -0,0 +1,76 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class IngredientTest {
+
+    Ingredient testIngredient;
+
+    @BeforeEach
+    void beforeEach() {
+        testIngredient = new Ingredient(FoodItem.ONION, 0.5f, MeasuringUnit.KG);
+    }
+
+    @Test
+    @DisplayName("The constructor creates an ingredient object successfully")
+    void constructValidIngredient() {
+        Ingredient validIngredient = new Ingredient(FoodItem.ONION, 1, MeasuringUnit.KG);
+        assertEquals(validIngredient, new Ingredient(FoodItem.ONION, 1, MeasuringUnit.KG));
+    }
+
+    @Test
+    @DisplayName("The constructor throws exceptions for illegal input.")
+    void constructorThrowsExceptionsWhenItShould() {
+        assertThrows(IllegalArgumentException.class, () -> new Ingredient(null, 2, MeasuringUnit.DL));
+        assertThrows(IllegalArgumentException.class, () -> new Ingredient(FoodItem.ONION, -5, MeasuringUnit.DL));
+        assertThrows(IllegalArgumentException.class, () -> new Ingredient(FoodItem.ONION, 0, MeasuringUnit.DL));
+        assertThrows(IllegalArgumentException.class, () -> new Ingredient(FoodItem.ONION, 2, null));
+    }
+
+    @Test
+    @DisplayName("Change of food type works for valid food type.")
+    void setFoodTypeWorksForValidType() {
+        testIngredient.setFoodType(FoodItem.LEMON);
+        assertEquals(new Ingredient(FoodItem.LEMON, 0.5f, MeasuringUnit.KG), testIngredient);
+    }
+
+    @Test
+    @DisplayName("Change of food type to invalid type throws exception.")
+    void setFoodTypeThrowsException() {
+        assertThrows(IllegalArgumentException.class, () -> testIngredient.setFoodType(null));
+    }
+
+    @Test
+    @DisplayName("Change of food amount works for valid amount.")
+    void setAmountWorksForValidAmount() {
+        testIngredient.setAmount(2.5);
+        assertEquals(new Ingredient(FoodItem.LEMON, 2.5f, MeasuringUnit.KG), testIngredient);
+    }
+
+    @Test
+    @DisplayName("Change of food amount to invalid amount throws exception.")
+    void setAmountThrowsException() {
+        assertThrows(IllegalArgumentException.class, () -> testIngredient.setAmount(0));
+        assertThrows(IllegalArgumentException.class, () -> testIngredient.setAmount(-1));
+    }
+
+    @Test
+    @DisplayName("Change of measuring unit works for valid unit.")
+    void setUnitWorksForValidUnit() {
+        testIngredient.setUnit(MeasuringUnit.TBS);
+        assertEquals(new Ingredient(FoodItem.LEMON, 0.5f, MeasuringUnit.TBS), testIngredient);
+    }
+
+    @Test
+    @DisplayName("Change of measuring to invalid unit throws exception.")
+    void setUnitThrowsException() {
+        assertThrows(IllegalArgumentException.class, () -> testIngredient.setUnit(null));
+    }
+
+//TODO: Test for equals method?
+
+}
\ No newline at end of file
-- 
GitLab