Skip to content

Commit 7238fdf

Browse files
author
thinkingmedia
committed
improves test coverage for components
1 parent 46deb66 commit 7238fdf

11 files changed

+210
-23
lines changed

src/Controller/Component.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public function initialize(array $config)
146146
* Magic method for lazy loading $components.
147147
*
148148
* @param string $name Name of component to get.
149-
* @return mixed A Component object or null.
149+
* @return Component|null A Component object or null.
150150
*/
151151
public function __get($name)
152152
{
@@ -157,6 +157,7 @@ public function __get($name)
157157
if (isset($this->{$name})) {
158158
return $this->{$name};
159159
}
160+
return null;
160161
}
161162

162163
/**

tests/TestCase/Controller/ComponentTest.php

Lines changed: 119 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,18 @@
1313
*/
1414
namespace Cake\Test\TestCase\Controller;
1515

16-
use Cake\Controller\Component;
16+
use Cake\Controller\Component\CookieComponent;
1717
use Cake\Controller\ComponentRegistry;
1818
use Cake\Controller\Controller;
19-
use Cake\Core\App;
2019
use Cake\Core\Configure;
20+
use Cake\Event\EventManager;
2121
use Cake\TestSuite\TestCase;
22-
use TestApp\Controller\ComponentTestController;
2322
use TestApp\Controller\Component\AppleComponent;
23+
use TestApp\Controller\Component\BananaComponent;
24+
use TestApp\Controller\Component\ConfiguredComponent;
25+
use TestApp\Controller\Component\OrangeComponent;
26+
use TestApp\Controller\Component\SomethingWithCookieComponent;
27+
use TestApp\Controller\ComponentTestController;
2428

2529
/**
2630
* ComponentTest class
@@ -37,8 +41,6 @@ public function setUp()
3741
{
3842
parent::setUp();
3943
Configure::write('App.namespace', 'TestApp');
40-
41-
$this->_pluginPaths = App::path('Plugin');
4244
}
4345

4446
/**
@@ -51,7 +53,7 @@ public function testInnerComponentConstruction()
5153
$Collection = new ComponentRegistry();
5254
$Component = new AppleComponent($Collection);
5355

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

5759
/**
@@ -64,8 +66,8 @@ public function testNestedComponentLoading()
6466
$Collection = new ComponentRegistry();
6567
$Apple = new AppleComponent($Collection);
6668

67-
$this->assertInstanceOf('TestApp\Controller\Component\OrangeComponent', $Apple->Orange, 'class is wrong');
68-
$this->assertInstanceOf('TestApp\Controller\Component\BananaComponent', $Apple->Orange->Banana, 'class is wrong');
69+
$this->assertInstanceOf(OrangeComponent::class, $Apple->Orange, 'class is wrong');
70+
$this->assertInstanceOf(BananaComponent::class, $Apple->Orange->Banana, 'class is wrong');
6971
$this->assertTrue(empty($Apple->Session));
7072
$this->assertTrue(empty($Apple->Orange->Session));
7173
}
@@ -77,18 +79,18 @@ public function testNestedComponentLoading()
7779
*/
7880
public function testInnerComponentsAreNotEnabled()
7981
{
80-
$mock = $this->getMockBuilder('Cake\Event\EventManager')->getMock();
82+
$mock = $this->getMockBuilder(EventManager::class)->getMock();
8183
$controller = new Controller();
8284
$controller->eventManager($mock);
8385

8486
$mock->expects($this->once())
8587
->method('on')
86-
->with($this->isInstanceOf('TestApp\Controller\Component\AppleComponent'));
88+
->with($this->isInstanceOf(AppleComponent::class));
8789

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

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

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

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

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

142-
$this->assertInstanceOf('TestApp\Controller\Component\SomethingWithCookieComponent', $Controller->SomethingWithCookie);
143-
$this->assertInstanceOf('Cake\Controller\Component\CookieComponent', $Controller->SomethingWithCookie->Cookie);
144+
$this->assertInstanceOf(SomethingWithCookieComponent::class, $Controller->SomethingWithCookie);
145+
$this->assertInstanceOf(CookieComponent::class, $Controller->SomethingWithCookie->Cookie);
144146
}
145147

146148
/**
@@ -165,4 +167,106 @@ public function testDebugInfo()
165167
$result = $Component->__debugInfo();
166168
$this->assertEquals($expected, $result);
167169
}
170+
171+
/**
172+
* Tests null return for unknown magic properties.
173+
*
174+
* @return void
175+
*/
176+
public function testMagicReturnsNull()
177+
{
178+
$Component = new AppleComponent(new ComponentRegistry());
179+
$this->assertNull($Component->ShouldBeNull);
180+
}
181+
182+
/**
183+
* Tests config via constructor
184+
*
185+
* @return void
186+
*/
187+
public function testConfigViaConstructor()
188+
{
189+
$Component = new ConfiguredComponent(new ComponentRegistry(), ['chicken' => 'soup']);
190+
$this->assertEquals(['chicken' => 'soup'], $Component->configCopy);
191+
$this->assertEquals(['chicken' => 'soup'], $Component->config());
192+
}
193+
194+
/**
195+
* Lazy load a component without events.
196+
*
197+
* @return void
198+
*/
199+
public function testLazyLoading()
200+
{
201+
$Component = new ConfiguredComponent(new ComponentRegistry(), [], ['Apple', 'Banana', 'Orange']);
202+
$this->assertInstanceOf(AppleComponent::class, $Component->Apple, 'class is wrong');
203+
$this->assertInstanceOf(OrangeComponent::class, $Component->Orange, 'class is wrong');
204+
$this->assertInstanceOf(BananaComponent::class, $Component->Banana, 'class is wrong');
205+
}
206+
207+
/**
208+
* Lazy load a component that does not exist.
209+
*
210+
* @expectedException \Cake\Controller\Exception\MissingComponentException
211+
* @expectedExceptionMessage Component class YouHaveNoBananasComponent could not be found.
212+
* @return void
213+
*/
214+
public function testLazyLoadingDoesNotExists()
215+
{
216+
$Component = new ConfiguredComponent(new ComponentRegistry(), [], ['YouHaveNoBananas']);
217+
$bananas = $Component->YouHaveNoBananas;
218+
}
219+
220+
/**
221+
* Lazy loaded components can have config options
222+
*
223+
* @return void
224+
*/
225+
public function testConfiguringInnerComponent()
226+
{
227+
$Component = new ConfiguredComponent(new ComponentRegistry(), [], ['Configured' => ['foo' => 'bar']]);
228+
$this->assertInstanceOf(ConfiguredComponent::class, $Component->Configured, 'class is wrong');
229+
$this->assertNotSame($Component, $Component->Configured, 'Component instance was reused');
230+
$this->assertEquals(['foo' => 'bar', 'enabled' => false], $Component->Configured->config());
231+
}
232+
233+
/**
234+
* Test enabling events for lazy loaded components
235+
*
236+
* @return void
237+
*/
238+
public function testEventsInnerComponent()
239+
{
240+
$eventManager = $this->getMockBuilder(EventManager::class)->getMock();
241+
$eventManager->expects($this->once())
242+
->method('on')
243+
->with($this->isInstanceOf(AppleComponent::class));
244+
245+
$controller = new Controller();
246+
$controller->eventManager($eventManager);
247+
248+
$Collection = new ComponentRegistry($controller);
249+
250+
$Component = new ConfiguredComponent($Collection, [], ['Apple' => ['enabled' => true]]);
251+
$this->assertInstanceOf(AppleComponent::class, $Component->Apple, 'class is wrong');
252+
}
253+
254+
/**
255+
* Disabled events do not register for event listeners.
256+
*
257+
* @return void
258+
*/
259+
public function testNoEventsInnerComponent()
260+
{
261+
$eventManager = $this->getMockBuilder(EventManager::class)->getMock();
262+
$eventManager->expects($this->never())->method('on');
263+
264+
$controller = new Controller();
265+
$controller->eventManager($eventManager);
266+
267+
$Collection = new ComponentRegistry($controller);
268+
269+
$Component = new ConfiguredComponent($Collection, [], ['Apple' => ['enabled' => false]]);
270+
$this->assertInstanceOf(AppleComponent::class, $Component->Apple, 'class is wrong');
271+
}
168272
}

tests/test_app/TestApp/Controller/Component/AppleComponent.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
namespace TestApp\Controller\Component;
1515

