Use option label when formatting the option label with the provided pattern fails (#4205)

Issue discussed in openhab/openhab-android#3623

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
lolodomo
2024-05-01 17:33:38 +02:00
committed by GitHub
parent c430e6f6e4
commit 21186d6168
2 changed files with 86 additions and 13 deletions
@@ -20,6 +20,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.IllegalFormatException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -64,7 +65,6 @@ import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.types.PlayPauseType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.model.sitemap.sitemap.ColorArray;
import org.openhab.core.model.sitemap.sitemap.Default;
import org.openhab.core.model.sitemap.sitemap.Group;
@@ -401,19 +401,20 @@ public class ItemUIRegistryImpl implements ItemUIRegistry {
// if the channel contains options, we build a label with the mapped option value
if (stateDescription != null) {
for (StateOption option : stateDescription.getOptions()) {
if (option.getValue().equals(state.toString()) && option.getLabel() != null) {
State stateOption = new StringType(option.getLabel());
String optionLabel = option.getLabel();
if (option.getValue().equals(state.toString()) && optionLabel != null) {
String formatPatternOption;
try {
String formatPatternOption = stateOption.format(formatPattern);
labelMappedOption = label.trim();
labelMappedOption = labelMappedOption.substring(0,
labelMappedOption.indexOf("[") + 1) + formatPatternOption + "]";
} catch (IllegalArgumentException e) {
formatPatternOption = String.format(formatPattern, optionLabel);
} catch (IllegalFormatException e) {
logger.debug(
"Mapping option value '{}' for item {} using format '{}' failed ({}); mapping is ignored",
stateOption, itemName, formatPattern, e.getMessage());
labelMappedOption = null;
"Mapping option value '{}' for item {} using format '{}' failed ({}); format is ignored and option label is used",
optionLabel, itemName, formatPattern, e.getMessage());
formatPatternOption = optionLabel;
}
labelMappedOption = label.trim();
labelMappedOption = labelMappedOption.substring(0, labelMappedOption.indexOf("[") + 1)
+ formatPatternOption + "]";
break;
}
}
@@ -690,7 +690,7 @@ public class ItemUIRegistryImplTest {
}
@Test
public void getLabelLabelWithMappedOption() {
public void getLabelStringItemLabelWithMappedOption() {
String testLabel = "Label";
StateDescription stateDescription = mock(StateDescription.class);
@@ -707,7 +707,7 @@ public class ItemUIRegistryImplTest {
}
@Test
public void getLabelLabelWithUnmappedOption() {
public void getLabelStringItemLabelWithUnmappedOption() {
String testLabel = "Label";
StateDescription stateDescription = mock(StateDescription.class);
@@ -723,6 +723,78 @@ public class ItemUIRegistryImplTest {
assertEquals("Label [State]", label);
}
@Test
public void getLabelStringItemLabelWithMappedOptionButInappropriatePattern() {
String testLabel = "Label";
StateDescription stateDescription = mock(StateDescription.class);
List<StateOption> options = new ArrayList<>();
options.add(new StateOption("State0", "This is the state 0"));
options.add(new StateOption("State1", "This is the state 1"));
when(widgetMock.getLabel()).thenReturn(testLabel);
when(itemMock.getStateDescription()).thenReturn(stateDescription);
when(stateDescription.getPattern()).thenReturn("Value: %f");
when(stateDescription.getOptions()).thenReturn(options);
when(itemMock.getState()).thenReturn(new StringType("State0"));
String label = uiRegistry.getLabel(widgetMock);
assertEquals("Label [This is the state 0]", label);
}
@Test
public void getLabelNumberItemLabelWithMappedOption() {
String testLabel = "Label";
StateDescription stateDescription = mock(StateDescription.class);
List<StateOption> options = new ArrayList<>();
options.add(new StateOption("0", "This is the state number 0"));
options.add(new StateOption("1", "This is the state number 1"));
when(widgetMock.getLabel()).thenReturn(testLabel);
when(itemMock.getStateDescription()).thenReturn(stateDescription);
when(stateDescription.getPattern()).thenReturn("%s");
when(stateDescription.getOptions()).thenReturn(options);
when(itemMock.getState()).thenReturn(new DecimalType(1));
String label = uiRegistry.getLabel(widgetMock);
assertEquals("Label [This is the state number 1]", label);
}
@Test
public void getLabelNumberItemLabelWithUnmappedOption() {
String testLabel = "Label";
StateDescription stateDescription = mock(StateDescription.class);
List<StateOption> options = new ArrayList<>();
options.add(new StateOption("0", "This is the state number 0"));
options.add(new StateOption("1", "This is the state number 1"));
when(widgetMock.getLabel()).thenReturn(testLabel);
when(itemMock.getStateDescription()).thenReturn(stateDescription);
when(stateDescription.getPattern()).thenReturn("%s");
when(stateDescription.getOptions()).thenReturn(options);
when(itemMock.getState()).thenReturn(new DecimalType(2));
String label = uiRegistry.getLabel(widgetMock);
assertEquals("Label [2]", label);
}
@Test
public void getLabelNumberItemLabelWithMappedOptionButInappropriatePattern() {
String testLabel = "Label";
StateDescription stateDescription = mock(StateDescription.class);
List<StateOption> options = new ArrayList<>();
options.add(new StateOption("0", "This is the state number 0"));
options.add(new StateOption("1", "This is the state number 1"));
when(widgetMock.getLabel()).thenReturn(testLabel);
when(itemMock.getStateDescription()).thenReturn(stateDescription);
when(stateDescription.getPattern()).thenReturn("Value: %f");
when(stateDescription.getOptions()).thenReturn(options);
when(itemMock.getState()).thenReturn(new DecimalType(0));
String label = uiRegistry.getLabel(widgetMock);
assertEquals("Label [This is the state number 0]", label);
when(stateDescription.getPattern()).thenReturn("Value: %d");
label = uiRegistry.getLabel(widgetMock);
assertEquals("Label [This is the state number 0]", label);
}
@Test
public void getLabelTransformationContainingPercentS() throws ItemNotFoundException {
// It doesn't matter that "FOO" doesn't exist - this is to assert it doesn't fail before because of the two "%s"