~ubuntu-branches/ubuntu/precise/xom/precise

« back to all changes in this revision

Viewing changes to src/nu/xom/tests/ParentNodeTest.java

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2007-11-25 15:50:40 UTC
  • Revision ID: james.westby@ubuntu.com-20071125155040-r75ikcqf1vu0cei7
Tags: upstream-1.1
ImportĀ upstreamĀ versionĀ 1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2002-2004 Elliotte Rusty Harold
 
2
   
 
3
   This library is free software; you can redistribute it and/or modify
 
4
   it under the terms of version 2.1 of the GNU Lesser General Public 
 
5
   License as published by the Free Software Foundation.
 
6
   
 
7
   This library is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 
10
   GNU Lesser General Public License for more details.
 
11
   
 
12
   You should have received a copy of the GNU Lesser General Public
 
13
   License along with this library; if not, write to the 
 
14
   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
 
15
   Boston, MA 02111-1307  USA
 
16
   
 
17
   You can contact Elliotte Rusty Harold by sending e-mail to
 
18
   elharo@metalab.unc.edu. Please include the word "XOM" in the
 
19
   subject line. The XOM home page is located at http://www.xom.nu/
 
20
*/
 
21
 
 
22
package nu.xom.tests;
 
23
 
 
24
import nu.xom.Comment;
 
25
import nu.xom.CycleException;
 
26
import nu.xom.DocType;
 
27
import nu.xom.Document;
 
28
import nu.xom.Element;
 
29
import nu.xom.IllegalAddException;
 
30
import nu.xom.MultipleParentException;
 
31
import nu.xom.NoSuchChildException;
 
32
import nu.xom.Node;
 
33
import nu.xom.ProcessingInstruction;
 
34
import nu.xom.Text;
 
35
 
 
36
 
 
37
/**
 
38
 * <p>
 
39
 *   Tests adding, removing, and counting children from parent nodes.
 
40
 * </p>
 
41
 * 
 
42
 * @author Elliotte Rusty Harold
 
43
 * @version 1.0
 
44
 *
 
45
 */
 
