Skip to content

Commit

Permalink
feat: shape from list in calculated variables (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
nsenave authored Aug 6, 2024
1 parent 028afc8 commit f9cbbc1
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 9 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<artifactId>lunatic-model</artifactId>
<packaging>jar</packaging>

<version>3.12.0</version>
<version>3.13.0</version>
<name>Lunatic Model</name>
<description>Classes and converters for the Lunatic model</description>
<url>https://inseefr.github.io/Lunatic-Model/</url>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fr.insee.lunatic.model.flat.variable;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import fr.insee.lunatic.model.flat.LabelType;
import lombok.Getter;
import lombok.Setter;
Expand All @@ -11,23 +13,60 @@
/**
* A calculated variable contains an expression to be evaluated at runtime.
*/
@Getter
@Setter
public class CalculatedVariableType extends VariableType {

public CalculatedVariableType() {
variableType = VariableTypeEnum.CALCULATED;
}

/** Expression of the calculated variable. */
@Getter @Setter
protected LabelType expression;

/** Name of collected and/or external variables that are required to evaluate the expression. */
@Getter @Setter
@JsonInclude(JsonInclude.Include.NON_EMPTY)
protected List<String> bindingDependencies = new ArrayList<>();

/** Name of the collected variable that define the 'shape' of the variable.
* To be replaced with iteration reference and dimension. */
protected String shapeFrom;
/** Name of the collected variables that determine the 'shape' of the variable. */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
protected List<String> shapeFrom = new ArrayList<>();

/**
* Returns the list of the 'shape from' variable names.
* @return A list of variable names.
*/
@JsonProperty("shapeFrom")
public List<String> getShapeFromList() {
return shapeFrom;
}

@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
public void setShapeFrom(List<String> variableNames) {
this.shapeFrom = variableNames;
}

/**
* Get the first variable in the shape from variables list.
* @return A variable name.
* @deprecated The shape from property is a list now so this method will be removed at some point.
*/
@Deprecated(since = "3.13.0")
public String getShapeFrom() {
if (shapeFrom.isEmpty())
return null;
return shapeFrom.getFirst();
}

/**
* Set shape from variable.
* @param variableName Variable name.
* @deprecated The shape from property is now a list of variable names.
*/
@Deprecated(since = "3.13.0")
public void setShapeFrom(String variableName) {
shapeFrom.clear();
shapeFrom.add(variableName);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class CalculatedVariableSerializationTest {
"value": "<VTL expression>",
"type": "VTL"
},
"shapeFrom": "SOME_COLLECTED_VARIABLE"
"shapeFrom": ["SOME_COLLECTED_VARIABLE"]
}
]
}""";
Expand Down Expand Up @@ -90,7 +90,7 @@ void serializeCalculatedVariable_withShapeFrom() throws SerializationException,
calculatedVariableType.setExpression(new LabelType());
calculatedVariableType.getExpression().setValue("<VTL expression>");
calculatedVariableType.getExpression().setType(LabelTypeEnum.VTL);
calculatedVariableType.setShapeFrom("SOME_COLLECTED_VARIABLE");
calculatedVariableType.getShapeFromList().add("SOME_COLLECTED_VARIABLE");
questionnaire.getVariables().add(calculatedVariableType);
//
String result = jsonSerializer.serialize(questionnaire);
Expand Down Expand Up @@ -124,8 +124,53 @@ void deserializeCalculatedVariable_withShapeFrom() throws SerializationException
assertEquals(1, questionnaire.getVariables().size());
CalculatedVariableType calculatedVariableType = assertInstanceOf(CalculatedVariableType.class,
questionnaire.getVariables().getFirst());
assertEquals("SOME_COLLECTED_VARIABLE", calculatedVariableType.getShapeFrom());
assertEquals(1, calculatedVariableType.getShapeFromList().size());
assertEquals("SOME_COLLECTED_VARIABLE", calculatedVariableType.getShapeFromList().getFirst());
assertEquals(1, calculatedVariableType.getDimension().value());
}

@Test
void deserializeShapeFrom_twoVariables() throws SerializationException {
//
String jsonInput = """
{"componentType":"Questionnaire","variables":[
{"variableType":"CALCULATED","shapeFrom":["VAR1", "VAR2"]}
]}""";
//
Questionnaire deserialized = jsonDeserializer.deserialize(new ByteArrayInputStream(jsonInput.getBytes()));
//
CalculatedVariableType calculatedVariable = (CalculatedVariableType) deserialized.getVariables().getFirst();
assertEquals(List.of("VAR1", "VAR2"), calculatedVariable.getShapeFromList());
}

@Test
void serializeShapeFrom_twoVariables() throws SerializationException, JSONException {
//
Questionnaire questionnaire = new Questionnaire();
CalculatedVariableType calculatedVariable = new CalculatedVariableType();
calculatedVariable.setShapeFrom(List.of("VAR1", "VAR2"));
questionnaire.getVariables().add(calculatedVariable);
//
String serialized = jsonSerializer.serialize(questionnaire);
//
String expected = """
{"componentType":"Questionnaire","variables":[
{"variableType":"CALCULATED","shapeFrom":["VAR1", "VAR2"]}
]}""";
JSONAssert.assertEquals(expected, serialized, JSONCompareMode.STRICT);
}

@Test
void stringShapeFrom_backwardCompatibility() throws SerializationException {
//
String stringShapeFrom = """
{"componentType":"Questionnaire","variables":[
{"variableType":"CALCULATED","shapeFrom":"FOO"}
]}""";
//
Questionnaire deserialized = jsonDeserializer.deserialize(new ByteArrayInputStream(stringShapeFrom.getBytes()));
CalculatedVariableType calculatedVariable = (CalculatedVariableType) deserialized.getVariables().getFirst();
assertEquals("FOO", calculatedVariable.getShapeFromList().getFirst());
}

}

0 comments on commit f9cbbc1

Please sign in to comment.