summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/private/appframework/app.php44
-rw-r--r--lib/private/appframework/dependencyinjection/dicontainer.php177
-rw-r--r--lib/private/appframework/utility/simplecontainer.php85
-rw-r--r--lib/private/route/router.php38
-rw-r--r--lib/public/appframework/app.php16
-rw-r--r--lib/public/appframework/queryexception.php28
-rw-r--r--tests/lib/appframework/AppTest.php45
-rw-r--r--tests/lib/appframework/utility/SimpleContainerTest.php167
8 files changed, 586 insertions, 14 deletions
diff --git a/lib/private/appframework/app.php b/lib/private/appframework/app.php
index f56ba4af870..b94c7bd9957 100644
--- a/lib/private/appframework/app.php
+++ b/lib/private/appframework/app.php
@@ -24,8 +24,9 @@
namespace OC\AppFramework;
-use OC\AppFramework\DependencyInjection\DIContainer;
-
+use \OC_App;
+use \OC\AppFramework\DependencyInjection\DIContainer;
+use \OCP\AppFramework\QueryException;
/**
* Entry point for every request in your app. You can consider this as your
@@ -37,6 +38,34 @@ class App {
/**
+ * Turns an app id into a namespace by either reading the appinfo.xml's
+ * namespace tag or uppercasing the appid's first letter
+ * @param string $appId the app id
+ * @param string $topNamespace the namespace which should be prepended to
+ * the transformed app id, defaults to OCA\
+ * @return string the starting namespace for the app
+ */
+ public static function buildAppNamespace($appId, $topNamespace='OCA\\') {
+ // first try to parse the app's appinfo/info.xml <namespace> tag
+ $filePath = OC_App::getAppPath($appId) . '/appinfo/info.xml';
+ $loadEntities = libxml_disable_entity_loader(false);
+ $xml = @simplexml_load_file($filePath);
+ libxml_disable_entity_loader($loadEntities);
+
+ if ($xml) {
+ $result = $xml->xpath('/info/namespace');
+ if ($result && count($result) > 0) {
+ // take first namespace result
+ return $topNamespace . trim((string) $result[0]);
+ }
+ }
+
+ // if the tag is not found, fall back to uppercasing the first letter
+ return $topNamespace . ucfirst($appId);
+ }
+
+
+ /**
* Shortcut for calling a controller method and printing the result
* @param string $controllerName the name of the controller under which it is
* stored in the DI container
@@ -48,7 +77,16 @@ class App {
if (!is_null($urlParams)) {
$container['urlParams'] = $urlParams;
}
- $controller = $container[$controllerName];
+ $appName = $container['AppName'];
+
+ // first try $controllerName then go for \OCA\AppName\Controller\$controllerName
+ try {
+ $controller = $container->query($controllerName);
+ } catch(QueryException $e) {
+ $appNameSpace = self::buildAppNamespace($appName);
+ $controllerName = $appNameSpace . '\\Controller\\' . $controllerName;
+ $controller = $container->query($controllerName);
+ }
// initialize the dispatcher and run all the middleware before the controller
$dispatcher = $container['Dispatcher'];
diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php
index dc57ef4c167..2c5089865a3 100644
--- a/lib/private/appframework/dependencyinjection/dicontainer.php
+++ b/lib/private/appframework/dependencyinjection/dicontainer.php
@@ -36,12 +36,13 @@ use OC\AppFramework\Utility\SimpleContainer;
use OC\AppFramework\Utility\TimeFactory;
use OC\AppFramework\Utility\ControllerMethodReflector;
use OCP\AppFramework\IApi;
+use OCP\AppFramework\QueryException;
use OCP\AppFramework\IAppContainer;
use OCP\AppFramework\Middleware;
use OCP\IServerContainer;
-class DIContainer extends SimpleContainer implements IAppContainer{
+class DIContainer extends SimpleContainer implements IAppContainer {
/**
* @var array
@@ -53,19 +54,181 @@ class DIContainer extends SimpleContainer implements IAppContainer{
* @param string $appName the name of the app
*/
public function __construct($appName, $urlParams = array()){
-
$this['AppName'] = $appName;
$this['urlParams'] = $urlParams;
- $this->registerParameter('ServerContainer', \OC::$server);
+ /**
+ * Core services
+ */
+ $this->registerService('OCP\\IAppConfig', function($c) {
+ return \OC::$server->getAppConfig();
+ });
- $this->registerService('API', function($c){
- return new API($c['AppName']);
+ $this->registerService('OCP\\IAppManager', function($c) {
+ return \OC::$server->getAppManager();
+ });
+
+ $this->registerService('OCP\\IAvatarManager', function($c) {
+ return \OC::$server->getAvatarManager();
+ });
+
+ $this->registerService('OCP\\Activity\\IManager', function($c) {
+ return \OC::$server->getActivityManager();
+ });
+
+ $this->registerService('OCP\\ICache', function($c) {
+ return \OC::$server->getCache();
+ });
+
+ $this->registerService('OCP\\ICacheFactory', function($c) {
+ return \OC::$server->getMemCacheFactory();
+ });
+
+ $this->registerService('OCP\\IConfig', function($c) {
+ return \OC::$server->getConfig();
+ });
+
+ $this->registerService('OCP\\Contacts\\IManager', function($c) {
+ return \OC::$server->getContactsManager();
+ });
+
+ $this->registerService('OCP\\IDateTimeZone', function($c) {
+ return \OC::$server->getDateTimeZone();
+ });
+
+ $this->registerService('OCP\\IDb', function($c) {
+ return \OC::$server->getDb();
+ });
+
+ $this->registerService('OCP\\IDBConnection', function($c) {
+ return \OC::$server->getDatabaseConnection();
+ });
+
+ $this->registerService('OCP\\Diagnostics\\IEventLogger', function($c) {
+ return \OC::$server->getEventLogger();
+ });
+
+ $this->registerService('OCP\\Diagnostics\\IQueryLogger', function($c) {
+ return \OC::$server->getQueryLogger();
+ });
+
+ $this->registerService('OCP\\Files\\Config\\IMountProviderCollection', function($c) {
+ return \OC::$server->getMountProviderCollection();
+ });
+
+ $this->registerService('OCP\\Files\\IRootFolder', function($c) {
+ return \OC::$server->getRootFolder();
+ });
+
+ $this->registerService('OCP\\IGroupManager', function($c) {
+ return \OC::$server->getGroupManager();
+ });
+
+ $this->registerService('OCP\\IL10N', function($c) {
+ return \OC::$server->getL10N($c->query('AppName'));
+ });
+
+ $this->registerService('OCP\\ILogger', function($c) {
+ return \OC::$server->getLogger();
+ });
+
+ $this->registerService('OCP\\BackgroundJob\\IJobList', function($c) {
+ return \OC::$server->getJobList();
+ });
+
+ $this->registerService('OCP\\AppFramework\\Utility\\IControllerMethodReflector', function($c) {
+ return $c->query('ControllerMethodReflector');
+ });
+
+ $this->registerService('OCP\\INavigationManager', function($c) {
+ return \OC::$server->getNavigationManager();
});
+ $this->registerService('OCP\\IPreview', function($c) {
+ return \OC::$server->getPreviewManager();
+ });
+
+ $this->registerService('OCP\\IRequest', function($c) {
+ return $c->query('Request');
+ });
+
+ $this->registerService('OCP\\ITagManager', function($c) {
+ return \OC::$server->getTagManager();
+ });
+
+ $this->registerService('OCP\\ITempManager', function($c) {
+ return \OC::$server->getTempManager();
+ });
+
+ $this->registerService('OCP\\AppFramework\\Utility\\ITimeFactory', function($c) {
+ return $c->query('TimeFactory');
+ });
+
+ $this->registerService('OCP\\Route\\IRouter', function($c) {
+ return \OC::$server->getRouter();
+ });
+
+ $this->registerService('OCP\\ISearch', function($c) {
+ return \OC::$server->getSearch();
+ });
+
+ $this->registerService('OCP\\ISearch', function($c) {
+ return \OC::$server->getSearch();
+ });
+
+ $this->registerService('OCP\\Security\\ICrypto', function($c) {
+ return \OC::$server->getCrypto();
+ });
+
+ $this->registerService('OCP\\Security\\IHasher', function($c) {
+ return \OC::$server->getHasher();
+ });
+
+ $this->registerService('OCP\\Security\\ISecureRandom', function($c) {
+ return \OC::$server->getSecureRandom();
+ });
+
+ $this->registerService('OCP\\IURLGenerator', function($c) {
+ return \OC::$server->getURLGenerator();
+ });
+
+ $this->registerService('OCP\\IUserManager', function($c) {
+ return \OC::$server->getUserManager();
+ });
+
+ $this->registerService('OCP\\IUserSession', function($c) {
+ return \OC::$server->getUserSession();
+ });
+
+ $this->registerService('ServerContainer', function ($c) {
+ $c->query('OCP\\ILogger')->warning(
+ 'Accessing the server container is deprecated. Use type ' .
+ 'annotations to inject core services instead!'
+ );
+ return \OC::$server;
+ });
+
+ // commonly used attributes
+ $this->registerService('UserId', function ($c) {
+ return $c->query('OCP\\IUserSession')->getSession()->get('user_id');
+ });
+
+ $this->registerService('WebRoot', function ($c) {
+ return $c->query('ServerContainer')->getWebRoot();
+ });
+
+
/**
- * Http
+ * App Framework APIs
*/
+ $this->registerService('API', function($c){
+ $c->query('OCP\\ILogger')->warning(
+ 'Accessing the API class is deprecated! Use the appropriate ' .
+ 'services instead!'
+ );
+ return new API($c['AppName']);
+ });
+
$this->registerService('Request', function($c) {
/** @var $c SimpleContainer */
/** @var $server SimpleContainer */
@@ -234,4 +397,6 @@ class DIContainer extends SimpleContainer implements IAppContainer{
}
\OCP\Util::writeLog($this->getAppName(), $message, $level);
}
+
+
}
diff --git a/lib/private/appframework/utility/simplecontainer.php b/lib/private/appframework/utility/simplecontainer.php
index 55b9cf7a977..68d52d759e0 100644
--- a/lib/private/appframework/utility/simplecontainer.php
+++ b/lib/private/appframework/utility/simplecontainer.php
@@ -1,7 +1,29 @@
<?php
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2014 Bernhard Posselt <dev@bernhard-posselt.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
namespace OC\AppFramework\Utility;
+use \OCP\AppFramework\QueryException;
+
/**
* Class SimpleContainer
*
@@ -9,12 +31,71 @@ namespace OC\AppFramework\Utility;
*/
class SimpleContainer extends \Pimple\Container implements \OCP\IContainer {
+
+ /**
+ * @param ReflectionClass $class the class to instantiate
+ * @return stdClass the created class
+ */
+ private function buildClass(\ReflectionClass $class) {
+ $constructor = $class->getConstructor();
+ if ($constructor === null) {
+ return $class->newInstance();
+ } else {
+ $parameters = [];
+ foreach ($constructor->getParameters() as $parameter) {
+ $parameterClass = $parameter->getClass();
+
+ // try to find out if it is a class or a simple parameter
+ if ($parameterClass === null) {
+ $resolveName = $parameter->getName();
+ } else {
+ $resolveName = $parameterClass->name;
+ }
+
+ $parameters[] = $this->query($resolveName);
+ }
+ return $class->newInstanceArgs($parameters);
+ }
+ }
+
+
+ /**
+ * If a parameter is not registered in the container try to instantiate it
+ * by using reflection to find out how to build the class
+ * @param string $name the class name to resolve
+ * @throws QueryException if the class could not be found or instantiated
+ */
+ private function resolve($name) {
+ $baseMsg = 'Could not resolve ' . $name . '!';
+ try {
+ $class = new \ReflectionClass($name);
+ if ($class->isInstantiable()) {
+ return $this->buildClass($class);
+ } else {
+ throw new QueryException($baseMsg .
+ ' Class can not be instantiated');
+ }
+ } catch(\ReflectionException $e) {
+ throw new QueryException($baseMsg . ' ' . $e->getMessage());
+ }
+ }
+
+
/**
* @param string $name name of the service to query for
* @return mixed registered service for the given $name
+ * @throws QueryExcpetion if the query could not be resolved
*/
public function query($name) {
- return $this->offsetGet($name);
+ if ($this->offsetExists($name)) {
+ return $this->offsetGet($name);
+ } else {
+ $object = $this->resolve($name);
+ $this->registerService($name, function () use ($object) {
+ return $object;
+ });
+ return $object;
+ }
}
/**
@@ -44,4 +125,6 @@ class SimpleContainer extends \Pimple\Container implements \OCP\IContainer {
$this[$name] = parent::factory($closure);
}
}
+
+
}
diff --git a/lib/private/route/router.php b/lib/private/route/router.php
index 5d6f621dc38..3559b841926 100644
--- a/lib/private/route/router.php
+++ b/lib/private/route/router.php
@@ -9,6 +9,7 @@
namespace OC\Route;
use OCP\Route\IRouter;
+use OCP\AppFramework\App;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Routing\RequestContext;
@@ -129,7 +130,7 @@ class Router implements IRouter {
if (!isset($this->loadedApps[$app])) {
$this->loadedApps[$app] = true;
$this->useCollection($app);
- $this->requireRouteFile($file);
+ $this->requireRouteFile($file, $app);
$collection = $this->getCollection($app);
$collection->addPrefix('/apps/' . $app);
$this->root->addCollection($collection);
@@ -283,10 +284,39 @@ class Router implements IRouter {
/**
* To isolate the variable scope used inside the $file it is required in it's own method
- * @param string $file
+ * @param string $file the route file location to include
+ * @param string $appName
*/
- private function requireRouteFile($file) {
- require_once $file;
+ private function requireRouteFile($file, $appName) {
+ $this->setupRoutes(include_once $file, $appName);
}
+
+ /**
+ * If a routes.php file returns an array, try to set up the application and
+ * register the routes for the app. The application class will be chosen by
+ * camelcasing the appname, e.g.: my_app will be turned into
+ * \OCA\MyApp\AppInfo\Application. If that class does not exist, a default
+ * App will be intialized. This makes it optional to ship an
+ * appinfo/application.php by using the built in query resolver
+ * @param array $routes the application routes
+ * @param string $appName the name of the app.
+ */
+ private function setupRoutes($routes, $appName) {
+ if (is_array($routes)) {
+ $appNameSpace = App::buildAppNamespace($appName);
+
+ $applicationClassName = $appNameSpace . '\\AppInfo\\Application';
+
+ if (class_exists($applicationClassName)) {
+ $application = new $applicationClassName();
+ } else {
+ $application = new App($appName);
+ }
+
+ $application->registerRoutes($this, $routes);
+ }
+ }
+
+
}
diff --git a/lib/public/appframework/app.php b/lib/public/appframework/app.php
index 21612327879..da405262aef 100644
--- a/lib/public/appframework/app.php
+++ b/lib/public/appframework/app.php
@@ -37,6 +37,22 @@ use OC\AppFramework\routing\RouteConfig;
* to be registered using IContainer::registerService
*/
class App {
+
+
+ /**
+ * Turns an app id into a namespace by convetion. The id is split at the
+ * underscores, all parts are camelcased and reassembled. e.g.:
+ * some_app_id -> OCA\SomeAppId
+ * @param string $appId the app id
+ * @param string $topNamespace the namespace which should be prepended to
+ * the transformed app id, defaults to OCA\
+ * @return string the starting namespace for the app
+ */
+ public static function buildAppNamespace($appId, $topNamespace='OCA\\') {
+ return \OC\AppFramework\App::buildAppNamespace($appId, $topNamespace);
+ }
+
+
/**
* @param array $urlParams an array with variables extracted from the routes
*/
diff --git a/lib/public/appframework/queryexception.php b/lib/public/appframework/queryexception.php
new file mode 100644
index 00000000000..f08d5b9a12f
--- /dev/null
+++ b/lib/public/appframework/queryexception.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2014 Bernhard Posselt <dev@bernhard-posselt.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCP\AppFramework;
+
+use Exception;
+
+
+class QueryException extends Exception {}
diff --git a/tests/lib/appframework/AppTest.php b/tests/lib/appframework/AppTest.php
index 86128db118f..e60f3439f23 100644
--- a/tests/lib/appframework/AppTest.php
+++ b/tests/lib/appframework/AppTest.php
@@ -24,6 +24,17 @@
namespace OC\AppFramework;
+function rrmdir($directory) {
+ $files = array_diff(scandir($directory), array('.','..'));
+ foreach ($files as $file) {
+ if (is_dir($directory . '/' . $file)) {
+ rrmdir($directory . '/' . $file);
+ } else {
+ unlink($directory . '/' . $file);
+ }
+ }
+ return rmdir($directory);
+}
class AppTest extends \Test\TestCase {
@@ -36,6 +47,7 @@ class AppTest extends \Test\TestCase {
private $output;
private $controllerName;
private $controllerMethod;
+ private $appPath;
protected function setUp() {
parent::setUp();
@@ -59,6 +71,17 @@ class AppTest extends \Test\TestCase {
$this->container[$this->controllerName] = $this->controller;
$this->container['Dispatcher'] = $this->dispatcher;
$this->container['urlParams'] = array();
+
+ $this->appPath = __DIR__ . '/../../../apps/namespacetestapp/appinfo';
+ $infoXmlPath = $this->appPath . '/info.xml';
+ mkdir($this->appPath, 0777, true);
+
+ $xml = '<?xml version="1.0" encoding="UTF-8"?>' .
+ '<info>' .
+ '<id>namespacetestapp</id>' .
+ '<namespace>NameSpaceTestApp</namespace>' .
+ '</info>';
+ file_put_contents($infoXmlPath, $xml);
}
@@ -77,6 +100,28 @@ class AppTest extends \Test\TestCase {
}
+ public function testBuildAppNamespace() {
+ $ns = App::buildAppNamespace('someapp');
+ $this->assertEquals('OCA\Someapp', $ns);
+ }
+
+
+ public function testBuildAppNamespaceCore() {
+ $ns = App::buildAppNamespace('someapp', 'OC\\');
+ $this->assertEquals('OC\Someapp', $ns);
+ }
+
+
+ public function testBuildAppNamespaceInfoXml() {
+ $ns = App::buildAppNamespace('namespacetestapp', 'OCA\\');
+ $this->assertEquals('OCA\NameSpaceTestApp', $ns);
+ }
+
+
+ protected function tearDown() {
+ rrmdir($this->appPath);
+ }
+
/*
FIXME: this complains about shit headers which are already sent because
of the content length. Would be cool if someone could fix this
diff --git a/tests/lib/appframework/utility/SimpleContainerTest.php b/tests/lib/appframework/utility/SimpleContainerTest.php
new file mode 100644
index 00000000000..c5c522d911f
--- /dev/null
+++ b/tests/lib/appframework/utility/SimpleContainerTest.php
@@ -0,0 +1,167 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2014 Bernhard Posselt <dev@bernhard-posselt.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace Test\AppFramework\Utility;
+
+use OC\AppFramework\Utility\SimpleContainer;
+
+
+interface TestInterface {}
+
+class ClassEmptyConstructor implements IInterfaceConstructor {}
+
+class ClassSimpleConstructor implements IInterfaceConstructor {
+ public $test;
+ public function __construct($test) {
+ $this->test = $test;
+ }
+}
+
+class ClassComplexConstructor {
+ public $class;
+ public $test;
+ public function __construct(ClassSimpleConstructor $class, $test) {
+ $this->class = $class;
+ $this->test = $test;
+ }
+}
+
+interface IInterfaceConstructor {}
+class ClassInterfaceConstructor {
+ public $class;
+ public $test;
+ public function __construct(IInterfaceConstructor $class, $test) {
+ $this->class = $class;
+ $this->test = $test;
+ }
+}
+
+
+class SimpleContainerTest extends \Test\TestCase {
+
+
+ private $container;
+
+ public function setUp() {
+ $this->container = new SimpleContainer();
+ }
+
+
+ public function testRegister() {
+ $this->container->registerParameter('test', 'abc');
+ $this->assertEquals('abc', $this->container->query('test'));
+ }
+
+
+ /**
+ * @expectedException \OCP\AppFramework\QueryException
+ */
+ public function testNothingRegistered() {
+ $this->container->query('something really hard');
+ }
+
+
+ /**
+ * @expectedException \OCP\AppFramework\QueryException
+ */
+ public function testNotAClass() {
+ $this->container->query('Test\AppFramework\Utility\TestInterface');
+ }
+
+
+ public function testNoConstructorClass() {
+ $object = $this->container->query('Test\AppFramework\Utility\ClassEmptyConstructor');
+ $this->assertTrue($object instanceof ClassEmptyConstructor);
+ }
+
+
+ public function testInstancesOnlyOnce() {
+ $object = $this->container->query('Test\AppFramework\Utility\ClassEmptyConstructor');
+ $object2 = $this->container->query('Test\AppFramework\Utility\ClassEmptyConstructor');
+ $this->assertSame($object, $object2);
+ }
+
+ public function testConstructorSimple() {
+ $this->container->registerParameter('test', 'abc');
+ $object = $this->container->query(
+ 'Test\AppFramework\Utility\ClassSimpleConstructor'
+ );
+ $this->assertTrue($object instanceof ClassSimpleConstructor);
+ $this->assertEquals('abc', $object->test);
+ }
+
+
+ public function testConstructorComplex() {
+ $this->container->registerParameter('test', 'abc');
+ $object = $this->container->query(
+ 'Test\AppFramework\Utility\ClassComplexConstructor'
+ );
+ $this->assertTrue($object instanceof ClassComplexConstructor);
+ $this->assertEquals('abc', $object->class->test);
+ $this->assertEquals('abc', $object->test);
+ }
+
+
+ public function testConstructorComplexInterface() {
+ $this->container->registerParameter('test', 'abc');
+ $this->container->registerService(
+ 'Test\AppFramework\Utility\IInterfaceConstructor', function ($c) {
+ return $c->query('Test\AppFramework\Utility\ClassSimpleConstructor');
+ });
+ $object = $this->container->query(
+ 'Test\AppFramework\Utility\ClassInterfaceConstructor'
+ );
+ $this->assertTrue($object instanceof ClassInterfaceConstructor);
+ $this->assertEquals('abc', $object->class->test);
+ $this->assertEquals('abc', $object->test);
+ }
+
+
+ public function tesOverrideService() {
+ $this->container->registerParameter('test', 'abc');
+ $this->container->registerService(
+ 'Test\AppFramework\Utility\IInterfaceConstructor', function ($c) {
+ return $c->query('Test\AppFramework\Utility\ClassSimpleConstructor');
+ });
+ $this->container->registerService(
+ 'Test\AppFramework\Utility\IInterfaceConstructor', function ($c) {
+ return $c->query('Test\AppFramework\Utility\ClassEmptyConstructor');
+ });
+ $object = $this->container->query(
+ 'Test\AppFramework\Utility\ClassInterfaceConstructor'
+ );
+ $this->assertTrue($object instanceof ClassEmptyConstructor);
+ $this->assertEquals('abc', $object->test);
+ }
+
+
+ /**
+ * @expectedException \OCP\AppFramework\QueryException
+ */
+ public function testConstructorComplexNoTestParameterFound() {
+ $object = $this->container->query(
+ 'Test\AppFramework\Utility\ClassComplexConstructor'
+ );
+ }
+
+
+}