46
public class ParentNodeTest extends XOMTestCase {
 
47
 
 
48
    public ParentNodeTest(String name) {
 
49
        super(name);
 
50
    }
 
51
    
 
52
    
 
53
    private Element empty;
 
54
    private Element notEmpty;
 
55
    private Text child;
 
56
    
 
57
    
 
58
    protected void setUp() {
 
59
        empty = new Element("Empty");
 
60
        notEmpty = new Element("NotEmpty");
 
61
        child = new Text("Hello");
 
62
        notEmpty.appendChild(child);
 
63
    }
 
64
 
 
65
    
 
66
    public void testDetach() {
 
67
        
 
68
        Text text = new Text("This will be attached then detached");
 
69
        empty.appendChild(text);
 
70
        assertEquals(empty, text.getParent());
 
71
        text.detach();
 
72
        assertNull(text.getParent());
 
73
        
 
74
    }
 
75
 
 
76
    
 
77
    public void testAppendChild() {   
 
78
        
 
79
        Element child = new Element("test");
 
80
        empty.appendChild(child);
 
81
        assertEquals(1, empty.getChildCount());
 
82
        assertEquals(empty.getChild(0), child);
 
83
        child.detach();
 
84
        
 
85
        notEmpty.appendChild(child);
 
86
        assertTrue(!notEmpty.getChild(0).equals(child));
 
87
        assertTrue(notEmpty.getChild(1).equals(child));
 
88
        
 
89
    } 
 
90
 
 
91
    
 
92
    public void testAppendChildToItself() { 
 
93
        
 
94
        Element child = new Element("test");
 
95
        try {
 
96
            child.appendChild(child);
 
97
            fail("Appended node to itself");
 
98
        }
 
99
        catch (CycleException success) {
 
100
            assertNotNull(success.getMessage());
 
101
        }
 
102
        
 
103
    } 
 
104
 
 
105
    
 
106
    public void testCycle() {  
 
107
        
 
108
        Element a = new Element("test");
 
109
        Element b = new Element("test");
 
110
        try {
 
111
            a.appendChild(b);
 
112
            b.appendChild(a);
 
113
            fail("Allowed cycle");
 
114
        }
 
115
        catch (CycleException success) {
 
116
            assertNotNull(success.getMessage());
 
117
        }
 
118
        
 
119
    } 
 
120
 
 
121
    public void testInsertChild() {
 
122
        
 
123
        Element parent = new Element("parent");
 
124
        
 
125
        // Test insert into empty element
 
126
        Element child1 = new Element("child");
 
127
        parent.insertChild(child1, 0);
 
128
        assertTrue(parent.getChildCount() > 0);
 
129
        assertEquals(0, parent.indexOf(child1));
 
130
        
 
131
        // Test insert at beginning
 
132
        Element child2 = new Element("child2");
 
133
        parent.insertChild(child2, 0);
 
134
        assertEquals(0, parent.indexOf(child2));
 
135
        assertEquals(1, parent.indexOf(child1));
 
136
        
 
137
        // Test insert in middle
 
138
        Element child3 = new Element("child3");
 
139
        parent.insertChild(child3, 1);
 
140
        assertEquals(0, parent.indexOf(child2));
 
141
        assertEquals(1, parent.indexOf(child3));
 
142
        assertEquals(2, parent.indexOf(child1));
 
143
        
 
144
        // Test insert at beginning with children
 
145
        Element child4 = new Element("child4");
 
146
        parent.insertChild(child4, 0);
 
147
        assertEquals(0, parent.indexOf(child4));
 
148
        assertEquals(1, parent.indexOf(child2));
 
149
        assertEquals(2, parent.indexOf(child3));
 
150
        assertEquals(3, parent.indexOf(child1));
 
151
        
 
152
        // Test insert at end with children
 
153
        Element child5 = new Element("child5");
 
154
        parent.insertChild(child5, 4);
 
155
        assertEquals(0, parent.indexOf(child4));
 
156
        assertEquals(1, parent.indexOf(child2));
 
157
        assertEquals(2, parent.indexOf(child3));
 
158
        assertEquals(3, parent.indexOf(child1));
 
159
        assertEquals(4, parent.indexOf(child5));   
 
160
        
 
161
        try {
 
162
            parent.insertChild((Element) null, 0);
 
163
            fail("Inserted null");
 
164
        }
 
165
        catch (NullPointerException success) {
 
166
            assertNotNull(success.getMessage());
 
167
        }
 
168
 
 
169
        try {
 
170
            parent.insertChild((Text) null, 0);
 
171
            fail("Inserted null");
 
172
        }
 
173
        catch (NullPointerException success) {
 
174
            assertNotNull(success.getMessage());
 
175
        }
 
176
 
 
177
        try {
 
178
            parent.insertChild((Comment) null, 0);
 
179
            fail("Inserted null");
 
180
        }
 
181
        catch (NullPointerException success) {
 
182
            assertNotNull(success.getMessage());
 
183
        }
 
184
 
 
185
        try {
 
186
            parent.insertChild((ProcessingInstruction) null, 0);
 
187
            fail("Inserted null");
 
188
        }
 
189
        catch (NullPointerException success) {
 
190
            assertNotNull(success.getMessage());
 
191
        }
 
192
 
 
193
    } 
 
194
 
 
195
    
 
196
    public void testAppendChild2() {
 
197
        
 
198
        try {
 
199
            empty.appendChild(new Document(notEmpty));
 
200
            fail("appended a document to an element");
 
201
        }
 
202
        catch (IllegalAddException success) {
 
203
            assertNotNull(success.getMessage());
 
204
        }
 
205
        
 
206
        try {
 
207
            empty.appendChild(child);
 
208
            fail("appended a child twice");
 
209
        }
 
210
        catch (MultipleParentException success) {
 
211
            assertNotNull(success.getMessage());
 
212
        }
 
213
 
 
214
    } 
 
215
 
 
216
    
 
217
    public void testReplaceChild() {
 
218
        
 
219
        Element old1 = new Element("old1");
 
220
        Element old2 = new Element("old2");
 
221
        Element old3 = new Element("old3");
 
222
        Element new1 = new Element("new1");
 
223
        Element new2 = new Element("new2");
 
224
        Element new3 = new Element("new3");
 
225
        
 
226
        empty.appendChild(old1);
 
227
        empty.appendChild(old2);
 
228
        empty.appendChild(old3);
 
229
        
 
230
        empty.replaceChild(old1, new1);
 
231
        empty.replaceChild(old3, new3);
 
232
        empty.replaceChild(old2, new2);
 
233
 
 
234
        Node current1 = empty.getChild(0);
 
235
        Node current2 = empty.getChild(1);
 
236
        Node current3 = empty.getChild(2);
 
237
        
 
238
        assertEquals(new1, current1);
 
239
        assertEquals(new2, current2);
 
240
        assertEquals(new3, current3);
 
241
        
 
242
        try {
 
243
            empty.replaceChild(new1, null);
 
244
        }
 
245
        catch (NullPointerException success) {
 
246
            assertNotNull(success.getMessage());
 
247
        }
 
248
        
 
249
        try {
 
250
            empty.replaceChild(null, old1);
 
251
        }
 
252
        catch (NullPointerException success) {
 
253
            assertNotNull(success.getMessage());
 
254
        }
 
255
        
 
256
        Element new4 = new Element("new4");
 
257
        
 
258
        try {
 
259
            empty.replaceChild(new4, new Element("test"));
 
260
            fail("Replaced Nonexistent element");     
 
261
        }
 
262
        catch (NoSuchChildException success) {
 
263
            assertNotNull(success.getMessage());
 
264
        }
 
265
 
 
266
        // Test replacing node with itself
 
267
        empty.replaceChild(new1, new1);
 
268
        assertEquals(new1, empty.getChild(0));        
 
269
        assertEquals(empty, new1.getParent());        
 
270
 
 
271
        // Test replacing node with a sibling
 
272
        try {
 
273
            empty.replaceChild(new1, new2);
 
274
            fail("replaced a node with its sibling");
 
275
        }
 
276
        catch (MultipleParentException success) {
 
277
            assertNotNull(success.getMessage());
 
278
        }
 
279
        
 
280
        
 
281
    } 
 
282
 
 
283
    
 
284
    public void testIndexOf() {
 
285
        
 
286
        Element child1 = new Element("old1");
 
287
        Text child2 = new Text("old2");
 
288
        Comment child3 = new Comment("old3");
 
289
        
 
290
        assertEquals(-1, empty.indexOf(child1));        
 
291
        
 
292
        empty.appendChild(child1);
 
293
        empty.appendChild(child2);
 
294
        empty.appendChild(child3);
 
295
        
 
296
        assertEquals(0, empty.indexOf(child1));
 
297
        assertEquals(1, empty.indexOf(child2));
 
298
        assertEquals(2, empty.indexOf(child3));
 
299
        assertEquals(-1, empty.indexOf(empty));
 
300
        assertEquals(-1, empty.indexOf(new Text("test")));
 
301
 
 
302
    } 
 
303
 
 
304
    
 
305
    public void testGetChild() {
 
306
        
 
307
        Element old1 = new Element("old1");
 
308
        Element old2 = new Element("old2");
 
309
        Element old3 = new Element("old3");
 
310
 
 
311
        try {
 
312
            empty.getChild(0);
 
313
            fail("No index exception");   
 
314
        }
 
315
        catch (IndexOutOfBoundsException success) {
 
316
            // success
 
317
            assertNotNull(success.getMessage());
 
318
        }
 
319
        
 
320
        empty.appendChild(old1);
 
321
        empty.appendChild(old2);
 
322
        empty.appendChild(old3);
 
323
        
 
324
        assertEquals(old1, empty.getChild(0));
 
325
        assertEquals(old3, empty.getChild(2));
 
326
        assertEquals(old2, empty.getChild(1));
 
327
 
 
328
        try {
 
329
            empty.getChild(5);
 
330
            fail("No index exception");   
 
331
        }
 
332
        catch (IndexOutOfBoundsException success) {
 
333
            // success
 
334
            assertNotNull(success.getMessage());
 
335
        }
 
336
 
 
337
    } 
 
338
 
 
339
    
 
340
    public void testRemoveChild() {
 
341
        
 
342
        try {
 
343
            empty.removeChild(0);
 
344
            fail("Removed child from empty element");   
 
345
        }
 
346
        catch (IndexOutOfBoundsException success) {
 
347
            assertNotNull(success.getMessage());
 
348
        }
 
349
 
 
350
        Element old1 = new Element("old1");
 
351
        Element old2 = new Element("old2");
 
352
        Element old3 = new Element("old3");
 
353
 
 
354
        try {
 
355
            empty.removeChild(old1);
 
356
            fail("Removed non-existent child from empty element");   
 
357
        }
 
358
        catch (NoSuchChildException success) {
 
359
            assertNotNull(success.getMessage());
 
360
        }
 
361
 
 
362
        empty.appendChild(old1);
 
363
        empty.appendChild(old2);
 
364
        empty.appendChild(old3);
 
365
        
 
366
        empty.removeChild(1);
 
367
        assertEquals(old1, empty.getChild(0));
 
368
        assertEquals(old3, empty.getChild(1));
 
369
 
 
370
        try {
 
371
            empty.removeChild(5);
 
372
            fail("No IndexOutOfBoundsException");   
 
373
        }
 
374
        catch (IndexOutOfBoundsException success) {
 
375
            assertNotNull(success.getMessage());
 
376
        }
 
377
        
 
378
        empty.removeChild(1);
 
379
        empty.removeChild(0);
 
380
        assertNull(old2.getParent());
 
381
        
 
382
        assertEquals(0, empty.getChildCount());
 
383
 
 
384
        empty.appendChild(old1);
 
385
        empty.appendChild(old2);
 
386
        empty.appendChild(old3);
 
387
        
 
388
        assertEquals(3, empty.getChildCount());
 
389
 
 
390
        empty.removeChild(old3);
 
391
        empty.removeChild(old1);
 
392
        empty.removeChild(old2);
 
393
        
 
394
        assertEquals(0, empty.getChildCount());
 
395
        assertNull(old1.getParent());   
 
396
 
 
397
    } 
 
398
 
 
399
 
 
400
    public void testReplaceChildFailures() {
 
401
        
 
402
        Element old1 = new Element("old1");
 
403
        Element old2 = new Element("old2");
 
404
        Element old3 = new Element("old3");
 
405
        Element new1 = new Element("new1");
 
406
        Element new3 = new Element("new3");
 
407
        
 
408
        empty.appendChild(old1);
 
409
        empty.appendChild(old2);
 
410
        
 
411
        try {
 
412
            empty.replaceChild(old3, new3);
 
413
            fail("Replaced non-existent child");
 
414
        }
 
415
        catch (NoSuchChildException success) {
 
416
            assertNotNull(success.getMessage());
 
417
        }
 
418
 
 
419
        try {
 
420
            empty.replaceChild(old1, null);
 
421
            fail("Replaced child with null");
 
422
        }
 
423
        catch (NullPointerException success) {
 
424
            assertNotNull(success.getMessage());
 
425
        }
 
426
 
 
427
        try {
 
428
            empty.replaceChild(null, new1);
 
429
            fail("Replaced null");
 
430
        }
 
431
        catch (NullPointerException success) {
 
432
            assertNotNull(success.getMessage());
 
433
        }
 
434
 
 
435
    } 
 
436
    
 
437
    
 
438
    public void testReplaceChildInEmptyParent() {
 
439
        
 
440
        Element test1 = new Element("test");
 
441
        Element test2 = new Element("test");
 
442
        try {
 
443
            empty.replaceChild(test1, test2);
 
444
            fail("Replaced element in empty parent");
 
445
        }   
 
446
        catch (NoSuchChildException success) {
 
447
            assertNotNull(success.getMessage());   
 
448
        } 
 
449
        
 
450
    }
 
451
 
 
452
    
 
453
    // Document that this behavior is intentional
 
454
    // An element cannot be replaced by its sibling unless
 
455
    // the sibling is first detached. 
 
456
    public void testReplaceSibling() {
 
457
        
 
458
        Element parent = new Element("parent");
 
459
        Element test1 = new Element("test");
 
460
        Element test2 = new Element("test");
 
461
        parent.appendChild(test1);
 
462
        parent.appendChild(test2);
 
463
        try {
 
464
            parent.replaceChild(test1, test2);
 
465
            fail("Replaced element without detaching first");
 
466
        }   
 
467
        catch (IllegalAddException success) {
 
468
            assertNotNull(success.getMessage());   
 
469
        } 
 
470
        
 
471
        assertEquals(2, parent.getChildCount());
 
472
        assertEquals(parent, test1.getParent());
 
473
        assertEquals(parent, test2.getParent());
 
474
        
 
475
    }
 
476
 
 
477
    
 
478
    // Similarly, this test documents the conscious decision
 
479
    // that you cannot insert an existing child into its own parent,
 
480
    // even at the same position
 
481
    public void testCantInsertExisitngChild() {
 
482
        
 
483
        Element parent = new Element("parent");
 
484
        Element test1 = new Element("test");
 
485
        Element test2 = new Element("test");
 
486
        parent.appendChild(test1);
 
487
        parent.appendChild(test2);
 
488
        try {
 
489
            parent.insertChild(test2, 0);
 
490
            fail("Inserted element without detaching first");
 
491
        }   
 
492
        catch (MultipleParentException success) {
 
493
            assertNotNull(success.getMessage());   
 
494
        } 
 
495
        
 
496
        try {
 
497
            parent.insertChild(test2, 1);
 
498
            fail("Inserted element without detaching first");
 
499
        }   
 
500
        catch (MultipleParentException success) {
 
501
            assertNotNull(success.getMessage());   
 
502
        } 
 
503
        
 
504
        assertEquals(2, parent.getChildCount());
 
505
        assertEquals(parent, test1.getParent());
 
506
        assertEquals(parent, test2.getParent());
 
507
        
 
508
    }
 
509
 
 
510
    
 
511
    // can't remove when insertion is legal;
 
512
    // succeeed or fail as unit
 
513
    public void testReplaceChildAtomicity() {
 
514
        
 
515
        Element parent = new Element("parent");
 
516
        Text child = new Text("child");
 
517
        parent.appendChild(child);
 
518
        
 
519
        try {
 
520
            parent.replaceChild(child, new DocType("root"));
 
521
            fail("allowed doctype child of element");
 
522
        }
 
523
        catch (IllegalAddException success) {
 
524
            assertEquals(parent, child.getParent());
 
525
            assertEquals(1, parent.getChildCount());
 
526
        }
 
527
        
 
528
        Element e = new Element("e");
 
529
        Text child2 = new Text("child2");
 
530
        e.appendChild(child2);
 
531
        try {
 
532
            parent.replaceChild(child, child2);
 
533
            fail("allowed replacement with existing parent");
 
534
        }
 
535
        catch (MultipleParentException success) {
 
536
            assertEquals(e, child2.getParent());
 
537
            assertEquals(parent, child.getParent());
 
538
            assertEquals(1, parent.getChildCount());
 
539
            assertEquals(1, e.getChildCount());
 
540
        }
 
541
        
 
542
    }
 
543
    
 
544
    
 
545
}