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.model;
017:
018: import java.util.ArrayList;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.Locale;
022:
023: import org.apache.commons.jxpath.AbstractFactory;
024: import org.apache.commons.jxpath.ClassFunctions;
025: import org.apache.commons.jxpath.JXPathContext;
026: import org.apache.commons.jxpath.JXPathTestCase;
027: import org.apache.commons.jxpath.NestedTestBean;
028: import org.apache.commons.jxpath.Pointer;
029: import org.apache.commons.jxpath.ri.QName;
030: import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
031: import org.apache.commons.jxpath.ri.compiler.TestFunctions;
032: import org.apache.commons.jxpath.ri.model.beans.PropertyOwnerPointer;
033: import org.apache.commons.jxpath.ri.model.beans.PropertyPointer;
034:
035: /**
036: * Abstract superclass for Bean access with JXPath.
037: *
038: * @author Dmitri Plotnikov
039: * @version $Revision: 1.19 $ $Date: 2004/02/29 14:17:45 $
040: */
041:
042: public abstract class BeanModelTestCase extends JXPathTestCase {
043: private JXPathContext context;
044:
045: /**
046: * Construct a new instance of this test case.
047: *
048: * @param name Name of the test case
049: */
050: public BeanModelTestCase(String name) {
051: super (name);
052: }
053:
054: public void setUp() {
055: // if (context == null) {
056: context = JXPathContext.newContext(createContextBean());
057: context.setLocale(Locale.US);
058: context.setFactory(getAbstractFactory());
059: // }
060: }
061:
062: protected abstract Object createContextBean();
063:
064: protected abstract AbstractFactory getAbstractFactory();
065:
066: /**
067: * Test property iterators, the core of the graph traversal engine
068: */
069: public void testIndividualIterators() {
070: testIndividual(+1, 0, true, false, 0);
071: testIndividual(-1, 0, true, false, 4);
072:
073: testIndividual(0, -1, true, true, 4);
074: testIndividual(+1, -1, true, true, 4);
075: testIndividual(-1, -1, true, true, 0);
076:
077: testIndividual(0, 1, true, false, 2);
078: testIndividual(0, 1, true, true, 1);
079:
080: testIndividual(0, 0, false, false, 4);
081: testIndividual(0, 0, false, true, 4);
082: }
083:
084: private void testIndividual(int relativePropertyIndex, int offset,
085: boolean useStartLocation, boolean reverse, int expected) {
086: PropertyOwnerPointer root = (PropertyOwnerPointer) NodePointer
087: .newNodePointer(new QName(null, "root"),
088: createContextBean(), Locale.getDefault());
089:
090: NodeIterator it;
091:
092: PropertyPointer start = null;
093:
094: if (useStartLocation) {
095: start = root.getPropertyPointer();
096: start.setPropertyIndex(relativeProperty(start,
097: relativePropertyIndex));
098: start.setIndex(offset);
099: }
100: it = root.childIterator(new NodeNameTest(new QName(null,
101: "integers")), reverse, start);
102:
103: int size = 0;
104: while (it.setPosition(it.getPosition() + 1)) {
105: size++;
106: }
107: assertEquals("ITERATIONS: Individual, relativePropertyIndex="
108: + relativePropertyIndex + ", offset=" + offset
109: + ", useStartLocation=" + useStartLocation
110: + ", reverse=" + reverse, expected, size);
111: }
112:
113: /**
114: * Test property iterators with multiple properties returned
115: */
116: public void testMultipleIterators() {
117: testMultiple(0, 0, true, false, 20);
118:
119: testMultiple(3, 0, true, false, 16);
120: testMultiple(3, -1, true, true, 8);
121: testMultiple(3, 0, true, true, 4);
122: testMultiple(0, 0, false, false, 21);
123: testMultiple(0, 0, false, true, 21);
124:
125: testMultiple(3, 1, true, false, 15);
126: testMultiple(3, 3, true, false, 13);
127: }
128:
129: private void testMultiple(int propertyIndex, int offset,
130: boolean useStartLocation, boolean reverse, int expected) {
131: PropertyOwnerPointer root = (PropertyOwnerPointer) NodePointer
132: .newNodePointer(new QName(null, "root"),
133: createContextBean(), Locale.getDefault());
134: NodeIterator it;
135:
136: PropertyPointer start = null;
137:
138: if (useStartLocation) {
139: start = root.getPropertyPointer();
140: start.setPropertyIndex(propertyIndex);
141: start.setIndex(offset);
142: }
143: it = root.childIterator(null, reverse, start);
144:
145: int size = 0;
146: while (it.setPosition(it.getPosition() + 1)) {
147: // System.err.println("LOC: " + it.getCurrentNodePointer());
148: size++;
149: }
150: assertEquals("ITERATIONS: Multiple, propertyIndex="
151: + propertyIndex + ", offset=" + offset
152: + ", useStartLocation=" + useStartLocation
153: + ", reverse=" + reverse, expected, size);
154: }
155:
156: private int relativeProperty(PropertyPointer holder, int offset) {
157: String[] names = holder.getPropertyNames();
158: for (int i = 0; i < names.length; i++) {
159: if (names[i].equals("integers")) {
160: return i + offset;
161: }
162: }
163: return -1;
164: }
165:
166: public void testIteratePropertyArrayWithHasNext() {
167: JXPathContext context = JXPathContext
168: .newContext(createContextBean());
169: Iterator it = context.iteratePointers("/integers");
170: List actual = new ArrayList();
171: while (it.hasNext()) {
172: actual.add(((Pointer) it.next()).asPath());
173: }
174: assertEquals("Iterating 'hasNext'/'next'<" + "/integers" + ">",
175: list("/integers[1]", "/integers[2]", "/integers[3]",
176: "/integers[4]"), actual);
177: }
178:
179: public void testIteratePropertyArrayWithoutHasNext() {
180: JXPathContext context = JXPathContext
181: .newContext(createContextBean());
182: Iterator it = context.iteratePointers("/integers");
183: List actual = new ArrayList();
184: for (int i = 0; i < 4; i++) {
185: actual.add(it.next().toString());
186: }
187: assertEquals("Iterating 'next'<" + "/integers" + ">", list(
188: "/integers[1]", "/integers[2]", "/integers[3]",
189: "/integers[4]"), actual);
190: }
191:
192: public void testIterateAndSet() {
193: JXPathContext context = JXPathContext
194: .newContext(createContextBean());
195:
196: Iterator it = context.iteratePointers("beans/int");
197: int i = 5;
198: while (it.hasNext()) {
199: NodePointer pointer = (NodePointer) it.next();
200: pointer.setValue(new Integer(i++));
201: }
202:
203: it = context.iteratePointers("beans/int");
204: List actual = new ArrayList();
205: while (it.hasNext()) {
206: actual.add(((Pointer) it.next()).getValue());
207: }
208: assertEquals("Iterating <" + "beans/int" + ">", list(
209: new Integer(5), new Integer(6)), actual);
210: }
211:
212: /**
213: * Test contributed by Kate Dvortsova
214: */
215: public void testIteratePointerSetValue() {
216: JXPathContext context = JXPathContext
217: .newContext(createContextBean());
218:
219: assertXPathValue(context, "/beans[1]/name", "Name 1");
220: assertXPathValue(context, "/beans[2]/name", "Name 2");
221:
222: // Test setting via context
223: context.setValue("/beans[2]/name", "Name 2 set");
224: assertXPathValue(context, "/beans[2]/name", "Name 2 set");
225:
226: // Restore original value
227: context.setValue("/beans[2]/name", "Name 2");
228: assertXPathValue(context, "/beans[2]/name", "Name 2");
229:
230: int iterCount = 0;
231: Iterator iter = context.iteratePointers("/beans/name");
232: while (iter.hasNext()) {
233: iterCount++;
234: Pointer pointer = (Pointer) iter.next();
235: String s = (String) pointer.getValue();
236: s = s + "suffix";
237: pointer.setValue(s);
238: assertEquals("pointer.getValue", s, pointer.getValue());
239: // fails right here, the value isn't getting set in the bean.
240: assertEquals("context.getValue", s, context
241: .getValue(pointer.asPath()));
242: }
243: assertEquals("Iteration count", 2, iterCount);
244:
245: assertXPathValue(context, "/beans[1]/name", "Name 1suffix");
246: assertXPathValue(context, "/beans[2]/name", "Name 2suffix");
247: }
248:
249: public void testRoot() {
250: assertXPathValueAndPointer(context, "/", context
251: .getContextBean(), "/");
252: }
253:
254: public void testAxisAncestor() {
255: // ancestor::
256: assertXPathValue(context, "int/ancestor::root = /",
257: Boolean.TRUE);
258:
259: assertXPathValue(context,
260: "count(beans/name/ancestor-or-self::node())",
261: new Double(5));
262:
263: assertXPathValue(context,
264: "beans/name/ancestor-or-self::node()[3] = /",
265: Boolean.TRUE);
266: }
267:
268: public void testAxisChild() {
269: assertXPathValue(context, "boolean", Boolean.FALSE);
270:
271: assertXPathPointer(context, "boolean", "/boolean");
272:
273: assertXPathPointerIterator(context, "boolean", list("/boolean"));
274:
275: // Count elements in a child collection
276: assertXPathValue(context, "count(set)", new Double(3));
277:
278: // assertXPathValue(context,"boolean/class/name", "java.lang.Boolean");
279:
280: // Child with namespace - should not find any
281: assertXPathValueIterator(context, "foo:boolean", list());
282:
283: // Count all children with a wildcard
284: assertXPathValue(context, "count(*)", new Double(21));
285:
286: // Same, constrained by node type = node()
287: assertXPathValue(context, "count(child::node())",
288: new Double(21));
289: }
290:
291: public void testAxisChildNestedBean() {
292: // Nested bean
293: assertXPathValue(context, "nestedBean/name", "Name 0");
294:
295: assertXPathPointer(context, "nestedBean/name",
296: "/nestedBean/name");
297:
298: assertXPathPointerIterator(context, "nestedBean/name",
299: list("/nestedBean/name"));
300: }
301:
302: public void testAxisChildNestedCollection() {
303: assertXPathValueIterator(context, "integers", list(new Integer(
304: 1), new Integer(2), new Integer(3), new Integer(4)));
305:
306: assertXPathPointer(context, "integers", "/integers");
307:
308: assertXPathPointerIterator(context, "integers", list(
309: "/integers[1]", "/integers[2]", "/integers[3]",
310: "/integers[4]"));
311: }
312:
313: public void testIndexPredicate() {
314: assertXPathValue(context, "integers[2]", new Integer(2));
315:
316: assertXPathPointer(context, "integers[2]", "/integers[2]");
317:
318: assertXPathPointerIterator(context, "integers[2]",
319: list("/integers[2]"));
320:
321: assertXPathValue(context, "beans[1]/name", "Name 1");
322:
323: assertXPathPointer(context, "beans[1]/name", "/beans[1]/name");
324:
325: assertXPathValueIterator(context, "beans[1]/strings", list(
326: "String 1", "String 2", "String 3"));
327:
328: assertXPathValueIterator(context, "beans/strings[2]", list(
329: "String 2", "String 2"));
330:
331: // Find the first match
332: assertXPathValue(context, "beans/strings[2]", "String 2");
333:
334: // Indexing in a set collected from a UnionContext
335: assertXPathValue(context, "(beans/strings[2])[1]", "String 2");
336: }
337:
338: public void testAxisDescendant() {
339: // descendant::
340: assertXPathValue(context, "count(descendant::node())",
341: new Double(65));
342:
343: // Should not find any descendants with name root
344: assertXPathValue(context, "count(descendant::root)",
345: new Double(0));
346:
347: assertXPathValue(context, "count(descendant::name)",
348: new Double(7));
349: }
350:
351: public void testAxisDescendantOrSelf() {
352: // descendant-or-self::
353: assertXPathValueIterator(context, "descendant-or-self::name",
354: set("Name 1", "Name 2", "Name 3", "Name 6", "Name 0",
355: "Name 5", "Name 4"));
356:
357: // Same - abbreviated syntax
358: assertXPathValueIterator(context, "//name", set("Name 1",
359: "Name 2", "Name 3", "Name 6", "Name 0", "Name 5",
360: "Name 4"));
361:
362: // See that it actually finds self
363: assertXPathValue(context, "count(descendant-or-self::root)",
364: new Double(1));
365:
366: // Combine descendant-or-self:: and and self::
367: assertXPathValue(context, "count(nestedBean//.)", new Double(7));
368:
369: // Combine descendant-or-self:: and and self::name
370: assertXPathValue(context, "count(//self::beans)", new Double(2));
371:
372: // Count all nodes in the tree
373: assertXPathValue(context, "count(descendant-or-self::node())",
374: new Double(66));
375:
376: }
377:
378: public void testAxisFollowing() {
379: // following::
380: assertXPathValue(context,
381: "count(nestedBean/strings[2]/following::node())",
382: new Double(21));
383:
384: assertXPathValue(context,
385: "count(nestedBean/strings[2]/following::strings)",
386: new Double(7));
387: }
388:
389: public void testAxisFollowingSibling() {
390: // following-sibling::
391: assertXPathValue(context,
392: "count(/nestedBean/following-sibling::node())",
393: new Double(8));
394:
395: assertXPathValue(context,
396: "count(/nestedBean/following-sibling::object)",
397: new Double(1));
398:
399: // Combine parent:: and following-sibling::
400: assertXPathValue(
401: context,
402: "count(/nestedBean/boolean/../following-sibling::node())",
403: new Double(8));
404:
405: assertXPathValue(
406: context,
407: "count(/nestedBean/boolean/../following-sibling::object)",
408: new Double(1));
409:
410: // Combine descendant:: and following-sibling::
411: assertXPathValue(
412: context,
413: "count(/descendant::boolean/following-sibling::node())",
414: new Double(53));
415:
416: assertXPathValue(context,
417: "count(/descendant::boolean/following-sibling::name)",
418: new Double(7));
419: }
420:
421: public void testAxisParent() {
422: // parent::
423: assertXPathValue(context, "count(/beans/..)", new Double(1));
424:
425: assertXPathValue(context, "count(//..)", new Double(9));
426:
427: assertXPathValue(context, "count(//../..)", new Double(2));
428:
429: assertXPathValueIterator(context, "//parent::beans/name", list(
430: "Name 1", "Name 2"));
431: }
432:
433: public void testAxisPreceding() {
434: // preceding::
435: assertXPathValue(context,
436: "count(beans[2]/int/preceding::node())", new Double(8));
437:
438: assertXPathValue(context,
439: "count(beans[2]/int/preceding::boolean)", new Double(2));
440: }
441:
442: public void testAxisPrecedingSibling() {
443: // preceding-sibling::
444: assertXPathValue(context,
445: "count(/boolean/preceding-sibling::node())",
446: new Double(2));
447:
448: assertXPathValue(context,
449: "count(/nestedBean/int/../preceding-sibling::node())",
450: new Double(12));
451:
452: assertXPathValue(context,
453: "count(/descendant::int/preceding-sibling::node())",
454: new Double(10));
455: }
456:
457: public void testAxisSelf() {
458: // self::
459: assertXPathValue(context, "self::node() = /", Boolean.TRUE);
460:
461: assertXPathValue(context, "self::root = /", Boolean.TRUE);
462: }
463:
464: public void testUnion() {
465: // Union - note corrected document order
466: assertXPathValueIterator(context,
467: "integers | beans[1]/strings", list("String 1",
468: "String 2", "String 3", new Integer(1),
469: new Integer(2), new Integer(3), new Integer(4)));
470:
471: assertXPathValue(
472: context,
473: "count((integers | beans[1]/strings)[contains(., '1')])",
474: new Double(2));
475:
476: assertXPathValue(
477: context,
478: "count((integers | beans[1]/strings)[name(.) = 'strings'])",
479: new Double(3));
480:
481: // Note that the following is different from "integer[2]" -
482: // it is a filter expression
483: assertXPathValue(context, "(integers)[2]", new Integer(2));
484: }
485:
486: public void testAxisAttribute() {
487: // Attributes are just like children to beans
488: assertXPathValue(context, "count(@*)", new Double(21.0));
489:
490: // Unknown attribute
491: assertXPathValueLenient(context, "@foo", null);
492: }
493:
494: /**
495: * Testing the pseudo-attribute "name" that java beans
496: * objects appear to have.
497: */
498: public void testAttributeName() {
499: assertXPathValue(context, "nestedBean[@name = 'int']",
500: new Integer(1));
501:
502: assertXPathPointer(context, "nestedBean[@name = 'int']",
503: "/nestedBean/int");
504: }
505:
506: public void testAttributeLang() {
507:
508: assertXPathValue(context, "@xml:lang", "en-US");
509:
510: assertXPathValue(context, "count(@xml:*)", new Double(1));
511:
512: assertXPathValue(context, "lang('en')", Boolean.TRUE);
513:
514: assertXPathValue(context, "lang('fr')", Boolean.FALSE);
515: }
516:
517: public void testCoreFunctions() {
518:
519: assertXPathValue(context, "boolean(boolean)", Boolean.TRUE);
520:
521: assertXPathValue(context, "boolean(boolean = false())",
522: Boolean.TRUE);
523:
524: assertXPathValue(context, "boolean(integers[position() < 3])",
525: Boolean.TRUE);
526:
527: assertXPathValue(context, "boolean(integers[position() > 4])",
528: Boolean.FALSE);
529:
530: assertXPathValue(context, "sum(integers)", new Double(10));
531:
532: assertXPathValueAndPointer(context, "integers[last()]",
533: new Integer(4), "/integers[4]");
534:
535: assertXPathValueAndPointer(context, "//strings[last()]",
536: "String 3", "/beans[1]/strings[3]");
537: }
538:
539: public void testBooleanPredicate() {
540: // use child axis
541:
542: // bean[1]/int = 1
543: // bean[2]/int = 3
544:
545: assertXPathValue(context, "beans[int > 2]/name", "Name 2");
546:
547: assertXPathValueIterator(context, "beans[int > 2]/name",
548: list("Name 2"));
549:
550: assertXPathValueIterator(context, "beans[int >= 1]/name", list(
551: "Name 1", "Name 2"));
552:
553: assertXPathValueIterator(context, "beans[int < 2]/name",
554: list("Name 1"));
555:
556: assertXPathValueIterator(context, "beans[int <= 3]/name", list(
557: "Name 1", "Name 2"));
558:
559: assertXPathValueIterator(context,
560: "beans[1]/strings[string-length() = 8]", list(
561: "String 1", "String 2", "String 3"));
562:
563: // use some fancy axis and the child axis in the predicate
564: assertXPathValueIterator(context,
565: "//self::node()[name = 'Name 0']/name", list("Name 0"));
566:
567: // use context-dependent function in the predicate
568: assertXPathValue(context,
569: "beans/strings[name(.)='strings'][2]", "String 2");
570:
571: // use context-independent function in the predicate
572: assertXPathValueIterator(context,
573: "//self::node()[name(.) = concat('n', 'a', 'm', 'e')]",
574: list("Name 1", "Name 2", "Name 3", "Name 6", "Name 0",
575: "Name 5", "Name 4"));
576:
577: assertXPathValueIterator(context, "integers[position()<3]",
578: list(new Integer(1), new Integer(2)));
579:
580: context.getVariables().declareVariable("temp",
581: context.getValue("beans"));
582:
583: assertXPathValueIterator(context, "$temp[int < 2]/int",
584: list(new Integer(1)));
585: }
586:
587: public void testDocumentOrder() {
588: assertDocumentOrder(context, "boolean", "int", -1);
589:
590: assertDocumentOrder(context, "integers[1]", "integers[2]", -1);
591:
592: assertDocumentOrder(context, "integers[1]", "integers[1]", 0);
593:
594: assertDocumentOrder(context, "nestedBean/int", "nestedBean", 1);
595:
596: assertDocumentOrder(context, "nestedBean/int",
597: "nestedBean/strings", -1);
598:
599: assertDocumentOrder(context, "nestedBean/int", "object/int", -1);
600: }
601:
602: public void testSetPropertyValue() {
603: // Simple property
604: assertXPathSetValue(context, "int", new Integer(2));
605:
606: // Simple property with conversion from string
607: assertXPathSetValue(context, "int", "3", new Integer(3));
608:
609: // Simple property with conversion from array
610: assertXPathSetValue(context, "int", new int[] { 4 },
611: new Integer(4));
612:
613: // Attribute (which is the same as a child for beans
614: assertXPathSetValue(context, "@int", new Integer(10));
615: }
616:
617: public void testSetCollectionElement() {
618: // Collection element
619: assertXPathSetValue(context, "integers[2]", new Integer(5));
620:
621: // Collection element with conversion
622: assertXPathSetValue(context, "integers[2]", new int[] { 6 },
623: new Integer(6));
624: }
625:
626: public void testSetContextDependentNode() {
627: // Find node without using SimplePathInterpreter
628: assertXPathSetValue(context, "integers[position() = 1]",
629: new Integer(8));
630:
631: // Find node without using SimplePathInterpreter and set its property
632: assertXPathSetValue(context, "beans[name = 'Name 1']/int",
633: new Integer(9));
634:
635: }
636:
637: public void testSetNonPrimitiveValue() {
638: // First, let's see if we can set a collection element to null
639: assertXPathSetValue(context, "beans[2]", null);
640:
641: // Now, assign it a whole bean
642: context.setValue("beans[2]", new NestedTestBean("Name 9"));
643:
644: assertEquals("Modified <" + "beans[2]/name" + ">", "Name 9",
645: context.getValue("beans[2]/name"));
646: }
647:
648: public void testCreatePath() {
649: context.setValue("nestedBean", null);
650:
651: // Calls factory.createObject(..., TestBean, "nestedBean")
652: assertXPathCreatePath(context, "/nestedBean/int",
653: new Integer(1), "/nestedBean/int");
654:
655: boolean ex = false;
656: try {
657: assertXPathCreatePath(context,
658: "/nestedBean/beans[last() + 1]", new Integer(1),
659: "/nestedBean/beans[last() + 1]");
660: } catch (Exception e) {
661: ex = true;
662: }
663: assertTrue("Exception thrown on invalid path for creation", ex);
664:
665: }
666:
667: public void testCreatePathAndSetValue() {
668: context.setValue("nestedBean", null);
669:
670: // Calls factory.createObject(..., TestBean, "nestedBean")
671: assertXPathCreatePathAndSetValue(context, "/nestedBean/int",
672: new Integer(2), "/nestedBean/int");
673: }
674:
675: public void testCreatePathExpandNewCollection() {
676: context.setValue("beans", null);
677:
678: // Calls factory.createObject(..., testBean, "beans", 2),
679: // then factory.createObject(..., testBean, "beans", 2)
680: assertXPathCreatePath(context, "/beans[2]/int", new Integer(1),
681: "/beans[2]/int");
682: }
683:
684: public void testCreatePathAndSetValueExpandNewCollection() {
685: context.setValue("beans", null);
686:
687: // Calls factory.createObject(..., testBean, "beans", 2),
688: // then factory.createObject(..., testBean, "beans", 2)
689: assertXPathCreatePathAndSetValue(context, "/beans[2]/int",
690: new Integer(2), "/beans[2]/int");
691: }
692:
693: public void testCreatePathExpandExistingCollection() {
694: // Calls factory.createObject(..., TestBean, "integers", 5)
695: // to expand collection
696: assertXPathCreatePathAndSetValue(context, "/integers[5]",
697: new Integer(3), "/integers[5]");
698: }
699:
700: public void testCreatePathExpandExistingCollectionAndSetProperty() {
701: // Another, but the collection already exists
702: assertXPathCreatePath(context, "/beans[3]/int", new Integer(1),
703: "/beans[3]/int");
704: }
705:
706: public void testCreatePathAndSetValueExpandExistingCollection() {
707: // Another, but the collection already exists
708: assertXPathCreatePathAndSetValue(context, "/beans[3]/int",
709: new Integer(2), "/beans[3]/int");
710: }
711:
712: public void testCreatePathCreateBeanExpandCollection() {
713: context.setValue("nestedBean", null);
714:
715: // Calls factory.createObject(..., TestBean, "nestedBean")
716: // Calls factory.createObject(..., nestedBean, "strings", 2)
717: assertXPathCreatePath(context, "/nestedBean/strings[2]",
718: "String 2", "/nestedBean/strings[2]");
719: }
720:
721: public void testCreatePathAndSetValueCreateBeanExpandCollection() {
722: context.setValue("nestedBean", null);
723:
724: // Calls factory.createObject(..., TestBean, "nestedBean")
725: // Calls factory.createObject(..., nestedBean, "strings", 2)
726: assertXPathCreatePathAndSetValue(context,
727: "/nestedBean/strings[2]", "Test",
728: "/nestedBean/strings[2]");
729: }
730:
731: public void testRemovePathPropertyValue() {
732: // Remove property value
733: context.removePath("nestedBean/int");
734: assertEquals("Remove property value", new Integer(0), context
735: .getValue("nestedBean/int"));
736: }
737:
738: public void testRemovePathArrayElement() {
739: // Assigns a new array to the property
740: context.removePath("nestedBean/strings[1]");
741: assertEquals("Remove array element", "String 2", context
742: .getValue("nestedBean/strings[1]"));
743: }
744:
745: public void testRemovePathBeanValue() {
746: context.removePath("nestedBean");
747: assertEquals("Remove collection element", null, context
748: .getValue("nestedBean"));
749: }
750:
751: public void testRelativeContextRelativePath() {
752: JXPathContext relative = context.getRelativeContext(context
753: .getPointer("nestedBean"));
754:
755: assertXPathValueAndPointer(relative, "int", new Integer(1),
756: "/nestedBean/int");
757: }
758:
759: public void testRelativeContextAbsolutePath() {
760: JXPathContext relative = context.getRelativeContext(context
761: .getPointer("nestedBean"));
762:
763: assertXPathValueAndPointer(relative, "/integers[2]",
764: new Integer(2), "/integers[2]");
765: }
766:
767: public void testRelativeContextParent() {
768: JXPathContext relative = context.getRelativeContext(context
769: .getPointer("nestedBean"));
770:
771: assertXPathValueAndPointer(relative, "../integers[2]",
772: new Integer(2), "/integers[2]");
773: }
774:
775: public void testRelativeContextInheritance() {
776: context.setFunctions(new ClassFunctions(TestFunctions.class,
777: "test"));
778: JXPathContext relative = context.getRelativeContext(context
779: .getPointer("nestedBean"));
780:
781: assertXPathValue(relative, "test:countPointers(strings)",
782: new Integer(3));
783: }
784: }
|