Browse files

Complete Service component refactor.

  • Loading branch information...
1 parent a1454b9 commit bbb8b1135642de97accc15b342c86f1e8f8aa214 @trq trq committed Jan 19, 2013
Showing with 412 additions and 1,166 deletions.
  1. +3 −3 Phakefile
  2. +13 −38 lib/Proem/Bootstrap/Dispatch.php
  3. +7 −17 lib/Proem/Bootstrap/Request.php
  4. +7 −17 lib/Proem/Bootstrap/Route.php
  5. +2 −19 lib/Proem/Bootstrap/Tests/DispatchTest.php
  6. +1 −51 lib/Proem/Bootstrap/Tests/RequestTest.php
  7. +1 −53 lib/Proem/Bootstrap/Tests/RouteTest.php
  8. +8 −7 lib/Proem/Proem.php
  9. +4 −7 lib/Proem/Service/Asset.php
  10. +0 −187 lib/Proem/Service/AssetComposer.php
  11. +0 −69 lib/Proem/Service/AssetComposerInterface.php
  12. +1 −1 lib/Proem/Service/AssetInterface.php
  13. +120 −102 lib/Proem/Service/AssetManager.php
  14. +26 −32 lib/Proem/Service/AssetManagerInterface.php
  15. +0 −144 lib/Proem/Service/AssetResolver.php
  16. +0 −61 lib/Proem/Service/AssetResolverInterface.php
  17. +0 −21 lib/Proem/Service/Tests/AssetComposerFixtures/Foo.php
  18. +0 −101 lib/Proem/Service/Tests/AssetComposerTest.php
  19. +9 −0 lib/Proem/Service/Tests/AssetManagerFixtures/Bar.php
  20. +9 −0 lib/Proem/Service/Tests/AssetManagerFixtures/Bar2.php
  21. +16 −0 lib/Proem/Service/Tests/AssetManagerFixtures/Foo.php
  22. +16 −0 lib/Proem/Service/Tests/AssetManagerFixtures/NeedsInterface.php
  23. +9 −0 lib/Proem/Service/Tests/AssetManagerFixtures/Some.php
  24. +6 −0 lib/Proem/Service/Tests/AssetManagerFixtures/SomeInterface.php
  25. +10 −0 lib/Proem/Service/Tests/AssetManagerFixtures/Someother.php
  26. +120 −38 lib/Proem/Service/Tests/AssetManagerTest.php
  27. +0 −17 lib/Proem/Service/Tests/AssetResolverFixtures/Bar.php
  28. +0 −8 lib/Proem/Service/Tests/AssetResolverFixtures/BarInterface.php
  29. +0 −10 lib/Proem/Service/Tests/AssetResolverFixtures/Foo.php
  30. +0 −17 lib/Proem/Service/Tests/AssetResolverFixtures/SomeBar.php
  31. +0 −121 lib/Proem/Service/Tests/AssetResolverTest.php
  32. +11 −10 lib/Proem/Service/Tests/AssetTest.php
  33. +12 −13 tests/ProemTest.php
  34. +1 −2 tests/phpunit.xml
