ArrayComparator.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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 arrays for equality.
  13. */
  14. class ArrayComparator extends Comparator
  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_array($expected) && is_array($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 ($canonicalize) {
  42. sort($expected);
  43. sort($actual);
  44. }
  45. $remaining = $actual;
  46. $expString = $actString = "Array (\n";
  47. $equal = true;
  48. foreach ($expected as $key => $value) {
  49. unset($remaining[$key]);
  50. if (!array_key_exists($key, $actual)) {
  51. $expString .= sprintf(
  52. " %s => %s\n",
  53. $this->exporter->export($key),
  54. $this->exporter->shortenedExport($value)
  55. );
  56. $equal = false;
  57. continue;
  58. }
  59. try {
  60. $comparator = $this->factory->getComparatorFor($value, $actual[$key]);
  61. $comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
  62. $expString .= sprintf(
  63. " %s => %s\n",
  64. $this->exporter->export($key),
  65. $this->exporter->shortenedExport($value)
  66. );
  67. $actString .= sprintf(
  68. " %s => %s\n",
  69. $this->exporter->export($key),
  70. $this->exporter->shortenedExport($actual[$key])
  71. );
  72. } catch (ComparisonFailure $e) {
  73. $expString .= sprintf(
  74. " %s => %s\n",
  75. $this->exporter->export($key),
  76. $e->getExpectedAsString()
  77. ? $this->indent($e->getExpectedAsString())
  78. : $this->exporter->shortenedExport($e->getExpected())
  79. );
  80. $actString .= sprintf(
  81. " %s => %s\n",
  82. $this->exporter->export($key),
  83. $e->getActualAsString()
  84. ? $this->indent($e->getActualAsString())
  85. : $this->exporter->shortenedExport($e->getActual())
  86. );
  87. $equal = false;
  88. }
  89. }
  90. foreach ($remaining as $key => $value) {
  91. $actString .= sprintf(
  92. " %s => %s\n",
  93. $this->exporter->export($key),
  94. $this->exporter->shortenedExport($value)
  95. );
  96. $equal = false;
  97. }
  98. $expString .= ')';
  99. $actString .= ')';
  100. if (!$equal) {
  101. throw new ComparisonFailure(
  102. $expected,
  103. $actual,
  104. $expString,
  105. $actString,
  106. false,
  107. 'Failed asserting that two arrays are equal.'
  108. );
  109. }
  110. }
  111. protected function indent($lines)
  112. {
  113. return trim(str_replace("\n", "\n ", $lines));
  114. }
  115. }