diff --git a/pom.xml b/pom.xml
index 893b8a5..3089c7a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,6 +34,7 @@
UTF-8
11
3.3.0-rc2
+ 5.4.0
@@ -111,6 +112,13 @@
com.github.gwenn
sqlite-dialect
0.1.2
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ ${junit.jupiter.version}
+ test
diff --git a/src/main/java/com/mousetech/gourmetj/IngredientUI.java b/src/main/java/com/mousetech/gourmetj/IngredientUI.java
index 280266a..8a88e33 100644
--- a/src/main/java/com/mousetech/gourmetj/IngredientUI.java
+++ b/src/main/java/com/mousetech/gourmetj/IngredientUI.java
@@ -4,8 +4,8 @@ import com.mousetech.gourmetj.persistence.model.Ingredient;
import com.mousetech.gourmetj.persistence.model.IngredientIF;
import com.mousetech.gourmetj.persistence.model.Recipe;
import com.mousetech.gourmetj.persistence.model.Shopcat;
-
-import com.mousetech.gourmetj.IngredientDigester.IngredientAmountFormat;
+import com.mousetech.gourmetj.utils.IngredientDigester;
+import com.mousetech.gourmetj.utils.IngredientDigester.IngredientAmountFormat;
/**
* JSF-friendly decorator for @see Ingredient. Formats amount
diff --git a/src/main/java/com/mousetech/gourmetj/RecipeDetailBean.java b/src/main/java/com/mousetech/gourmetj/RecipeDetailBean.java
index c21665e..01baab2 100644
--- a/src/main/java/com/mousetech/gourmetj/RecipeDetailBean.java
+++ b/src/main/java/com/mousetech/gourmetj/RecipeDetailBean.java
@@ -31,6 +31,7 @@ import com.mousetech.gourmetj.persistence.model.Recipe;
import com.mousetech.gourmetj.persistence.model.Shopcat;
import com.mousetech.gourmetj.persistence.service.RecipeService;
import com.mousetech.gourmetj.springweb.PictureController;
+import com.mousetech.gourmetj.utils.IngredientDigester;
/**
* Backing bean for display/edit recipe detail
diff --git a/src/main/java/com/mousetech/gourmetj/IngredientDigester.java b/src/main/java/com/mousetech/gourmetj/utils/IngredientDigester.java
similarity index 99%
rename from src/main/java/com/mousetech/gourmetj/IngredientDigester.java
rename to src/main/java/com/mousetech/gourmetj/utils/IngredientDigester.java
index 076029d..612c515 100644
--- a/src/main/java/com/mousetech/gourmetj/IngredientDigester.java
+++ b/src/main/java/com/mousetech/gourmetj/utils/IngredientDigester.java
@@ -1,4 +1,4 @@
-package com.mousetech.gourmetj;
+package com.mousetech.gourmetj.utils;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
diff --git a/src/test/java/com/mousetech/gourmetj/jsf/util/IngredientUITest.java b/src/test/java/com/mousetech/gourmetj/jsf/util/IngredientUITest.java
new file mode 100644
index 0000000..6528f13
--- /dev/null
+++ b/src/test/java/com/mousetech/gourmetj/jsf/util/IngredientUITest.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (C) 2021, Tim Holloway
+ *
+ * Date written: Dec 2, 2021
+ * Author: Tim Holloway
+ */
+package com.mousetech.gourmetj.jsf.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+import com.mousetech.gourmetj.IngredientUI;
+import com.mousetech.gourmetj.persistence.model.Ingredient;
+
+/**
+ * @author timh
+ * @since Dec 2, 2021
+ */
+public class IngredientUITest {
+
+ /**
+ * Test method for {@link com.mousetech.gourmetj.jsf.util.IngredientUI#getDisplayAmount()}.
+ */
+ @Test
+ public void testGetDisplayAmount() {
+ IngredientUI ui = new IngredientUI(new Ingredient());
+
+ ui.setAmount(12.0d);
+ assertEquals("12", ui.getDisplayAmount());
+
+ ui.setAmount(2.66666d);
+ assertEquals( "2⅔", ui.getDisplayAmount());
+
+ ui.setAmount(4.5);
+ assertEquals("4½", ui.getDisplayAmount());
+
+ ui.setAmount(3.57d);
+ assertEquals("3.57", ui.getDisplayAmount());
+ }
+
+ /**
+ * Test method for {@link com.mousetech.gourmetj.jsf.util.IngredientUI#setDisplayAmount(java.lang.String)}.
+ */
+ @Test
+ public void testSetDisplayAmount() {
+ IngredientUI ui = new IngredientUI(new Ingredient());
+
+ ui.setDisplayAmount("3 - 1/2");
+ assertEquals(3.5d, ui.getAmount(), 0.001);
+
+ ui.setDisplayAmount("2⅔");
+ assertEquals(2.6666, ui.getAmount(), 0.001);
+
+ ui.setDisplayAmount("9");
+ assertEquals(9.0d, ui.getAmount(), 0.001);
+}
+
+ /**
+ * Test method for {@link com.mousetech.gourmetj.jsf.util.IngredientUI#getOptionalCB()}.
+ */
+ @Test
+ public void testGetOptionalCB() {
+ //fail("Not yet implemented");
+ }
+
+ /**
+ * Test method for {@link com.mousetech.gourmetj.jsf.util.IngredientUI#setOptionalCB(boolean)}.
+ */
+ @Test
+ public void testSetOptionalCB() {
+ //fail("Not yet implemented");
+ }
+
+}
diff --git a/src/test/java/com/mousetech/gourmetj/utils/IngredientDigesterTest.java b/src/test/java/com/mousetech/gourmetj/utils/IngredientDigesterTest.java
new file mode 100644
index 0000000..0eaa4db
--- /dev/null
+++ b/src/test/java/com/mousetech/gourmetj/utils/IngredientDigesterTest.java
@@ -0,0 +1,143 @@
+package com.mousetech.gourmetj.utils;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+import com.mousetech.gourmetj.utils.IngredientDigester.IngredientAmountFormat;
+
+public class IngredientDigesterTest {
+
+ @Test
+ public void digestFractionTest() {
+ Double value;
+
+ value = IngredientDigester.digestFraction("5");
+ assertEquals(0.0d, value, 0.001); // No fractional part
+
+ value = IngredientDigester.digestFraction("1/2");
+ assertEquals(0.5d, value, 0.001);
+
+ value = IngredientDigester.digestFraction("3 3/4");
+ assertEquals(3.75d, value, 0.001);
+
+ value = IngredientDigester.digestFraction("33 - 1/3");
+ assertEquals(33.33333333d, value, 0.001);
+ }
+
+ @Test
+ public void digestSingleAmountTest() {
+ Double value;
+
+ value = IngredientDigester.parseSingleAmount("5");
+ assertEquals(5.0d, value, 0.001); // No fractional part
+
+ value = IngredientDigester.parseSingleAmount("1/2");
+ assertEquals(0.5d, value, 0.001);
+
+ value = IngredientDigester.parseSingleAmount("3 3/4");
+ assertEquals(3.75d, value, 0.001);
+
+// value = IngredientDigester.parseSingleAmount("33 - 1/3");
+// assertEquals(0.33333333d, value, 0.001);
+ }
+
+ @Test
+ public void parseAmountTest() {
+ Double[] value;
+
+ value = IngredientDigester.digestAmount("5");
+ assertEquals(5.0d, value[0], 0.001);
+ assertNull(value[1]);
+
+ value = IngredientDigester.digestAmount("2½");
+ assertEquals(2.5d, value[0], 0.001);
+ assertNull(value[1]);
+
+ value = IngredientDigester.digestAmount("7 ⅓");
+ assertEquals(7.33333d, value[0], 0.001);
+ assertNull(value[1]);
+
+ value = IngredientDigester.digestAmount("1/3");
+ assertEquals(0.33333d, value[0], 0.001);
+ assertNull(value[1]);
+
+ value = IngredientDigester.digestAmount("9 3/4");
+ assertEquals(9.75d, value[0], 0.001);
+ assertNull(value[1]);
+
+ value = IngredientDigester.digestAmount("3-5");
+ assertEquals(3.0d, value[0], 0.001);
+ assertEquals(5.0d, value[1], 0.001);
+
+ value = IngredientDigester.digestAmount("1/2 -3/4");
+ assertEquals(0.5d, value[0], 0.001);
+ assertEquals(0.75d, value[1], 0.001);
+
+ value = IngredientDigester.digestAmount("¼-⅓");
+ assertEquals(0.25d, value[0], 0.001);
+ assertEquals(0.33333333d, value[1], 0.001);
+
+ }
+
+ @Test
+ public void testAmountParser() {
+ String[] results;
+
+ results = IngredientDigester.parseFancyNumber("1 cup milk");
+ assertEquals("1", results[0]);
+ assertEquals("cup milk", results[1]);
+
+
+ results = IngredientDigester.parseFancyNumber("2 ½ lbs pease");
+ assertEquals("2 ½", results[0]);
+ assertEquals("lbs pease", results[1]);
+
+ results = IngredientDigester.parseFancyNumber("2 3/4 cups water");
+ assertEquals("2 3/4", results[0]);
+ assertEquals("cups water", results[1]);
+
+ results = IngredientDigester.parseFancyNumber("7 1/2 cups water");
+ assertEquals("7 1/2", results[0]);
+ assertEquals("cups water", results[1]);
+
+ }
+
+ @Test
+ public void testDisplayFormatTest() {
+ String value;
+
+ value = IngredientDigester.displayAmountPart(
+ IngredientAmountFormat.IA_TEXT, 0d);
+ assertEquals("", value);
+
+ value = IngredientDigester.displayAmountPart(
+ IngredientAmountFormat.IA_TEXT, 0.5d);
+ assertEquals("1/2", value);
+
+ value = IngredientDigester.displayAmountPart(
+ IngredientAmountFormat.IA_TEXT, 12.0d);
+ assertEquals("12", value);
+
+ value = IngredientDigester.displayAmountPart(
+ IngredientAmountFormat.IA_SYMBOLS, 3.5d);
+ assertEquals("3½", value);
+
+ value = IngredientDigester.displayAmountPart(
+ IngredientAmountFormat.IA_DECIMAL, 3.5d);
+ assertEquals("3.5", value);
+
+ value = IngredientDigester.displayAmountPart(
+ IngredientAmountFormat.IA_TEXT, 3.5d);
+ assertEquals("3 1/2", value);
+
+
+ value = IngredientDigester.displayAmountPart(
+ IngredientAmountFormat.IA_SYMBOLS, 7.333333333d);
+ assertEquals("7⅓", value);
+
+ value = IngredientDigester.displayAmountPart(
+ IngredientAmountFormat.IA_SYMBOLS, 7.933333333d);
+ assertEquals("7.933", value);
+ }
+}
diff --git a/src/test/java/com/mousetech/gourmetj/utils/TimeFormatterTest.java b/src/test/java/com/mousetech/gourmetj/utils/TimeFormatterTest.java
index 6a4a160..d9a413d 100644
--- a/src/test/java/com/mousetech/gourmetj/utils/TimeFormatterTest.java
+++ b/src/test/java/com/mousetech/gourmetj/utils/TimeFormatterTest.java
@@ -26,17 +26,24 @@ class TimeFormatterTest {
@Test
void test() {
- assertEquals(5000, TimeFormatter.parseTime("5s"));
- assertEquals(5000*60, TimeFormatter.parseTime("5m"));
+ assertEquals(5000,
+ TimeFormatter.parseTime("5s").longValue());
+ assertEquals(5000 * 60,
+ TimeFormatter.parseTime("5m").longValue());
- assertEquals(3600_000 + 25*60_000, TimeFormatter.parseTime("1 hour, 25 min"));
-
- assertEquals(5*3600000 + 6*60000, TimeFormatter.parseTime("5h 6m"));
- assertEquals(277562000L, TimeFormatter.parseTime("3d 5h 6m 2s"));
+ assertEquals(3600_000L + 25 * 60_000, TimeFormatter
+ .parseTime("1 hour, 25 min").longValue());
- assertEquals(18000000L, TimeFormatter.parseTime("1.5 hours"));
-
- assertEquals(3*3600_000, TimeFormatter.parseTime("3 hours"));
+ assertEquals(5 * 3600000 + 6 * 60000,
+ TimeFormatter.parseTime("5h 6m").longValue());
+ assertEquals(277562000L,
+ TimeFormatter.parseTime("3d 5h 6m 2s").longValue());
+
+ assertEquals(18000000L,
+ TimeFormatter.parseTime("1.5 hours").longValue());
+
+ assertEquals(3 * 3600_000,
+ TimeFormatter.parseTime("3 hours").longValue());
assertNull(TimeFormatter.parseTime("1 week"));
}