Last active
June 8, 2018 21:20
-
-
Save gskema/afd0d83a442f7760f89f18ab66e16769 to your computer and use it in GitHub Desktop.
Automatic PHPUnit test for object cloning ::__clone()
This file contains hidden or 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
<?php | |
use PHPUnit\Framework\TestCase; | |
class CloneTest extends TestCase | |
{ | |
/** | |
* @dataProvider testClone | |
* | |
* @param object $obj0 | |
* @throws ReflectionException | |
*/ | |
public function testClone(object $obj0) | |
{ | |
$obj1 = clone $obj0; | |
$ref = (new ReflectionClass($obj0)); | |
$className = $ref->getName(); | |
$shortClassName = $ref->getShortName(); | |
$properties = $ref->getProperties(); | |
if (empty($properties)) { | |
$this->assertTrue(true); | |
} | |
foreach ($properties as $property) { | |
$property->setAccessible(true); | |
$propName = $property->getName(); | |
$val0 = $property->getValue($obj0); | |
$val1 = $property->getValue($obj1); | |
$this->assertEquals($val0, $val1, sprintf( | |
'Expected %s:$%s to be equal after cloning', | |
$className, | |
$propName | |
)); | |
$this->assertNotHashEquals($val0, $val1, sprintf('property "%s"', $propName)); | |
if (is_array($val0) && is_array($val1)) { | |
$this->assertNotArrayHashEquals($val0, $val1, $shortClassName.'::$'.$propName); | |
} | |
} | |
} | |
protected function assertNotHashEquals($value1, $value2, string $propertyText) | |
{ | |
$hash0 = is_object($value1) ? md5(spl_object_hash($value1)) : null; | |
$hash1 = is_object($value2) ? md5(spl_object_hash($value2)) : null; | |
if ($hash0 && $hash1) { | |
$this->assertNotEquals($hash0, $hash1, sprintf( | |
'Expected %s to have different spl_object_hash()', | |
$propertyText | |
)); | |
} | |
} | |
protected function assertNotArrayHashEquals(array $array1, array $array2, string $path) | |
{ | |
foreach ($array1 as $key => $val1) { | |
$subPath = $path ? $path.'['.$key.']' : null; | |
$val2 = $array2[$key] ?? null; | |
if (is_array($val1) && is_array($val2)) { | |
$this->assertNotArrayHashEquals($val1, $val2, $subPath); | |
} elseif (is_object($val1) && is_object($val2)) { | |
$this->assertNotHashEquals($val1, $val2, sprintf('array property "%s"', $subPath)); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment