1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.utils;
18
19 import static org.apache.juneau.common.utils.Utils.*;
20 import static org.junit.jupiter.api.Assertions.*;
21
22 import java.text.*;
23
24 import org.apache.juneau.*;
25 import org.junit.jupiter.api.*;
26
27
28
29
30 class StringExpressionMatcher_Test extends TestBase {
31
32 private void test(String expression, String toString, String[] shouldMatch, String[] shouldNotMatch) {
33 var m = safe(()->new StringExpressionMatcher(expression));
34 assertEquals(toString, m.toString());
35 for (var i : shouldMatch)
36 if (! m.matches(i))
37 fail("Matcher "+m+" should have matched '"+i+"' but didn't.");
38 for (var i : shouldNotMatch)
39 if (m.matches(i))
40 fail("Matcher "+m+" should not have matched '"+i+"' but did.");
41 }
42
43
44
45
46
47 @Test void a01_noOperand() {
48 test("", "(NEVER)", a(), a("foo", "foox", "xfoo", "fo", null));
49 test(null, "(NEVER)", a(), a("foo", "foox", "xfoo", "fo", null));
50 test(" ", "(NEVER)", a(), a("foo", "foox", "xfoo", "fo", null));
51 test("()", "(NEVER)", a(), a("foo", "foox", "xfoo", "fo", null));
52 test("(())", "(NEVER)", a(), a("foo", "foox", "xfoo", "fo", null));
53 test(" ( ( ) ) ", "(NEVER)", a(), a("foo", "foox", "xfoo", "fo", null));
54 }
55
56
57
58
59
60 @Test void a02_singleOperand_eq() {
61 test("foo", "[= foo]", a("foo"), a("foox", "xfoo", "fo", null));
62 test(" foo ", "[= foo]", a("foo"), a("foox", "xfoo", "fo", null));
63 test("(foo)", "[= foo]", a("foo"), a("foox", "xfoo", "fo", null));
64 test("((foo))", "[= foo]", a("foo"), a("foox", "xfoo", "fo", null));
65 test(" ( foo ) ", "[= foo]", a("foo"), a("foox", "xfoo", "fo", null));
66 test(" ( ( foo ) ) ", "[= foo]", a("foo"), a("foox", "xfoo", "fo", null));
67 }
68
69
70
71
72
73 @Test void a03_singleOperand_pattern() {
74 test("foo*", "[* foo.*]", a("foo", "foox"), a("xfoo", "fo", null));
75 test(" foo* ", "[* foo.*]", a("foo", "foox"), a("xfoo", "fo", null));
76 test("(foo*)", "[* foo.*]", a("foo", "foox"), a("xfoo", "fo", null));
77 test("((foo*))", "[* foo.*]", a("foo", "foox"), a("xfoo", "fo", null));
78 test(" ( foo* ) ", "[* foo.*]", a("foo", "foox"), a("xfoo", "fo", null));
79 test(" ( ( foo* ) ) ", "[* foo.*]", a("foo", "foox"), a("xfoo", "fo", null));
80 }
81
82
83
84
85
86 @Test void a04_or_singlePipe() {
87 test("foo|bar|baz", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
88 test(" foo | bar | baz ", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
89 test("(foo|bar|baz)", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
90 test("(foo)|(bar)|(baz)", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
91 test(" ( foo | bar | baz ) ", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
92 test("((foo)|(bar)|(baz))", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
93 test("((((foo))|((bar))|((baz))))", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
94 test(" ( ( ( ( foo ) ) | ( ( bar ) ) | ( ( baz ) ) ) ) ", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
95 }
96
97
98
99
100
101 @Test void a05_or_doublePipe() {
102 test("foo||bar||baz", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
103 test(" foo || bar || baz ", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
104 test("(foo||bar||baz)", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
105 test("(foo)||(bar)||(baz)", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
106 test(" ( foo || bar || baz ) ", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
107 test("((foo)||(bar)||(baz))", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
108 test("((((foo))||((bar))||((baz))))", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
109 test(" ( ( ( ( foo ) ) || ( ( bar ) ) || ( ( baz ) ) ) ) ", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
110 }
111
112
113
114
115
116 @Test void a06_or_comma() {
117 test("foo,bar,baz", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
118 test(" foo , bar , baz ", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
119 test("(foo,bar,baz)", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
120 test("(foo),(bar),(baz)", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
121 test(" ( foo , bar , baz ) ", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
122 test("((foo),(bar),(baz))", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
123 test("((((foo)),((bar)),((baz))))", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
124 test(" ( ( ( ( foo ) ) , ( ( bar ) ) , ( ( baz ) ) ) ) ", "(| [= foo] [= bar] [= baz])", a("foo", "bar", "baz"), a("foox", "xfoo", "fo", null));
125 }
126
127
128
129
130
131 @Test void a07_and_singleAmp() {
132 test("fo*&*oo&foo", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
133 test(" fo* & *oo & foo ", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
134 test("(fo*&*oo&foo)", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
135 test("(fo*)&(*oo)&(foo)", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
136 test(" ( fo* & *oo & foo ) ", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
137 test("((fo*)&(*oo)&(foo))", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
138 test("((((fo*))&((*oo))&((foo))))", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
139 test(" ( ( ( ( fo* ) ) & ( ( *oo ) ) & ( ( foo ) ) ) ) ", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
140 }
141
142
143
144
145
146 @Test void a08_and_doubleAmp() {
147 test("fo*&&*oo&&foo", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
148 test(" fo* && *oo && foo ", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
149 test("(fo*&&*oo&&foo)", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
150 test("(fo*)&&(*oo)&&(foo)", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
151 test(" ( fo* && *oo && foo ) ", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
152 test("((fo*)&&(*oo)&&(foo))", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
153 test("((((fo*))&&((*oo))&&((foo))))", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
154 test(" ( ( ( ( fo* ) ) && ( ( *oo ) ) && ( ( foo ) ) ) ) ", "(& [* fo.*] [* .*oo] [= foo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
155 }
156
157
158
159
160
161 @Test void a09_and_singleMixed() {
162 test("fo*&*oo|bar", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
163 test("bar|fo*&*oo", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
164 test(" fo* & *oo | bar ", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
165 test(" bar | fo* & *oo ", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
166 test("(fo*&*oo|bar)", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
167 test("(bar|fo*&*oo)", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
168 test("(fo*)&(*oo)|(bar)", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
169 test("(bar)|(fo*)&(*oo)", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
170 test(" ( fo* & *oo | bar ) ", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
171 test(" ( bar | fo* & *oo ) ", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
172 test("((fo*)&(*oo)|(bar))", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
173 test("((bar)|(fo*)&(*oo))", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
174 test("((((fo*))&((*oo))|((bar))))", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
175 test("((((bar))|((fo*))&((*oo))))", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
176 test(" ( ( ( ( fo* ) ) & ( ( *oo ) ) | ( ( bar ) ) ) ) ", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
177 test(" ( ( ( ( bar ) ) | ( ( fo* ) ) & ( ( *oo ) ) ) ) ", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
178 }
179
180
181
182
183
184 @Test void a10_and_doubleMixed() {
185 test("fo*&&*oo||bar", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
186 test("bar||fo*&&*oo", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
187 test(" fo* && *oo || bar ", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
188 test(" bar || fo* && *oo ", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
189 test("(fo*&&*oo||bar)", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
190 test("(bar||fo*&&*oo)", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
191 test("(fo*)&&(*oo)||(bar)", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
192 test("(bar)||(fo*)&&(*oo)", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
193 test(" ( fo* && *oo || bar ) ", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
194 test(" ( bar || fo* && *oo ) ", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
195 test("((fo*)&&(*oo)||(bar))", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
196 test("((bar)||(fo*)&&(*oo))", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
197 test("((((fo*))&&((*oo))||((bar))))", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
198 test("((((bar))||((fo*))&&((*oo))))", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
199 test(" ( ( ( ( fo* ) ) && ( ( *oo ) ) || ( ( bar ) ) ) ) ", "(| (& [* fo.*] [* .*oo]) [= bar])", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
200 test(" ( ( ( ( bar ) ) || ( ( fo* ) ) && ( ( *oo ) ) ) ) ", "(| [= bar] (& [* fo.*] [* .*oo]))", a("foo", "bar"), a("foox", "xfoo", "fo", "baz", null));
201 }
202
203
204
205
206
207 @Test void a11_and_singleMixedParentheses() {
208 test("fo*&(*oo|bar)", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
209 test("(bar|fo*)&*oo", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
210 test(" fo* & ( *oo | bar ) ", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
211 test(" ( bar | fo* ) & *oo ", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
212 test("(fo*&(*oo|bar))", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
213 test("((bar|fo*)&*oo)", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
214 test("(fo*)&((*oo)|(bar))", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
215 test("((bar)|(fo*))&(*oo)", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
216 test(" ( fo* & ( *oo | bar ) ) ", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
217 test(" ( ( bar | fo* ) & *oo ) ", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
218 test("((fo*)&((*oo)|(bar)))", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
219 test("(((bar)|(fo*))&(*oo))", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
220 test("((((fo*))&(((*oo))|((bar)))))", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
221 test("(((((bar))|((fo*)))&((*oo))))", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
222 test(" ( ( ( ( fo* ) ) & ( ( ( *oo ) ) | ( ( bar ) ) ) ) ) ", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
223 test(" ( ( ( ( ( bar ) ) | ( ( fo* ) ) ) & ( ( *oo ) ) ) ) ", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
224 }
225
226
227
228
229
230 @Test void a12_and_doubleMixedParentheses() {
231 test("fo*&&(*oo||bar)", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
232 test("(bar||fo*)&&*oo", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
233 test(" fo* && ( *oo || bar ) ", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
234 test(" ( bar || fo* ) && *oo ", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
235 test("(fo*&&(*oo||bar))", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
236 test("((bar||fo*)&&*oo)", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
237 test("(fo*)&((*oo)||(bar))", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
238 test("((bar)||(fo*))&&(*oo)", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
239 test(" ( fo* && ( *oo || bar ) ) ", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
240 test(" ( ( bar || fo* ) && *oo ) ", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
241 test("((fo*)&&((*oo)||(bar)))", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
242 test("(((bar)||(fo*))&&(*oo))", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
243 test("((((fo*))&&(((*oo))||((bar)))))", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
244 test("(((((bar))||((fo*)))&&((*oo))))", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
245 test(" ( ( ( ( fo* ) ) && ( ( ( *oo ) ) || ( ( bar ) ) ) ) ) ", "(& [* fo.*] (| [* .*oo] [= bar]))", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
246 test(" ( ( ( ( ( bar ) ) || ( ( fo* ) ) ) && ( ( *oo ) ) ) ) ", "(& (| [= bar] [* fo.*]) [* .*oo])", a("foo"), a("foox", "xfoo", "fo", "bar", "baz", null));
247 }
248
249
250
251
252
253 @Test void b01_errors() {
254 assertThrows(ParseException.class, ()->new StringExpressionMatcher("&foo"));
255 assertThrows(ParseException.class, ()->new StringExpressionMatcher("foo bar"));
256 assertThrows(ParseException.class, ()->new StringExpressionMatcher("(foo"));
257 assertThrows(ParseException.class, ()->new StringExpressionMatcher("foo &"));
258 assertThrows(ParseException.class, ()->new StringExpressionMatcher("foo ||"));
259 assertThrows(ParseException.class, ()->new StringExpressionMatcher("foo ,"));
260 assertThrows(ParseException.class, ()->new StringExpressionMatcher("foo & "));
261 assertThrows(ParseException.class, ()->new StringExpressionMatcher("foo || "));
262 assertThrows(ParseException.class, ()->new StringExpressionMatcher("foo , "));
263 }
264 }