Daniel Kinzler has uploaded a new change for review. https://gerrit.wikimedia.org/r/83816
Change subject: (bug 52799) Introducing dumpJson. ...................................................................... (bug 52799) Introducing dumpJson. This allows JSON dumps to be created for all entities. This is a baseline implementation. In later changes, this will be extended to allow for entities to be filtered by type, ids to be loaded from file, etc. Change-Id: I09eaa2a7b6fa9cb6a5ffc57b5f28c30e93d79f8b --- M lib/WikibaseLib.classes.php A lib/includes/Dumpers/JsonDumpGenerator.php A lib/tests/phpunit/Dumpers/JsonDumpGeneratorTest.php M repo/Wikibase.classes.php M repo/includes/store/EntityPerPage.php A repo/includes/store/sql/ConvertingResultWrapper.php A repo/includes/store/sql/DatabaseRowEntityIdIterator.php M repo/includes/store/sql/EntityPerPageTable.php A repo/maintenance/dumpJson.php A repo/tests/phpunit/includes/store/sql/DatabaseRowEntityIdIteratorTest.php A repo/tests/phpunit/includes/store/sql/EntityPerPageTableTest.php 11 files changed, 782 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase refs/changes/16/83816/1 diff --git a/lib/WikibaseLib.classes.php b/lib/WikibaseLib.classes.php index f63ede2..af37853 100644 --- a/lib/WikibaseLib.classes.php +++ b/lib/WikibaseLib.classes.php @@ -85,6 +85,9 @@ 'Wikibase\EntityDiffVisualizer' => 'includes/EntityDiffVisualizer.php', 'Wikibase\EntityFactory' => 'includes/EntityFactory.php', + // includes/Dumpers + 'Wikibase\Dumpers\JsonDumpGenerator' => 'includes/Dumpers/JsonDumpGenerator.php', + // includes/formatters 'Wikibase\Lib\EntityIdFormatter' => 'includes/formatters/EntityIdFormatter.php', 'Wikibase\Lib\EntityIdLabelFormatter' => 'includes/formatters/EntityIdLabelFormatter.php', diff --git a/lib/includes/Dumpers/JsonDumpGenerator.php b/lib/includes/Dumpers/JsonDumpGenerator.php new file mode 100644 index 0000000..20f007f --- /dev/null +++ b/lib/includes/Dumpers/JsonDumpGenerator.php @@ -0,0 +1,144 @@ +<?php + +namespace Wikibase\Dumpers; +use MWException; +use Traversable; +use Wikibase\DataModel\Entity\EntityId; +use Wikibase\EntityLookup; +use Wikibase\Lib\Serializers\Serializer; +use Wikibase\StorageException; + +/** + * JsonDumpGenerator generates an JSON dump of a given set of entities. + * + * @since 0.5 + * + * @license GPL 2+ + * @author Daniel Kinzler + */ +class JsonDumpGenerator { + + /** + * @var int flags to use with json_encode as a bit field, see PHP's JSON_XXX constants. + */ + public $jsonFlags = 0; + + /** + * @var resource File handle for output + */ + protected $out; + + /** + * @var Serializer + */ + protected $entitySerializer; + + /** + * @var EntityLookup + */ + protected $entityLookup; + + /** + * @param resource $out + * @param \Wikibase\EntityLookup $lookup + * @param Serializer $entitySerializer + * + * @throws \InvalidArgumentException + */ + public function __construct( $out, EntityLookup $lookup, Serializer $entitySerializer ) { + if ( !is_resource( $out ) ) { + throw new \InvalidArgumentException( '$out must be a file handle!' ); + } + + $this->out = $out; + $this->entitySerializer = $entitySerializer; + $this->entityLookup = $lookup; + } + + /** + * Generates a JSON dump, writing to the file handle provided to the constructor. + * + * @param Traversable $idStream an Iterator that returns EntityId instances + */ + public function generateDump( Traversable $idStream ) { + + $json = "[\n"; //TODO: make optional + $this->writeToDump( $json ); + + $i = 0; + + /* @var EntityId $id */ + foreach ( $idStream as $id ) { + try { + if ( $i++ > 0 ) { + $this->writeToDump( ",\n" ); + } + + $entity = $this->entityLookup->getEntity( $id ); + $data = $this->entitySerializer->getSerialized( $entity ); + $json = $this->encode( $data ); + $this->writeToDump( $json ); + } catch ( StorageException $ex ) { + $this->handleStorageException( $ex ); + } + } + + $json = "]\n"; //TODO: make optional + $this->writeToDump( $json ); + } + + /** + * @param $ex + */ + private function handleStorageException( $ex ) { + //TODO: optionally, log & ignore. + throw $ex; + } + + /** + * Encodes the given data as JSON + * + * @param $data + * + * @return string + * @throws \MWException + */ + public function encode( $data ) { + $json = json_encode( $data, $this->jsonFlags ); + + if ( $json === false ) { + // TODO: optionally catch & skip this + throw new MWException( 'Failed to encode data structure.' ); + } + + return $json; + } + + /** + * Writers the given string to the output provided to the constructor. + * + * @param $json + */ + private function writeToDump( $json ) { + //TODO: use output stream object + fwrite( $this->out, $json ); + } + + /** + * Flags to use with json_encode as a bit field, see PHP's JSON_XXX constants. + * + * @param int $jsonFlags + */ + public function setJsonFlags( $jsonFlags ) { + $this->jsonFlags = $jsonFlags; + } + + /** + * Flags to use with json_encode as a bit field, see PHP's JSON_XXX constants. + * + * @return int + */ + public function getJsonFlags() { + return $this->jsonFlags; + } +} diff --git a/lib/tests/phpunit/Dumpers/JsonDumpGeneratorTest.php b/lib/tests/phpunit/Dumpers/JsonDumpGeneratorTest.php new file mode 100644 index 0000000..58527d9 --- /dev/null +++ b/lib/tests/phpunit/Dumpers/JsonDumpGeneratorTest.php @@ -0,0 +1,134 @@ +<?php + +namespace Wikibase\Test\Dumpers; +use ArrayObject; +use Wikibase\DataModel\Entity\EntityId; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\Dumpers\JsonDumpGenerator; +use Wikibase\Entity; +use Wikibase\EntityContentFactory; +use Wikibase\EntityFactory; +use Wikibase\Property; + +/** + * JsonDumpGeneratorTest + * + * @covers JsonDumpGenerator + * + * + * + * @license GPL 2+ + * @author Daniel Kinzler + */ +class JsonDumpGeneratorTest extends \PHPUnit_Framework_TestCase { + + /** + * @param EntityId[] $ids + * + * @return Entity[] + */ + protected function makeEntities( array $ids ) { + $entities = array(); + + /* @var EntityId $id */ + foreach ( $ids as $id ) { + $entity = EntityFactory::singleton()->newEmpty( $id->getEntityType() ); + $entity->setId( $id ); + + $key = $id->getPrefixedId(); + $entities[$key] = $entity; + } + + return $entities; + } + + /** + * @param EntityId[] $ids + * + * @return JsonDumpGenerator + */ + protected function newDumpGenerator( array $ids = array() ) { + $out = fopen( 'php://output', 'w' ); // eek + + $serializer = $this->getMock( 'Wikibase\Lib\Serializers\Serializer' ); + $serializer->expects( $this->any() ) + ->method( 'getSerialized' ) + ->will( $this->returnCallback( function ( Entity $entity ) { + return array( + 'id' => $entity->getId()->getPrefixedId() + ); + } + ) ); + + $entities = $this->makeEntities( $ids ); + + $entityLookup = $this->getMock( 'Wikibase\EntityLookup' ); + $entityLookup->expects( $this->any() ) + ->method( 'getEntity' ) + ->will( $this->returnCallback( function ( EntityId $id ) use ( $entities ) { + $key = $id->getPrefixedId(); + return $entities[$key]; + } + ) ); + + return new JsonDumpGenerator( $out, $entityLookup, $serializer ); + } + + /** + * @dataProvider idProvider + */ + public function testGenerateDump( array $ids ) { + $dumper = $this->newDumpGenerator( $ids ); + $idList = new ArrayObject( $ids ); + + ob_start(); + $dumper->generateDump( $idList ); + $json = ob_get_clean(); + + // check that the resulting json contains all the ids we asked for. + $data = json_decode( $json, true ); + + $this->assertTrue( is_array( $data ), 'decode failed: ' . $json ); + + $actualIds = array_map( function( $entityData ) { + return $entityData['id']; + }, $data ); + + $expectedIds = array_map( function( EntityId $id ) { + return $id->getPrefixedId(); + }, $ids ); + + $this->assertEquals( $expectedIds, $actualIds ); + } + + public static function idProvider() { + $p10 = new PropertyId( 'P10' ); + $q30 = new ItemId( 'Q30' ); + + return array( + 'empty' => array( array() ), + 'some entities' => array( array( $p10, $q30 ) ), + ); + } + + /** + * @dataProvider dataProvider + */ + public function testEncode( $data ) { + $dumper = $this->newDumpGenerator(); + $json = $dumper->encode( $data ); + + $actual = json_decode( $json, true ); + $this->assertEquals( $data, $actual ); + } + + public static function dataProvider() { + return array( + 'string' => array( 'bla' ), + 'list' => array( array( 'a', 'b', 'c' ) ), + 'map' => array( array( 'a' => 1, 'b' => 2, 'c' => 3 ) ), + ); + } + +} diff --git a/repo/Wikibase.classes.php b/repo/Wikibase.classes.php index fc7b3c9..547d14c 100644 --- a/repo/Wikibase.classes.php +++ b/repo/Wikibase.classes.php @@ -153,6 +153,8 @@ 'Wikibase\DispatchStats' => 'includes/store/sql/DispatchStats.php', 'Wikibase\TermSearchKeyBuilder' => 'includes/store/sql/TermSearchKeyBuilder.php', 'Wikibase\PropertyInfoTableBuilder' => 'includes/store/sql/PropertyInfoTableBuilder.php', + 'Wikibase\ConvertingResultWrapper' => 'includes/store/sql/ConvertingResultWrapper.php', + 'Wikibase\DatabaseRowEntityIdIterator' => 'includes/store/sql/DatabaseRowEntityIdIterator.php', // includes/updates 'Wikibase\EntityDeletionUpdate' => 'includes/updates/EntityDeletionUpdate.php', diff --git a/repo/includes/store/EntityPerPage.php b/repo/includes/store/EntityPerPage.php index 4961724..238ccc4 100644 --- a/repo/includes/store/EntityPerPage.php +++ b/repo/includes/store/EntityPerPage.php @@ -1,6 +1,7 @@ <?php namespace Wikibase; +use Iterator; /** * Interface to a table that join wiki pages and entities. @@ -96,4 +97,11 @@ * @return EntityId[] */ public function getItemsWithoutSitelinks( $siteId = null, $limit = 50, $offset = 0 ); + + /** + * Returns an iterator providing an EntityId object for each entity. + * + * @return Iterator + */ + public function getEntities(); } diff --git a/repo/includes/store/sql/ConvertingResultWrapper.php b/repo/includes/store/sql/ConvertingResultWrapper.php new file mode 100644 index 0000000..ab5a9f0 --- /dev/null +++ b/repo/includes/store/sql/ConvertingResultWrapper.php @@ -0,0 +1,83 @@ +<?php + +namespace Wikibase; +use Iterator; +use ResultWrapper; + +/** + * Base class for iterators that convert each row of a database result into an appropriate object. + * + * @since 0.5 + * + * @ingroup WikibaseRepo + * + * @licence GNU GPL v2+ + * @author Daniel Kinzler + */ +abstract class ConvertingResultWrapper implements Iterator { + + /** + * @var \ResultWrapper + */ + protected $rows; + + /** + * @param ResultWrapper $rows + */ + public function __construct( ResultWrapper $rows ) { + $this->rows = $rows; + } + + /** + * @see Iterator::current() + * @see ResultWrapper::current() + */ + public function current() { + $current = $this->rows->current(); + $current = $this->convert( $current ); + return $current; + } + + /** + * @see Iterator::next() + * @see ResultWrapper::next() + */ + public function next() { + $this->rows->next(); + } + + /** + * @see Iterator::key() + * @see ResultWrapper::key() + * @return mixed scalar or null + */ + public function key() { + return $this->rows->key(); + } + + /** + * @see Iterator::valid() + * @see ResultWrapper::valid() + * @return bool + */ + public function valid() { + return $this->rows->valid(); + } + + /** + * @see Iterator::rewind() + * @see ResultWrapper::rewind() + */ + public function rewind() { + $this->rows->rewind(); + } + + /** + * Converts a database row into the desired representation. + * + * @param object $row An object representing the raw database row, as returned by ResultWrapper::current(). + * + * @return mixed + */ + protected abstract function convert( $row ); +} diff --git a/repo/includes/store/sql/DatabaseRowEntityIdIterator.php b/repo/includes/store/sql/DatabaseRowEntityIdIterator.php new file mode 100644 index 0000000..3ac7af9 --- /dev/null +++ b/repo/includes/store/sql/DatabaseRowEntityIdIterator.php @@ -0,0 +1,65 @@ +<?php + +namespace Wikibase; +use ResultWrapper; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\Entity\PropertyId; + +/** + * Allows a database result set containing entity IDs to be iterated as EntityId objects. + * + * @since 0.5 + * + * @ingroup WikibaseRepo + * + * @licence GNU GPL v2+ + * @author Daniel Kinzler + */ +class DatabaseRowEntityIdIterator extends ConvertingResultWrapper { + + /** + * @var string + */ + protected $idField; + + /** + * @var string + */ + protected $typeField; + + public function __construct( ResultWrapper $rows, $typeField, $idField ) { + parent::__construct( $rows ); + + $this->idField = $idField; + $this->typeField = $typeField; + } + + /** + * Converts a database row into the desired representation. + * + * @param object $row An object representing the raw database row, as returned by ResultWrapper::current(). + * + * @return EntityId + */ + protected function convert( $row ) { + $idField = $this->idField; //PHP fails + $typeField = $this->typeField; //PHP fails + + $id = (int)$row->$idField; + $type = $row->$typeField; + + //TODO: use an EntityIdFactory here + switch ( $type ) { + case 'item': + $entityId = new ItemId( "Q$id" ); + break; + case 'property': + $entityId = new PropertyId( "P$id" ); + break; + default: + throw new \RuntimeException( "Unknown entity type: $type" ); + } + + return $entityId; + } +} diff --git a/repo/includes/store/sql/EntityPerPageTable.php b/repo/includes/store/sql/EntityPerPageTable.php index 9314874..a8896d0 100644 --- a/repo/includes/store/sql/EntityPerPageTable.php +++ b/repo/includes/store/sql/EntityPerPageTable.php @@ -1,6 +1,7 @@ <?php namespace Wikibase; +use Iterator; /** * Represents a lookup database table that make the link between entities and pages. @@ -28,6 +29,7 @@ * * @licence GNU GPL v2+ * @author Thomas Pellissier Tanon + * @author Daniel Kinzler */ class EntityPerPageTable implements EntityPerPage { @@ -219,4 +221,23 @@ } return $entities; } + + /** + * Returns an iterator providing an EntityId object for each entity. + * + * @return Iterator + */ + public function getEntities() { + //XXX: Would be nice to get the DBR from a load balancer and allow access to foreign wikis. + // But since we return a ResultWrapper, we don't know when we can release the connection for re-use. + + $dbr = wfGetDB( DB_SLAVE ); + $rows = $dbr->select( + 'wb_entity_per_page', + array( 'epp_entity_id', 'epp_entity_type' ), + '', + __METHOD__ ); + + return new DatabaseRowEntityIdIterator( $rows, 'epp_entity_type', 'epp_entity_id' ); + } } diff --git a/repo/maintenance/dumpJson.php b/repo/maintenance/dumpJson.php new file mode 100644 index 0000000..5519ca8 --- /dev/null +++ b/repo/maintenance/dumpJson.php @@ -0,0 +1,103 @@ +<?php + +namespace Wikibase; +use Iterator; +use Maintenance; +use ValueFormatters\FormatterOptions; +use Wikibase\Dumpers\JsonDumpGenerator; +use Wikibase\Lib\EntityIdFormatter; +use Wikibase\Lib\Serializers\EntitySerializationOptions; +use Wikibase\Lib\Serializers\EntitySerializer; +use Wikibase\Lib\Serializers\Serializer; +use Wikibase\Repo\WikibaseRepo; + +$basePath = getenv( 'MW_INSTALL_PATH' ) !== false ? getenv( 'MW_INSTALL_PATH' ) : __DIR__ . '/../../../..'; + +require_once $basePath . '/maintenance/Maintenance.php'; + +/** + * Maintenance script for generating a JSON dump of entities in the repository. + * + * @since 0.5 + * + * @ingroup WikibaseRepo + * + * @licence GNU GPL v2+ + * @author Daniel Kinzler + */ +class DumpJasonInfo extends Maintenance { + + /** + * @var EntityLookup + */ + public $entityLookup; + + /** + * @var Serializer + */ + public $entitySerializer; + + /** + * @var EntityPerPage + */ + public $entityPerPage; + + public function __construct() { + parent::__construct(); + + $this->mDescription = 'Generate a JSON dump from entities in the repository.'; + + //TODO: read list of IDs from file + //TODO: filter by entity type + //$this->addOption( 'rebuild-all', "Update property info for all properties (per default, only missing entries are created)" ); + //$this->addOption( 'start-row', "The ID of the first row to update (useful for continuing aborted runs)", false, true ); + //$this->addOption( 'batch-size', "Number of rows to update per database transaction (100 per default)", false, true ); + } + + public function finalSetup() { + parent::finalSetup(); + + $serializerOptions = new EntitySerializationOptions( new EntityIdFormatter( new FormatterOptions() ) ); + $this->entitySerializer = new EntitySerializer( $serializerOptions ); + + //TODO: allow injection for unit tests + $this->entityPerPage = new EntityPerPageTable(); + $this->entityLookup = WikibaseRepo::getDefaultInstance()->getEntityLookup(); + } + + /** + * Outputs a message vis the output() method. + * + * @since 0.4 + * + * @param $msg + */ + public function report( $msg ) { + $this->output( "$msg\n" ); + } + + /** + * Do the actual work. All child classes will need to implement this + */ + public function execute() { + $output = fopen( 'php://stdout', 'wa' ); //TODO: Allow injection of an OutputStream + $dumper = new JsonDumpGenerator( $output, $this->entityLookup, $this->entitySerializer ); + + $idStream = $this->makeIdStream(); + $dumper->generateDump( $idStream ); + } + + /** + * @return Iterator a stream of EntityId objects + */ + public function makeIdStream() { + //TODO: provide list/filter of entities + //TODO: allow ids to be read from a file + + $stream = $this->entityPerPage->getEntities(); + return $stream; + } +} + +$maintClass = 'Wikibase\DumpJasonInfo'; +require_once( RUN_MAINTENANCE_IF_MAIN ); diff --git a/repo/tests/phpunit/includes/store/sql/DatabaseRowEntityIdIteratorTest.php b/repo/tests/phpunit/includes/store/sql/DatabaseRowEntityIdIteratorTest.php new file mode 100644 index 0000000..43073c7 --- /dev/null +++ b/repo/tests/phpunit/includes/store/sql/DatabaseRowEntityIdIteratorTest.php @@ -0,0 +1,108 @@ +<?php + +namespace Wikibase\Test; + +use Wikibase\DatabaseRowEntityIdIterator; +use Wikibase\DataModel\Entity\EntityId; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\EntityContent; +use Wikibase\EntityContentFactory; +use Wikibase\EntityFactory; +use Wikibase\Property; +use Wikibase\Repo\WikibaseRepo; + +/** + * @covers Wikibase\DatabaseRowEntityIdIterator + * + * @since 0.5 + * + * @ingroup WikibaseRepoTest + * @ingroup Test + * + * @group Wikibase + * @group WikibaseStore + * @group Database + * + * @group medium + * + * @licence GNU GPL v2+ + * @author Daniel Kinzler + */ +class DatabaseRowEntityIdIteratorTest extends \MediaWikiTestCase { + + /** + * @param EntityId[] $entityId + * + * @return string the table name + */ + protected function setUpTestTable( array $entityIds ) { + $dbw = wfGetDB( DB_MASTER ); + $dbw->delete( 'wb_entity_per_page', '1', __METHOD__ ); + + $i = 0; + + /* @var EntityId $id */ + foreach ( $entityIds as $id ) { + $i++; + + $dbw->insert( + 'wb_entity_per_page', + array( + 'epp_entity_id' => $id->getNumericId(), + 'epp_entity_type' => $id->getEntityType(), + 'epp_page_id' => $i, + ), + __METHOD__ + ); + } + + return 'wb_entity_per_page'; + } + + /** + * @param $ids + * + * @return DatabaseRowEntityIdIterator + */ + protected function newDatabaseRowEntityIdIterator( $ids ) { + $dbr = wfGetDB( DB_MASTER ); + $table = $this->setUpTestTable( $ids ); + + $rows = $dbr->select( + $table, + array( 'epp_entity_type', 'epp_entity_id', ), + '', + __METHOD__ + ); + + $iterator = new DatabaseRowEntityIdIterator( $rows, 'epp_entity_type', 'epp_entity_id' ); + return $iterator; + } + + /** + * @dataProvider idProvider + */ + public function testIteration( $ids ) { + $iterator = $this->newDatabaseRowEntityIdIterator( $ids ); + + if ( empty( $ids ) ) { + $this->assertFalse( $iterator->valid() ); + } + + foreach ( $iterator as $id ) { + $this->assertInstanceOf( 'Wikibase\DataModel\Entity\EntityId', $id ); + $this->assertContains( $id, $ids, '', false, false ); + } + } + + public static function idProvider() { + $p10 = new PropertyId( 'P10' ); + $q30 = new ItemId( 'Q30' ); + + return array( + 'empty' => array( array() ), + 'some entities' => array( array( $p10, $q30 ) ), + ); + } +} diff --git a/repo/tests/phpunit/includes/store/sql/EntityPerPageTableTest.php b/repo/tests/phpunit/includes/store/sql/EntityPerPageTableTest.php new file mode 100644 index 0000000..2a41ed8 --- /dev/null +++ b/repo/tests/phpunit/includes/store/sql/EntityPerPageTableTest.php @@ -0,0 +1,111 @@ +<?php + +namespace Wikibase\Test; + +use Wikibase\DataModel\Entity\EntityId; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\EntityContent; +use Wikibase\EntityContentFactory; +use Wikibase\EntityFactory; +use Wikibase\EntityPerPageTable; +use Wikibase\Property; +use Wikibase\Repo\WikibaseRepo; + +/** + * @covers Wikibase\EntityPerPageTable + * + * @since 0.5 + * + * @ingroup WikibaseRepoTest + * @ingroup Test + * + * @group Wikibase + * @group WikibaseStore + * @group WikibaseEntityPerPage + * @group Database + * + * @group medium + * + * @licence GNU GPL v2+ + * @author Daniel Kinzler + */ +class EntityPerPageTableTest extends \MediaWikiTestCase { + + /** + * @param EntityId[] $entityId + * + * @return EntityPerPageTable + */ + protected function newEntityPerPageTable( array $entityIds ) { + $table = new EntityPerPageTable(); + $table->clear(); + + /* @var EntityId $id */ + foreach ( $entityIds as $id ) { + $entity = EntityFactory::singleton()->newEmpty( $id->getEntityType() ); + $entity->setId( $id ); + + if ( $entity instanceof Property ) { + $entity->setDataTypeId( 'string' ); + } + + $content = EntityContentFactory::singleton()->newFromEntity( $entity ); + $title = $content->getTitle(); + + if ( !$title->exists() ) { + $content->save(); + } + + $table->addEntityContent( $content ); + } + + return $table; + } + + public function testAddEntityContent( /* EntityContent $entityContent */ ) { + $this->markTestIncomplete( "test me!" ); + } + + public function testDeleteEntityContent( /* EntityContent $entityContent */ ) { + $this->markTestIncomplete( "test me!" ); + } + + public function testClear() { + $this->markTestIncomplete( "test me!" ); + } + + public function testRebuild() { + $this->markTestIncomplete( "test me!" ); + } + + public function testGetEntitiesWithoutTerm( /* $termType, $language = null, $entityType = null, $limit = 50, $offset = 0 */ ) { + $this->markTestIncomplete( "test me!" ); + } + + public function testGetItemsWithoutSitelinks( /* $siteId = null, $limit = 50, $offset = 0 */ ) { + $this->markTestIncomplete( "test me!" ); + } + + /** + * @dataProvider getEntitiesProvider + */ + public function testGetEntities( $ids ) { + $table = $this->newEntityPerPageTable( $ids ); + + $iterator = $table->getEntities(); + $actual = iterator_to_array( $iterator ); + + $this->assertArrayEquals( $ids, $actual ); + } + + public static function getEntitiesProvider() { + $p10 = new PropertyId( 'P10' ); + $q30 = new ItemId( 'Q30' ); + + return array( + 'empty' => array( array() ), + 'some entities' => array( array( $p10, $q30 ) ), + ); + } +} -- To view, visit https://gerrit.wikimedia.org/r/83816 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I09eaa2a7b6fa9cb6a5ffc57b5f28c30e93d79f8b Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Daniel Kinzler <daniel.kinz...@wikimedia.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits