1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration.tree;
18
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.StringTokenizer;
22
23 import junit.framework.TestCase;
24
25 /***
26 * Test class for DefaultConfigurationNode.
27 *
28 * @author Oliver Heger
29 */
30 public class TestDefaultConfigurationNode extends TestCase
31 {
32 /*** Constant array for the field names. */
33 private static final String[] FIELD_NAMES =
34 { "UID", "NAME", "FIRSTNAME", "LASTLOGIN"};
35
36 /*** Constant array for the field data types. */
37 private static final String[] FIELD_TYPES =
38 { "long", "string", "string", "date"};
39
40 /*** Constant array for additional field attributes. */
41 private static final String[] FIELD_ATTRS =
42 { "primarykey,unique", "notnull", "notnull", null};
43
44 /*** The node to be tested. */
45 DefaultConfigurationNode node;
46
47 protected void setUp() throws Exception
48 {
49 super.setUp();
50 node = new DefaultConfigurationNode();
51 node.setName("table");
52 node.setReference("TestReference");
53 node.addAttribute(new DefaultConfigurationNode("type", "system"));
54 node.addChild(new DefaultConfigurationNode("name", "users"));
55
56
57 for (int i = 0; i < FIELD_NAMES.length; i++)
58 {
59 DefaultConfigurationNode field = new DefaultConfigurationNode(
60 "field");
61 field
62 .addChild(new DefaultConfigurationNode("name",
63 FIELD_NAMES[i]));
64 field.addAttribute(new DefaultConfigurationNode("type",
65 FIELD_TYPES[i]));
66 if (FIELD_ATTRS[i] != null)
67 {
68 StringTokenizer tok = new StringTokenizer(FIELD_ATTRS[i], ", ");
69 while (tok.hasMoreTokens())
70 {
71 field.addAttribute(new DefaultConfigurationNode(
72 "attribute", tok.nextToken()));
73 }
74 }
75 node.addChild(field);
76 }
77 }
78
79 /***
80 * Tests a newly created, uninitialized node.
81 */
82 public void testNewNode()
83 {
84 node = new DefaultConfigurationNode();
85 assertNull("name is not null", node.getName());
86 assertNull("value is not null", node.getValue());
87 assertNull("reference is not null", node.getReference());
88 assertTrue("Children are not empty", node.getChildren().isEmpty());
89 assertTrue("Named children are not empty", node.getChildren("test")
90 .isEmpty());
91 assertEquals("Children cound is not 0", 0, node.getChildrenCount());
92 assertEquals("Named children count is not 0", 0, node
93 .getChildrenCount("test"));
94 assertTrue("Attributes are not empty", node.getAttributes().isEmpty());
95 assertTrue("Named attributes are not empty", node.getAttributes("test")
96 .isEmpty());
97 assertNull("Node has a parent", node.getParentNode());
98 assertFalse("Node is defined", node.isDefined());
99 try
100 {
101 node.getAttribute(0);
102 fail("Could access non existing attribute!");
103 }
104 catch (IndexOutOfBoundsException iex)
105 {
106
107 }
108 }
109
110 /***
111 * Tests accessing a node's reference.
112 */
113 public void testGetReference()
114 {
115 assertEquals("Reference was not stored", "TestReference", node
116 .getReference());
117 }
118
119 /***
120 * Tests accessing the node's children.
121 */
122 public void testGetChildren()
123 {
124 assertEquals("Number of children incorrect", FIELD_NAMES.length + 1,
125 node.getChildrenCount());
126 List children = node.getChildren();
127 Iterator it = children.iterator();
128 DefaultConfigurationNode child = (DefaultConfigurationNode) it.next();
129 assertEquals("Wrong node", "name", child.getName());
130 checkFieldNodes(it);
131 }
132
133 /***
134 * Tests accessing the node's children by name.
135 */
136 public void testGetChildrenByName()
137 {
138 List children = node.getChildren("field");
139 assertEquals("Incorrect number of child nodes", FIELD_NAMES.length,
140 children.size());
141 assertEquals("Incorrect result of getChildrenCount()",
142 FIELD_NAMES.length, node.getChildrenCount("field"));
143 checkFieldNodes(children.iterator());
144 assertTrue("Found non existing nodes", node.getChildren("test")
145 .isEmpty());
146 assertEquals("Wrong children list for null", node.getChildren(), node
147 .getChildren(null));
148 }
149
150 /***
151 * Tests adding a new child node.
152 */
153 public void testAddChild()
154 {
155 int cnt = node.getChildrenCount();
156 DefaultConfigurationNode ndNew = new DefaultConfigurationNode("test",
157 "xyz");
158 node.addChild(ndNew);
159 assertEquals("New node was not added", cnt + 1, node.getChildrenCount());
160 List children = node.getChildren();
161 assertEquals("Incorrect number of children", node.getChildrenCount(),
162 children.size());
163 assertSame("Node was not added to end", ndNew, children.get(cnt));
164 assertEquals("Incorrect number of named children", 1, node
165 .getChildrenCount(ndNew.getName()));
166 assertFalse("Child is an attribute", ndNew.isAttribute());
167 assertSame("Parent was not set", node, ndNew.getParentNode());
168 }
169
170 /***
171 * Tests adding invalid child nodes.
172 */
173 public void testAddUndefinedChild()
174 {
175 try
176 {
177 node.addChild(null);
178 fail("null node could be added!");
179 }
180 catch (IllegalArgumentException iex)
181 {
182
183 }
184
185 try
186 {
187 node.addChild(new DefaultConfigurationNode());
188 fail("Node without name could be added!");
189 }
190 catch (IllegalArgumentException iex)
191 {
192
193 }
194 }
195
196 /***
197 * Tests removing a child node.
198 */
199 public void testRemoveChild()
200 {
201 DefaultConfigurationNode child = (DefaultConfigurationNode) node
202 .getChildren().get(3);
203 int cnt = node.getChildrenCount();
204 node.removeChild(child);
205 assertEquals("Child was not removed", cnt - 1, node.getChildrenCount());
206 for (Iterator it = node.getChildren().iterator(); it.hasNext();)
207 {
208 assertNotSame("Found removed node", child, it.next());
209 }
210 assertNull("Parent reference was not removed", child.getParentNode());
211 }
212
213 /***
214 * Tests removing a child node that does not belong to this node.
215 */
216 public void testRemoveNonExistingChild()
217 {
218 int cnt = node.getChildrenCount();
219 node.removeChild(new DefaultConfigurationNode("test"));
220 node.removeChild(new DefaultConfigurationNode());
221 node.removeChild((ConfigurationNode) null);
222 node.removeChild("non existing child node");
223 node.removeChild((String) null);
224 assertEquals("Children were changed", cnt, node.getChildrenCount());
225 }
226
227 /***
228 * Tests removing children by their name.
229 */
230 public void testRemoveChildByName()
231 {
232 int cnt = node.getChildrenCount();
233 node.removeChild("name");
234 assertEquals("Child was not removed", cnt - 1, node.getChildrenCount());
235 assertEquals("Still found name child", 0, node.getChildrenCount("name"));
236 node.removeChild("field");
237 assertEquals("Still remaining nodes", 0, node.getChildrenCount());
238 }
239
240 /***
241 * Tests removing all children at once.
242 */
243 public void testRemoveChildren()
244 {
245 node.removeChildren();
246 assertEquals("Children count is not 0", 0, node.getChildrenCount());
247 assertTrue("Children are not empty", node.getChildren().isEmpty());
248 }
249
250 /***
251 * Tests accessing a child by its index.
252 */
253 public void testGetChild()
254 {
255 ConfigurationNode child = node.getChild(2);
256 assertEquals("Wrong child returned", child, node.getChildren().get(2));
257 }
258
259 /***
260 * Tests accessing child nodes with invalid indices.
261 */
262 public void testGetChildInvalidIndex()
263 {
264 try
265 {
266 node.getChild(4724);
267 fail("Could access invalid index!");
268 }
269 catch (IndexOutOfBoundsException iex)
270 {
271
272 }
273 }
274
275 /***
276 * Tests accessing the node's attributes.
277 */
278 public void testGetAttributes()
279 {
280 assertEquals("Number of attributes incorrect", 1, node
281 .getAttributeCount());
282 List attributes = node.getAttributes();
283 Iterator it = attributes.iterator();
284 DefaultConfigurationNode attr = (DefaultConfigurationNode) it.next();
285 assertEquals("Wrong node", "type", attr.getName());
286 assertFalse("More attributes", it.hasNext());
287 }
288
289 /***
290 * Tests accessing the node's attributes by name.
291 */
292 public void testGetAttributesByName()
293 {
294 assertEquals("Incorrect number of attributes", 1, node
295 .getAttributeCount("type"));
296 DefaultConfigurationNode field = (DefaultConfigurationNode) node
297 .getChildren().get(1);
298 assertEquals("Incorrect number of attributes", 2, field
299 .getAttributeCount("attribute"));
300 List attrs = field.getAttributes("attribute");
301 assertEquals("Wrong value", "primarykey",
302 ((DefaultConfigurationNode) attrs.get(0)).getValue());
303 assertEquals("Wrong value", "unique", ((DefaultConfigurationNode) attrs
304 .get(1)).getValue());
305 }
306
307 /***
308 * Tests adding a new attribute node.
309 */
310 public void testAddAttribute()
311 {
312 int cnt = node.getAttributeCount();
313 DefaultConfigurationNode ndNew = new DefaultConfigurationNode("test",
314 "xyz");
315 node.addAttribute(ndNew);
316 assertEquals("New node was not added", cnt + 1, node
317 .getAttributeCount());
318 List attrs = node.getAttributes();
319 assertEquals("Incorrect number of attributes",
320 node.getAttributeCount(), attrs.size());
321 assertSame("Node was not added to end", ndNew, attrs.get(cnt));
322 assertEquals("Incorrect number of named attributes", 1, node
323 .getAttributeCount(ndNew.getName()));
324 assertTrue("Child is no attribute", ndNew.isAttribute());
325 assertSame("Parent was not set", node, ndNew.getParentNode());
326 }
327
328 /***
329 * Tests removing an attribute node.
330 */
331 public void testRemoveAttribute()
332 {
333 DefaultConfigurationNode attr = (DefaultConfigurationNode) node
334 .getAttributes().get(0);
335 int cnt = node.getAttributeCount();
336 node.removeAttribute(attr);
337 assertEquals("Attribute was not removed", cnt - 1, node
338 .getAttributeCount());
339 for (Iterator it = node.getAttributes().iterator(); it.hasNext();)
340 {
341 assertNotSame("Found removed node", attr, it.next());
342 }
343 assertNull("Parent reference was not removed", attr.getParentNode());
344 }
345
346 /***
347 * Tests removing attributes by their names.
348 */
349 public void testRemoveAttributeByName()
350 {
351 ConfigurationNode field = node.getChild(1);
352 assertEquals("Incorrect number of attributes", 3, field
353 .getAttributeCount());
354 field.removeAttribute("attribute");
355 assertEquals("Not all nodes removed", 1, field.getAttributeCount());
356 assertTrue("Remaining attributes", field.getAttributes("attribute")
357 .isEmpty());
358 field.removeAttribute("type");
359 assertEquals("Remaining attributes", 0, field.getAttributeCount());
360 }
361
362 /***
363 * Tests removing all attributes.
364 */
365 public void testRemoveAttributes()
366 {
367 node.removeAttributes();
368 assertEquals("Not all attributes removed", 0, node.getAttributeCount());
369 assertTrue("Attributes not empty", node.getAttributes().isEmpty());
370 }
371
372 /***
373 * Tests changing a node's attribute state.
374 */
375 public void testChangeAttributeState()
376 {
377 ConfigurationNode attr = node.getAttribute(0);
378 try
379 {
380 attr.setAttribute(false);
381 fail("Could change node's attribute state!");
382 }
383 catch (IllegalStateException iex)
384 {
385
386 }
387 }
388
389 /***
390 * Tests the visit() method using a simple visitor.
391 */
392 public void testVisit()
393 {
394 CountNodeVisitor visitor = new CountNodeVisitor();
395 node.visit(visitor);
396 assertEquals("Not all nodes visited", 19, visitor.beforeCalls);
397 assertEquals("Different number of before and after calls",
398 visitor.beforeCalls, visitor.afterCalls);
399 }
400
401 /***
402 * Tests the visit() method with a visitor that terminates the visit
403 * process.
404 */
405 public void testVisitWithTerminate()
406 {
407 CountNodeVisitor visitor = new CountNodeVisitor(10);
408 node.visit(visitor);
409 assertEquals("Incorrect number of nodes visited", visitor.maxCalls,
410 visitor.beforeCalls);
411 assertEquals("Different number of before and after calls",
412 visitor.beforeCalls, visitor.afterCalls);
413 }
414
415 /***
416 * Tests the visit() method when null is passed in. This should throw an
417 * exception.
418 */
419 public void testVisitWithNullVisitor()
420 {
421 try
422 {
423 node.visit(null);
424 fail("Could pass in null visitor!");
425 }
426 catch (IllegalArgumentException iex)
427 {
428
429 }
430 }
431
432 /***
433 * Tests cloning a node.
434 */
435 public void testClone()
436 {
437 node.setValue("TestValue");
438 DefaultConfigurationNode clone = (DefaultConfigurationNode) node.clone();
439 assertEquals("Value not cloned", "TestValue", clone.getValue());
440 assertEquals("Name not cloned", "table", clone.getName());
441 assertEquals("Reference not cloned", "TestReference", clone.getReference());
442 assertEquals("Children were cloned", 0, clone.getChildrenCount());
443 assertEquals("Attributes were cloned", 0, clone.getAttributeCount());
444 }
445
446 /***
447 * Helper method for checking the child nodes of type "field".
448 *
449 * @param itFields the iterator with the child nodes
450 */
451 private void checkFieldNodes(Iterator itFields)
452 {
453 for (int i = 0; i < FIELD_NAMES.length; i++)
454 {
455 DefaultConfigurationNode child = (DefaultConfigurationNode) itFields
456 .next();
457 assertEquals("Wrong node", "field", child.getName());
458 List nameNodes = child.getChildren("name");
459 assertEquals("Wrong number of name nodes", 1, nameNodes.size());
460 DefaultConfigurationNode nameNode = (DefaultConfigurationNode) nameNodes
461 .get(0);
462 assertEquals("Wrong field name", FIELD_NAMES[i], nameNode
463 .getValue());
464 }
465 }
466
467 /***
468 * A test visitor implementation that is able to count the number of visits.
469 * It also supports a maximum number of visits to be set; if this number is
470 * reached, the <code>terminate()</code> method returns <b>true</b>.
471 */
472 static class CountNodeVisitor implements ConfigurationNodeVisitor
473 {
474 public int beforeCalls;
475
476 public int afterCalls;
477
478 public int maxCalls;
479
480 public CountNodeVisitor()
481 {
482 this(Integer.MAX_VALUE);
483 }
484
485 public CountNodeVisitor(int maxNumberOfVisits)
486 {
487 maxCalls = maxNumberOfVisits;
488 }
489
490 public void visitBeforeChildren(ConfigurationNode node)
491 {
492 beforeCalls++;
493 }
494
495 public void visitAfterChildren(ConfigurationNode node)
496 {
497 afterCalls++;
498 }
499
500 public boolean terminate()
501 {
502 return beforeCalls >= maxCalls;
503 }
504 }
505 }