Skip to content

Commit

Permalink
ActionInputsHelper: Allow any number of decimals & Apply primitive in…
Browse files Browse the repository at this point in the history
…put default values (#4424)

* ActionInputHelper: Set step site to 0 if param type decimal

This makes the UI allow any step size, i.e. entering any number of decimals.

Signed-off-by: Florian Hotze <[email protected]>

* ActionInputHelper: Apply default values when mapping from serialised to action inputs

This has been forgotten to be implemented.

Signed-off-by: Florian Hotze <[email protected]>
  • Loading branch information
florian-h05 authored Oct 26, 2024
1 parent 4125f3d commit 52b26ba
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import javax.measure.Unit;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.type.ActionType;
import org.openhab.core.automation.type.Input;
import org.openhab.core.config.core.ConfigDescriptionParameter;
Expand Down Expand Up @@ -177,6 +178,9 @@ public ConfigDescriptionParameter mapActionInputToConfigDescriptionParameter(Inp
if (unit != null) {
builder = builder.withUnit(unit.getSymbol());
}
if (parameterType == ConfigDescriptionParameter.Type.DECIMAL) {
builder = builder.withStepSize(BigDecimal.ZERO);
}
return builder.build();
}

Expand All @@ -197,11 +201,29 @@ public Map<String, Object> mapSerializedInputsToActionInputs(ActionType actionTy
} catch (IllegalArgumentException e) {
logger.warn("{} Input parameter is ignored.", e.getMessage());
}
} else {
value = getDefaultValueForActionInput(input);
if (value != null) {
newArguments.put(input.getName(), value);
}
}
}
return newArguments;
}

private @Nullable Object getDefaultValueForActionInput(Input input) {
return switch (input.getType()) {
case "boolean" -> false;
case "byte" -> (byte) 0;
case "short" -> (short) 0;
case "int" -> 0;
case "long" -> 0L;
case "float" -> 0.0f;
case "double" -> 0.0d;
default -> null;
};
}

