jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/376645 )

Change subject: Enable indexing statements on items
......................................................................


Enable indexing statements on items

Statements are indexed in the field 'statements' and are represented
as 'property:value' e.g. P31:Q4167410.

The list of properties indexed is configured by searchIndexProperties
config var.

Bug: T175199
Change-Id: I880808d70ed5350d39c81e1f41560dccfd982d00
---
M docs/options.wiki
M lib/includes/DataTypeDefinitions.php
M repo/Wikibase.hooks.php
M repo/Wikibase.php
M repo/WikibaseRepo.datatypes.php
M repo/config/Wikibase.default.php
M repo/includes/Search/Elastic/Fields/ItemFieldDefinitions.php
M repo/includes/Search/Elastic/Fields/PropertyFieldDefinitions.php
A repo/includes/Search/Elastic/Fields/StatementProviderFieldDefinitions.php
A repo/includes/Search/Elastic/Fields/StatementsField.php
M repo/includes/WikibaseRepo.php
M repo/tests/phpunit/includes/Search/Elastic/Fields/ItemFieldDefinitionsTest.php
A repo/tests/phpunit/includes/Search/Elastic/Fields/StatementsFieldTest.php
13 files changed, 393 insertions(+), 11 deletions(-)

Approvals:
  jenkins-bot: Verified
  Thiemo Mättig (WMDE): Looks good to me, approved



diff --git a/docs/options.wiki b/docs/options.wiki
index e6d55c5..e17c651 100644
--- a/docs/options.wiki
+++ b/docs/options.wiki
@@ -66,6 +66,7 @@
 :;prefixSearchProfiles: Loaded from 
<code>config/EntityPrefixSearchProfiles.php</code>, does not need to be defined 
manually. (Cirrus)
 :;defaultPrefixRescoreProfile: name of the rescoring profile to use for prefix 
search. The profile should be defined in 
<code>config/ElasticSearchRescoreProfiles.php</code>. (Cirrus)
 :;rescoreProfiles: Loaded from 
<code>config/ElasticSearchRescoreProfiles.php</code>, does not have to be 
defined manually. (Cirrus).
+;searchIndexProperties: Array of names of properties that would be included in 
the 'properties' field of the search index. For now, only relevant when Cirrus 
search is enabled.
 == Client Settings ==
 
 === Basic Settings ===
diff --git a/lib/includes/DataTypeDefinitions.php 
b/lib/includes/DataTypeDefinitions.php
index 4f4ba53..cc6cc94 100644
--- a/lib/includes/DataTypeDefinitions.php
+++ b/lib/includes/DataTypeDefinitions.php
@@ -314,4 +314,12 @@
                );
        }
 
+       /**
+        * Get data formatters for search indexing for each type.
+        * @return callable[] List of callbacks, with keys having "VT:" 
prefixes.
+        */
+       public function getIndexDataFormatters() {
+               return $this->getMapForDefinitionField( 
'search-index-data-formatter' );
+       }
+
 }
diff --git a/repo/Wikibase.hooks.php b/repo/Wikibase.hooks.php
index c9a0c45..7500e9d 100644
--- a/repo/Wikibase.hooks.php
+++ b/repo/Wikibase.hooks.php
@@ -35,6 +35,7 @@
 use Wikibase\Repo\Content\EntityHandler;
 use Wikibase\Repo\Hooks\InfoActionHookHandler;
 use Wikibase\Repo\Hooks\OutputPageEntityIdReader;
+use Wikibase\Repo\Search\Elastic\Fields\StatementsField;
 use Wikibase\Repo\WikibaseRepo;
 use Wikibase\Store\Sql\SqlSubscriptionLookup;
 use WikiPage;
@@ -983,4 +984,26 @@
                $pageInfo = $infoActionHookHandler->handle( $context, $pageInfo 
);
        }
 
