jenkins-bot has submitted this change and it was merged.

Change subject: Introduce SnakRdfBuilder.
......................................................................


Introduce SnakRdfBuilder.

Factor common code out of FullStatementRdfBuilder and TruthyStatementRdfBuilder.
Introduce DataValueRdfBuilder interface to replace SnakValueRdfBuilder.

This is done in preparation for introducing a registry for DataValueRdfBuilders
for different data types, instead of hardcoding handling for all known types
directly.

Change-Id: I946f4593895c49c937bad0c0c66e1cf0e932ad2a
---
M repo/includes/rdf/ComplexValueRdfBuilder.php
A repo/includes/rdf/DataValueRdfBuilder.php
M repo/includes/rdf/FullStatementRdfBuilder.php
M repo/includes/rdf/RdfBuilder.php
M repo/includes/rdf/SimpleValueRdfBuilder.php
A repo/includes/rdf/SnakRdfBuilder.php
D repo/includes/rdf/SnakValueRdfBuilder.php
M repo/includes/rdf/TruthyStatementRdfBuilder.php
M repo/tests/phpunit/includes/rdf/ComplexValueRdfBuilderTest.php
M repo/tests/phpunit/includes/rdf/FullStatementsRdfBuilderTest.php
M repo/tests/phpunit/includes/rdf/SimpleValueRdfBuilderTest.php
A repo/tests/phpunit/includes/rdf/SnakRdfBuilderTest.php
M repo/tests/phpunit/includes/rdf/TruthyStatementsRdfBuilderTest.php
13 files changed, 472 insertions(+), 207 deletions(-)

Approvals:
  Hoo man: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/repo/includes/rdf/ComplexValueRdfBuilder.php 
b/repo/includes/rdf/ComplexValueRdfBuilder.php
index e929fde..4f71190 100644
--- a/repo/includes/rdf/ComplexValueRdfBuilder.php
+++ b/repo/includes/rdf/ComplexValueRdfBuilder.php
@@ -63,8 +63,8 @@
         * @param string $dataType Property data type
         * @param DataValue $value
         */
