2 /***************************************************************
4 * (c) 2010 Daniel Pötzinger
5 * (c) 2010 Bastian Waidelich <bastian@typo3.org>
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.
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
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.
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
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');
29 * Testcase for class t3lib_object_Container.
31 * @author Daniel Pötzinger
32 * @author Bastian Waidelich <bastian@typo3.org>
36 class Tx_Extbase_Tests_Unit_Object_Container_ContainerTest
extends Tx_Extbase_Tests_Unit_BaseTestCase
{
39 * @var Tx_Extbase_Object_Container_Container
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));
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));
55 public function getInstanceReturnsInstanceOfSimpleClass() {
56 $object = $this->container
->getInstance('t3lib_object_tests_c');
57 $this->assertInstanceOf('t3lib_object_tests_c', $object);
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);
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
);
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
);
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
);
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
);
106 * @expectedException Tx_Extbase_Object_Exception
108 public function getInstanceThrowsExceptionWhenTryingToInstanciateASingletonWithConstructorParameters() {
109 $this->container
->getInstance('t3lib_object_tests_amixed_array_singleton', array('somevalue'));
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
);
125 public function getInstancePassesGivenParameterToTheNewObject() {
126 $mockObject = $this->getMock('t3lib_object_tests_c');
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
);
136 public function getInstanceReturnsAFreshInstanceIfObjectIsNoSingleton() {
137 $object1 = $this->container
->getInstance('t3lib_object_tests_a');
138 $object2 = $this->container
->getInstance('t3lib_object_tests_a');
140 $this->assertNotSame($object1, $object2);
146 public function getInstanceReturnsSameInstanceInstanceIfObjectIsSingleton() {
147 $object1 = $this->container
->getInstance('t3lib_object_tests_singleton');
148 $object2 = $this->container
->getInstance('t3lib_object_tests_singleton');
150 $this->assertSame($object1, $object2);
155 * @expectedException Tx_Extbase_Object_Exception_CannotBuildObject
157 public function getInstanceThrowsExceptionIfPrototypeObjectsWiredViaConstructorInjectionContainCyclicDependencies() {
158 $this->container
->getInstance('t3lib_object_tests_cyclic1WithSetterDependency');
163 * @expectedException Tx_Extbase_Object_Exception_CannotBuildObject
165 public function getInstanceThrowsExceptionIfPrototypeObjectsWiredViaSetterInjectionContainCyclicDependencies() {
166 $this->container
->getInstance('t3lib_object_tests_cyclic1');
171 * @expectedException Tx_Extbase_Object_Exception
173 public function getInstanceThrowsExceptionIfClassWasNotFound() {
174 $this->container
->getInstance('nonextistingclass_bla');
180 public function getInstanceUsesClassNameSha1AsCacheKey() {
181 $className = 'Tx\Extbase\Object\Container\Fixtures\NamespacedClass';
182 $classNameHash = sha1($className);
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));
188 $mockedCache->expects($this->any())->method('has')->will($this->returnValue(FALSE));
189 $mockedCache->expects($this->once())->method('set')->with($classNameHash, $this->anything());
191 $this->container
->getInstance($className);
197 public function getEmptyObjectReturnsInstanceOfSimpleClass() {
198 $object = $this->container
->getEmptyObject('t3lib_object_tests_c');
199 $this->assertInstanceOf('t3lib_object_tests_c', $object);
205 public function test_canGetChildClass() {
206 $object = $this->container
->getInstance('t3lib_object_tests_b_child');
207 $this->assertInstanceOf('t3lib_object_tests_b_child', $object);
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);
218 $this->assertInstanceOf('t3lib_object_tests_someinterface', $object->dependency
);
219 $this->assertInstanceOf('t3lib_object_tests_someimplementation', $object->dependency
);
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
);
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);
237 $object = $this->container
->getInstance('t3lib_object_singletonNeedsPrototype');
238 $this->assertInstanceOf('t3lib_object_prototype', $object->dependency
);
244 public function singletonWhichRequiresSingletonViaSetterInjectionWorks() {
245 $this->container
->expects($this->never())->method('log');
247 $object = $this->container
->getInstance('t3lib_object_singletonNeedsSingleton');
248 $this->assertInstanceOf('t3lib_object_singleton', $object->dependency
);
254 public function prototypeWhichRequiresPrototypeViaSetterInjectionWorks() {
255 $this->container
->expects($this->never())->method('log');
257 $object = $this->container
->getInstance('t3lib_object_prototypeNeedsPrototype');
258 $this->assertInstanceOf('t3lib_object_prototype', $object->dependency
);
264 public function prototypeWhichRequiresSingletonViaSetterInjectionWorks() {
265 $this->container
->expects($this->never())->method('log');
267 $object = $this->container
->getInstance('t3lib_object_prototypeNeedsSingleton');
268 $this->assertInstanceOf('t3lib_object_singleton', $object->dependency
);
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);
277 $object = $this->container
->getInstance('t3lib_object_singletonNeedsPrototypeInConstructor');
278 $this->assertInstanceOf('t3lib_object_prototype', $object->dependency
);
284 public function singletonWhichRequiresSingletonViaConstructorInjectionWorks() {
285 $this->container
->expects($this->never())->method('log');
287 $object = $this->container
->getInstance('t3lib_object_singletonNeedsSingletonInConstructor');
288 $this->assertInstanceOf('t3lib_object_singleton', $object->dependency
);
294 public function prototypeWhichRequiresPrototypeViaConstructorInjectionWorks() {
295 $this->container
->expects($this->never())->method('log');
297 $object = $this->container
->getInstance('t3lib_object_prototypeNeedsPrototypeInConstructor');
298 $this->assertInstanceOf('t3lib_object_prototype', $object->dependency
);
304 public function prototypeWhichRequiresSingletonViaConstructorInjectionWorks() {
305 $this->container
->expects($this->never())->method('log');
307 $object = $this->container
->getInstance('t3lib_object_prototypeNeedsSingletonInConstructor');
308 $this->assertInstanceOf('t3lib_object_singleton', $object->dependency
);