View
6 Phakefile
@@ -15,7 +15,7 @@ group('proem', function() {
group('dev', function() {
desc('Default tasks to execute before commit');
- task('pre-commit', 'tests', 'sniff', function() {});
+ task('pre-commit', 'tests', function() {});
desc('Run the unit tests');
task('tests', function($args) {
@@ -44,10 +44,10 @@ group('dev', function() {
system('php -S 127.0.0.1:8080 -t tests/log/report/');
});
- desc('Sniff code for PSR-1/2');
+ desc('Sniff code for PSR-1');
task('sniff', function ($args) {
chdir(realpath(__DIR__));
- system('vendor/bin/phpcs -a --ignore=/Tests/* --standard=PSR2 lib/');
+ system('vendor/bin/phpcs -a --ignore=/Tests/* --standard=PSR1 lib/');
});
desc('Build the Phar archive');
View
51 lib/Proem/Bootstrap/Dispatch.php
@@ -48,47 +48,22 @@ class Dispatch extends ChainEventAbstract
*/
public function in(AssetManagerInterface $assetManager)
{
- if ($assetManager->provides('eventManager', 'Proem\Signal\EventManagerInterface')) {
- $assetManager->get('eventManager')->trigger(
- new Event('proem.in.dispatch'),
- function ($responseEvent) use ($assetManager) {
- // Check for a customized Dispatch\Dispatcher.
- if (
- $responseEvent->has('dispatcherAsset') &&
- $responseEvent->get('dispatcherAsset') instanceof AssetInterface &&
- $responseEvent->get('dispatcherAsset')->provides('Proem\Dispatch\DispatcherInterface')
- ) {
- $assetManager->set('dispatcher', $responseEvent->get('dispatcherAsset'));
- }
-
- // Check for a customized Dispatch\Staging
- if (
- $responseEvent->has('stageAsset') &&
- $responseEvent->get('stageAsset') instanceof AssetInterface &&
- $responseEvent->get('stageAsset')->provides('Proem\Dispatch\StageInterface')
- ) {
- $assetManager->set('stage', $responseEvent->get('stageAsset'));
- }
+ $assetManager->resolve('eventManager')->trigger(
+ new Event('proem.in.dispatch'),
+ function ($responseEvent) use ($assetManager) {
+ // Check for a customized Dispatch\Dispatcher.
+ if ($responseEvent->has('dispatcherAsset')) {
+ $assetManager->attach('dispatcher', $responseEvent->get('dispatcherAsset'));
}
- );
- }
- if (!$assetManager->provides('Proem\Dispatch\Dispatcher')) {
- $assetManager->set('dispatcher', (new AssetComposer('Proem\Dispatch\Dispatcher'))->compose(true));
- }
+ // Check for a customized Dispatch\Staging
+ if ($responseEvent->has('stageAsset')) {
+ $assetManager->attach('stage', $responseEvent->get('stageAsset'));
+ }
+ }
+ );
- if (!$assetManager->provides('Proem\Dispatch\Stage')) {
- (new Stage($assetManager))->process();
- } else {
- /**
- * TODO: This call should likely be replaced by some method that resolves
- * to return an asset by type not by index. eg; getProvided().
- *
- * It could in fact replace this entire if statement if it can also resolve
- * to create assets that don't exist within the asset manager.
- */
- $assetManager->get('stage')->process();
- }
+ $assetManager->resolve('stage')->process();
}
/**
View
24 lib/Proem/Bootstrap/Request.php
@@ -55,24 +55,14 @@ class Request extends ChainEventAbstract
*/
public function in(AssetManagerInterface $assetManager)
{
- if ($assetManager->provides('eventManager', 'Proem\Signal\EventManagerInterface')) {
- $assetManager->get('eventManager')->trigger(
- new Event('proem.in.request'),
- function ($responseEvent) use ($assetManager) {
- if (
- $responseEvent->has('requestAsset') &&
- $responseEvent->get('requestAsset') instanceof AssetInterface &&
- $responseEvent->get('requestAsset')->provides('Proem\Http\Request')
- ) {
- $assetManager->set('request', $responseEvent->get('requestAsset'));
- }
+ $assetManager->resolve('eventManager')->trigger(
+ new Event('proem.in.request'),
+ function ($responseEvent) use ($assetManager) {
+ if ($responseEvent->has('requestAsset')) {
+ $assetManager->attach('request', $responseEvent->get('requestAsset'));
}
- );
- }
-
- if (!$assetManager->provides('Proem\Http\Request')) {
- $assetManager->set('request', (new AssetComposer('Proem\Http\Request'))->compose(true));
- }
+ }
+ );
}
/**
View
24 lib/Proem/Bootstrap/Route.php
@@ -55,24 +55,14 @@ class Route extends ChainEventAbstract
*/
public function in(AssetManagerInterface $assetManager)
{
- if ($assetManager->provides('eventManager', 'Proem\Signal\EventManagerInterface')) {
- $assetManager->get('eventManager')->trigger(
- new Event('proem.in.route'),
- function ($responseEvent) use ($assetManager) {
- if (
- $responseEvent->has('routeManagerAsset') &&
- $responseEvent->get('routeManagerAsset') instanceof AssetInterface &&
- $responseEvent->get('routeManagerAsset')->provides('Proem\Routing\RouteManagerInterface')
- ) {
- $assetManager->set('routeManager', $responseEvent->get('routeManagerAsset'));
- }
+ $assetManager->resolve('eventManager')->trigger(
+ new Event('proem.in.route'),
+ function ($responseEvent) use ($assetManager) {
+ if ($responseEvent->has('routeManagerAsset')) {
+ $assetManager->attach('routeManager', $responseEvent->get('routeManagerAsset'));
}
- );
- }
-
- if (!$assetManager->provides('Proem\Routing\RouteManagerInterface')) {
- $assetManager->set('routeManager', (new AssetComposer('Proem\Routing\RouteManager'))->compose(true));
- }
+ }
+ );
}
/**
View
21 lib/Proem/Bootstrap/Tests/DispatchTest.php
@@ -45,38 +45,21 @@ public function testCanTriggerEvent()
->once();
$assetManager = m::mock('Proem\Service\AssetManagerInterface');
- $assetManager
- ->shouldReceive('provides')
- ->with('eventManager', 'Proem\Signal\EventManagerInterface')
- ->once()
- ->andReturn(true);
$assetManager
- ->shouldReceive('get')
+ ->shouldReceive('resolve')
->with('eventManager')
->once()
->andReturn($eventManager);
- $assetManager
- ->shouldReceive('provides')
- ->with('Proem\Dispatch\Dispatcher')
- ->once()
- ->andReturn(true);
-
- $assetManager
- ->shouldReceive('provides')
- ->with('Proem\Dispatch\Stage')
- ->once()
- ->andReturn(true);
-
$stage = m::mock('Proem\Dispatch\Stage');
$stage
->shouldReceive('process')
->once()
->andReturn(true);
$assetManager
- ->shouldReceive('get')
+ ->shouldReceive('resolve')
->with('stage')
->once()
->andReturn($stage);
View
52 lib/Proem/Bootstrap/Tests/RequestTest.php
@@ -47,63 +47,13 @@ public function testCanTriggerEvent()
->once();
$assetManager = m::mock('Proem\Service\AssetManagerInterface');
- $assetManager
- ->shouldReceive('provides')
- ->with('eventManager', 'Proem\Signal\EventManagerInterface')
- ->once()
- ->andReturn(true);
-
- $assetManager
- ->shouldReceive('get')
- ->with('eventManager')
- ->once()
- ->andReturn($eventManager);
-
- // Event Done
-
- $assetManager
- ->shouldReceive('provides')
- ->with('Proem\Http\Request')
- ->once()
- ->andReturn(true);
-
- $request = new Request;
- $request->in($assetManager);
- }
-
- public function testCanSetDefaultRequestAsset()
- {
- $event = m::mock('Proem\Signal\EventInterface', ['proem.in.request']);
- $eventManager = m::mock('Proem\Signal\EventManagerInterface');
- $eventManager
- ->shouldReceive('trigger')
- ->with('Proem\Signal\EventInterface', 'closure')
- ->once();
-
- $assetManager = m::mock('Proem\Service\AssetManagerInterface');
- $assetManager
- ->shouldReceive('provides')
- ->with('eventManager', 'Proem\Signal\EventManagerInterface')
- ->once()
- ->andReturn(true);
$assetManager
- ->shouldReceive('get')
+ ->shouldReceive('resolve')
->with('eventManager')
->once()
->andReturn($eventManager);
- $assetManager
- ->shouldReceive('provides')
- ->with('Proem\Http\Request')
- ->once()
- ->andReturn(false);
-
- $assetManager
- ->shouldReceive('set')
- ->with('request', 'Proem\Service\AssetInterface')
- ->once();
-
$request = new Request;
$request->in($assetManager);
}
View
54 lib/Proem/Bootstrap/Tests/RouteTest.php
@@ -38,72 +38,20 @@ public function testCanInstantiate()
public function testCanTriggerEvent()
{
- // Handle Event
-
$eventManager = m::mock('Proem\Signal\EventManagerInterface');
$eventManager
->shouldReceive('trigger')
->with('Proem\Signal\EventInterface', 'closure')
->once();
$assetManager = m::mock('Proem\Service\AssetManagerInterface');
- $assetManager
- ->shouldReceive('provides')
- ->with('eventManager', 'Proem\Signal\EventManagerInterface')
- ->once()
- ->andReturn(true);
$assetManager
- ->shouldReceive('get')
+ ->shouldReceive('resolve')
->with('eventManager')
->once()
->andReturn($eventManager);
- // Event Done
-
- $assetManager
- ->shouldReceive('provides')
- ->with('Proem\Routing\RouteManagerInterface')
- ->once()
- ->andReturn(true);
-
- $route = new Route;
- $route->in($assetManager);
- }
-
- public function testCanSetDefaultRouteAsset()
- {
- $event = m::mock('Proem\Signal\EventInterface', ['proem.in.route']);
- $eventManager = m::mock('Proem\Signal\EventManagerInterface');
- $eventManager
- ->shouldReceive('trigger')
- ->with('Proem\Signal\EventInterface', 'closure')
- ->once();
-
- $assetManager = m::mock('Proem\Service\AssetManagerInterface');
- $assetManager
- ->shouldReceive('provides')
- ->with('eventManager', 'Proem\Signal\EventManagerInterface')
- ->once()
- ->andReturn(true);
-
- $assetManager
- ->shouldReceive('get')
- ->with('eventManager')
- ->once()
- ->andReturn($eventManager);
-
- $assetManager
- ->shouldReceive('provides')
- ->with('Proem\Routing\RouteManagerInterface')
- ->once()
- ->andReturn(false);
-
- $assetManager
- ->shouldReceive('set')
- ->with('routeManager', 'Proem\Service\AssetInterface')
- ->once();
-
$route = new Route;
$route->in($assetManager);
}
View
15 lib/Proem/Proem.php
@@ -59,15 +59,16 @@ class Proem
*/
public function __construct(AssetManagerInterface $assetManager = null)
{
- if ($assetManager !== null) {
- $this->assetManager = $assetManager;
- } else {
+ if ($assetManager === null) {
$this->assetManager = new AssetManager;
+ } else {
+ $this->assetManager = $assetManager;
}
- if (!$this->assetManager->provides('Proem\Signal\EventManagerInterface')) {
- $this->assetManager->set('eventManager', (new AssetComposer('Proem\Signal\EventManager'))->compose(true));
- }
+ $this->assetManager->alias([
+ 'Proem\Signal\EventManagerInterface' => 'Proem\Signal\EventManager',
+ 'Proem\Signal\EventManager' => 'eventManager'
+ ]);
}
/**
@@ -81,7 +82,7 @@ public function bootstrap(EventInterface $initEvent = null)
$initEvent = new Event('proem.init');
}
- $this->assetManager->get('eventManager')->trigger($initEvent);
+ $this->assetManager->resolve('eventManager')->trigger($initEvent);
return $this;
}
View
11 lib/Proem/Service/Asset.php
@@ -137,7 +137,7 @@ public function is($type = null)
* @param array $params Allow last minute setting of parameters.
* @param Proem\Service\AssetManagerInterface $assetManager
*/
- public function fetch(array $params = [], AssetManagerInterface $assetManager = null)
+ public function __invoke(array $params = [], AssetManagerInterface $assetManager = null)
{
$asset = $this->asset;
@@ -155,12 +155,9 @@ public function fetch(array $params = [], AssetManagerInterface $assetManager =
* that whenever this Asset is retrieved it will always return the same instance.
*
* <code>
- * $foo = new Asset(
- * 'Foo',
- * Asset::single(function() {
- * return new Foo;
- * })
- * );
+ * $foo = (new Asset('Foo'))->single(function() {
+ * return new Foo;
+ * });
* </code>
*
* @param closure $closure
View
187 lib/Proem/Service/AssetComposer.php
@@ -1,187 +0,0 @@
-<?php
-
-/**
- * The MIT License
- *
- * Copyright (c) 2010 - 2013 Tony R Quilkey <trq@proemframework.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/**
- * @namespace Proem\Service
- */
-namespace Proem\Service;
-
-use Proem\Service\AssetComposerInterface;
-use Proem\Service\Asset;
-
-/**
- * A **VERY** simple asset composer.
- *
- * This composer is capable of building assets from an array of
- * arguments. It also contains methods for editing the same.
- */
-class AssetComposer implements AssetComposerInterface
-{
- /**
- * The class this asset is to provide.
- *
- * @var string
- */
- protected $class;
-
- /**
- * An Array of arguments to pass to the construct
- * of the object being created.
- *
- * @var array
- */
- protected $constructArgs = [];
-
- /**
- * An array of arguments to pass to methods on the
- * object being created.
- *
- * This array takes the name of the method as an index,
- * followed by an array of arguments.
- *
- * @var array
- */
- protected $methodArgs = [];
-
- /**
- * Setup
- *
- * <code>
- * $foo = (new AssetComposer([
- * 'class' => 'Foo',
- * 'construct' => ['arg1'],
- * 'methods' => [
- * 'setArg2' => ['arg2']
- * ]
- * ]))->compose();
- * </code>
- *
- * <code>
- * $foo = (new AssetComposer('Foo'))
- * ->construct(['arg1'])
- * ->methods(['setArg2' => ['arg2']])
- * ->compose();
- * </code>
- *
- * @param string|array $class Either the name of the class to create, or an array of arguments.
- */
- public function __construct($class)
- {
- if (is_array($class)) {
- if (isset($class['class'])) {
- $this->class = $class['class'];
- }
-
- if (isset($class['construct'])) {
- $this->constructArgs = $class['construct'];
- }
-
- if (isset($class['methods'])) {
- $this->methodArgs = $class['methods'];
- }
- } else {
- $this->class = $class;
- }
- }
-
- /**
- * Set an array of arguments to pass to the object's
- * __construct method.
- *
- * @param array
- */
- public function construct($constructArgs)
- {
- $this->constructArgs = $constructArgs;
- return $this;
- }
-
- /**
- * Set an array of arguments to pass to different methods on the
- * objected being constructed.
- *
- * @param array
- */
- public function methods($methodArgs)
- {
- $this->methodArgs = $methodArgs;
- return $this;
- }
-
- /**
- * Build a configured Asset and return it.
- *
- * This Asset can optionally be returned implementing a singleton.
- *
- * @param bool $single
- * @return Proem\Service\AssetInterface
- */
- public function compose($single = false)
- {
- $reflection = new \ReflectionClass($this->class);
-
- if ($single) {
- static $obj;
- if ($obj == null) {
- $obj = (new Asset($this->class))->single(
- function () use ($reflection) {
- if ($this->constructArgs) {
- $object = $reflection->newInstanceArgs($this->constructArgs);
- } else {
- $object = $reflection->newInstance();
- }
-
- foreach ($this->methodArgs as $method => $params) {
- if ($reflection->hasMethod($method)) {
- call_user_func_array([$object, $method], $params);
- }
- }
- return $object;
- }
- );
- }
- return $obj;
- } else {
- return new Asset(
- $this->class,
- function () use ($reflection) {
- if ($this->constructArgs) {
- $object = $reflection->newInstanceArgs($this->constructArgs);
- } else {
- $object = $reflection->newInstance();
- }
-
- foreach ($this->methodArgs as $method => $params) {
- if ($reflection->hasMethod($method)) {
- call_user_func_array([$object, $method], $params);
- }
- }
- return $object;
- }
- );
- }
- }
-}
View
69 lib/Proem/Service/AssetComposerInterface.php
@@ -1,69 +0,0 @@
-<?php
-
-/**
- * The MIT License
- *
- * Copyright (c) 2010 - 2013 Tony R Quilkey <trq@proemframework.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/**
- * @namespace Proem\Service
- */
-namespace Proem\Service;
-
-/**
- * A **VERY** simple asset composer interface.
- */
-interface AssetComposerInterface
-{
- /**
- * Setup
- *
- * @param string|array $class Either the name of the class to create, or an array of arguments.
- */
- public function __construct($class);
-
- /**
- * Set an array of arguments to pass to the object's
- * __construct method.
- *
- * @param array
- */
- public function construct($constructArgs);
-
- /**
- * Set an array of arguments to pass to different methods on the
- * objected being constructed.
- *
- * @param array
- */
- public function methods($methodArgs);
-
- /**
- * Build a configured Asset and return it.
- *
- * This Asset can optionally be returned implementing a singleton.
- *
- * @param bool $single
- * @return Proem\Service\AssetInterface
- */
- public function compose($single = false);
-}
View
2 lib/Proem/Service/AssetInterface.php
@@ -61,7 +61,7 @@ public function is();
* @param array $params Allow last minute setting of parameters.
* @param Proem\Service\AssetManagerInterface $assetManager
*/
- public function fetch(array $params = [], AssetManagerInterface $assetManager = null);
+ public function __invoke(array $params = [], AssetManagerInterface $assetManager = null);
/**
* Store an asset in such a way that when it is retrieved it will always return
View
222 lib/Proem/Service/AssetManager.php
@@ -29,168 +29,186 @@
*/
namespace Proem\Service;
-use Proem\Service\AssetManagerInterface;
-use Proem\Service\AssetInterface;
-use Proem\Util\Structure\DataCollectionTrait;
+use Proem\Service\Asset;
/**
* A collection of assets.
*
- * Within the manager itself assets are stored in a hash of key values where each
- * value is an asset container.
+ * Within the manager itself assets are stored in a hash of key value pairs where each
+ * value is an asset container of some sort. These containers can be simple closures, or
+ * objects of type \Proem\Service\Asset.a
*
- * These containers contain the parameters required to instantiate an asset as
- * well as a closure capable of returning a configured and instantiated asset.
- *
- * While this class looks very similar to the DataCollectionInterface it does *NOT* implement
- * it. In fact, if you look closer you will note that the methods defined within the AssetManagerInterface
- * are slight variants of the DataCollectionInterface's set(), get() and has().
- *
- * @see Proem\Service\Asset
+ * These containers are capable of returning an instantiated object of the type requested.
*/
class AssetManager implements AssetManagerInterface
{
/**
- * Use the generic DataCollectionTrait trait.
+ * Store our assets.
*
- * This provides implementations for the Iterator and Serializable
+ * @var array
*/
- use DataCollectionTrait;
+ protected $assets = [];
/**
- * Store any *resolver* config
+ * Store any instances.
*
* @var array
*/
- protected $resolverConfig;
+ protected $instances = [];
/**
- * Store an array containing information about what
- * Assets this manager provides.
+ * Store alias mappings.
*
* @var array
*/
- protected $provides = [];
+ protected $aliases = [];
/**
- * Setup.
+ * Alias a class to a simpler name or an interface/abstract to an implementation.
*
- * Optionaly pass in and then pass on the asset resolver configuration.
- *
- * @param array $resolverConfig
+ * @param string $type
+ * @param string $alias
+ * @param bool $force Optionally override existing index.
*/
- public function __construct(array $resolverConfig = [])
+ public function alias($type, $alias = null, $force = false)
{
- $this->resolverConfig = $resolverConfig;
+ if (is_array($type)) {
+ foreach ($type as $asset => $alias) {
+ $this->setParam('aliases', $alias, $asset, $force);
+ }
+ } else {
+ $this->setParam('aliases', $alias, $type, $force);
+ }
}
/**
- * Store an Asset container by named index.
+ * Attach an asset to the service manager if it doesn't already exist.
*
- * @param string $index The index the asset will be referenced by.
- * @param Proem\Service\AssetInterface $asset
- * @return Proem\Service\AssetManagerInterface
- */
- public function set($index, AssetInterface $asset)
- {
- $this->data[$index] = $asset;
- $this->provides[$index] = $asset->is();
- return $this;
- }
-
- /**
- * Retrieve an object from an asset.
+ * Assets can be provided by a *type* Asset object, a closure providing
+ * the asst or an actual instance of an object.
*
- * @param string $index The index the asset is referenced by
- * @param array $params Allow last minute setting of parameters.
- * @return object The object provided by the asset container
- */
- public function get($index, array $params = [])
- {
- return isset($this->data[$index]) ? $this->data[$index]->fetch($params, $this) : null;
- }
-
- /**
- * Retrieve an asset.
+ * Setting the bool $single to true will force any asset provided via a closure
+ * to be wrapped within another closure which will cache the results. This makes
+ * asset return the same instance on each call. (A singleton).
*
- * @param string $index The index the asset is referenced by
- * @param array $params Allow last minute setting of parameters.
- * @return object The object provided by the asset container
+ * @param string|array $name The name to index the asset by. Also excepts an array so as to alias.
+ * @param Proem\Service\Asset|closure|object $type
+ * @param bool $single
+ * @param bool $force Optionally override existing (@see force).
*/
- public function getAsset($index, array $params = [])
+ public function attach($name, $type = null, $single = false, $force = false)
{
- return isset($this->data[$index]) ? $this->data[$index] : null;
+ if (is_array($name)) {
+ $alias = key($name);
+ $type = current($name);
+ $this->alias($type, $alias, $force);
+ }
+
+ if ($type instanceof \Closure && $single) {
+ $this->setParam('assets', $name, function($params) use ($type) {
+ static $obj;
+
+ if ($obj === null) {
+ $obj = $type($params, $this);
+ }
+ return $obj;
+ }, $force);
+
+ } elseif ($type instanceof \Closure || $type instanceof Asset) {
+ $this->setParam('assets', $name, $type, $force);
+
+ } elseif (is_object($type)) {
+ $this->setParam('instances', $name, $type, $force);
+ }
}
/**
- * Check to see if this manager has a specific asset by index.
+ * Attach an asset to the service manager overriding any existing of the same index.
*
- * @param string $index The index the asset is referenced by
- * @return bool
+ * @param string|array $name The name to index the asset by. Also excepts an array so as to alias.
+ * @param Proem\Service\Asset|closure|object $type
+ * @param bool $single
*/
- public function has($index)
- {
- return isset($this->data[$index]);
+ public function force($name, $type = null, $single = false) {
+ $this->attach($name, $type, $single, true);
}
/**
- * Check to see if this manager provides a specifically named
- * asset and (optionally) that asset is a specific type.
+ * Return an asset by index.
*
- * @param string $index
- * @param string $provides
- * @return bool
+ * First map any alias, then check to see if we already have an instance of this
+ * type cached, if so, return it. If not, check to see if we have any assets indexed
+ * by this name, if so, execute it's closure and return the results.
+ *
+ * If the above fails, we start the auto resolve process. This attempts to resolve to
+ * instantiate the requested object and any dependencies that it may require to do so.
+ *
+ * @param string $name
+ * @param array $params Any extra paremeters to pass along to a closure|Asset|object
*/
- public function provides($index, $provides = null)
+ public function resolve($name, $params = [])
{
- if ($provides === null) {
- return in_array($index, $this->provides);
+ if (isset($this->aliases[$name])) {
+ $name = $this->aliases[$name];
+ }
+
+ if (isset($this->instances[$name])) {
+ return $this->instances[$name];
+ }
+
+ if (isset($this->assets[$name])) {
+ return $this->assets[$name]($params, $this);
+
} else {
- if ($this->has($index)) {
- return $this->data[$index]->is($provides);
+ $reflection = new \ReflectionClass($name);
+ if ($reflection->isInstantiable()) {
+ $construct = $reflection->getConstructor();
+ if ($construct === null) {
+ $object = new $name;
+ } else {
+ $dependencies = $this->getDependencies($construct->getParameters());
+ $object = $reflection->newInstanceArgs($dependencies);
+ }
+
+ if (method_exists($object, 'setParams')) {
+ $object->setParams($params);
+ }
+
+ return $object;
}
}
}
/**
- * If the asset manager provides an object of a specific type, return
- * the asset providing that object type.
+ * A helper used to set aliases, assets and instances.
+ *
+ * Not pretty! But hey?
*
- * @param string $object The complete object name (namespaced).
+ * @param string $type
+ * @param string $index
+ * @param mixed $value
+ * @param bool force override
*/
- public function getProvided($object)
- {
- if ($this->provides($object)) {
- return $this->data[array_flip($this->provides)[$object]];
+ protected function setParam($type, $index, $value, $force = false) {
+ if ($force) {
+ $this->{$type}[$index] = $value;
+ } else if (!isset($this->{$type}[$index])) {
+ $this->{$type}[$index] = $value;
}
}
/**
- * If the asset manager provides an object of a specific type, return
- * the asset providing that object type. Otherwise, attempt to compose
- * the asset.
- *
- * @param string $object The complete object name (namespaced).
+ * A simple helper to resolve an assets dependencies.
*/
- public function resolve($object, $constructArgs = null, $methodArgs = null)
+ protected function getDependencies($params)
{
- if ($this->has($object)) {
- // Resolve by name?
- return $this->get($object, $args);
-
- } elseif ($asset = $this->getProvided($object)) {
- // Resolve by type?
- return $asset;
-
- } else {
- // Go and create.
- $asset = (new AssetResolver($this->resolverConfig))->resolve($object, $constructArgs, $methodArgs);
- $name = $asset->is();
- if (!isset($this->data[$name])) {
- $this->set($name, $asset);
+ $deps = [];
+ foreach ($params as $param) {
+ $dependency = $param->getClass();
+ if ($dependency !== null) {
+ $deps[] = $this->resolve($dependency->name);
}
}
-
- return $asset;
+ return $deps;
}
}
View
58 lib/Proem/Service/AssetManagerInterface.php
@@ -34,50 +34,44 @@
/**
* Interface that all asset managers must implement.
*/
-interface AssetManagerInterface extends \Iterator, \Serializable, \Countable
+interface AssetManagerInterface
{
/**
- * Store an Asset container by named index.
+ * Alias a class to a simpler name or an interface/abstract to an implementation.
*
- * @param string $index The index the asset will be referenced by.
- * @param Proem\Service\AssetInterface $asset
- * @return Proem\Service\AssetManagerInterface
+ * @param string $type
+ * @param string $alias
+ * @param bool $force Optionally override existing index.
*/
- public function set($index, AssetInterface $asset);
+ public function alias($type, $alias = null, $force = false);
/**
- * Retrieve an object from an asset.
+ * Attach an asset to the service manager.
*
- * @param string $index The index the asset is referenced by
- * @param array $params Allow last minute setting of parameters.
- * @return object The object provided by the asset container
- */
- public function get($index, array $params = []);
-
- /**
- * Retrieve an asset.
+ * Assets can be provided by a *type* Asset object, a closure providing
+ * the asst or an actual instance of an object.
*
- * @param string $index The index the asset is referenced by
- * @param array $params Allow last minute setting of parameters.
- * @return object The object provided by the asset container
- */
- public function getAsset($index, array $params = []);
-
- /**
- * Check to see if this manager has a specific asset by index.
+ * Setting the bool $single to true will force any asset provided via a closure
+ * to be wrapped within another closure which will cache the results. This makes
+ * asset return the same instance on each call. (A singleton).
*
- * @param string $index The index the asset is referenced by
- * @return bool
+ * @param string|array $name The name to index the asset by. Also excepts an array so as to alias.
+ * @param Proem\Service\Asset|closure|object $type
+ * @param bool $single
*/
- public function has($index);
+ public function attach($name, $type = null, $single = false);
/**
- * Check to see if this manager provides a specifically named
- * asset and (optionally) that asset is a specific type.
+ * Return an asset by index.
+ *
+ * First map any alias, then check to see if we already have an instance of this
+ * type cached, if so, return it. If not, check to see if we have any assets indexed
+ * by this name, if so, execute it's closure and return the results.
+ *
+ * If the above fails, we start the auto resolve process. This attempts to resolve to
+ * instantiate the requested object and any dependencies that it may require to do so.
*
- * @param string $index
- * @param string $provides
- * @return bool
+ * @param string $name
*/
- public function provides($index, $provides = null);
+ public function resolve($name);
}
View
144 lib/Proem/Service/AssetResolver.php
@@ -1,144 +0,0 @@
-<?php
-
-/**
- * The MIT License
- *
- * Copyright (c) 2010 - 2013 Tony R Quilkey <trq@proemframework.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/**
- * @namespace Proem\Service
- */
-namespace Proem\Service;
-
-use Proem\Service\Asset;
-
-/**
- * A **VERY** simple asset resolver.
- *
- * Designed to attempt to build an asset from scratch.
- *
- * Presently there is no error handling. If you pass the
- * wrong config into a construct, stuff will blow up in
- * your face.
- */
-class AssetResolver implements AssetResolverInterface
-{
- /**
- * Store any configuration options.
- *
- * @var array
- */
- protected $config;
-
- /**
- * Setup
- *
- * @param array $config
- */
- public function __construct(array $config = [])
- {
- $this->config = $config;
- }
-
- /**
- * Attempt asset resolution from the complete object type and
- * any arguments requiring injection via either the construct
- * other method.
- *
- * @param string $object The complete (namespaced) object type
- * @param array $constructArgs Any arguments that need to be passed as the construct arg.
- * @param array $methodArgs Any arguments that need to be passed as the methods arg.
- * @see \Proem\Service\AssetComposer
- */
- public function resolve($object, $constructArgs = null, $methodArgs = null)
- {
- $object = str_replace(['Interface', 'Abstract'], '', $object);
- $args = [];
-
- if ($constructArgs) {
- $args['construct'] = (array) $constructArgs;
- }
-
- if ($methodArgs) {
- $args['methods'] = (array) $methodArgs;
- }
-
- // Interface and Abstract configs should be merged first.
- foreach (['Interface', 'Abstract'] as $type) {
- if (isset($this->config[$object . $type])) {
- $args = array_merge_recursive($this->config[$object . $type], $args);
- }
- }
-
- // More specific object configs.
- if (isset($this->config[$object])) {
- $args = array_merge_recursive($this->config[$object], $args);
- }
-
- // Resolve any @ and # dependcies.
- $args = $this->resolveDependencies($args);
-
- $object = isset($args['class']) ? $args['class'] : $object;
- $composer = new AssetComposer($object);
-
- // Prepare to compose.
- foreach (['construct', 'methods'] as $type) {
- if (isset($args[$type])) {
- $composer->$type($args[$type]);
- }
- }
- $single = isset($args['single']) ? $args['single'] : false;
-
- return $composer->compose($single);
- }
-
- /**
- * Within the *construct* and *methods* options the special symbols # and @
- * appearing at the start of the value represent a dependant asset or object
- * dependency which should also be resolved.
- *
- * This method attempts to do so.
- *
- * @param array $args Any arguments that need to be passed to the asset.
- * @see \Proem\Service\AssetComposer
- */
- protected function resolveDependencies($args)
- {
- foreach (['construct', 'methods'] as $type) {
- if (isset($args[$type])) {
- foreach ($args[$type] as $key => $value) {
- if ($value{0} == '#') {
- // # Asset
- $args[$type][$key] = $this->resolve(substr($value, 1));
- }
-
- if ($value{0} == '@') {
- // @ Object
- $args[$type][$key] = $this->resolve(substr($value, 1))->fetch();
- }
- }
- }
- }
-
- return $args;
- }
-}
View
61 lib/Proem/Service/AssetResolverInterface.php
@@ -1,61 +0,0 @@
-<?php
-
-/**
- * The MIT License
- *
- * Copyright (c) 2010 - 2013 Tony R Quilkey <trq@proemframework.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/**
- * @namespace Proem\Service
- */
-namespace Proem\Service;
-
-/**
- * A **VERY** simple asset resolver.
- *
- * Designed to attempt to build an asset from scratch.
- *
- * Presently there is no error handling. If you pass the
- * wrong config into a construct, stuff will blow up in
- * your face.
- */
-interface AssetResolverInterface
-{
- /**
- * Setup
- *
- * @param array $config
- */
- public function __construct(array $config = []);
-
- /**
- * Attempt asset resolution from the complete object type and
- * any arguments requiring injection via either the construct
- * other method.
- *
- * @param string $object The complete (namespaced) object type
- * @param array $constructArgs Any arguments that need to be passed as the construct arg.
- * @param array $methodArgs Any arguments that need to be passed as the methods arg.
- * @see \Proem\Service\AssetComposer
- */
- public function resolve($object, $constructArgs = null, $methodArgs = null);
-}
View
21 lib/Proem/Service/Tests/AssetComposerFixtures/Foo.php
@@ -1,21 +0,0 @@
-<?php
-
-class Foo
-{
- protected $var;
-
- public function __construct($var = null)
- {
- $this->var = $var;
- }
-
- public function setVar($var)
- {
- $this->var = $var;
- }
-
- public function getVar()
- {
- return $this->var;
- }
-}
View
101 lib/Proem/Service/Tests/AssetComposerTest.php
@@ -1,101 +0,0 @@
-<?php
-
-/**
- * The MIT License
- *
- * Copyright (c) 2010 - 2013 Tony R Quilkey <trq@proemframework.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-namespace Proem\Service\Tests;
-
-use Proem\Service\AssetComposerInterface;
-use Proem\Service\AssetComposer;
-
-require_once __DIR__ . '/AssetComposerFixtures/Foo.php';
-
-class AssetComposerTest extends \PHPUnit_Framework_TestCase
-{
- public function testCanInstantiateAssetManager()
- {
- $this->assertInstanceOf('Proem\Service\AssetComposerInterface', new AssetComposer([]));
- }
-
- public function testCanBuildSimpleAsset()
- {
- $foo = new AssetComposer('Foo');
-
- $this->assertInstanceOf('Proem\Service\AssetInterface', $foo->compose());
- $this->assertInstanceOf('Foo', $foo->compose()->fetch());
- }
-
- public function testCanBuildSingletonAsset()
- {
- $foo = new AssetComposer('Foo');
- $this->assertInstanceOf('Proem\Service\AssetInterface', $foo->compose());
- $this->assertInstanceOf('Foo', $foo->compose()->fetch());
- $this->assertSame($foo->compose(true)->fetch(), $foo->compose(true)->fetch());
- }
-
- public function testCanBuildAssetFromConstructArray()
- {
-
- $foo = new AssetComposer([
- 'class' => 'Foo',
- 'construct' => ['hello']
- ]);
-
- $this->assertInstanceOf('Proem\Service\AssetInterface', $foo->compose());
- $this->assertInstanceOf('Foo', $foo->compose()->fetch());
- $this->assertEquals('hello', $foo->compose()->fetch()->getVar());
- }
-
- public function testCanBuildAssetFromComplexArray()
- {
- $foo = new AssetComposer([
- 'class' => 'Foo',
- 'methods' => ['setVar' => ['hello']]
- ]);
-
- $this->assertInstanceOf('Proem\Service\AssetInterface', $foo->compose());
- $this->assertInstanceOf('Foo', $foo->compose()->fetch());
- $this->assertEquals('hello', $foo->compose()->fetch()->getVar());
- }
-
- public function testCanBuildAssetFromConstructCall()
- {
- $foo = new AssetComposer('Foo');
- $foo->construct(['hello']);
-
- $this->assertInstanceOf('Proem\Service\AssetInterface', $foo->compose());
- $this->assertInstanceOf('Foo', $foo->compose()->fetch());
- $this->assertEquals('hello', $foo->compose()->fetch()->getVar());
- }
-
- public function testCanBuildAssetFromMethodCall()
- {
- $foo = new AssetComposer('Foo');
- $foo->methods(['setVar' => ['hello']]);
-
- $this->assertInstanceOf('Proem\Service\AssetInterface', $foo->compose());
- $this->assertInstanceOf('Foo', $foo->compose()->fetch());
- $this->assertEquals('hello', $foo->compose()->fetch()->getVar());
- }
-}
View
9 lib/Proem/Service/Tests/AssetManagerFixtures/Bar.php
@@ -0,0 +1,9 @@
+<?php
+
+class Bar
+{
+ public function doSomething()
+ {
+ return "bar";
+ }
+}
View
9 lib/Proem/Service/Tests/AssetManagerFixtures/Bar2.php
@@ -0,0 +1,9 @@
+<?php
+
+class Bar2 extends Bar
+{
+ public function doSomething()
+ {
+ return "bar2";
+ }
+}
View
16 lib/Proem/Service/Tests/AssetManagerFixtures/Foo.php
@@ -0,0 +1,16 @@
+<?php
+
+class Foo
+{
+ protected $bar;
+
+ public function __construct(Bar $bar)
+ {
+ $this->bar = $bar;
+ }
+
+ public function getBar()
+ {
+ return $this->bar;
+ }
+}
View
16 lib/Proem/Service/Tests/AssetManagerFixtures/NeedsInterface.php
@@ -0,0 +1,16 @@
+<?php
+
+class NeedsInterface
+{
+ protected $bar;
+
+ public function __construct(SomeInterface $bar)
+ {
+ $this->bar = $bar;
+ }
+
+ public function getBar()
+ {
+ return $this->bar;
+ }
+}
View
9 lib/Proem/Service/Tests/AssetManagerFixtures/Some.php
@@ -0,0 +1,9 @@
+<?php
+
+class Some implements SomeInterface
+{
+ public function doSomething()
+ {
+ return "some";
+ }
+}
View
6 lib/Proem/Service/Tests/AssetManagerFixtures/SomeInterface.php
@@ -0,0 +1,6 @@
+<?php
+
+interface SomeInterface
+{
+ public function doSomething();
+}
View
10 lib/Proem/Service/Tests/AssetManagerFixtures/Someother.php
@@ -0,0 +1,10 @@
+<?php
+
+class Someother implements SomeInterface
+{
+ public function doSomething()
+ {
+ return "someother";
+ }
+}
+
View
158 lib/Proem/Service/Tests/AssetManagerTest.php
@@ -38,57 +38,139 @@ public function testCanInstantiateAssetManager()
$this->assertInstanceOf('Proem\Service\AssetManagerInterface', $am);
}
- public function testCanStoreAndRetreive()
+ public function testCanAttachAndRetreiveClosure()
+ {
+ $am = new AssetManager;
+ $am->attach('foo', function() { return new \stdClass; });
+
+ $this->assertInstanceOf('\stdClass', $am->resolve('foo'));
+ }
+
+ public function testCanAttachAndRetreiveInstance()
+ {
+ $am = new AssetManager;
+ $am->attach('foo', new \stdClass);
+
+ $this->assertInstanceOf('\stdClass', $am->resolve('foo'));
+ }
+
+ public function testCanStoreAndRetreiveAssetObject()
{
$asset = m::mock('\Proem\Service\Asset', ['stdClass']);
$asset
- ->shouldReceive('is')
- ->once()
- ->andReturn('stdClass');
- $asset
- ->shouldReceive('fetch')
+ ->shouldReceive('__invoke')
->once()
->andReturn(new \stdClass);
$am = new AssetManager;
- $am->set('foo', $asset);
+ $am->attach('foo', $asset);
- $this->assertInstanceOf('\stdClass', $am->get('foo'));
+ $this->assertInstanceOf('\stdClass', $am->resolve('foo'));
}
- public function testProvides()
+ public function testCanAttachAndRetreiveClosureSingleton()
{
- $asset = m::mock('\Proem\Service\Asset', ['stdClass']);
- $asset
- ->shouldReceive('is')
- ->twice()
- ->andReturn(true);
+ $am = new AssetManager;
+ $am->attach('foo', function() { return new \stdClass; }, true);
+ $this->assertInstanceOf('\stdClass', $am->resolve('foo'));
+ $this->assertSame($am->resolve('foo'), $am->resolve('foo'));
+ }
+
+ public function testInstanceIsSingleton()
+ {
$am = new AssetManager;
- $am->set('foo', $asset);
+ $am->attach('foo', new \stdClass);
- $this->assertTrue($am->provides('stdClass'));
- $this->assertTrue($am->provides('foo', 'stdClass'));
+ $this->assertInstanceOf('\stdClass', $am->resolve('foo'));
+ $this->assertSame($am->resolve('foo'), $am->resolve('foo'));
}
- public function testCanGetProvided()
+ public function testCanAlias()
{
- $asset = m::mock('\Proem\Service\Asset', ['stdClass']);
- $asset
- ->shouldReceive('is')
- ->once()
- ->andReturn('stdClass');
+ $am = new AssetManager;
+ $am->alias('stdClass', 'foo');
+ $am->attach('foo', new \stdClass);
+
+ $this->assertInstanceOf('\stdClass', $am->resolve('foo'));
+ $this->assertInstanceOf('\stdClass', $am->resolve('stdClass'));
+ }
+
+ public function testCanAliasOnAttach()
+ {
+ $am = new AssetManager;
+ $am->attach(['foo' => 'stdClass'], new \stdClass);
+
+ $this->assertInstanceOf('\stdClass', $am->resolve('foo'));
+ $this->assertInstanceOf('\stdClass', $am->resolve('stdClass'));
+ }
+ public function testCanAutoResolveSimple()
+ {
+ require_once __DIR__ . '/AssetManagerFixtures/Bar.php';
+ $am = new AssetManager;
+
+ $this->assertInstanceOf('Bar', $am->resolve('Bar'));
+ }
+
+ public function testCanAutoResolveWithDeps()
+ {
+ require_once __DIR__ . '/AssetManagerFixtures/Foo.php';
+ require_once __DIR__ . '/AssetManagerFixtures/Bar.php';
$am = new AssetManager;
- $am->set('foo', $asset);
- $this->assertInstanceOf('\Proem\Service\Asset', $am->getProvided('stdClass'));
+ $this->assertInstanceOf('Foo', $am->resolve('Foo'));
+ $this->assertInstanceOf('Bar', $am->resolve('Foo')->getBar());
+ }
+
+ public function testCanAutoResolveAliased()
+ {
+ require_once __DIR__ . '/AssetManagerFixtures/Bar.php';
+ $am = new AssetManager;
+ $am->alias('Bar', 'thisisbar');
+
+ $this->assertInstanceOf('Bar', $am->resolve('thisisbar'));
+ }
+
+ public function testCanAutoResolveAliasedDependency()
+ {
+ require_once __DIR__ . '/AssetManagerFixtures/Foo.php';
+ require_once __DIR__ . '/AssetManagerFixtures/Bar2.php';
+ $am = new AssetManager;
+ $am->alias('Bar2', 'Bar');
+
+ $this->assertInstanceOf('Bar2', $am->resolve('Foo')->getBar());
+ }
+
+ public function testCanAutoResolveWithDependencyRequiringInterface()
+ {
+ require_once __DIR__ . '/AssetManagerFixtures/NeedsInterface.php';
+ require_once __DIR__ . '/AssetManagerFixtures/SomeInterface.php';
+ require_once __DIR__ . '/AssetManagerFixtures/Some.php';
+
+ $am = new AssetManager;
+ $am->alias('Some', 'SomeInterface');
+
+ $this->assertInstanceOf('NeedsInterface', $am->resolve('NeedsInterface'));
+ }
+
+ public function testCanRemapAnAlias()
+ {
+ require_once __DIR__ . '/AssetManagerFixtures/NeedsInterface.php';
+ require_once __DIR__ . '/AssetManagerFixtures/SomeInterface.php';
+ require_once __DIR__ . '/AssetManagerFixtures/Some.php';
+ require_once __DIR__ . '/AssetManagerFixtures/Someother.php';
+
+ $am = new AssetManager;
+ $am->alias('Some', 'SomeInterface');
+
+ $am->attach('Some', function() { return new \Someother; });
+
+ $this->assertInstanceOf('NeedsInterface', $am->resolve('NeedsInterface'));
+ $this->assertEquals('someother', $am->resolve('NeedsInterface')->getBar()->doSomething());
}
- /**
- * TODO: Should have a better look at mocking the Mail & Transport classes.
- */
- public function testCanBuildComplexDependencies()
+ public function testCanBuildComplexServices()
{
require_once __DIR__ . '/AssetManagerFixtures/Transport.php';
require_once __DIR__ . '/AssetManagerFixtures/Mail.php';
@@ -106,19 +188,19 @@ function($asset) {
);
$mail = new Asset('Mail', function($asset, $assetManager) {
- return new \Mail($assetManager->get('transport'));
+ return new \Mail($assetManager->resolve('transport'));
});
$assetManager = new AssetManager;
- $assetManager->set('transport', $transport);
- $assetManager->set('mail', $mail);
+ $assetManager->attach('transport', $transport);
+ $assetManager->attach('mail', $mail);
- $this->assertInstanceOf('\Transport', $assetManager->get('transport'));
- $this->assertInstanceOf('\Mail', $assetManager->get('mail'));
- $this->assertInstanceOf('\Transport', $assetManager->get('mail')->transport);
+ $this->assertInstanceOf('\Transport', $assetManager->resolve('transport'));
+ $this->assertInstanceOf('\Mail', $assetManager->resolve('mail'));
+ $this->assertInstanceOf('\Transport', $assetManager->resolve('mail')->transport);
- $this->assertEquals('smtp.foo.com', $assetManager->get('mail')->transport->server);
- $this->assertEquals('username', $assetManager->get('mail')->transport->username);
- $this->assertEquals('password', $assetManager->get('mail')->transport->password);
+ $this->assertEquals('smtp.foo.com', $assetManager->resolve('mail')->transport->server);
+ $this->assertEquals('username', $assetManager->resolve('mail')->transport->username);
+ $this->assertEquals('password', $assetManager->resolve('mail')->transport->password);
}
}
View
17 lib/Proem/Service/Tests/AssetResolverFixtures/Bar.php
@@ -1,17 +0,0 @@
-<?php
-
-namespace ResolverFixtures;
-
-class Bar implements BarInterface
-{
- protected $data;
- public function __construct($data = null)
- {
- $this->data = $data;
- }
-
- public function getData()
- {
- return $this->data;
- }
-}
View
8 lib/Proem/Service/Tests/AssetResolverFixtures/BarInterface.php
@@ -1,8 +0,0 @@
-<?php
-
-namespace ResolverFixtures;
-
-interface BarInterface
-{
- public function getData();
-}
View
10 lib/Proem/Service/Tests/AssetResolverFixtures/Foo.php
@@ -1,10 +0,0 @@
-<?php
-
-namespace ResolverFixtures;
-
-class Foo
-{
- public function __construct(Bar $bar)
- {
- }
-}
View
17 lib/Proem/Service/Tests/AssetResolverFixtures/SomeBar.php
@@ -1,17 +0,0 @@
-<?php
-
-namespace ResolverFixtures;
-
-class SomeBar implements BarInterface
-{
- protected $data;
- public function __construct($data = null)
- {
- $this->data = $data;
- }
-
- public function getData()
- {
- return $this->data;
- }
-}
View
121 lib/Proem/Service/Tests/AssetResolverTest.php
@@ -1,121 +0,0 @@
-<?php
-
-/**
- * The MIT License
- *
- * Copyright (c) 2010 - 2013 Tony R Quilkey <trq@proemframework.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-namespace Proem\Service\Tests;
-
-use Proem\Service\AssetResolver;
-use Proem\Service\AssetManager;
-
-require_once __DIR__ . '/AssetResolverFixtures/Foo.php';
-require_once __DIR__ . '/AssetResolverFixtures/BarInterface.php';
-require_once __DIR__ . '/AssetResolverFixtures/Bar.php';
-require_once __DIR__ . '/AssetResolverFixtures/SomeBar.php';
-
-class AssetResolverTest extends \PHPUnit_Framework_TestCase
-{
- public function testCanInstantiate()
- {
- $this->assertInstanceOf('Proem\Service\AssetResolverInterface', new AssetResolver);
- }
-
- public function testCanResolveSimple()
- {
- $result = (new AssetResolver)->resolve('\ResolverFixtures\Bar');
- $this->assertInstanceOf('\ResolverFixtures\Bar', $result->fetch());
- }
-
- public function testCanResolveComplex()
- {
- $result = (new AssetResolver)
- ->resolve('\ResolverFixtures\BarInterface', 'some-data');
-
- $this->assertInstanceOf('\ResolverFixtures\Bar', $result->fetch());
- $this->assertEquals('some-data', $result->fetch()->getData());
- }
-
- public function testCanResolveComplexViaConfig()
- {
- $result = (new AssetResolver(['\ResolverFixtures\Bar' => ['construct' => ['some-data']]]))
- ->resolve('\ResolverFixtures\Bar');
-
- $this->assertInstanceOf('\ResolverFixtures\Bar', $result->fetch());
- $this->assertEquals('some-data', $result->fetch()->getData());
- }
-
- public function testCanResolveComplexViaConfigWithDependencies()
- {
- $result = (new AssetResolver([
- '\ResolverFixtures\Foo' => [
- 'construct' => [
- '@\ResolverFixtures\Bar'
- ]
- ]
- ]))->resolve('\ResolverFixtures\Foo');
-
- $this->assertInstanceOf('\ResolverFixtures\Foo', $result->fetch());
- }
-
- public function testResolvesInterfaceToObject()
- {
- $result = (new AssetResolver)->resolve('\ResolverFixtures\BarInterface');
- $this->assertInstanceOf('\ResolverFixtures\BarInterface', $result->fetch());
- $this->assertInstanceOf('\ResolverFixtures\Bar', $result->fetch());
- }
-
- public function testResolvesInterfaceConfigToObject()
- {
- $result = (new AssetResolver(['\ResolverFixtures\BarInterface' => ['construct' => ['some-data']]]))
- ->resolve('\ResolverFixtures\Bar');
-
- $this->assertInstanceOf('\ResolverFixtures\Bar', $result->fetch());
- $this->assertEquals('some-data', $result->fetch()->getData());
-
- $result = (new AssetResolver(['\ResolverFixtures\Bar' => ['construct' => ['some-data']]]))
- ->resolve('\ResolverFixtures\BarInterface');
-
- $this->assertInstanceOf('\ResolverFixtures\BarInterface', $result->fetch());
- $this->assertInstanceOf('\ResolverFixtures\Bar', $result->fetch());
- $this->assertEquals('some-data', $result->fetch()->getData());
- }
-
- public function testCanResolveComplexViaConfigWithOverloadedDependencies()
- {
- $result = (new AssetResolver([
- '\ResolverFixtures\BarInterface' => [
- 'class' => '\ResolverFixtures\SomeBar'
- ]
- ]))->resolve('\ResolverFixtures\BarInterface');
- $this->assertInstanceOf('\ResolverFixtures\BarInterface', $result->fetch());
- $this->assertInstanceOf('\ResolverFixtures\SomeBar', $result->fetch());
- }
-
- public function testResolvesViaAssetManager()
- {
- $result = (new AssetManager)->resolve('\ResolverFixtures\BarInterface');
- $this->assertInstanceOf('\ResolverFixtures\BarInterface', $result->fetch());
- $this->assertInstanceOf('\ResolverFixtures\Bar', $result->fetch());
- }
-}
View
21 lib/Proem/Service/Tests/AssetTest.php
@@ -42,7 +42,7 @@ public function testCanMakeAsset()
return new \stdClass;
});
- $this->assertInstanceOf('\stdClass', $asset->fetch());
+ $this->assertInstanceOf('\stdClass', $asset());
}
public function testCanMakeWithParamsParam()
@@ -51,17 +51,18 @@ public function testCanMakeWithParamsParam()
return new \stdClass;
});
- $this->assertInstanceOf('\stdClass', $asset->fetch());
+ $this->assertInstanceOf('\stdClass', $asset());
}
/**
* @expectedException DomainException
*/
public function testInvalidAsset()
{
- (new Asset('Foo', function() {
+ $asset = new Asset('Foo', function() {
return new \stdClass;
- }))->fetch();
+ });
+ $asset();
}
public function testAssetType()
@@ -82,7 +83,7 @@ public function testCanSetParams()
return $class;
});
- $this->assertEquals('bar', $asset->fetch()->foo);
+ $this->assertEquals('bar', $asset()->foo);
}
public function testReturnsDifferentInstance()
@@ -91,7 +92,7 @@ public function testReturnsDifferentInstance()
return new \StdClass;
});
- $this->assertNotSame($asset->fetch(), $asset->fetch());
+ $this->assertNotSame($asset(), $asset());
}
public function testReturnsSingleton()
@@ -100,7 +101,7 @@ public function testReturnsSingleton()
return new \StdClass;
});
- $this->assertSame($asset->fetch(), $asset->fetch());
+ $this->assertSame($asset(), $asset());
}
public function testReturnsSingletonWithParams()
@@ -111,8 +112,8 @@ public function testReturnsSingletonWithParams()
return $class;
});
- $this->assertSame($asset->fetch(), $asset->fetch());
- $this->assertEquals('bar', $asset->fetch()->foo);
+ $this->assertSame($asset(), $asset());
+ $this->assertEquals('bar', $asset()->foo);
}
public function testCanPassParamsAtFetch()
@@ -123,6 +124,6 @@ public function testCanPassParamsAtFetch()
return $class;
});
- $this->assertEquals('bar', $asset->fetch(['foo' => 'bar'])->foo);
+ $this->assertEquals('bar', $asset(['foo' => 'bar'])->foo);
}
}
View
25 tests/ProemTest.php
@@ -35,10 +35,12 @@ public function testCanInstantiateProem()
{
$assetManager = \Mockery::mock('\Proem\Service\AssetManagerInterface');
$assetManager
- ->shouldReceive('provides')
+ ->shouldReceive('alias')
->once()
- ->with('Proem\Signal\EventManagerInterface')
- ->andReturn(true);
+ ->with([
+ 'Proem\Signal\EventManagerInterface' => 'Proem\Signal\EventManager',
+ 'Proem\Signal\EventManager' => 'eventManager'
+ ]);
$this->assertInstanceOf('Proem\Proem', new Proem($assetManager));
}
@@ -51,20 +53,17 @@ public function testLoadsDefaultEventManager()
->once()
->with('\Proem\Signal\EventInterface');
- $assetManager = m::mock('\Proem\Service\AssetManagerInterface');
- $assetManager
- ->shouldReceive('provides')
- ->once()
- ->with('Proem\Signal\EventManagerInterface')
- ->andReturn(false);
-
+ $assetManager = \Mockery::mock('\Proem\Service\AssetManagerInterface');
$assetManager
- ->shouldReceive('set')
+ ->shouldReceive('alias')
->once()
- ->with('eventManager', 'Proem\Service\Asset');
+ ->with([
+ 'Proem\Signal\EventManagerInterface' => 'Proem\Signal\EventManager',
+ 'Proem\Signal\EventManager' => 'eventManager'
+ ]);
$assetManager
- ->shouldReceive('get')
+ ->shouldReceive('resolve')
->once()
->with('eventManager')
->andReturn($eventManager);
View
3 tests/phpunit.xml
@@ -4,8 +4,7 @@
<testsuites>
<testsuite name="Proem Framework Test Suite">
<directory>./</directory>
- <directory>../lib/Proem/*/Tests/</directory>