From 03edc1b6e3cd6eccc137e3b42eae36047a08e66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20S=C3=A9nave?= <59770457+nsenave@users.noreply.github.com> Date: Mon, 15 Jan 2024 16:00:28 +0100 Subject: [PATCH] refactor: create enum class for label type (#124) * refactor: create enum class for label type * fix(label type): right value for 'vtl md' * chore: bump version after fix * refactor(label type): proper type in condition filter too * chore: version 3.2.7 --- pom.xml | 2 +- .../model/flat/ConditionFilterType.java | 4 +- .../insee/lunatic/model/flat/LabelType.java | 55 +++++++++++- .../lunatic/model/flat/LabelTypeEnum.java | 32 +++++++ .../ConditionFilterSerializationTest.java | 68 ++++++++++++++ .../conversion/LabelSerializationTest.java | 88 +++++++++++++++++++ 6 files changed, 243 insertions(+), 6 deletions(-) create mode 100644 src/main/java/fr/insee/lunatic/model/flat/LabelTypeEnum.java create mode 100644 src/test/java/fr/insee/lunatic/conversion/ConditionFilterSerializationTest.java create mode 100644 src/test/java/fr/insee/lunatic/conversion/LabelSerializationTest.java diff --git a/pom.xml b/pom.xml index 5750c73c..994eea69 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ lunatic-model jar - 3.2.5 + 3.2.7 Lunatic Model Classes and converters for the Lunatic model https://inseefr.github.io/Lunatic-Model/ diff --git a/src/main/java/fr/insee/lunatic/model/flat/ConditionFilterType.java b/src/main/java/fr/insee/lunatic/model/flat/ConditionFilterType.java index 1cf05172..5bd6918f 100644 --- a/src/main/java/fr/insee/lunatic/model/flat/ConditionFilterType.java +++ b/src/main/java/fr/insee/lunatic/model/flat/ConditionFilterType.java @@ -15,10 +15,8 @@ }) @Getter @Setter -public class ConditionFilterType { +public class ConditionFilterType extends LabelType { - protected String value; - protected String type; @JsonIgnore protected List bindingDependencies; diff --git a/src/main/java/fr/insee/lunatic/model/flat/LabelType.java b/src/main/java/fr/insee/lunatic/model/flat/LabelType.java index 3b499f8e..2934e1a6 100644 --- a/src/main/java/fr/insee/lunatic/model/flat/LabelType.java +++ b/src/main/java/fr/insee/lunatic/model/flat/LabelType.java @@ -1,5 +1,6 @@ package fr.insee.lunatic.model.flat; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import lombok.Getter; import lombok.Setter; @@ -8,10 +9,60 @@ "value", "type" }) -@Getter -@Setter public class LabelType { + @Getter @Setter protected String value; + protected String type; + @JsonIgnore + private LabelTypeEnum typeEnum; + + /** + * Get label type. + * @return String value of label type. + * @deprecated The string property is being replaced with an enum. Use the getTypeEnum method. + */ + @Deprecated(since = "3.2.6") + public String getType() { + if (typeEnum != null) + return typeEnum.value(); + return type; + } + + /** + * Set string label type. + * @param type String value of label type, can be either "VTL_MD" or "VTL". + * @deprecated The string property is being replaced with an enum. + */ + @Deprecated(since = "3.2.6") + public void setType(String type) { + if (! (LabelTypeEnum.VTL_MD.value().equals(type) || LabelTypeEnum.VTL.value().equals(type))) + throw new IllegalArgumentException(String.format( + "Label type can be either \"%s\" or \"%s\".", + LabelTypeEnum.VTL_MD.value(), LabelTypeEnum.VTL.value())); + this.type = type; + this.typeEnum = null; + } + + /** + * Temporary getter for the type property being changed to an enum. In a future version, the getType + * will return the proper label type. + * @return Label type. + */ + public LabelTypeEnum getTypeEnum() { + if (type != null) + return LabelTypeEnum.fromValue(type); + return typeEnum; + } + + /** + * Set label type. + * @param labelTypeEnum Label type. + */ + public void setType(LabelTypeEnum labelTypeEnum) { + this.type = null; + this.typeEnum = labelTypeEnum; + } + } diff --git a/src/main/java/fr/insee/lunatic/model/flat/LabelTypeEnum.java b/src/main/java/fr/insee/lunatic/model/flat/LabelTypeEnum.java new file mode 100644 index 00000000..911f3d7b --- /dev/null +++ b/src/main/java/fr/insee/lunatic/model/flat/LabelTypeEnum.java @@ -0,0 +1,32 @@ +package fr.insee.lunatic.model.flat; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum LabelTypeEnum { + + /** Label that is a VTL expression and contains Markdown formatting. */ + VTL_MD("VTL|MD"), + /** Label that is a VTL expression. */ + VTL("VTL"); + + private final String value; + + LabelTypeEnum(String v) { + value = v; + } + + @JsonValue + public String value() { + return value; + } + + public static LabelTypeEnum fromValue(String v) { + for (LabelTypeEnum c : LabelTypeEnum.values()) { + if (c.value.equals(v)) { + return c; + } + } + throw new IllegalArgumentException(v); + } + +} diff --git a/src/test/java/fr/insee/lunatic/conversion/ConditionFilterSerializationTest.java b/src/test/java/fr/insee/lunatic/conversion/ConditionFilterSerializationTest.java new file mode 100644 index 00000000..f501c88c --- /dev/null +++ b/src/test/java/fr/insee/lunatic/conversion/ConditionFilterSerializationTest.java @@ -0,0 +1,68 @@ +package fr.insee.lunatic.conversion; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import fr.insee.lunatic.model.flat.ConditionFilterType; +import fr.insee.lunatic.model.flat.LabelTypeEnum; +import org.json.JSONException; +import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ConditionFilterSerializationTest { + + @Test + void serializeConditionFilter() throws JsonProcessingException, JSONException { + // + ConditionFilterType conditionFilterType = new ConditionFilterType(); + conditionFilterType.setValue("if FOO then BAR else BAZ"); + conditionFilterType.setType(LabelTypeEnum.VTL); + conditionFilterType.setBindingDependencies(List.of("FOO", "BAR", "BAZ")); + // + ObjectMapper objectMapper = new ObjectMapper(); + String result = objectMapper.writerFor(ConditionFilterType.class).writeValueAsString(conditionFilterType); + // + String expected = """ + {"value": "if FOO then BAR else BAZ", "type": "VTL"} + """; // (binding dependencies are ignored) + JSONAssert.assertEquals(expected, result, JSONCompareMode.STRICT); + } + + @Test // to be removed when string type is removed + void serializeConditionFilter_stringType() throws JsonProcessingException, JSONException { + // + ConditionFilterType conditionFilterType = new ConditionFilterType(); + conditionFilterType.setValue("if FOO then BAR else BAZ"); + conditionFilterType.setType("VTL"); + conditionFilterType.setBindingDependencies(List.of("FOO", "BAR", "BAZ")); + // + ObjectMapper objectMapper = new ObjectMapper(); + String result = objectMapper.writerFor(ConditionFilterType.class).writeValueAsString(conditionFilterType); + // + String expected = """ + {"value": "if FOO then BAR else BAZ", "type": "VTL"} + """; // (binding dependencies are ignored) + JSONAssert.assertEquals(expected, result, JSONCompareMode.STRICT); + } + + @Test + void deserializeConditionFilter() throws JsonProcessingException { + // + String jsonInput = """ + {"value": "if FOO then BAR else BAZ", "type": "VTL"} + """; + // + ConditionFilterType conditionFilterType = new ObjectMapper().readValue(jsonInput, ConditionFilterType.class); + // + assertEquals("if FOO then BAR else BAZ", conditionFilterType.getValue()); + assertEquals(LabelTypeEnum.VTL, conditionFilterType.getTypeEnum()); + assertEquals("VTL", conditionFilterType.getType()); // to be removed when string type is removed + assertTrue(conditionFilterType.getBindingDependencies().isEmpty()); + } + +} diff --git a/src/test/java/fr/insee/lunatic/conversion/LabelSerializationTest.java b/src/test/java/fr/insee/lunatic/conversion/LabelSerializationTest.java new file mode 100644 index 00000000..fccea976 --- /dev/null +++ b/src/test/java/fr/insee/lunatic/conversion/LabelSerializationTest.java @@ -0,0 +1,88 @@ +package fr.insee.lunatic.conversion; + +import fr.insee.lunatic.exception.SerializationException; +import fr.insee.lunatic.model.flat.LabelType; +import fr.insee.lunatic.model.flat.LabelTypeEnum; +import fr.insee.lunatic.model.flat.Questionnaire; +import org.json.JSONException; +import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; + +import java.io.ByteArrayInputStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class LabelSerializationTest { + + @Test + void serializeFromQuestionnaire_usingEnumType() throws SerializationException, JSONException { + // + Questionnaire questionnaire = new Questionnaire(); + LabelType label = new LabelType(); + label.setValue("Foo label"); + label.setType(LabelTypeEnum.VTL_MD); + questionnaire.setLabel(label); + // + JsonSerializer jsonSerializer = new JsonSerializer(); + String result = jsonSerializer.serialize(questionnaire); + // + String expected = """ + {"label": {"value": "Foo label", "type": "VTL|MD"}} + """; + JSONAssert.assertEquals(expected, result, JSONCompareMode.STRICT); + } + + @Test + void serializeFromQuestionnaire_usingStringType() throws SerializationException, JSONException { + // + Questionnaire questionnaire = new Questionnaire(); + LabelType label = new LabelType(); + label.setValue("Foo label"); + label.setType("VTL|MD"); + questionnaire.setLabel(label); + // + JsonSerializer jsonSerializer = new JsonSerializer(); + String result = jsonSerializer.serialize(questionnaire); + // + String expected = """ + {"label": {"value": "Foo label", "type": "VTL|MD"}} + """; + JSONAssert.assertEquals(expected, result, JSONCompareMode.STRICT); + } + + @Test + void labelObject_usingStringType_illegalValue() { + LabelType label = new LabelType(); + assertThrows(IllegalArgumentException.class, () -> label.setType("Foo type")); + } + + @Test + void deserializeFromQuestionnaire() throws SerializationException { + // + String jsonInput = """ + {"label": {"value": "Foo label", "type": "VTL|MD"}} + """; + // + JsonDeserializer jsonDeserializer = new JsonDeserializer(); + Questionnaire questionnaire = jsonDeserializer.deserialize(new ByteArrayInputStream(jsonInput.getBytes())); + // + LabelType label = questionnaire.getLabel(); + assertEquals(LabelTypeEnum.VTL_MD, label.getTypeEnum()); + assertEquals("VTL|MD", label.getType()); + } + + @Test + void deserializeFromQuestionnaire_illegalTypeValue() { + // + String jsonInput = """ + {"label": {"value": "Foo label", "type": "Foo value"}} + """; + // + JsonDeserializer jsonDeserializer = new JsonDeserializer(); + assertThrows(SerializationException.class, () -> + jsonDeserializer.deserialize(new ByteArrayInputStream(jsonInput.getBytes()))); + } + +}