Clover coverage report - Clover results for XOM 1.2d1
Coverage timestamp: Wed Feb 8 2006 08:31:33 EST
file stats: LOC: 756   Methods: 23
NCLOC: 329   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
XOMTestCase.java 96.3% 98.1% 100% 97.7%
coverage coverage
 1    /* Copyright 2002-2005 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 junit.framework.ComparisonFailure;
 25    import junit.framework.TestCase;
 26    import nu.xom.Attribute;
 27    import nu.xom.Comment;
 28    import nu.xom.DocType;
 29    import nu.xom.Document;
 30    import nu.xom.Element;
 31    import nu.xom.Namespace;
 32    import nu.xom.Node;
 33    import nu.xom.ProcessingInstruction;
 34    import nu.xom.Text;
 35   
 36   
 37    /**
 38    * <p>
 39    * Provides utility methods to compare nodes for deep equality in an
 40    * infoset sense.
 41    * </p>
 42    *
 43    * @author Elliotte Rusty Harold
 44    * @version 1.1a2
 45    *
 46    */
 47    public class XOMTestCase extends TestCase {
 48   
 49    /**
 50    * <p>
 51    * Create a new <code>XOMTestCase</code> with the specified name.
 52    * </p>
 53    */
 54  1388 public XOMTestCase(String name) {
 55  1388 super(name);
 56    }
 57   
 58    /**
 59    * <p>
 60    * Asserts that two text nodes are equal. Text nodes are considered
 61    * equal if they are identical char by char, or if both are null.
 62    * Unicode and whitespace normalization is not performed before
 63    * comparison. If the two nodes are not equal, a
 64    * <code>ComparisonFailure</code> is thrown.
 65    * </p>
 66    *
 67    * @param expected the text the test should produce
 68    * @param actual the text the test does produce
 69    *
 70    * @throws ComparisonFailure if the text nodes are not equal
 71    */
 72  4 public static void assertEquals(Text expected, Text actual) {
 73  4 assertEquals(null, expected, actual);
 74    }
 75   
 76   
 77    /**
 78    * <p>
 79    * Asserts that two text nodes are equal. Text nodes are considered
 80    * equal if they are identical char by char, or if both are null.
 81    * Unicode and whitespace normalization is not performed before
 82    * comparison. If the two nodes are not equal, a
 83    * <code>ComparisonFailure</code> is thrown with the given
 84    * message.
 85    * </p>
 86    *
 87    * @param message printed if the texts are not equal
 88    * @param expected the text the test should produce
 89    * @param actual the text the test does produce
 90    *
 91    * @throws ComparisonFailure if the text nodes are not equal
 92    */
 93  33994 public static void assertEquals(
 94    String message, Text expected, Text actual) {
 95   
 96  1 if (actual == expected) return;
 97  33993 nullCheck(message, expected, actual);
 98   
 99  33991 assertEquals(message, expected.getValue(), actual.getValue());
 100    }
 101   
 102   
 103  125656 private static void nullCheck(String message, Node expected, Node actual) {
 104   
 105  125656 if (expected == null) {
 106  1 throw new ComparisonFailure(message, null, actual.toXML());
 107    }
 108  125655 else if (actual == null) {
 109  2 throw new ComparisonFailure(message, expected.toXML(), null);
 110    }
 111   
 112    }
 113   
 114   
 115    /**
 116    * <p>
 117    * Asserts that two attribute nodes are equal.
 118    * Attribute nodes are considered equal if their
 119    * qualified names, namespace URIs, and values
 120    * are equal. The type is not considered because it tends not to
 121    * survive a roundtrip. If the two nodes are not equal, a
 122    * <code>ComparisonFailure</code> is thrown.
 123    * </p>
 124    *
 125    * <p>
 126    * There is special handling for the <code>xml:base</code>
 127    * attribute. In order to facilitate comparison between relative
 128    * and absolute URIs, two <code>xml:base</code> attributes are
 129    * considered equal if one might be a relative form of the other.
 130    * </p>
 131    *
 132    * @param expected the attribute the test should produce
 133    * @param actual the attribute the test does produce
 134    *
 135    * @throws ComparisonFailure if the sttributes are not equal
 136    */
 137  10 public static void assertEquals(
 138    Attribute expected, Attribute actual) {
 139  10 assertEquals(null, expected, actual);
 140    }
 141   
 142   
 143    /**
 144    * <p>
 145    * Asserts that two attribute nodes are equal.
 146    * Attribute nodes are considered equal if their
 147    * qualified names, namespace URIs, and values
 148    * are equal. The type is not considered because this tends not to
 149    * survive a roundtrip. If the two nodes are not equal, a
 150    * <code>ComparisonFailure</code> is thrown with the given
 151    * message.
 152    * </p>
 153    *
 154    * <p>
 155    * There is special handling for the <code>xml:base</code>
 156    * attribute. In order to facilitate comparison between relative and
 157    * absolute URIs, two <code>xml:base</code> attributes are
 158    * considered equal if one might be a relative form of the other.
 159    * </p>
 160    *
 161    * @param message printed if the attributes are not equal
 162    * @param expected the attribute the test should produce
 163    * @param actual the attribute the test does produce
 164    *
 165    * @throws ComparisonFailure if the attributes are not equal
 166    */
 167  11213 public static void assertEquals(
 168    String message, Attribute expected, Attribute actual) {
 169   
 170  8 if (actual == expected) return;
 171  11205 nullCheck(message, expected, actual);
 172   
 173  11205 String value1 = expected.getValue();
 174  11205 String value2 = actual.getValue();
 175  11205 if ("xml:base".equals(expected.getQualifiedName())) {
 176    // handle possibility that one is relative and other is not
 177  73 if (value1.equals(value2)) return;
 178  29 if (value1.startsWith("../")) {
 179  27 assertTrue(message, value2.endsWith(value1.substring(2)));
 180    }
 181    else {
 182  2 assertTrue(message,
 183    value1.endsWith('/' + value2) || value2.endsWith('/' + value1));
 184    }
 185    }
 186    else {
 187  11103 assertEquals(message, value1, value2);
 188  11103 assertEquals(message, expected.getLocalName(), actual.getLocalName());
 189  11103 assertEquals(message,
 190    expected.getQualifiedName(), actual.getQualifiedName()
 191    );
 192  11103 assertEquals(message,
 193    expected.getNamespaceURI(), actual.getNamespaceURI()
 194    );
 195    }
 196   
 197    }
 198   
 199   
 200    /**
 201    * <p>
 202    * Asserts that two <code>DocType</code> nodes are equal.
 203    * <code>DocType</code> nodes are considered equal if their
 204    * root element names, public IDs, and system IDs
 205    * are equal. The internal DTD subsets are not considered.
 206    * If the two nodes are not equal, a
 207    * <code>ComparisonFailure</code> is thrown.
 208    * </p>
 209    *
 210    * @param expected the DOCTYPE declaration the test should produce
 211    * @param actual the DOCTYPE declaration the test does produce
 212    *
 213    * @throws ComparisonFailure if the document type declarations
 214    * are not equal
 215    */
 216  11 public static void assertEquals(DocType expected, DocType actual) {
 217  11 assertEquals(null, expected, actual);
 218    }
 219   
 220   
 221    /**
 222    * <p>
 223    * Asserts that two <code>DocType</code> nodes are equal.
 224    * <code>DocType</code> nodes are considered equal if their
 225    * root element name, public ID, and system ID
 226    * are equal. The internal DTD subsets are not considered.
 227    * If the two nodes are not equal, a
 228    * <code>ComparisonFailure</code> is thrown with the given
 229    * message.
 230    * </p>
 231    *
 232    * @param message printed if the DOCTYPE declarations are not equal
 233    * @param expected the DOCTYPE declaration the test should produce
 234    * @param actual the DOCTYPE declaration the test does produce
 235    *
 236    * @throws ComparisonFailure if the document type declarations
 237    * are not equal
 238    *
 239    */
 240  587 public static void assertEquals(
 241    String message, DocType expected, DocType actual) {
 242   
 243  11 if (actual == expected) return;
 244  576 nullCheck(message, expected, actual);
 245   
 246  576 assertEquals(message,
 247    expected.getPublicID(),
 248    actual.getPublicID()
 249    );
 250  576 assertEquals(message,
 251    expected.getSystemID(),
 252    actual.getSystemID()
 253    );
 254  576 assertEquals(message,
 255    expected.getRootElementName(),
 256    actual.getRootElementName()
 257    );
 258    }
 259   
 260   
 261    /**
 262    * <p>
 263    * Asserts that two element nodes are equal.
 264    * Element nodes are considered equal if their
 265    * qualified names, namespace URI, attributes,
 266    * declared namespaces, and children
 267    * are equal. Consecutive text node children are coalesced
 268    * before the comparison is made. If the two nodes are not equal,
 269    * a <code>ComparisonFailure</code> is thrown.
 270    * </p>
 271    *
 272    * @param expected the element the test should produce
 273    * @param actual the element the test does produce
 274    *
 275    * @throws ComparisonFailure if the elements are not equal
 276    */
 277  31 public static void assertEquals(
 278    Element expected, Element actual) {
 279  31 assertEquals(null, expected, actual);
 280   
 281    }
 282   
 283   
 284    /**
 285    * <p>
 286    * Asserts that two element nodes are equal.
 287    * Element nodes are considered equal if their
 288    * qualified names, namespace URI, attributes,
 289    * declared namespaces, and children
 290    * are equal. Consecutive text node children are coalesced
 291    * before the comparison is made. If the two nodes are not equal,
 292    * a <code>ComparisonFailure</code> is thrown with the given
 293    * message.
 294    * </p>
 295    *
 296    * @param message printed if the elements are not equal
 297    * @param expected the element the test should produce
 298    * @param actual the element the test does produce
 299    *
 300    * @throws ComparisonFailure if the elements are not equal
 301    */
 302  21019 public static void assertEquals(String message,
 303    Element expected, Element actual) {
 304   
 305  19 if (actual == expected) return;
 306  21000 nullCheck(message, expected, actual);
 307   
 308  21000 assertEquals(message,
 309    expected.getLocalName(),
 310    actual.getLocalName()
 311    );
 312  20999 assertEquals(message,
 313    expected.getNamespacePrefix(),
 314    actual.getNamespacePrefix()
 315    );
 316  20999 assertEquals(message,
 317    expected.getNamespaceURI(),
 318    actual.getNamespaceURI()
 319    );
 320   
 321  20999 assertEquals(message,
 322    expected.getAttributeCount(),
 323    actual.getAttributeCount()
 324    );
 325   
 326  20999 for (int i = 0; i < expected.getAttributeCount(); i++ ) {
 327  11201 Attribute att1 = expected.getAttribute(i);
 328  11201 Attribute att2
 329    = actual.getAttribute(
 330    att1.getLocalName(),
 331    att1.getNamespaceURI()
 332    );
 333  11201 assertNotNull(message, att2);
 334  11201 assertEquals(message, att1, att2);
 335    }
 336   
 337    // Check declared namespaces by listing all the prefixes
 338    // on element1 and making sure element2 gives the same value
 339    // for those prefixes, and vice versa. This is necessary
 340    // to handle a few weird cases that arise in XInclude
 341    // when prefixes are declared multiple times, to account for
 342    // the fact that some serializers may drop redundant
 343    // namespace declarations.
 344  20999 for (int i = 0;
 345  42178 i < expected.getNamespaceDeclarationCount();
 346    i++ ) {
 347  21179 String prefix1 = expected.getNamespacePrefix(i);
 348  21179 String uri1 = expected.getNamespaceURI(prefix1);
 349  21179 assertNotNull(message, actual.getNamespaceURI(prefix1));
 350  21179 assertEquals(message,
 351    uri1, actual.getNamespaceURI(prefix1)
 352    );
 353    }
 354  20999 for (int i = 0;
 355  42153 i < actual.getNamespaceDeclarationCount();
 356    i++ ) {
 357  21154 String prefix1 = actual.getNamespacePrefix(i);
 358  21154 String uri1 = actual.getNamespaceURI(prefix1);
 359  21154 assertNotNull(message, expected.getNamespaceURI(prefix1));
 360  21154 assertEquals(message,
 361    uri1, expected.getNamespaceURI(prefix1)
 362    );
 363    }
 364   
 365  20999 compareChildren(message, expected, actual);
 366   
 367    }
 368   
 369   
 370  41998 private static boolean hasAdjacentTextNodes(Element element) {
 371   
 372  41998 boolean previousWasText = false;
 373  41998 int count = element.getChildCount();
 374  41998 for (int i = 0; i < count; i++) {
 375  152424 Node child = element.getChild(i);
 376  152424 if (child instanceof Text) {
 377  46 if (previousWasText) return true;
 378  67963 else previousWasText = true;
 379    }
 380    else {
 381  84415 previousWasText = false;
 382    }
 383    }
 384  41952 return false;
 385   
 386    }
 387   
 388   
 389  20999 private static void compareChildren(String message, Element expected, Element actual) {
 390   
 391  20999 Element expectedCopy = expected;
 392  20999 Element actualCopy = actual;
 393  20999 if (hasAdjacentTextNodes(expected)) {
 394  3 expectedCopy = combineTextNodes(expected);
 395    }
 396  20999 if (hasAdjacentTextNodes(actual)) {
 397  43 actualCopy = combineTextNodes(actual);
 398    }
 399   
 400  20999 int count = expectedCopy.getChildCount();
 401  20999 assertEquals(message, count, actualCopy.getChildCount());
 402  20997 int nonTextNodes = count;
 403  20997 for (int i = 0; i < count; i++) {
 404  54456 Node child1 = expectedCopy.getChild(i);
 405    // could remove this instanceof Test by having combineTextNodes
 406    // set a list of text indices
 407  54456 if (child1 instanceof Text) {
 408  33989 nonTextNodes--;
 409  33989 Node child2 = actualCopy.getChild(i);
 410  33989 assertEquals(message, child1, child2);
 411    }
 412    }
 413   
 414    // now compare everything that isn't text using the original
 415    // element objects
 416  20997 for (int i = 0; i < nonTextNodes; i++) {
 417  20467 Node expectedChild = getNonTextNode(expected, i);
 418  20467 Node actualChild = getNonTextNode(actual, i);
 419  20467 assertEquals(message, expectedChild, actualChild);
 420    }
 421   
 422    }
 423   
 424   
 425  40934 private static Node getNonTextNode(Element element, int index) {
 426   
 427  40934 int nonTextCount = 0;
 428  40934 int count = element.getChildCount();
 429  265409 for (int i = 0; i < count; i++) {
 430  265409 Node child = element.getChild(i);
 431  265409 if (! (child instanceof Text) ) {
 432  40934 if (nonTextCount == index) return child;
 433  98146 nonTextCount++;
 434    }
 435    }
 436  0 throw new RuntimeException(
 437    "Bug in XOMTestCase: this statement should not be reachable");
 438   
 439    }
 440   
 441    /* We only need to make an element that has the combined text
 442    * nodes, and something as a child placeholder.
 443    * It does need to have the other pieces.
 444    */
 445  46 private static Element combineTextNodes(Element element) {
 446   
 447  46 Element stub = new Element("a");
 448  46 Comment stubc = new Comment("c");
 449  46 StringBuffer sb = new StringBuffer();
 450  46 int count = element.getChildCount();
 451  46 for (int i = 0; i < count; i++) {
 452  100 Node child = element.getChild(i);
 453  100 if (child instanceof Text) {
 454  73 sb.setLength(0);
 455  73 do {
 456  153 sb.append(child.getValue());
 457  153 i++;
 458  153 if (i == count) {
 459  46 break;
 460    }
 461  107 child = element.getChild(i);
 462  107 } while (child instanceof Text);
 463  73 i--;
 464  73 stub.appendChild(sb.toString());
 465    }
 466    else {
 467  27 stub.appendChild(stubc.copy());
 468    }
 469    }
 470  46 return stub;
 471   
 472    }
 473   
 474   
 475    /**
 476    * <p>
 477    * Asserts that two document nodes are equal.
 478    * Document nodes are considered equal if their
 479    * children are equal. If the two nodes are not equal,
 480    * a <code>ComparisonFailure</code> is thrown.
 481    * </p>
 482    *
 483    * @param expected the document the test should produce
 484    * @param actual the document the test does produce
 485    *
 486    * @throws ComparisonFailure if the documents are not equal
 487    */
 488  197 public static void assertEquals(
 489    Document expected, Document actual) {
 490  197 assertEquals(null, expected, actual);
 491    }
 492   
 493   
 494    /**
 495    * <p>
 496    * Asserts that two document nodes are equal.
 497    * Document nodes are considered equal if their
 498    * children are equal. If the two nodes are not equal,
 499    * a <code>ComparisonFailure</code> is thrown with the given
 500    * message.
 501    * </p>
 502    *
 503    * @param message printed if the documents are not equal
 504    * @param expected the document the test should produce
 505    * @param actual the document the test does produce
 506    *
 507    * @throws ComparisonFailure if the documents are not equal
 508    */
 509  1006 public static void assertEquals(
 510    String message, Document expected, Document actual) {
 511   
 512  2 if (actual == expected) return;
 513  1004 nullCheck(message, expected, actual);
 514   
 515  1004 assertEquals(message,
 516    expected.getChildCount(),
 517    actual.getChildCount()
 518    );
 519  1002 for (int i = 0; i < actual.getChildCount(); i++) {
 520  1957 Node child1 = expected.getChild(i);
 521  1957 Node child2 = actual.getChild(i);
 522  1957 assertEquals(message, child1, child2);
 523    }
 524   
 525    }
 526   
 527   
 528    /**
 529    * <p>
 530    * Asserts that two comment nodes are equal. Comment nodes are
 531    * considered equal if they are identical char by char, or if both
 532    * are null. Unicode and whitespace normalization is not performed
 533    * before comparison. If the two nodes are not equal, a
 534    * <code>ComparisonFailure</code> is thrown.
 535    * </p>
 536    *
 537    * @param expected the comment the test should produce
 538    * @param actual the comment the test does produce
 539    *
 540    * @throws ComparisonFailure if the comments are not equal
 541    */
 542  1 public static void assertEquals(Comment expected, Comment actual) {
 543  1 assertEquals(null, expected, actual);
 544    }
 545   
 546   
 547    /**
 548    * <p>
 549    * Asserts that two comment nodes are equal. Comment nodes are considered
 550    * equal if they are identical char by char, or if both are null.
 551    * Unicode and whitespace normalization is not performed before
 552    * comparison. If the two nodes are not equal, a
 553    * <code>ComparisonFailure</code> is thrown with the given
 554    * message.
 555    * </p>
 556    *
 557    * @param message printed if the comments are not equal
 558    * @param expected the comment the test should produce
 559    * @param actual the comment the test does produce
 560    *
 561    * @throws ComparisonFailure if the comments are not equal
 562    */
 563  1065 public static void assertEquals(
 564    String message, Comment expected, Comment actual) {
 565   
 566  1 if (actual == expected) return;
 567  1064 nullCheck(message, expected, actual);
 568  1064 assertEquals(message, expected.getValue(), actual.getValue());
 569   
 570    }
 571   
 572   
 573    /**
 574    * <p>
 575    * Asserts that two processing instruction nodes are equal.
 576    * Processing instruction nodes are considered
 577    * equal if they have the same target and the same value.
 578    * If the two nodes are not equal, a
 579    * <code>ComparisonFailure</code> is thrown.
 580    * </p>
 581    *
 582    * @param expected the processing instruction the test should produce
 583    * @param actual the processing instruction the test does produce
 584    *
 585    * @throws ComparisonFailure if the processing instructions
 586    * are not equal
 587    */
 588  2 public static void assertEquals(ProcessingInstruction expected,
 589    ProcessingInstruction actual) {
 590  2 assertEquals(null, expected, actual);
 591    }
 592   
 593   
 594    /**
 595    * <p>
 596    * Asserts that two processing instruction nodes are equal.
 597    * Processing instruction nodes are considered
 598    * equal if they have the same target and the same value.
 599    * If the two nodes are not equal, a
 600    * <code>ComparisonFailure</code> is thrown with the given
 601    * message.
 602    * </p>
 603    *
 604    * @param message printed if the processing instructions are
 605    * not equal
 606    * @param expected the processing instruction the test
 607    * should produce
 608    * @param actual the processing instruction the test does produce
 609    *
 610    * @throws ComparisonFailure if the processing instructions
 611    * are not equal
 612    */
 613  96 public static void assertEquals(String message,
 614    ProcessingInstruction expected,
 615    ProcessingInstruction actual) {
 616   
 617  1 if (actual == expected) return;
 618  95 nullCheck(message, expected, actual);
 619   
 620  95 assertEquals(message, expected.getValue(), actual.getValue());
 621  95 assertEquals(message, expected.getTarget(), actual.getTarget());
 622   
 623    }
 624   
 625   
 626    /**
 627    * <p>
 628    * Asserts that two namespace nodes are equal.
 629    * Namespace nodes are considered
 630    * equal if they have the same prefix and the same URI.
 631    * If the two nodes are not equal, a
 632    * <code>ComparisonFailure</code> is thrown with the given
 633    * message.
 634    * </p>
 635    *
 636    * @param message printed if the namespaces are not equal
 637    * @param expected the namespace the test should produce
 638    * @param actual the namespace the test does produce
 639    *
 640    * @throws ComparisonFailure if the namespaces are not equal
 641    */
 642  1 public static void assertEquals(String message,
 643    Namespace expected, Namespace actual) {
 644   
 645  0 if (actual == expected) return;
 646  1 nullCheck(message, expected, actual);
 647   
 648  1 assertEquals(message, expected.getValue(), actual.getValue());
 649  1 assertEquals(message, expected.getPrefix(), actual.getPrefix());
 650   
 651    }
 652   
 653   
 654    /**
 655    * <p>
 656    * Asserts that two nodes are equal. If the two nodes are not
 657    * equal a <code>ComparisonFailure</code> is thrown.
 658    * The subclass is not considered. The basic XOM class
 659    * is considered, but the subclass is not. For example,
 660    * a <code>Text</code> object can be equal to an object that
 661    * is an <code>HTMLText</code>, but it can never be equal to
 662    * a <code>Comment</code>.
 663    * </p>
 664    *
 665    * @param expected the node the test should produce
 666    * @param actual the node the test does produce
 667    *
 668    * @throws ComparisonFailure if the nodes are not equal
 669    */
 670  208 public static void assertEquals(Node expected, Node actual) {
 671  208 assertEquals(null, expected, actual);
 672    }
 673   
 674   
 675    /**
 676    * <p>
 677    * Asserts that two nodes are equal. If the two nodes are not
 678    * equal a <code>ComparisonFailure</code> is thrown with the given
 679    * message. The subclass is not considered. The basic XOM class
 680    * is considered, but the subclass is not. For example,
 681    * a <code>Text</code> object can be equal to an an
 682    * <code>HTMLText</code> object, but it can never be equal to
 683    * a <code>Comment</code>.
 684    * </p>
 685    *
 686    * @param message printed if the nodes are not equal
 687    * @param expected the node the test should produce
 688    * @param actual the node the test does produce
 689    *
 690    * @throws ComparisonFailure if the nodes are not equal
 691    */
 692  56896 public static void assertEquals(
 693    String message, Node expected, Node actual) {
 694   
 695  178 if (actual == expected) return;
 696  56718 nullCheck(message, expected, actual);
 697   
 698  56717 try {
 699  56717 if (expected instanceof Document) {
 700  1 assertEquals(message, (Document) expected, (Document) actual);
 701    }
 702  56716 else if (expected instanceof Element) {
 703  20987 assertEquals(message, (Element) expected, (Element) actual);
 704    }
 705  35729 else if (expected instanceof Text) {
 706  33991 assertEquals(message, (Text) expected, (Text) actual);
 707    }
 708  1738 else if (expected instanceof DocType) {
 709  576 assertEquals(message,
 710    (DocType) expected,
 711    (DocType) actual
 712    );
 713    }
 714  1162 else if (expected instanceof Comment) {
 715  1064 assertEquals(message,
 716    (Comment) expected,
 717    (Comment) actual
 718    );
 719    }
 720  98 else if (expected instanceof ProcessingInstruction) {
 721  94 assertEquals(message,
 722    (ProcessingInstruction) expected,
 723    (ProcessingInstruction) actual
 724    );
 725    }
 726  4 else if (expected instanceof Attribute) {
 727  3 assertEquals(message,
 728    (Attribute) expected,
 729    (Attribute) actual
 730    );
 731    }
 732  1 else if (expected instanceof Namespace) {
 733  1 assertEquals(message,
 734    (Namespace) expected,
 735    (Namespace) actual
 736    );
 737    }
 738    else {
 739  0 throw new IllegalArgumentException(
 740    "Unexpected node type "
 741    + expected.getClass().getName()
 742    );
 743    }
 744    }
 745    catch (ClassCastException ex) {
 746  2 throw new ComparisonFailure(message
 747    + "; Mismatched node types: "
 748    + expected.getClass().getName() + " != "
 749    + actual.getClass().getName(),
 750    expected.toXML(), actual.toXML());
 751    }
 752   
 753    }
 754   
 755   
 756    }