+       /**
+        * Add Wikibase-specific analyzer configs.
+        * @param array $config
+        */
+       public static function onCirrusSearchAnalysisConfig( &$config ) {
+               // Analyzer for splitting statements and extracting properties:
+               // P31:Q1234 => P31
+               $config['analyzer']['extract_wb_property'] = [
+                       'type' => 'custom',
+                       'tokenizer' => 'split_wb_statements',
+                       'filter' => [ 'first_token' ],
+               ];
+               $config['tokenizer']['split_wb_statements'] = [
+                       'type' => 'pattern',
+                       'pattern' => StatementsField::STATEMENT_SEPARATOR,
+               ];
+               $config['filter']['first_token'] = [
+                       'type' => 'limit',
+                       'max_token_count' => 1
+               ];
+       }
+
 }
diff --git a/repo/Wikibase.php b/repo/Wikibase.php
index 75c87b2..82fa168 100644
--- a/repo/Wikibase.php
+++ b/repo/Wikibase.php
@@ -1003,6 +1003,7 @@
        $wgHooks['BeforeDisplayNoArticleText'][] = 
'Wikibase\ViewEntityAction::onBeforeDisplayNoArticleText';
        $wgHooks['InfoAction'][] = '\Wikibase\RepoHooks::onInfoAction';
        $wgHooks['BeforePageDisplayMobile'][] = 
'\Wikibase\RepoHooks::onBeforePageDisplayMobile';
+       $wgHooks['CirrusSearchAnalysisConfig'][] = 
'\Wikibase\RepoHooks::onCirrusSearchAnalysisConfig';
 
        // update hooks
        $wgHooks['LoadExtensionSchemaUpdates'][] = 
'\Wikibase\Repo\Store\Sql\ChangesSubscriptionSchemaUpdater::onSchemaUpdate';
diff --git a/repo/WikibaseRepo.datatypes.php b/repo/WikibaseRepo.datatypes.php
index f71b329..b4683f3 100644
--- a/repo/WikibaseRepo.datatypes.php
+++ b/repo/WikibaseRepo.datatypes.php
@@ -25,11 +25,13 @@
  */
 
 use DataValues\Geo\Parsers\GlobeCoordinateParser;
+use DataValues\StringValue;
 use ValueFormatters\FormatterOptions;
 use ValueParsers\ParserOptions;
 use ValueParsers\QuantityParser;
 use ValueParsers\StringParser;
 use ValueParsers\ValueParser;
+use Wikibase\DataModel\Entity\EntityIdValue;
 use Wikibase\Lib\Store\FieldPropertyInfoProvider;
 use Wikibase\Lib\Store\PropertyInfoStore;
 use Wikibase\Rdf\DedupeBag;
@@ -249,6 +251,11 @@
                        ) {
                                return new LiteralValueRdfBuilder( null, null );
                        },
+                       'search-index-data-formatter' => function(
+                               StringValue $value
+                       ) {
+                               return $value->getValue();
+                       },
                ],
                'VT:time' => [
                        'expert-module' => 'jquery.valueview.experts.TimeInput',
@@ -340,6 +347,11 @@
                        ) {
                                return new EntityIdRdfBuilder( $vocab, $tracker 
);
                        },
+                       'search-index-data-formatter' => function(
+                               EntityIdValue $value
+                       ) {
+                               return 
$value->getEntityId()->getSerialization();
+                       },
                ],
                'PT:wikibase-item' => [
                        'expert-module' => 'wikibase.experts.Item',
diff --git a/repo/config/Wikibase.default.php b/repo/config/Wikibase.default.php
index 40b6e9b..4de2da9 100644
--- a/repo/config/Wikibase.default.php
+++ b/repo/config/Wikibase.default.php
@@ -256,4 +256,7 @@
                // Rescore profiles, loaded by Wikibase.php
                'rescoreProfiles' => [],
        ],
+
+       // List of properties to be indexed
+       'searchIndexProperties' => []
 ];
