DOMNodeComparator.php (3475B)
1 <?php 2 /* 3 * This file is part of the Comparator package. 4 * 5 * (c) Sebastian Bergmann <sebastian@phpunit.de> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11 namespace SebastianBergmann\Comparator; 12 13 use DOMDocument; 14 use DOMNode; 15 16 /** 17 * Compares DOMNode instances for equality. 18 */ 19 class DOMNodeComparator extends ObjectComparator 20 { 21 /** 22 * Returns whether the comparator can compare two values. 23 * 24 * @param mixed $expected The first value to compare 25 * @param mixed $actual The second value to compare 26 * @return bool 27 */ 28 public function accepts($expected, $actual) 29 { 30 return $expected instanceof DOMNode && $actual instanceof DOMNode; 31 } 32 33 /** 34 * Asserts that two values are equal. 35 * 36 * @param mixed $expected The first value to compare 37 * @param mixed $actual The second value to compare 38 * @param float $delta The allowed numerical distance between two values to 39 * consider them equal 40 * @param bool $canonicalize If set to TRUE, arrays are sorted before 41 * comparison 42 * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is 43 * ignored when comparing string values 44 * @throws ComparisonFailure Thrown when the comparison 45 * fails. Contains information about the 46 * specific errors that lead to the failure. 47 */ 48 public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false) 49 { 50 $expectedAsString = $this->nodeToText($expected, true, $ignoreCase); 51 $actualAsString = $this->nodeToText($actual, true, $ignoreCase); 52 53 if ($expectedAsString !== $actualAsString) { 54 if ($expected instanceof DOMDocument) { 55 $type = 'documents'; 56 } else { 57 $type = 'nodes'; 58 } 59 60 throw new ComparisonFailure( 61 $expected, 62 $actual, 63 $expectedAsString, 64 $actualAsString, 65 false, 66 sprintf("Failed asserting that two DOM %s are equal.\n", $type) 67 ); 68 } 69 } 70 71 /** 72 * Returns the normalized, whitespace-cleaned, and indented textual 73 * representation of a DOMNode. 74 * 75 * @param DOMNode $node 76 * @param bool $canonicalize 77 * @param bool $ignoreCase 78 * @return string 79 */ 80 private function nodeToText(DOMNode $node, $canonicalize, $ignoreCase) 81 { 82 if ($canonicalize) { 83 $document = new DOMDocument; 84 $document->loadXML($node->C14N()); 85 86 $node = $document; 87 } 88 89 if ($node instanceof DOMDocument) { 90 $document = $node; 91 } else { 92 $document = $node->ownerDocument; 93 } 94 95 $document->formatOutput = true; 96 $document->normalizeDocument(); 97 98 if ($node instanceof DOMDocument) { 99 $text = $node->saveXML(); 100 } else { 101 $text = $document->saveXML($node); 102 } 103 104 if ($ignoreCase) { 105 $text = strtolower($text); 106 } 107 108 return $text; 109 } 110 }