-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replaced PHPUnit_Framework_Constraint_IsEqual::recursiveComparison() …
…with a comparator sub-component This sub-component has three final goals: * Allow end-users to override the comparison mechanism for specific data types. This is especially interesting when classes have internal, random property values (for example generated tokens or IDs) that should be ignored when comparing two objects. This goal is achieved by this commit. You can implement a custom extension of PHPUnit_Framework_Comparator and register it by passing it to PHPUnit_Framework_Comparator::register(). Look at the source of the existing comparators for more inspiration. * Currently, PHPUnit fails to print the difference between very large object trees. These trees are converted to strings using print_r(), which fails to export such large trees and leads to segmentation faults. You can reproduce this behaviour by passing two unequal Doctrine_Record[1] instances to assertEquals(). This goal will be achieved in a future commit. * Currently, the diff output for large object trees is very hard to use, because the diff contains much more information than necessary to inspect the error. Because comparators throw PHPUnit_Framework_ComparisonFailure instances when they fail, they can also provide a lot of information about where exactly the comparison failed. This goal will also be achieved in a future commit. [1] http://www.doctrine-project.org
- Loading branch information
Bernhard Schussek
committed
Jun 14, 2011
1 parent
5937d9a
commit d38ea8f
Showing
19 changed files
with
1,338 additions
and
178 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
<?php | ||
/** | ||
* PHPUnit | ||
* | ||
* Copyright (c) 2002-2011, Sebastian Bergmann <sebastian@phpunit.de>. | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* * Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* * Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in | ||
* the documentation and/or other materials provided with the | ||
* distribution. | ||
* | ||
* * Neither the name of Sebastian Bergmann nor the names of his | ||
* contributors may be used to endorse or promote products derived | ||
* from this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
* | ||
* @package PHPUnit | ||
* @subpackage Framework | ||
* @author Bernhard Schussek <bschussek@gmail.com> | ||
* @copyright 2002-2011 Sebastian Bergmann <sebastian@phpunit.de> | ||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License | ||
* @link http://www.phpunit.de/ | ||
* @since File available since Release 3.6.0 | ||
*/ | ||
|
||
/** | ||
* Abstract base class for comparators which compare values for equality. | ||
* | ||
* @package PHPUnit | ||
* @subpackage Framework | ||
* @author Bernhard Schussek <bschussek@gmail.com> | ||
* @copyright 2002-2011 Sebastian Bergmann <sebastian@phpunit.de> | ||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License | ||
* @version Release: @package_version@ | ||
* @link http://www.phpunit.de/ | ||
* @since Class available since Release 3.6.0 | ||
*/ | ||
abstract class PHPUnit_Framework_Comparator | ||
{ | ||
/** | ||
* @var array | ||
*/ | ||
protected static $comparators = array(); | ||
|
||
/** | ||
* Returns the correct comparator for comparing two values. | ||
* | ||
* @param mixed $a The first value to compare | ||
* @param mixed $b The second value to compare | ||
* @return PHPUnit_Framework_Comparator | ||
* @since Method available since Release 3.0.0 | ||
*/ | ||
public static function getInstance($a, $b) | ||
{ | ||
foreach (self::$comparators as $comparator) { | ||
if ($comparator->accepts($a, $b)) { | ||
return $comparator; | ||
} | ||
} | ||
|
||
throw new InvalidArgumentException(sprintf('No comparator is registered for comparing the types "%s" and "%s"', gettype($a), gettype($b))); | ||
} | ||
|
||
/** | ||
* Registers a new comparator. | ||
* | ||
* This comparator will be returned by getInstance() if its accept() method | ||
* returns TRUE for the compared values. It has higher priority than the | ||
* existing comparators, meaning that its accept() method will be tested | ||
* before those of the other comparators. | ||
* | ||
* @param PHPUnit_Framework_Comparator $comparator The registered comparator | ||
* @since Method available since Release 3.0.0 | ||
*/ | ||
public static function register(PHPUnit_Framework_Comparator $comparator) | ||
{ | ||
array_unshift(self::$comparators, $comparator); | ||
} | ||
|
||
/** | ||
* Unregisters a comparator. | ||
* | ||
* This comparator will no longer be returned by getInstance(). | ||
* | ||
* @param PHPUnit_Framework_Comparator $comparator The unregistered comparator | ||
* @since Method available since Release 3.0.0 | ||
*/ | ||
public static function unregister(PHPUnit_Framework_Comparator $comparator) | ||
{ | ||
if (false !== ($key = array_search($comparator, self::$comparators, true))) | ||
{ | ||
unset(self::$comparators[$key]); | ||
} | ||
} | ||
|
||
/** | ||
* Returns whether the comparator can compare two values. | ||
* | ||
* @param mixed $a The first value to compare | ||
* @param mixed $b The second value to compare | ||
* @return boolean | ||
* @since Method available since Release 3.0.0 | ||
*/ | ||
abstract public function accepts($a, $b); | ||
|
||
/** | ||
* Asserts that two values are equal. | ||
* | ||
* @param mixed $a The first value to compare | ||
* @param mixed $b The second value to compare | ||
* @param float $delta The allowed numerical distance between two values to | ||
* consider them equal | ||
* @param bool $canonicalize If set to TRUE, arrays are sorted before | ||
* comparison | ||
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is | ||
* ignored when comparing string values | ||
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison | ||
* fails. Contains information about the | ||
* specific errors that lead to the failure. | ||
* @since Method available since Release 3.0.0 | ||
*/ | ||
abstract public function assertEquals($a, $b, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
<?php | ||
/** | ||
* PHPUnit | ||
* | ||
* Copyright (c) 2002-2011, Sebastian Bergmann <sebastian@phpunit.de>. | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* * Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* * Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in | ||
* the documentation and/or other materials provided with the | ||
* distribution. | ||
* | ||
* * Neither the name of Sebastian Bergmann nor the names of his | ||
* contributors may be used to endorse or promote products derived | ||
* from this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
* | ||
* @package PHPUnit | ||
* @subpackage Framework | ||
* @author Bernhard Schussek <bschussek@gmail.com> | ||
* @copyright 2002-2011 Sebastian Bergmann <sebastian@phpunit.de> | ||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License | ||
* @link http://www.phpunit.de/ | ||
* @since File available since Release 3.6.0 | ||
*/ | ||
|
||
/** | ||
* Compares arrays for equality. | ||
* | ||
* @package PHPUnit | ||
* @subpackage Framework_Comparator | ||
* @author Bernhard Schussek <bschussek@gmail.com> | ||
* @copyright 2002-2011 Sebastian Bergmann <sebastian@phpunit.de> | ||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License | ||
* @version Release: @package_version@ | ||
* @link http://www.phpunit.de/ | ||
* @since Class available since Release 3.6.0 | ||
*/ | ||
class PHPUnit_Framework_Comparator_Array extends PHPUnit_Framework_Comparator | ||
{ | ||
/** | ||
* Returns whether the comparator can compare two values. | ||
* | ||
* @param mixed $a The first value to compare | ||
* @param mixed $b The second value to compare | ||
* @return boolean | ||
* @since Method available since Release 3.6.0 | ||
*/ | ||
public function accepts($a, $b) | ||
{ | ||
return is_array($a) && is_array($b); | ||
} | ||
|
||
/** | ||
* Asserts that two values are equal. | ||
* | ||
* @param mixed $a The first value to compare | ||
* @param mixed $b The second value to compare | ||
* @param float $delta The allowed numerical distance between two values to | ||
* consider them equal | ||
* @param bool $canonicalize If set to TRUE, arrays are sorted before | ||
* comparison | ||
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is | ||
* ignored when comparing string values | ||
* @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison | ||
* fails. Contains information about the | ||
* specific errors that lead to the failure. | ||
* @since Method available since Release 3.6.0 | ||
*/ | ||
public function assertEquals($a, $b, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE, array &$processed = array()) | ||
{ | ||
$remaining = $b; | ||
|
||
if ($canonicalize) { | ||
sort($a); | ||
sort($b); | ||
} | ||
|
||
foreach ($a as $key => $value) { | ||
if (!isset($b[$key])) { | ||
throw new PHPUnit_Framework_ComparisonFailure($a/*->dumpExcerpt($key, $comparator)*/, $b); | ||
} | ||
|
||
try { | ||
self::getInstance($value, $b[$key])->assertEquals($value, $b[$key], $delta, $canonicalize, $ignoreCase, $processed); | ||
} | ||
|
||
catch (PHPUnit_Framework_ComparisonFailure $e) { | ||
throw new PHPUnit_Framework_ComparisonFailure($a/*->dumpExcerpt($key, $e->getExpected())*/, $b/*->dumpExcerpt($key, $e->getActual())*/); | ||
} | ||
|
||
unset($remaining[$key]); | ||
} | ||
|
||
foreach ($remaining as $key => $value) { | ||
throw new PHPUnit_Framework_ComparisonFailure($a, $b/*->dumpExcerpt($key, $value)*/); | ||
} | ||
} | ||
|
||
protected function dumpAll() | ||
{ | ||
$result = $this->getType().' ('; | ||
|
||
if (!empty($this->value)) { | ||
$result .= "\n"; | ||
|
||
foreach ($this->value as $k => $v) { | ||
$result .= sprintf(" %s => %s,\n", var_export($k, true), $this->indent($v)); | ||
} | ||
} | ||
|
||
$result .= ')'; | ||
|
||
return $result; | ||
} | ||
|
||
protected function dumpExcerpt($key = null, $value = null) | ||
{ | ||
$result = $this->getType().' ('; | ||
|
||
if (!empty($this->value)) { | ||
$truncated = false; | ||
$result .= "\n"; | ||
|
||
foreach ($this->value as $k => $v) { | ||
if ((is_null($key) || $key !== $k) && !$truncated) { | ||
$result .= " ...\n"; | ||
$truncated = true; | ||
} | ||
else if ($k === $key) { | ||
$value = null === $value | ||
? $v | ||
: ($value instanceof PHPUnit_Framework_SelfDescribing ? $value->toString() : $value); | ||
$result .= sprintf(" %s => %s,\n", var_export($k, true), $this->indent($value)); | ||
$truncated = false; | ||
} | ||
} | ||
} | ||
|
||
$result .= ')'; | ||
|
||
return $result; | ||
} | ||
|
||
protected function indent($lines) | ||
{ | ||
$lines = explode("\n", $lines); | ||
|
||
foreach ($lines as $key => $line) { | ||
$lines[$key] = ' '.$line; | ||
} | ||
|
||
return trim(implode("\n", $lines)); | ||
} | ||
} |
Oops, something went wrong.