Sfoglia il codice sorgente

Add string ctor to Duration, as well as the test cases to cover it.

Sam Jaffe 5 anni fa
parent
commit
9c68a9fd11

+ 25 - 1
src/main/lombok/org/leumasjaffe/recipe/model/Duration.java

@@ -1,5 +1,11 @@
 package org.leumasjaffe.recipe.model;
 
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
 import lombok.AccessLevel;
 import lombok.AllArgsConstructor;
 import lombok.EqualsAndHashCode;
@@ -24,6 +30,24 @@ public class Duration {
 	int minSeconds = 0;
 	int maxSeconds = 0;
 	
+	@JsonCreator
+	public Duration(final String serial) {
+		final String[] tokens = serial.split(" ");
+		final boolean isRange = tokens.length == 4;
+		
+		final Optional<Display> rv = Stream.of(Display.values())
+				.filter(v -> v.abbreviation.equals(tokens[isRange ? 3 : 1])).findFirst();
+		
+		displayAs = rv.orElseThrow(() -> new IllegalArgumentException("Unknown time measure: " + tokens[1]));
+
+		if (isRange) {
+			minSeconds = (int) (Float.parseFloat(tokens[0]) * displayAs.inSeconds);
+			maxSeconds = (int) (Float.parseFloat(tokens[2]) * displayAs.inSeconds);
+		} else {
+			maxSeconds = (int) (Float.parseFloat(tokens[0]) * displayAs.inSeconds);
+		}
+	}
+	
 	public Duration plus(Duration rhs) {
 		final Display newDisplayAs = displayAs.ordinal() < rhs.displayAs.ordinal() ?
 				displayAs : rhs.displayAs;
@@ -50,7 +74,7 @@ public class Duration {
 		return this;
 	}
 
-	@Override
+	@Override @JsonValue
 	public String toString() {
 		StringBuilder build = new StringBuilder();
 		if (minSeconds != 0) {

+ 28 - 0
src/test/java/org/leumasjaffe/recipe/model/DurationTest.java

@@ -96,5 +96,33 @@ class DurationTest {
 	void testHalfHourDisplayIsNotUsedForCloserToWhole(int value) {
 		assertNotEquals("0.5 hr", new Duration(HOURS, 0, value).toString());
 	}
+	
+	@Test
+	void testStringConstructorProducesCorrectData() {
+		assertEquals(new Duration(HOURS, 3600, 7200), new Duration("1 - 2 hr"));
+		assertEquals(new Duration(MINUTES, 600, 3600), new Duration("10 - 60 min"));
+		assertEquals(new Duration(SECONDS, 5, 10), new Duration("5 - 10 s"));
+
+		assertEquals(new Duration(HOURS, 0, 3600), new Duration("1 hr"));
+		assertEquals(new Duration(MINUTES, 0, 3600), new Duration("60 min"));
+		assertEquals(new Duration(SECONDS, 0, 10), new Duration("10 s"));
+	}
+	
+	@Test
+	void testStringConstructorThrowsOnUnknownDuration() {
+		assertThrows(IllegalArgumentException.class,
+				() -> new Duration("0.5 tocks"));
+	}
+	
+	@Test
+	void testStringConstructorProcessesFloats() {
+		assertEquals("0.5 hr", new Duration("0.5 hr").toString());
+	}
+	
+	@Test
+	void testStringConstructorCanBeLossy() {
+		assertEquals("0.5 hr", new Duration("0.25 hr").toString());
+		assertEquals("0 hr", new Duration("0.2 hr").toString());
+	}
 
 }

+ 6 - 30
src/test/resources/example.json

@@ -10,11 +10,7 @@
           "dependsOn": [],
           "vessel": "",
           "preparation": {
-            "duration": {
-              "displayAs": "MINUTES",
-              "minSeconds": 300,
-              "maxSeconds": 600
-            }
+            "duration": "5 - 10 min"
           },
           "cooking": [
             {
@@ -25,11 +21,7 @@
                   "amount": "1 Tbsp"
                 }
               ],
-              "duration": {
-                "displayAs": "SECONDS",
-                "minSeconds": 30,
-                "maxSeconds": 60
-              },
+              "duration": "30 - 60 s",
               "instruction": "Heat oil over high heat"
             },
             {
@@ -40,21 +32,13 @@
                   "amount": "100 g"
                 }
               ],
-              "duration": {
-                "displayAs": "MINUTES",
-                "minSeconds": 300,
-                "maxSeconds": 900
-              },
+              "duration": "5 - 10 min",
               "instruction": "Sauté the onions until soft and translucent, stirring to prevent burning"
             }
           ],
           "rest": {
             "where": "ROOM_TEMPERATURE",
-            "duration": {
-              "displayAs": "SECONDS",
-              "minSeconds": 0,
-              "maxSeconds": 30
-            }
+            "duration": "30 s"
           }
         },
         {
@@ -70,11 +54,7 @@
                   "amount": "1 Tbsp"
                 }
               ],
-              "duration": {
-                "displayAs": "SECONDS",
-                "minSeconds": 30,
-                "maxSeconds": 60
-              },
+              "duration": "30 - 60 s",
               "instruction": "Heat oil over high heat"
             },
             {
@@ -85,11 +65,7 @@
                   "amount": "100 g"
                 }
               ],
-              "duration": {
-                "displayAs": "MINUTES",
-                "minSeconds": 300,
-                "maxSeconds": 900
-              },
+              "duration": "5 - 10 min",
               "instruction": "Sauté the onions until soft and translucent, stirring to prevent burning"
             }
           ]