Skip to content

Commit

Permalink
improves test coverage for components
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkingmedia committed Oct 28, 2016
1 parent 46deb66 commit 7238fdf
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 23 deletions.
3 changes: 2 additions & 1 deletion src/Controller/Component.php
Expand Up @@ -146,7 +146,7 @@ public function initialize(array $config)
* Magic method for lazy loading $components.
*
* @param string $name Name of component to get.
* @return mixed A Component object or null.
* @return Component|null A Component object or null.
*/
public function __get($name)
{
Expand All @@ -157,6 +157,7 @@ public function __get($name)
if (isset($this->{$name})) {
return $this->{$name};
}
return null;
}

/**
Expand Down
134 changes: 119 additions & 15 deletions tests/TestCase/Controller/ComponentTest.php
Expand Up @@ -13,14 +13,18 @@
*/
namespace Cake\Test\TestCase\Controller;

use Cake\Controller\Component;
use Cake\Controller\Component\CookieComponent;
use Cake\Controller\ComponentRegistry;
use Cake\Controller\Controller;
use Cake\Core\App;
use Cake\Core\Configure;
use Cake\Event\EventManager;
use Cake\TestSuite\TestCase;
use TestApp\Controller\ComponentTestController;
use TestApp\Controller\Component\AppleComponent;
use TestApp\Controller\Component\BananaComponent;
use TestApp\Controller\Component\ConfiguredComponent;
use TestApp\Controller\Component\OrangeComponent;
use TestApp\Controller\Component\SomethingWithCookieComponent;
use TestApp\Controller\ComponentTestController;

/**
* ComponentTest class
Expand All @@ -37,8 +41,6 @@ public function setUp()
{
parent::setUp();
Configure::write('App.namespace', 'TestApp');

$this->_pluginPaths = App::path('Plugin');
}

/**
Expand All @@ -51,7 +53,7 @@ public function testInnerComponentConstruction()
$Collection = new ComponentRegistry();
$Component = new AppleComponent($Collection);

$this->assertInstanceOf('TestApp\Controller\Component\OrangeComponent', $Component->Orange, 'class is wrong');
$this->assertInstanceOf(OrangeComponent::class, $Component->Orange, 'class is wrong');
}

/**
Expand All @@ -64,8 +66,8 @@ public function testNestedComponentLoading()
$Collection = new ComponentRegistry();
$Apple = new AppleComponent($Collection);

$this->assertInstanceOf('TestApp\Controller\Component\OrangeComponent', $Apple->Orange, 'class is wrong');
$this->assertInstanceOf('TestApp\Controller\Component\BananaComponent', $Apple->Orange->Banana, 'class is wrong');
$this->assertInstanceOf(OrangeComponent::class, $Apple->Orange, 'class is wrong');
$this->assertInstanceOf(BananaComponent::class, $Apple->Orange->Banana, 'class is wrong');
$this->assertTrue(empty($Apple->Session));
$this->assertTrue(empty($Apple->Orange->Session));
}
Expand All @@ -77,18 +79,18 @@ public function testNestedComponentLoading()
*/
public function testInnerComponentsAreNotEnabled()
{
$mock = $this->getMockBuilder('Cake\Event\EventManager')->getMock();
$mock = $this->getMockBuilder(EventManager::class)->getMock();
$controller = new Controller();
$controller->eventManager($mock);

$mock->expects($this->once())
->method('on')
->with($this->isInstanceOf('TestApp\Controller\Component\AppleComponent'));
->with($this->isInstanceOf(AppleComponent::class));

$Collection = new ComponentRegistry($controller);
$Apple = $Collection->load('Apple');

$this->assertInstanceOf('TestApp\Controller\Component\OrangeComponent', $Apple->Orange, 'class is wrong');
$this->assertInstanceOf(OrangeComponent::class, $Apple->Orange, 'class is wrong');
}

/**
Expand All @@ -111,7 +113,7 @@ public function testMultipleComponentInitialize()
/**
* Test a duplicate component being loaded more than once with same and differing configurations.
*
* @expectedException RuntimeException
* @expectedException \RuntimeException
* @expectedExceptionMessage The "Banana" alias has already been loaded with the following config:
* @return void
*/
Expand All @@ -123,7 +125,7 @@ public function testDuplicateComponentInitialize()
$Collection->load('Banana', ['property' => ['closure' => function () {
}]]);

$this->assertInstanceOf('TestApp\Controller\Component\BananaComponent', $Collection->Banana, 'class is wrong');
$this->assertInstanceOf(BananaComponent::class, $Collection->Banana, 'class is wrong');

$Collection->load('Banana', ['property' => ['differs']]);
}
Expand All @@ -139,8 +141,8 @@ public function testSomethingReferencingCookieComponent()
$Controller->loadComponent('SomethingWithCookie');
$Controller->startupProcess();

$this->assertInstanceOf('TestApp\Controller\Component\SomethingWithCookieComponent', $Controller->SomethingWithCookie);
$this->assertInstanceOf('Cake\Controller\Component\CookieComponent', $Controller->SomethingWithCookie->Cookie);
$this->assertInstanceOf(SomethingWithCookieComponent::class, $Controller->SomethingWithCookie);
$this->assertInstanceOf(CookieComponent::class, $Controller->SomethingWithCookie->Cookie);
}

/**
Expand All @@ -165,4 +167,106 @@ public function testDebugInfo()
$result = $Component->__debugInfo();
$this->assertEquals($expected, $result);
}

/**
* Tests null return for unknown magic properties.
*
* @return void
*/
public function testMagicReturnsNull()
{
$Component = new AppleComponent(new ComponentRegistry());
$this->assertNull($Component->ShouldBeNull);
}

/**
* Tests config via constructor
*
* @return void
*/
public function testConfigViaConstructor()
{
$Component = new ConfiguredComponent(new ComponentRegistry(), ['chicken' => 'soup']);
$this->assertEquals(['chicken' => 'soup'], $Component->configCopy);
$this->assertEquals(['chicken' => 'soup'], $Component->config());
}

/**
* Lazy load a component without events.
*
* @return void
*/
public function testLazyLoading()
{
$Component = new ConfiguredComponent(new ComponentRegistry(), [], ['Apple', 'Banana', 'Orange']);
$this->assertInstanceOf(AppleComponent::class, $Component->Apple, 'class is wrong');
$this->assertInstanceOf(OrangeComponent::class, $Component->Orange, 'class is wrong');
$this->assertInstanceOf(BananaComponent::class, $Component->Banana, 'class is wrong');
}

/**
* Lazy load a component that does not exist.
*
* @expectedException \Cake\Controller\Exception\MissingComponentException
* @expectedExceptionMessage Component class YouHaveNoBananasComponent could not be found.
* @return void
*/
public function testLazyLoadingDoesNotExists()
{
$Component = new ConfiguredComponent(new ComponentRegistry(), [], ['YouHaveNoBananas']);
$bananas = $Component->YouHaveNoBananas;
}

/**
* Lazy loaded components can have config options
*
* @return void
*/
public function testConfiguringInnerComponent()
{
$Component = new ConfiguredComponent(new ComponentRegistry(), [], ['Configured' => ['foo' => 'bar']]);
$this->assertInstanceOf(ConfiguredComponent::class, $Component->Configured, 'class is wrong');
$this->assertNotSame($Component, $Component->Configured, 'Component instance was reused');
$this->assertEquals(['foo' => 'bar', 'enabled' => false], $Component->Configured->config());
}

/**
* Test enabling events for lazy loaded components
*
* @return void
*/
public function testEventsInnerComponent()
{
$eventManager = $this->getMockBuilder(EventManager::class)->getMock();
$eventManager->expects($this->once())
->method('on')
->with($this->isInstanceOf(AppleComponent::class));

$controller = new Controller();
$controller->eventManager($eventManager);

$Collection = new ComponentRegistry($controller);

$Component = new ConfiguredComponent($Collection, [], ['Apple' => ['enabled' => true]]);
$this->assertInstanceOf(AppleComponent::class, $Component->Apple, 'class is wrong');
}

