[BUGFIX] ObjectContainer does not support namespaces
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Object / Container / ContainerTest.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 * (c) 2010 Daniel Pötzinger
5 * (c) 2010 Bastian Waidelich <bastian@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 require_once(t3lib_extMgm::extPath('extbase') . 'Tests/Unit/Object/Container/Fixtures/Testclasses.php');
26 require_once(t3lib_extMgm::extPath('extbase') . 'Tests/Unit/Object/Container/Fixtures/NamespaceTestclasses.php');
27
28 /**
29 * Testcase for class t3lib_object_Container.
30 *
31 * @author Daniel Pötzinger
32 * @author Bastian Waidelich <bastian@typo3.org>
33 * @package TYPO3
34 * @subpackage t3lib
35 */
36 class Tx_Extbase_Tests_Unit_Object_Container_ContainerTest extends Tx_Extbase_Tests_Unit_BaseTestCase {
37
38 /**
39 * @var Tx_Extbase_Object_Container_Container
40 */
41 private $container;
42
43 public function setUp() {
44 //our mocked cache will allways indicate that he has nothing in the cache to force that we get the real classinfo
45 $mockedCache = $this->getMock('Tx_Extbase_Object_Container_ClassInfoCache',array('has'));
46 $mockedCache->expects($this->any())->method('has')->will($this->returnValue(false));
47
48 $this->container = $this->getMock('Tx_Extbase_Object_Container_Container', array('log','getClassInfoCache'));
49 $this->container->expects($this->any())->method('getClassInfoCache')->will($this->returnValue($mockedCache));
50 }
51
52 /**
53 * @test
54 */
55 public function getInstanceReturnsInstanceOfSimpleClass() {
56 $object = $this->container->getInstance('t3lib_object_tests_c');
57 $this->assertInstanceOf('t3lib_object_tests_c', $object);
58 }
59
60 /**
61 * @test
62 */
63 public function getInstanceReturnsInstanceOfSimpleNamespacedClass() {
64 $object = $this->container->getInstance('Tx\Extbase\Object\Container\Fixtures\NamespacedClass');
65 $this->assertInstanceOf('Tx\Extbase\Object\Container\Fixtures\NamespacedClass', $object);
66 }
67
68 /**
69 * @test
70 */
71 public function getInstanceReturnsInstanceOfAClassWithConstructorInjection() {
72 $object = $this->container->getInstance('t3lib_object_tests_b');
73 $this->assertInstanceOf('t3lib_object_tests_b', $object);
74 $this->assertInstanceOf('t3lib_object_tests_c', $object->c);
75 }
76
77 /**
78 * @test
79 */
80 public function getInstanceReturnsInstanceOfAClassWithTwoLevelDependency() {
81 $object = $this->container->getInstance('t3lib_object_tests_a');
82 $this->assertInstanceOf('t3lib_object_tests_a', $object);
83 $this->assertInstanceOf('t3lib_object_tests_c', $object->b->c);
84 }
85
86 /**
87 * @test
88 */
89 public function getInstanceReturnsInstanceOfAClassWithMixedSimpleTypeAndConstructorInjection() {
90 $object = $this->container->getInstance('t3lib_object_tests_amixed_array');
91 $this->assertInstanceOf('t3lib_object_tests_amixed_array', $object);
92 $this->assertEquals(array('some' => 'default'), $object->myvalue);
93 }
94
95 /**
96 * @test
97 */
98 public function getInstanceReturnsInstanceOfAClassWithMixedSimpleTypeAndConstructorInjectionWithNullDefaultValue() {
99 $object = $this->container->getInstance('t3lib_object_tests_amixed_null');
100 $this->assertInstanceOf('t3lib_object_tests_amixed_null', $object);
101 $this->assertNull($object->myvalue);
102 }
103
104 /**
105 * @test
106 * @expectedException Tx_Extbase_Object_Exception
107 */
108 public function getInstanceThrowsExceptionWhenTryingToInstanciateASingletonWithConstructorParameters() {
109 $this->container->getInstance('t3lib_object_tests_amixed_array_singleton', array('somevalue'));
110 }
111
112 /**
113 * @test
114 */
115 public function getInstanceReturnsInstanceOfAClassWithConstructorInjectionAndDefaultConstructorParameters() {
116 $object = $this->container->getInstance('t3lib_object_tests_amixed_array');
117 $this->assertInstanceOf('t3lib_object_tests_b', $object->b);
118 $this->assertInstanceOf('t3lib_object_tests_c', $object->c);
119 $this->assertEquals(array('some' => 'default'), $object->myvalue);
120 }
121
122 /**
123 * @test
124 */
125 public function getInstancePassesGivenParameterToTheNewObject() {
126 $mockObject = $this->getMock('t3lib_object_tests_c');
127
128 $object = $this->container->getInstance('t3lib_object_tests_a', array($mockObject));
129 $this->assertInstanceOf('t3lib_object_tests_a', $object);
130 $this->assertSame($mockObject, $object->c);
131 }
132
133 /**
134 * @test
135 */
136 public function getInstanceReturnsAFreshInstanceIfObjectIsNoSingleton() {
137 $object1 = $this->container->getInstance('t3lib_object_tests_a');
138 $object2 = $this->container->getInstance('t3lib_object_tests_a');
139
140 $this->assertNotSame($object1, $object2);
141 }
142
143 /**
144 * @test
145 */
146 public function getInstanceReturnsSameInstanceInstanceIfObjectIsSingleton() {
147 $object1 = $this->container->getInstance('t3lib_object_tests_singleton');
148 $object2 = $this->container->getInstance('t3lib_object_tests_singleton');
149
150 $this->assertSame($object1, $object2);
151 }
152
153 /**
154 * @test
155 * @expectedException Tx_Extbase_Object_Exception_CannotBuildObject
156 */
157 public function getInstanceThrowsExceptionIfPrototypeObjectsWiredViaConstructorInjectionContainCyclicDependencies() {
158 $this->container->getInstance('t3lib_object_tests_cyclic1WithSetterDependency');
159 }
160
161 /**
162 * @test
163 * @expectedException Tx_Extbase_Object_Exception_CannotBuildObject
164 */
165 public function getInstanceThrowsExceptionIfPrototypeObjectsWiredViaSetterInjectionContainCyclicDependencies() {
166 $this->container->getInstance('t3lib_object_tests_cyclic1');
167 }
168
169 /**
170 * @test
171 * @expectedException Tx_Extbase_Object_Exception
172 */
173 public function getInstanceThrowsExceptionIfClassWasNotFound() {
174 $this->container->getInstance('nonextistingclass_bla');
175 }
176
177 /**
178 * @test
179 */
180 public function getInstanceUsesClassNameSha1AsCacheKey() {
181 $className = 'Tx\Extbase\Object\Container\Fixtures\NamespacedClass';
182 $classNameHash = sha1($className);
183
184 $mockedCache = $this->getMock('Tx_Extbase_Object_Container_ClassInfoCache',array('has', 'set'));
185 $this->container = $this->getMock('Tx_Extbase_Object_Container_Container', array('log','getClassInfoCache'));
186 $this->container->expects($this->any())->method('getClassInfoCache')->will($this->returnValue($mockedCache));
187
188 $mockedCache->expects($this->any())->method('has')->will($this->returnValue(FALSE));
189 $mockedCache->expects($this->once())->method('set')->with($classNameHash, $this->anything());
190
191 $this->container->getInstance($className);
192 }
193
194 /**
195 * @test
196 */
197 public function getEmptyObjectReturnsInstanceOfSimpleClass() {
198 $object = $this->container->getEmptyObject('t3lib_object_tests_c');
199 $this->assertInstanceOf('t3lib_object_tests_c', $object);
200 }
201
202 /**
203 * @test
204 */
205 public function test_canGetChildClass() {
206 $object = $this->container->getInstance('t3lib_object_tests_b_child');
207 $this->assertInstanceOf('t3lib_object_tests_b_child', $object);
208 }
209
210 /**
211 * @test
212 */
213 public function test_canInjectInterfaceInClass() {
214 $this->container->registerImplementation('t3lib_object_tests_someinterface', 't3lib_object_tests_someimplementation');
215 $object = $this->container->getInstance('t3lib_object_tests_needsinterface');
216 $this->assertInstanceOf('t3lib_object_tests_needsinterface', $object);
217
218 $this->assertInstanceOf('t3lib_object_tests_someinterface', $object->dependency);
219 $this->assertInstanceOf('t3lib_object_tests_someimplementation', $object->dependency);
220 }
221
222 /**
223 * @test
224 */
225 public function test_canBuildCyclicDependenciesOfSingletonsWithSetter() {
226 $object = $this->container->getInstance('t3lib_object_tests_resolveablecyclic1');
227 $this->assertInstanceOf('t3lib_object_tests_resolveablecyclic1', $object);
228 $this->assertInstanceOf('t3lib_object_tests_resolveablecyclic1', $object->o2->o3->o1);
229 }
230
231 /**
232 * @test
233 */
234 public function singletonWhichRequiresPrototypeViaSetterInjectionWorksAndAddsDebugMessage() {
235 $this->container->expects($this->once())->method('log')->with('The singleton "t3lib_object_singletonNeedsPrototype" needs a prototype in "injectDependency". This is often a bad code smell; often you rather want to inject a singleton.', 1);
236
237 $object = $this->container->getInstance('t3lib_object_singletonNeedsPrototype');
238 $this->assertInstanceOf('t3lib_object_prototype', $object->dependency);
239 }
240
241 /**
242 * @test
243 */
244 public function singletonWhichRequiresSingletonViaSetterInjectionWorks() {
245 $this->container->expects($this->never())->method('log');
246
247 $object = $this->container->getInstance('t3lib_object_singletonNeedsSingleton');
248 $this->assertInstanceOf('t3lib_object_singleton', $object->dependency);
249 }
250
251 /**
252 * @test
253 */
254 public function prototypeWhichRequiresPrototypeViaSetterInjectionWorks() {
255 $this->container->expects($this->never())->method('log');
256
257 $object = $this->container->getInstance('t3lib_object_prototypeNeedsPrototype');
258 $this->assertInstanceOf('t3lib_object_prototype', $object->dependency);
259 }
260
261 /**
262 * @test
263 */
264 public function prototypeWhichRequiresSingletonViaSetterInjectionWorks() {
265 $this->container->expects($this->never())->method('log');
266
267 $object = $this->container->getInstance('t3lib_object_prototypeNeedsSingleton');
268 $this->assertInstanceOf('t3lib_object_singleton', $object->dependency);
269 }
270
271 /**
272 * @test
273 */
274 public function singletonWhichRequiresPrototypeViaConstructorInjectionWorksAndAddsDebugMessage() {
275 $this->container->expects($this->once())->method('log')->with('The singleton "t3lib_object_singletonNeedsPrototypeInConstructor" needs a prototype in the constructor. This is often a bad code smell; often you rather want to inject a singleton.', 1);
276
277 $object = $this->container->getInstance('t3lib_object_singletonNeedsPrototypeInConstructor');
278 $this->assertInstanceOf('t3lib_object_prototype', $object->dependency);
279 }
280
281 /**
282 * @test
283 */
284 public function singletonWhichRequiresSingletonViaConstructorInjectionWorks() {
285 $this->container->expects($this->never())->method('log');
286
287 $object = $this->container->getInstance('t3lib_object_singletonNeedsSingletonInConstructor');
288 $this->assertInstanceOf('t3lib_object_singleton', $object->dependency);
289 }
290
291 /**
292 * @test
293 */
294 public function prototypeWhichRequiresPrototypeViaConstructorInjectionWorks() {
295 $this->container->expects($this->never())->method('log');
296
297 $object = $this->container->getInstance('t3lib_object_prototypeNeedsPrototypeInConstructor');
298 $this->assertInstanceOf('t3lib_object_prototype', $object->dependency);
299 }
300
301 /**
302 * @test
303 */
304 public function prototypeWhichRequiresSingletonViaConstructorInjectionWorks() {
305 $this->container->expects($this->never())->method('log');
306
307 $object = $this->container->getInstance('t3lib_object_prototypeNeedsSingletonInConstructor');
308 $this->assertInstanceOf('t3lib_object_singleton', $object->dependency);
309 }
310 }
311 ?>