ObjectComparator.php 3.9 KB

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