ObjectComparator.php (4001B)
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 /** 14 * Compares objects for equality. 15 */ 16 class ObjectComparator extends ArrayComparator 17 { 18 /** 19 * Returns whether the comparator can compare two values. 20 * 21 * @param mixed $expected The first value to compare 22 * @param mixed $actual The second value to compare 23 * @return bool 24 */ 25 public function accepts($expected, $actual) 26 { 27 return is_object($expected) && is_object($actual); 28 } 29 30 /** 31 * Asserts that two values are equal. 32 * 33 * @param mixed $expected The first value to compare 34 * @param mixed $actual The second value to compare 35 * @param float $delta The allowed numerical distance between two values to 36 * consider them equal 37 * @param bool $canonicalize If set to TRUE, arrays are sorted before 38 * comparison 39 * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is 40 * ignored when comparing string values 41 * @param array $processed 42 * @throws ComparisonFailure Thrown when the comparison 43 * fails. Contains information about the 44 * specific errors that lead to the failure. 45 */ 46 public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array()) 47 { 48 if (get_class($actual) !== get_class($expected)) { 49 throw new ComparisonFailure( 50 $expected, 51 $actual, 52 $this->exporter->export($expected), 53 $this->exporter->export($actual), 54 false, 55 sprintf( 56 '%s is not instance of expected class "%s".', 57 $this->exporter->export($actual), 58 get_class($expected) 59 ) 60 ); 61 } 62 63 // don't compare twice to allow for cyclic dependencies 64 if (in_array(array($actual, $expected), $processed, true) || 65 in_array(array($expected, $actual), $processed, true)) { 66 return; 67 } 68 69 $processed[] = array($actual, $expected); 70 71 // don't compare objects if they are identical 72 // this helps to avoid the error "maximum function nesting level reached" 73 // CAUTION: this conditional clause is not tested 74 if ($actual !== $expected) { 75 try { 76 parent::assertEquals( 77 $this->toArray($expected), 78 $this->toArray($actual), 79 $delta, 80 $canonicalize, 81 $ignoreCase, 82 $processed 83 ); 84 } catch (ComparisonFailure $e) { 85 throw new ComparisonFailure( 86 $expected, 87 $actual, 88 // replace "Array" with "MyClass object" 89 substr_replace($e->getExpectedAsString(), get_class($expected) . ' Object', 0, 5), 90 substr_replace($e->getActualAsString(), get_class($actual) . ' Object', 0, 5), 91 false, 92 'Failed asserting that two objects are equal.' 93 ); 94 } 95 } 96 } 97 98 /** 99 * Converts an object to an array containing all of its private, protected 100 * and public properties. 101 * 102 * @param object $object 103 * @return array 104 */ 105 protected function toArray($object) 106 { 107 return $this->exporter->toArray($object); 108 } 109 }