diff --git a/repo/includes/Search/Elastic/Fields/ItemFieldDefinitions.php 
b/repo/includes/Search/Elastic/Fields/ItemFieldDefinitions.php
index 8e9edb5..4d6a6b3 100644
--- a/repo/includes/Search/Elastic/Fields/ItemFieldDefinitions.php
+++ b/repo/includes/Search/Elastic/Fields/ItemFieldDefinitions.php
@@ -16,12 +16,19 @@
         */
        private $descriptionsProviderFieldDefinitions;
 
+       /**
+        * @var StatementProviderFieldDefinitions
+        */
+       private $statementProviderFieldDefinitions;
+
        public function __construct(
                LabelsProviderFieldDefinitions $labelsProviderFieldDefinitions,
-               DescriptionsProviderFieldDefinitions 
$descriptionsProviderFieldDefinitions
+               DescriptionsProviderFieldDefinitions 
$descriptionsProviderFieldDefinitions,
+               StatementProviderFieldDefinitions 
$statementProviderFieldDefinitions
        ) {
                $this->labelsProviderFieldDefinitions = 
$labelsProviderFieldDefinitions;
                $this->descriptionsProviderFieldDefinitions = 
$descriptionsProviderFieldDefinitions;
+               $this->statementProviderFieldDefinitions = 
$statementProviderFieldDefinitions;
        }
 
        /**
@@ -33,15 +40,15 @@
                 * - labels
                 * - descriptions
                 * - link count
-                * - statement count
+                * - statements
                 */
                $fields = array_merge(
                        $this->labelsProviderFieldDefinitions->getFields(),
-                       $this->descriptionsProviderFieldDefinitions->getFields()
+                       
$this->descriptionsProviderFieldDefinitions->getFields(),
+                       $this->statementProviderFieldDefinitions->getFields()
                );
 
                $fields['sitelink_count'] = new SiteLinkCountField();
-               $fields['statement_count'] = new StatementCountField();
 
                return $fields;
        }
diff --git a/repo/includes/Search/Elastic/Fields/PropertyFieldDefinitions.php 
b/repo/includes/Search/Elastic/Fields/PropertyFieldDefinitions.php
index 1d2e760..0db6a14 100644
--- a/repo/includes/Search/Elastic/Fields/PropertyFieldDefinitions.php
+++ b/repo/includes/Search/Elastic/Fields/PropertyFieldDefinitions.php
@@ -16,12 +16,19 @@
         */
        private $descriptionsProviderFieldDefinitions;
 
+       /**
+        * @var StatementProviderFieldDefinitions
+        */
+       private $statementProviderFieldDefinitions;
+
        public function __construct(
                LabelsProviderFieldDefinitions $labelsProviderFieldDefinitions,
-               DescriptionsProviderFieldDefinitions 
$descriptionsProviderFieldDefinitions
+               DescriptionsProviderFieldDefinitions 
$descriptionsProviderFieldDefinitions,
+               StatementProviderFieldDefinitions 
$statementProviderFieldDefinitions
        ) {
                $this->labelsProviderFieldDefinitions = 
$labelsProviderFieldDefinitions;
                $this->descriptionsProviderFieldDefinitions = 
$descriptionsProviderFieldDefinitions;
+               $this->statementProviderFieldDefinitions = 
$statementProviderFieldDefinitions;
        }
 
        /**
@@ -32,14 +39,14 @@
                 * Properties have:
                 * - labels
                 * - descriptions
+                * - statements
                 * - statement count
                 */
                $fields = array_merge(
                        $this->labelsProviderFieldDefinitions->getFields(),
-                       $this->descriptionsProviderFieldDefinitions->getFields()
+                       
$this->descriptionsProviderFieldDefinitions->getFields(),
+                       $this->statementProviderFieldDefinitions->getFields()
                );
-
-               $fields['statement_count'] = new StatementCountField();
 
                return $fields;
        }
