Clover coverage report - Clover results for XOM 1.2d1
Coverage timestamp: Wed Feb 8 2006 08:31:33 EST
file stats: LOC: 545   Methods: 17
NCLOC: 380   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ParentNodeTest.java - 90.4% 100% 91%
coverage coverage
 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  15 public ParentNodeTest(String name) {
 49  15 super(name);
 50    }
 51   
 52   
 53    private Element empty;
 54    private Element notEmpty;
 55    private Text child;
 56   
 57   
 58  15 protected void setUp() {
 59  15 empty = new Element("Empty");
 60  15 notEmpty = new Element("NotEmpty");
 61  15 child = new Text("Hello");
 62  15 notEmpty.appendChild(child);
 63    }
 64   
 65   
 66  1 public void testDetach() {
 67   
 68  1 Text text = new Text("This will be attached then detached");
 69  1 empty.appendChild(text);
 70  1 assertEquals(empty, text.getParent());
 71  1 text.detach();
 72  1 assertNull(text.getParent());
 73   
 74    }
 75   
 76   
 77  1 public void testAppendChild() {
 78   
 79  1 Element child = new Element("test");
 80  1 empty.appendChild(child);
 81  1 assertEquals(1, empty.getChildCount());
 82  1 assertEquals(empty.getChild(0), child);
 83  1 child.detach();
 84   
 85  1 notEmpty.appendChild(child);
 86  1 assertTrue(!notEmpty.getChild(0).equals(child));
 87  1 assertTrue(notEmpty.getChild(1).equals(child));
 88   
 89    }
 90   
 91   
 92  1 public void testAppendChildToItself() {
 93   
 94  1 Element child = new Element("test");
 95  1 try {
 96  1 child.appendChild(child);
 97  0 fail("Appended node to itself");
 98    }
 99    catch (CycleException success) {
 100  1 assertNotNull(success.getMessage());
 101    }
 102   
 103    }
 104   
 105   
 106  1 public void testCycle() {
 107   
 108  1 Element a = new Element("test");
 109  1 Element b = new Element("test");
 110  1 try {
 111  1 a.appendChild(b);
 112  1 b.appendChild(a);
 113  0 fail("Allowed cycle");
 114    }
 115    catch (CycleException success) {
 116  1 assertNotNull(success.getMessage());
 117    }
 118   
 119    }
 120   
 121  1 public void testInsertChild() {
 122   
 123  1 Element parent = new Element("parent");
 124   
 125    // Test insert into empty element
 126  1 Element child1 = new Element("child");
 127  1 parent.insertChild(child1, 0);
 128  1 assertTrue(parent.getChildCount() > 0);
 129  1 assertEquals(0, parent.indexOf(child1));
 130   
 131    // Test insert at beginning
 132  1 Element child2 = new Element("child2");
 133  1 parent.insertChild(child2, 0);
 134  1 assertEquals(0, parent.indexOf(child2));
 135  1 assertEquals(1, parent.indexOf(child1));
 136   
 137    // Test insert in middle
 138  1 Element child3 = new Element("child3");
 139  1 parent.insertChild(child3, 1);
 140  1 assertEquals(0, parent.indexOf(child2));
 141  1 assertEquals(1, parent.indexOf(child3));
 142  1 assertEquals(2, parent.indexOf(child1));
 143   
 144    // Test insert at beginning with children
 145  1 Element child4 = new Element("child4");
 146  1 parent.insertChild(child4, 0);
 147  1 assertEquals(0, parent.indexOf(child4));
 148  1 assertEquals(1, parent.indexOf(child2));
 149  1 assertEquals(2, parent.indexOf(child3));
 150  1 assertEquals(3, parent.indexOf(child1));
 151   
 152    // Test insert at end with children
 153  1 Element child5 = new Element("child5");
 154  1 parent.insertChild(child5, 4);
 155  1 assertEquals(0, parent.indexOf(child4));
 156  1 assertEquals(1, parent.indexOf(child2));
 157  1 assertEquals(2, parent.indexOf(child3));
 158  1 assertEquals(3, parent.indexOf(child1));
 159  1 assertEquals(4, parent.indexOf(child5));
 160   
 161  1 try {
 162  1 parent.insertChild((Element) null, 0);
 163  0 fail("Inserted null");
 164    }
 165    catch (NullPointerException success) {
 166  1 assertNotNull(success.getMessage());
 167    }
 168   
 169  1 try {
 170  1 parent.insertChild((Text) null, 0);
 171  0 fail("Inserted null");
 172    }
 173    catch (NullPointerException success) {
 174  1 assertNotNull(success.getMessage());
 175    }
 176   
 177  1 try {
 178  1 parent.insertChild((Comment) null, 0);
 179  0 fail("Inserted null");
 180    }
 181    catch (NullPointerException success) {
 182  1 assertNotNull(success.getMessage());
 183    }
 184   
 185  1 try {
 186  1 parent.insertChild((ProcessingInstruction) null, 0);
 187  0 fail("Inserted null");
 188    }
 189    catch (NullPointerException success) {
 190  1 assertNotNull(success.getMessage());
 191    }
 192   
 193    }
 194   
 195   
 196  1 public void testAppendChild2() {
 197   
 198  1 try {
 199  1 empty.appendChild(new Document(notEmpty));
 200  0 fail("appended a document to an element");
 201    }
 202    catch (IllegalAddException success) {
 203  1 assertNotNull(success.getMessage());
 204    }
 205   
 206  1 try {
 207  1 empty.appendChild(child);
 208  0 fail("appended a child twice");
 209    }
 210    catch (MultipleParentException success) {
 211  1 assertNotNull(success.getMessage());
 212    }
 213   
 214    }
 215   
 216   
 217  1 public void testReplaceChild() {
 218   
 219  1 Element old1 = new Element("old1");
 220  1 Element old2 = new Element("old2");
 221  1 Element old3 = new Element("old3");
 222  1 Element new1 = new Element("new1");
 223  1 Element new2 = new Element("new2");
 224  1 Element new3 = new Element("new3");
 225   
 226  1 empty.appendChild(old1);
 227  1 empty.appendChild(old2);
 228  1 empty.appendChild(old3);
 229   
 230  1 empty.replaceChild(old1, new1);
 231  1 empty.replaceChild(old3, new3);
 232  1 empty.replaceChild(old2, new2);
 233   
 234  1 Node current1 = empty.getChild(0);
 235  1 Node current2 = empty.getChild(1);
 236  1 Node current3 = empty.getChild(2);
 237   
 238  1 assertEquals(new1, current1);
 239  1 assertEquals(new2, current2);
 240  1 assertEquals(new3, current3);
 241   
 242  1 try {
 243  1 empty.replaceChild(new1, null);
 244    }
 245    catch (NullPointerException success) {
 246  1 assertNotNull(success.getMessage());
 247    }
 248   
 249  1 try {
 250  1 empty.replaceChild(null, old1);
 251    }
 252    catch (NullPointerException success) {
 253  1 assertNotNull(success.getMessage());
 254    }
 255   
 256  1 Element new4 = new Element("new4");
 257   
 258  1 try {
 259  1 empty.replaceChild(new4, new Element("test"));
 260  0 fail("Replaced Nonexistent element");
 261    }
 262    catch (NoSuchChildException success) {
 263  1 assertNotNull(success.getMessage());
 264    }
 265   
 266    // Test replacing node with itself
 267  1 empty.replaceChild(new1, new1);
 268  1 assertEquals(new1, empty.getChild(0));
 269  1 assertEquals(empty, new1.getParent());
 270   
 271    // Test replacing node with a sibling
 272  1 try {
 273  1 empty.replaceChild(new1, new2);
 274  0 fail("replaced a node with its sibling");
 275    }
 276    catch (MultipleParentException success) {
 277  1 assertNotNull(success.getMessage());
 278    }
 279   
 280   
 281    }
 282   
 283   
 284  1 public void testIndexOf() {
 285   
 286  1 Element child1 = new Element("old1");
 287  1 Text child2 = new Text("old2");
 288  1 Comment child3 = new Comment("old3");
 289   
 290  1 assertEquals(-1, empty.indexOf(child1));
 291   
 292  1 empty.appendChild(child1);
 293  1 empty.appendChild(child2);
 294  1 empty.appendChild(child3);
 295   
 296  1 assertEquals(0, empty.indexOf(child1));
 297  1 assertEquals(1, empty.indexOf(child2));
 298  1 assertEquals(2, empty.indexOf(child3));
 299  1 assertEquals(-1, empty.indexOf(empty));
 300  1 assertEquals(-1, empty.indexOf(new Text("test")));
 301   
 302    }
 303   
 304   
 305  1 public void testGetChild() {
 306   
 307  1 Element old1 = new Element("old1");
 308  1 Element old2 = new Element("old2");
 309  1 Element old3 = new Element("old3");
 310   
 311  1 try {
 312  1 empty.getChild(0);
 313  0 fail("No index exception");
 314    }
 315    catch (IndexOutOfBoundsException success) {
 316    // success
 317  1 assertNotNull(success.getMessage());
 318    }
 319   
 320  1 empty.appendChild(old1);
 321  1 empty.appendChild(old2);
 322  1 empty.appendChild(old3);
 323   
 324  1 assertEquals(old1, empty.getChild(0));
 325  1 assertEquals(old3, empty.getChild(2));
 326  1 assertEquals(old2, empty.getChild(1));
 327   
 328  1 try {
 329  1 empty.getChild(5);
 330  0 fail("No index exception");
 331    }
 332    catch (IndexOutOfBoundsException success) {
 333    // success
 334  1 assertNotNull(success.getMessage());
 335    }
 336   
 337    }
 338   
 339   
 340  1 public void testRemoveChild() {
 341   
 342  1 try {
 343  1 empty.removeChild(0);
 344  0 fail("Removed child from empty element");
 345    }
 346    catch (IndexOutOfBoundsException success) {
 347  1 assertNotNull(success.getMessage());
 348    }
 349   
 350  1 Element old1 = new Element("old1");
 351  1 Element old2 = new Element("old2");
 352  1 Element old3 = new Element("old3");
 353   
 354  1 try {
 355  1 empty.removeChild(old1);
 356  0 fail("Removed non-existent child from empty element");
 357    }
 358    catch (NoSuchChildException success) {
 359  1 assertNotNull(success.getMessage());
 360    }
 361   
 362  1 empty.appendChild(old1);
 363  1 empty.appendChild(old2);
 364  1 empty.appendChild(old3);
 365   
 366  1 empty.removeChild(1);
 367  1 assertEquals(old1, empty.getChild(0));
 368  1 assertEquals(old3, empty.getChild(1));
 369   
 370  1 try {
 371  1 empty.removeChild(5);
 372  0 fail("No IndexOutOfBoundsException");
 373    }
 374    catch (IndexOutOfBoundsException success) {
 375  1 assertNotNull(success.getMessage());
 376    }
 377   
 378  1 empty.removeChild(1);
 379  1 empty.removeChild(0);
 380  1 assertNull(old2.getParent());
 381   
 382  1 assertEquals(0, empty.getChildCount());
 383   
 384  1 empty.appendChild(old1);
 385  1 empty.appendChild(old2);
 386  1 empty.appendChild(old3);
 387   
 388  1 assertEquals(3, empty.getChildCount());
 389   
 390  1 empty.removeChild(old3);
 391  1 empty.removeChild(old1);
 392  1 empty.removeChild(old2);
 393   
 394  1 assertEquals(0, empty.getChildCount());
 395  1 assertNull(old1.getParent());
 396   
 397    }
 398   
 399   
 400  1 public void testReplaceChildFailures() {
 401   
 402  1 Element old1 = new Element("old1");
 403  1 Element old2 = new Element("old2");
 404  1 Element old3 = new Element("old3");
 405  1 Element new1 = new Element("new1");
 406  1 Element new3 = new Element("new3");
 407   
 408  1 empty.appendChild(old1);
 409  1 empty.appendChild(old2);
 410   
 411  1 try {
 412  1 empty.replaceChild(old3, new3);
 413  0 fail("Replaced non-existent child");
 414    }
 415    catch (NoSuchChildException success) {
 416  1 assertNotNull(success.getMessage());
 417    }
 418   
 419  1 try {
 420  1 empty.replaceChild(old1, null);
 421  0 fail("Replaced child with null");
 422    }
 423    catch (NullPointerException success) {
 424  1 assertNotNull(success.getMessage());
 425    }
 426   
 427  1 try {
 428  1 empty.replaceChild(null, new1);
 429  0 fail("Replaced null");
 430    }
 431    catch (NullPointerException success) {
 432  1 assertNotNull(success.getMessage());
 433    }
 434   
 435    }
 436   
 437   
 438  1 public void testReplaceChildInEmptyParent() {
 439   
 440  1 Element test1 = new Element("test");
 441  1 Element test2 = new Element("test");
 442  1 try {
 443  1 empty.replaceChild(test1, test2);
 444  0 fail("Replaced element in empty parent");
 445    }
 446    catch (NoSuchChildException success) {
 447  1 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  1 public void testReplaceSibling() {
 457   
 458  1 Element parent = new Element("parent");
 459  1 Element test1 = new Element("test");
 460  1 Element test2 = new Element("test");
 461  1 parent.appendChild(test1);
 462  1 parent.appendChild(test2);
 463  1 try {
 464  1 parent.replaceChild(test1, test2);
 465  0 fail("Replaced element without detaching first");
 466    }
 467    catch (IllegalAddException success) {
 468  1 assertNotNull(success.getMessage());
 469    }
 470   
 471  1 assertEquals(2, parent.getChildCount());
 472  1 assertEquals(parent, test1.getParent());
 473  1 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  1 public void testCantInsertExisitngChild() {
 482   
 483  1 Element parent = new Element("parent");
 484  1 Element test1 = new Element("test");
 485  1 Element test2 = new Element("test");
 486  1 parent.appendChild(test1);
 487  1 parent.appendChild(test2);
 488  1 try {
 489  1 parent.insertChild(test2, 0);
 490  0 fail("Inserted element without detaching first");
 491    }
 492    catch (MultipleParentException success) {
 493  1 assertNotNull(success.getMessage());
 494    }
 495   
 496  1 try {
 497  1 parent.insertChild(test2, 1);
 498  0 fail("Inserted element without detaching first");
 499    }
 500    catch (MultipleParentException success) {
 501  1 assertNotNull(success.getMessage());
 502    }
 503   
 504  1 assertEquals(2, parent.getChildCount());
 505  1 assertEquals(parent, test1.getParent());
 506  1 assertEquals(parent, test2.getParent());
 507   
 508    }
 509   
 510   
 511    // can't remove when insertion is legal;
 512    // succeeed or fail as unit
 513  1 public void testReplaceChildAtomicity() {
 514   
 515  1 Element parent = new Element("parent");
 516  1 Text child = new Text("child");
 517  1 parent.appendChild(child);
 518   
 519  1 try {
 520  1 parent.replaceChild(child, new DocType("root"));
 521  0 fail("allowed doctype child of element");
 522    }
 523    catch (IllegalAddException success) {
 524  1 assertEquals(parent, child.getParent());
 525  1 assertEquals(1, parent.getChildCount());
 526    }
 527   
 528  1 Element e = new Element("e");
 529  1 Text child2 = new Text("child2");
 530  1 e.appendChild(child2);
 531  1 try {
 532  1 parent.replaceChild(child, child2);
 533  0 fail("allowed replacement with existing parent");
 534    }
 535    catch (MultipleParentException success) {
 536  1 assertEquals(e, child2.getParent());
 537  1 assertEquals(parent, child.getParent());
 538  1 assertEquals(1, parent.getChildCount());
 539  1 assertEquals(1, e.getChildCount());
 540    }
 541   
 542    }
 543   
 544   
 545    }