Skip to content

Instantly share code, notes, and snippets.

@malarzm
Last active March 26, 2024 21:18
Show Gist options
  • Save malarzm/e8c6141b510708e52c8535d2a13cd613 to your computer and use it in GitHub Desktop.
Save malarzm/e8c6141b510708e52c8535d2a13cd613 to your computer and use it in GitHub Desktop.
PHPUnit's MemoryGuard
<?php
declare(strict_types=1);
namespace Answear\DevelopmentHelpers\PHPUnit;
use PHPUnit\Framework\Test;
use PHPUnit\Framework\TestListener;
use PHPUnit\Framework\TestListenerDefaultImplementation;
class MemoryGuard implements TestListener
{
use TestListenerDefaultImplementation;
private const PHPUNIT_PROPERTY_PREFIX = 'PHPUnit';
/**
* @var callable
*/
private $unsetter;
public function __construct()
{
$this->unsetter = function ($propertyName) {
unset($this->$propertyName);
};
}
public function endTest(Test $test, float $time): void
{
$this->safelyFreeProperties($test);
}
private function safelyFreeProperties(Test $test): void
{
$testReflection = new \ReflectionObject($test);
foreach ($this->getAllProperties($testReflection) as $property) {
$this->unsetter = $this->unsetter->bindTo($test, $property->getDeclaringClass()->getName());
if ($this->isSafeToFreeProperty($property)) {
($this->unsetter)($property->getName());
}
}
}
private function isSafeToFreeProperty(\ReflectionProperty $property): bool
{
return !$property->isStatic() && $this->isNotPhpUnitProperty($property);
}
private function isNotPhpUnitProperty(\ReflectionProperty $property): bool
{
return 0 !== strpos($property->getDeclaringClass()->getName(), self::PHPUNIT_PROPERTY_PREFIX);
}
/**
* @return \ReflectionProperty[]
*/
private function getAllProperties(\ReflectionObject $object): array
{
$properties = $object->getProperties();
while ($object->getParentClass()) {
$object = $object->getParentClass();
if (0 === strpos($object->getNamespaceName(), self::PHPUNIT_PROPERTY_PREFIX)) {
break;
}
$properties = array_merge($properties, $object->getProperties(\ReflectionProperty::IS_PRIVATE));
}
return $properties;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment