Skip to content

Commit

Permalink
Merge branch 'release-0.0.5'
Browse files Browse the repository at this point in the history
  • Loading branch information
trq committed Jan 14, 2012
2 parents 5cc9337 + 0d1839c commit b12b374
Show file tree
Hide file tree
Showing 6 changed files with 463 additions and 1 deletion.
141 changes: 141 additions & 0 deletions lib/Proem/Api/Asset.php
@@ -0,0 +1,141 @@
<?php

/**
* The MIT License
*
* Copyright (c) 2010 - 2012 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
*/
namespace Proem\Api;

use Proem\Asset\Manager;

/**
* Proem\Asset
*
* An Asset container.
*
* Asset containers are reponsible for instantiating Assets. The containers themselves
* are capable of holding all the parameters that might be required to configure an object
* as well as having the ability to ijnstantiate an object using these parameters via a
* Closure.
*/
class Asset
{
/**
* Store any required parameters
*
* @var array @params
*/
private $params = [];

/**
* The Closure responsible for instantiating the payload.
*
* @var closure $asset
*/
private $asset;

/**
* Set a parameters by named index
*
* @param string $index
* @param mixed $value
*/
public function setParam($index, $value)
{
$this->params[$index] = $value;
return $this;
}

/**
* Retrieve a parameter by named index
*
* @param string $index
*/
public function getParam($index)
{
return isset($this->params[$index]) ? $this->params[$index] : null;
}

/**
* Store the Closure reponsible for instantiating an Asset
*
* @param Closure $closure
*/
public function setAsset(\Closure $closure)
{
$this->asset = $closure;
return $this;
}

/**
* Retrieve an instantiated Asset.
*
* Here the closure is passed this asset container and optionally the
* Proem\Api\Asset\Manager.
*
* This provides the closure with the ability to use any required parameters
* and also be able to call upon any other assets stored in the asset manager.
*
* @param Proem\Api\Asset\Manager $assetManager
*/
public function getAsset(Manager $assetManager = null)
{
$asset = $this->asset;
return $asset($this, $assetManager);
}

/**
* Store an asset in such a way that when it is retrieved it will always return
* the same instance.
*
* Here we wrap a Closure within a Closure and store the returned value (an Asset)
* of the inner Closure within a static variable in the outer Closure. Thus ensuring
* that whenever this Asset is retrieved it will always return the same instance.
*
* Example:
*
* <code>
* $foo = new Asset;
* $foo->setAsset($foo->single(function() {
* return new Foo;
* }));
* </code>
*
* @param Closure $closure
*/
public function single(\Closure $closure)
{
return function ($assetContainer = null, $assetManager = null) use ($closure) {
static $obj;
if (is_null($obj)) {
$obj = $closure($assetContainer, $assetManager);
}
return $obj;
};
}

}
89 changes: 89 additions & 0 deletions lib/Proem/Api/Asset/Manager.php
@@ -0,0 +1,89 @@
<?php

/**
* The MIT License
*
* Copyright (c) 2010 - 2012 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\Api\Asset
*/
namespace Proem\Api\Asset;

use Proem\Asset;

/**
* Proem\Api\Asset\Manager
*
* A Registry of Assets.
*
* Within the manager itself Assets are stored in a hash of key values where each
* value is an Asset container.
*
* These containers contain the parameters required to instantiate an Asset as
* well as a Closure capable of returning a configured and instantiated Asset.
*
* @see Proem\Api\Asset
*/
class Manager
{
/**
* Store assets
*
* @var $assets array
*/
private $assets = [];

/**
* Store an Asset container by named index.
*
* @param string $index The index the asset will be referenced by.
* @param Proem\Api\Asset $asset
*/
public function setAsset($index, Asset $asset)
{
$this->assets[$index] = $asset;
return $this;
}

/**
* Retrieve an Asset container by named index.
*
* @param string $index The index the asset is referenced by.
*/
public function getContainer($index)
{
return isset($this->assets[$index]) ? $this->assets[$index] : null;
}

/**
* Retrieve an actual instantiated Asset object from within it's container.
*
* @param string $index The index the asset is referenced by.
*/
public function getAsset($index)
{
return isset($this->assets[$index]) ? $this->assets[$index]->getAsset($this) : null;
}

}
2 changes: 1 addition & 1 deletion lib/Proem/Api/Proem.php
Expand Up @@ -36,5 +36,5 @@
*/
class Proem
{
const VERSION = '0.0.4';
const VERSION = '0.0.5';
}
139 changes: 139 additions & 0 deletions tests/lib/Proem/Tests/AssetTest.php
@@ -0,0 +1,139 @@
<?php

/**
* The MIT License
*
* Copyright (c) 2010 - 2012 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\Tests;

use Proem\Asset,
Proem\Asset\Manager,
Proem\Asset\Foo,
Proem\Asset\Bar;

class AssetTest extends \PHPUnit_Framework_TestCase
{
public function testCanInstantiateAsset()
{
$a = new Asset;
$this->assertInstanceOf('Proem\Asset', $a);
}

public function testCanInstantiateAssetManager()
{
$am = new Manager;
$this->assertInstanceOf('Proem\Asset\Manager', $am);
}

public function testAssetCanInstantiate()
{
$bar = new Asset;
$bar->setAsset(function() {
return new Bar;
});

$this->assertInstanceOf('Proem\Asset\Bar', $bar->getAsset());
}

public function testAssetCanSetParams()
{
$foo = new Asset;
$foo->setParam('name', 'trq')
->setAsset(function($a) {
return new Foo($a->getParam('name'));
});

$asset = $foo->getAsset();

$this->assertEquals('Hello trq', $asset->say());
}

public function testSingleReturnsDifferentInstance()
{
$bar = new Asset;
$bar->setAsset(function() {
return new Bar;
});

$one = $bar->getAsset();
$this->assertInstanceOf('Proem\Asset\Bar', $one);

$two = $bar->getAsset();
$this->assertInstanceOf('Proem\Asset\Bar', $two);

$this->assertNotSame($one, $two);

}

public function testSingleReturnsSameInstance()
{
$bar = new Asset;
$bar->setAsset($bar->single(function() {
return new Bar;
}));

$one = $bar->getAsset();
$this->assertInstanceOf('Proem\Asset\Bar', $one);

$two = $bar->getAsset();
$this->assertInstanceOf('Proem\Asset\Bar', $two);

$this->assertSame($one, $two);

}

public function testAssetManagerCanStoreAndRetrieve()
{
$bar = new Asset;
$bar->setAsset(function() {
return new Bar;
});

$am = new Manager;
$am->setAsset('bar', $bar);

$this->assertInstanceOf('Proem\Asset\Bar', $am->getAsset('bar'));
}

public function testCanGetDepsThroughManager()
{
$bar = new Asset;
$bar->setAsset(function() {
return new Bar;
});

$foo = new Asset;
$foo->setAsset(function($a, $am) {
$f = new Foo('something');
$f->setBar($am->getAsset('bar'));
return $f;
});

$am = new Manager;
$am->setAsset('foo', $foo)->setAsset('bar', $bar);

$this->assertInstanceOf('Proem\Asset\Bar', $am->getAsset('bar'));
$this->assertInstanceOf('Proem\Asset\Foo', $am->getAsset('foo'));
$this->assertInstanceOf('Proem\Asset\Bar', $am->getAsset('foo')->getBar());
}
}

0 comments on commit b12b374

Please sign in to comment.