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 11namespace SebastianBergmann\Comparator; 12 13/** 14 * Compares arrays for equality. 15 */ 16class ArrayComparator extends Comparator 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_array($expected) && is_array($actual); 28 } 29 30 /** 31 * Asserts that two values are equal. 32 * 33 * @param mixed $expected First value to compare 34 * @param mixed $actual Second value to compare 35 * @param float $delta Allowed numerical distance between two values to consider them equal 36 * @param bool $canonicalize Arrays are sorted before comparison when set to true 37 * @param bool $ignoreCase Case is ignored when set to true 38 * @param array $processed List of already processed elements (used to prevent infinite recursion) 39 * 40 * @throws ComparisonFailure 41 */ 42 public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array()) 43 { 44 if ($canonicalize) { 45 sort($expected); 46 sort($actual); 47 } 48 49 $remaining = $actual; 50 $expString = $actString = "Array (\n"; 51 $equal = true; 52 53 foreach ($expected as $key => $value) { 54 unset($remaining[$key]); 55 56 if (!array_key_exists($key, $actual)) { 57 $expString .= sprintf( 58 " %s => %s\n", 59 $this->exporter->export($key), 60 $this->exporter->shortenedExport($value) 61 ); 62 63 $equal = false; 64 65 continue; 66 } 67 68 try { 69 $comparator = $this->factory->getComparatorFor($value, $actual[$key]); 70 $comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed); 71 72 $expString .= sprintf( 73 " %s => %s\n", 74 $this->exporter->export($key), 75 $this->exporter->shortenedExport($value) 76 ); 77 $actString .= sprintf( 78 " %s => %s\n", 79 $this->exporter->export($key), 80 $this->exporter->shortenedExport($actual[$key]) 81 ); 82 } catch (ComparisonFailure $e) { 83 $expString .= sprintf( 84 " %s => %s\n", 85 $this->exporter->export($key), 86 $e->getExpectedAsString() 87 ? $this->indent($e->getExpectedAsString()) 88 : $this->exporter->shortenedExport($e->getExpected()) 89 ); 90 91 $actString .= sprintf( 92 " %s => %s\n", 93 $this->exporter->export($key), 94 $e->getActualAsString() 95 ? $this->indent($e->getActualAsString()) 96 : $this->exporter->shortenedExport($e->getActual()) 97 ); 98 99 $equal = false; 100 } 101 } 102 103 foreach ($remaining as $key => $value) { 104 $actString .= sprintf( 105 " %s => %s\n", 106 $this->exporter->export($key), 107 $this->exporter->shortenedExport($value) 108 ); 109 110 $equal = false; 111 } 112 113 $expString .= ')'; 114 $actString .= ')'; 115 116 if (!$equal) { 117 throw new ComparisonFailure( 118 $expected, 119 $actual, 120 $expString, 121 $actString, 122 false, 123 'Failed asserting that two arrays are equal.' 124 ); 125 } 126 } 127 128 protected function indent($lines) 129 { 130 return trim(str_replace("\n", "\n ", $lines)); 131 } 132} 133