ObjectComparator.php 3.5 KB

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