1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jxpath.ri;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21
22 import org.apache.commons.jxpath.AbstractJXPathTest;
23 import org.apache.commons.jxpath.JXPathContext;
24 import org.apache.commons.jxpath.ri.compiler.Constant;
25 import org.apache.commons.jxpath.ri.compiler.CoreFunction;
26 import org.apache.commons.jxpath.ri.compiler.CoreOperationAdd;
27 import org.apache.commons.jxpath.ri.compiler.CoreOperationAnd;
28 import org.apache.commons.jxpath.ri.compiler.CoreOperationDivide;
29 import org.apache.commons.jxpath.ri.compiler.CoreOperationEqual;
30 import org.apache.commons.jxpath.ri.compiler.CoreOperationGreaterThan;
31 import org.apache.commons.jxpath.ri.compiler.CoreOperationGreaterThanOrEqual;
32 import org.apache.commons.jxpath.ri.compiler.CoreOperationLessThan;
33 import org.apache.commons.jxpath.ri.compiler.CoreOperationLessThanOrEqual;
34 import org.apache.commons.jxpath.ri.compiler.CoreOperationMod;
35 import org.apache.commons.jxpath.ri.compiler.CoreOperationMultiply;
36 import org.apache.commons.jxpath.ri.compiler.CoreOperationNegate;
37 import org.apache.commons.jxpath.ri.compiler.CoreOperationNotEqual;
38 import org.apache.commons.jxpath.ri.compiler.CoreOperationOr;
39 import org.apache.commons.jxpath.ri.compiler.CoreOperationSubtract;
40 import org.apache.commons.jxpath.ri.compiler.CoreOperationUnion;
41 import org.apache.commons.jxpath.ri.compiler.ExpressionPath;
42 import org.apache.commons.jxpath.ri.compiler.ExtensionFunction;
43 import org.apache.commons.jxpath.ri.compiler.LocationPath;
44 import org.apache.commons.jxpath.ri.compiler.NameAttributeTest;
45 import org.apache.commons.jxpath.ri.compiler.VariableReference;
46 import org.junit.jupiter.api.Test;
47
48
49
50
51 public class JXPathCompiledExpressionTest extends AbstractJXPathTest {
52
53 private void assertXPathExpression(final String xpath, final Class expectedClass) {
54 assertXPathExpression(xpath, expectedClass, xpath);
55 }
56
57
58
59
60
61 private void assertXPathExpression(final String xpath, final Class expectedClass, final String expected) {
62 final JXPathCompiledExpression expression = (JXPathCompiledExpression) JXPathContext.compile(xpath);
63 assertEquals(expectedClass, expression.getExpression().getClass(), "Expression class for " + xpath);
64 assertEquals(expected, expression.getExpression().toString(), "Expression toString() for " + xpath);
65 }
66
67 @Test
68 public void testConstant() {
69 assertXPathExpression("1", Constant.class);
70 assertXPathExpression("1.5", Constant.class);
71 assertXPathExpression("'foo'", Constant.class);
72 }
73
74 @Test
75 public void testCoreFunction() {
76 assertXPathExpression("last()", CoreFunction.class);
77 assertXPathExpression("position()", CoreFunction.class);
78 assertXPathExpression("count(book)", CoreFunction.class);
79 assertXPathExpression("id(13)", CoreFunction.class);
80 assertXPathExpression("local-name()", CoreFunction.class);
81 assertXPathExpression("local-name(book)", CoreFunction.class);
82 assertXPathExpression("namespace-uri()", CoreFunction.class);
83 assertXPathExpression("namespace-uri(book)", CoreFunction.class);
84 assertXPathExpression("name()", CoreFunction.class);
85 assertXPathExpression("name(book)", CoreFunction.class);
86 assertXPathExpression("string(3)", CoreFunction.class);
87 assertXPathExpression("concat('a', 'b')", CoreFunction.class);
88 assertXPathExpression("starts-with('a', 'b')", CoreFunction.class);
89 assertXPathExpression("ends-with('a', 'b')", CoreFunction.class);
90 assertXPathExpression("contains('a', 'b')", CoreFunction.class);
91 assertXPathExpression("substring-before('a', 1)", CoreFunction.class);
92 assertXPathExpression("substring-after('a', 2)", CoreFunction.class);
93 assertXPathExpression("substring('a', 2)", CoreFunction.class);
94 assertXPathExpression("substring('a', 2, 3)", CoreFunction.class);
95 assertXPathExpression("string-length('a')", CoreFunction.class);
96 assertXPathExpression("normalize-space('a')", CoreFunction.class);
97 assertXPathExpression("translate('a', 'b', 'c')", CoreFunction.class);
98 assertXPathExpression("boolean('true')", CoreFunction.class);
99 assertXPathExpression("not(1)", CoreFunction.class);
100 assertXPathExpression("true()", CoreFunction.class);
101 assertXPathExpression("false()", CoreFunction.class);
102 assertXPathExpression("lang('fr')", CoreFunction.class);
103 assertXPathExpression("number('12')", CoreFunction.class);
104 assertXPathExpression("sum(book/price)", CoreFunction.class);
105 assertXPathExpression("floor(11.4)", CoreFunction.class);
106 assertXPathExpression("ceiling(11.4)", CoreFunction.class);
107 assertXPathExpression("round(11.4)", CoreFunction.class);
108 assertXPathExpression("key('title', 'Hobbit')", CoreFunction.class);
109 assertXPathExpression("format-number(12, '##')", CoreFunction.class);
110 }
111
112 @Test
113 public void testCoreOperationAnd() {
114 assertXPathExpression("2 and 4", CoreOperationAnd.class);
115 assertXPathExpression("2 > 1 and 4 < 5", CoreOperationAnd.class);
116 }
117
118 @Test
119 public void testCoreOperationDivide() {
120 assertXPathExpression("2 div 4", CoreOperationDivide.class);
121 assertXPathExpression("2|3 div -3", CoreOperationDivide.class, "2 | 3 div -3");
122 }
123
124 @Test
125 public void testCoreOperationEqual() {
126 assertXPathExpression("2 = 4", CoreOperationEqual.class);
127 assertXPathExpression("2 + 1 = 3", CoreOperationEqual.class);
128 }
129
130 @Test
131 public void testCoreOperationGreaterThan() {
132 assertXPathExpression("3>4", CoreOperationGreaterThan.class, "3 > 4");
133 assertXPathExpression("3>(2>=1)", CoreOperationGreaterThan.class, "3 > (2 >= 1)");
134 assertXPathExpression("1 > (1 and 2 <= (2 or 3) = 4)", CoreOperationGreaterThan.class);
135 }
136
137 @Test
138 public void testCoreOperationGreaterThanOrEqual() {
139 assertXPathExpression("3>=4", CoreOperationGreaterThanOrEqual.class, "3 >= 4");
140 assertXPathExpression("3>=(2>=1)", CoreOperationGreaterThanOrEqual.class, "3 >= (2 >= 1)");
141 }
142
143 @Test
144 public void testCoreOperationLessThan() {
145 assertXPathExpression("3<4", CoreOperationLessThan.class, "3 < 4");
146 assertXPathExpression("3<(2>=1)", CoreOperationLessThan.class, "3 < (2 >= 1)");
147 }
148
149 @Test
150 public void testCoreOperationLessThanOrEqual() {
151 assertXPathExpression("3<=4", CoreOperationLessThanOrEqual.class, "3 <= 4");
152 assertXPathExpression("3<=(2>=1)", CoreOperationLessThanOrEqual.class, "3 <= (2 >= 1)");
153 }
154
155 @Test
156 public void testCoreOperationMinus() {
157 assertXPathExpression("1 - 1", CoreOperationSubtract.class);
158 assertXPathExpression("1 - 1 - 2", CoreOperationSubtract.class);
159 assertXPathExpression("1 - (1 - 2)", CoreOperationSubtract.class);
160 }
161
162 @Test
163 public void testCoreOperationMod() {
164 assertXPathExpression("2 mod 4", CoreOperationMod.class);
165 assertXPathExpression("2|3 mod -3", CoreOperationMod.class, "2 | 3 mod -3");
166 }
167
168 @Test
169 public void testCoreOperationMultiply() {
170 assertXPathExpression("2*4", CoreOperationMultiply.class, "2 * 4");
171 assertXPathExpression("2*(3 + 1)", CoreOperationMultiply.class, "2 * (3 + 1)");
172 }
173
174 @Test
175 public void testCoreOperationNameAttributeTest() {
176 assertXPathExpression("@name = 'bar'", NameAttributeTest.class);
177 }
178
179 @Test
180 public void testCoreOperationNotEqual() {
181 assertXPathExpression("2 != 4", CoreOperationNotEqual.class);
182 assertXPathExpression("2 + 1 != 3", CoreOperationNotEqual.class);
183 }
184
185 @Test
186 public void testCoreOperationOr() {
187 assertXPathExpression("2 or 4", CoreOperationOr.class);
188 assertXPathExpression("2 > 1 or 4 < 5", CoreOperationOr.class);
189 assertXPathExpression("1 > 1 and 2 <= 2 or 3 = 4", CoreOperationOr.class);
190 }
191
192 @Test
193 public void testCoreOperationSum() {
194 assertXPathExpression("3 + 1 + 4", CoreOperationAdd.class);
195 assertXPathExpression("(3 + 1) + 4", CoreOperationAdd.class, "3 + 1 + 4");
196 assertXPathExpression("3 + (1 + 4)", CoreOperationAdd.class, "3 + 1 + 4");
197 assertXPathExpression("3 + -1", CoreOperationAdd.class, "3 + -1");
198 assertXPathExpression("2*-3 + -1", CoreOperationAdd.class, "2 * -3 + -1");
199 }
200
201 @Test
202 public void testCoreOperationUnaryMinus() {
203 assertXPathExpression("-3", CoreOperationNegate.class);
204 assertXPathExpression("-(3 + 1)", CoreOperationNegate.class);
205 }
206
207 @Test
208 public void testCoreOperationUnion() {
209 assertXPathExpression("3 | 1 | 4", CoreOperationUnion.class);
210 }
211
212 @Test
213 public void testExpressionPath() {
214 assertXPathExpression("$x/foo/bar", ExpressionPath.class);
215 assertXPathExpression("(2 + 2)/foo/bar", ExpressionPath.class);
216 assertXPathExpression("$x[3][2 + 2]/foo/bar", ExpressionPath.class);
217 }
218
219 @Test
220 public void testExtensionFunction() {
221 assertXPathExpression("my:function(3, other.function())", ExtensionFunction.class);
222 }
223
224 @Test
225 public void testLocationPathAxisAttribute() {
226 assertXPathExpression("attribute::foo:bar", LocationPath.class, "@foo:bar");
227 assertXPathExpression("@foo:bar", LocationPath.class);
228 assertXPathExpression("../@foo:bar", LocationPath.class);
229 assertXPathExpression("@*", LocationPath.class);
230 assertXPathExpression("@*[last()]", LocationPath.class);
231 }
232
233 @Test
234 public void testLocationPathAxisChild() {
235 assertXPathExpression("child::foo:bar", LocationPath.class, "foo:bar");
236 assertXPathExpression("foo:bar", LocationPath.class);
237 assertXPathExpression("/foo:bar", LocationPath.class);
238 assertXPathExpression("/foo/bar", LocationPath.class);
239 assertXPathExpression("*", LocationPath.class);
240 assertXPathExpression("foo:*", LocationPath.class);
241 }
242
243 @Test
244 public void testLocationPathAxisDescendant() {
245 assertXPathExpression("descendant::foo:bar", LocationPath.class);
246 }
247
248 @Test
249 public void testLocationPathAxisDescendantOrSelf() {
250 assertXPathExpression("descendant-or-self::foo:bar", LocationPath.class);
251 assertXPathExpression("//foo", LocationPath.class);
252 assertXPathExpression("foo//bar", LocationPath.class);
253 }
254
255 @Test
256 public void testLocationPathAxisOther() {
257 assertXPathExpression("ancestor::foo:bar", LocationPath.class);
258 assertXPathExpression("ancestor-or-self::foo:bar", LocationPath.class);
259 assertXPathExpression("namespace::foo:bar", LocationPath.class);
260 assertXPathExpression("preceding::foo:bar", LocationPath.class);
261 assertXPathExpression("preceding-sibling::foo:bar", LocationPath.class);
262 assertXPathExpression("following::foo:bar", LocationPath.class);
263 assertXPathExpression("following-sibling::foo:bar", LocationPath.class);
264 }
265
266 @Test
267 public void testLocationPathAxisParent() {
268 assertXPathExpression("parent::foo:bar", LocationPath.class);
269 assertXPathExpression("..", LocationPath.class);
270 }
271
272 @Test
273 public void testLocationPathAxisSelf() {
274 assertXPathExpression("self::foo:bar", LocationPath.class);
275 assertXPathExpression(".", LocationPath.class);
276 }
277
278 @Test
279 public void testLocationPathNodeTest() {
280 assertXPathExpression("node()", LocationPath.class);
281 assertXPathExpression("text()", LocationPath.class);
282 assertXPathExpression("comment()", LocationPath.class);
283 assertXPathExpression("processing-instruction()", LocationPath.class);
284 assertXPathExpression("processing-instruction('test')", LocationPath.class);
285 }
286
287 @Test
288 public void testVariableReference() {
289 assertXPathExpression("$x", VariableReference.class);
290 assertXPathExpression("$x:y", VariableReference.class);
291 }
292 }