]> git.basschouten.com Git - openhab-addons.git/blob
e34886c651790bf26bfca0aaf316ea52a3c74256
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.deutschebahn.internal.filter;
14
15 import static org.hamcrest.MatcherAssert.assertThat;
16 import static org.hamcrest.Matchers.*;
17 import static org.junit.jupiter.api.Assertions.fail;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.regex.Pattern;
24
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.junit.jupiter.api.Test;
27 import org.openhab.binding.deutschebahn.internal.AttributeSelection;
28 import org.openhab.binding.deutschebahn.internal.EventAttribute;
29 import org.openhab.binding.deutschebahn.internal.EventAttributeSelection;
30 import org.openhab.binding.deutschebahn.internal.EventType;
31 import org.openhab.binding.deutschebahn.internal.TripLabelAttribute;
32
33 /**
34  * Tests for {@link FilterParser}
35  *
36  * @author Sönke Küper - Initial contribution.
37  */
38 @NonNullByDefault
39 public class FilterParserTest {
40
41     private static final class FilterTokenSequenceBuilder {
42
43         private final List<FilterToken> tokens = new ArrayList<>();
44         private int position = 0;
45
46         private int getPos() {
47             this.position++;
48             return this.position;
49         }
50
51         public List<FilterToken> build() {
52             return this.tokens;
53         }
54
55         public FilterTokenSequenceBuilder and() {
56             this.tokens.add(new AndOperator(getPos()));
57             return this;
58         }
59
60         public FilterTokenSequenceBuilder or() {
61             this.tokens.add(new OrOperator(getPos()));
62             return this;
63         }
64
65         public FilterTokenSequenceBuilder bracketOpen() {
66             this.tokens.add(new BracketOpenToken(getPos()));
67             return this;
68         }
69
70         public FilterTokenSequenceBuilder bracketClose() {
71             this.tokens.add(new BracketCloseToken(getPos()));
72             return this;
73         }
74
75         public ChannelNameEquals channelFilter(String channelGroup, String channelName, String pattern) {
76             ChannelNameEquals channelNameEquals = new ChannelNameEquals(getPos(), channelGroup, channelName,
77                     Pattern.compile(pattern));
78             this.tokens.add(channelNameEquals);
79             return channelNameEquals;
80         }
81
82         public FilterTokenSequenceBuilder channelFilter(ChannelNameEquals equals) {
83             this.tokens.add(equals);
84             return this;
85         }
86     }
87
88     private static FilterTokenSequenceBuilder builder() {
89         return new FilterTokenSequenceBuilder();
90     }
91
92     private static void checkAttributeFilter(TimetableStopPredicate predicate, ChannelNameEquals channelEquals,
93             EventType eventType, EventAttribute<?, ?> eventAttribute) {
94         checkAttributeFilter(predicate, channelEquals, new EventAttributeSelection(eventType, eventAttribute));
95     }
96
97     private static void checkAttributeFilter(TimetableStopPredicate predicate, ChannelNameEquals channelEquals,
98             AttributeSelection attributeSelection) {
99         assertThat(predicate, is(instanceOf(TimetableStopByStringEventAttributeFilter.class)));
100         TimetableStopByStringEventAttributeFilter attributeFilter = (TimetableStopByStringEventAttributeFilter) predicate;
101         assertThat(attributeFilter.getFilter(), is(channelEquals.getFilterValue()));
102         assertThat(attributeFilter.getAttributeSelection(), is(attributeSelection));
103     }
104
105     private static OrPredicate assertOr(TimetableStopPredicate predicate) {
106         assertThat(predicate, is(instanceOf(OrPredicate.class)));
107         return (OrPredicate) predicate;
108     }
109
110     private static AndPredicate assertAnd(TimetableStopPredicate predicate) {
111         assertThat(predicate, is(instanceOf(AndPredicate.class)));
112         return (AndPredicate) predicate;
113     }
114
115     @Test
116     public void testParseSimple() throws FilterParserException {
117         final List<FilterToken> input = new ArrayList<>();
118         ChannelNameEquals channelEquals = new ChannelNameEquals(1, "trip", "number", Pattern.compile("20"));
119         input.add(channelEquals);
120         final TimetableStopPredicate result = FilterParser.parse(input);
121         checkAttributeFilter(result, channelEquals, TripLabelAttribute.N);
122     }
123
124     @Test
125     public void testParseAnd() throws FilterParserException {
126         final FilterTokenSequenceBuilder b = builder();
127         final ChannelNameEquals channelEquals01 = b.channelFilter("trip", "number", "20");
128         b.and();
129         final ChannelNameEquals channelEquals02 = b.channelFilter("trip", "number", "30");
130         final TimetableStopPredicate result = FilterParser.parse(b.build());
131         final AndPredicate andPredicate = assertAnd(result);
132
133         checkAttributeFilter(andPredicate.getFirst(), channelEquals01, TripLabelAttribute.N);
134         checkAttributeFilter(andPredicate.getSecond(), channelEquals02, TripLabelAttribute.N);
135     }
136
137     @Test
138     public void testParseOr() throws FilterParserException {
139         final FilterTokenSequenceBuilder b = builder();
140         final ChannelNameEquals channelEquals01 = b.channelFilter("trip", "number", "20");
141         b.or();
142         final ChannelNameEquals channelEquals02 = b.channelFilter("trip", "number", "30");
143         final TimetableStopPredicate result = FilterParser.parse(b.build());
144         final OrPredicate orPredicate = assertOr(result);
145
146         checkAttributeFilter(orPredicate.getFirst(), channelEquals01, TripLabelAttribute.N);
147         checkAttributeFilter(orPredicate.getSecond(), channelEquals02, TripLabelAttribute.N);
148     }
149
150     @Test
151     public void testParseWithBrackets() throws FilterParserException {
152         final FilterTokenSequenceBuilder b = new FilterTokenSequenceBuilder();
153         final ChannelNameEquals channelEquals01 = b.channelFilter("trip", "number", "20");
154         b.and();
155         b.bracketOpen();
156         final ChannelNameEquals channelEquals02 = b.channelFilter("departure", "line", "RE10");
157         b.or();
158         final ChannelNameEquals channelEquals03 = b.channelFilter("departure", "line", "RE20");
159         b.bracketClose();
160         final List<FilterToken> input = b.build();
161
162         final TimetableStopPredicate result = FilterParser.parse(input);
163         final AndPredicate andPredicate = assertAnd(result);
164
165         checkAttributeFilter(andPredicate.getFirst(), channelEquals01, TripLabelAttribute.N);
166         final OrPredicate orPredicate = assertOr(andPredicate.getSecond());
167
168         checkAttributeFilter(orPredicate.getFirst(), channelEquals02, EventType.DEPARTURE, EventAttribute.L);
169         checkAttributeFilter(orPredicate.getSecond(), channelEquals03, EventType.DEPARTURE, EventAttribute.L);
170     }
171
172     @Test
173     public void testParseWithMultipleBrackets() throws FilterParserException {
174         final FilterTokenSequenceBuilder b = builder();
175         b.bracketOpen();
176         b.bracketOpen();
177         final ChannelNameEquals channelEquals01 = b.channelFilter("trip", "number", "20");
178         b.and();
179         final ChannelNameEquals channelEquals02 = b.channelFilter("departure", "line", "RE22");
180         b.bracketClose();
181         b.or();
182         b.bracketOpen();
183         final ChannelNameEquals channelEquals03 = b.channelFilter("trip", "number", "30");
184         b.and();
185         final ChannelNameEquals channelEquals04 = b.channelFilter("departure", "line", "RE33");
186         b.bracketClose();
187         b.bracketClose();
188
189         final List<FilterToken> input = b.build();
190
191         final TimetableStopPredicate result = FilterParser.parse(input);
192         final OrPredicate orPredicate = assertOr(result);
193
194         final AndPredicate firstAnd = assertAnd(orPredicate.getFirst());
195         checkAttributeFilter(firstAnd.getFirst(), channelEquals01, TripLabelAttribute.N);
196         checkAttributeFilter(firstAnd.getSecond(), channelEquals02, EventType.DEPARTURE, EventAttribute.L);
197
198         final AndPredicate secondAnd = assertAnd(orPredicate.getSecond());
199         checkAttributeFilter(secondAnd.getFirst(), channelEquals03, TripLabelAttribute.N);
200         checkAttributeFilter(secondAnd.getSecond(), channelEquals04, EventType.DEPARTURE, EventAttribute.L);
201     }
202
203     @Test
204     public void testParseErrors() {
205         final ChannelNameEquals channelEquals = new ChannelNameEquals(1, "trip", "number", Pattern.compile("20"));
206         try {
207             FilterParser.parse(Collections.emptyList());
208             fail();
209         } catch (FilterParserException e) {
210         }
211
212         try {
213             FilterParser.parse(builder().and().build());
214             fail();
215         } catch (FilterParserException e) {
216         }
217
218         try {
219             FilterParser.parse(builder().or().build());
220             fail();
221         } catch (FilterParserException e) {
222         }
223         try {
224             FilterParser.parse(builder().bracketOpen().build());
225             fail();
226         } catch (FilterParserException e) {
227         }
228         try {
229             FilterParser.parse(builder().bracketClose().build());
230             fail();
231         } catch (FilterParserException e) {
232         }
233         try {
234             FilterParser.parse(builder().bracketOpen().bracketClose().build());
235             fail();
236         } catch (FilterParserException e) {
237         }
238         try {
239             FilterParser.parse(builder().bracketOpen().and().build());
240             fail();
241         } catch (FilterParserException e) {
242         }
243         try {
244             FilterParser.parse(builder().bracketOpen().and().build());
245             fail();
246         } catch (FilterParserException e) {
247         }
248         try {
249             FilterParser.parse(builder().channelFilter(channelEquals).and().bracketOpen().build());
250             fail();
251         } catch (FilterParserException e) {
252         }
253         try {
254             FilterParser.parse(builder().channelFilter(channelEquals).and().bracketClose().build());
255             fail();
256         } catch (FilterParserException e) {
257         }
258         try {
259             FilterParser.parse(builder().channelFilter(channelEquals).or().bracketOpen().build());
260             fail();
261         } catch (FilterParserException e) {
262         }
263         try {
264             FilterParser.parse(builder().channelFilter(channelEquals).or().bracketClose().build());
265             fail();
266         } catch (FilterParserException e) {
267         }
268         try {
269             FilterParser.parse(builder().channelFilter(channelEquals).and().build());
270             fail();
271         } catch (FilterParserException e) {
272         }
273         try {
274             FilterParser.parse(builder().channelFilter(channelEquals).or().build());
275             fail();
276         } catch (FilterParserException e) {
277         }
278         try {
279             FilterParser.parse(Arrays.asList(channelEquals, channelEquals));
280             fail();
281         } catch (FilterParserException e) {
282         }
283     }
284 }