1616
use Cake\Controller\Component;
17-
use Cake\Controller\Controller;
1817
use Cake\Event\Event;
1918

2019
/**
2120
* AppleComponent class
21+
*
22+
* @property OrangeComponent $Orange
2223
*/
2324
class AppleComponent extends Component
2425
{
@@ -34,7 +35,6 @@ class AppleComponent extends Component
3435
* startup method
3536
*
3637
* @param Event $event
37-
* @param mixed $controller
3838
* @return void
3939
*/
4040
public function startup(Event $event)

tests/test_app/TestApp/Controller/Component/BananaComponent.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
namespace TestApp\Controller\Component;
1515

1616
use Cake\Controller\Component;
17-
use Cake\Controller\Controller;
18-
use Cake\Event\Event;
1917

2018
/**
2119
* BananaComponent class
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
/**
3+
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4+
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5+
*
6+
* Licensed under The MIT License
7+
* Redistributions of files must retain the above copyright notice.
8+
*
9+
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10+
* @link http://cakephp.org CakePHP(tm) Project
11+
* @since 3.3.6
12+
* @license http://www.opensource.org/licenses/mit-license.php MIT License
13+
*/
14+
namespace TestApp\Controller\Component;
15+
16+
use Cake\Controller\Component;
17+
use Cake\Controller\ComponentRegistry;
18+
19+
/**
20+
* A test component that makes a copy of the configuration.
21+
*/
22+
class ConfiguredComponent extends Component
23+
{
24+
/**
25+
* @var array
26+
*/
27+
public $configCopy;
28+
29+
/**
30+
* components property
31+
*
32+
* @var array
33+
*/
34+
public $components = [];
35+
36+
/**
37+
* Constructor
38+
*
39+
* @param ComponentRegistry $registry A ComponentRegistry this component can use to lazy load its components
40+
* @param array $config Array of configuration settings.
41+
* @param array $components Array of child components.
42+
*/
43+
public function __construct(ComponentRegistry $registry, array $config, array $components = [])
44+
{
45+
$this->components = $components;
46+
47+
parent::__construct($registry, $config);
48+
}
49+
50+
/**
51+
* @param array $config
52+
*/
53+
public function initialize(array $config)
54+
{
55+
$this->configCopy = $config;
56+
57+
parent::initialize($config);
58+
}
59+
}

tests/test_app/TestApp/Controller/Component/MutuallyReferencingOneComponent.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
/**
1919
* MutuallyReferencingOneComponent class
20+
*
21+
* @property MutuallyReferencingTwoComponent $MutuallyReferencingTwo
2022
*/
2123
class MutuallyReferencingOneComponent extends Component
2224
{

tests/test_app/TestApp/Controller/Component/MutuallyReferencingTwoComponent.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
/**
1919
* MutuallyReferencingTwoComponent class
20+
*
21+
* @property MutuallyReferencingOneComponent $MutuallyReferencingOne
2022
*/
2123
class MutuallyReferencingTwoComponent extends Component
2224
{

tests/test_app/TestApp/Controller/Component/OrangeComponent.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
/**
2121
* OrangeComponent class
22+
*
23+
* @property BananaComponent $Banana
2224
*/
2325
class OrangeComponent extends Component
2426
{
@@ -30,6 +32,13 @@ class OrangeComponent extends Component
3032
*/
3133
public $components = ['Banana'];
3234

35+
/**
36+
* controller property
37+
*
38+
* @var Controller
39+
*/
40+
public $Controller;
41+
3342
/**
3443
* initialize method
3544
*
@@ -46,7 +55,7 @@ public function initialize(array $config)
4655
* startup method
4756
*
4857
* @param Event $event
49-
* @return string
58+
* @return void
5059
*/
5160
public function startup(Event $event)
5261
{

tests/test_app/TestApp/Controller/Component/ParamTestComponent.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
/**
1919
* ParamTestComponent
20+
*
21+
* @property BananaComponent $Banana
2022
*/
2123
class ParamTestComponent extends Component
2224
{

tests/test_app/TestApp/Controller/Component/SomethingWithCookieComponent.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
/**
1919
* SomethingWithCookieComponent class
20+
*
21+
* @property Component\CookieComponent $Cookie
2022
*/
2123
class SomethingWithCookieComponent extends Component
2224
{

0 commit comments

Comments
 (0)