Addshore has uploaded a new change for review. https://gerrit.wikimedia.org/r/230765
Change subject: Use EntityRedirectResolvingDecorator from DataModelServices ...................................................................... Use EntityRedirectResolvingDecorator from DataModelServices Change-Id: Id19341206c494a2c83f25a75b6b3da428527ee66 --- D lib/includes/store/EntityRedirectResolvingDecorator.php M lib/includes/store/RedirectResolvingEntityLookup.php D lib/tests/phpunit/store/EntityRedirectResolvingDecoratorTest.php 3 files changed, 1 insertion(+), 240 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase refs/changes/65/230765/1 diff --git a/lib/includes/store/EntityRedirectResolvingDecorator.php b/lib/includes/store/EntityRedirectResolvingDecorator.php deleted file mode 100644 index 986d88f..0000000 --- a/lib/includes/store/EntityRedirectResolvingDecorator.php +++ /dev/null @@ -1,94 +0,0 @@ -<?php - -namespace Wikibase\Lib\Store; - -use InvalidArgumentException; -use Wikibase\DataModel\Entity\EntityId; - -/** - * Generic decorator class for transparently resolving EntityRedirects. - * - * This is done by delegating calls to a target object while adding a kind of - * "retry" logic to any method that has an EntityId as its first parameter and - * throws an UnresolvedRedirectException when that EntityId refers to a redirect. - * - * This effectively adds transparent redirect resolution to all methods of the - * target object. - * - * @since 0.5 - * - * @licence GNU GPL v2+ - * @author Daniel Kinzler - */ -class EntityRedirectResolvingDecorator { - - /** - * @var object - */ - private $targetObject; - - /** - * @var int The maximum number of redirects to follow - */ - private $maxResolutionDepth; - - /** - * Constructs a decorator for the given target object. The resulting proxy - * object supports all methods of the target object, but does not formally implement - * any interface. - * - * The decorator is effective for any method that takes an EntityId as its first parameter, - * and throws an UnresolvedRedirectException when that EntityId refers to a redirect. - * - * @param object $targetObject The object to attach the redirect resolution decorator to. - * Typically an EntityLookup or EntityRevisionLookup. - * - * @param int $maxResolutionDepth The maximum number of redirect levels to resolve - * on each function call. - * - * @throws InvalidArgumentException - */ - public function __construct( $targetObject, $maxResolutionDepth = 1 ) { - if ( !is_object( $targetObject ) ) { - throw new InvalidArgumentException( '$target must be an object' ); - } - - if ( !is_int( $maxResolutionDepth ) || $maxResolutionDepth < 0 ) { - throw new InvalidArgumentException( '$maxResolutionDepth must be a positive integer' ); - } - - $this->targetObject = $targetObject; - $this->maxResolutionDepth = $maxResolutionDepth; - } - - /** - * Method invocation handler which delegates calls to the target object supplied to - * the constructor. This adds a kind of "retry" logic to any method that has an - * EntityId as its first parameter and throws an UnresolvedRedirectException when a - * redirect is encountered. - * - * This essentially adds transparent redirect resolution to the respective methods of the - * target object. - */ - public function __call( $name, $arguments ) { - $retries = $this->maxResolutionDepth; - - do { - try { - $method = array( $this->targetObject, $name ); - return call_user_func_array( $method, $arguments ); - } catch ( UnresolvedRedirectException $ex ) { - // If the first argument was an EntityId, replace it and retry. - // Otherwise, give up. - if ( !isset( $arguments[0] ) || !( $arguments[0] instanceof EntityId ) ) { - break; - } - - $arguments[0] = $ex->getRedirectTargetId(); - } - } while ( $retries-- ); - - throw $ex; - } - -} diff --git a/lib/includes/store/RedirectResolvingEntityLookup.php b/lib/includes/store/RedirectResolvingEntityLookup.php index e7da7d3..1a5c503 100644 --- a/lib/includes/store/RedirectResolvingEntityLookup.php +++ b/lib/includes/store/RedirectResolvingEntityLookup.php @@ -4,6 +4,7 @@ use Wikibase\DataModel\Entity\EntityDocument; use Wikibase\DataModel\Entity\EntityId; +use Wikibase\DataModel\Services\Entity\EntityRedirectResolvingDecorator; use Wikibase\DataModel\Services\Lookup\EntityLookup; /** diff --git a/lib/tests/phpunit/store/EntityRedirectResolvingDecoratorTest.php b/lib/tests/phpunit/store/EntityRedirectResolvingDecoratorTest.php deleted file mode 100644 index 1de7c0f..0000000 --- a/lib/tests/phpunit/store/EntityRedirectResolvingDecoratorTest.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php - -namespace Wikibase\Lib\Test\Store; - -use RuntimeException; -use Wikibase\DataModel\Entity\EntityId; -use Wikibase\DataModel\Entity\Item; -use Wikibase\DataModel\Entity\ItemId; -use Wikibase\EntityRevision; -use Wikibase\Lib\Store\EntityRedirectResolvingDecorator; -use Wikibase\Lib\Store\EntityRevisionLookup; -use Wikibase\Lib\Store\UnresolvedRedirectException; -use Wikibase\PropertyLabelResolver; - -/** - * @covers Wikibase\Lib\Store\EntityRedirectResolvingDecorator - * - * @group WikibaseLib - * @group Wikibase - * - * @licence GNU GPL v2+ - * @author Daniel Kinzler - */ -class EntityRedirectResolvingDecoratorTest extends \PHPUnit_Framework_TestCase { - - public function constructionErrorProvider() { - return array( - array( '', 1 ), - array( null, 1 ), - array( new ItemId( 'Q7' ), -3 ), - array( new ItemId( 'Q7' ), null ), - ); - } - - /** - * @dataProvider constructionErrorProvider - */ - public function testConstructionError( $target, $levels ) { - $this->setExpectedException( 'InvalidArgumentException' ); - - new EntityRedirectResolvingDecorator( $target, $levels ); - } - - public function getEntityRevision( EntityId $id ) { - if ( $id->getSerialization() === 'Q1' ) { - throw new UnresolvedRedirectException( new ItemId( 'Q5' ) ); - } - - if ( $id->getSerialization() === 'Q5' ) { - throw new UnresolvedRedirectException( new ItemId( 'Q10' ) ); - } - - return new EntityRevision( new Item( $id ), 777 ); - } - - private function getEntityRevisionLookup() { - $lookup = $this->getMock( 'Wikibase\Lib\Store\EntityRevisionLookup' ); - - $lookup->expects( $this->any() ) - ->method( 'getEntityRevision' ) - ->will( $this->returnCallback( array( $this, 'getEntityRevision' ) ) ); - - return $lookup; - } - - public function redirectResolutionProvider() { - // Redirects as per $this->getEntityRevision: - // Q1 -> Q5 -> Q10 - - $q1 = new ItemId( 'Q1' ); - $q5 = new ItemId( 'Q5' ); - $q10 = new ItemId( 'Q10' ); - - return array( - 'no redirect' => array( $q10, 1, $q10 ), - 'redirect resolved' => array( $q5, 1, $q10 ), - 'double redirect resolved' => array( $q1, 2, $q10 ), - ); - } - - /** - * @dataProvider redirectResolutionProvider - */ - public function testRedirectResolution( EntityId $id, $levels, EntityId $expected ) { - $target = $this->getEntityRevisionLookup(); - - /* @var EntityRevisionLookup $decorator */ - $decorator = new EntityRedirectResolvingDecorator( $target, $levels ); - $revision = $decorator->getEntityRevision( $id ); - - $this->assertEquals( $expected, $revision->getEntity()->getId() ); - } - - public function redirectResolutionFailureProvider() { - // Redirects as per $this->getEntityRevision: - // Q1 -> Q5 -> Q10 - - $q1 = new ItemId( 'Q1' ); - $q5 = new ItemId( 'Q5' ); - - return array( - 'zero levels' => array( $q5, 0 ), - 'double redirect' => array( $q1, 1 ), - ); - } - - /** - * @dataProvider redirectResolutionFailureProvider - */ - public function testRedirectResolutionFailure( EntityId $id, $levels ) { - $target = $this->getEntityRevisionLookup(); - - $this->setExpectedException( 'Wikibase\Lib\Store\UnresolvedRedirectException' ); - - /* @var EntityRevisionLookup $decorator */ - $decorator = new EntityRedirectResolvingDecorator( $target, $levels ); - $decorator->getEntityRevision( $id ); - } - - public function testNoEntityId() { - $target = $this->getMock( 'Wikibase\PropertyLabelResolver' ); - $target->expects( $this->once() ) - ->method( 'getPropertyIdsForLabels' ) - ->will( $this->throwException( new UnresolvedRedirectException( new ItemId( 'Q12' ) ) ) ); - - $this->setExpectedException( 'Wikibase\Lib\Store\UnresolvedRedirectException' ); - - /* @var PropertyLabelResolver $decorator */ - $decorator = new EntityRedirectResolvingDecorator( $target ); - $decorator->getPropertyIdsForLabels( array( 'foo' ) ); - } - - public function testError() { - $target = $this->getMock( 'Wikibase\PropertyLabelResolver' ); - $target->expects( $this->once() ) - ->method( 'getPropertyIdsForLabels' ) - ->will( $this->throwException( new RuntimeException( 'Boo!' ) ) ); - - $this->setExpectedException( 'RuntimeException' ); - - /* @var PropertyLabelResolver $decorator */ - $decorator = new EntityRedirectResolvingDecorator( $target ); - $decorator->getPropertyIdsForLabels( array( 'foo' ) ); - } - -} -- To view, visit https://gerrit.wikimedia.org/r/230765 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id19341206c494a2c83f25a75b6b3da428527ee66 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Addshore <addshorew...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits