Implement ObjectProxy class

This commit is contained in:
Dan Jones 2021-10-15 10:43:30 -05:00
commit d857775289
10 changed files with 417 additions and 79 deletions

View file

@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace Danjones000\Test\Spy;
use Danjones000\Spy\Example;
use Mockery\MockInterface;
class ExampleTest extends TestCase
{
public function testGreet(): void
{
/** @var Example & MockInterface $example */
$example = $this->mockery(Example::class);
$example->shouldReceive('greet')->passthru();
$this->assertSame('Hello, Friends!', $example->greet('Friends'));
}
}

View file

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Danjones000\Test\Spy\Fixtures;
class Example
{
protected const PROT_CONST = 2;
private const PRIV_CONST = 3;
protected static int $protStatic = 4;
private static int $privStatic = 5;
protected int $prot = 6;
private int $priv = 7;
public static function reset(): void
{
static::$protStatic = 4;
static::$privStatic = 5;
}
protected function protMethod(): int
{
return $this->prot;
}
private function privMethod(int $priv): void
{
$this->priv = $priv;
}
protected static function protStatMethod(int $protStatic): void
{
static::$protStatic = $protStatic;
}
private static function privStatMethod(): int
{
return static::$privStatic;
}
}

129
tests/ObjectProxyTest.php Normal file
View file

@ -0,0 +1,129 @@
<?php
declare(strict_types=1);
namespace Danjones000\Test\Spy;
use Danjones000\Spy\ObjectProxy;
use Mockery;
use Mockery\MockInterface;
class ObjectProxyTest extends TestCase
{
protected Fixtures\Example $example;
protected ObjectProxy $spy;
protected ObjectProxy $classSpy;
protected \ReflectionObject $reflection;
protected function setUp(): void
{
parent::setUp();
Fixtures\Example::reset();
$this->example = new Fixtures\Example();
$this->spy = new ObjectProxy($this->example);
$this->classSpy = new ObjectProxy(Fixtures\Example::class);
$this->reflection = new \ReflectionObject($this->example);
}
public function testCallingProtectedMethod(): void
{
$ret = $this->spy->protMethod();
$this->assertEquals(6, $ret);
}
public function testCallPrivateMethod(): void
{
$this->spy->privMethod(42);
$prop = $this->reflection->getProperty('priv');
$prop->setAccessible(true);
$this->assertEquals(42, $prop->getValue($this->example));
}
public function testCallProtectedStaticMethod(): void
{
$this->classSpy->protStatMethod(42);
$prop = $this->reflection->getProperty('protStatic');
$prop->setAccessible(true);
$this->assertEquals(42, $prop->getValue());
}
public function testCallPrivateStaticMethod(): void
{
$ret = $this->classSpy->privStatMethod();
$this->assertEquals(5, $ret);
}
public function testAccessPrivateProperty(): void
{
$this->assertEquals(7, $this->spy->priv);
}
public function testAccessProtectedProperty(): void
{
$this->assertEquals(6, $this->spy->prot);
}
public function testAccessPrivateStaticProperty(): void
{
$this->assertEquals(5, $this->classSpy->privStatic);
}
public function testAccessProtectedStaticProperty(): void
{
$this->assertEquals(4, $this->classSpy->protStatic);
}
public function testAccessPrivateConstantThroughCall(): void
{
$ret = $this->classSpy->call(fn () => static::PRIV_CONST);
$this->assertEquals(3, $ret);
$ret = $this->classSpy->call(fn () => self::PRIV_CONST);
$this->assertEquals(3, $ret);
}
public function testAccessProtectedConstantThroughCall(): void
{
$ret = $this->classSpy->call(fn () => static::PROT_CONST);
$this->assertEquals(2, $ret);
$ret = $this->classSpy->call(fn () => self::PROT_CONST);
$this->assertEquals(2, $ret);
}
public function testModifyPrivateProperty(): void
{
$this->spy->priv = 42;
$prop = $this->reflection->getProperty('priv');
$prop->setAccessible(true);
$this->assertEquals(42, $prop->getValue($this->example));
}
public function testModifyProtectedProperty(): void
{
$this->spy->prot = 42;
$prop = $this->reflection->getProperty('prot');
$prop->setAccessible(true);
$this->assertEquals(42, $prop->getValue($this->example));
}
public function testModifyPrivateStaticProperty(): void
{
$this->classSpy->privStatic = 42;
$prop = $this->reflection->getProperty('privStatic');
$prop->setAccessible(true);
$this->assertEquals(42, $prop->getValue());
}
public function testModifyProtectedStaticProperty(): void
{
$this->classSpy->protStatic = 42;
$prop = $this->reflection->getProperty('protStatic');
$prop->setAccessible(true);
$this->assertEquals(42, $prop->getValue());
}
}