Jeroen De Dauw has submitted this change and it was merged.

Change subject: Simplify subobject access + add some tests
......................................................................


Simplify subobject access + add some tests

Change-Id: If7f55305b3fa6fdf7523c2141cecf5e84f1f1342
---
M includes/SMW_SemanticData.php
M includes/api/BrowseBySubject.php
M tests/phpunit/includes/SemanticDataTest.php
3 files changed, 210 insertions(+), 32 deletions(-)

Approvals:
  Jeroen De Dauw: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/includes/SMW_SemanticData.php b/includes/SMW_SemanticData.php
index 79ffbcd..a28ec6d 100644
--- a/includes/SMW_SemanticData.php
+++ b/includes/SMW_SemanticData.php
@@ -214,10 +214,10 @@
        /**
         * Generate a hash value to simplify the comparison of this data
         * container with other containers. Subdata is taken into account.
-        * 
+        *
         * The hash uses PHP's md5 implementation, which is among the fastest
         * hash algorithms that PHP offers.
-        * 
+        *
         * @note This function may be used to obtain keys for SemanticData
         * objects or to do simple equalitiy tests. Equal hashes with very
         * high probability indicate equal data. However, the hash is
@@ -372,7 +372,7 @@
         * @param SMWDataValue $dataValue
         */
        public function addDataValue( SMWDataValue $dataValue ) {
-               \SMW\Profiler::In(  __METHOD__, true );
+               Profiler::In(  __METHOD__, true );
 
                if ( $dataValue->getProperty() instanceof DIProperty ) {
                        if ( !$dataValue->isValid() ) {
@@ -391,7 +391,7 @@
                        $this->addError( $dataValue->getErrors() );
                }
 
-               \SMW\Profiler::Out( __METHOD__, true );
+               Profiler::Out( __METHOD__, true );
        }
 
        /**
@@ -478,6 +478,7 @@
         * @throws MWException if subjects do not match
         */
        public function importDataFrom( SemanticData $semanticData ) {
+
                if( !$this->mSubject->equals( $semanticData->getSubject() ) ) {
                        throw new MWException( "SMWSemanticData can only 
represent data about one subject. Importing data for another subject is not 
possible." );
                }
@@ -539,6 +540,43 @@
        }
 
        /**
+        * Whether the SemanticData has a SubSemanticData container and if
+        * specified has a particluar subobject using its name as identifier
+        *
+        * @since 1.9
+        *
+        * @param string $subobjectName|null
+        *
+        * @return boolean
+        */
+       public function hasSubSemanticData( $subobjectName = null ) {
+
+               if ( $this->subSemanticData === array() ) {
+                       return false;
+               }
+
+               return $subobjectName !== null ? isset( $this->subSemanticData[ 
$subobjectName ] ) : true;
+       }
+
+       /**
+        * Find a particular subobject container using its name as identifier
+        *
+        * @since 1.9
+        *
+        * @param string $subobjectName
+        *
+        * @return SMWContainerSemanticData|[]
+        */
+       public function findSubSemanticData( $subobjectName ) {
+
+               if ( $this->hasSubSemanticData( $subobjectName ) ) {
+                       return $this->subSemanticData[ $subobjectName ];
+               }
+
+               return array();
+       }
+
+       /**
         * Add data about subobjects.
         * Will only work if the data that is added is about a subobject of
         * this SMWSemanticData's subject. Otherwise an exception is thrown.
@@ -563,7 +601,7 @@
                        throw new MWException( "Data for a subobject of 
{$semanticData->getSubject()->getDBkey()} cannot be added to 
{$this->getSubject()->getDBkey()}." );
                }
 
-               if( array_key_exists( $subobjectName, $this->subSemanticData ) 
) {
+               if( $this->hasSubSemanticData( $subobjectName ) ) {
                        $this->subSemanticData[$subobjectName]->importDataFrom( 
$semanticData );
                } else {
                        $semanticData->subDataAllowed = false;
@@ -590,7 +628,8 @@
                }
 
                $subobjectName = 
$semanticData->getSubject()->getSubobjectName();
-               if( array_key_exists( $subobjectName, $this->subSemanticData ) 
) {
+
+               if( $this->hasSubSemanticData( $subobjectName ) ) {
                        $this->subSemanticData[$subobjectName]->removeDataFrom( 
$semanticData );
 
                        if( $this->subSemanticData[$subobjectName]->isEmpty() ) 
{
diff --git a/includes/api/BrowseBySubject.php b/includes/api/BrowseBySubject.php
index 9640fce..58569a3 100644
--- a/includes/api/BrowseBySubject.php
+++ b/includes/api/BrowseBySubject.php
@@ -88,10 +88,8 @@
         */
        protected function addSubSemanticData( $store, $property, 
&$semanticData ) {
 
-               $subSemanticData = $semanticData->getSubSemanticData();
-
                foreach ( $semanticData->getPropertyValues( $property ) as 
$value ) {
-                       if ( $value instanceOf DIWikiPage && !isset( 
$subSemanticData[ $value->getSubobjectName() ] ) ) {
+                       if ( $value instanceOf DIWikiPage && 
!$semanticData->hasSubSemanticData( $value->getSubobjectName() ) ) {
                                $semanticData->addSubSemanticData( 
$store->getSemanticData( $value ) );
                        }
                }
diff --git a/tests/phpunit/includes/SemanticDataTest.php 
b/tests/phpunit/includes/SemanticDataTest.php
index 44b5c3b..194d0b1 100644
--- a/tests/phpunit/includes/SemanticDataTest.php
+++ b/tests/phpunit/includes/SemanticDataTest.php
@@ -37,6 +37,20 @@
        /**
         * @since 1.9
         *
+        * @return Subobject
+        */
+       private function newSubobject( Title $title, $property = 'Quuy', $value 
= 'Xeer' ) {
+
+               $subobject = new Subobject( $title );
+               $subobject->setSemanticData( 'Foo' );
+               $subobject->addDataValue( DataValueFactory::newPropertyValue( 
$property, $value ) );
+
+               return $subobject;
+       }
+
+       /**
+        * @since 1.9
+        *
         * @return SemanticData
         */
        private function newInstance( Title $title = null ) {
@@ -122,10 +136,7 @@
                $instance = $this->newInstance( $title );
                $instance->addDataValue( DataValueFactory::newPropertyValue( 
'Has fooQuex', 'Bar' ) );
 
-               $subobject = new Subobject( $title );
-               $subobject->setSemanticData( 'Foo' );
-               $subobject->addDataValue( DataValueFactory::newPropertyValue( 
'Has subobjects', 'Bam' ) );
-
+               $subobject = $this->newSubobject( $title );
                $instance->addPropertyObjectValue( $subobject->getProperty(), 
$subobject->getContainer() );
 
                $this->assertInternalType(
@@ -144,12 +155,9 @@
                $title = $this->newTitle();
                $instance = $this->newInstance( $title );
 
-               $subobject = new Subobject( $title );
-               $subobject->setSemanticData( 'Foo' );
-               $subobject->addDataValue( DataValueFactory::newPropertyValue( 
'Has subobjects', 'Bam' ) );
-
                // Adds only a subobject reference to the container
-               $instance->addPropertyObjectValue( $subobject->getProperty(), 
$subobject->getContainer() );
+               $subobject = $this->newSubobject( $title );
+               $instance->addPropertyObjectValue( $subobject->getProperty(), 
$subobject->getSemanticData()->getSubject() );
 
                $this->assertNotInstanceOf(
                        'SMWContainerSemanticData',
@@ -158,7 +166,7 @@
                );
 
                // Adds a complete container
-               $instance->addPropertyObjectValue( $subobject->getProperty(), 
$subobject->getSemanticData()->getSubject() );
+               $instance->addPropertyObjectValue( $subobject->getProperty(), 
$subobject->getContainer() );
 
                foreach ( $instance->getSubSemanticData() as $subSemanticData ) 
{
 
@@ -175,17 +183,24 @@
        /**
         * @since 1.9
         */
+       public function testImportDataFromWithDifferentSubjectMWException() {
+
+               $this->setExpectedException( 'MWException' );
+               $this->newInstance()->importDataFrom( $this->newInstance() );
+
+       }
+
+       /**
+        * @since 1.9
+        */
        public function testAddAndRemoveSubSemanticData() {
 
                $title = $this->newTitle();
                $instance = $this->newInstance( $title );
 
-               $subobject = new Subobject( $title );
-               $subobject->setSemanticData( 'Foo' );
-               $subobject->addDataValue( DataValueFactory::newPropertyValue( 
'Has subobjects', 'Bam' ) );
-
                // Adds only a subobject reference to the container
-               $instance->addPropertyObjectValue( $subobject->getProperty(), 
$subobject->getContainer() );
+               $subobject = $this->newSubobject( $title );
+               $instance->addPropertyObjectValue( $subobject->getProperty(), 
$subobject->getSemanticData()->getSubject() );
 
                $this->assertNotInstanceOf(
                        'SMWContainerSemanticData',
@@ -224,6 +239,106 @@
        /**
         * @since 1.9
         */
+       public function testAddSubSemanticDataWithOutSubobjectNameMWException() 
{
+
+               $this->setExpectedException( 'MWException' );
+               $this->newInstance()->addSubSemanticData( $this->newInstance() 
);
+
+       }
+
+       /**
+        * @since 1.9
+        */
+       public function testAddSubSemanticDataWithDifferentKeyMWException() {
+
+               $this->setExpectedException( 'MWException' );
+               $this->newInstance()->addSubSemanticData(
+                       $this->newSubobject( $this->newTitle() 
)->getSemanticData()
+               );
+
+       }
+
+       /**
+        * @since 1.9
+        */
+       public function testHasAndFindSubSemanticData() {
+
+               $title = $this->newTitle();
+               $instance = $this->newInstance( $title );
+
+               $subobject = $this->newSubobject( $title );
+               $subobjectName = 
$subobject->getSemanticData()->getSubject()->getSubobjectName();
+
+               $this->assertFalse(
+                       $instance->hasSubSemanticData() ,
+                       'Asserts that hasSubSemanticData() returns false'
+               );
+
+               $this->assertEmpty(
+                       $instance->findSubSemanticData( $subobjectName ),
+                       'Asserts that findSubSemanticData() returns empty'
+               );
+
+               // Adds only a subobject reference to the container
+               $instance->addPropertyObjectValue( $subobject->getProperty(), 
$subobject->getSemanticData()->getSubject() );
+
+               $this->assertFalse(
+                       $instance->hasSubSemanticData( $subobjectName ),
+                       'Asserts that hasSubSemanticData() returns false'
+               );
+
+               $this->assertEmpty(
+                       $instance->findSubSemanticData( $subobjectName ),
+                       'Asserts that findSubSemanticData() returns empty'
+               );
+
+               $instance->addSubSemanticData( $subobject->getSemanticData() );
+
+               $this->assertTrue(
+                       $instance->hasSubSemanticData( $subobjectName ),
+                       'Asserts that hasSubSemanticData() returns true'
+               );
+
+               $this->assertNotEmpty(
+                       $instance->findSubSemanticData( $subobjectName ),
+                       'Asserts that findSubSemanticData() returns not empty'
+               );
+
+               $this->assertInstanceOf(
+                       'SMWContainerSemanticData',
+                       $instance->findSubSemanticData( $subobjectName ),
+                       'Asserts that findSubSemanticData() does return a 
SMWContainerSemanticData instance'
+               );
+
+       }
+
+       /**
+        * @since 1.9
+        */
+       public function testHasSubSemanticDataOnNonStringSubobjectName() {
+
+               $this->assertFalse(
+                       $this->newInstance()->hasSubSemanticData( new \stdClass 
),
+                       'Asserts that hasSubSemanticData() returns false'
+               );
+
+       }
+
+       /**
+        * @since 1.9
+        */
+       public function testFindSubSemanticDataOnNonStringSubobjectName() {
+
+               $this->assertEmpty(
+                       $this->newInstance()->findSubSemanticData( new 
\stdClass ),
+                       'Asserts that findSubSemanticData() returns an empty 
array'
+               );
+
+       }
+
+       /**
+        * @since 1.9
+        */
        public function testVisibility() {
 
                $title = $this->newTitle();
@@ -235,10 +350,7 @@
                        'Asserts that hasVisibleProperties() returns true'
                );
 
-               $subobject = new Subobject( $title );
-               $subobject->setSemanticData( 'Foo' );
-               $subobject->addDataValue( DataValueFactory::newPropertyValue( 
'Has subobjects', 'Bam' ) );
-
+               $subobject = $this->newSubobject( $title );
                $instance->addPropertyObjectValue( $subobject->getProperty(), 
$subobject->getContainer() );
 
                $this->assertTrue(
@@ -249,19 +361,21 @@
        }
 
        /**
+        * @dataProvider removePropertyObjectProvider
+        *
         * @since 1.9
         */
-       public function testRemovePropertyObjectValue() {
+       public function testRemovePropertyObjectValue( $title, $property, 
$dataItem ) {
 
-               $instance = $this->newInstance();
-               $instance->addPropertyObjectValue( new DIProperty( '_MDAT'), 
DITime::newFromTimestamp( 1272508903 ) );
+               $instance = $this->newInstance( $title );
+               $instance->addPropertyObjectValue( $property, $dataItem );
 
                $this->assertFalse(
                        $instance->isEmpty() ,
                        'Asserts that isEmpty() returns false'
                );
 
-               $instance->removePropertyObjectValue( new DIProperty( '_MDAT'), 
DITime::newFromTimestamp( 1272508903 ) );
+               $instance->removePropertyObjectValue( $property, $dataItem );
 
                $this->assertTrue(
                        $instance->isEmpty() ,
@@ -315,6 +429,33 @@
        /**
         * @return array
         */
+       public function removePropertyObjectProvider() {
+
+               $provider = array();
+
+               $title = $this->newTitle();
+               $subobject = $this->newSubobject( $title );
+
+               // #0
+               $provider[] = array(
+                       $title,
+                       new DIProperty( '_MDAT'),
+                       DITime::newFromTimestamp( 1272508903 )
+               );
+
+               // #1
+               $provider[] = array(
+                       $title,
+                       $subobject->getProperty(),
+                       $subobject->getContainer()
+               );
+
+               return $provider;
+       }
+
+       /**
+        * @return array
+        */
        public function dataValueDataProvider() {
 
                $provider = array();

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

Gerrit-MessageType: merged
Gerrit-Change-Id: If7f55305b3fa6fdf7523c2141cecf5e84f1f1342
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/SemanticMediaWiki
Gerrit-Branch: master
Gerrit-Owner: Mwjames <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to