diff --git 
a/repo/includes/Search/Elastic/Fields/StatementProviderFieldDefinitions.php 
b/repo/includes/Search/Elastic/Fields/StatementProviderFieldDefinitions.php
new file mode 100644
index 0000000..285c2d0
--- /dev/null
+++ b/repo/includes/Search/Elastic/Fields/StatementProviderFieldDefinitions.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Wikibase\Repo\Search\Elastic\Fields;
+
+use Wikibase\Lib\DataTypeDefinitions;
+
+/**
+ * Fields for an object that has statements.
+ */
+class StatementProviderFieldDefinitions implements FieldDefinitions {
+
+       /**
+        * List of properties to index.
+        * @var string[]
+        */
+       private $properties;
+
+       /**
+        * @var callable[]
+        */
+       private $definitions;
+
+       /**
+        * StatementProviderFieldDefinitions constructor.
+        * @param string[] $properties List of properties to index
+        * @param callable[] $definitions
+        */
+       public function __construct( array $properties, array $definitions ) {
+               $this->definitions = $definitions;
+               $this->properties = $properties;
+       }
+
+       /**
+        * Get the list of definitions
+        * @return WikibaseIndexField[] key is field name, value is 
WikibaseIndexField
+        */
+       public function getFields() {
+               $fields['statement_keywords'] = new StatementsField( 
$this->properties, $this->definitions );
+               $fields['statement_count'] = new StatementCountField();
+               return $fields;
+       }
+
+}
diff --git a/repo/includes/Search/Elastic/Fields/StatementsField.php 
b/repo/includes/Search/Elastic/Fields/StatementsField.php
new file mode 100644
index 0000000..985fbcd
--- /dev/null
+++ b/repo/includes/Search/Elastic/Fields/StatementsField.php
@@ -0,0 +1,134 @@
+<?php
+namespace Wikibase\Repo\Search\Elastic\Fields;
+
+use CirrusSearch;
+use SearchEngine;
+use SearchIndexFieldDefinition;
+use Wikibase\DataModel\Entity\EntityDocument;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\DataModel\Statement\StatementListProvider;
+
+/**
+ * Field indexing statements for particular item.
+ */
+class StatementsField extends SearchIndexFieldDefinition implements 
WikibaseIndexField {
+
+       /**
+        * String which separates property from value in statement 
representation.
+        * Should be the string that is:
+        * - Not part of property ID serialization
+        * - Regex-safe
+        */
+       const STATEMENT_SEPARATOR = '=';
+
+       /**
+        * List of properties to index
+        * @var string[]
+        */
+       private $properties;
+
+       /**
+        * @var callable[]
+        */
+       private $definitions;
+
+       /**
+        * StatementsField constructor.
+        * @param string[] $properties
+        * @param callable[] $definitions
+        */
+       public function __construct( array $properties, array $definitions ) {
+               $this->properties = $properties;
+               $this->definitions = $definitions;
+               parent::__construct( "", \SearchIndexField::INDEX_TYPE_KEYWORD 
);
+       }
+
+       /**
+        * Produce specific field mapping
+        *
+        * @param SearchEngine $engine
+        * @param string $name
+        *
+        * @return \SearchIndexField|null Null if mapping is not supported
+        */
+       public function getMappingField( SearchEngine $engine, $name ) {
+               if ( !( $engine instanceof CirrusSearch ) ) {
+                       // For now only Cirrus/Elastic is supported
+                       return null;
+               }
+               return $this;
+       }
+
+       /**
+        * @param EntityDocument $entity
+        *
+        * @return mixed Get the value of the field to be indexed when a 
page/document
+        *               is indexed. This might be an array with nested data, 
if the field
+        *               is defined with nested type or an int or string for 
simple field types.
+        */
+       public function getFieldData( EntityDocument $entity ) {
+               if ( !( $entity instanceof StatementListProvider ) ) {
+                       return [];
+               }
+               $data = [];
+
+               foreach ( $this->properties as $property ) {
+                       try {
+                               $id = new PropertyId( $property );
+                       } catch ( \Exception $e ) {
+                               // If we couldn't resolve ID for this property, 
skip it
+                               continue;
+                       }
+                       foreach ( $entity->getStatements()->getByPropertyId( 
$id )->getMainSnaks() as $snak ) {
+                               if ( !( $snak instanceof PropertyValueSnak ) ) {
+                                       // Won't index novalue/somevalue for now
+                                       continue;
+                               }
+
+                               $dataValue = $snak->getDataValue();
+                               if ( !isset( $this->definitions["VT:" . 
$dataValue->getType()] ) ) {
+                                       // We do not know how to format these 
values
+                                       continue;
+                               }
+                               $callback = $this->definitions["VT:" . 
$dataValue->getType()];
+                               $value = $callback( $dataValue );
+                               if ( !$value ) {
+                                       continue;
+                               }
+                               $data[] = 
$snak->getPropertyId()->getSerialization() . self::STATEMENT_SEPARATOR
+                                         . $value;
+                       }
+               }
+
+               return $data;
+       }
+
+       /**
+        * @param SearchEngine $engine
+        * @return array
+        */
+       public function getMapping( SearchEngine $engine ) {
+               // Since we need a specially tuned field, we can not use
+               // standard search engine types.
+               if ( !( $engine instanceof CirrusSearch ) ) {
+                       // For now only Cirrus/Elastic is supported
+                       return [];
+               }
+
+               $config = [
+                       'type' => 'keyword',
+                       "ignore_above" => 255
+               ];
+               // Subfield indexing only property names, so we could do matches
+               // like "property exists" without specifying the value.
+               $config['fields']['property'] = [
+                       'type' => 'text',
+                       'analyzer' => "extract_wb_property",
+                       'search_analyzer' => 'keyword',
+               ];
+
+               return $config;
+       }
+
+}
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index 6e69dba..10a47dc 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -99,6 +99,7 @@
 use Wikibase\Repo\Search\Elastic\Fields\ItemFieldDefinitions;
 use Wikibase\Repo\Search\Elastic\Fields\LabelsProviderFieldDefinitions;
 use Wikibase\Repo\Search\Elastic\Fields\PropertyFieldDefinitions;
