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.transform.scale.internal;
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.mockito.ArgumentMatchers.*;
19 import java.io.IOException;
20 import java.nio.charset.StandardCharsets;
21 import java.nio.file.Files;
22 import java.nio.file.Path;
23 import java.util.HashMap;
26 import javax.measure.quantity.Dimensionless;
28 import org.eclipse.jdt.annotation.NonNullByDefault;
29 import org.junit.jupiter.api.BeforeEach;
30 import org.junit.jupiter.api.Test;
31 import org.junit.jupiter.api.extension.ExtendWith;
32 import org.mockito.Mock;
33 import org.mockito.Mockito;
34 import org.mockito.junit.jupiter.MockitoExtension;
35 import org.mockito.junit.jupiter.MockitoSettings;
36 import org.mockito.quality.Strictness;
37 import org.mockito.stubbing.Answer;
38 import org.openhab.core.library.types.QuantityType;
39 import org.openhab.core.transform.Transformation;
40 import org.openhab.core.transform.TransformationException;
41 import org.openhab.core.transform.TransformationRegistry;
44 * @author Gaƫl L'hopital - Initial contribution
46 @ExtendWith(MockitoExtension.class)
47 @MockitoSettings(strictness = Strictness.LENIENT)
49 public class ScaleTransformServiceTest {
50 private static final String SRC_FOLDER = "conf" + File.separator + "transform";
53 private @NonNullByDefault({}) TransformationRegistry transformationConfigurationRegistry;
54 private final Map<String, Transformation> configurationMap = new HashMap<>();
55 private @NonNullByDefault({}) ScaleTransformationService processor;
58 public void init() throws IOException {
59 configurationMap.clear();
60 Files.walk(Path.of(SRC_FOLDER)).filter(Files::isRegularFile).forEach(file -> {
62 String content = new String(Files.readAllBytes(file), StandardCharsets.UTF_8);
63 String uid = Path.of(SRC_FOLDER).relativize(file).toString();
64 Transformation transformationConfiguration = new Transformation(uid, uid, "scale",
65 Map.of(Transformation.FUNCTION, content));
66 configurationMap.put(uid, transformationConfiguration);
67 } catch (IOException ignored) {
71 Mockito.when(transformationConfigurationRegistry.get(anyString(), eq(null)))
72 .thenAnswer((Answer<Transformation>) invocation -> {
73 Object[] args = invocation.getArguments();
74 return configurationMap.get(args[0]);
76 processor = new ScaleTransformationService(transformationConfigurationRegistry);
80 public void testTransformByScale() throws TransformationException {
81 // need to be sure we'll have the german version
82 String existingscale = "scale" + File.separator + "humidex_de.scale";
84 String transformedResponse = processor.transform(existingscale, source);
85 assertEquals("nicht wesentlich", transformedResponse);
87 existingscale = "scale" + File.separator + "limits.scale";
89 transformedResponse = processor.transform(existingscale, source);
90 assertEquals("middle", transformedResponse);
94 public void testTransformByScaleLimits() throws TransformationException {
95 String existingscale = "scale" + File.separator + "limits.scale";
97 // Testing upper bound opened range
98 String source = "500";
99 String transformedResponse = processor.transform(existingscale, source);
100 assertEquals("extreme", transformedResponse);
102 // Testing lower bound opened range
104 transformedResponse = processor.transform(existingscale, source);
105 assertEquals("low", transformedResponse);
107 // Testing unfinite up and down range
108 existingscale = "scale" + File.separator + "catchall.scale";
110 transformedResponse = processor.transform(existingscale, source);
111 assertEquals("catchall", transformedResponse);
115 public void testTransformByScaleUndef() throws TransformationException {
116 // check that for undefined/non numeric value we return empty string
118 String existingscale = "scale" + File.separator + "humidex_fr.scale";
120 assertThrows(TransformationException.class, () -> processor.transform(existingscale, source));
124 public void testTransformByScaleErrorInBounds() throws TransformationException {
125 // the tested file contains inputs that generate a conversion error of the bounds
127 String existingscale = "scale" + File.separator + "erroneous.scale";
128 String source = "15";
130 @SuppressWarnings("unused")
131 String transformedResponse = processor.transform(existingscale, source);
133 } catch (TransformationException e) {
139 public void testTransformByScaleErrorInValue() throws TransformationException {
140 // checks that an error is raised when trying to scale an erroneous value
141 String existingscale = "scale" + File.separator + "evaluationorder.scale";
142 String source = "azerty";
143 assertThrows(TransformationException.class, () -> processor.transform(existingscale, source));
147 public void testEvaluationOrder() throws TransformationException {
148 // Ensures that only first matching scale as presented in the file is taken in account
149 String evaluationOrder = "scale" + File.separator + "evaluationorder.scale";
150 // This value matches two lines of the scale file
151 String source = "12";
153 String transformedResponse = processor.transform(evaluationOrder, source);
154 assertEquals("first", transformedResponse);
158 public void testTransformQuantityType() throws TransformationException {
159 QuantityType<Dimensionless> airQuality = new QuantityType<>("992 ppm");
160 String aqScaleFile = "scale" + File.separator + "netatmo_aq.scale";
161 String expected = "Correcte (992 ppm) !";
163 String transformedResponse = processor.transform(aqScaleFile, airQuality.toString());
164 assertEquals(expected, transformedResponse);
168 public void testCatchNonNumericValue() throws TransformationException {
169 // checks that an error is raised when trying to scale an erroneous value
170 String existingscale = "scale" + File.separator + "catchnonnumeric.scale";
171 String source = "azerty";
172 String transformedResponse = processor.transform(existingscale, source);
173 assertEquals("Non Numeric", transformedResponse);
177 public void testTransformAndFormat() throws TransformationException {
178 String existingscale = "scale" + File.separator + "netatmo_aq.scale";
179 String source = "992";
180 String transformedResponse = processor.transform(existingscale, source);
181 assertEquals("Correcte (992) !", transformedResponse);
185 public void testValueExceedsRange() throws TransformationException {
186 String existingscale = "scale" + File.separator + "humidex.scale";
187 String source = "200";
188 assertThrows(TransformationException.class, () -> processor.transform(existingscale, source));