/**
* Maps a serialised input to the Java type required by the given {@link Input}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.*;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
Expand Down Expand Up @@ -63,132 +64,132 @@ public class ActionInputHelperTest {
@Test
public void testMapActionInputToConfigDescriptionParameterWhenBoolean() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Boolean")),
ConfigDescriptionParameter.Type.BOOLEAN, false, null, null, null);
ConfigDescriptionParameter.Type.BOOLEAN, false, null, null, null, null);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("boolean")),
ConfigDescriptionParameter.Type.BOOLEAN, true, "false", null, null);
ConfigDescriptionParameter.Type.BOOLEAN, true, "false", null, null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenByte() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Byte")),
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null);
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null, null);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("byte")),
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null);
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenShort() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Short")),
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null);
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null, null);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("short")),
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null);
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenInteger() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Integer")),
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null);
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null, null);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("int")),
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null);
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenLong() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Long")),
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null);
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null, null);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("long")),
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null);
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenFloat() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Float")),
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null);
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null, BigDecimal.ZERO);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("float")),
ConfigDescriptionParameter.Type.DECIMAL, true, "0", null, null);
ConfigDescriptionParameter.Type.DECIMAL, true, "0", null, null, BigDecimal.ZERO);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenDouble() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Double")),
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null);
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null, BigDecimal.ZERO);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("double")),
ConfigDescriptionParameter.Type.DECIMAL, true, "0", null, null);
ConfigDescriptionParameter.Type.DECIMAL, true, "0", null, null, BigDecimal.ZERO);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenNumber() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Number")),
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null);
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null, BigDecimal.ZERO);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenDecimalType() {
checkParameter(
helper.mapActionInputToConfigDescriptionParameter(
buildInput("org.openhab.core.library.types.DecimalType")),
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null);
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null, BigDecimal.ZERO);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenQuantityType() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("QuantityType<Temperature>")),
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, "°C");
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, "°C", BigDecimal.ZERO);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenString() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.String")),
ConfigDescriptionParameter.Type.TEXT, false, null, null, null);
ConfigDescriptionParameter.Type.TEXT, false, null, null, null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenLocalDate() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.LocalDate")),
ConfigDescriptionParameter.Type.TEXT, false, null, "date", null);
ConfigDescriptionParameter.Type.TEXT, false, null, "date", null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenLocalTime() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.LocalTime")),
ConfigDescriptionParameter.Type.TEXT, false, null, "time", null);
ConfigDescriptionParameter.Type.TEXT, false, null, "time", null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenLocalDateTime() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.LocalDateTime")),
ConfigDescriptionParameter.Type.TEXT, false, null, "datetime", null);
ConfigDescriptionParameter.Type.TEXT, false, null, "datetime", null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenDate() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.util.Date")),
ConfigDescriptionParameter.Type.TEXT, false, null, "datetime", null);
ConfigDescriptionParameter.Type.TEXT, false, null, "datetime", null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenZonedDateTime() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.ZonedDateTime")),
ConfigDescriptionParameter.Type.TEXT, false, null, null, null);
ConfigDescriptionParameter.Type.TEXT, false, null, null, null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenInstant() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.Instant")),
ConfigDescriptionParameter.Type.TEXT, false, null, null, null);
ConfigDescriptionParameter.Type.TEXT, false, null, null, null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenDuration() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.Duration")),
ConfigDescriptionParameter.Type.TEXT, false, null, null, null);
ConfigDescriptionParameter.Type.TEXT, false, null, null, null, null);
}

@Test
public void testMapActionInputToConfigDescriptionParameterWhenDefaultValue() {
Input input = new Input(PARAM_NAME, "int", PARAM_LABEL, PARAM_DESCRIPTION, null, false, null, "-1");
checkParameter(helper.mapActionInputToConfigDescriptionParameter(input),
ConfigDescriptionParameter.Type.INTEGER, true, "-1", null, null);
ConfigDescriptionParameter.Type.INTEGER, true, "-1", null, null, null);
}

@Test
Expand All @@ -205,9 +206,9 @@ public void testMapActionInputsToConfigDescriptionParametersWhenOk() {
.mapActionInputsToConfigDescriptionParameters(List.of(input1, input2));
assertThat(params.size(), is(2));
checkParameter(params.get(0), "Boolean", ConfigDescriptionParameter.Type.BOOLEAN, PARAM_LABEL,
PARAM_DESCRIPTION, true, "false", null, null);
PARAM_DESCRIPTION, true, "false", null, null, null);
checkParameter(params.get(1), "String", ConfigDescriptionParameter.Type.TEXT, PARAM_LABEL, PARAM_DESCRIPTION,
false, null, null, null);
false, null, null, null, null);
}

@Test
Expand Down Expand Up @@ -476,6 +477,29 @@ public void testMapSerializedInputToActionInputWhenAnyOtherType() {
assertThat(helper.mapSerializedInputToActionInput(input, val), is(val));
}

@Test
public void testMapSerializedInputsToActionInputsAppliesDefaults() {
Input inputBoolean = buildInput("BooleanParam", "boolean");
Input inputByte = buildInput("ByteParam", "byte");
Input inputShort = buildInput("ShortParam", "short");
Input inputInteger = buildInput("IntegerParam", "int");
Input inputLong = buildInput("LongParam", "long");
Input inputFloat = buildInput("FloatParam", "float");
Input inputDouble = buildInput("DoubleParam", "double");
ActionType action = new ActionType("action", null,
List.of(inputBoolean, inputByte, inputShort, inputInteger, inputLong, inputFloat, inputDouble));

Map<String, Object> result = helper.mapSerializedInputsToActionInputs(action, Map.of());
assertThat(result.size(), is(7));
assertThat(result.get("BooleanParam"), is(Boolean.FALSE));
assertThat(result.get("ByteParam"), is((byte) 0));
assertThat(result.get("ShortParam"), is((short) 0));
assertThat(result.get("IntegerParam"), is(0));
assertThat(result.get("LongParam"), is(0L));
assertThat(result.get("FloatParam"), is(0.0f));
assertThat(result.get("DoubleParam"), is(0.0));
}

@Test
public void testMapSerializedInputsToActionInputs() {
Input input1 = buildInput("BooleanParam", "java.lang.Boolean");
Expand All @@ -500,13 +524,15 @@ private Input buildInput(String name, String type) {
}

private void checkParameter(ConfigDescriptionParameter param, ConfigDescriptionParameter.Type type,
boolean required, @Nullable String defaultValue, @Nullable String context, @Nullable String unit) {
checkParameter(param, PARAM_NAME, type, PARAM_LABEL, PARAM_DESCRIPTION, required, defaultValue, context, unit);
boolean required, @Nullable String defaultValue, @Nullable String context, @Nullable String unit,
@Nullable BigDecimal step) {
checkParameter(param, PARAM_NAME, type, PARAM_LABEL, PARAM_DESCRIPTION, required, defaultValue, context, unit,
step);
}

private void checkParameter(ConfigDescriptionParameter param, String name, ConfigDescriptionParameter.Type type,
String label, String description, boolean required, @Nullable String defaultValue, @Nullable String context,
@Nullable String unit) {
@Nullable String unit, @Nullable BigDecimal step) {
assertThat(param.getName(), is(name));
assertThat(param.getLabel(), is(label));
assertThat(param.getDescription(), is(description));
Expand All @@ -528,6 +554,11 @@ private void checkParameter(ConfigDescriptionParameter param, String name, Confi
} else {
assertNotNull(param.getUnit());
}
if (step == null) {
assertNull(param.getStepSize());
} else {
assertThat(param.getStepSize(), is(step));
}
}

public class TestUnitProvider implements UnitProvider {
Expand Down

0 comments on commit 52b26ba

Please sign in to comment.