+use Wikibase\Repo\Search\Elastic\Fields\StatementProviderFieldDefinitions;
 use Wikibase\Repo\Store\EntityTitleStoreLookup;
 use Wikibase\Lib\Store\LanguageFallbackLabelDescriptionLookupFactory;
 use Wikibase\Lib\Store\PrefetchingTermLookup;
@@ -1465,11 +1466,22 @@
        }
 
        /**
+        * @return StatementProviderFieldDefinitions
+        */
+       public function getStatementProviderDefinitions() {
+               return new StatementProviderFieldDefinitions(
+                       $this->settings->getSetting( 'searchIndexProperties' ),
+                       
$this->getDataTypeDefinitions()->getIndexDataFormatters()
+               );
+       }
+
+       /**
         * @return ItemFieldDefinitions
         */
        private function getItemFieldDefinitions() {
                return new ItemFieldDefinitions(
-                       $this->getLabelProviderDefinitions(), 
$this->getDescriptionProviderDefinitions()
+                       $this->getLabelProviderDefinitions(), 
$this->getDescriptionProviderDefinitions(),
+                       $this->getStatementProviderDefinitions()
                );
        }
 
@@ -1478,7 +1490,8 @@
         */
        private function getPropertyFieldDefinitions() {
                return new PropertyFieldDefinitions(
-                       $this->getLabelProviderDefinitions(), 
$this->getDescriptionProviderDefinitions()
+                       $this->getLabelProviderDefinitions(), 
$this->getDescriptionProviderDefinitions(),
+                       $this->getStatementProviderDefinitions()
                );
        }
 
diff --git 
a/repo/tests/phpunit/includes/Search/Elastic/Fields/ItemFieldDefinitionsTest.php
 
