001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.jxpath.ri;
017:
018: import org.apache.commons.jxpath.JXPathContext;
019: import org.apache.commons.jxpath.JXPathTestCase;
020: import org.apache.commons.jxpath.ri.compiler.Constant;
021: import org.apache.commons.jxpath.ri.compiler.CoreFunction;
022: import org.apache.commons.jxpath.ri.compiler.CoreOperationAdd;
023: import org.apache.commons.jxpath.ri.compiler.CoreOperationAnd;
024: import org.apache.commons.jxpath.ri.compiler.CoreOperationDivide;
025: import org.apache.commons.jxpath.ri.compiler.CoreOperationEqual;
026: import org.apache.commons.jxpath.ri.compiler.CoreOperationGreaterThan;
027: import org.apache.commons.jxpath.ri.compiler.CoreOperationGreaterThanOrEqual;
028: import org.apache.commons.jxpath.ri.compiler.CoreOperationLessThan;
029: import org.apache.commons.jxpath.ri.compiler.CoreOperationLessThanOrEqual;
030: import org.apache.commons.jxpath.ri.compiler.CoreOperationMod;
031: import org.apache.commons.jxpath.ri.compiler.CoreOperationMultiply;
032: import org.apache.commons.jxpath.ri.compiler.CoreOperationNegate;
033: import org.apache.commons.jxpath.ri.compiler.CoreOperationNotEqual;
034: import org.apache.commons.jxpath.ri.compiler.CoreOperationOr;
035: import org.apache.commons.jxpath.ri.compiler.CoreOperationSubtract;
036: import org.apache.commons.jxpath.ri.compiler.CoreOperationUnion;
037: import org.apache.commons.jxpath.ri.compiler.ExpressionPath;
038: import org.apache.commons.jxpath.ri.compiler.ExtensionFunction;
039: import org.apache.commons.jxpath.ri.compiler.LocationPath;
040: import org.apache.commons.jxpath.ri.compiler.NameAttributeTest;
041: import org.apache.commons.jxpath.ri.compiler.VariableReference;
042:
043: /**
044: * Test compiler.
045: *
046: * @author Dmitri Plotnikov
047: * @version $Revision: 1.5 $ $Date: 2004/02/29 14:17:44 $
048: */
049:
050: public class JXPathCompiledExpressionTest extends JXPathTestCase {
051:
052: /**
053: * Construct a new instance of this test case.
054: *
055: * @param name Name of the test case
056: */
057: public JXPathCompiledExpressionTest(String name) {
058: super (name);
059: }
060:
061: public void testConstant() {
062: assertXPathExpression("1", Constant.class);
063: assertXPathExpression("1.5", Constant.class);
064: assertXPathExpression("'foo'", Constant.class);
065: }
066:
067: public void testCoreFunction() {
068: assertXPathExpression("last()", CoreFunction.class);
069: assertXPathExpression("position()", CoreFunction.class);
070: assertXPathExpression("count(book)", CoreFunction.class);
071: assertXPathExpression("id(13)", CoreFunction.class);
072: assertXPathExpression("local-name()", CoreFunction.class);
073: assertXPathExpression("local-name(book)", CoreFunction.class);
074: assertXPathExpression("namespace-uri()", CoreFunction.class);
075: assertXPathExpression("namespace-uri(book)", CoreFunction.class);
076: assertXPathExpression("name()", CoreFunction.class);
077: assertXPathExpression("name(book)", CoreFunction.class);
078: assertXPathExpression("string(3)", CoreFunction.class);
079: assertXPathExpression("concat('a', 'b')", CoreFunction.class);
080: assertXPathExpression("starts-with('a', 'b')",
081: CoreFunction.class);
082: assertXPathExpression("contains('a', 'b')", CoreFunction.class);
083: assertXPathExpression("substring-before('a', 1)",
084: CoreFunction.class);
085: assertXPathExpression("substring-after('a', 2)",
086: CoreFunction.class);
087: assertXPathExpression("substring('a', 2)", CoreFunction.class);
088: assertXPathExpression("substring('a', 2, 3)",
089: CoreFunction.class);
090: assertXPathExpression("string-length('a')", CoreFunction.class);
091: assertXPathExpression("normalize-space('a')",
092: CoreFunction.class);
093: assertXPathExpression("translate('a', 'b', 'c')",
094: CoreFunction.class);
095: assertXPathExpression("boolean('true')", CoreFunction.class);
096: assertXPathExpression("not(1)", CoreFunction.class);
097: assertXPathExpression("true()", CoreFunction.class);
098: assertXPathExpression("false()", CoreFunction.class);
099: assertXPathExpression("lang('fr')", CoreFunction.class);
100: assertXPathExpression("number('12')", CoreFunction.class);
101: assertXPathExpression("sum(book/price)", CoreFunction.class);
102: assertXPathExpression("floor(11.4)", CoreFunction.class);
103: assertXPathExpression("ceiling(11.4)", CoreFunction.class);
104: assertXPathExpression("round(11.4)", CoreFunction.class);
105: assertXPathExpression("key('title', 'Hobbit')",
106: CoreFunction.class);
107: assertXPathExpression("format-number(12, '##')",
108: CoreFunction.class);
109: }
110:
111: public void testCoreOperationAnd() {
112: assertXPathExpression("2 and 4", CoreOperationAnd.class);
113:
114: assertXPathExpression("2 > 1 and 4 < 5", CoreOperationAnd.class);
115: }
116:
117: public void testCoreOperationOr() {
118: assertXPathExpression("2 or 4", CoreOperationOr.class);
119:
120: assertXPathExpression("2 > 1 or 4 < 5", CoreOperationOr.class);
121:
122: assertXPathExpression("1 > 1 and 2 <= 2 or 3 = 4",
123: CoreOperationOr.class);
124: }
125:
126: public void testCoreOperationEqual() {
127: assertXPathExpression("2 = 4", CoreOperationEqual.class);
128:
129: assertXPathExpression("2 + 1 = 3", CoreOperationEqual.class);
130: }
131:
132: public void testCoreOperationNameAttributeTest() {
133: assertXPathExpression("@name = 'bar'", NameAttributeTest.class);
134: }
135:
136: public void testCoreOperationNotEqual() {
137: assertXPathExpression("2 != 4", CoreOperationNotEqual.class);
138:
139: assertXPathExpression("2 + 1 != 3", CoreOperationNotEqual.class);
140: }
141:
142: public void testCoreOperationLessThan() {
143: assertXPathExpression("3<4", CoreOperationLessThan.class,
144: "3 < 4");
145:
146: assertXPathExpression("3<(2>=1)", CoreOperationLessThan.class,
147: "3 < (2 >= 1)");
148: }
149:
150: public void testCoreOperationLessThanOrEqual() {
151: assertXPathExpression("3<=4",
152: CoreOperationLessThanOrEqual.class, "3 <= 4");
153:
154: assertXPathExpression("3<=(2>=1)",
155: CoreOperationLessThanOrEqual.class, "3 <= (2 >= 1)");
156: }
157:
158: public void testCoreOperationGreaterThan() {
159: assertXPathExpression("3>4", CoreOperationGreaterThan.class,
160: "3 > 4");
161:
162: assertXPathExpression("3>(2>=1)",
163: CoreOperationGreaterThan.class, "3 > (2 >= 1)");
164:
165: assertXPathExpression("1 > (1 and 2 <= (2 or 3) = 4)",
166: CoreOperationGreaterThan.class);
167: }
168:
169: public void testCoreOperationGreaterThanOrEqual() {
170: assertXPathExpression("3>=4",
171: CoreOperationGreaterThanOrEqual.class, "3 >= 4");
172:
173: assertXPathExpression("3>=(2>=1)",
174: CoreOperationGreaterThanOrEqual.class, "3 >= (2 >= 1)");
175: }
176:
177: public void testCoreOperationDivide() {
178: assertXPathExpression("2 div 4", CoreOperationDivide.class);
179:
180: assertXPathExpression("2|3 div -3", CoreOperationDivide.class,
181: "2 | 3 div -3");
182: }
183:
184: public void testCoreOperationMod() {
185: assertXPathExpression("2 mod 4", CoreOperationMod.class);
186:
187: assertXPathExpression("2|3 mod -3", CoreOperationMod.class,
188: "2 | 3 mod -3");
189: }
190:
191: public void testCoreOperationMultiply() {
192: assertXPathExpression("2*4", CoreOperationMultiply.class,
193: "2 * 4");
194:
195: assertXPathExpression("2*(3 + 1)", CoreOperationMultiply.class,
196: "2 * (3 + 1)");
197: }
198:
199: public void testCoreOperationMinus() {
200: assertXPathExpression("1 - 1", CoreOperationSubtract.class);
201:
202: assertXPathExpression("1 - 1 - 2", CoreOperationSubtract.class);
203:
204: assertXPathExpression("1 - (1 - 2)",
205: CoreOperationSubtract.class);
206: }
207:
208: public void testCoreOperationSum() {
209: assertXPathExpression("3 + 1 + 4", CoreOperationAdd.class);
210:
211: assertXPathExpression("(3 + 1) + 4", CoreOperationAdd.class,
212: "3 + 1 + 4");
213:
214: assertXPathExpression("3 + (1 + 4)", CoreOperationAdd.class,
215: "3 + 1 + 4");
216:
217: assertXPathExpression("3 + -1", CoreOperationAdd.class,
218: "3 + -1");
219:
220: assertXPathExpression("2*-3 + -1", CoreOperationAdd.class,
221: "2 * -3 + -1");
222: }
223:
224: public void testCoreOperationUnaryMinus() {
225: assertXPathExpression("-3", CoreOperationNegate.class);
226: assertXPathExpression("-(3 + 1)", CoreOperationNegate.class);
227: }
228:
229: public void testCoreOperationUnion() {
230: assertXPathExpression("3 | 1 | 4", CoreOperationUnion.class);
231: }
232:
233: public void testExpressionPath() {
234: assertXPathExpression("$x/foo/bar", ExpressionPath.class);
235: assertXPathExpression("(2 + 2)/foo/bar", ExpressionPath.class);
236: assertXPathExpression("$x[3][2 + 2]/foo/bar",
237: ExpressionPath.class);
238: }
239:
240: public void testExtensionFunction() {
241: assertXPathExpression("my:function(3, other.function())",
242: ExtensionFunction.class);
243: }
244:
245: public void testLocationPathAxisSelf() {
246: assertXPathExpression("self::foo:bar", LocationPath.class);
247:
248: assertXPathExpression(".", LocationPath.class);
249: }
250:
251: public void testLocationPathAxisChild() {
252: assertXPathExpression("child::foo:bar", LocationPath.class,
253: "foo:bar");
254:
255: assertXPathExpression("foo:bar", LocationPath.class);
256:
257: assertXPathExpression("/foo:bar", LocationPath.class);
258:
259: assertXPathExpression("/foo/bar", LocationPath.class);
260:
261: assertXPathExpression("*", LocationPath.class);
262:
263: assertXPathExpression("foo:*", LocationPath.class);
264:
265: }
266:
267: public void testLocationPathAxisParent() {
268: assertXPathExpression("parent::foo:bar", LocationPath.class);
269:
270: assertXPathExpression("..", LocationPath.class);
271: }
272:
273: public void testLocationPathAxisAttribute() {
274: assertXPathExpression("attribute::foo:bar", LocationPath.class,
275: "@foo:bar");
276:
277: assertXPathExpression("@foo:bar", LocationPath.class);
278:
279: assertXPathExpression("../@foo:bar", LocationPath.class);
280:
281: assertXPathExpression("@*", LocationPath.class);
282:
283: assertXPathExpression("@*[last()]", LocationPath.class);
284: }
285:
286: public void testLocationPathAxisDescendant() {
287: assertXPathExpression("descendant::foo:bar", LocationPath.class);
288: }
289:
290: public void testLocationPathAxisDescendantOrSelf() {
291: assertXPathExpression("descendant-or-self::foo:bar",
292: LocationPath.class);
293:
294: assertXPathExpression("//foo", LocationPath.class);
295:
296: assertXPathExpression("foo//bar", LocationPath.class);
297: }
298:
299: public void testLocationPathAxisOther() {
300: assertXPathExpression("ancestor::foo:bar", LocationPath.class);
301:
302: assertXPathExpression("ancestor-or-self::foo:bar",
303: LocationPath.class);
304:
305: assertXPathExpression("namespace::foo:bar", LocationPath.class);
306:
307: assertXPathExpression("preceding::foo:bar", LocationPath.class);
308:
309: assertXPathExpression("preceding-sibling::foo:bar",
310: LocationPath.class);
311:
312: assertXPathExpression("following::foo:bar", LocationPath.class);
313:
314: assertXPathExpression("following-sibling::foo:bar",
315: LocationPath.class);
316: }
317:
318: public void testLocationPathNodeTest() {
319: assertXPathExpression("node()", LocationPath.class);
320:
321: assertXPathExpression("text()", LocationPath.class);
322:
323: assertXPathExpression("comment()", LocationPath.class);
324:
325: assertXPathExpression("processing-instruction()",
326: LocationPath.class);
327:
328: assertXPathExpression("processing-instruction('test')",
329: LocationPath.class);
330: }
331:
332: public void testVariableReference() {
333: assertXPathExpression("$x", VariableReference.class);
334:
335: assertXPathExpression("$x:y", VariableReference.class);
336: }
337:
338: /**
339: * Compiles the xpath into an Expression, checks the expression
340: * class, converts the expression to string and checks that the string
341: * matches the expected one.
342: */
343: private void assertXPathExpression(String xpath,
344: Class expectedClass, String expected) {
345: JXPathCompiledExpression expression = (JXPathCompiledExpression) JXPathContext
346: .compile(xpath);
347:
348: assertEquals("Expression class for " + xpath, expectedClass,
349: expression.getExpression().getClass());
350:
351: assertEquals("Expression toString() for " + xpath, expected,
352: expression.getExpression().toString());
353: }
354:
355: private void assertXPathExpression(String xpath, Class expectedClass) {
356: assertXPathExpression(xpath, expectedClass, xpath);
357: }
358:
359: }
|