Bene has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/203527

Change subject: Create a new special page to list properties by data type
......................................................................

Create a new special page to list properties by data type

The new special page is called Special:ListProperties.
Queries can be done via the form or in the format
Special:ListProperties/dataType, eg Special:ListProperties/url.

Bug: T55618
Change-Id: I79a08ec87bf76adba869d4b7eb22098b41fbdb72
---
M lib/includes/store/CachingPropertyInfoStore.php
M lib/includes/store/DummyPropertyInfoStore.php
M lib/includes/store/PropertyInfoStore.php
M lib/includes/store/sql/PropertyInfoTable.php
M lib/tests/phpunit/store/MockPropertyInfoStore.php
M lib/tests/phpunit/store/PropertyInfoStoreTestHelper.php
M lib/tests/phpunit/store/Sql/PropertyInfoTableTest.php
M repo/Wikibase.i18n.alias.php
M repo/Wikibase.php
M repo/i18n/en.json
M repo/includes/DataTypeSelector.php
A repo/includes/specials/SpecialListProperties.php
M repo/includes/store/sql/SqlStore.php
A repo/tests/phpunit/includes/specials/SpecialListPropertiesTest.php
14 files changed, 394 insertions(+), 39 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase 
refs/changes/27/203527/1

diff --git a/lib/includes/store/CachingPropertyInfoStore.php 
b/lib/includes/store/CachingPropertyInfoStore.php
index 79f9e60..9023c68 100644
--- a/lib/includes/store/CachingPropertyInfoStore.php
+++ b/lib/includes/store/CachingPropertyInfoStore.php
@@ -90,6 +90,26 @@
        }
 
        /**
+        * @see PropertyInfoStore::getPropertyInfoForDataType
+        *
+        * @param string $dataType
+        *
+        * @return array[]
+        */
+       public function getPropertyInfoForDataType( $dataType ) {
+               $propertyInfo = $this->getAllPropertyInfo();
+               $propertyInfoForDataType = array();
+
+               foreach ( $propertyInfo as $id => $info ) {
+                       if ( $info[PropertyInfoStore::KEY_DATA_TYPE] === 
$dataType ) {
+                               $propertyInfoForDataType[$id] = $info;
+                       }
+               }
+
+               return $propertyInfoForDataType;
+       }
+
+       /**
         * @see PropertyInfoStore::getAllPropertyInfo
         *
         * @return array[]
diff --git a/lib/includes/store/DummyPropertyInfoStore.php 
b/lib/includes/store/DummyPropertyInfoStore.php
index 5da4327..09c6504 100644
--- a/lib/includes/store/DummyPropertyInfoStore.php
+++ b/lib/includes/store/DummyPropertyInfoStore.php
@@ -27,6 +27,17 @@
        }
 
        /**
+        * @see PropertyInfoStore::getPropertyInfoForDataType
+        *
+        * @param string $dataType
+        *
+        * @return array[]
+        */
+       public function getPropertyInfoForDataType( $dataType ) {
+               return array();
+       }
+
+       /**
         * @see PropertyInfoStore::getAllPropertyInfo
         *
         * @return array[]
diff --git a/lib/includes/store/PropertyInfoStore.php 
b/lib/includes/store/PropertyInfoStore.php
index 8c9d01d..5df532c 100644
--- a/lib/includes/store/PropertyInfoStore.php
+++ b/lib/includes/store/PropertyInfoStore.php
@@ -9,6 +9,7 @@
 /**
  * @license GPL 2+
  * @author Daniel Kinzler
+ * @author Bene* < benestar.wikime...@gmail.com >
  */
 interface PropertyInfoStore {
 
@@ -33,6 +34,21 @@
        public function getPropertyInfo( PropertyId $propertyId );
 
        /**
+        * Returns the property info for all properties with the given data 
type.
+        *
+        * @note: There is no guarantee that an info array is returned for all 
existing properties.
+        *        Also, it is not guaranteed that the ionfo arrays will contain 
all well known fields.
+        *
+        * @param string $dataType
+        *
+        * @return array[] An associative array mapping property IDs to info 
arrays.
+        *
+        * @throws StorageException
+        * @throws DBError
+        */
+       public function getPropertyInfoForDataType( $dataType );
+
+       /**
         * Returns the property info for all properties.
         * The caller is responsible for avoiding calling this if there are too 
many properties.
         *
diff --git a/lib/includes/store/sql/PropertyInfoTable.php 
b/lib/includes/store/sql/PropertyInfoTable.php
index 02e8047..c90f4f2 100644
--- a/lib/includes/store/sql/PropertyInfoTable.php
+++ b/lib/includes/store/sql/PropertyInfoTable.php
@@ -5,6 +5,7 @@
 use DBAccessBase;
 use DBError;
 use InvalidArgumentException;
+use ResultWrapper;
 use Wikibase\DataModel\Entity\PropertyId;
 
 /**
@@ -14,6 +15,7 @@
  *
  * @license GPL 2+
  * @author Daniel Kinzler
+ * @author Bene* < benestar.wikime...@gmail.com >
  */
 class PropertyInfoTable extends DBAccessBase implements PropertyInfoStore {
 
@@ -42,9 +44,56 @@
                        throw new InvalidArgumentException( '$wiki must be a 
string or false.' );
                }
 
+               parent::__construct( $wiki );
                $this->tableName = 'wb_property_info';
                $this->isReadonly = $isReadonly;
-               $this->wiki = $wiki;
+       }
+
+       /**
+        * Decodes an info blob.
+        *
+        * @param string|null|bool $blob
+        *
+        * @return array|null The decoded blob as an associative array, or null 
if the blob
+        *         could not be decoded.
+        */
+       private function decodeInfo( $blob ) {
+               if ( $blob === false || $blob === null ) {
+                       return null;
+               }
+
+               $info = json_decode( $blob, true );
+
+               if ( !is_array( $info ) ) {
+                       $info = null;
+               }
+
+               return $info;
+       }
+
+       /**
+        * Decodes a result with info blobs.
+        *
+        * @param ResultWrapper $res
+        *
+        * @return array[] The array of decoded blobs
+        */
+       private function decodeInfoArray( ResultWrapper $res ) {
+               $infos = array();
+
+               while ( $row = $res->fetchObject() ) {
+                       $info = $this->decodeInfo( $row->pi_info );
+
+                       if ( $info === null ) {
+                               wfLogWarning( "failed to decode property info 
blob for property "
+                                       . $row->pi_property_id . ": " . 
$row->pi_info );
+                               continue;
+                       }
+
+                       $infos[$row->pi_property_id] = $info;
+               }
+
+               return $infos;
        }
 
        /**
@@ -83,29 +132,33 @@
        }
 
        /**
-        * Decodes an info blob.
+        * @see PropertyDataTypeLookup::getPropertyInfoForDataType
         *
-        * @param string|null|bool  $blob
+        * @param string $dataType
         *
-        * @return array|null The decoded blob as an associative array, or null 
if the blob
-        *         could not be decoded.
+        * @return array[]
+        *
+        * @throws DBError
         */
-       protected function decodeInfo( $blob ) {
-               if ( $blob === false || $blob === null ) {
-                       return null;
-               }
+       public function getPropertyInfoForDataType( $dataType ) {
+               $dbw = $this->getConnection( DB_SLAVE );
 
-               $info = json_decode( $blob, true );
+               $res = $dbw->select(
+                       $this->tableName,
+                       array( 'pi_property_id', 'pi_info' ),
+                       array( 'pi_type' => $dataType ),
+                       __METHOD__
+               );
 
-               if ( !is_array( $info ) ) {
-                       $info = null;
-               }
+               $infos = $this->decodeInfoArray( $res );
 
-               return $info;
+               $this->releaseConnection( $dbw );
+
+               return $infos;
        }
 
        /**
-        * @see   PropertyInfoStore::getAllPropertyInfo
+        * @see PropertyInfoStore::getAllPropertyInfo
         *
         * @return array[]
         *
@@ -121,19 +174,7 @@
                        __METHOD__
                );
 
-               $infos = array();
-
-               while ( $row = $res->fetchObject() ) {
-                       $info = $this->decodeInfo( $row->pi_info );
-
-                       if ( $info === null ) {
-                               wfLogWarning( "failed to decode property info 
blob for property "
-                                       . $row->pi_property_id . ": " . 
$row->pi_info );
-                               continue;
-                       }
-
-                       $infos[$row->pi_property_id] = $info;
-               }
+               $infos = $this->decodeInfoArray( $res );
 
                $this->releaseConnection( $dbw );
 
diff --git a/lib/tests/phpunit/store/MockPropertyInfoStore.php 
b/lib/tests/phpunit/store/MockPropertyInfoStore.php
index 18d59bb..140243b 100644
--- a/lib/tests/phpunit/store/MockPropertyInfoStore.php
+++ b/lib/tests/phpunit/store/MockPropertyInfoStore.php
@@ -48,7 +48,27 @@
        }
 
        /**
-        * @see   PropertyInfoStore::getAllPropertyInfo
+        * @see PropertyInfoStore::getPropertyInfoForDataType
+        *
+        * @param string $dataType
+        *
+        * @return array[]
+        */
+       public function getPropertyInfoForDataType( $dataType ) {
+               $propertyInfo = $this->getAllPropertyInfo();
+               $propertyInfoForDataType = array();
+
+               foreach ( $propertyInfo as $id => $info ) {
+                       if ( $info[PropertyInfoStore::KEY_DATA_TYPE] === 
$dataType ) {
+                               $propertyInfoForDataType[$id] = $info;
+                       }
+               }
+
+               return $propertyInfoForDataType;
+       }
+
+       /**
+        * @see PropertyInfoStore::getAllPropertyInfo
         *
         * @return array[]
         */
diff --git a/lib/tests/phpunit/store/PropertyInfoStoreTestHelper.php 
b/lib/tests/phpunit/store/PropertyInfoStoreTestHelper.php
index 44c59a9..da2a08e 100644
--- a/lib/tests/phpunit/store/PropertyInfoStoreTestHelper.php
+++ b/lib/tests/phpunit/store/PropertyInfoStoreTestHelper.php
@@ -85,6 +85,28 @@
                $this->test->assertEquals( $info23, $table->getPropertyInfo( 
$p23 ), "should return what was set" );
        }
 
+       public function testGetPropertyInfoForDataType() {
+               $table = $this->newPropertyInfoStore();
+               $p23 = new PropertyId( 'P23' );
+               $p42 = new PropertyId( 'P42' );
+               $info23 = array( PropertyInfoStore::KEY_DATA_TYPE => 'string' );
+               $info42 = array( PropertyInfoStore::KEY_DATA_TYPE => 
'commonsMedia', 'foo' => 'bar' );
+
+               $this->test->assertCount( 0, 
$table->getPropertyInfoForDataType( 'commonsMedia' ), "should initially be 
empty" );
+
+               $table->setPropertyInfo( $p23, $info23 );
+               $this->test->assertCount( 0, 
$table->getPropertyInfoForDataType( 'commonsMedia' ), "after adding one 
property" );
+
+               $table->setPropertyInfo( $p42, $info42 );
+               $this->test->assertCount( 1, 
$table->getPropertyInfoForDataType( 'commonsMedia' ), "after adding the second 
property" );
+
+               $table->removePropertyInfo( $p23 );
+               $this->test->assertCount( 1, 
$table->getPropertyInfoForDataType( 'commonsMedia' ), "after removing one 
property" );
+
+               $table->removePropertyInfo( $p42 );
+               $this->test->assertCount( 0, 
$table->getPropertyInfoForDataType( 'commonsMedia' ), "after removing the 
second property" );
+       }
+
        public function testGetAllPropertyInfo() {
                $table = $this->newPropertyInfoStore();
                $p23 = new PropertyId( 'P23' );
diff --git a/lib/tests/phpunit/store/Sql/PropertyInfoTableTest.php 
b/lib/tests/phpunit/store/Sql/PropertyInfoTableTest.php
index 4662873..2a03240 100644
--- a/lib/tests/phpunit/store/Sql/PropertyInfoTableTest.php
+++ b/lib/tests/phpunit/store/Sql/PropertyInfoTableTest.php
@@ -64,6 +64,10 @@
                $this->helper->testGetPropertyInfo();
        }
 
+       public function testGetPropertyInfoForDataType() {
+               $this->helper->testGetPropertyInfoForDataType();
+       }
+
        public function testGetAllPropertyInfo() {
                $this->helper->testGetAllPropertyInfo();
        }
diff --git a/repo/Wikibase.i18n.alias.php b/repo/Wikibase.i18n.alias.php
index a449b40..be8a5bc 100644
--- a/repo/Wikibase.i18n.alias.php
+++ b/repo/Wikibase.i18n.alias.php
@@ -22,6 +22,7 @@
        'GoToLinkedPage' => array( 'GoToLinkedPage' ),
        'ItemDisambiguation' => array( 'ItemDisambiguation' ),
        'ListDatatypes' => array( 'ListDatatypes' ),
+       'ListProperties' => array( 'ListProperties' ),
        'SetLabel' => array( 'SetLabel' ),
        'SetDescription' => array( 'SetDescription' ),
        'SetAliases' => array( 'SetAliases' ),
diff --git a/repo/Wikibase.php b/repo/Wikibase.php
index 5a73d8e..eb89cda 100644
--- a/repo/Wikibase.php
+++ b/repo/Wikibase.php
@@ -180,6 +180,7 @@
        $wgSpecialPages['EntitiesWithoutLabel']                         = 
array( 'Wikibase\Repo\Specials\SpecialEntitiesWithoutPageFactory', 
'newSpecialEntitiesWithoutLabel' );
        $wgSpecialPages['EntitiesWithoutDescription']           = array( 
'Wikibase\Repo\Specials\SpecialEntitiesWithoutPageFactory', 
'newSpecialEntitiesWithoutDescription' );
        $wgSpecialPages['ListDatatypes']                                        
= 'Wikibase\Repo\Specials\SpecialListDatatypes';
+       $wgSpecialPages['ListProperties']                                       
= 'Wikibase\Repo\Specials\SpecialListProperties';
        $wgSpecialPages['DispatchStats']                                        
= 'Wikibase\Repo\Specials\SpecialDispatchStats';
        $wgSpecialPages['EntityData']                                           
= 'Wikibase\Repo\Specials\SpecialEntityData';
        $wgSpecialPages['MyLanguageFallbackChain']                      = 
'Wikibase\Repo\Specials\SpecialMyLanguageFallbackChain';
diff --git a/repo/i18n/en.json b/repo/i18n/en.json
index 71e8bd6..461f15a 100644
--- a/repo/i18n/en.json
+++ b/repo/i18n/en.json
@@ -245,6 +245,10 @@
        "wikibase-listdatatypes-intro": "This is a list of all data types 
available on this installation:",
        "wikibase-history-title-with-label": "Revision history of \"$2\" ($1)",
        "wikibase-history-title-without-label": "Revision history of ($1)",
+       "special-listproperties": "List of properties by data type",
+       "wikibase-listproperties-legend": "Get list of properties by data type",
+       "wikibase-listproperties-label-datatype": "Data type:",
+       "wikibase-listproperties-submit": "Find",
        "special-entitieswithoutdescription": "Entities without description",
        "wikibase-entitieswithoutdescription-legend": "Get list of entities 
without description",
        "special-entitieswithoutlabel": "Entities without label",
diff --git a/repo/includes/DataTypeSelector.php 
b/repo/includes/DataTypeSelector.php
index f0ae7fa..9fd9a25 100644
--- a/repo/includes/DataTypeSelector.php
+++ b/repo/includes/DataTypeSelector.php
@@ -55,10 +55,11 @@
         *
         * @param string $id
         * @param string $name
+        * @param string $selectedTypeId
         *
         * @return string
         */
-       public function getHtml( $id = 'datatype', $name = 'datatype' ) {
+       public function getHtml( $id = 'datatype', $name = 'datatype', 
$selectedTypeId = '' ) {
                $dataTypes = array();
 
                foreach ( $this->dataTypes as $dataType ) {
@@ -70,9 +71,15 @@
                $html = '';
 
                foreach ( $dataTypes as $typeId => $typeLabel ) {
+                       $attrs = array( 'value' => $typeId );
+
+                       if ( $typeId === $selectedTypeId ) {
+                               $attrs['selected'] = true;
+                       }
+
                        $html .= Html::element(
                                'option',
-                               array( 'value' => $typeId ),
+                               $attrs,
                                $typeLabel
                        );
                }
diff --git a/repo/includes/specials/SpecialListProperties.php 
b/repo/includes/specials/SpecialListProperties.php
new file mode 100644
index 0000000..00e56b6
--- /dev/null
+++ b/repo/includes/specials/SpecialListProperties.php
@@ -0,0 +1,159 @@
+<?php
+
+namespace Wikibase\Repo\Specials;
+
+use DataTypes\DataTypeFactory;
+use Html;
+use Linker;
+use MWException;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataTypeSelector;
+use Wikibase\PropertyInfoStore;
+use Wikibase\Repo\WikibaseRepo;
+
+/**
+ * Special page to list properties by data type
+ *
+ * @since 0.5
+ * @licence GNU GPL v2+
+ * @author Bene* < benestar.wikime...@gmail.com >
+ */
+class SpecialListProperties extends SpecialWikibasePage {
+
+       /**
+        * @var DataTypeFactory
+        */
+       private $dataTypeFactory;
+
+       /**
+        * @var PropertyInfoStore
+        */
+       private $propertyInfoStore;
+
+       /**
+        * @var string
+        */
+       private $dataType;
+
+       /**
+        * @since 0.5
+        */
+       public function __construct() {
+               parent::__construct( 'ListProperties' );
+
+               $this->dataTypeFactory = 
WikibaseRepo::getDefaultInstance()->getDataTypeFactory();
+               $this->propertyInfoStore = 
WikibaseRepo::getDefaultInstance()->getStore()->getPropertyInfoStore();
+       }
+
+       /**
+        * @see SpecialWikibasePage::execute
+        *
+        * @since 0.5
+        *
+        * @param string|null $subPage
+        */
+       public function execute( $subPage ) {
+               parent::execute( $subPage );
+
+               $this->prepareArguments( $subPage );
+               $this->showForm();
+
+               if ( $this->dataType !== null ) {
+                       $this->showQuery();
+               }
+       }
+
+       private function prepareArguments( $subPage ) {
+               $request = $this->getRequest();
+
+               $this->dataType = $request->getText( 'datatype', $subPage );
+               if ( !in_array( $this->dataType, 
$this->dataTypeFactory->getTypeIds() ) ) {
+                       $this->dataType = null;
+               }
+       }
+
+       private function showForm() {
+               $dataTypeSelect = new DataTypeSelector(
+                       $this->dataTypeFactory->getTypes(),
+                       $this->getLanguage()->getCode()
+               );
+
+               $this->getOutput()->addHTML(
+                       Html::openElement(
+                               'form',
+                               array(
+                                       'action' => 
$this->getPageTitle()->getLocalURL(),
+                                       'name' => 'listproperties',
+                                       'id' => 'wb-listproperties-form'
+                               )
+                       ) .
+                       Html::input (
+                               'title',
+                               $this->getPageTitle()->getPrefixedText(),
+                               'hidden',
+                               array()
+                       ) .
+                       Html::openElement( 'fieldset' ) .
+                       Html::element(
+                               'legend',
+                               array(),
+                               $this->msg( 'wikibase-listproperties-legend' 
)->text()
+                       ) .
+                       Html::openElement( 'p' ) .
+                       Html::element(
+                               'label',
+                               array(
+                                       'for' => 'wb-listproperties-datatype'
+                               ),
+                               $this->msg( 
'wikibase-listproperties-label-datatype' )->text()
+                       ) . ' ' .
+                       $dataTypeSelect->getHTML( 'wb-listproperties-datatype', 
'datatype', $this->dataType ) . ' ' .
+                       Html::input(
+                               'submit',
+                               $this->msg( 'wikibase-listproperties-submit' 
)->text(),
+                               'submit',
+                               array(
+                                       'id' => 
'wikibase-listproperties-submit',
+                                       'class' => 'wb-input-button'
+                               )
+                       ) .
+                       Html::closeElement( 'p' ) .
+                       Html::closeElement( 'fieldset' ) .
+                       Html::closeElement( 'form' )
+               );
+       }
+
+       private function showQuery() {
+               $propertyInfoForDataType = 
$this->propertyInfoStore->getPropertyInfoForDataType( $this->dataType );
+
+               if ( empty( $propertyInfoForDataType ) ) {
+                       $this->getOutput()->addWikiMsg( 'specialpage-empty' );
+                       return;
+               }
+
+               $html = Html::openElement( 'ul' );
+
+               foreach ( $propertyInfoForDataType as $numericId => $info ) {
+                       $row = $this->formatRow( PropertyId::newFromNumber( 
$numericId ) );
+                       $html .= Html::rawElement( 'li', array(), $row );
+               }
+
+               $html .= Html::closeElement( 'ul' );
+               $this->getOutput()->addHTML( $html );
+       }
+
+       /**
+        * @see SpecialWikibaseQueryPage::formatRow
+        */
+       private function formatRow( PropertyId $propertyId ) {
+               try {
+                       $title = 
WikibaseRepo::getDefaultInstance()->getEntityContentFactory()->getTitleForId( 
$propertyId );
+                       return Linker::linkKnown( $title );
+               } catch ( MWException $e ) {
+                       wfWarn( "Error formatting result row: " . 
$e->getMessage() );
+                       return false;
+               }
+       }
+
+}
+
diff --git a/repo/includes/store/sql/SqlStore.php 
b/repo/includes/store/sql/SqlStore.php
index 395cbf0..41a820c 100644
--- a/repo/includes/store/sql/SqlStore.php
+++ b/repo/includes/store/sql/SqlStore.php
@@ -81,9 +81,9 @@
        private $entityInfoBuilderFactory = null;
 
        /**
-        * @var PropertyInfoTable|null
+        * @var PropertyInfoStore|null
         */
-       private $propertyInfoTable = null;
+       private $propertyInfoStore = null;
 
        /**
         * @var ChangesTable|null
@@ -657,19 +657,19 @@
         * @return PropertyInfoStore
         */
        public function getPropertyInfoStore() {
-               if ( !$this->propertyInfoTable ) {
-                       $this->propertyInfoTable = 
$this->newPropertyInfoTable();
+               if ( !$this->propertyInfoStore ) {
+                       $this->propertyInfoStore = 
$this->newPropertyInfoStore();
                }
 
-               return $this->propertyInfoTable;
+               return $this->propertyInfoStore;
        }
 
        /**
-        * Creates a new PropertyInfoTable
+        * Creates a new PropertyInfoStore
         *
-        * @return PropertyInfoTable
+        * @return PropertyInfoStore
         */
-       private function newPropertyInfoTable() {
+       private function newPropertyInfoStore() {
                $usePropertyInfoTable = WikibaseRepo::getDefaultInstance()->
                        getSettings()->getSetting( 'usePropertyInfoTable' );
 
diff --git a/repo/tests/phpunit/includes/specials/SpecialListPropertiesTest.php 
b/repo/tests/phpunit/includes/specials/SpecialListPropertiesTest.php
new file mode 100644
index 0000000..07fc67f
--- /dev/null
+++ b/repo/tests/phpunit/includes/specials/SpecialListPropertiesTest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Wikibase\Test;
+
+use Language;
+use Wikibase\Repo\Specials\SpecialListProperties;
+use Wikibase\Test\SpecialPageTestBase;
+
+/**
+ * @covers Wikibase\Repo\Specials\SpecialListProperties
+ *
+ * @group Wikibase
+ * @group WikibaseRepo
+ * @group SpecialPage
+ * @group WikibaseSpecialPage
+ *
+ * @licence GNU GPL v2+
+ * @author Bene* < benestar.wikime...@gmail.com >
+ */
+class SpecialListPropertiesTest extends SpecialPageTestBase {
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->setMwGlobals( array(
+                       'wgContLang' => Language::factory( 'qqx' )
+               ) );
+       }
+
+       protected function newSpecialPage() {
+               return new SpecialListProperties();
+       }
+
+       public function testExecute() {
+               // This also tests that there is no fatal error, that the 
restriction handling is working
+               // and doesn't block. That is, the default should let the user 
execute the page.
+               list( $output, ) = $this->executeSpecialPage( '' );
+
+               $this->assertInternalType( 'string', $output );
+               $this->assertContains( 'wikibase-listproperties-summary', 
$output );
+               $this->assertContains( 'wikibase-listproperties-legend', 
$output );
+
+               list( $output, ) = $this->executeSpecialPage( 'url' );
+
+               $this->assertContains( 'specialpage-empty', $output );
+       }
+
+}
+

-- 
To view, visit https://gerrit.wikimedia.org/r/203527
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I79a08ec87bf76adba869d4b7eb22098b41fbdb72
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Bene <benestar.wikime...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to