b/repo/tests/phpunit/includes/Search/Elastic/Fields/ItemFieldDefinitionsTest.php
index 3c58931..d890f25 100644
--- 
a/repo/tests/phpunit/includes/Search/Elastic/Fields/ItemFieldDefinitionsTest.php
+++ 
b/repo/tests/phpunit/includes/Search/Elastic/Fields/ItemFieldDefinitionsTest.php
@@ -9,6 +9,8 @@
 use Wikibase\Repo\Search\Elastic\Fields\LabelsProviderFieldDefinitions;
 use Wikibase\Repo\Search\Elastic\Fields\SiteLinkCountField;
 use Wikibase\Repo\Search\Elastic\Fields\StatementCountField;
+use Wikibase\Repo\Search\Elastic\Fields\StatementProviderFieldDefinitions;
+use Wikibase\Repo\Search\Elastic\Fields\StatementsField;
 
 /**
  * @covers Wikibase\Repo\Search\Elastic\Fields\ItemFieldDefinitions
@@ -24,7 +26,8 @@
 
                $fieldDefinitions = new ItemFieldDefinitions(
                        $this->newLabelsProviderFieldDefinitions( 
$languageCodes ),
-                       $this->newDescriptionsProviderFieldDefinitions( 
$languageCodes )
+                       $this->newDescriptionsProviderFieldDefinitions( 
$languageCodes ),
+                       new StatementProviderFieldDefinitions( [], [] )
                );
 
                $fields = $fieldDefinitions->getFields();
@@ -37,6 +40,9 @@
 
                $this->assertArrayHasKey( 'statement_count', $fields );
                $this->assertInstanceOf( StatementCountField::class, 
$fields['statement_count'] );
+
+               $this->assertArrayHasKey( 'statement_keywords', $fields );
+               $this->assertInstanceOf( StatementsField::class, 
$fields['statement_keywords'] );
        }
 
        private function newLabelsProviderFieldDefinitions( array 
$languageCodes ) {
diff --git 
a/repo/tests/phpunit/includes/Search/Elastic/Fields/StatementsFieldTest.php 
b/repo/tests/phpunit/includes/Search/Elastic/Fields/StatementsFieldTest.php
new file mode 100644
index 0000000..2f8a8ef
--- /dev/null
+++ b/repo/tests/phpunit/includes/Search/Elastic/Fields/StatementsFieldTest.php
@@ -0,0 +1,124 @@
+<?php
+
+namespace Wikibase\Repo\Tests\Search\Elastic\Fields;
+
+use CirrusSearch;
+use DataValues\BooleanValue;
+use DataValues\DecimalValue;
+use DataValues\StringValue;
+use DataValues\UnboundedQuantityValue;
+use PHPUnit_Framework_TestCase;
+use Wikibase\DataModel\Entity\EntityDocument;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Snak\PropertyNoValueSnak;
+use Wikibase\DataModel\Snak\PropertySomeValueSnak;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\DataModel\Statement\StatementListProvider;
+use Wikibase\Repo\Search\Elastic\Fields\StatementsField;
+use Wikibase\Repo\Tests\ChangeOp\StatementListProviderDummy;
+use Wikibase\Repo\Tests\Rdf\RdfBuilderTestData;
+use Wikibase\Repo\WikibaseRepo;
+
+/**
+ * @covers Wikibase\Repo\Search\Elastic\Fields\StatementsField
+ *
+ * @group WikibaseElastic
+ * @group Wikibase
+ *
+ */
+class StatementsFieldTest extends PHPUnit_Framework_TestCase {
+
+       /**
+        * List of properties we handle.
+        * @var string[]
+        */
+       private $properties = [ 'P1', 'P2', 'P4', 'P7', 'P8' ];
+
+       public function statementsProvider() {
+               $testData = new RdfBuilderTestData(
+                       __DIR__ . '/../../../../data/rdf/entities', ''
+               );
+
+               return [
+                       'empty' => [
+                               $testData->getEntity( 'Q1' ),
+                               []
+                       ],
+                       'Q4' => [
+                               $testData->getEntity( 'Q4' ),
+                               [ 'P2=Q42', 'P2=Q666', 'P7=simplestring' ]
+                       ],
+                       'Q7' => [
+                               $testData->getEntity( 'Q7' ),
+                               [ 'P7=string', 'P7=string2' ]
+                       ],
+                       'Q8' => [
+                               $testData->getEntity( 'Q8' ),
+                               []
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider statementsProvider
+        * @param EntityDocument $entity
+        * @param $expected
+        */
+       public function testStatements( EntityDocument $entity, $expected ) {
+               if ( !class_exists( CirrusSearch::class ) ) {
+                       $this->markTestSkipped( 'CirrusSearch needed.' );
+               }
+               $repo = WikibaseRepo::getDefaultInstance();
+
+               $field = new StatementsField( $this->properties, 
$repo->getDataTypeDefinitions()->getIndexDataFormatters() );
+               $this->assertEquals( $expected, $field->getFieldData( $entity ) 
);
+       }
+
+       public function testFormatters() {
+               $formatters = [
+                       'VT:string' => function ( StringValue $s ) {
+                               return "STRING:" . $s->getValue();
+                       },
+
+                       'VT:quantity' => function ( UnboundedQuantityValue $v ) 
{
+                               return "VALUE:" . $v->getAmount();
+                       },
+
+               ];
+               $field = new StatementsField( [ 'P123' ], $formatters );
+
+               $snaks = [
+                       new PropertyValueSnak( 123, new StringValue( 
'testString' ) ),
+                       new PropertyValueSnak( 123,
+                               new UnboundedQuantityValue( new DecimalValue( 
456 ), "1" ) ),
+                       new PropertySomeValueSnak( 123 ),
+                       new PropertyValueSnak( 123, new StringValue( 
'testString2' ) ),
+                       new PropertyNoValueSnak( 123 ),
+                       new PropertyValueSnak( 123, new BooleanValue( false ) ),
+               ];
+
+               $mockList = $this->getMockBuilder( StatementListProvider::class 
)->setMethods( [
+                       'getByPropertyId',
+                       'getMainSnaks',
+                       'getStatements',
+               ] )->getMock();
+               $mockList->expects( $this->once() )->method( 'getByPropertyId' 
)->willReturnSelf();
+               $mockList->expects( $this->once() )->method( 'getMainSnaks' 
)->willReturn( $snaks );
+
+               $entity =
+                       $this->getMockBuilder( 
StatementListProviderDummy::class )
+                               ->disableOriginalConstructor()
+                               ->getMock();
+               $entity->expects( $this->once() )->method( 'getStatements' 
)->willReturn( $mockList );
+
+               $expected = [
+                       'P123=STRING:testString',
+                       'P123=VALUE:+456',
+                       'P123=STRING:testString2'
+               ];
+
+               $data = $field->getFieldData( $entity );
+               $this->assertEquals( $expected, $data );
+       }
+
+}

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I880808d70ed5350d39c81e1f41560dccfd982d00
Gerrit-PatchSet: 21
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Smalyshev <smalys...@wikimedia.org>
Gerrit-Reviewer: Addshore <addshorew...@gmail.com>
Gerrit-Reviewer: Aleksey Bekh-Ivanov (WMDE) <aleksey.bekh-iva...@wikimedia.de>
Gerrit-Reviewer: Aude <aude.w...@gmail.com>
Gerrit-Reviewer: DCausse <dcau...@wikimedia.org>
Gerrit-Reviewer: Daniel Kinzler <daniel.kinz...@wikimedia.de>
Gerrit-Reviewer: EBernhardson <ebernhard...@wikimedia.org>
Gerrit-Reviewer: Hoo man <h...@online.de>
Gerrit-Reviewer: Smalyshev <smalys...@wikimedia.org>
Gerrit-Reviewer: Thiemo Mättig (WMDE) <thiemo.maet...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to