-       protected function addValueForDataType( RdfWriter $writer, 
$propertyValueNamespace, $propertyValueLName, $dataType, $value ) {
-               parent::addValueForDataType( $writer, $propertyValueNamespace, 
$propertyValueLName, $dataType, $value );
+       public function addValue( RdfWriter $writer, $propertyValueNamespace, 
$propertyValueLName, $dataType, $value ) {
+               parent::addValue( $writer, $propertyValueNamespace, 
$propertyValueLName, $dataType, $value );
 
                switch ( $value->getType() ) {
                        case 'time':
diff --git a/repo/includes/rdf/DataValueRdfBuilder.php 
b/repo/includes/rdf/DataValueRdfBuilder.php
new file mode 100644
index 0000000..a442d83
--- /dev/null
+++ b/repo/includes/rdf/DataValueRdfBuilder.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Wikibase\Rdf;
+
+use DataValues\DataValue;
+use Wikimedia\Purtle\RdfWriter;
+
+/**
+ * Interface for RDF mapping for wikibase data values.
+ *
+ * @since 0.5
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ * @author Stas Malyshev
+ */
+interface DataValueRdfBuilder {
+
+       /**
+        * Adds specific value
+        *
+        * @param RdfWriter $writer
+        * @param string $propertyValueNamespace Property value relation 
namespace
+        * @param string $propertyValueLName Property value relation name
+        * @param string $dataType Property data type
+        * @param DataValue $value
+        */
+       public function addValue(
+               RdfWriter $writer,
+               $propertyValueNamespace,
+               $propertyValueLName,
+               $dataType,
+               $value
+       );
+
+}
diff --git a/repo/includes/rdf/FullStatementRdfBuilder.php 
b/repo/includes/rdf/FullStatementRdfBuilder.php
index cd6dd25..625376d 100644
--- a/repo/includes/rdf/FullStatementRdfBuilder.php
+++ b/repo/includes/rdf/FullStatementRdfBuilder.php
@@ -2,12 +2,9 @@
 
 namespace Wikibase\Rdf;
 
-use InvalidArgumentException;
 use Wikibase\DataModel\Entity\EntityDocument;
 use Wikibase\DataModel\Entity\EntityId;
 use Wikibase\DataModel\Reference;
-use Wikibase\DataModel\Snak\PropertyValueSnak;
-use Wikibase\DataModel\Snak\Snak;
 use Wikibase\DataModel\Statement\Statement;
 use Wikibase\DataModel\Statement\StatementList;
 use Wikibase\DataModel\Statement\StatementListProvider;
@@ -29,11 +26,6 @@
  * @author Stas Malyshev
  */
 class FullStatementRdfBuilder implements EntityRdfBuilder {
-
-       /**
-        * @var EntityMentionListener
-        */
-       private $mentionedEntityTracker;
 
        /**
         * @var DedupeBag
@@ -66,16 +58,16 @@
        private $referenceWriter;
 
        /**
-        * @var SnakValueRdfBuilder
+        * @var SnakRdfBuilder
         */
-       private $valueBuilder;
+       private $snakBuilder;
 
        /**
         * @param RdfVocabulary $vocabulary
         * @param RdfWriter $writer
-        * @param SnakValueRdfBuilder $valueBuilder
+        * @param SnakRdfBuilder $snakBuilder
         */
-       public function __construct( RdfVocabulary $vocabulary, RdfWriter 
$writer, SnakValueRdfBuilder $valueBuilder ) {
+       public function __construct( RdfVocabulary $vocabulary, RdfWriter 
$writer, SnakRdfBuilder $snakBuilder ) {
                $this->vocabulary = $vocabulary;
 
                // Note: since we process references as nested structures, they 
need a separate
@@ -83,24 +75,9 @@
                $this->statementWriter = $writer;
                $this->referenceWriter = $writer->sub();
 
-               $this->valueBuilder = $valueBuilder;
+               $this->snakBuilder = $snakBuilder;
 
-               $this->mentionedEntityTracker = new NullEntityMentionListener();
                $this->dedupeBag = new NullDedupeBag();
-       }
-
-       /**
-        * @return EntityMentionListener
-        */
-       public function getEntityMentionListener() {
-               return $this->mentionedEntityTracker;
-       }
-
-       /**
-        * @param EntityMentionListener $mentionedEntityTracker
-        */
-       public function setEntityMentionListener( $mentionedEntityTracker ) {
-               $this->mentionedEntityTracker = $mentionedEntityTracker;
        }
 
        /**
@@ -182,7 +159,7 @@
                if ( $this->produceQualifiers ) {
                        // this assumes statement was added by addMainSnak
                        foreach ( $statement->getQualifiers() as $q ) {
-                               $this->addSnak( $this->statementWriter, $q, 
RdfVocabulary::NSP_QUALIFIER );
+                               $this->snakBuilder->addSnak( 
$this->statementWriter, $q, RdfVocabulary::NSP_QUALIFIER );
                        }
                }
 
@@ -203,7 +180,7 @@
                                        ->a( RdfVocabulary::NS_ONTOLOGY, 
'Reference' );
 
                                foreach ( $reference->getSnaks() as $refSnak ) {
-                                       $this->addSnak( $this->referenceWriter, 
$refSnak, RdfVocabulary::NSP_REFERENCE );
+                                       $this->snakBuilder->addSnak( 
$this->referenceWriter, $refSnak, RdfVocabulary::NSP_REFERENCE );
                                }
                        }
                }
@@ -240,42 +217,7 @@
                        wfLogWarning( "Unknown rank $rank encountered for 
$entityId:{$statement->getGuid()}" );
                }
 
-               $this->addSnak( $this->statementWriter, $snak, 
RdfVocabulary::NSP_CLAIM_STATEMENT );
-               $this->mentionedEntityTracker->propertyMentioned( 
$snak->getPropertyId() );
-
-       }
-
-       /**
-        * Adds the given Statement's main Snak to the RDF graph.
-        *
-        * @todo share more of this code with TruthyStatementRdfBuilder
-        *
-        * @param RdfWriter $writer
-        * @param Snak $snak
-        * @param string $propertyNamespace
-        *
-        * @throws InvalidArgumentException
-        */
-       private function addSnak( RdfWriter $writer, Snak $snak, 
$propertyNamespace ) {
-               $propertyId = $snak->getPropertyId();
-               switch ( $snak->getType() ) {
-                       case 'value':
-                               /** @var PropertyValueSnak $snak */
-                               $this->valueBuilder->addSnakValue( $writer, 
$propertyId, $snak->getDataValue(), $propertyNamespace );
-                               break;
-                       case 'somevalue':
-                               $propertyValueLName = 
$this->vocabulary->getEntityLName( $propertyId );
-
-                               $writer->say( $propertyNamespace, 
$propertyValueLName )->is( '_', $writer->blank() );
-                               break;
-                       case 'novalue':
-                               $propertyValueLName = 
$this->vocabulary->getEntityLName( $propertyId );
-
-                               $writer->say( 'a' )->is( 
RdfVocabulary::NSP_NOVALUE, $propertyValueLName );
-                               break;
-                       default:
-                               throw new InvalidArgumentException( 'Unknown 
snak type: ' . $snak->getType() );
-               }
+               $this->snakBuilder->addSnak( $this->statementWriter, $snak, 
RdfVocabulary::NSP_CLAIM_STATEMENT );
        }
 
        /**
diff --git a/repo/includes/rdf/RdfBuilder.php b/repo/includes/rdf/RdfBuilder.php
index 50c23ea..4255c9c 100644
--- a/repo/includes/rdf/RdfBuilder.php
+++ b/repo/includes/rdf/RdfBuilder.php
@@ -119,7 +119,7 @@
        }
 
        /**
-        * @return SnakValueRdfBuilder
+        * @return DataValueRdfBuilder
         */
        private function newSimpleValueRdfBuilder() {
                $simpleValueBuilder = new SimpleValueRdfBuilder( 
$this->vocabulary, $this->propertyLookup );
@@ -129,21 +129,33 @@
        }
 
        /**
-        * @return SnakValueRdfBuilder
+        * @return DataValueRdfBuilder
         */
-       private function newSnakValueBuilder() {
-               if ( $this->shouldProduce( RdfProducer::PRODUCE_FULL_VALUES ) ) 
{
-                       // NOTE: use sub-writers for nested structures
-                       $valueWriter = $this->writer->sub();
+       private function newComplexValueRdfBuilder() {
+               // NOTE: use sub-writers for nested structures
+               $valueWriter = $this->writer->sub();
 
-                       $statementValueBuilder = new ComplexValueRdfBuilder( 
$this->vocabulary, $valueWriter, $this->propertyLookup );
-                       $statementValueBuilder->setDedupeBag( $this->dedupBag );
-                       $statementValueBuilder->setEntityMentionListener( $this 
);
+               $statementValueBuilder = new ComplexValueRdfBuilder( 
$this->vocabulary, $valueWriter, $this->propertyLookup );
+               $statementValueBuilder->setDedupeBag( $this->dedupBag );
+               $statementValueBuilder->setEntityMentionListener( $this );
+
+               return $statementValueBuilder;
+       }
+
+       /**
+        * @return SnakRdfBuilder
+        */
+       private function newSnakBuilder( $full ) {
+               if ( $full === 'full' ) {
+                       $statementValueBuilder = 
$this->newComplexValueRdfBuilder();
                } else {
                        $statementValueBuilder = 
$this->newSimpleValueRdfBuilder();
                }
 
-               return $statementValueBuilder;
+               $snakBuilder = new SnakRdfBuilder( $this->vocabulary, 
$statementValueBuilder, $this->propertyLookup );
+               $snakBuilder->setEntityMentionListener( $this );
+
+               return $snakBuilder;
        }
 
        /**
@@ -151,8 +163,8 @@
         */
        private function newTruthyStatementRdfBuilder() {
                //NOTE: currently, the only simple values are supported in 
truthy mode!
-               $simpleValueBuilder = $this->newSimpleValueRdfBuilder();
-               $statementBuilder = new TruthyStatementRdfBuilder( 
$this->vocabulary, $this->writer, $simpleValueBuilder );
+               $simpleSnakBuilder = $this->newSnakBuilder( 'simple' );
+               $statementBuilder = new TruthyStatementRdfBuilder( 
$this->vocabulary, $this->writer, $simpleSnakBuilder );
 
                return $statementBuilder;
        }
@@ -161,11 +173,10 @@
         * @return EntityRdfBuilder
         */
        private function newFullStatementRdfBuilder() {
-               $statementValueBuilder = $this->newSnakValueBuilder();
+               $statementValueBuilder = $this->newSnakBuilder( 
$this->shouldProduce( RdfProducer::PRODUCE_FULL_VALUES ) ? 'full' : 'simple' );
 
                $statementBuilder = new FullStatementRdfBuilder( 
$this->vocabulary, $this->writer, $statementValueBuilder );
                $statementBuilder->setDedupeBag( $this->dedupBag );
-               $statementBuilder->setEntityMentionListener( $this );
                $statementBuilder->setProduceQualifiers( $this->shouldProduce( 
RdfProducer::PRODUCE_QUALIFIERS ) );
                $statementBuilder->setProduceReferences( $this->shouldProduce( 
RdfProducer::PRODUCE_REFERENCES ) );
 
diff --git a/repo/includes/rdf/SimpleValueRdfBuilder.php 
b/repo/includes/rdf/SimpleValueRdfBuilder.php
index c9b0358..ad0eeae 100644
--- a/repo/includes/rdf/SimpleValueRdfBuilder.php
+++ b/repo/includes/rdf/SimpleValueRdfBuilder.php
@@ -10,9 +10,7 @@
 use DataValues\StringValue;
 use DataValues\TimeValue;
 use Wikibase\DataModel\Entity\EntityIdValue;
-use Wikibase\DataModel\Entity\PropertyId;
 use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
-use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException;
 use Wikimedia\Purtle\RdfWriter;
 
 /**
@@ -24,22 +22,12 @@
  * @author Daniel Kinzler
  * @author Stas Malyshev
  */
-class SimpleValueRdfBuilder implements SnakValueRdfBuilder {
+class SimpleValueRdfBuilder implements DataValueRdfBuilder {
 
        /**
         * @var EntityMentionListener
         */
        private $mentionedEntityTracker;
-
-       /**
-        * @var RdfVocabulary
-        */
-       protected $vocabulary;
-
-       /**
-        * @var PropertyDataTypeLookup
-        */
-       private $propertyLookup;
 
        /**
         * @var DateTimeValueCleaner
@@ -74,38 +62,6 @@
        }
 
        /**
-        * Adds the value of the given property to the RDF graph.
-        *
-        * @param RdfWriter $writer
-        * @param PropertyId $propertyId
-        * @param DataValue $value
-        * @param string $propertyNamespace The property namespace for this snak
-        */
-       public function addSnakValue(
-               RdfWriter $writer,
-               PropertyId $propertyId,
-               DataValue $value,
-               $propertyNamespace
-       ) {
-               $propertyValueLName = $this->vocabulary->getEntityLName( 
$propertyId );
-
-               $typeId = $value->getType();
-               $dataType = null;
-
-               if ( $typeId === 'string' ) {
-                       // We only care about the actual data type of strings, 
so we can save time but not asking
-                       // for any other types
-                       try {
-                               $dataType = 
$this->propertyLookup->getDataTypeIdForProperty( $propertyId );
-                       } catch ( PropertyDataTypeLookupException $e ) {
-                               // keep "unknown"
-                       }
-               }
-
-               $this->addValueForDataType( $writer, $propertyNamespace, 
$propertyValueLName, $dataType, $value );
-       }
-
-       /**
         * Adds specific value
         *
         * @param RdfWriter $writer
@@ -114,7 +70,7 @@
         * @param string $dataType Property data type
         * @param DataValue $value
         */
-       protected function addValueForDataType(
+       public function addValue(
                RdfWriter $writer,
                $propertyValueNamespace,
                $propertyValueLName,
diff --git a/repo/includes/rdf/SnakRdfBuilder.php 
b/repo/includes/rdf/SnakRdfBuilder.php
new file mode 100644
index 0000000..6ddb205
--- /dev/null
+++ b/repo/includes/rdf/SnakRdfBuilder.php
@@ -0,0 +1,137 @@
+<?php
+
+namespace Wikibase\Rdf;
+
+use DataValues\DataValue;
+use InvalidArgumentException;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
+use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\DataModel\Snak\Snak;
+use Wikimedia\Purtle\RdfWriter;
+
+/**
+ * Implementation for RDF mapping for Snaks.
+ *
+ * @since 0.5
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ * @author Stas Malyshev
+ */
+class SnakRdfBuilder {
+
+       /**
+        * @var EntityMentionListener
+        */
+       private $mentionedEntityTracker;
+
+       /**
+        * @var RdfVocabulary
+        */
+       private $vocabulary;
+
+       /**
+        * @var DataValueRdfBuilder
+        */
+       private $valueBuilder;
+
+       /**
+        * @var PropertyDataTypeLookup
+        */
+       private $propertyLookup;
+
+       /**
+        * @param RdfVocabulary $vocabulary
+        * @param DataValueRdfBuilder $valueBuilder
+        * @param PropertyDataTypeLookup $propertyLookup
+        */
+       public function __construct( RdfVocabulary $vocabulary, 
DataValueRdfBuilder $valueBuilder, PropertyDataTypeLookup $propertyLookup ) {
+               $this->vocabulary = $vocabulary;
+               $this->valueBuilder = $valueBuilder;
+               $this->propertyLookup = $propertyLookup;
+
+               $this->mentionedEntityTracker = new NullEntityMentionListener();
+       }
+
+       /**
+        * @return EntityMentionListener
+        */
+       public function getEntityMentionListener() {
+               return $this->mentionedEntityTracker;
+       }
+
+       /**
+        * @param EntityMentionListener $mentionedEntityTracker
+        */
+       public function setEntityMentionListener( EntityMentionListener 
$mentionedEntityTracker ) {
+               $this->mentionedEntityTracker = $mentionedEntityTracker;
+       }
+
+       /**
+        * Adds the given Statement's main Snak to the RDF graph.
+        *
+        * @param RdfWriter $writer
+        * @param Snak $snak
+        * @param string $propertyNamespace
+        *
+        * @throws InvalidArgumentException
+        */
+       public function addSnak( RdfWriter $writer, Snak $snak, 
$propertyNamespace ) {
+               $propertyId = $snak->getPropertyId();
+               switch ( $snak->getType() ) {
+                       case 'value':
+                               /** @var PropertyValueSnak $snak */
+                               $this->addSnakValue( $writer, $propertyId, 
$snak->getDataValue(), $propertyNamespace );
+                               break;
+                       case 'somevalue':
+                               $propertyValueLName = 
$this->vocabulary->getEntityLName( $propertyId );
+
+                               $writer->say( $propertyNamespace, 
$propertyValueLName )->is( '_', $writer->blank() );
+                               break;
+                       case 'novalue':
+                               $propertyValueLName = 
$this->vocabulary->getEntityLName( $propertyId );
+
+                               $writer->say( 'a' )->is( 
RdfVocabulary::NSP_NOVALUE, $propertyValueLName );
+                               break;
+                       default:
+                               throw new InvalidArgumentException( 'Unknown 
snak type: ' . $snak->getType() );
+               }
+
+               $this->mentionedEntityTracker->propertyMentioned( 
$snak->getPropertyId() );
+       }
+
+       /**
+        * Adds the value of the given property to the RDF graph.
+        *
+        * @param RdfWriter $writer
+        * @param PropertyId $propertyId
+        * @param DataValue $value
+        * @param string $propertyNamespace The property namespace for this snak
+        */
+       private function addSnakValue(
+               RdfWriter $writer,
+               PropertyId $propertyId,
+               DataValue $value,
+               $propertyNamespace
+       ) {
+               $propertyValueLName = $this->vocabulary->getEntityLName( 
$propertyId );
+
+               $typeId = $value->getType();
+               $dataType = null;
+
+               if ( $typeId === 'string' ) {
+                       // We only care about the actual data type of strings, 
so we can save time but not asking
+                       // for any other types
+                       try {
+                               $dataType = 
$this->propertyLookup->getDataTypeIdForProperty( $propertyId );
+                       } catch ( PropertyDataTypeLookupException $e ) {
+                               // keep "unknown"
+                       }
+               }
+
+               $this->valueBuilder->addValue( $writer, $propertyNamespace, 
$propertyValueLName, $dataType, $value );
+       }
+
+}
diff --git a/repo/includes/rdf/SnakValueRdfBuilder.php 
b/repo/includes/rdf/SnakValueRdfBuilder.php
deleted file mode 100644
index aa71e62..0000000
--- a/repo/includes/rdf/SnakValueRdfBuilder.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-namespace Wikibase\Rdf;
-
-use DataValues\DataValue;
-use Wikibase\DataModel\Entity\PropertyId;
-use Wikimedia\Purtle\RdfWriter;
-
-/**
- * Interface for RDF mapping for wikibase data values.
- *
- * @since 0.5
- *
- * @licence GNU GPL v2+
- * @author Daniel Kinzler
- * @author Stas Malyshev
- */
-interface SnakValueRdfBuilder {
-
-       /**
-        * Adds the value of the given property to the RDF graph.
-        *
-        * @param RdfWriter $writer entity-level writer
-        * @param PropertyId $propertyId
-        * @param DataValue $value
-        * @param string $propertyNamespace The property namespace for this snak
-        *
-        * @return
-        */
-       public function addSnakValue(
-               RdfWriter $writer,
-               PropertyId $propertyId,
-               DataValue $value,
-               $propertyNamespace
-       );
-
-}
diff --git a/repo/includes/rdf/TruthyStatementRdfBuilder.php 
b/repo/includes/rdf/TruthyStatementRdfBuilder.php
index 92e3f38..5f9992d 100644
--- a/repo/includes/rdf/TruthyStatementRdfBuilder.php
+++ b/repo/includes/rdf/TruthyStatementRdfBuilder.php
@@ -5,7 +5,6 @@
 use InvalidArgumentException;
 use Wikibase\DataModel\Entity\EntityDocument;
 use Wikibase\DataModel\Entity\EntityId;
-use Wikibase\DataModel\Snak\PropertyValueSnak;
 use Wikibase\DataModel\Statement\Statement;
 use Wikibase\DataModel\Statement\StatementList;
 use Wikibase\DataModel\Statement\StatementListProvider;
@@ -43,19 +42,19 @@
        private $writer;
 
        /**
-        * @var SnakValueRdfBuilder
+        * @var SnakRdfBuilder
         */
-       private $valueBuilder;
+       private $snakBuilder;
 
        /**
         * @param RdfVocabulary $vocabulary
         * @param RdfWriter $writer
-        * @param SnakValueRdfBuilder $valueBuilder
+        * @param SnakRdfBuilder $snakBuilder
         */
-       public function __construct( RdfVocabulary $vocabulary, RdfWriter 
$writer, SnakValueRdfBuilder $valueBuilder ) {
+       public function __construct( RdfVocabulary $vocabulary, RdfWriter 
$writer, SnakRdfBuilder $snakBuilder ) {
                $this->vocabulary = $vocabulary;
                $this->writer = $writer;
-               $this->valueBuilder = $valueBuilder;
+               $this->snakBuilder = $snakBuilder;
        }
 
        /**
@@ -90,25 +89,7 @@
 
                $this->writer->about( RdfVocabulary::NS_ENTITY, $entityLName );
 
-               $propertyId = $snak->getPropertyId();
-               switch ( $snak->getType() ) {
-                       case 'value':
-                               /** @var PropertyValueSnak $snak */
-                               $this->valueBuilder->addSnakValue( 
$this->writer, $propertyId, $snak->getDataValue(), 
RdfVocabulary::NSP_DIRECT_CLAIM );
-                               break;
-                       case 'somevalue':
-                               $propertyValueLName = 
$this->vocabulary->getEntityLName( $propertyId );
-
-                               $this->writer->say( 
RdfVocabulary::NSP_DIRECT_CLAIM, $propertyValueLName )->is( '_', 
$this->writer->blank() );
-                               break;
-                       case 'novalue':
-                               $propertyValueLName = 
$this->vocabulary->getEntityLName( $propertyId );
-
-                               $this->writer->say( 'a' )->is( 
RdfVocabulary::NSP_NOVALUE, $propertyValueLName );
-                               break;
-                       default:
-                               throw new InvalidArgumentException( 'Unknown 
snak type: ' . $snak->getType() );
-               }
+               $this->snakBuilder->addSnak( $this->writer, $snak, 
RdfVocabulary::NSP_DIRECT_CLAIM );
        }
 
        /**
diff --git a/repo/tests/phpunit/includes/rdf/ComplexValueRdfBuilderTest.php 
b/repo/tests/phpunit/includes/rdf/ComplexValueRdfBuilderTest.php
index e91955d..2af4884 100644
--- a/repo/tests/phpunit/includes/rdf/ComplexValueRdfBuilderTest.php
+++ b/repo/tests/phpunit/includes/rdf/ComplexValueRdfBuilderTest.php
@@ -109,12 +109,13 @@
                $this->assertEquals( $expectedTriples, $actualTripels );
        }
 
-       public function provideAddSnakValue() {
+       public function provideAddValue() {
                // NOTE: data types must match 
$this->getTestData()->getMockRepository();
 
                return array(
                        'wikibase-entityid' => array(
                                new PropertyId( 'P2' ),
+                               'wikibase-item',
                                new EntityIdValue( new ItemId( 'Q42' ) ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/statement/P2> <http://acme.test/Q42> .',
@@ -123,6 +124,7 @@
                        ),
                        'commonsMedia' => array(
                                new PropertyId( 'P3' ),
+                               'commonsMedia',
                                new StringValue( 'Test.jpg' ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/statement/P3> 
<http://commons.wikimedia.org/wiki/Special:FilePath/Test.jpg> .',
@@ -131,6 +133,7 @@
                        ),
                        'globecoordinate' => array(
                                new PropertyId( 'P4' ),
+                               'globecoordinate',
                                new GlobeCoordinateValue(
                                        new LatLongValue( 12.25, -45.5 ),
                                        0.025,
@@ -164,6 +167,7 @@
                        ),
                        'monolingualtext' => array(
                                new PropertyId( 'P5' ),
+                               'monolingualtext',
                                new MonolingualTextValue( 'ru', 'Берлин' ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/statement/P5> "\u0411\u0435\u0440\u043B\u0438\u043D"@ru 
.',
@@ -172,6 +176,7 @@
                        ),
                        'quantity' => array(
                                new PropertyId( 'P6' ),
+                               'quantity',
                                new QuantityValue(
                                        new DecimalValue( '+0.00011' ),
                                        '1',
@@ -200,6 +205,7 @@
                        ),
                        'quantity-unit' => array(
                                new PropertyId( 'P6' ),
+                               'quantity',
                                new QuantityValue(
                                        new DecimalValue( '-2.3' ),
                                        
'https://www.wikidata.org/entity/Q11573',
@@ -229,6 +235,7 @@
                        ),
                        'string' => array(
                                new PropertyId( 'P7' ),
+                               'string',
                                new StringValue( 'Kittens' ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/statement/P7> "Kittens" .',
@@ -237,6 +244,7 @@
                        ),
                        'time' => array(
                                new PropertyId( 'P8' ),
+                               'time',
                                new TimeValue( '+2015-03-03T00:00:00Z', 0, 0, 
0, TimeValue::PRECISION_DAY, RdfVocabulary::GREGORIAN_CALENDAR ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/statement/P8> 
"2015-03-03T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .',
@@ -262,6 +270,7 @@
                        ),
                        'time-year' => array( // NOTE: may changed to use 
xsd:gYear
                                new PropertyId( 'P8' ),
+                               'time',
                                new TimeValue( '+2015-00-00T00:00:00Z', 0, 0, 
0, TimeValue::PRECISION_YEAR, RdfVocabulary::GREGORIAN_CALENDAR ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/statement/P8> 
"2015-01-01T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .',
@@ -287,6 +296,7 @@
                        ),
                        'time-margin' => array(
                                new PropertyId( 'P8' ),
+                               'time',
                                new TimeValue( '+2015-03-03T00:00:00Z', 0, 3, 
3, TimeValue::PRECISION_DAY, RdfVocabulary::GREGORIAN_CALENDAR ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/statement/P8> 
"2015-03-03T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .',
@@ -316,6 +326,7 @@
                                                 //       XSD 1.1 uses 
astronomical numbering (-44 means 43 BCE),
                                                 //       conversion would 
apply.
                                new PropertyId( 'P8' ),
+                               'time',
                                new TimeValue( '-0044-03-15T00:00:00Z', 0, 3, 
3, TimeValue::PRECISION_DAY, RdfVocabulary::GREGORIAN_CALENDAR ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/statement/P8> 
"-0043-03-15T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .',
@@ -340,6 +351,7 @@
                                                    //       are known, they 
could be converted to (proleptic)
                                                    //       gregorian an 
output as an XSD date.
                                new PropertyId( 'P8' ),
+                               'time',
                                new TimeValue( '+1492-10-12T00:00:00Z', 0, 0, 
0, TimeValue::PRECISION_DAY, RdfVocabulary::JULIAN_CALENDAR ),
                                array(
                                        // Julian-to-Gregorian conversion 
applies.
@@ -366,6 +378,7 @@
                        ),
                        'url' => array(
                                new PropertyId( 'P9' ),
+                               'url',
                                new StringValue( 'http://quux.test/xyzzy' ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/statement/P9> <http://quux.test/xyzzy> .',
@@ -374,6 +387,7 @@
                        ),
                        'url-mailto' => array(
                                new PropertyId( 'P9' ),
+                               'url',
                                new StringValue( 'mailto:xy...@quux.test' ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/statement/P9> <mailto:xy...@quux.test> .',
@@ -384,14 +398,14 @@
        }
 
        /**
-        * @dataProvider provideAddSnakValue
+        * @dataProvider provideAddValue
         */
-       public function testAddSnakValue( PropertyId $propertyId, DataValue 
$value, array $expectedTriples, array $expectedValueTriples ) {
+       public function testAddValue( PropertyId $propertyId, $dataType, 
DataValue $value, array $expectedTriples, array $expectedValueTriples ) {
                $writer = $this->getTestData()->getNTriplesWriter();
                $writer->about( RdfVocabulary::NS_ENTITY, 'Q11' );
 
                $builder = $this->newBuilder();
-               $builder->addSnakValue( $writer, $propertyId, $value, 
RdfVocabulary::NSP_CLAIM_STATEMENT );
+               $builder->addValue( $writer, 
RdfVocabulary::NSP_CLAIM_STATEMENT, $propertyId->getSerialization(), $dataType, 
$value );
 
                $this->assertTriplesEqual( $expectedTriples, $writer );
 
@@ -399,8 +413,9 @@
                $this->assertTriplesEqual( $expectedValueTriples, 
$builder->test_value_writer );
        }
 
-       public function testAddSnakValue_mention() {
+       public function testAddValue_mention() {
                $propertyId = new PropertyId( 'P2' );
+               $dataType = 'wikibase-item';
                $value = new EntityIdValue( new ItemId( 'Q42' ) );
 
                $writer = $this->getTestData()->getNTriplesWriter();
@@ -408,14 +423,15 @@
 
                $mentioned = array();
                $builder = $this->newBuilder( $mentioned );
-               $builder->addSnakValue( $writer, $propertyId, $value, 
RdfVocabulary::NSP_CLAIM_STATEMENT );
+               $builder->addValue( $writer, 
RdfVocabulary::NSP_CLAIM_STATEMENT, $propertyId->getSerialization(), $dataType, 
$value );
 
                $this->assertEquals( array( 'Q42' ), array_keys( $mentioned ) );
        }
 
-       public function testAddSnakValue_seen() {
+       public function testAddValue_seen() {
                $propertyId = new PropertyId( 'P8' );
                $value = new TimeValue( '+2015-03-03T00:00:00Z', 0, 0, 0, 
TimeValue::PRECISION_DAY, RdfVocabulary::GREGORIAN_CALENDAR );
+               $dataType = 'time';
 
                $writer = $this->getTestData()->getNTriplesWriter();
                $writer->about( RdfVocabulary::NS_ENTITY, 'Q11' );
@@ -426,7 +442,7 @@
                $seen->alreadySeen( $value->getHash(), 'V' );
 
                $builder = $this->newBuilder( $mentioned, $seen );
-               $builder->addSnakValue( $writer, $propertyId, $value, 
RdfVocabulary::NSP_CLAIM_STATEMENT );
+               $builder->addValue( $writer, 
RdfVocabulary::NSP_CLAIM_STATEMENT, $propertyId->getSerialization(), $dataType, 
$value );
 
                // since the value was already "seen", the value writer should 
be empty.
                $this->assertTriplesEqual( array(), $builder->test_value_writer 
);
diff --git a/repo/tests/phpunit/includes/rdf/FullStatementsRdfBuilderTest.php 
b/repo/tests/phpunit/includes/rdf/FullStatementsRdfBuilderTest.php
index 1f5a507..fa2c159 100644
--- a/repo/tests/phpunit/includes/rdf/FullStatementsRdfBuilderTest.php
+++ b/repo/tests/phpunit/includes/rdf/FullStatementsRdfBuilderTest.php
@@ -10,6 +10,7 @@
 use Wikibase\Rdf\NullDedupeBag;
 use Wikibase\Rdf\RdfProducer;
 use Wikibase\Rdf\SimpleValueRdfBuilder;
+use Wikibase\Rdf\SnakRdfBuilder;
 
 /**
  * @covers Wikibase\Rdf\FullStatementRdfBuilder
@@ -72,11 +73,13 @@
                        $statementValueBuilder = new SimpleValueRdfBuilder( 
$vocabulary, $this->getTestData()->getMockRepository() );
                }
 
-               $statementBuilder = new FullStatementRdfBuilder( $vocabulary, 
$writer, $statementValueBuilder );
+               $snakRdfBuilder = new SnakRdfBuilder( $vocabulary, 
$statementValueBuilder, $this->getTestData()->getMockRepository() );
+               $statementBuilder = new FullStatementRdfBuilder( $vocabulary, 
$writer, $snakRdfBuilder );
                $statementBuilder->setDedupeBag( $dedupe ?: new NullDedupeBag() 
);
 
                if ( $flavor & RdfProducer::PRODUCE_PROPERTIES ) {
-                       $statementBuilder->setEntityMentionListener( 
$mentionTracker );
+                       $snakRdfBuilder->setEntityMentionListener( 
$mentionTracker );
+                       $statementValueBuilder->setEntityMentionListener( 
$mentionTracker );
                }
 
                $statementBuilder->setProduceQualifiers( $flavor & 
RdfProducer::PRODUCE_QUALIFIERS );
diff --git a/repo/tests/phpunit/includes/rdf/SimpleValueRdfBuilderTest.php 
b/repo/tests/phpunit/includes/rdf/SimpleValueRdfBuilderTest.php
index c52c6a5..22ccab8 100644
--- a/repo/tests/phpunit/includes/rdf/SimpleValueRdfBuilderTest.php
+++ b/repo/tests/phpunit/includes/rdf/SimpleValueRdfBuilderTest.php
@@ -96,12 +96,13 @@
                $this->assertEquals( $expectedTriples, $actualTripels );
        }
 
-       public function provideAddSnakValue() {
+       public function provideAddValue() {
                // NOTE: data types must match 
$this->getTestData()->getMockRepository();
 
                return array(
                        'wikibase-entityid' => array(
                                new PropertyId( 'P2' ),
+                               'wikibase-item',
                                new EntityIdValue( new ItemId( 'Q42' ) ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P2> <http://acme.test/Q42> .',
@@ -109,6 +110,7 @@
                        ),
                        'commonsMedia' => array(
                                new PropertyId( 'P3' ),
+                               'commonsMedia',
                                new StringValue( 'Test.jpg' ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P3> 
<http://commons.wikimedia.org/wiki/Special:FilePath/Test.jpg> .',
@@ -116,6 +118,7 @@
                        ),
                        'globecoordinate' => array(
                                new PropertyId( 'P4' ),
+                               'globecoordinate',
                                new GlobeCoordinateValue(
                                        new LatLongValue( 12.25, -45.5 ),
                                        0.025,
@@ -127,6 +130,7 @@
                        ),
                        'monolingualtext' => array(
                                new PropertyId( 'P5' ),
+                               'monolingualtext',
                                new MonolingualTextValue( 'ru', 'Берлин' ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P5> "\u0411\u0435\u0440\u043B\u0438\u043D"@ru .',
@@ -134,6 +138,7 @@
                        ),
                        'quantity' => array(
                                new PropertyId( 'P6' ),
+                               'quantity',
                                new QuantityValue(
                                        new DecimalValue( '+0.00011' ),
                                        '1',
@@ -145,6 +150,7 @@
                        ),
                        'quantity-unit' => array(
                                new PropertyId( 'P6' ),
+                               'quantity',
                                new QuantityValue(
                                        new DecimalValue( '-2.3' ),
                                        
'https://www.wikidata.org/entity/Q11573',
@@ -156,6 +162,7 @@
                        ),
                        'string' => array(
                                new PropertyId( 'P7' ),
+                               'string',
                                new StringValue( 'Kittens' ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P7> "Kittens" .',
@@ -163,6 +170,7 @@
                        ),
                        'time' => array(
                                new PropertyId( 'P8' ),
+                               'time',
                                new TimeValue( '+2015-03-03T00:00:00Z', 0, 0, 
0, TimeValue::PRECISION_DAY, RdfVocabulary::GREGORIAN_CALENDAR ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P8> 
"2015-03-03T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .',
@@ -170,6 +178,7 @@
                        ),
                        'time-year' => array( // NOTE: may changed to use 
xsd:gYear
                                new PropertyId( 'P8' ),
+                               'time',
                                new TimeValue( '+2015-00-00T00:00:00Z', 0, 0, 
0, TimeValue::PRECISION_YEAR, RdfVocabulary::GREGORIAN_CALENDAR ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P8> 
"2015-01-01T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .',
@@ -177,6 +186,7 @@
                        ),
                        'time-margin' => array(
                                new PropertyId( 'P8' ),
+                               'time',
                                new TimeValue( '+2015-03-03T00:00:00Z', 0, 3, 
3, TimeValue::PRECISION_DAY, RdfVocabulary::GREGORIAN_CALENDAR ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P8> 
"2015-03-03T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .',
@@ -188,6 +198,7 @@
                                                 //       XSD 1.1 uses 
astronomical numbering (-44 means 43 BCE),
                                                 //       conversion would 
apply.
                                new PropertyId( 'P8' ),
+                               'time',
                                new TimeValue( '-0044-03-15T00:00:00Z', 0, 3, 
3, TimeValue::PRECISION_DAY, RdfVocabulary::GREGORIAN_CALENDAR ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P8> 
"-0043-03-15T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .',
@@ -199,6 +210,7 @@
                                                    //       are known, they 
could be converted to (proleptic)
                                                    //       gregorian an 
output as an XSD date.
                                new PropertyId( 'P8' ),
+                               'time',
                                new TimeValue( '+1492-10-12T00:00:00Z', 0, 0, 
0, TimeValue::PRECISION_DAY, RdfVocabulary::JULIAN_CALENDAR ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P8> 
"1492-10-21T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .',
@@ -206,6 +218,7 @@
                        ),
                        'url' => array(
                                new PropertyId( 'P9' ),
+                               'url',
                                new StringValue( 'http://quux.test/xyzzy' ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P9> <http://quux.test/xyzzy> .',
@@ -213,6 +226,7 @@
                        ),
                        'url-mailto' => array(
                                new PropertyId( 'P9' ),
+                               'url',
                                new StringValue( 'mailto:xy...@quux.test' ),
                                array(
                                        '<http://acme.test/Q11> 
<http://acme.test/prop/direct/P9> <mailto:xy...@quux.test> .',
@@ -222,21 +236,22 @@
        }
 
        /**
-        * @dataProvider provideAddSnakValue
+        * @dataProvider provideAddValue
         */
-       public function testAddSnakValue( PropertyId $propertyId, DataValue 
$value, array $expectedTriples ) {
+       public function testAddValue( PropertyId $propertyId, $dataType, 
DataValue $value, array $expectedTriples ) {
                $writer = $this->getTestData()->getNTriplesWriter();
 
                $writer->about( RdfVocabulary::NS_ENTITY, 'Q11' );
 
                $builder = $this->newBuilder();
-               $builder->addSnakValue( $writer, $propertyId, $value, 
RdfVocabulary::NSP_DIRECT_CLAIM );
+               $builder->addValue( $writer, RdfVocabulary::NSP_DIRECT_CLAIM, 
$propertyId->getSerialization(), $dataType, $value );
 
                $this->assertTriplesEqual( $expectedTriples, $writer );
        }
 
-       public function testAddSnakValue_mention() {
+       public function testAddValue_mention() {
                $propertyId = new PropertyId( 'P2' );
+               $dataType = 'wikibase-item';
                $value = new EntityIdValue( new ItemId( 'Q42' ) );
 
                $writer = $this->getTestData()->getNTriplesWriter();
@@ -245,7 +260,7 @@
 
                $mentioned = array();
                $builder = $this->newBuilder( $mentioned );
-               $builder->addSnakValue( $writer, $propertyId, $value, 
RdfVocabulary::NSP_DIRECT_CLAIM );
+               $builder->addValue( $writer, RdfVocabulary::NSP_DIRECT_CLAIM, 
$propertyId->getSerialization(), $dataType, $value );
 
                $this->assertEquals( array( 'Q42' ), array_keys( $mentioned ) );
        }
diff --git a/repo/tests/phpunit/includes/rdf/SnakRdfBuilderTest.php 
b/repo/tests/phpunit/includes/rdf/SnakRdfBuilderTest.php
new file mode 100644
index 0000000..73945e4
--- /dev/null
+++ b/repo/tests/phpunit/includes/rdf/SnakRdfBuilderTest.php
@@ -0,0 +1,203 @@
+<?php
+
+namespace Wikibase\Test\Rdf;
+
+use DataValues\DataValue;
+use DataValues\StringValue;
+use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\DataModel\Entity\EntityIdValue;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Entity\Property;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Snak\PropertyNoValueSnak;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\DataModel\Snak\Snak;
+use Wikibase\Rdf\RdfVocabulary;
+use Wikibase\Rdf\SnakRdfBuilder;
+use Wikimedia\Purtle\RdfWriter;
+
+/**
+ * @covers Wikibase\Rdf\SnakRdfBuilder
+ *
+ * @group Wikibase
+ * @group WikibaseRepo
+ * @group WikibaseRdf
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ * @author Stas Malyshev
+ */
+class SnakRdfBuilderTest extends \PHPUnit_Framework_TestCase {
+
+       /**
+        * @var RdfBuilderTestData|null
+        */
+       private $testData = null;
+
+       /**
+        * Initialize repository data
+        *
+        * @return RdfBuilderTestData
+        */
+       private function getTestData() {
+               if ( $this->testData === null ) {
+                       $this->testData = new RdfBuilderTestData(
+                               __DIR__ . "/../../data/rdf",
+                               __DIR__ . "/../../data/rdf/SnakRdfBuilder"
+                       );
+               }
+
+               return $this->testData;
+       }
+
+       /**
+        * @param string $propertyNamespace
+        * @param string $propertyValueLName
+        * @param string $dataType
+        * @param DataValue $value
+        * @param EntityId[] &$mentioned receives the IDs of any mentioned 
entities.
+        *
+        * @return SnakRdfBuilder
+        */
+       private function newBuilder(
+               $propertyNamespace,
+               $propertyValueLName,
+               $dataType = null,
+               DataValue $value = null,
+               array &$mentioned = array()
+       ) {
+               $mentionTracker = $this->getMock( 
'Wikibase\Rdf\EntityMentionListener' );
+               $mentionTracker->expects( $this->any() )
+                       ->method( 'propertyMentioned' )
+                       ->will( $this->returnCallback( function( EntityId $id ) 
use ( &$mentioned ) {
+                               $key = $id->getSerialization();
+                               $mentioned[$key] = $id;
+                       } ) );
+
+               $valueBuilder = $this->getMock( 
'Wikibase\Rdf\DataValueRdfBuilder' );
+
+               if ( $value ) {
+                       $valueBuilder->expects( $this->once() )
+                               ->method( 'addValue' )
+                               ->with( $this->anything(), $propertyNamespace, 
$propertyValueLName, $dataType, $value );
+               } else {
+                       $valueBuilder->expects( $this->never() )
+                               ->method( 'addValue' );
+               }
+
+               $vocabulary = $this->getTestData()->getVocabulary();
+
+               $builder = new SnakRdfBuilder( $vocabulary, $valueBuilder, 
$this->getTestData()->getMockRepository() );
+               $builder->setEntityMentionListener( $mentionTracker );
+
+               return $builder;
+       }
+
+       /**
+        * Extract text test data from RDF builder
+        *
+        * @param RdfWriter $writer
+        *
+        * @return string[] ntriples lines, sorted
+        */
+       private function getDataFromWriter( RdfWriter $writer ) {
+               $ntriples = $writer->drain();
+
+               $lines = explode( "\n", trim( $ntriples ) );
+               sort( $lines );
+               return $lines;
+       }
+
+       private function assertTriplesEqual( array $expectedTriples, RdfWriter 
$writer ) {
+               $actualTripels = $this->getDataFromWriter( $writer );
+               sort( $expectedTriples );
+
+               $this->assertEquals( $expectedTriples, $actualTripels );
+       }
+
+       public function provideAddSnakValue() {
+               // NOTE: data types must match 
$this->getTestData()->getMockRepository();
+
+               return array(
+                       'value snak' => array(
+                               new PropertyValueSnak(
+                                       new PropertyId( 'P2' ),
+                                       new EntityIdValue( new ItemId( 'Q42' ) )
+                               ),
+                               null, // Currently, the data type is only 
looked up for string values
+                       ),
+                       'value snak with data type' => array(
+                               new PropertyValueSnak(
+                                       new PropertyId( 'P9' ),
+                                       new StringValue( 'http://acme.com' )
+                               ),
+                               'url', // Data type should be supplied at least 
for string values
+                               array()
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider provideAddSnakValue
+        */
+       public function testAddSnakValue( Snak $snak, $dataType ) {
+               $writer = $this->getTestData()->getNTriplesWriter();
+
+               $writer->about( RdfVocabulary::NS_ENTITY, 'Q11' );
+
+               $propertyId = $snak->getPropertyId();
+               $value = $snak instanceof PropertyValueSnak ? 
$snak->getDataValue() : null;
+
+               $builder = $this->newBuilder(
+                       RdfVocabulary::NSP_DIRECT_CLAIM,
+                       $propertyId->getSerialization(),
+                       $dataType,
+                       $value
+               );
+
+               // assertions are done by the mocks
+               $builder->addSnak( $writer, $snak, 
RdfVocabulary::NSP_DIRECT_CLAIM );
+       }
+
+       public function testAddSnakValue_novalue() {
+               $propertyId = new PropertyId( 'P2' );
+               $snak = new PropertyNoValueSnak( $propertyId );
+
+               $writer = $this->getTestData()->getNTriplesWriter();
+               $writer->about( RdfVocabulary::NS_ENTITY, 'Q11' );
+
+               $builder = $this->newBuilder(
+                       RdfVocabulary::NSP_DIRECT_CLAIM,
+                       $propertyId->getSerialization()
+               );
+
+               $expectedTriples = array(
+                       '<http://acme.test/Q11> 
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type> 
<http://acme.test/prop/novalue/P2> .',
+               );
+
+               $builder->addSnak( $writer, $snak, 
RdfVocabulary::NSP_DIRECT_CLAIM );
+               $this->assertTriplesEqual( $expectedTriples, $writer );
+       }
+
+       public function testAddSnakValue_mention() {
+               $propertyId = new PropertyId( 'P2' );
+               $value = new EntityIdValue( new ItemId( 'Q42' ) );
+               $snak = new PropertyValueSnak( $propertyId, $value );
+
+               $writer = $this->getTestData()->getNTriplesWriter();
+               $writer->about( RdfVocabulary::NS_ENTITY, 'Q11' );
+
+               $mentioned = array();
+               $builder = $this->newBuilder(
+                       RdfVocabulary::NSP_DIRECT_CLAIM,
+                       $propertyId->getSerialization(),
+                       null,
+                       $value,
+                       $mentioned
+               );
+
+               $builder->addSnak( $writer, $snak, 
RdfVocabulary::NSP_DIRECT_CLAIM );
+               $this->assertEquals( array( 'P2' ), array_keys( $mentioned ) );
+       }
+
+}
diff --git a/repo/tests/phpunit/includes/rdf/TruthyStatementsRdfBuilderTest.php 
b/repo/tests/phpunit/includes/rdf/TruthyStatementsRdfBuilderTest.php
index c9b7311..2ee6854 100644
--- a/repo/tests/phpunit/includes/rdf/TruthyStatementsRdfBuilderTest.php
+++ b/repo/tests/phpunit/includes/rdf/TruthyStatementsRdfBuilderTest.php
@@ -3,6 +3,7 @@
 namespace Wikibase\Test\Rdf;
 
 use Wikibase\Rdf\SimpleValueRdfBuilder;
+use Wikibase\Rdf\SnakRdfBuilder;
 use Wikibase\Rdf\TruthyStatementRdfBuilder;
 
 /**
@@ -47,11 +48,12 @@
                $writer = $this->getTestData()->getNTriplesWriter();
 
                $valueBuilder = new SimpleValueRdfBuilder( $vocabulary, 
$this->getTestData()->getMockRepository() );
+               $snakBuilder = new SnakRdfBuilder( $vocabulary, $valueBuilder, 
$this->getTestData()->getMockRepository() );
 
                $builder = new TruthyStatementRdfBuilder(
                        $vocabulary,
                        $writer,
-                       $valueBuilder
+                       $snakBuilder
                );
 
                // HACK: stick the writer into a public field, for use by 
getDataFromBuilder()

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I946f4593895c49c937bad0c0c66e1cf0e932ad2a
Gerrit-PatchSet: 14
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <daniel.kinz...@wikimedia.de>
Gerrit-Reviewer: Addshore <addshorew...@gmail.com>
Gerrit-Reviewer: Daniel Kinzler <daniel.kinz...@wikimedia.de>
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