Mwjames has uploaded a new change for review.

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


Change subject: Enable DIC object definitions to be merged with other containers
......................................................................

Enable DIC object definitions to be merged with other containers

* Move mock objects into the MockObjectRepository
* Change visibility of some methods
* Rename EmptyDependencyContainer to NullDependencyContainer

Change-Id: I16f5ea5f6db35d22feaea6a968b6b80d7c7e6bc5
---
M SemanticMediaWiki.classes.php
M docs/dic.md
M includes/context/EmptyContext.php
M includes/dic/BaseDependencyContainer.php
M includes/dic/DependencyContainer.php
D includes/dic/EmptyDependencyContainer.php
A includes/dic/NullDependencyContainer.php
M includes/dic/SharedDependencyContainer.php
M includes/dic/SimpleDependencyBuilder.php
M tests/phpunit/MockObjectRepository.php
M tests/phpunit/includes/dic/SharedDependencyContainerTest.php
M tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php
12 files changed, 178 insertions(+), 158 deletions(-)


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

diff --git a/SemanticMediaWiki.classes.php b/SemanticMediaWiki.classes.php
index 9e17122..26c98bd 100644
--- a/SemanticMediaWiki.classes.php
+++ b/SemanticMediaWiki.classes.php
@@ -80,7 +80,7 @@
        'SMW\DependencyObject'                => 
'includes/dic/DependencyContainer.php',
        'SMW\DependencyContainer'             => 
'includes/dic/DependencyContainer.php',
        'SMW\BaseDependencyContainer'         => 
'includes/dic/BaseDependencyContainer.php',
-       'SMW\EmptyDependencyContainer'        => 
'includes/dic/EmptyDependencyContainer.php',
+       'SMW\NullDependencyContainer'         => 
'includes/dic/NullDependencyContainer.php',
        'SMW\SharedDependencyContainer'       => 
'includes/dic/SharedDependencyContainer.php',
 
        // Dependency Injector
diff --git a/docs/dic.md b/docs/dic.md
index b556286..81d42e7 100644
--- a/docs/dic.md
+++ b/docs/dic.md
@@ -70,7 +70,7 @@
 ### DependencyContainer
 * DependencyContainer is an interface that specifies how to register a 
DepencyObject.
 * BaseDependencyContainer implements the DependencyContainer and declares 
methods to retrieve and store object definitions
-* EmptyDependencyContainer is an empty container that extends 
BaseDependencyContainer
+* NullDependencyContainer is an empty container that extends 
BaseDependencyContainer
 * SharedDependencyContainer implements most common object definitions that are 
