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.loxone.internal.controls;
15 import static org.hamcrest.MatcherAssert.assertThat;
16 import static org.hamcrest.Matchers.*;
17 import static org.junit.jupiter.api.Assertions.*;
19 import java.io.IOException;
20 import java.lang.reflect.Type;
21 import java.math.BigDecimal;
22 import java.util.Collection;
23 import java.util.List;
26 import java.util.stream.Collectors;
28 import org.openhab.binding.loxone.internal.types.LxCategory;
29 import org.openhab.binding.loxone.internal.types.LxContainer;
30 import org.openhab.binding.loxone.internal.types.LxState;
31 import org.openhab.binding.loxone.internal.types.LxUuid;
32 import org.openhab.core.thing.Channel;
33 import org.openhab.core.thing.type.ChannelKind;
34 import org.openhab.core.types.Command;
35 import org.openhab.core.types.State;
36 import org.openhab.core.types.StateDescription;
37 import org.openhab.core.types.StateOption;
40 * Common test framework class for all (@link LxControl} objects
42 * @author Pawel Pieczul - initial contribution
46 LxServerHandlerDummy handler;
52 void setupControl(String controlUuid, String roomUuid, String categoryUuid, String controlName) {
53 this.controlUuid = new LxUuid(controlUuid);
54 this.roomUuid = new LxUuid(roomUuid);
55 this.categoryUuid = new LxUuid(categoryUuid);
56 this.controlName = controlName;
57 handler = new LxServerHandlerDummy();
58 handler.loadConfiguration();
61 <T> void testControlCreation(Class<T> testClass, int numberOfControls, int numberOfSubcontrols,
62 int numberOfChannels, int numberOfChannelsWithSubs, int numberOfStates) {
63 assertEquals(numberOfControls, numberOfControls(testClass));
64 LxControl c = getControl(controlUuid);
66 Map<LxUuid, LxControl> subC = c.getSubControls();
68 assertEquals(numberOfSubcontrols, subC.size());
69 assertEquals(controlUuid, c.getUuid());
70 assertEquals(controlName, c.getName());
71 assertEquals(controlName, c.getLabel());
72 LxContainer room = c.getRoom();
74 assertEquals(roomUuid, room.getUuid());
75 LxCategory cat = c.getCategory();
77 assertEquals(categoryUuid, cat.getUuid());
78 assertEquals(numberOfChannels, c.getChannels().size());
79 assertEquals(numberOfChannelsWithSubs, c.getChannelsWithSubcontrols().size());
80 assertEquals(numberOfStates, c.getStates().size());
83 void testChannel(LxControl ctrl, String itemType, String namePostFix, BigDecimal min, BigDecimal max,
84 BigDecimal step, String format, Boolean readOnly, List<StateOption> options, Set<String> tags) {
86 Channel c = getChannel(getExpectedName(ctrl.getLabel(), ctrl.getRoom().getName(), namePostFix), ctrl);
88 assertNotNull(c.getUID());
89 assertNotNull(c.getDescription());
90 assertEquals(itemType, c.getAcceptedItemType());
91 assertEquals(ChannelKind.STATE, c.getKind());
92 StateDescription d = handler.stateDescriptions.get(c.getUID());
93 if (readOnly != null || min != null || max != null || step != null || format != null || options != null) {
95 assertEquals(min, d.getMinimum());
96 assertEquals(max, d.getMaximum());
97 assertEquals(step, d.getStep());
98 assertEquals(format, d.getPattern());
99 assertEquals(readOnly, d.isReadOnly());
100 List<StateOption> opts = d.getOptions();
101 if (options == null) {
102 assertTrue(opts.isEmpty());
105 assertEquals(options.size(), opts.size());
106 options.forEach(o -> {
107 String label = o.getLabel();
108 long num = opts.stream().filter(
109 f -> label != null && label.equals(f.getLabel()) && o.getValue().equals(f.getValue()))
110 .collect(Collectors.counting());
111 assertEquals(1, num);
118 assertThat(c.getDefaultTags(), hasItems(tags.toArray(new String[0])));
120 assertThat(c.getDefaultTags(), empty());
124 void testChannel(String itemType, String namePostFix, BigDecimal min, BigDecimal max, BigDecimal step,
125 String format, Boolean readOnly, List<StateOption> options, Set<String> tags) {
126 LxControl ctrl = getControl(controlUuid);
127 testChannel(ctrl, itemType, namePostFix, min, max, step, format, readOnly, options, tags);
130 void testChannel(String itemType) {
131 testChannel(itemType, null, null, null, null, null, null, null, null);
134 void testChannel(String itemType, Set<String> tags) {
135 testChannel(itemType, null, null, null, null, null, null, null, tags);
138 void testChannel(LxControl ctrl, String itemType) {
139 testChannel(ctrl, itemType, null, null, null, null, null, null, null, null);
142 void testChannel(LxControl ctrl, String itemType, Set<String> tags) {
143 testChannel(ctrl, itemType, null, null, null, null, null, null, null, tags);
146 void testChannel(String itemType, String namePostFix) {
147 testChannel(itemType, namePostFix, null, null, null, null, null, null, null);
150 void testNoChannel(String namePostFix) {
151 LxControl ctrl = getControl(controlUuid);
153 Channel c = getChannel(getExpectedName(ctrl.getLabel(), ctrl.getRoom().getName(), namePostFix), ctrl);
157 void testChannel(String itemType, String namePostFix, Set<String> tags) {
158 testChannel(itemType, namePostFix, null, null, null, null, null, null, tags);
161 void testChannel(String itemType, String namePostFix, BigDecimal min, BigDecimal max, BigDecimal step,
162 String format, Boolean readOnly, List<StateOption> options) {
163 testChannel(itemType, namePostFix, min, max, step, format, readOnly, options, null);
166 State getChannelState(LxControl ctrl, String namePostFix) {
168 Channel c = getChannel(getExpectedName(ctrl.getLabel(), ctrl.getRoom().getName(), namePostFix), ctrl);
170 return ctrl.getChannelState(c.getUID());
173 State getChannelState(String namePostFix) {
174 LxControl ctrl = getControl(controlUuid);
175 return getChannelState(ctrl, namePostFix);
178 void testChannelState(LxControl ctrl, String namePostFix, State expectedValue) {
179 State current = getChannelState(ctrl, namePostFix);
180 if (expectedValue != null) {
181 assertNotNull(current);
183 assertEquals(expectedValue, current);
186 void testChannelState(String namePostFix, State expectedValue) {
187 LxControl ctrl = getControl(controlUuid);
188 testChannelState(ctrl, namePostFix, expectedValue);
191 void testChannelState(State expectedValue) {
192 testChannelState((String) null, expectedValue);
195 void testChannelState(LxControl ctrl, State expectedValue) {
196 testChannelState(ctrl, null, expectedValue);
199 void changeLoxoneState(String stateName, Object value) {
200 LxControl ctrl = getControl(controlUuid);
202 LxState state = ctrl.getStates().get(stateName);
203 assertNotNull(state);
204 state.setStateValue(value);
207 void executeCommand(LxControl ctrl, String namePostFix, Command command) {
209 Channel c = getChannel(getExpectedName(ctrl.getLabel(), ctrl.getRoom().getName(), namePostFix), ctrl);
212 ctrl.handleCommand(c.getUID(), command);
213 } catch (IOException e) {
214 fail("This exception should never happen in test environment.");
218 void executeCommand(String namePostFix, Command command) {
219 LxControl ctrl = getControl(controlUuid);
220 executeCommand(ctrl, namePostFix, command);
223 void executeCommand(LxControl ctrl, Command command) {
224 executeCommand(ctrl, null, command);
227 void executeCommand(Command command) {
228 executeCommand((String) null, command);
231 void testAction(String expectedAction, int numberOfActions) {
232 assertEquals(numberOfActions, handler.actionQueue.size());
233 if (numberOfActions > 0) {
234 String action = handler.actionQueue.poll();
235 assertNotNull(action);
236 assertEquals(controlUuid + "/" + expectedAction, action);
240 void testAction(String expectedAction) {
241 if (expectedAction == null) {
244 testAction(expectedAction, 1);
248 void testSubControl(Type type, String name) {
249 LxControl ctrl = getControl(controlUuid);
251 long n = ctrl.getSubControls().values().stream().filter(c -> name.equals(c.getName()))
252 .collect(Collectors.counting());
256 private Channel getChannel(String name, LxControl c) {
257 List<Channel> channels = c.getChannels();
258 List<Channel> filtered = channels.stream().filter(a -> name.equals(a.getLabel())).collect(Collectors.toList());
259 if (filtered.size() == 1) {
260 return filtered.get(0);
265 private <T> long numberOfControls(Class<T> c) {
266 Collection<LxControl> v = handler.controls.values();
267 return v.stream().filter(o -> c.equals(o.getClass())).collect(Collectors.counting());
270 private LxControl getControl(LxUuid uuid) {
271 return handler.controls.get(uuid);
274 private String getExpectedName(String controlName, String roomName, String postFix) {
275 return roomName + " / " + controlName + (postFix != null ? postFix : "");