2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.dbquery.internal;
15 import static org.hamcrest.CoreMatchers.anyOf;
16 import static org.hamcrest.CoreMatchers.instanceOf;
17 import static org.hamcrest.CoreMatchers.is;
18 import static org.hamcrest.MatcherAssert.assertThat;
19 import static org.hamcrest.number.IsCloseTo.closeTo;
21 import java.math.BigDecimal;
22 import java.nio.charset.Charset;
23 import java.time.Duration;
24 import java.time.Instant;
25 import java.time.ZoneId;
26 import java.time.ZonedDateTime;
27 import java.util.Base64;
28 import java.util.Date;
29 import java.util.stream.Stream;
31 import org.eclipse.jdt.annotation.NonNullByDefault;
32 import org.junit.jupiter.api.AfterEach;
33 import org.junit.jupiter.api.BeforeEach;
34 import org.junit.jupiter.api.Test;
35 import org.junit.jupiter.params.ParameterizedTest;
36 import org.junit.jupiter.params.provider.MethodSource;
37 import org.junit.jupiter.params.provider.ValueSource;
38 import org.openhab.core.library.types.DateTimeType;
39 import org.openhab.core.library.types.DecimalType;
40 import org.openhab.core.library.types.OnOffType;
41 import org.openhab.core.library.types.OpenClosedType;
42 import org.openhab.core.library.types.StringType;
43 import org.openhab.core.types.State;
44 import org.openhab.core.types.UnDefType;
48 * @author Joan Pujol - Initial contribution
51 class Value2StateConverterTest {
52 public static final BigDecimal BIG_DECIMAL_NUMBER = new BigDecimal("212321213123123123123123");
53 private Value2StateConverter instance;
57 instance = new Value2StateConverter();
66 @ValueSource(classes = { StringType.class, DecimalType.class, DateTimeType.class, OpenClosedType.class,
68 void givenNullValueReturnUndef(Class<State> classe) {
69 assertThat(instance.convertValue(null, classe), is(UnDefType.NULL));
73 @ValueSource(strings = { "", "stringValue" })
74 void givenStringValueAndStringTargetReturnStringtype(String value) {
75 var converted = instance.convertValue(value, StringType.class);
76 assertThat(converted.toFullString(), is(value));
80 @MethodSource("provideValuesOfAllSupportedResultRowTypesExceptBytes")
81 void givenValidObjectTypesAndStringTargetReturnStringtypeWithString(Object value) {
82 var converted = instance.convertValue(value, StringType.class);
83 assertThat(converted.toFullString(), is(value.toString()));
87 void givenByteArrayAndStringTargetReturnEncodedBase64() {
88 var someBytes = "Hello world".getBytes(Charset.defaultCharset());
89 var someBytesB64 = Base64.getEncoder().encodeToString(someBytes);
90 var converted = instance.convertValue(someBytes, StringType.class);
91 assertThat(converted.toFullString(), is(someBytesB64));
95 @MethodSource("provideNumericTypes")
96 void givenNumericTypeAndDecimalTargetReturnDecimaltype(Number value) {
97 var converted = instance.convertValue(value, DecimalType.class);
98 assertThat(converted, instanceOf(DecimalType.class));
99 assertThat(((DecimalType) converted).doubleValue(), closeTo(value.doubleValue(), 0.01d));
103 @MethodSource("provideNumericTypes")
104 void givenNumericStringAndDecimalTargetReturnDecimaltype(Number value) {
105 var numberString = value.toString();
106 var converted = instance.convertValue(numberString, DecimalType.class);
107 assertThat(converted, instanceOf(DecimalType.class));
108 assertThat(((DecimalType) converted).doubleValue(), closeTo(value.doubleValue(), 0.01d));
112 void givenDurationAndDecimalTargetReturnDecimaltypeWithMilliseconds() {
113 var duration = Duration.ofDays(1);
114 var converted = instance.convertValue(duration, DecimalType.class);
115 assertThat(converted, instanceOf(DecimalType.class));
116 assertThat(((DecimalType) converted).longValue(), is(duration.toMillis()));
120 void givenInstantAndDatetimeTargetReturnDatetype() {
121 var instant = Instant.now();
122 var converted = instance.convertValue(instant, DateTimeType.class);
123 assertThat(converted, instanceOf(DateTimeType.class));
124 assertThat(((DateTimeType) converted).getZonedDateTime(),
125 is(ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()).withFixedOffsetZone()));
129 void givenDateAndDatetimeTargetReturnDatetype() {
130 var date = new Date();
131 var converted = instance.convertValue(date, DateTimeType.class);
132 assertThat(converted, instanceOf(DateTimeType.class));
133 assertThat(((DateTimeType) converted).getZonedDateTime(),
134 is(ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).withFixedOffsetZone()));
138 @ValueSource(strings = { "2019-10-12T07:20:50.52Z", "2019-10-12" })
139 void givenValidStringDateAndDatetimeTargetReturnDatetype(String date) {
140 var converted = instance.convertValue(date, DateTimeType.class);
141 assertThat(converted, instanceOf(DateTimeType.class));
142 var convertedDateTime = ((DateTimeType) converted).getZonedDateTime();
143 assertThat(convertedDateTime.getYear(), is(2019));
144 assertThat(convertedDateTime.getMonthValue(), is(10));
145 assertThat(convertedDateTime.getDayOfMonth(), is(12));
146 assertThat(convertedDateTime.getHour(), anyOf(is(7), is(0)));
150 @MethodSource("trueValues")
151 void givenValuesConsideratedTrueAndOnOffTargetReturnOn(Object value) {
152 var converted = instance.convertValue(value, OnOffType.class);
153 assertThat(converted, instanceOf(OnOffType.class));
154 assertThat(converted, is(OnOffType.ON));
158 @MethodSource("falseValues")
159 void givenValuesConsideratedFalseAndOnOffTargetReturnOff(Object value) {
160 var converted = instance.convertValue(value, OnOffType.class);
161 assertThat(converted, instanceOf(OnOffType.class));
162 assertThat(converted, is(OnOffType.OFF));
166 @MethodSource("trueValues")
167 void givenValuesConsideratedTrueAndOpenClosedTargetReturnOpen(Object value) {
168 var converted = instance.convertValue(value, OpenClosedType.class);
169 assertThat(converted, instanceOf(OpenClosedType.class));
170 assertThat(converted, is(OpenClosedType.OPEN));
174 @MethodSource("falseValues")
175 void givenValuesConsideratedFalseAndOpenClosedTargetReturnClosed(Object value) {
176 var converted = instance.convertValue(value, OpenClosedType.class);
177 assertThat(converted, instanceOf(OpenClosedType.class));
178 assertThat(converted, is(OpenClosedType.CLOSED));
181 private static Stream<Object> trueValues() {
182 return Stream.of("true", "True", 1, 2, "On", "on", -1, 0.3);
185 private static Stream<Object> falseValues() {
186 return Stream.of("false", "False", 0, 0.0d, "off", "Off", "", "a value");
189 private static Stream<Number> provideNumericTypes() {
190 return Stream.of(1L, 1.2, 1.2f, -1, 0, BIG_DECIMAL_NUMBER);
193 private static Stream<Object> provideValuesOfAllSupportedResultRowTypes() {
194 return Stream.of("", "String", Boolean.TRUE, 1L, 1.2, 1.2f, BIG_DECIMAL_NUMBER,
195 "bytes".getBytes(Charset.defaultCharset()), Instant.now(), new Date(), Duration.ofDays(1));
198 private static Stream<Object> provideValuesOfAllSupportedResultRowTypesExceptBytes() {
199 return provideValuesOfAllSupportedResultRowTypes().filter(o -> !(o instanceof byte[]));