used within Semantic MediaWiki
 
 ```php
diff --git a/includes/context/EmptyContext.php 
b/includes/context/EmptyContext.php
index a4fbe8a..abe1386 100644
--- a/includes/context/EmptyContext.php
+++ b/includes/context/EmptyContext.php
@@ -63,7 +63,7 @@
        protected function register( DependencyBuilder $builder = null ) {
 
                if ( $builder === null ) {
-                       $builder = new SimpleDependencyBuilder( new 
EmptyDependencyContainer() );
+                       $builder = new SimpleDependencyBuilder( new 
NullDependencyContainer() );
                }
 
                $builder->getContainer()->registerObject( 'Settings', null );
diff --git a/includes/dic/BaseDependencyContainer.php 
b/includes/dic/BaseDependencyContainer.php
index 3ed9503..805475f 100644
--- a/includes/dic/BaseDependencyContainer.php
+++ b/includes/dic/BaseDependencyContainer.php
@@ -3,23 +3,17 @@
 namespace SMW;
 
 /**
- * Provides a DependencyContainer base class
- *
- * @file
- *
- * @license GNU GPL v2+
- * @since   1.9
- *
- * @author mwjames
- */
-
-/**
  * Implements the DependencyContainer interface and is responsible for handling
  * object storage, and retrieval of object definitions
  *
- * Examples and a more exhaustive description can be found at /di/README.md
+ * Examples and a more exhaustive description can be found at /docs/dic.md
  *
  * @ingroup DependencyContainer
+ *
+ * @licence GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
  */
 abstract class BaseDependencyContainer extends ObjectStorage implements 
DependencyContainer {
 
@@ -60,11 +54,9 @@
        }
 
        /**
-        * Returns storage array
+        * @see ObjectStorage::detach
         *
-        * @since 1.9
-        *
-        * @return array
+        * @since  1.9
         */
        public function toArray() {
                return $this->storage;
@@ -75,10 +67,10 @@
         *
         * @since 1.9
         *
-        * @param array $mergeable
+        * @return array
         */
        public function merge( array $mergeable ) {
-               $this->storage = array_merge( $this->storage, $mergeable );
+               $this->storage = array_merge_recursive( $this->storage, 
$mergeable );
        }
 
        /**
@@ -94,7 +86,7 @@
        }
 
        /**
-        * Register an object
+        * @see DependencyContainer::registerObject
         *
         * @since  1.9
         *
@@ -107,12 +99,26 @@
        }
 
        /**
-        * @see DependencyContainer::loadObjects
+        * @see DependencyContainer::loadAllDefinitions
         *
         * @since  1.9
+        *
+        * @return array
         */
-       public function loadObjects() {
-               return array();
+       public function loadAllDefinitions() {
+
+               if ( !$this->has( 'def_' ) ) {
+                       $this->set( 'def_', $this->getDefinitions() );
+               }
+
+               return $this->get( 'def_' );
        }
 
+       /**
+        * @since  1.9
+        *
+        * @return array
+        */
+       protected abstract function getDefinitions();
+
 }
diff --git a/includes/dic/DependencyContainer.php 
b/includes/dic/DependencyContainer.php
index 0398b73..aaadf92 100644
--- a/includes/dic/DependencyContainer.php
+++ b/includes/dic/DependencyContainer.php
@@ -3,20 +3,14 @@
 namespace SMW;
 
 /**
- * Provides interfaces for dependency injection
- *
- * @file
- *
- * @license GNU GPL v2+
- * @since   1.9
- *
- * @author mwjames
- */
-
-/**
  * Interface specifying a dependency object
  *
  * @ingroup DependencyContainer
+ *
+ * @licence GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
  */
 interface DependencyObject {
 
@@ -33,7 +27,7 @@
         *
         * @param DependencyBuilder $builder
         */
-       public function inheritDescription( DependencyBuilder $builder );
+       public function retrieveDefinition( DependencyBuilder $builder );
 
 }
 
@@ -52,10 +46,10 @@
        public function registerObject( $objectName, $objectSignature, 
$objectScope );
 
        /**
-        * Collects and map objects for deferred registration
+        * Retrieves object definitions
         *
         * @since  1.9
         */
-       public function loadObjects();
+       public function loadAllDefinitions();
 
 }
diff --git a/includes/dic/EmptyDependencyContainer.php 
b/includes/dic/EmptyDependencyContainer.php
deleted file mode 100644
index 8f1ad5d..0000000
--- a/includes/dic/EmptyDependencyContainer.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-namespace SMW;
-
-/**
- * Provides an empty DependencyContainer entity
- *
- * @file
- *
- * @license GNU GPL v2+
- * @since   1.9
- *
- * @author mwjames
- */
-
-/**
- * Provides an empty DependencyContainer entity
- *
- * @ingroup DependencyContainer
- */
-class EmptyDependencyContainer extends BaseDependencyContainer {}
diff --git a/includes/dic/NullDependencyContainer.php 
b/includes/dic/NullDependencyContainer.php
new file mode 100644
index 0000000..513103b
--- /dev/null
+++ b/includes/dic/NullDependencyContainer.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace SMW;
+
+/**
+ * Provides an empty DependencyContainer entity
+ *
+ * @ingroup DependencyContainer
+ *
+ * @licence GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+class NullDependencyContainer extends BaseDependencyContainer {
+
+       /**
+        * @since 1.9
+        */
+       protected function getDefinitions() {
+               return null;
+       }
+
+}
diff --git a/includes/dic/SharedDependencyContainer.php 
b/includes/dic/SharedDependencyContainer.php
index 37f3942..c8c2696 100644
--- a/includes/dic/SharedDependencyContainer.php
+++ b/includes/dic/SharedDependencyContainer.php
@@ -19,15 +19,13 @@
         * @since  1.9
         */
        public function __construct() {
-               $this->load();
+               $this->loadAtInstantiation();
        }
 
        /**
-        * Load object definitions in advance
-        *
         * @since  1.9
         */
-       public function load() {
+       protected function loadAtInstantiation() {
 
                /**
                 * Settings object definition
@@ -65,15 +63,13 @@
        }
 
        /**
-        * Load object definitions on request
-        *
-        * @see  DependencyContainer::loadObjects
+        * @see BaseDependencyContainer::registerDefinitions
         *
         * @since  1.9
         *
         * @return array
         */
-       public function loadObjects() {
+       protected function getDefinitions() {
                return array(
                        'ParserData'            => $this->getParserData(),
                        'NamespaceExaminer'     => 
$this->getNamespaceExaminer(),
diff --git a/includes/dic/SimpleDependencyBuilder.php 
b/includes/dic/SimpleDependencyBuilder.php
index 4695772..b1e2546 100644
--- a/includes/dic/SimpleDependencyBuilder.php
+++ b/includes/dic/SimpleDependencyBuilder.php
@@ -38,7 +38,7 @@
        protected $recursionLevel = 0;
 
        /**
-        * Specifies a depth (or threshold) for a dependency graph. In case a 
build
+        * Specifies a max depth (or threshold) for a dependency graph. In case 
a build
         * will overstep this limit it is assumed that the builder is caught in 
an
         * infinite loop due to a self-reference (circular reference) within its
         * object definition
@@ -61,19 +61,23 @@
                $this->dependencyContainer = $dependencyContainer;
 
                if ( $this->dependencyContainer === null ) {
-                       $this->dependencyContainer = new 
EmptyDependencyContainer();
+                       $this->dependencyContainer = new 
NullDependencyContainer();
                }
 
        }
 
        /**
-        * Register DependencyContainer
+        * Register a DependencyContainer
         *
         * @since  1.9
         *
         * @param DependencyContainer $container
         */
        public function registerContainer( DependencyContainer $container ) {
+
+               $this->dependencyContainer->loadAllDefinitions();
+               $container->loadAllDefinitions();
+
                $this->dependencyContainer->merge( $container->toArray() );
        }
 
@@ -233,7 +237,7 @@
 
                if ( !$this->dependencyContainer->has( $objectName ) ) {
 
-                       if ( !$this->search( $objectName ) ) {
+                       if ( !$this->searchObjectByName( $objectName ) ) {
                                throw new OutOfBoundsException( "{$objectName} 
is not registered or available as service object" );
                        };
 
@@ -250,7 +254,7 @@
                }
 
                if ( $objectSignature instanceOf DependencyObject ) {
-                       $objectSignature = 
$objectSignature->inheritDescription( $this );
+                       $objectSignature = 
$objectSignature->retrieveDefinition( $this );
                }
 
                return $this->load( $objectName, $objectSignature, $objectScope 
);
@@ -324,15 +328,13 @@
        }
 
        /**
-        * Locate and register a deferred object
-        *
-        * @param string $objectName
+        * @since  1.9
         *
         * @return boolean
         */
-       private function search( $objectName ) {
+       private function searchObjectByName( $objectName ) {
 
-               $objectCatalog = $this->dependencyContainer->loadObjects();
+               $objectCatalog = 
$this->dependencyContainer->loadAllDefinitions();
 
                if ( isset( $objectCatalog[$objectName] ) ) {
 
diff --git a/tests/phpunit/MockObjectRepository.php 
b/tests/phpunit/MockObjectRepository.php
index bd7f2fa..2b34368 100644
--- a/tests/phpunit/MockObjectRepository.php
+++ b/tests/phpunit/MockObjectRepository.php
@@ -151,6 +151,58 @@
        }
 
        /**
+        * Returns an DependencyObject object
+        *
+        * @since 1.9
+        *
+        * @return DependencyObject
+        */
+       public function DependencyObject() {
+
+               $methods = $this->builder->getInvokedMethods();
+
+               $dependencyObject = $this->getMockBuilder( 
'SMW\DependencyObject' )
+                       ->setMethods( $methods )
+                       ->getMock();
+
+               foreach ( $methods as $method ) {
+
+                       $dependencyObject->expects( $this->any() )
+                               ->method( $method )
+                               ->will( $this->builder->setCallback( $method ) 
);
+
+               }
+
+               return $dependencyObject;
+       }
+
+       /**
+        * Returns an Observer object
+        *
+        * @since 1.9
+        *
+        * @return Observer
+        */
+       public function FakeDependencyContainer() {
+
+               $methods = $this->builder->getInvokedMethods();
+
+               $dependencyObject = $this->getMockBuilder( 
'SMW\NullDependencyContainer' )
+                       ->setMethods( $methods )
+                       ->getMock();
+
+               foreach ( $methods as $method ) {
+
+                       $dependencyObject->expects( $this->any() )
+                               ->method( $method )
+                               ->will( $this->builder->setCallback( $method ) 
);
+
+               }
+
+               return $dependencyObject;
+       }
+
+       /**
         * Returns a ParserData object
         *
         * @since 1.9
diff --git a/tests/phpunit/includes/dic/SharedDependencyContainerTest.php 
b/tests/phpunit/includes/dic/SharedDependencyContainerTest.php
index 4755abc..86aaa9f 100644
--- a/tests/phpunit/includes/dic/SharedDependencyContainerTest.php
+++ b/tests/phpunit/includes/dic/SharedDependencyContainerTest.php
@@ -88,7 +88,7 @@
                        $this->assertObjectRegistration( $objectName, 
$registeredObjects );
                }
 
-               foreach ( $instance->loadObjects() as $objectName => 
$objectSiganture ) {
+               foreach ( $instance->loadAllDefinitions() as $objectName => 
$objectSiganture ) {
                        $this->assertObjectRegistration( $objectName, 
$registeredObjects );
                }
 
diff --git a/tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php 
b/tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php
index 3885fda..a1c5d1f 100644
--- a/tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php
+++ b/tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php
@@ -2,7 +2,7 @@
 
 namespace SMW\Test;
 
-use SMW\EmptyDependencyContainer;
+use SMW\NullDependencyContainer;
 use SMW\SimpleDependencyBuilder;
 use SMW\DependencyBuilder;
 use SMW\DependencyObject;
@@ -46,36 +46,6 @@
        /**
         * @since 1.9
         *
-        * @return DependencyContainer
-        */
-       private function newDependencyContainer( $toArray = array() ) {
-
-               $container = $this->getMockBuilder( '\SMW\DependencyContainer' )
-                       ->disableOriginalConstructor()
-                       ->setMethods( array(
-                               'preload',
-                               'toArray',
-                               'registerObject',
-                               'has',
-                               'get',
-                               'set',
-                               'remove',
-                               'merge',
-                               'loadObjects'
-                               )
-                       )
-                       ->getMock();
-
-               $container->expects( $this->any() )
-                       ->method( 'toArray' )
-                       ->will( $this->returnValue( $toArray ) );
-
-               return $container;
-       }
-
-       /**
-        * @since 1.9
-        *
         * @return SimpleDependencyBuilder
         */
        private function newInstance( $dependencyContainer = null ) {
@@ -96,8 +66,12 @@
 
                $instance = $this->newInstance();
 
+               $container = $this->newMockBuilder()->newObject( 
'FakeDependencyContainer', array(
+                       'toArray' => array( 'Test' => array( '123', 0 ) )
+               ) );
+
                // Register container
-               $instance->registerContainer( $this->newDependencyContainer( 
array( 'Test' => array( '123', 0 ) ) ) );
+               $instance->registerContainer( $container );
 
                $this->assertEquals(
                        '123',
@@ -105,8 +79,12 @@
                        'asserts object creation'
                );
 
+               $container = $this->newMockBuilder()->newObject( 
'FakeDependencyContainer', array(
+                       'toArray' => array( 'Test2' => array( 9001, 1 ) )
+               ) );
+
                // Register additional container and asserts that both objects 
are available
-               $instance->registerContainer( $this->newDependencyContainer( 
array( 'Test2' => array( 9001, 1 ) ) ) );
+               $instance->registerContainer( $container );
 
                $this->assertEquals(
                        '123',
@@ -132,20 +110,28 @@
 
                $instance = $this->newInstance();
 
-               $instance->registerContainer( $this->newDependencyContainer( 
array( 'Test' => array( 9001, 1 ) ) ) );
+               $container = $this->newMockBuilder()->newObject( 
'FakeDependencyContainer', array(
+                       'toArray' => array( 'Test' => array( 9001, 1 ) )
+               ) );
+
+               $instance->registerContainer( $container );
 
                $this->assertEquals(
                        9001,
                        $instance->newObject( 'Test' ),
-                       'asserts object creation after container merge'
+                       'Asserts object creation after container merge'
                );
 
-               $instance->registerContainer( $this->newDependencyContainer( 
array( 'Test' => array( 1009, 0 ) ) ) );
+               $container = $this->newMockBuilder()->newObject( 
'FakeDependencyContainer', array(
+                       'toArray' => array( 'Test' => array( 1009, 0 ) )
+               ) );
+
+               $instance->registerContainer( $container );
 
                $this->assertEquals(
-                       1009,
+                       9001,
                        $instance->newObject( 'Test' ),
-                       'asserts object definition has been overridden'
+                       'Asserts object definition has not been overridden'
                );
 
        }
@@ -173,7 +159,7 @@
        public function testRegisterObjectUsingMagicMethodEagerLoading() {
 
                $instance  = $this->newInstance();
-               $container = new EmptyDependencyContainer();
+               $container = new NullDependencyContainer();
 
                // Eager loading
                $container->someFunnyTitle = $this->newTitle();
@@ -194,7 +180,7 @@
        public function testRegisterObjectUsingMagicMethodLazyLoading() {
 
                $instance  = $this->newInstance();
-               $container = new EmptyDependencyContainer();
+               $container = new NullDependencyContainer();
 
                $container->someFunnyTitle = $this->newTitle();
                $container->FakeWikiPage = function ( DependencyBuilder 
$builder ) {
@@ -234,7 +220,7 @@
                $instance  = $this->newInstance();
 
                // Clear registered container
-               $instance->registerContainer( new EmptyDependencyContainer() );
+               $instance->registerContainer( new NullDependencyContainer() );
 
                // Object is using an argument that where invoked using the 
__set method
                // and is evenly accessible during the build process using 
newObject()
@@ -591,8 +577,9 @@
         */
        public function testDeferredLoading( $setup, $expected ) {
 
-               $container = new FakeDependencyContainer();
-               $container->setObjects( array( 'Quux' => $setup ) );
+               $container = $this->newMockBuilder()->newObject( 
'FakeDependencyContainer', array(
+                       'getDefinitions' => array( 'Quux' => $setup )
+               ) );
 
                $instance = $this->newInstance( $container );
 
@@ -612,8 +599,7 @@
         */
        public function 
testDeferredLoadingWithScopeChangeAndRecursiveObjectGraph() {
 
-               $container = new FakeDependencyContainer();
-               $container->setObjects( array(
+               $objectGraph = array(
 
                        'Title' => function( $builder ) {
                                return new Title();
@@ -631,6 +617,10 @@
                                return $builder->newObject( 'Bar' );
                        }
 
+               );
+
+               $container = $this->newMockBuilder()->newObject( 
'FakeDependencyContainer', array(
+                       'getDefinitions' => $objectGraph
                ) );
 
                $instance = $this->newInstance( $container );
@@ -762,8 +752,7 @@
 
                $this->setExpectedException( 'OutOfBoundsException' );
 
-               $container = new FakeDependencyContainer();
-               $container->setObjects( array(
+               $objectGraph = array(
 
                        'Title' => function( $builder ) {
                                return $builder->newObject( 'Title' );  // 
self-reference
@@ -785,6 +774,10 @@
                                return $builder->newObject( 'Foo' );
                        }
 
+               );
+
+               $container = $this->newMockBuilder()->newObject( 
'FakeDependencyContainer', array(
+                       'getDefinitions' => $objectGraph
                ) );
 
                $instance = $this->newInstance( $container );
@@ -833,26 +826,16 @@
                $closure  = function() use( $stdClass ) { return $stdClass; };
 
                // #0
-               $dependencyObject = $this->getMockBuilder( 
'\SMW\DependencyObject' )
-                       ->disableOriginalConstructor()
-                       ->setMethods( array( 'inheritDescription' ) )
-                       ->getMock();
-
-               $dependencyObject->expects( $this->any() )
-                       ->method( 'inheritDescription' )
-                       ->will( $this->returnValue( $stdClass ) );
+               $dependencyObject = $this->newMockBuilder()->newObject( 
'DependencyObject', array(
+                       'retrieveDefinition' => $stdClass
+               ) );
 
                $provider[] = array( $dependencyObject, $stdClass );
 
                // #1
-               $dependencyObject = $this->getMockBuilder( 
'\SMW\DependencyObject' )
-                       ->disableOriginalConstructor()
-                       ->setMethods( array( 'inheritDescription' ) )
-                       ->getMock();
-
-               $dependencyObject->expects( $this->any() )
-                       ->method( 'inheritDescription' )
-                       ->will( $this->returnValue( $closure ) );
+               $dependencyObject = $this->newMockBuilder()->newObject( 
'DependencyObject', array(
+                       'retrieveDefinition' => $closure
+               ) );
 
                $provider[] = array( $dependencyObject, $stdClass );
 
@@ -867,22 +850,6 @@
 
 }
 
-/**
- * A fake dependency container
- */
-class FakeDependencyContainer extends EmptyDependencyContainer {
-
-       protected $objects;
-
-       public function setObjects( $objects ) {
-               $this->objects = $objects;
-       }
-
-       public function loadObjects() {
-               return $this->objects;
-       }
-
-}
 
 /**
  * A fake object instance

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I16f5ea5f6db35d22feaea6a968b6b80d7c7e6bc5
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/SemanticMediaWiki
Gerrit-Branch: master
Gerrit-Owner: Mwjames <[email protected]>

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

Reply via email to