ArrayComparator.php 4.5 KB

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