/**
* Disabled events do not register for event listeners.
*
* @return void
*/
public function testNoEventsInnerComponent()
{
$eventManager = $this->getMockBuilder(EventManager::class)->getMock();
$eventManager->expects($this->never())->method('on');

$controller = new Controller();
$controller->eventManager($eventManager);

$Collection = new ComponentRegistry($controller);

$Component = new ConfiguredComponent($Collection, [], ['Apple' => ['enabled' => false]]);
$this->assertInstanceOf(AppleComponent::class, $Component->Apple, 'class is wrong');
}
}
Expand Up @@ -14,11 +14,12 @@
namespace TestApp\Controller\Component;

use Cake\Controller\Component;
use Cake\Controller\Controller;
use Cake\Event\Event;

/**
* AppleComponent class
*
* @property OrangeComponent $Orange
*/
class AppleComponent extends Component
{
Expand All @@ -34,7 +35,6 @@ class AppleComponent extends Component
* startup method
*
* @param Event $event
* @param mixed $controller
* @return void
*/
public function startup(Event $event)
Expand Down
Expand Up @@ -14,8 +14,6 @@
namespace TestApp\Controller\Component;

use Cake\Controller\Component;
use Cake\Controller\Controller;
use Cake\Event\Event;

/**
* BananaComponent class
Expand Down
@@ -0,0 +1,59 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.3.6
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace TestApp\Controller\Component;

use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;

/**
* A test component that makes a copy of the configuration.
*/
class ConfiguredComponent extends Component
{
/**
* @var array
*/
public $configCopy;

/**
* components property
*
* @var array
*/
public $components = [];

/**
* Constructor
*
* @param ComponentRegistry $registry A ComponentRegistry this component can use to lazy load its components
* @param array $config Array of configuration settings.
* @param array $components Array of child components.
*/
public function __construct(ComponentRegistry $registry, array $config, array $components = [])
{
$this->components = $components;

parent::__construct($registry, $config);
}

/**
* @param array $config
*/
public function initialize(array $config)
{
$this->configCopy = $config;

parent::initialize($config);
}
}
Expand Up @@ -17,6 +17,8 @@

/**
* MutuallyReferencingOneComponent class
*
* @property MutuallyReferencingTwoComponent $MutuallyReferencingTwo
*/
class MutuallyReferencingOneComponent extends Component
{
Expand Down
Expand Up @@ -17,6 +17,8 @@

/**
* MutuallyReferencingTwoComponent class
*
* @property MutuallyReferencingOneComponent $MutuallyReferencingOne
*/
class MutuallyReferencingTwoComponent extends Component
{
Expand Down
11 changes: 10 additions & 1 deletion tests/test_app/TestApp/Controller/Component/OrangeComponent.php
Expand Up @@ -19,6 +19,8 @@

/**
* OrangeComponent class
*
* @property BananaComponent $Banana
*/
class OrangeComponent extends Component
{
Expand All @@ -30,6 +32,13 @@ class OrangeComponent extends Component
*/
public $components = ['Banana'];

/**
* controller property
*
* @var Controller
*/
public $Controller;

/**
* initialize method
*
Expand All @@ -46,7 +55,7 @@ public function initialize(array $config)
* startup method
*
* @param Event $event
* @return string
* @return void
*/
public function startup(Event $event)
{
Expand Down
Expand Up @@ -17,6 +17,8 @@

/**
* ParamTestComponent
*
* @property BananaComponent $Banana
*/
class ParamTestComponent extends Component
{
Expand Down
Expand Up @@ -17,6 +17,8 @@

/**
* SomethingWithCookieComponent class
*
* @property Component\CookieComponent $Cookie
*/
class SomethingWithCookieComponent extends Component
{
Expand Down

0 comments on commit 7238fdf

Please sign in to comment.