banker/tests/Friend.php

134 lines
2.8 KiB
PHP
Raw Permalink Normal View History

2016-10-19 09:57:06 -04:00
<?php declare(strict_types=1);
/**
* Banker
*
* A Caching library implementing psr/cache (PSR 6) and psr/simple-cache (PSR 16)
2016-10-19 09:57:06 -04:00
*
2021-11-30 11:56:15 -05:00
* PHP version 8+
2016-10-19 09:57:06 -04:00
*
* @package Banker
* @author Timothy J. Warren <tim@timshomepage.net>
2023-03-16 13:09:36 -04:00
* @copyright 2016 - 2023 Timothy J. Warren
2016-10-19 09:57:06 -04:00
* @license http://www.opensource.org/licenses/mit-license.html MIT License
2023-03-16 16:24:11 -04:00
* @version 4.1.1
2016-10-19 09:57:06 -04:00
* @link https://git.timshomepage.net/timw4mail/banker
*/
2016-09-06 17:03:43 -04:00
namespace Aviat\Banker\Tests;
2021-11-30 13:47:51 -05:00
use Exception;
2016-09-06 17:03:43 -04:00
use ReflectionClass;
2021-11-30 13:47:51 -05:00
use ReflectionException;
2016-09-06 17:03:43 -04:00
use ReflectionMethod;
use ReflectionProperty;
use InvalidArgumentException;
use BadMethodCallException;
/**
* Friend class for testing
*/
class Friend {
/**
* Object to create a friend of
*/
2021-11-30 13:47:51 -05:00
private mixed $_friend_;
2016-09-06 17:03:43 -04:00
/**
* Reflection class of the object
*/
2021-11-30 13:47:51 -05:00
private mixed $_reflect_;
2016-09-06 17:03:43 -04:00
/**
* Create a friend object
*
* @param object $obj
2021-11-30 13:47:51 -05:00
* @throws InvalidArgumentException|ReflectionException
2016-09-06 17:03:43 -04:00
*/
2021-11-30 13:47:51 -05:00
public function __construct(mixed $obj)
2016-09-06 17:03:43 -04:00
{
if ( ! is_object($obj))
{
throw new InvalidArgumentException("Friend must be an object");
}
$this->_friend_ = $obj;
$this->_reflect_ = new ReflectionClass($obj);
}
/**
* Retrieve a friend's property
*
* @param string $key
* @return mixed
*/
2021-11-30 13:47:51 -05:00
public function __get(string $key): mixed
2016-09-06 17:03:43 -04:00
{
if ($this->_reflect_->hasProperty($key))
{
$property = $this->_get_property($key);
return $property->getValue($this->_friend_);
}
return NULL;
}
/**
* Set a friend's property
*
* @param string $key
* @param mixed $value
* @return void
*/
2021-11-30 13:47:51 -05:00
public function __set(string $key, mixed $value): void
2016-09-06 17:03:43 -04:00
{
if ($this->_reflect_->hasProperty($key))
{
$property = $this->_get_property($key);
$property->setValue($this->_friend_, $value);
}
}
/**
* Calls a protected or private method on the friend
*
2021-11-30 13:47:51 -05:00
* @param string $method
* @param array $args
2016-09-06 17:03:43 -04:00
* @return mixed
* @throws BadMethodCallException
2021-11-30 13:47:51 -05:00
* @throws ReflectionException
2016-09-06 17:03:43 -04:00
*/
2021-11-30 13:47:51 -05:00
public function __call(string $method, array $args): mixed
2016-09-06 17:03:43 -04:00
{
if ( ! $this->_reflect_->hasMethod($method))
{
throw new BadMethodCallException("Method '{$method}' does not exist");
}
$friendMethod = new ReflectionMethod($this->_friend_, $method);
$friendMethod->setAccessible(TRUE);
return $friendMethod->invokeArgs($this->_friend_, $args);
}
/**
* Iterates over parent classes to get a ReflectionProperty
*
* @codeCoverageIgnore
* @param string $name
* @return ReflectionProperty|null
*/
2021-11-30 13:47:51 -05:00
private function _get_property(string $name): ?ReflectionProperty
2016-09-06 17:03:43 -04:00
{
try
{
$property = $this->_reflect_->getProperty($name);
$property->setAccessible(TRUE);
return $property;
}
// Return NULL on any exception, so no further logic needed
// in the catch block
2021-11-30 13:47:51 -05:00
catch (Exception)
2016-09-06 17:03:43 -04:00
{
return NULL;
}
}
}