Gergő Tisza has uploaded a new change for review.
https://gerrit.wikimedia.org/r/266188
Change subject: Handle static access in TestingAccessWrapper
......................................................................
Handle static access in TestingAccessWrapper
Change-Id: Ia8ec6ee0a364807e78fc182c4ce99d782b921eda
---
M tests/phpunit/data/helpers/WellProtectedClass.php
M tests/phpunit/includes/TestingAccessWrapper.php
M tests/phpunit/includes/TestingAccessWrapperTest.php
3 files changed, 147 insertions(+), 18 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/88/266188/1
diff --git a/tests/phpunit/data/helpers/WellProtectedClass.php
b/tests/phpunit/data/helpers/WellProtectedClass.php
index a45cfbb..f2b5a14 100644
--- a/tests/phpunit/data/helpers/WellProtectedClass.php
+++ b/tests/phpunit/data/helpers/WellProtectedClass.php
@@ -17,9 +17,20 @@
}
class WellProtectedClass extends WellProtectedParentClass {
+ protected static $staticProperty = 'sp';
+ private static $staticPrivateProperty = 'spp';
+
protected $property;
private $privateProperty;
+ protected static function staticMethod() {
+ return 'sm';
+ }
+
+ private static function staticPrivateMethod() {
+ return 'spm';
+ }
+
public function __construct() {
parent::__construct();
$this->property = 1;
diff --git a/tests/phpunit/includes/TestingAccessWrapper.php
b/tests/phpunit/includes/TestingAccessWrapper.php
index 63d8971..0d5d6f6 100644
--- a/tests/phpunit/includes/TestingAccessWrapper.php
+++ b/tests/phpunit/includes/TestingAccessWrapper.php
@@ -12,36 +12,97 @@
* $formatter = $title->getTitleFormatter();
*
* TODO:
- * - Provide access to static methods and properties.
* - Organize other helper classes in tests/testHelpers.inc into a directory.
*/
class TestingAccessWrapper {
+ /** @var mixed The object, or the class name for static-only access */
public $object;
/**
* Return the same object, without access restrictions.
*/
public static function newFromObject( $object ) {
+ if ( !is_object( $object ) ) {
+ throw new InvalidArgumentException( __METHOD__ . ' must
be called with an object' );
+ }
$wrapper = new TestingAccessWrapper();
$wrapper->object = $object;
return $wrapper;
}
+ /**
+ * Allow access to non-public static methods and properties of the
class.
+ * Use non-static access,
+ */
+ public static function newFromClass( $className ) {
+ if ( !is_string( $className ) ) {
+ throw new InvalidArgumentException( __METHOD__ . ' must
be called with a class name' );
+ }
+ $wrapper = new TestingAccessWrapper();
+ $wrapper->object = $className;
+ return $wrapper;
+ }
+
public function __call( $method, $args ) {
- $classReflection = new ReflectionClass( $this->object );
- $methodReflection = $classReflection->getMethod( $method );
- $methodReflection->setAccessible( true );
- return $methodReflection->invokeArgs( $this->object, $args );
+ $methodReflection = $this->getMethod( $method );
+
+ if ( $this->isStatic() && !$methodReflection->isStatic() ) {
+ throw new DomainException( __METHOD__ . ': Cannot call
non-static when wrapping static class' );
+ }
+
+ return $methodReflection->invokeArgs(
$methodReflection->isStatic() ? null : $this->object, $args );
+ }
+
+ public function __set( $name, $value ) {
+ $propertyReflection = $this->getProperty( $name );
+
+ if ( $this->isStatic() && !$propertyReflection->isStatic() ) {
+ throw new DomainException( __METHOD__ . ': Cannot set
property when wrapping static class' );
+ }
+
+ $propertyReflection->setValue( $this->object, $value );
+ }
+
+ public function __get( $name ) {
+ $propertyReflection = $this->getProperty( $name );
+
+ if ( $this->isStatic() && !$propertyReflection->isStatic() ) {
+ throw new DomainException( __METHOD__ . ': Cannot get
property when wrapping static class' );
+ }
+
+ return $propertyReflection->getValue( $this->object );
+ }
+
+ private function isStatic() {
+ return is_string( $this->object );
}
/**
+ * Return a property and make it accessible.
+ * @param string $name
+ * @return ReflectionMethod
+ */
+ private function getMethod( $name ) {
+ $classReflection = new ReflectionClass( $this->object );
+ $methodReflection = $classReflection->getMethod( $name );
+ $methodReflection->setAccessible( true );
+ return $methodReflection;
+ }
+
+ /**
+ * Return a property and make it accessible.
+ *
* ReflectionClass::getProperty() fails if the private property is
defined
* in a parent class. This works more like ReflectionClass::getMethod().
+ *
+ * @param string $name
+ * @return ReflectionProperty
+ * @throws ReflectionException
*/
private function getProperty( $name ) {
$classReflection = new ReflectionClass( $this->object );
try {
- return $classReflection->getProperty( $name );
+ $propertyReflection = $classReflection->getProperty(
$name );
} catch ( ReflectionException $ex ) {
while ( true ) {
$classReflection =
$classReflection->getParentClass();
@@ -54,23 +115,13 @@
continue;
}
if ( $propertyReflection->isPrivate() ) {
- return $propertyReflection;
+ break;
} else {
throw $ex;
}
}
}
- }
-
- public function __set( $name, $value ) {
- $propertyReflection = $this->getProperty( $name );
$propertyReflection->setAccessible( true );
- $propertyReflection->setValue( $this->object, $value );
- }
-
- public function __get( $name ) {
- $propertyReflection = $this->getProperty( $name );
- $propertyReflection->setAccessible( true );
- return $propertyReflection->getValue( $this->object );
+ return $propertyReflection;
}
}
diff --git a/tests/phpunit/includes/TestingAccessWrapperTest.php
b/tests/phpunit/includes/TestingAccessWrapperTest.php
index fc54afa..23eb023 100644
--- a/tests/phpunit/includes/TestingAccessWrapperTest.php
+++ b/tests/phpunit/includes/TestingAccessWrapperTest.php
@@ -3,6 +3,7 @@
class TestingAccessWrapperTest extends MediaWikiTestCase {
protected $raw;
protected $wrapped;
+ protected $wrappedStatic;
function setUp() {
parent::setUp();
@@ -10,12 +11,38 @@
require_once __DIR__ .
'/../data/helpers/WellProtectedClass.php';
$this->raw = new WellProtectedClass();
$this->wrapped = TestingAccessWrapper::newFromObject(
$this->raw );
+ $this->wrappedStatic = TestingAccessWrapper::newFromClass(
'WellProtectedClass' );
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testConstructorException() {
+ TestingAccessWrapper::newFromObject( 'WellProtectedClass' );
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testStaticConstructorException() {
+ TestingAccessWrapper::newFromClass( new WellProtectedClass() );
}
function testGetProperty() {
$this->assertSame( 1, $this->wrapped->property );
$this->assertSame( 42, $this->wrapped->privateProperty );
$this->assertSame( 9000, $this->wrapped->privateParentProperty
);
+ $this->assertSame( 'sp', $this->wrapped->staticProperty );
+ $this->assertSame( 'spp', $this->wrapped->staticPrivateProperty
);
+ $this->assertSame( 'sp', $this->wrappedStatic->staticProperty );
+ $this->assertSame( 'spp',
$this->wrappedStatic->staticPrivateProperty );
+ }
+
+ /**
+ * @expectedException DomainException
+ */
+ function testGetException() {
+ $this->wrappedStatic->property;
}
function testSetProperty() {
@@ -30,6 +57,33 @@
$this->wrapped->privateParentProperty = 12;
$this->assertSame( 12, $this->wrapped->privateParentProperty );
$this->assertSame( 12, $this->raw->getPrivateParentProperty() );
+
+ $this->wrapped->staticProperty = 'x';
+ $this->assertSame( 'x', $this->wrapped->staticProperty );
+ $this->assertSame( 'x', $this->wrappedStatic->staticProperty );
+
+ $this->wrapped->staticPrivateProperty = 'y';
+ $this->assertSame( 'y', $this->wrapped->staticPrivateProperty );
+ $this->assertSame( 'y',
$this->wrappedStatic->staticPrivateProperty );
+
+ $this->wrappedStatic->staticProperty = 'X';
+ $this->assertSame( 'X', $this->wrapped->staticProperty );
+ $this->assertSame( 'X', $this->wrappedStatic->staticProperty );
+
+ $this->wrappedStatic->staticPrivateProperty = 'Y';
+ $this->assertSame( 'Y', $this->wrapped->staticPrivateProperty );
+ $this->assertSame( 'Y',
$this->wrappedStatic->staticPrivateProperty );
+
+ // don't rely on PHPUnit to restore static properties
+ $this->wrapped->staticProperty = 'sp';
+ $this->wrapped->staticPrivateProperty = 'spp';
+ }
+
+ /**
+ * @expectedException DomainException
+ */
+ function testSetException() {
+ $this->wrappedStatic->property = 1;
}
function testCallMethod() {
@@ -44,9 +98,22 @@
$this->wrapped->incrementPrivateParentPropertyValue();
$this->assertSame( 9001, $this->wrapped->privateParentProperty
);
$this->assertSame( 9001, $this->raw->getPrivateParentProperty()
);
+
+ $this->assertSame( 'sm', $this->wrapped->staticMethod() );
+ $this->assertSame( 'spm', $this->wrapped->staticPrivateMethod()
);
+ $this->assertSame( 'sm', $this->wrappedStatic->staticMethod() );
+ $this->assertSame( 'spm',
$this->wrappedStatic->staticPrivateMethod() );
}
function testCallMethodTwoArgs() {
$this->assertSame( 'two', $this->wrapped->whatSecondArg( 'one',
'two' ) );
}
+
+ /**
+ * @expectedException DomainException
+ */
+ function testCallMethodException() {
+ $this->wrappedStatic->incrementPropertyValue();
+ }
+
}
--
To view, visit https://gerrit.wikimedia.org/r/266188
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia8ec6ee0a364807e78fc182c4ce99d782b921eda
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Gergő Tisza <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits