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.fmiweather;
15 import static org.junit.jupiter.api.Assertions.*;
17 import java.lang.reflect.InvocationTargetException;
18 import java.lang.reflect.Method;
19 import java.math.BigDecimal;
20 import java.util.Arrays;
21 import java.util.List;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.junit.jupiter.params.ParameterizedTest;
26 import org.junit.jupiter.params.provider.MethodSource;
27 import org.openhab.binding.fmiweather.internal.AbstractWeatherHandler;
28 import org.openhab.binding.fmiweather.internal.client.Data;
31 * Base class for response parsing tests
33 * @author Sami Salonen - Initial contribution
37 public class AbstractWeatherHandlerTest {
39 private static BigDecimal bd(Number x) {
40 return new BigDecimal(x.doubleValue());
43 protected static long floorToEvenMinutes(long epochSeconds, int roundMinutes) {
46 method = AbstractWeatherHandler.class.getDeclaredMethod("floorToEvenMinutes", long.class, int.class);
47 method.setAccessible(true);
48 Object res = method.invoke(null, epochSeconds, roundMinutes);
51 } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
52 | InvocationTargetException e) {
54 throw new IllegalStateException(); // to make compiler happy
58 protected static long ceilToEvenMinutes(long epochSeconds, int roundMinutes) {
61 method = AbstractWeatherHandler.class.getDeclaredMethod("ceilToEvenMinutes", long.class, int.class);
62 method.setAccessible(true);
63 Object res = method.invoke(null, epochSeconds, roundMinutes);
66 } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
67 | InvocationTargetException e) {
69 throw new IllegalStateException(); // to make compiler happy
73 public static final List<Object[]> parametersForFloorToEvenMinutes() {
74 return Arrays.asList(new Object[][] { //
75 { 1626605128L /* 2021-07-18 10:45:28 */, 1, 1626605100 /* 10:45 */ }, //
76 { 1626605128L /* 2021-07-18 10:45:28 */, 5, 1626605100 /* 10:45 */ }, //
77 { 1626605128L /* 2021-07-18 10:45:28 */, 10, 1626604800 /* 10:40 */ }, //
78 { 1626605128L /* 2021-07-18 10:45:28 */, 30, 1626604200 /* 10:30 */ }, //
79 { 1626605128L /* 2021-07-18 10:45:28 */, 60, 1626602400 /* 10:00 */ }, //
83 protected static int lastValidIndex(Data data) {
86 method = AbstractWeatherHandler.class.getDeclaredMethod("lastValidIndex", Data.class);
87 method.setAccessible(true);
88 Object res = method.invoke(null, data);
91 } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
92 | InvocationTargetException e) {
94 throw new IllegalStateException(); // to make compiler happy
99 @MethodSource("parametersForFloorToEvenMinutes")
100 public void testFloorToEvenMinutes(long epochSeconds, int roundMinutes, long expected) {
101 assertEquals(expected, floorToEvenMinutes(epochSeconds, roundMinutes));
104 public static final List<Object[]> parametersForCeilToEvenMinutes() {
105 return Arrays.asList(new Object[][] { //
106 { 1626605128L /* 2021-07-18 10:45:28 */, 1, 1626605160 /* 10:46 */ }, //
107 { 1626605128L /* 2021-07-18 10:45:28 */, 5, 1626605400 /* 10:50 */ }, //
108 { 1626605128L /* 2021-07-18 10:45:28 */, 10, 1626605400 /* 10:50 */ }, //
109 { 1626605128L /* 2021-07-18 10:45:28 */, 30, 1626606000 /* 11:00 */ }, //
110 { 1626605128L /* 2021-07-18 10:45:28 */, 60, 1626606000 /* 11:00 */ }, //
115 @MethodSource("parametersForCeilToEvenMinutes")
116 public void testCeilToEvenMinutes(long epochSeconds, int roundMinutes, long expected) {
117 assertEquals(expected, ceilToEvenMinutes(epochSeconds, roundMinutes));
120 public static final List<Object[]> parametersForLastValidIndex() {
121 return Arrays.asList(new Object[][] { //
122 { "no nulls", 1, new BigDecimal[] { bd(1), bd(2) } }, //
123 { "one null in beginning", 1, new BigDecimal[] { null, bd(2) } }, //
124 { "two nulls", 2, new BigDecimal[] { null, null, bd(2) } }, //
125 { "three nulls", 3, new BigDecimal[] { null, null, null, bd(2) } }, //
126 { "null at end", 1, new BigDecimal[] { bd(1), bd(2), null } }, //
127 { "null at end #2", 2, new BigDecimal[] { bd(1), bd(2), bd(2), null } }, //
128 { "null in middle", 3, new BigDecimal[] { bd(1), bd(2), null, bd(3) } }, //
129 { "null in beginning and middle", 3, new BigDecimal[] { null, bd(2), null, bd(3) } }, //
130 { "all null #1", -1, new BigDecimal[] { null, null, } }, //
131 { "all null #2", -1, new BigDecimal[] { null, null, null, } }, //
132 { "all null #3", -1, new BigDecimal[] { null, null, null, null } }, //
137 @MethodSource("parametersForLastValidIndex")
138 public void testLastValidIndex(String msg, int expected, @Nullable BigDecimal... values) {
139 long[] dummyTimestamps = new long[values.length];
140 assertEquals(expected, lastValidIndex(new Data(dummyTimestamps, values)), msg);