[+TASK] Extbase (Tests): Moving all Tests in "Unit" directory (2/2)
authorBastian Waidelich <bastian@typo3.org>
Sat, 27 Nov 2010 11:57:04 +0000 (11:57 +0000)
committerBastian Waidelich <bastian@typo3.org>
Sat, 27 Nov 2010 11:57:04 +0000 (11:57 +0000)
43 files changed:
typo3/sysext/extbase/Tests/Unit/Configuration/BackendConfigurationManager_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Configuration/FrontendConfigurationManager_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/DomainObject/AbstractEntity_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Fixtures/Entity.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/MVC/Controller/AbstractController_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/MVC/Controller/ActionController_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/MVC/Controller/Argument_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/MVC/Controller/Arguments_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/MVC/DispatcherTest.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/MVC/Web/RequestBuilder_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/MVC/Web/RequestTest.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/MVC/Web/Routing/UriBuilder_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Object/Container/ClassInfoFactoryTest.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Object/Container/ContainerTest.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Object/Container/Fixtures/Testclasses.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Persistence/Mapper/DataMapFactory_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Persistence/ObjectStorage_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Persistence/QueryResult_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Persistence/Query_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Persistence/Repository_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Persistence/Session_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Persistence/Storage/Typo3DbBackend_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Reflection/Service_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Security/Channel/RequestHashService_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Security/Cryptography/HashService_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Utility/Extension_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Utility/TypoScript_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/AlphanumericValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/ConjunctionValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/DateTimeValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/EmailAddressValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/FloatValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/GenericObjectValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/IntegerValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/NotEmptyValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/NumberRangeValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/NumberValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/RawValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/RegularExpressionValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/StringLengthValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/Validator/TextValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/ValidatorResolver_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/ext_autoload.php

diff --git a/typo3/sysext/extbase/Tests/Unit/Configuration/BackendConfigurationManager_testcase.php b/typo3/sysext/extbase/Tests/Unit/Configuration/BackendConfigurationManager_testcase.php
new file mode 100644 (file)
index 0000000..1152734
--- /dev/null
@@ -0,0 +1,170 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_Tests_Unit_Configuration_BackendConfigurationManager_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @var array
+        */
+       protected $getBackup;
+
+       /**
+        * @var array
+        */
+       protected $postBackup;
+
+       /**
+        * @var t3lib_DB
+        */
+       protected $typo3DbBackup;
+
+       /**
+        * @var Tx_Extbase_Configuration_BackendConfigurationManager
+        */
+       protected $backendConfigurationManager;
+
+       /**
+        * Sets up this testcase
+        */
+       public function setUp() {
+               $this->getBackup = t3lib_div::_GET();
+               $this->postBackup = t3lib_div::_POST();
+
+               $this->typo3DbBackup = $GLOBALS['TYPO3_DB'];
+               $GLOBALS['TYPO3_DB'] = $this->getMock('t3lib_DB', array());
+
+               $this->backendConfigurationManager = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Configuration_BackendConfigurationManager'), array('dummy'));
+       }
+
+       /**
+        * Tears down this testcase
+        */
+       public function tearDown() {
+               t3lib_div::_GETset($this->getBackup);
+               $_POST = $this->postBackup;
+       }
+
+       /**
+        * @test
+        */
+       public function getTypoScriptSetupCanBeTested() {
+               $this->markTestIncomplete('This method can\'t be tested with the current TYPO3 version, because we can\'t mock objects returned from t3lib_div::makeInstance().');
+       }
+
+       /**
+        * @test
+        */
+       public function getCurrentPageIdReturnsPageIdFromGet() {
+               t3lib_div::_GETset(array('id' => 123));
+
+               $expectedResult = 123;
+               $actualResult = $this->backendConfigurationManager->_call('getCurrentPageId');
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function getCurrentPageIdReturnsPageIdFromPost() {
+               t3lib_div::_GETset(array('id' => 123));
+               $_POST['id'] = 321;
+
+               $expectedResult = 321;
+               $actualResult = $this->backendConfigurationManager->_call('getCurrentPageId');
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function getCurrentPageIdReturnsPidFromFirstRootTemplateIfIdIsNotSet() {
+               $GLOBALS['TYPO3_DB']->expects($this->once())
+                       ->method('exec_SELECTgetRows')
+                       ->with('pid', 'sys_template', 'deleted=0 AND hidden=0 AND root=1', '', '', '1')
+                       ->will(
+                               $this->returnValue(
+                                       array(
+                                               array('pid' => 123)
+                                       )
+                               )
+                       );
+
+               $expectedResult = 123;
+               $actualResult = $this->backendConfigurationManager->_call('getCurrentPageId');
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function getCurrentPageIdReturnsUidFromFirstRootPageIfIdIsNotSetAndNoRootTemplateWasFound() {
+               $GLOBALS['TYPO3_DB']->expects($this->at(0))
+                       ->method('exec_SELECTgetRows')
+                       ->with('pid', 'sys_template', 'deleted=0 AND hidden=0 AND root=1', '', '', '1')
+                       ->will($this->returnValue(array()));
+
+               $GLOBALS['TYPO3_DB']->expects($this->at(1))
+                       ->method('exec_SELECTgetRows')
+                       ->with('uid', 'pages', 'deleted=0 AND hidden=0 AND is_siteroot=1', '', '', '1')
+                       ->will(
+                               $this->returnValue(
+                                       array(
+                                               array('uid' => 321)
+                                       )
+                               )
+                       );
+
+               $expectedResult = 321;
+               $actualResult = $this->backendConfigurationManager->_call('getCurrentPageId');
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function getCurrentPageIdReturnsDefaultStoragePidIfIdIsNotSetNoRootTemplateAndRootPageWasFound() {
+               $GLOBALS['TYPO3_DB']->expects($this->at(0))
+                       ->method('exec_SELECTgetRows')
+                       ->with('pid', 'sys_template', 'deleted=0 AND hidden=0 AND root=1', '', '', '1')
+                       ->will($this->returnValue(array()));
+
+               $GLOBALS['TYPO3_DB']->expects($this->at(1))
+                       ->method('exec_SELECTgetRows')
+                       ->with('uid', 'pages', 'deleted=0 AND hidden=0 AND is_siteroot=1', '', '', '1')
+                       ->will($this->returnValue(array()));
+
+               $expectedResult = 0;
+               $actualResult = $this->backendConfigurationManager->_call('getCurrentPageId');
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Configuration/FrontendConfigurationManager_testcase.php b/typo3/sysext/extbase/Tests/Unit/Configuration/FrontendConfigurationManager_testcase.php
new file mode 100644 (file)
index 0000000..f585a05
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_Configuration_FrontendConfigurationManager_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @var tslib_fe
+        */
+       protected $tsfeBackup;
+
+       /**
+        * @var Tx_Extbase_Configuration_FrontendConfigurationManager
+        */
+       protected $frontendConfigurationManager;
+       /**
+        * Sets up this testcase
+        */
+       public function setUp() {
+               $this->tsfeBackup = $GLOBALS['TSFE'];
+               $this->frontendConfigurationManager = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Configuration_FrontendConfigurationManager'), array('dummy'));
+       }
+
+       /**
+        * Tears down this testcase
+        */
+       public function tearDown() {
+               $GLOBALS['TSFE']->tmpl->setup;
+       }
+
+       /**
+        * @test
+        */
+       public function getTypoScriptSetupReturnsSetupFromTSFE() {
+               $GLOBALS['TSFE']->tmpl->setup = array('foo' => 'bar');
+               $this->assertEquals(array('foo' => 'bar'), $this->frontendConfigurationManager->_callRef('getTypoScriptSetup'));
+       }
+
+       /**
+        * @test
+        */
+       public function overrideSwitchableControllerActionsFromFlexformMergesNonCacheableActions() {
+               $frameworkConfiguration = array(
+                       'userFunc' => 'tx_extbase_dispatcher->dispatch',
+                       'pluginName' => 'Pi1',
+                       'extensionName' => 'SomeExtension',
+                       'switchableControllerActions' => array(
+                               'Controller1' => array(
+                                       'controller' => 'Controller1',
+                                       'actions' => 'action1 , action2'
+                               ),
+                               'Controller2' => array(
+                                       'controller' => 'Controller2',
+                                       'actions' => 'action2 , action1,action3',
+                                       'nonCacheableActions' => 'action2, action3'
+                               )
+                       )
+               );
+               $flexformConfiguration = array(
+                       'switchableControllerActions' => 'Controller1->action2;Controller2->action3;Controller2->action1'
+               );
+               $expectedResult = array(
+                       'userFunc' => 'tx_extbase_dispatcher->dispatch',
+                       'pluginName' => 'Pi1',
+                       'extensionName' => 'SomeExtension',
+                       'switchableControllerActions' => array(
+                               'Controller1' => array(
+                                       'controller' => 'Controller1',
+                                       'actions' => 'action2'
+                               ),
+                               'Controller2' => array(
+                                       'controller' => 'Controller2',
+                                       'actions' => 'action3,action1',
+                                       'nonCacheableActions' => 'action3'
+                               )
+                       )
+               );
+               $actualResult = $this->frontendConfigurationManager->_callRef('overrideSwitchableControllerActionsFromFlexform', $frameworkConfiguration, $flexformConfiguration);
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/DomainObject/AbstractEntity_testcase.php b/typo3/sysext/extbase/Tests/Unit/DomainObject/AbstractEntity_testcase.php
new file mode 100644 (file)
index 0000000..b5a5573
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Sebastian Kurfürst <sebastian@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_DomainObject_AbstractEntity_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function objectIsNotDirtyAfterCallingMemorizeCleanStateWithSimpleProperties() {
+               $domainObjectName = uniqid('DomainObject_');
+               eval('class ' . $domainObjectName . ' extends Tx_Extbase_DomainObject_AbstractEntity {
+                       public $foo;
+                       public $bar;
+               }');
+               $domainObject = new $domainObjectName();
+               $domainObject->foo = 'Test';
+               $domainObject->bar = 'It is raining outside';
+               $domainObject->_memorizeCleanState();
+
+               $this->assertFalse($domainObject->_isDirty());
+       }
+
+       /**
+        * @test
+        */
+       public function objectIsDirtyAfterCallingMemorizeCleanStateWithSimplePropertiesAndModifyingThePropertiesAfterwards() {
+               $domainObjectName = uniqid('DomainObject_');
+               eval('class ' . $domainObjectName . ' extends Tx_Extbase_DomainObject_AbstractEntity {
+                       public $foo;
+                       public $bar;
+               }');
+               $domainObject = new $domainObjectName();
+               $domainObject->foo = 'Test';
+               $domainObject->bar = 'It is raining outside';
+
+               $domainObject->_memorizeCleanState();
+               $domainObject->bar = 'Now it is sunny.';
+
+               $this->assertTrue($domainObject->_isDirty());
+       }
+
+       /**
+        * @test
+        */
+       public function objectIsNotDirtyAfterCallingMemorizeCleanStateWithObjectProperties() {
+               $domainObjectName = uniqid('DomainObject_');
+               eval('class ' . $domainObjectName . ' extends Tx_Extbase_DomainObject_AbstractEntity {
+                       public $foo;
+                       public $bar;
+               }');
+               $domainObject = new $domainObjectName();
+               $domainObject->foo = new DateTime();
+               $domainObject->bar = 'It is raining outside';
+               $domainObject->_memorizeCleanState();
+
+               $this->assertFalse($domainObject->_isDirty());
+       }
+
+       /**
+        * @test
+        */
+       public function objectIsNotDirtyAfterCallingMemorizeCleanStateWithOtherDomainObjectsAsProperties() {
+               $domainObjectName = uniqid('DomainObject_');
+               eval('class ' . $domainObjectName . ' extends Tx_Extbase_DomainObject_AbstractEntity {
+                       public $foo;
+                       public $bar;
+               }');
+
+               $secondDomainObjectName = uniqid('DomainObject_');
+               eval('class ' . $secondDomainObjectName . ' extends Tx_Extbase_DomainObject_AbstractEntity {
+                       public $foo;
+                       public $bar;
+               }');
+               $secondDomainObject = new $secondDomainObjectName;
+               $secondDomainObject->_memorizeCleanState();
+
+
+               $domainObject = new $domainObjectName();
+               $domainObject->foo = $secondDomainObject;
+               $domainObject->bar = 'It is raining outside';
+               $domainObject->_memorizeCleanState();
+
+               $this->assertFalse($domainObject->_isDirty());
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Fixtures/Entity.php b/typo3/sysext/extbase/Tests/Unit/Fixtures/Entity.php
new file mode 100644 (file)
index 0000000..505c70a
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * An entity
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $ID:$
+ * @entity
+ */
+class Tx_Extbase_Tests_Fixtures_Entity extends Tx_Extbase_DomainObject_AbstractEntity {
+
+       /**
+        * The entity's name
+        *
+        * @var string
+        */
+       protected $name;
+
+
+       /**
+        * Constructs this entity
+        *
+        * @param string $name Name of this blog
+        * @return void
+        */
+       public function __construct($name) {
+               $this->setName($name);
+       }
+       
+       /**
+        * Sets this entity's name
+        *
+        * @param string $name The entity's name
+        * @return void
+        */
+       public function setName($name) {
+               $this->name = $name;
+       }
+
+       /**
+        * Returns the entity's name
+        *
+        * @return string The entity's name
+        */
+       public function getName() {
+               return $this->name;
+       }
+       
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/MVC/Controller/AbstractController_testcase.php b/typo3/sysext/extbase/Tests/Unit/MVC/Controller/AbstractController_testcase.php
new file mode 100644 (file)
index 0000000..a64a98f
--- /dev/null
@@ -0,0 +1,235 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_MVC_Controller_AbstractController_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function theExtensionNameIsInitialized() {
+               $extensionName = uniqid('Test');
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('initializeObjects'), array(), 'Tx_' . $extensionName . '_Controller');
+               $this->assertSame($extensionName, $controller->_get('extensionName'));
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_MVC_Exception_UnsupportedRequestType
+        */
+       public function processRequestWillThrowAnExceptionIfTheGivenRequestIsNotSupported() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request');
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_Web_Response');
+
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('mapRequestArgumentsToControllerArguments'), array(), '', FALSE);
+               $controller->_set('supportedRequestTypes', array('Tx_Something_Request'));
+               $controller->processRequest($mockRequest, $mockResponse);
+       }
+
+       /**
+        * @test
+        */
+       public function processRequestSetsTheDispatchedFlagOfTheRequest() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request');
+               $mockRequest->expects($this->once())->method('setDispatched')->with(TRUE);
+
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_Web_Response');
+
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('initializeArguments', 'initializeControllerArgumentsBaseValidators', 'mapRequestArgumentsToControllerArguments'), array(), '', FALSE);
+               $controller->processRequest($mockRequest, $mockResponse);
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_MVC_Exception_StopAction
+        */
+       public function forwardThrowsAStopActionException() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request');
+               $mockRequest->expects($this->once())->method('setDispatched')->with(FALSE);
+               $mockRequest->expects($this->once())->method('setControllerActionName')->with('foo');
+
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('dummy'), array(), '', FALSE);
+               $controller->_set('request', $mockRequest);
+               $controller->_call('forward', 'foo');
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_MVC_Exception_StopAction
+        */
+       public function forwardSetsControllerAndArgumentsAtTheRequestObjectIfTheyAreSpecified() {
+               $arguments = array('foo' => 'bar');
+
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request');
+               $mockRequest->expects($this->once())->method('setControllerActionName')->with('foo');
+               $mockRequest->expects($this->once())->method('setControllerName')->with('Bar');
+               $mockRequest->expects($this->once())->method('setControllerExtensionName')->with('Baz');
+               $mockRequest->expects($this->once())->method('setArguments')->with($arguments);
+
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('dummy'), array(), '', FALSE);
+               $controller->_set('request', $mockRequest);
+               $controller->_call('forward', 'foo', 'Bar', 'Baz', $arguments);
+       }
+
+       /**
+        * @test
+        */
+       public function redirectRedirectsToTheSpecifiedAction() {
+               $arguments = array('foo' => 'bar');
+
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request');
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_Web_Response');
+
+               $mockUriBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_UriBuilder');
+               $mockUriBuilder->expects($this->once())->method('reset')->will($this->returnValue($mockUriBuilder));
+               $mockUriBuilder->expects($this->once())->method('setTargetPageUid')->with(123)->will($this->returnValue($mockUriBuilder));
+               $mockUriBuilder->expects($this->once())->method('uriFor')->with('theActionName', $arguments, 'TheControllerName', 'TheExtensionName')->will($this->returnValue('the uri'));
+
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('redirectToURI'), array(), '', FALSE);
+               $controller->expects($this->once())->method('redirectToURI')->with('the uri');
+               $controller->_set('request', $mockRequest);
+               $controller->_set('response', $mockResponse);
+               $controller->_set('uriBuilder', $mockUriBuilder);
+               $controller->_call('redirect', 'theActionName', 'TheControllerName', 'TheExtensionName', $arguments, 123);
+       }
+
+       /**
+        * @test
+        */
+       public function theBaseUriIsAddedIfNotAlreadyExists() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request');
+               $mockRequest->expects($this->any())->method('getBaseURI')->will($this->returnValue('http://www.example.com/foo/'));
+
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('dummy'), array(), '', FALSE);
+               $controller->_set('request', $mockRequest);
+               $actualResult = $controller->_call('addBaseUriIfNecessary', 'bar/baz/boom.html');
+               $expectedResult = 'http://www.example.com/foo/bar/baz/boom.html';
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function theBaseUriIsNotAddedIfAlreadyExists() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request');
+               $mockRequest->expects($this->any())->method('getBaseURI')->will($this->returnValue('http://www.example.com/foo/'));
+
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('dummy'), array(), '', FALSE);
+               $controller->_set('request', $mockRequest);
+               $actualResult = $controller->_call('addBaseUriIfNecessary', 'http://www.example.com/foo/bar/baz/boom.html');
+               $expectedResult = 'http://www.example.com/foo/bar/baz/boom.html';
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_MVC_Exception_StopAction
+        */
+       public function throwStatusSetsTheSpecifiedStatusHeaderAndStopsTheCurrentAction() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request');
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_Web_Response');
+               $mockResponse->expects($this->once())->method('setStatus')->with(404, 'File Really Not Found');
+               $mockResponse->expects($this->once())->method('setContent')->with('<h1>All wrong!</h1><p>Sorry, the file does not exist.</p>');
+
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('dummy'), array(), '', FALSE);
+               $controller->_set('request', $mockRequest);
+               $controller->_set('response', $mockResponse);
+               $controller->_call('throwStatus', 404, 'File Really Not Found', '<h1>All wrong!</h1><p>Sorry, the file does not exist.</p>');
+       }
+
+       /**
+        * @test
+        */
+       public function initializeControllerArgumentsBaseValidatorsRegistersValidatorsDeclaredInTheArgumentModels() {
+               $mockValidators = array(
+                       'foo' => $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface'),
+               );
+
+               $mockValidatorResolver = $this->getMock('Tx_Extbase_Validation_ValidatorResolver', array(), array(), '', FALSE);
+               $mockValidatorResolver->expects($this->at(0))->method('getBaseValidatorConjunction')->with('FooType')->will($this->returnValue($mockValidators['foo']));
+               $mockValidatorResolver->expects($this->at(1))->method('getBaseValidatorConjunction')->with('BarType')->will($this->returnValue(NULL));
+
+               $mockArgumentFoo = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('foo'), '', FALSE);
+               $mockArgumentFoo->expects($this->once())->method('getDataType')->will($this->returnValue('FooType'));
+               $mockArgumentFoo->expects($this->once())->method('setValidator')->with($mockValidators['foo']);
+
+               $mockArgumentBar = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('bar'), '', FALSE);
+               $mockArgumentBar->expects($this->once())->method('getDataType')->will($this->returnValue('BarType'));
+               $mockArgumentBar->expects($this->never())->method('setValidator');
+
+               $mockArguments = new Tx_Extbase_MVC_Controller_Arguments();
+               $mockArguments->addArgument($mockArgumentFoo);
+               $mockArguments->addArgument($mockArgumentBar);
+
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('dummy'), array(), '', FALSE);
+               $controller->_set('arguments', $mockArguments);
+               $controller->injectValidatorResolver($mockValidatorResolver);
+               $controller->_call('initializeControllerArgumentsBaseValidators');
+       }
+
+       /**
+        * @test
+        */
+       public function mapRequestArgumentsToControllerArgumentsPreparesInformationAndValidatorsAndMapsAndValidates() {
+               $mockValidator = new Tx_Extbase_MVC_Controller_ArgumentsValidator(); // FIXME see original FLOW3 code
+
+               $mockArgumentFoo = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('foo'), '', FALSE);
+               $mockArgumentFoo->expects($this->any())->method('getName')->will($this->returnValue('foo'));
+               $mockArgumentBar = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('bar'), '', FALSE);
+               $mockArgumentBar->expects($this->any())->method('getName')->will($this->returnValue('bar'));
+
+               $mockArguments = new Tx_Extbase_MVC_Controller_Arguments();
+               $mockArguments->addArgument($mockArgumentFoo);
+               $mockArguments->addArgument($mockArgumentBar);
+
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request');
+               $mockRequest->expects($this->once())->method('getArguments')->will($this->returnValue(array('requestFoo', 'requestBar')));
+
+               $mockMappingResults = $this->getMock('Tx_Extbase_Property_MappingResults');
+
+               $mockPropertyMapper = $this->getMock('Tx_Extbase_Property_Mapper', array(), array(), '', FALSE);
+               $mockPropertyMapper->expects($this->once())->method('mapAndValidate')
+                       ->with(array('foo', 'bar'), array('requestFoo', 'requestBar'), $mockArguments, array(), $mockValidator)
+                       ->will($this->returnValue(TRUE));
+               $mockPropertyMapper->expects($this->once())->method('getMappingResults')->will($this->returnValue($mockMappingResults));
+
+               $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('dummy'), array(), '', FALSE);
+
+               $controller->_set('arguments', $mockArguments);
+               $controller->_set('request', $mockRequest);
+               $controller->_set('propertyMapper', $mockPropertyMapper);
+               $controller->_set('objectManager', $mockObjectManager);
+
+               $controller->_call('mapRequestArgumentsToControllerArguments');
+
+               $this->assertSame($mockMappingResults, $controller->_get('argumentsMappingResults'));
+               // $this->assertTrue(in_array('Tx_Extbase_Validation_Validator_ObjectValidatorInterface', class_implements($controller->_get('argumentsMappingResults'))));
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/MVC/Controller/ActionController_testcase.php b/typo3/sysext/extbase/Tests/Unit/MVC/Controller/ActionController_testcase.php
new file mode 100644 (file)
index 0000000..1758957
--- /dev/null
@@ -0,0 +1,599 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_MVC_Controller_ActionController_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function processRequestSticksToSpecifiedSequence() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request', array(), array(), '', FALSE);
+               $mockRequest->expects($this->once())->method('setDispatched')->with(TRUE);
+
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_Web_Response', array(), array(), '', FALSE);
+
+               $mockView = $this->getMock('Tx_Extbase_MVC_View_ViewInterface');
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array(
+                       'initializeFooAction', 'initializeAction', 'resolveActionMethodName', 'initializeActionMethodArguments', 'initializeActionMethodValidators', 'mapRequestArgumentsToControllerArguments', 'resolveView', 'initializeView', 'callActionMethod', 'checkRequestHash'),
+                       array(), '', FALSE);
+               $mockController->_set('objectFactory', $mockObjectFactory);
+               $mockController->expects($this->at(0))->method('resolveActionMethodName')->will($this->returnValue('fooAction'));
+               $mockController->expects($this->at(1))->method('initializeActionMethodArguments');
+               $mockController->expects($this->at(2))->method('initializeActionMethodValidators');
+               $mockController->expects($this->at(3))->method('initializeAction');
+               $mockController->expects($this->at(4))->method('initializeFooAction');
+               $mockController->expects($this->at(5))->method('mapRequestArgumentsToControllerArguments');
+               $mockController->expects($this->at(6))->method('checkRequestHash');
+               $mockController->expects($this->at(7))->method('resolveView')->will($this->returnValue($mockView));
+               $mockController->expects($this->at(8))->method('initializeView');
+               $mockController->expects($this->at(9))->method('callActionMethod');
+
+               $mockController->processRequest($mockRequest, $mockResponse);
+               $this->assertSame($mockRequest, $mockController->_get('request'));
+               $this->assertSame($mockResponse, $mockController->_get('response'));
+       }
+
+       /**
+        * @test
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function callActionMethodAppendsStringsReturnedByActionMethodToTheResponseObject() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_ResponseInterface', array(), array(), '', FALSE);
+               $mockResponse->expects($this->once())->method('appendContent')->with('the returned string');
+
+               $mockArguments = new ArrayObject;
+
+               $mockArgumentMappingResults = $this->getMock('Tx_Extbase_Property_MappingResults', array(), array(), '', FALSE);
+               $mockArgumentMappingResults->expects($this->once())->method('hasErrors')->will($this->returnValue(FALSE));
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('fooAction', 'initializeAction'), array(), '', FALSE);
+               $mockController->expects($this->once())->method('fooAction')->will($this->returnValue('the returned string'));
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('response', $mockResponse);
+               $mockController->_set('arguments', $mockArguments);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->_set('argumentsMappingResults', $mockArgumentMappingResults);
+               $mockController->_call('callActionMethod');
+       }
+
+       /**
+        * @test
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function callActionMethodRendersTheViewAutomaticallyIfTheActionReturnedNullAndAViewExists() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_ResponseInterface', array(), array(), '', FALSE);
+               $mockResponse->expects($this->once())->method('appendContent')->with('the view output');
+
+               $mockView = $this->getMock('Tx_Extbase_MVC_View_ViewInterface');
+               $mockView->expects($this->once())->method('render')->will($this->returnValue('the view output'));
+
+               $mockArguments = new ArrayObject;
+
+               $mockArgumentMappingResults = $this->getMock('Tx_Extbase_Property_MappingResults', array(), array(), '', FALSE);
+               $mockArgumentMappingResults->expects($this->once())->method('hasErrors')->will($this->returnValue(FALSE));
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('fooAction', 'initializeAction'), array(), '', FALSE);
+               $mockController->expects($this->once())->method('fooAction');
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('response', $mockResponse);
+               $mockController->_set('arguments', $mockArguments);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->_set('argumentsMappingResults', $mockArgumentMappingResults);
+               $mockController->_set('view', $mockView);
+               $mockController->_call('callActionMethod');
+       }
+
+       /**
+        * @test
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function callActionMethodCallsTheErrorActionIfTheMappingResultsHaveErrors() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_ResponseInterface', array(), array(), '', FALSE);
+               $mockResponse->expects($this->once())->method('appendContent')->with('the returned string');
+
+               $mockArguments = new ArrayObject;
+
+               $mockArgumentMappingResults = $this->getMock('Tx_Extbase_Property_MappingResults', array(), array(), '', FALSE);
+               $mockArgumentMappingResults->expects($this->once())->method('hasErrors')->will($this->returnValue(TRUE));
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('barAction', 'initializeAction'), array(), '', FALSE);
+               $mockController->expects($this->once())->method('barAction')->will($this->returnValue('the returned string'));
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('response', $mockResponse);
+               $mockController->_set('arguments', $mockArguments);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->_set('errorMethodName', 'barAction');
+               $mockController->_set('argumentsMappingResults', $mockArgumentMappingResults);
+               $mockController->_call('callActionMethod');
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       public function callActionMethodPassesDefaultValuesAsArguments() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_ResponseInterface', array(), array(), '', FALSE);
+
+               $arguments = new ArrayObject();
+               $optionalArgument = new Tx_Extbase_MVC_Controller_Argument('name1', 'Text');
+               $optionalArgument->setDefaultValue('Default value');
+               $arguments[] = $optionalArgument;
+
+               $mockArgumentMappingResults = $this->getMock('Tx_Extbase_Property_MappingResults', array(), array(), '', FALSE);
+               $mockArgumentMappingResults->expects($this->once())->method('hasErrors')->will($this->returnValue(FALSE));
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('fooAction', 'initializeAction'), array(), '', FALSE);
+               $mockController->expects($this->once())->method('fooAction')->with('Default value');
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('response', $mockResponse);
+               $mockController->_set('arguments', $arguments);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->_set('argumentsMappingResults', $mockArgumentMappingResults);
+               $mockController->_call('callActionMethod');
+       }
+
+       /**
+        * @test
+        * @author Karsten Dambekalns <karsten@typo3.org>
+        */
+       public function resolveViewUsesFluidTemplateViewIfTemplateIsAvailable() {
+               $mockSession = $this->getMock('Tx_Extbase_Session_SessionInterface');
+               $mockControllerContext = $this->getMock('Tx_Extbase_MVC_Controller_ControllerContext', array(), array(), '', FALSE);
+
+               $mockFluidTemplateView = $this->getMock('Tx_Extbase_MVC_View_ViewInterface', array('setControllerContext', 'getViewHelper', 'assign', 'assignMultiple', 'render', 'hasTemplate', 'initializeView'));
+               $mockFluidTemplateView->expects($this->once())->method('setControllerContext')->with($mockControllerContext);
+               $mockFluidTemplateView->expects($this->once())->method('hasTemplate')->will($this->returnValue(TRUE));
+
+               $mockObjectManager = $this->getMock('Tx_Extbase_Object_ObjectManagerInterface', array(), array(), '', FALSE);
+               $mockObjectManager->expects($this->at(0))->method('get')->with('Tx_Fluid_View_TemplateView')->will($this->returnValue($mockFluidTemplateView));
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('buildControllerContext'), array(), '', FALSE);
+               $mockController->expects($this->once())->method('buildControllerContext')->will($this->returnValue($mockControllerContext));
+               $mockController->_set('session', $mockSession);
+               $mockController->_set('objectManager', $mockObjectManager);
+
+               $this->assertSame($mockFluidTemplateView, $mockController->_call('resolveView'));
+       }
+
+       /**
+        * @test
+        * @author Bastian Waidelich <bastian@typo3.org>
+        */
+       public function resolveViewObjectNameUsesViewObjectNamePatternToResolveViewObjectName() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+               $mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('MyPackage'));
+               $mockRequest->expects($this->once())->method('getControllerName')->will($this->returnValue('MyController'));
+               $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('MyAction'));
+               $mockRequest->expects($this->once())->method('getFormat')->will($this->returnValue('MyFormat'));
+
+               $mockObjectManager = $this->getMock('Tx_Extbase_Object_ObjectManagerInterface', array(), array(), '', FALSE);
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('dummy'), array(), '', FALSE);
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('objectManager', $mockObjectManager);
+               $mockController->_set('viewObjectNamePattern', 'RandomViewObjectPattern_@package_@controller_@action_@format');
+
+               $mockController->_call('resolveViewObjectName');
+       }
+
+       /**
+        * @test
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function resolveActionMethodNameReturnsTheCurrentActionMethodNameFromTheRequest() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+               $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('fooBar'));
+
+               $mockController = $this->getAccessibleMock('Tx_Extbase_MVC_Controller_ActionController', array('fooBarAction'), array(), '', FALSE);
+               $mockController->_set('request', $mockRequest);
+
+               $this->assertEquals('fooBarAction', $mockController->_call('resolveActionMethodName'));
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_MVC_Exception_NoSuchAction
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function resolveActionMethodNameThrowsAnExceptionIfTheActionDefinedInTheRequestDoesNotExist() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+               $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('fooBar'));
+
+               $mockController = $this->getAccessibleMock('Tx_Extbase_MVC_Controller_ActionController', array('otherBarAction'), array(), '', FALSE);
+               $mockController->_set('request', $mockRequest);
+
+               $mockController->_call('resolveActionMethodName');
+       }
+
+       /**
+        * @test
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function initializeActionMethodArgumentsRegistersArgumentsFoundInTheSignatureOfTheCurrentActionMethod() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+
+               $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('addNewArgument', 'removeAll'), array(), '', FALSE);
+               $mockArguments->expects($this->at(0))->method('addNewArgument')->with('stringArgument', 'string', TRUE);
+               $mockArguments->expects($this->at(1))->method('addNewArgument')->with('integerArgument', 'integer', TRUE);
+               $mockArguments->expects($this->at(2))->method('addNewArgument')->with('objectArgument', 'F3_Foo_Bar', TRUE);
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('fooAction', 'evaluateDontValidateAnnotations'), array(), '', FALSE);
+
+               $methodParameters = array(
+                       'stringArgument' => array(
+                               'position' => 0,
+                               'byReference' => FALSE,
+                               'array' => FALSE,
+                               'optional' => FALSE,
+                               'allowsNull' => FALSE,
+                               'type' => 'string'
+                       ),
+                       'integerArgument' => array(
+                               'position' => 1,
+                               'byReference' => FALSE,
+                               'array' => FALSE,
+                               'optional' => FALSE,
+                               'allowsNull' => FALSE,
+                               'type' => 'integer'
+                       ),
+                       'objectArgument' => array(
+                               'position' => 2,
+                               'byReference' => FALSE,
+                               'array' => FALSE,
+                               'optional' => FALSE,
+                               'allowsNull' => FALSE,
+                               'type' => 'F3_Foo_Bar'
+                       )
+               );
+
+               $mockReflectionService = $this->getMock('Tx_Extbase_Reflection_Service', array(), array(), '', FALSE);
+               $mockReflectionService->expects($this->once())->method('getMethodParameters')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodParameters));
+
+               $mockController->injectReflectionService($mockReflectionService);
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('arguments', $mockArguments);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->_call('initializeActionMethodArguments');
+       }
+
+       /**
+        * @test
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function initializeActionMethodArgumentsRegistersOptionalArgumentsAsSuch() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+
+               $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array(), array(), '', FALSE);
+               $mockArguments->expects($this->at(0))->method('addNewArgument')->with('arg1', 'string', TRUE);
+               $mockArguments->expects($this->at(1))->method('addNewArgument')->with('arg2', 'array', FALSE, array(21));
+               $mockArguments->expects($this->at(2))->method('addNewArgument')->with('arg3', 'string', FALSE, 42);
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('fooAction', 'evaluateDontValidateAnnotations'), array(), '', FALSE);
+
+               $methodParameters = array(
+                       'arg1' => array(
+                               'position' => 0,
+                               'byReference' => FALSE,
+                               'array' => FALSE,
+                               'optional' => FALSE,
+                               'allowsNull' => FALSE,
+                               'type' => 'string'
+                       ),
+                       'arg2' => array(
+                               'position' => 1,
+                               'byReference' => FALSE,
+                               'array' => TRUE,
+                               'optional' => TRUE,
+                               'defaultValue' => array(21),
+                               'allowsNull' => FALSE
+                       ),
+                       'arg3' => array(
+                               'position' => 2,
+                               'byReference' => FALSE,
+                               'array' => FALSE,
+                               'optional' => TRUE,
+                               'defaultValue' => 42,
+                               'allowsNull' => FALSE,
+                               'type' => 'string'
+                       )
+               );
+
+               $mockReflectionService = $this->getMock('Tx_Extbase_Reflection_Service', array(), array(), '', FALSE);
+               $mockReflectionService->expects($this->once())->method('getMethodParameters')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodParameters));
+
+               $mockController->injectReflectionService($mockReflectionService);
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('arguments', $mockArguments);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->_call('initializeActionMethodArguments');
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sbastian@typo3.org>
+        * @expectedException Tx_Extbase_MVC_Exception_InvalidArgumentType
+        */
+       public function initializeActionMethodArgumentsThrowsExceptionIfDataTypeWasNotSpecified() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+
+               $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array(), array(), '', FALSE);
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('fooAction'), array(), '', FALSE);
+
+               $methodParameters = array(
+                       'arg1' => array(
+                               'position' => 0,
+                               'byReference' => FALSE,
+                               'array' => FALSE,
+                               'optional' => FALSE,
+                               'allowsNull' => FALSE,
+                       )
+               );
+
+               $mockReflectionService = $this->getMock('Tx_Extbase_Reflection_Service', array(), array(), '', FALSE);
+               $mockReflectionService->expects($this->once())->method('getMethodParameters')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodParameters));
+
+               $mockController->injectReflectionService($mockReflectionService);
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('arguments', $mockArguments);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->_call('initializeActionMethodArguments');
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sbastian@typo3.org>
+        */
+       public function initializeActionMethodValidatorsCorrectlyRegistersValidatorsBasedOnDataType() {
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('fooAction'), array(), '', FALSE);
+
+               $argument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $argument->expects($this->any())->method('getName')->will($this->returnValue('arg1'));
+
+               $arguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('dummy'), array(), '', FALSE);
+               $arguments->addArgument($argument);
+
+               $methodTagsValues = array(
+
+               );
+
+               $methodArgumentsValidatorConjunctions = array();
+               $methodArgumentsValidatorConjunctions['arg1'] = $this->getMock('Tx_Extbase_Validation_Validator_ConjunctionValidator', array(), array(), '', FALSE);
+
+               $mockReflectionService = $this->getMock('Tx_Extbase_Reflection_Service', array(), array(), '', FALSE);
+               $mockReflectionService->expects($this->once())->method('getMethodTagsValues')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodTagsValues));
+
+               $mockValidatorResolver = $this->getMock('Tx_Extbase_Validation_ValidatorResolver', array(), array(), '', FALSE);
+               $mockValidatorResolver->expects($this->once())->method('buildMethodArgumentsValidatorConjunctions')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodArgumentsValidatorConjunctions));
+
+               $mockController->injectReflectionService($mockReflectionService);
+               $mockController->injectValidatorResolver($mockValidatorResolver);
+               $mockController->_set('arguments', $arguments);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->_call('initializeActionMethodValidators');
+
+               $this->assertEquals($methodArgumentsValidatorConjunctions['arg1'], $arguments['arg1']->getValidator());
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sbastian@typo3.org>
+        */
+       public function initializeActionMethodValidatorsRegistersModelBasedValidators() {
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('fooAction'), array(), '', FALSE);
+
+               $argument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getDataType'), array(), '', FALSE);
+               $argument->expects($this->any())->method('getName')->will($this->returnValue('arg1'));
+               $argument->expects($this->any())->method('getDataType')->will($this->returnValue('F3_Foo_Quux'));
+
+               $arguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('dummy'), array(), '', FALSE);
+               $arguments->addArgument($argument);
+
+               $methodTagsValues = array(
+
+               );
+
+               $quuxBaseValidatorConjunction = $this->getMock('Tx_Extbase_Validation_Validator_ConjunctionValidator', array(), array(), '', FALSE);
+
+               $methodArgumentsValidatorConjunctions = array();
+               $methodArgumentsValidatorConjunctions['arg1'] = $this->getMock('Tx_Extbase_Validation_Validator_ConjunctionValidator', array(), array(), '', FALSE);
+               $methodArgumentsValidatorConjunctions['arg1']->expects($this->once())->method('addValidator')->with($quuxBaseValidatorConjunction);
+
+               $mockReflectionService = $this->getMock('Tx_Extbase_Reflection_Service', array(), array(), '', FALSE);
+               $mockReflectionService->expects($this->once())->method('getMethodTagsValues')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodTagsValues));
+
+               $mockValidatorResolver = $this->getMock('Tx_Extbase_Validation_ValidatorResolver', array(), array(), '', FALSE);
+               $mockValidatorResolver->expects($this->once())->method('buildMethodArgumentsValidatorConjunctions')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodArgumentsValidatorConjunctions));
+               $mockValidatorResolver->expects($this->once())->method('getBaseValidatorConjunction')->with('F3_Foo_Quux')->will($this->returnValue($quuxBaseValidatorConjunction));
+
+               $mockController->injectReflectionService($mockReflectionService);
+               $mockController->injectValidatorResolver($mockValidatorResolver);
+               $mockController->_set('arguments', $arguments);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->_call('initializeActionMethodValidators');
+
+               $this->assertEquals($methodArgumentsValidatorConjunctions['arg1'], $arguments['arg1']->getValidator());
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sbastian@typo3.org>
+        */
+       public function initializeActionMethodValidatorsDoesNotRegisterModelBasedValidatorsIfDontValidateAnnotationIsSet() {
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('fooAction'), array(), '', FALSE);
+
+               $argument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getDataType'), array(), '', FALSE);
+               $argument->expects($this->any())->method('getName')->will($this->returnValue('arg1'));
+               $argument->expects($this->any())->method('getDataType')->will($this->returnValue('F3_Foo_Quux'));
+
+               $arguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('dummy'), array(), '', FALSE);
+               $arguments->addArgument($argument);
+
+               $methodTagsValues = array(
+                       'dontvalidate' => array(
+                               '$arg1'
+                       )
+               );
+
+               $methodArgumentsValidatorConjunctions = array();
+               $methodArgumentsValidatorConjunctions['arg1'] = $this->getMock('Tx_Extbase_Validation_Validator_ConjunctionValidator', array(), array(), '', FALSE);
+
+               $mockReflectionService = $this->getMock('Tx_Extbase_Reflection_Service', array(), array(), '', FALSE);
+               $mockReflectionService->expects($this->once())->method('getMethodTagsValues')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodTagsValues));
+
+               $mockValidatorResolver = $this->getMock('Tx_Extbase_Validation_ValidatorResolver', array(), array(), '', FALSE);
+               $mockValidatorResolver->expects($this->once())->method('buildMethodArgumentsValidatorConjunctions')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodArgumentsValidatorConjunctions));
+               $mockValidatorResolver->expects($this->any())->method('getBaseValidatorConjunction')->will($this->throwException(new Exception("This should not be called because the dontvalidate annotation is set.")));
+
+               $mockController->injectReflectionService($mockReflectionService);
+               $mockController->injectValidatorResolver($mockValidatorResolver);
+               $mockController->_set('arguments', $arguments);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->_call('initializeActionMethodValidators');
+
+               $this->assertEquals($methodArgumentsValidatorConjunctions['arg1'], $arguments['arg1']->getValidator());
+       }
+
+       /**
+        * @test
+        * @author Christopher Hlubek <hlubek@networkteam.com>
+        */
+       public function defaultErrorActionSetsArgumentMappingResultsErrorsInRequest() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface', array(), array(), '', FALSE);
+               $mockFlashMessages = $this->getMock('Tx_Extbase_MVC_Controller_FlashMessages', array(), array(), '', FALSE);
+
+               $mockError = $this->getMock('Tx_Extbase_Error_Error', array('getMessage'), array(), '', FALSE);
+               $mockArgumentsMappingResults = $this->getMock('Tx_Extbase_Property_MappingResults', array('getErrors', 'getWarnings'), array(), '', FALSE);
+               $mockArgumentsMappingResults->expects($this->atLeastOnce())->method('getErrors')->will($this->returnValue(array($mockError)));
+               $mockArgumentsMappingResults->expects($this->any())->method('getWarnings')->will($this->returnValue(array()));
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('pushFlashMessage'), array(), '', FALSE);
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('flashMessages', $mockFlashMessages);
+               $mockController->_set('argumentsMappingResults', $mockArgumentsMappingResults);
+
+               $mockRequest->expects($this->once())->method('setErrors')->with(array($mockError));
+
+               $mockController->_call('errorAction');
+       }
+
+       /**
+        * @test
+        * @author Christopher Hlubek <hlubek@networkteam.com>
+        */
+       public function defaultErrorActionCallsGetErrorFlashMessageAndPutsFlashMessage() {
+               $this->markTestIncomplete('To be implemented');
+       }
+
+        /**
+        * Data Provider for checkRequestHashDoesNotThrowExceptionInNormalOperations
+        */
+       public function checkRequestHashInNormalOperation() {
+               return array(
+                       // HMAC is verified
+                       array(TRUE),
+                       // HMAC not verified, but objects are directly fetched from persistence layer
+                       array(FALSE, FALSE, Tx_Extbase_MVC_Controller_Argument::ORIGIN_PERSISTENCE, Tx_Extbase_MVC_Controller_Argument::ORIGIN_PERSISTENCE),
+                       // HMAC not verified, objects new and modified, but dontverifyrequesthash-annotation set
+                       array(FALSE, TRUE, Tx_Extbase_MVC_Controller_Argument::ORIGIN_PERSISTENCE, Tx_Extbase_MVC_Controller_Argument::ORIGIN_PERSISTENCE_AND_MODIFIED, array('dontverifyrequesthash' => ''))
+               );
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @dataProvider checkRequestHashInNormalOperation
+        */
+       public function checkRequestHashDoesNotThrowExceptionInNormalOperations($hmacVerified, $reflectionServiceNeedsInitialization = FALSE, $argument1Origin = 3, $argument2Origin = 3, $methodTagsValues = array()) {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request', array('isHmacVerified'), array(), '', FALSE);
+               $mockRequest->expects($this->once())->method('isHmacVerified')->will($this->returnValue($hmacVerified));
+
+               $argument1 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getOrigin'), array(), '', FALSE);
+               $argument1->expects($this->any())->method('getOrigin')->will($this->returnValue($argument1Origin));
+               $argument2 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getOrigin'), array(), '', FALSE);
+               $argument2->expects($this->any())->method('getOrigin')->will($this->returnValue($argument2Origin));
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('dummy'), array(), '', FALSE);
+
+               $mockReflectionService = $this->getMock('Tx_Extbase_Reflection_Service', array('getMethodTagsValues'), array(), '', FALSE);
+               if ($reflectionServiceNeedsInitialization) {
+                       // Somehow this is needed, else I get "Mocked method does not exist."
+                       $mockReflectionService->expects($this->any())->method('getMethodTagsValues')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodTagsValues));
+               }
+               $mockController->_set('arguments', array($argument1, $argument2));
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->injectReflectionService($mockReflectionService);
+
+               $mockController->_call('checkRequestHash');
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_MVC_Exception_InvalidOrNoRequestHash
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       public function checkRequestHashThrowsExceptionIfNeeded() {
+               // $this->markTestIncomplete('To be implemented');
+               $hmacVerified = FALSE;
+               $argument1Origin = Tx_Extbase_MVC_Controller_Argument::ORIGIN_PERSISTENCE_AND_MODIFIED;
+               $argument2Origin = Tx_Extbase_MVC_Controller_Argument::ORIGIN_PERSISTENCE;
+               $methodTagsValues = array();
+
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request', array('isHmacVerified'), array(), '', FALSE);
+               $mockRequest->expects($this->once())->method('isHmacVerified')->will($this->returnValue($hmacVerified));
+
+               $argument1 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getOrigin'), array(), '', FALSE);
+               $argument1->expects($this->any())->method('getOrigin')->will($this->returnValue($argument1Origin));
+               $argument2 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getOrigin'), array(), '', FALSE);
+               $argument2->expects($this->any())->method('getOrigin')->will($this->returnValue($argument2Origin));
+
+               $mockController = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_ActionController'), array('dummy'), array(), '', FALSE);
+
+               $mockReflectionService = $this->getMock('Tx_Extbase_Reflection_Service', array('getMethodTagsValues'), array(), '', FALSE);
+               $mockReflectionService->expects($this->any())->method('getMethodTagsValues')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodTagsValues));
+
+               $mockController->_set('arguments', array($argument1, $argument2));
+               $mockController->_set('request', $mockRequest);
+               $mockController->_set('actionMethodName', 'fooAction');
+               $mockController->injectReflectionService($mockReflectionService);
+
+               $mockController->_call('checkRequestHash');
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/MVC/Controller/Argument_testcase.php b/typo3/sysext/extbase/Tests/Unit/MVC/Controller/Argument_testcase.php
new file mode 100644 (file)
index 0000000..800d4f4
--- /dev/null
@@ -0,0 +1,179 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_MVC_Controller_Argument_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        * @expectedException InvalidArgumentException
+        */
+       public function constructingArgumentWithoutNameThrowsException() {
+               new Tx_Extbase_MVC_Controller_Argument(NULL, 'Text');
+       }
+
+       /**
+        * @test
+        * @expectedException InvalidArgumentException
+        */
+       public function constructingArgumentWithInvalidNameThrowsException() {
+               new Tx_Extbase_MVC_Controller_Argument(new ArrayObject(), 'Text');
+       }
+
+       /**
+        * @test
+        */
+       public function passingDataTypeToConstructorReallySetsTheDataType() {
+               $argument = new Tx_Extbase_MVC_Controller_Argument('dummy', 'Number');
+               $this->assertEquals('Number', $argument->getDataType(), 'The specified data type has not been set correctly.');
+       }
+
+       /**
+        * @test
+        */
+       public function setShortNameProvidesFluentInterface() {
+               $argument = new Tx_Extbase_MVC_Controller_Argument('dummy', 'Text');
+               $returnedArgument = $argument->setShortName('x');
+               $this->assertSame($argument, $returnedArgument, 'The returned argument is not the original argument.');
+       }
+
+       /**
+        * @test
+        */
+       public function setValueProvidesFluentInterface() {
+               $argument = new Tx_Extbase_MVC_Controller_Argument('dummy', 'Text');
+               $returnedArgument = $argument->setValue('x');
+               $this->assertSame($argument, $returnedArgument, 'The returned argument is not the original argument.');
+       }
+
+       /**
+        * @test
+        */
+       public function setValueTriesToConvertAnUidIntoTheRealObjectIfTheDataTypeClassSchemaIsSet() {
+               $object = new StdClass();
+
+               $argument = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_Argument'), array('findObjectByUid'), array(), '', FALSE);
+               $argument->expects($this->once())->method('findObjectByUid')->with('42')->will($this->returnValue($object));
+               $argument->_set('dataTypeClassSchema', 'stdClass');
+               $argument->_set('dataType', 'stdClass');
+               // $argument->_set('queryFactory', $mockQueryFactory);
+               $argument->setValue('42');
+
+               $this->assertSame($object, $argument->_get('value'));
+               $this->assertSame(Tx_Extbase_MVC_Controller_Argument::ORIGIN_PERSISTENCE, $argument->getOrigin());
+       }
+
+
+       /**
+        * @test
+        */
+       public function toStringReturnsTheStringVersionOfTheArgumentsValue() {
+               $argument = new Tx_Extbase_MVC_Controller_Argument('dummy', 'Text');
+               $argument->setValue(123);
+
+               $this->assertSame((string)$argument, '123', 'The returned argument is not a string.');
+               $this->assertNotSame((string)$argument, 123, 'The returned argument is identical to the set value.');
+       }
+
+       /**
+        * @test
+        */
+       public function dataTypeValidatorCanBeAFullClassName() {
+               $this->markTestIncomplete();
+
+               $this->mockObjectManager->expects($this->once())->method('isObjectRegistered')->with('Tx_Extbase_Validation_Validator_TextValidator')->will($this->returnValue(TRUE));
+               $this->mockObjectManager->expects($this->any())->method('get')->with('Tx_Extbase_Validation_Validator_TextValidator')->will($this->returnValue($this->getMock('Tx_Extbase_Validation_Validator_TextValidator')));
+
+               $argument = new Tx_Extbase_MVC_Controller_Argument('SomeArgument', 'Tx_Extbase_Validation_Validator_TextValidator');
+               $argument->injectObjectManager($this->mockObjectManager);
+
+               $this->assertType('Tx_Extbase_Validation_Validator_TextValidator', $argument->getDatatypeValidator(), 'The returned datatype validator is not a text validator as expected.');
+       }
+
+       /**
+        * @test
+        */
+       public function dataTypeValidatorCanBeAShortName() {
+               $this->markTestIncomplete();
+
+               $this->mockObjectManager->expects($this->once())->method('isObjectRegistered')->with('Tx_Extbase_Validation_Validator_TextValidator')->will($this->returnValue(TRUE));
+               $this->mockObjectManager->expects($this->any())->method('get')->with('Tx_Extbase_Validation_Validator_TextValidator')->will($this->returnValue($this->getMock('Tx_Extbase_Validation_Validator_TextValidator')));
+
+               $argument = new Tx_Extbase_MVC_Controller_Argument('SomeArgument', 'Text');
+               $argument->injectObjectManager($this->mockObjectManager);
+
+               $this->assertType('Tx_Extbase_Validation_Validator_TextValidator', $argument->getDatatypeValidator(), 'The returned datatype validator is not a text validator as expected.');
+       }
+
+       /**
+        * @test
+        */
+       public function setNewValidatorConjunctionCreatesANewValidatorConjunctionObject() {
+               $argument = new Tx_Extbase_MVC_Controller_Argument('dummy', 'Text');
+               $argument->setNewValidatorConjunction(array());
+
+               $this->assertType('Tx_Extbase_Validation_Validator_ConjunctionValidator', $argument->getValidator(), 'The returned validator is not a conjunction as expected.');
+       }
+
+       /**
+        * @test
+        */
+       public function setNewValidatorConjunctionAddsThePassedValidatorsToTheCreatedValidatorChain() {
+               eval('class Validator1 implements Tx_Extbase_Validation_Validator_ValidatorInterface {
+                       public function isValid($value) {}
+                       public function setOptions(array $validationOptions) {}
+                       public function getErrors() {}
+               }');
+               eval('class Validator2 implements Tx_Extbase_Validation_Validator_ValidatorInterface {
+                       public function isValid($value) {}
+                       public function setOptions(array $validationOptions) {}
+                       public function getErrors() {}
+               }');
+
+               $validator1 = new Validator1;
+               $validator2 = new Validator2;
+
+               $mockValidatorConjunction = $this->getMock('Tx_Extbase_Validation_Validator_ConjunctionValidator');
+               $mockValidatorConjunction->expects($this->at(0))->method('addValidator')->with($validator1);
+               $mockValidatorConjunction->expects($this->at(1))->method('addValidator')->with($validator2);
+
+               $argument = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_Argument'), array('dummy'), array(), '', FALSE);
+               $argument->_set('validator', $mockValidatorConjunction);
+               $argument->setNewValidatorConjunction(array('Validator1', 'Validator2'));
+       }
+
+       /**
+        * @test
+        */
+       public function settingDefaultValueReallySetsDefaultValue() {
+               $argument = new Tx_Extbase_MVC_Controller_Argument('dummy', 'Text');
+               $argument->setDefaultValue(42);
+
+               $this->assertEquals(42, $argument->getValue(), 'The default value was not stored in the Argument.');
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/MVC/Controller/Arguments_testcase.php b/typo3/sysext/extbase/Tests/Unit/MVC/Controller/Arguments_testcase.php
new file mode 100644 (file)
index 0000000..183da77
--- /dev/null
@@ -0,0 +1,252 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_MVC_Controller_Arguments_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function argumentsObjectIsOfScopePrototype() {
+               $arguments1 = $this->objectManager->get('Tx_Extbase_MVC_Controller_Arguments');
+               $arguments2 = $this->objectManager->get('Tx_Extbase_MVC_Controller_Arguments');
+               $this->assertNotSame($arguments1, $arguments2, 'The arguments object is not of scope prototype!');
+       }
+
+       /**
+        * @test
+        */
+       public function addingAnArgumentManuallyWorks() {
+               $arguments = $this->objectManager->get('Tx_Extbase_MVC_Controller_Arguments');
+               $newArgument = $this->objectManager->get('Tx_Extbase_MVC_Controller_Argument', 'argumentName1234', 'dummyValue');
+
+               $arguments->addArgument($newArgument);
+               $this->assertSame($newArgument, $arguments->getArgument('argumentName1234'), 'The added and retrieved argument is not the same.');
+       }
+
+       /**
+        * @test
+        */
+       public function addingAnArgumentReplacesArgumentWithSameName() {
+               $arguments = new Tx_Extbase_MVC_Controller_Arguments;
+
+               $mockFirstArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $mockFirstArgument->expects($this->any())->method('getName')->will($this->returnValue('argumentName1234'));
+               $arguments->addArgument($mockFirstArgument);
+
+               $mockSecondArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $mockSecondArgument->expects($this->any())->method('getName')->will($this->returnValue('argumentName1234'));
+               $arguments->addArgument($mockSecondArgument);
+
+               $this->assertSame($mockSecondArgument, $arguments->getArgument('argumentName1234'), 'The added and retrieved argument is not the same.');
+       }
+
+       /**
+        * @test
+        */
+       public function addNewArgumentProvidesFluentInterface() {
+               $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array(), '', FALSE);
+               $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('createArgument'));
+               $mockArguments->expects($this->any())->method('createArgument')->will($this->returnValue($mockArgument));
+
+               $newArgument = $mockArguments->addNewArgument('someArgument');
+               $this->assertType('Tx_Extbase_MVC_Controller_Argument', $newArgument, 'addNewArgument() did not return an argument object.');
+       }
+
+       /**
+        * @test
+        */
+       public function addingArgumentThroughArrayAccessWorks() {
+               $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('argumentName1234'));
+               $arguments = new Tx_Extbase_MVC_Controller_Arguments;
+
+               $arguments[] = $mockArgument;
+               $this->assertTrue($arguments->hasArgument('argumentName1234'), 'Added argument does not exist.');
+               $this->assertSame($mockArgument, $arguments->getArgument('argumentName1234'), 'Added and retrieved arguments are not the same.');
+       }
+
+       /**
+        * @test
+        */
+       public function retrievingArgumentThroughArrayAccessWorks() {
+               $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('argumentName1234'));
+               $arguments = new Tx_Extbase_MVC_Controller_Arguments;
+
+               $arguments[] = $mockArgument;
+               $this->assertSame($mockArgument, $arguments['argumentName1234'], 'Argument retrieved by array access is not the one we added.');
+       }
+
+       /**
+        * @test
+        */
+       public function getArgumentWithNonExistingArgumentNameThrowsException() {
+               $arguments = $this->objectManager->get('Tx_Extbase_MVC_Controller_Arguments');
+               try {
+                       $arguments->getArgument('someArgument');
+                       $this->fail('getArgument() did not throw an exception although the specified argument does not exist.');
+               } catch (Tx_Extbase_MVC_Exception_NoSuchArgument $exception) {
+               }
+       }
+
+       /**
+        * @test
+        */
+       public function issetReturnsCorrectResult() {
+               $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('argumentName1234'));
+               $arguments = new Tx_Extbase_MVC_Controller_Arguments;
+
+               $this->assertFalse(isset($arguments['argumentName1234']), 'isset() did not return FALSE.');
+               $arguments[] = $mockArgument;
+               $this->assertTrue(isset($arguments['argumentName1234']), 'isset() did not return TRUE.');
+       }
+
+       /**
+        * @test
+        */
+       public function getArgumentNamesReturnsNamesOfAddedArguments() {
+               $mockArgument1 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $mockArgument1->expects($this->any())->method('getName')->will($this->returnValue('argumentName1'));
+               $mockArgument2 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $mockArgument2->expects($this->any())->method('getName')->will($this->returnValue('argumentName2'));
+               $mockArgument3 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $mockArgument3->expects($this->any())->method('getName')->will($this->returnValue('argumentName3'));
+               $arguments = new Tx_Extbase_MVC_Controller_Arguments;
+               $arguments[] = $mockArgument1;
+               $arguments[] = $mockArgument2;
+               $arguments[] = $mockArgument3;
+
+               $expectedArgumentNames = array('argumentName1', 'argumentName2', 'argumentName3');
+               $this->assertEquals($expectedArgumentNames, $arguments->getArgumentNames(), 'Returned argument names were not as expected.');
+       }
+
+       /**
+        * @test
+        */
+       public function getArgumentShortNamesReturnsShortNamesOfAddedArguments() {
+               $mockArgument1 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getShortName'), array(), '', FALSE);
+               $mockArgument1->expects($this->any())->method('getName')->will($this->returnValue('argumentName1'));
+               $mockArgument1->expects($this->any())->method('getShortName')->will($this->returnValue('a'));
+               $mockArgument2 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getShortName'), array(), '', FALSE);
+               $mockArgument2->expects($this->any())->method('getName')->will($this->returnValue('argumentName2'));
+               $mockArgument2->expects($this->any())->method('getShortName')->will($this->returnValue('b'));
+               $mockArgument3 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getShortName'), array(), '', FALSE);
+               $mockArgument3->expects($this->any())->method('getName')->will($this->returnValue('argumentName3'));
+               $mockArgument3->expects($this->any())->method('getShortName')->will($this->returnValue('c'));
+               $arguments = new Tx_Extbase_MVC_Controller_Arguments;
+               $arguments[] = $mockArgument1;
+               $arguments[] = $mockArgument2;
+               $arguments[] = $mockArgument3;
+
+               $expectedShortNames = array('a', 'b', 'c');
+               $this->assertEquals($expectedShortNames, $arguments->getArgumentShortNames(), 'Returned argument short names were not as expected.');
+       }
+
+       /**
+        * @test
+        */
+       public function addNewArgumentCreatesAndAddsNewArgument() {
+               $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('dummyName'));
+               $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('createArgument'));
+               $mockArguments->expects($this->any())->method('createArgument')->with($this->equalTo('dummyName'))->will($this->returnValue($mockArgument));
+
+               $addedArgument = $mockArguments->addNewArgument('dummyName');
+               $this->assertType('Tx_Extbase_MVC_Controller_Argument', $addedArgument, 'addNewArgument() either did not add a new argument or did not return it.');
+
+               $retrievedArgument = $mockArguments['dummyName'];
+               $this->assertSame($addedArgument, $retrievedArgument, 'The added and the retrieved argument are not the same.');
+       }
+
+       /**
+        * @test
+        */
+       public function addNewArgumentAssumesTextDataTypeByDefault() {
+               $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE);
+               $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('dummyName'));
+               $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('createArgument'));
+               $mockArguments->expects($this->any())->method('createArgument')->with($this->equalTo('dummyName'), $this->equalTo('Text'))->will($this->returnValue($mockArgument));
+
+               $addedArgument = $mockArguments->addNewArgument('dummyName');
+       }
+
+       /**
+        * @test
+        */
+       public function addNewArgumentCanAddArgumentsMarkedAsRequired() {
+               $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'setRequired'), array(), '', FALSE);
+               $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('dummyName'));
+               $mockArgument->expects($this->any())->method('setRequired')->with(TRUE);
+               $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('createArgument'));
+               $mockArguments->expects($this->any())->method('createArgument')->with($this->equalTo('dummyName'), $this->equalTo('Text'))->will($this->returnValue($mockArgument));
+
+               $addedArgument = $mockArguments->addNewArgument('dummyName', 'Text', TRUE);
+       }
+
+       /**
+        * @test
+        */
+       public function addNewArgumentCanAddArgumentsMarkedAsOptionalWithDefaultValues() {
+               $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'setRequired'), array(), '', FALSE);
+               $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('dummyName'));
+               $mockArgument->expects($this->any())->method('setRequired')->with(TRUE);
+               $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('createArgument'));
+               $mockArguments->expects($this->any())->method('createArgument')->with($this->equalTo('dummyName'), $this->equalTo('Text'))->will($this->returnValue($mockArgument));
+
+               $addedArgument = $mockArguments->addNewArgument('dummyName', 'Text', TRUE);
+       }
+
+       /**
+        * @test
+        * @expectedException LogicException
+        * @author Bastian Waidelich <bastian@typo3.org>
+        */
+       public function callingInvalidMethodThrowsException() {
+               $arguments = $this->objectManager->get('Tx_Extbase_MVC_Controller_Arguments');
+               $arguments->nonExistingMethod();
+       }
+
+       /**
+        * @test
+        * @author Christopher Hlubek <hlubek@networkteam.com>
+        */
+       public function removeAllClearsAllArguments() {
+               $mockArgument1 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getShortName'), array(), '', FALSE);
+               $mockArgument1->expects($this->any())->method('getName')->will($this->returnValue('argumentName1'));
+               $mockArgument2 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getShortName'), array(), '', FALSE);
+               $mockArgument2->expects($this->any())->method('getName')->will($this->returnValue('argumentName2'));
+               $arguments = new Tx_Extbase_MVC_Controller_Arguments;
+               $arguments[] = $mockArgument1;
+               $arguments[] = $mockArgument2;
+
+               $this->assertTrue($arguments->hasArgument('argumentName2'));
+               $arguments->removeAll();
+               $this->assertFalse($arguments->hasArgument('argumentName2'));
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/MVC/DispatcherTest.php b/typo3/sysext/extbase/Tests/Unit/MVC/DispatcherTest.php
new file mode 100644 (file)
index 0000000..17cbe88
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the MVC Dispatcher
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_Extbase_MVC_DispatcherTest extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function dispatchCallsTheControllersProcessRequestMethodUntilTheIsDispatchedFlagInTheRequestObjectIsSet() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface');
+               $mockRequest->expects($this->at(0))->method('isDispatched')->will($this->returnValue(FALSE));
+               $mockRequest->expects($this->at(1))->method('isDispatched')->will($this->returnValue(FALSE));
+               $mockRequest->expects($this->at(2))->method('isDispatched')->will($this->returnValue(TRUE));
+
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_ResponseInterface');
+
+               $mockController = $this->getMock('Tx_Extbase_MVC_Controller_ControllerInterface', array('processRequest', 'canProcessRequest'));
+               $mockController->expects($this->exactly(2))->method('processRequest')->with($mockRequest, $mockResponse);
+
+               $dispatcher = $this->getMock('Tx_Extbase_MVC_Dispatcher', array('resolveController'), array(), '', FALSE);
+               $dispatcher->expects($this->any())->method('resolveController')->will($this->returnValue($mockController));
+               $dispatcher->dispatch($mockRequest, $mockResponse);
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_MVC_Exception_InfiniteLoop
+        */
+       public function dispatchThrowsAnInfiniteLoopExceptionIfTheRequestCouldNotBeDispachedAfter99Iterations() {
+               $requestCallCounter = 0;
+               /*
+               $requestCallBack = function() use (&$requestCallCounter) {
+                       return ($requestCallCounter++ < 101) ? FALSE : TRUE;
+               };
+                */
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_RequestInterface');
+               $mockRequest->expects($this->any())->method('isDispatched')->will($this->returnCallBack($requestCallBack, '__invoke'));
+
+               $mockResponse = $this->getMock('Tx_Extbase_MVC_ResponseInterface');
+               $mockController = $this->getMock('Tx_Extbase_MVC_Controller_ControllerInterface', array('processRequest', 'canProcessRequest'));
+
+               $dispatcher = $this->getMock('Tx_Extbase_MVC_Dispatcher', array('resolveController'), array(), '', FALSE);
+               $dispatcher->expects($this->any())->method('resolveController')->will($this->returnValue($mockController));
+               $dispatcher->dispatch($mockRequest, $mockResponse);
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/MVC/Web/RequestBuilder_testcase.php b/typo3/sysext/extbase/Tests/Unit/MVC/Web/RequestBuilder_testcase.php
new file mode 100644 (file)
index 0000000..e2bd28c
--- /dev/null
@@ -0,0 +1,202 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_MVC_Web_RequestBuilder_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @var array
+        */
+       protected $getBackup = array();
+
+       /**
+        * @var array
+        */
+       protected $postBackup = array();
+
+       public function __construct() {
+               require_once(t3lib_extMgm::extPath('extbase', 'Classes/MVC/Web/RequestBuilder.php'));
+       }
+
+       public function setUp() {
+               $this->configuration = array(
+                       'userFunc' => 'Tx_Extbase_Dispatcher->dispatch',
+                       'pluginName' => 'Pi1',
+                       'extensionName' => 'MyExtension',
+                       'controller' => 'TheFirstController',
+                       'action' => 'show',
+                       'switchableControllerActions' => array(
+                               'TheFirstController' => array(
+                                       'controller' => 'TheFirstController',
+                                       'actions' => 'show,index, ,new,create,delete,edit,update,setup,test'
+                               ),
+                               'TheSecondController' => array(
+                                       'controller' => 'TheSecondController',
+                                       'actions' => 'show, index'
+                               ),
+                               'TheThirdController' => array(
+                                       'controller' => 'TheThirdController',
+                                       'actions' => 'delete,create'
+                               )
+                       )
+               );
+               $this->builder = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_RequestBuilder'), array('dummy'));
+               $this->getBackup = $_GET;
+               $this->postBackup = $_POST;
+       }
+
+       public function tearDown() {
+               $_GET = $this->getBackup;
+               $_POST = $this->postBackup;
+       }
+
+       /**
+        * @test
+        */
+       public function buildReturnsAWebRequestObject() {
+               $this->builder->initialize($this->configuration);
+               $request = $this->builder->build();
+               $this->assertEquals('Tx_Extbase_MVC_Web_Request', get_class($request));
+               $this->assertEquals('Pi1', $request->getPluginName());
+               $this->assertEquals('MyExtension', $request->getControllerExtensionName());
+               $this->assertEquals('TheFirstController', $request->getControllerName());
+               $this->assertEquals('show', $request->getControllerActionName());
+       }
+
+       /**
+        * @test
+        */
+       public function buildWithoutConfigurationReturnsAWebRequestObjectWithDefaultSettings() {
+               $request = $this->builder->build();
+               $this->assertEquals('plugin', $request->getPluginName());
+               $this->assertEquals('Extbase', $request->getControllerExtensionName());
+               $this->assertEquals('Standard', $request->getControllerName());
+               $this->assertEquals('index', $request->getControllerActionName());
+       }
+
+       /**
+        * @test
+        */
+       public function buildWithMissingControllerConfigurationsReturnsAWebRequestObjectWithDefaultControllerSettings() {
+               $configuration = $this->configuration;
+               unset($configuration['controller']);
+               unset($configuration['action']);
+               unset($configuration['switchableControllerActions']);
+               $this->builder->initialize($configuration);
+               $request = $this->builder->build();
+               $this->assertEquals('Pi1', $request->getPluginName());
+               $this->assertEquals('MyExtension', $request->getControllerExtensionName());
+               $this->assertEquals('Standard', $request->getControllerName());
+               $this->assertEquals('index', $request->getControllerActionName());
+       }
+
+       /**
+        * @test
+        */
+       public function buildWithMissingActionsReturnsAWebRequestObjectWithDefaultControllerSettings() {
+               $configuration = $this->configuration;
+               unset($configuration['action']);
+               unset($configuration['switchableControllerActions']);
+               $this->builder->initialize($configuration);
+               $request = $this->builder->build();
+               $this->assertEquals('Pi1', $request->getPluginName());
+               $this->assertEquals('MyExtension', $request->getControllerExtensionName());
+               $this->assertEquals('TheFirstController', $request->getControllerName());
+               $this->assertEquals('index', $request->getControllerActionName());
+       }
+
+       /**
+        * @test
+        */
+       public function buildSetsTheRequestURIInTheRequestObject() {
+               $this->builder->initialize($this->configuration);
+               $request = $this->builder->build();
+               $this->assertEquals(t3lib_div::getIndpEnv('TYPO3_REQUEST_URL'), $request->getRequestURI());
+       }
+
+       /**
+        * @test
+        */
+       public function buildSetsParametersFromGetAndPostVariables() {
+               $this->builder->_set('extensionName', 'someExtensionName');
+               $this->builder->_set('pluginName', 'somePluginName');
+
+               $_GET = array(
+                       'tx_someotherextensionname_somepluginname' => array(
+                               'foo' => 'bar'
+                       ),
+                       'tx_someextensionname_somepluginname' => array(
+                               'parameter1' => 'valueGetsOverwritten',
+                               'parameter2' => array(
+                                       'parameter3' => 'value3'
+                               )
+                       )
+               );
+               $_POST = array(
+                       'tx_someextensionname_someotherpluginname' => array(
+                               'foo' => 'bar'
+                       ),
+                       'tx_someextensionname_somepluginname' => array(
+                               'parameter1' => 'value1',
+                               'parameter2' => array(
+                                       'parameter4' => 'value4'
+                               )
+                       )
+               );
+
+               $request = $this->builder->build();
+               $expectedResult = array(
+                       'parameter1' => 'value1',
+                       'parameter2' => array(
+                               'parameter3' => 'value3',
+                               'parameter4' => 'value4',
+                       ),
+               );
+               $actualResult = $request->getArguments();
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function initializeCorrectlySetsAllowedControllerActions() {
+               $this->builder->initialize($this->configuration);
+               $expectedResult = array(
+                       'TheFirstController' => array(
+                               'show', 'index', 'new', 'create', 'delete', 'edit', 'update', 'setup', 'test'
+                       ),
+                       'TheSecondController' => array(
+                               'show', 'index'
+                       ),
+                       'TheThirdController' => array(
+                               'delete', 'create'
+                       )
+               );
+               $actualResult = $this->builder->_get('allowedControllerActions');
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/MVC/Web/RequestTest.php b/typo3/sysext/extbase/Tests/Unit/MVC/Web/RequestTest.php
new file mode 100644 (file)
index 0000000..83da048
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Sebastian Kurfuerst <sebastian@typo3.org>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_MVC_Web_RequestTest extends Tx_Extbase_Tests_Unit_BaseTestCase {
+       /**
+        * @test
+        */
+       public function isCachedReturnsFalseByDefault() {
+               $request = new Tx_Extbase_MVC_Web_Request();
+               $this->assertFalse($request->isCached());
+       }
+
+       /**
+        * @test
+        */
+       public function isCachedReturnsTheValueWhichWasPreviouslySet() {
+               $request = new Tx_Extbase_MVC_Web_Request();
+               $request->setIsCached(TRUE);
+               $this->assertTrue($request->isCached());
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/MVC/Web/Routing/UriBuilder_testcase.php b/typo3/sysext/extbase/Tests/Unit/MVC/Web/Routing/UriBuilder_testcase.php
new file mode 100644 (file)
index 0000000..3ef3524
--- /dev/null
@@ -0,0 +1,576 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+require_once (t3lib_extMgm::extPath('extbase') . 'Tests/Unit/Fixtures/Entity.php');
+
+class Tx_Extbase_MVC_Web_Routing_UriBuilder_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @var tslib_fe
+        */
+       protected $tsfeBackup;
+
+       /**
+        * @var array
+        */
+       protected $getBackup;
+
+       /**
+        * @var tslib_cObj
+        */
+       protected $contentObject;
+
+       /**
+        * @var Tx_Extbase_MVC_Web_Request
+        */
+       protected $request;
+
+       /**
+        * @var Tx_Extbase_MVC_Web_Routing_UriBuilder
+        */
+       protected $uriBuilder;
+
+       public function setUp() {
+               $this->tsfeBackup = $GLOBALS['TSFE'];
+               $GLOBALS['TSFE'] = $this->getMock('tslib_fe', array(), array(), '', FALSE);
+
+               $this->getBackup = t3lib_div::_GET();
+
+               $this->contentObject = $this->getMock('tslib_cObj');
+               $this->request = $this->getMock('Tx_Extbase_MVC_Web_Request');
+
+               $this->uriBuilder = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Routing_UriBuilder'), array('dummy'), array($this->contentObject));
+               $this->uriBuilder->setRequest($this->request);
+       }
+
+       public function tearDown() {
+               $GLOBALS['TSFE'] = $this->tsfeBackup;
+               t3lib_div::_GETset($this->getBackup);
+       }
+
+       /**
+        * @test
+        */
+       public function settersAndGettersWorkAsExpected() {
+               $this->uriBuilder
+                       ->reset()
+                       ->setArguments(array('test' => 'arguments'))
+                       ->setSection('testSection')
+                       ->setFormat('testFormat')
+                       ->setCreateAbsoluteUri(TRUE)
+                       ->setAddQueryString(TRUE)
+                       ->setArgumentsToBeExcludedFromQueryString(array('test' => 'addQueryStringExcludeArguments'))
+                       ->setLinkAccessRestrictedPages(TRUE)
+                       ->setTargetPageUid(123)
+                       ->setTargetPageType(321)
+                       ->setNoCache(TRUE)
+                       ->setUseCacheHash(FALSE);
+
+               $this->assertEquals(array('test' => 'arguments'), $this->uriBuilder->getArguments());
+               $this->assertEquals('testSection', $this->uriBuilder->getSection());
+               $this->assertEquals('testFormat', $this->uriBuilder->getFormat());
+               $this->assertEquals(TRUE, $this->uriBuilder->getCreateAbsoluteUri());
+               $this->assertEquals(TRUE, $this->uriBuilder->getAddQueryString());
+               $this->assertEquals(array('test' => 'addQueryStringExcludeArguments'), $this->uriBuilder->getArgumentsToBeExcludedFromQueryString());
+               $this->assertEquals(TRUE, $this->uriBuilder->getLinkAccessRestrictedPages());
+               $this->assertEquals(123, $this->uriBuilder->getTargetPageUid());
+               $this->assertEquals(321, $this->uriBuilder->getTargetPageType());
+               $this->assertEquals(TRUE, $this->uriBuilder->getNoCache());
+               $this->assertEquals(FALSE, $this->uriBuilder->getUseCacheHash());
+       }
+
+       /**
+        * @test
+        */
+       public function uriForPrefixesArgumentsWithExtensionAndPluginNameAndSetsControllerArgument() {
+               $expectedArguments = array('tx_someextension_someplugin' => array('foo' => 'bar', 'baz' => array('extbase' => 'fluid'), 'controller' => 'SomeController'));
+
+               $this->uriBuilder->uriFor(NULL, array('foo' => 'bar', 'baz' => array('extbase' => 'fluid')), 'SomeController', 'SomeExtension', 'SomePlugin');
+               $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
+       }
+
+       /**
+        * @test
+        */
+       public function uriForRecursivelyMergesAndOverrulesControllerArgumentsWithArguments() {
+               $arguments = array('tx_someextension_someplugin' => array('foo' => 'bar'), 'additionalParam' => 'additionalValue');
+               $controllerArguments = array('foo' => 'overruled', 'baz' => array('extbase' => 'fluid'));
+               $expectedArguments = array('tx_someextension_someplugin' => array('foo' => 'overruled', 'baz' => array('extbase' => 'fluid'), 'controller' => 'SomeController'), 'additionalParam' => 'additionalValue');
+
+               $this->uriBuilder->setArguments($arguments);
+               $this->uriBuilder->uriFor(NULL, $controllerArguments, 'SomeController', 'SomeExtension', 'SomePlugin');
+               $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
+       }
+
+       /**
+        * @test
+        */
+       public function uriForOnlySetsActionArgumentIfSpecified() {
+               $expectedArguments = array('tx_someextension_someplugin' => array('controller' => 'SomeController'));
+
+               $this->uriBuilder->uriFor(NULL, array(), 'SomeController', 'SomeExtension', 'SomePlugin');
+               $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
+       }
+
+       /**
+        * @test
+        */
+       public function uriForSetsControllerFromRequestIfControllerIsNotSet() {
+               $this->request->expects($this->once())->method('getControllerName')->will($this->returnValue('SomeControllerFromRequest'));
+
+               $expectedArguments = array('tx_someextension_someplugin' => array('controller' => 'SomeControllerFromRequest'));
+
+               $this->uriBuilder->uriFor(NULL, array(), NULL, 'SomeExtension', 'SomePlugin');
+               $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
+       }
+
+       /**
+        * @test
+        */
+       public function uriForSetsExtensionNameFromRequestIfExtensionNameIsNotSet() {
+               $this->request->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('SomeExtensionNameFromRequest'));
+
+               $expectedArguments = array('tx_someextensionnamefromrequest_someplugin' => array('controller' => 'SomeController'));
+
+               $this->uriBuilder->uriFor(NULL, array(), 'SomeController', NULL, 'SomePlugin');
+               $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
+       }
+
+       /**
+        * @test
+        */
+       public function uriForSetsPluginNameFromRequestIfPluginNameIsNotSet() {
+               $this->request->expects($this->once())->method('getPluginName')->will($this->returnValue('SomePluginNameFromRequest'));
+
+               $expectedArguments = array('tx_someextension_somepluginnamefromrequest' => array('controller' => 'SomeController'));
+
+               $this->uriBuilder->uriFor(NULL, array(), 'SomeController', 'SomeExtension');
+               $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
+       }
+
+       /**
+        * @test
+        */
+       public function buildBackendUriKeepsQueryParametersIfAddQueryStringIsSet() {
+               t3lib_div::_GETset(array('M' => 'moduleKey', 'id' => 'pageId', 'foo' => 'bar'));
+
+               $this->uriBuilder->setAddQueryString(TRUE);
+
+               $expectedResult = 'mod.php?M=moduleKey&id=pageId&foo=bar';
+               $actualResult = $this->uriBuilder->buildBackendUri();
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function buildBackendUriRemovesSpecifiedQueryParametersIfArgumentsToBeExcludedFromQueryStringIsSet() {
+               t3lib_div::_GETset(array('M' => 'moduleKey', 'id' => 'pageId', 'foo' => 'bar'));
+
+               $this->uriBuilder->setAddQueryString(TRUE);
+               $this->uriBuilder->setArgumentsToBeExcludedFromQueryString(array('M', 'id'));
+
+               $expectedResult = 'mod.php?foo=bar';
+               $actualResult = $this->uriBuilder->buildBackendUri();
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function buildBackendUriKeepsModuleQueryParametersIfAddQueryStringIsNotSet() {
+               t3lib_div::_GETset(array('M' => 'moduleKey', 'id' => 'pageId', 'foo' => 'bar'));
+
+               $expectedResult = 'mod.php?M=moduleKey&id=pageId';
+               $actualResult = $this->uriBuilder->buildBackendUri();
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function buildBackendUriMergesAndOverrulesQueryParametersWithArguments() {
+               t3lib_div::_GETset(array('M' => 'moduleKey', 'id' => 'pageId', 'foo' => 'bar'));
+
+               $this->uriBuilder->setArguments(array('M' => 'overwrittenModuleKey', 'somePrefix' => array('bar' => 'baz')));
+
+               $expectedResult = 'mod.php?M=overwrittenModuleKey&id=pageId&somePrefix%5Bbar%5D=baz';
+               $actualResult = $this->uriBuilder->buildBackendUri();
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function buildBackendUriConvertsDomainObjectsAfterArgumentsHaveBeenMerged() {
+               t3lib_div::_GETset(array('M' => 'moduleKey'));
+
+               $mockDomainObject = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_DomainObject_AbstractEntity'), array('dummy'));
+               $mockDomainObject->_set('uid', '123');
+
+               $this->uriBuilder->setArguments(array('somePrefix' => array('someDomainObject' => $mockDomainObject)));
+
+               $expectedResult = 'mod.php?M=moduleKey&somePrefix%5BsomeDomainObject%5D=123';
+               $actualResult = $this->uriBuilder->buildBackendUri();
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function buildBackendUriRespectsSection() {
+               t3lib_div::_GETset(array('M' => 'moduleKey'));
+
+               $this->uriBuilder->setSection('someSection');
+
+               $expectedResult = 'mod.php?M=moduleKey#someSection';
+               $actualResult = $this->uriBuilder->buildBackendUri();
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function buildBackendUriCreatesAbsoluteUrisIfSpecified() {
+               t3lib_div::_GETset(array('M' => 'moduleKey'));
+
+               $this->request->expects($this->any())->method('getBaseURI')->will($this->returnValue('http://baseuri/' . TYPO3_mainDir));
+               $this->uriBuilder->setCreateAbsoluteUri(TRUE);
+
+               $expectedResult = 'http://baseuri/' . TYPO3_mainDir . 'mod.php?M=moduleKey';
+               $actualResult = $this->uriBuilder->buildBackendUri();
+               $this->assertSame($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function buildFrontendUriCreatesTypoLink() {
+               $uriBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_UriBuilder', array('buildTypolinkConfiguration'), array($this->contentObject));
+               $uriBuilder->expects($this->once())->method('buildTypolinkConfiguration')->will($this->returnValue(array('someTypoLinkConfiguration')));
+
+               $this->contentObject->expects($this->once())->method('typoLink_URL')->with(array('someTypoLinkConfiguration'));
+
+               $uriBuilder->buildFrontendUri();
+       }
+
+       /**
+        * @test
+        */
+       public function buildFrontendUriCreatesRelativeUrisByDefault() {
+               $this->contentObject->expects($this->once())->method('typoLink_URL')->will($this->returnValue('relative/uri'));
+
+               $expectedResult = 'relative/uri';
+               $actualResult = $this->uriBuilder->buildFrontendUri();
+
+               $this->assertSame($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function buildFrontendUriDoesNotStripLeadingSlashesFromRelativeUris() {
+               $this->contentObject->expects($this->once())->method('typoLink_URL')->will($this->returnValue('/relative/uri'));
+
+               $expectedResult = '/relative/uri';
+               $actualResult = $this->uriBuilder->buildFrontendUri();
+
+               $this->assertSame($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function buildFrontendUriCreatesAbsoluteUrisIfSpecified() {
+               $uriBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_UriBuilder', array('buildTypolinkConfiguration'), array($this->contentObject));
+               $uriBuilder->expects($this->once())->method('buildTypolinkConfiguration')->will($this->returnValue(array('foo' => 'bar')));
+
+               $this->contentObject->expects($this->once())->method('typoLink_URL')->with(array('foo' => 'bar', 'forceAbsoluteUrl' => TRUE))->will($this->returnValue('http://baseuri/relative/uri'));
+               $uriBuilder->setCreateAbsoluteUri(TRUE);
+
+               $expectedResult = 'http://baseuri/relative/uri';
+               $actualResult = $uriBuilder->buildFrontendUri();
+               $this->assertSame($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function resetSetsAllOptionsToTheirDefaultValue() {
+               $this->uriBuilder
+                       ->setArguments(array('test' => 'arguments'))
+                       ->setSection('testSection')
+                       ->setFormat('someFormat')
+                       ->setCreateAbsoluteUri(TRUE)
+                       ->setAddQueryString(TRUE)
+                       ->setArgumentsToBeExcludedFromQueryString(array('test' => 'addQueryStringExcludeArguments'))
+                       ->setLinkAccessRestrictedPages(TRUE)
+                       ->setTargetPageUid(123)
+                       ->setTargetPageType(321)
+                       ->setNoCache(TRUE)
+                       ->setUseCacheHash(FALSE);
+
+               $this->uriBuilder->reset();
+
+               $this->assertEquals(array(), $this->uriBuilder->getArguments());
+               $this->assertEquals('', $this->uriBuilder->getSection());
+               $this->assertEquals('', $this->uriBuilder->getFormat());
+               $this->assertEquals(FALSE, $this->uriBuilder->getCreateAbsoluteUri());
+               $this->assertEquals(FALSE, $this->uriBuilder->getAddQueryString());
+               $this->assertEquals(array(), $this->uriBuilder->getArgumentsToBeExcludedFromQueryString());
+               $this->assertEquals(FALSE, $this->uriBuilder->getLinkAccessRestrictedPages());
+               $this->assertEquals(NULL, $this->uriBuilder->getTargetPageUid());
+               $this->assertEquals(0, $this->uriBuilder->getTargetPageType());
+               $this->assertEquals(FALSE, $this->uriBuilder->getNoCache());
+               $this->assertEquals(TRUE, $this->uriBuilder->getUseCacheHash());
+       }
+
+       /**
+        * @test
+        */
+       public function buildTypolinkConfigurationRespectsSpecifiedTargetPageUid() {
+               $GLOBALS['TSFE']->id = 123;
+               $this->uriBuilder->setTargetPageUid(321);
+
+               $expectedConfiguration = array('parameter' => 321, 'useCacheHash' => 1);
+               $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
+
+               $this->assertEquals($expectedConfiguration, $actualConfiguration);
+       }
+
+       /**
+        * @test
+        */
+       public function buildTypolinkConfigurationUsesCurrentPageUidIfTargetPageUidIsNotSet() {
+               $GLOBALS['TSFE']->id = 123;
+
+               $expectedConfiguration = array('parameter' => 123, 'useCacheHash' => 1);
+               $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
+
+               $this->assertEquals($expectedConfiguration, $actualConfiguration);
+       }
+
+       /**
+        * @test
+        */
+       public function buildTypolinkConfigurationProperlySetsAdditionalArguments() {
+               $this->uriBuilder->setTargetPageUid(123);
+               $this->uriBuilder->setArguments(array('foo' => 'bar', 'baz' => array('extbase' => 'fluid')));
+
+               $expectedConfiguration = array('parameter' => 123, 'useCacheHash' => 1, 'additionalParams' => '&foo=bar&baz[extbase]=fluid');
+               $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
+
+               $this->assertEquals($expectedConfiguration, $actualConfiguration);
+       }
+
+       /**
+        * @test
+        */
+       public function buildTypolinkConfigurationConvertsDomainObjects() {
+               $mockDomainObject1 = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_DomainObject_AbstractEntity'), array('dummy'));
+               $mockDomainObject1->_set('uid', '123');
+
+               $mockDomainObject2 = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_DomainObject_AbstractEntity'), array('dummy'));
+               $mockDomainObject2->_set('uid', '321');
+
+               $this->uriBuilder->setTargetPageUid(123);
+               $this->uriBuilder->setArguments(array('someDomainObject' => $mockDomainObject1, 'baz' => array('someOtherDomainObject' => $mockDomainObject2)));
+
+               $expectedConfiguration = array('parameter' => 123, 'useCacheHash' => 1, 'additionalParams' => '&someDomainObject=123&baz[someOtherDomainObject]=321');
+               $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
+
+               $this->assertEquals($expectedConfiguration, $actualConfiguration);
+       }
+
+       /**
+        * @test
+        */
+       public function buildTypolinkConfigurationConsidersPageType() {
+               $this->uriBuilder->setTargetPageUid(123);
+               $this->uriBuilder->setTargetPageType(2);
+
+               $expectedConfiguration = array('parameter' => '123,2', 'useCacheHash' => 1);
+               $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
+
+               $this->assertEquals($expectedConfiguration, $actualConfiguration);
+       }
+
+       /**
+        * @test
+        */
+       public function buildTypolinkConfigurationDisablesCacheHashIfNoCacheIsSet() {
+               $this->uriBuilder->setTargetPageUid(123);
+               $this->uriBuilder->setNoCache(TRUE);
+
+               $expectedConfiguration = array('parameter' => 123, 'no_cache' => 1);
+               $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
+
+               $this->assertEquals($expectedConfiguration, $actualConfiguration);
+       }
+
+       /**
+        * @test
+        */
+       public function buildTypolinkConfigurationDoesNotSetUseCacheHashOptionIfUseCacheHashIsDisabled() {
+               $this->uriBuilder->setTargetPageUid(123);
+               $this->uriBuilder->setUseCacheHash(FALSE);
+
+               $expectedConfiguration = array('parameter' => 123);
+               $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
+
+               $this->assertEquals($expectedConfiguration, $actualConfiguration);
+       }
+
+       /**
+        * @test
+        */
+       public function buildTypolinkConfigurationConsidersSection() {
+               $this->uriBuilder->setTargetPageUid(123);
+               $this->uriBuilder->setSection('SomeSection');
+
+               $expectedConfiguration = array('parameter' => 123, 'useCacheHash' => 1, 'section' => 'SomeSection');
+               $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
+
+               $this->assertEquals($expectedConfiguration, $actualConfiguration);
+       }
+
+       /**
+        * @test
+        */
+       public function buildTypolinkConfigurationLinkAccessRestrictedPagesSetting() {
+               $this->uriBuilder->setTargetPageUid(123);
+               $this->uriBuilder->setLinkAccessRestrictedPages(TRUE);
+
+               $expectedConfiguration = array('parameter' => 123, 'useCacheHash' => 1, 'linkAccessRestrictedPages' => 1);
+               $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
+
+               $this->assertEquals($expectedConfiguration, $actualConfiguration);
+       }
+
+       /**
+        * @test
+        */
+       public function convertDomainObjectsToIdentityArraysConvertsDomainObjects() {
+               $mockDomainObject1 = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_DomainObject_AbstractEntity'), array('dummy'));
+               $mockDomainObject1->_set('uid', '123');
+
+               $mockDomainObject2 = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_DomainObject_AbstractEntity'), array('dummy'));
+               $mockDomainObject2->_set('uid', '321');
+
+               $expectedResult = array('foo' => array('bar' => 'baz'), 'domainObject1' => '123', 'second' => array('domainObject2' =>'321'));
+               $actualResult = $this->uriBuilder->_call('convertDomainObjectsToIdentityArrays', array('foo' => array('bar' => 'baz'), 'domainObject1' => $mockDomainObject1, 'second' => array('domainObject2' => $mockDomainObject2)));
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function conversionOfTansientObjectsIsInvoked() {
+               $className = uniqid('Tx_Extbase_Tests_Fixtures_Object');
+               eval('class ' . $className . ' extends Tx_Extbase_DomainObject_AbstractValueObject { public $name; public $uid; }');
+               $mockValueObject = new $className;
+               $mockValueObject->name = 'foo';
+
+               $mockUriBuilder = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Routing_UriBuilder'), array('convertTransientObjectToArray'));
+               $mockUriBuilder->expects($this->once())->method('convertTransientObjectToArray')->will($this->returnValue(array('foo' => 'bar')));
+               $actualResult = $mockUriBuilder->_call('convertDomainObjectsToIdentityArrays', array('object' => $mockValueObject));
+
+               $expectedResult = array('object' => array('foo' => 'bar'));
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_MVC_Exception_InvalidArgumentValue
+        */
+       public function conversionOfTansientObjectsThrowsExceptionForOtherThanValueObjects() {
+               $className = uniqid('Tx_Extbase_Tests_Fixtures_Object');
+               eval('class ' . $className . ' extends Tx_Extbase_DomainObject_AbstractEntity { public $name; public $uid; }');
+               $mockEntity = new $className;
+               $mockEntity->name = 'foo';
+
+               $mockUriBuilder = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Routing_UriBuilder'), array('dummy'));
+               $actualResult = $mockUriBuilder->_call('convertDomainObjectsToIdentityArrays', array('object' => $mockEntity));
+       }
+
+       /**
+        * @test
+        */
+       public function tansientObjectsAreConvertedToAnArrayOfProperties() {
+               $className = uniqid('Tx_Extbase_Tests_Fixtures_Object');
+               eval('class ' . $className . ' extends Tx_Extbase_DomainObject_AbstractValueObject { public $name; public $uid; }');
+               $mockValueObject = new $className;
+               $mockValueObject->name = 'foo';
+
+               $mockUriBuilder = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Routing_UriBuilder'), array('dummy'));
+               $actualResult = $mockUriBuilder->_call('convertTransientObjectToArray', $mockValueObject);
+
+               $expectedResult = array('name' => 'foo', 'uid' => NULL);
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function tansientObjectsAreRecursivelyConverted() {
+               $className = uniqid('Tx_Extbase_Tests_Fixtures_Object');
+               eval('class ' . $className . ' extends Tx_Extbase_DomainObject_AbstractValueObject { public $name; public $uid; }');
+               $mockInnerValueObject2 = new $className;
+               $mockInnerValueObject2->name = 'foo';
+               $mockInnerValueObject2->uid = 99;
+
+               $className = uniqid('Tx_Extbase_Tests_Fixtures_Object');
+               eval('class ' . $className . ' extends Tx_Extbase_DomainObject_AbstractValueObject { public $object; public $uid; }');
+               $mockInnerValueObject1 = new $className;
+               $mockInnerValueObject1->object = $mockInnerValueObject2;
+
+               $className = uniqid('Tx_Extbase_Tests_Fixtures_Object');
+               eval('class ' . $className . ' extends Tx_Extbase_DomainObject_AbstractValueObject { public $object; public $uid; }');
+               $mockValueObject = new $className;
+               $mockValueObject->object = $mockInnerValueObject1;
+
+               $mockUriBuilder = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Routing_UriBuilder'), array('dummy'));
+               $actualResult = $mockUriBuilder->_call('convertTransientObjectToArray', $mockValueObject);
+
+               $expectedResult = array(
+                       'object' => array(
+                               'object' => 99,
+                               'uid' => NULL),
+                       'uid' => NULL);
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Object/Container/ClassInfoFactoryTest.php b/typo3/sysext/extbase/Tests/Unit/Object/Container/ClassInfoFactoryTest.php
new file mode 100644 (file)
index 0000000..ba5fbd6
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*  (c) 2010 Daniel Pötzinger
+*  (c) 2010 Bastian Waidelich <bastian@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+require_once(t3lib_extMgm::extPath('extbase') . 'Tests/Unit/Object/Container/Fixtures/Testclasses.php');
+
+/**
+ * Testcase for class t3lib_object_ClassInfoFactory.
+ *
+ * @author Daniel Pötzinger
+ * @author Bastian Waidelich <bastian@typo3.org>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class Tx_Extbase_Object_Container_ClassInfoFactoryTest extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @var t3lib_object_ClassInfoFactory
+        */
+       private $classInfoFactory;
+
+       /**
+        *
+        */
+       public function setUp() {
+               $this->classInfoFactory = new Tx_Extbase_Object_Container_ClassInfoFactory();
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Object/Container/ContainerTest.php b/typo3/sysext/extbase/Tests/Unit/Object/Container/ContainerTest.php
new file mode 100644 (file)
index 0000000..c5a78dd
--- /dev/null
@@ -0,0 +1,164 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*  (c) 2010 Daniel Pötzinger
+*  (c) 2010 Bastian Waidelich <bastian@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+require_once(t3lib_extMgm::extPath('extbase') . 'Tests/Unit/Object/Container/Fixtures/Testclasses.php');
+
+/**
+ * Testcase for class t3lib_object_Container.
+ *
+ * @author Daniel Pötzinger
+ * @author Bastian Waidelich <bastian@typo3.org>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class Tx_Extbase_Object_Container_ContainerTest extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       private $container;
+
+       public function setUp() {
+               $this->container = Tx_Extbase_Object_Container_Container::getContainer();
+
+       }
+
+       /**
+        * @test
+        */
+       public function getInstanceReturnsInstanceOfSimpleClass() {
+               $object = $this->container->getInstance('t3lib_object_tests_c');
+               $this->assertType('t3lib_object_tests_c', $object);
+       }
+
+       /**
+        * @test
+        */
+       public function getInstanceReturnsInstanceOfAClassWithDependency() {
+               $object = $this->container->getInstance('t3lib_object_tests_b');
+               $this->assertType('t3lib_object_tests_b', $object);
+       }
+
+       /**
+        * @test
+        */
+       public function getInstanceReturnsInstanceOfAClassWithTwoLevelDependency() {
+               $object = $this->container->getInstance('t3lib_object_tests_a');
+               $this->assertType('t3lib_object_tests_a', $object);
+       }
+
+       /**
+        * @test
+        */
+       public function getInstanceReturnsInstanceOfAClassWithTwoLevelMixedArrayDependency() {
+               $object = $this->container->getInstance('t3lib_object_tests_amixed_array');
+               $this->assertType('t3lib_object_tests_amixed_array', $object);
+       }
+
+       /**
+        * @test
+        */
+       public function getInstanceReturnsInstanceOfAClassWithTwoLevelMixedStringDependency() {
+               $object = $this->container->getInstance('t3lib_object_tests_amixed_string');
+               $this->assertType('t3lib_object_tests_amixed_string', $object);
+       }
+
+       /**
+        * @test
+        */
+       public function getInstancePassesGivenParameterToTheNewObject() {
+               $mockObject = $this->getMock('t3lib_object_tests_c');
+
+               $object = $this->container->getInstance('t3lib_object_tests_a', $mockObject);
+               $this->assertType('t3lib_object_tests_a', $object);
+               $this->assertSame($mockObject, $object->c);
+       }
+
+       /**
+        * @test
+        */
+       public function getInstanceReturnsAFreshInstanceIfObjectIsNoSingleton() {
+               $object1 = $this->container->getInstance('t3lib_object_tests_a');
+               $object2 = $this->container->getInstance('t3lib_object_tests_a');
+
+               $this->assertNotSame($object1, $object2);
+       }
+
+       /**
+        * @test
+        */
+       public function getInstanceReturnsSameInstanceInstanceIfObjectIsSingleton() {
+               $object1 = $this->container->getInstance('t3lib_object_tests_singleton');
+               $object2 = $this->container->getInstance('t3lib_object_tests_singleton');
+
+               $this->assertSame($object1, $object2);
+       }
+
+       /**
+        * @test
+        * @expectedException Exception
+        */
+       public function getInstanceThrowsExceptionIfObjectContainsCyclicDependency() {
+               $this->container->getInstance('t3lib_object_tests_cyclic1');
+
+       }
+
+       /**
+        * @test
+        * @expectedException Exception
+        */
+       public function getInstanceThrowsExceptionIfClassWasNotFound() {
+               $this->container->getInstance('nonextistingclass_bla');
+
+       }
+
+       /**
+        * @test
+        */
+       public function test_canGetChildClass() {
+               $object = $this->container->getInstance('t3lib_object_tests_b_child');
+               $this->assertType('t3lib_object_tests_b_child', $object);
+       }
+
+       /**
+        * @test
+        */
+       public function test_canInjectInterfaceInClass() {
+               $this->container->registerImplementation('t3lib_object_tests_someinterface', 't3lib_object_tests_someimplementation');
+               $object = $this->container->getInstance('t3lib_object_tests_needsinterface');
+               $this->assertType('t3lib_object_tests_needsinterface', $object);
+       }
+
+       /**
+        * @test
+        */
+       public function test_canBuildCyclicDependenciesWithSetter() {
+               $object = $this->container->getInstance('t3lib_object_tests_resolveablecyclic1');
+               $this->assertType('t3lib_object_tests_resolveablecyclic1', $object);
+               $this->assertType('t3lib_object_tests_resolveablecyclic1', $object->o->o);
+       }
+
+
+
+}
+
+
+?>
diff --git a/typo3/sysext/extbase/Tests/Unit/Object/Container/Fixtures/Testclasses.php b/typo3/sysext/extbase/Tests/Unit/Object/Container/Fixtures/Testclasses.php
new file mode 100644 (file)
index 0000000..6f09a01
--- /dev/null
@@ -0,0 +1,166 @@
+<?php
+
+/**
+ * a  singleton class
+ *
+ */
+class t3lib_object_tests_singleton implements t3lib_Singleton {
+
+}
+
+/**
+ * test class A that depends on B and C
+ *
+ */
+class t3lib_object_tests_a {
+       public $b;
+       public $c;
+
+       public function __construct( t3lib_object_tests_c $c, t3lib_object_tests_b $b) {
+               $this->b = $b;
+               $this->c = $c;
+       }
+}
+/**
+ * test class A that depends on B and C and has a third default parameter in constructor
+ *
+ */
+class t3lib_object_tests_amixed_array implements t3lib_Singleton {
+       public function __construct(t3lib_object_tests_b $b, t3lib_object_tests_c $c, array $myvalue=array()) {
+
+       }
+}
+/**
+ * test class A that depends on B and C and has a third default parameter in constructor
+ *
+ */
+class t3lib_object_tests_amixed_string implements t3lib_Singleton {
+       public function __construct(t3lib_object_tests_b $b, t3lib_object_tests_c $c, $myvalue='test') {
+
+       }
+}
+/**
+ * test class B that depends on C
+ *
+ */
+class t3lib_object_tests_b implements t3lib_Singleton {
+       public function __construct(t3lib_object_tests_c $c) {
+
+       }
+}
+
+
+/**
+ * test class C without dependencys
+ *
+ */
+class t3lib_object_tests_c implements t3lib_Singleton {
+
+}
+
+/**
+ * test class B-Child that extends Class B (therfore depends also on Class C)
+ *
+ */
+class t3lib_object_tests_b_child extends t3lib_object_tests_b {
+}
+
+interface t3lib_object_tests_someinterface {
+
+}
+
+/**
+ * class which implements a Interface
+ *
+ */
+class t3lib_object_tests_someimplementation implements t3lib_object_tests_someinterface, t3lib_Singleton {
+}
+
+/**
+ * test class B-Child that extends Class B (therfore depends also on Class C)
+ *
+ */
+class t3lib_object_tests_b_child_someimplementation extends t3lib_object_tests_b implements t3lib_object_tests_someinterface {
+}
+
+/**
+ * class which depends on a Interface
+ *
+ */
+class t3lib_object_tests_needsinterface {
+       public function __construct(t3lib_object_tests_someinterface $i) {
+
+       }
+}
+
+/**
+ * classes that depends on each other (death look)
+ *
+ */
+class t3lib_object_tests_cyclic1 {
+       public function __construct(t3lib_object_tests_cyclic2 $c) {
+
+       }
+}
+
+class t3lib_object_tests_cyclic2 {
+       public function __construct(t3lib_object_tests_cyclic1 $c) {
+
+       }
+}
+
+/**
+ * class which has setter injections defined
+ *
+ */
+class t3lib_object_tests_injectmethods {
+       public $b;
+       public $bchild;
+
+       public function injectClassB(t3lib_object_tests_b $o) {
+               $this->b = $o;
+       }
+
+       /**
+        * @inject
+        * @param t3lib_object_tests_b $o
+        */
+       public function setClassBChild(t3lib_object_tests_b_child $o) {
+               $this->bchild = $o;
+       }
+}
+
+/**
+ * class which needs extenson settings injected
+ *
+ */
+class t3lib_object_tests_injectsettings {
+       public $settings;
+       public function injectExtensionSettings(array $settings) {
+               $this->settings = $settings;
+       }
+}
+
+/**
+ *
+ *
+ */
+class t3lib_object_tests_resolveablecyclic1 implements t3lib_Singleton {
+       public $o;
+       public function __construct(t3lib_object_tests_resolveablecyclic2 $cyclic2) {
+               $this->o = $cyclic2;
+       }
+}
+
+/**
+ *
+ *
+ */
+class t3lib_object_tests_resolveablecyclic2 implements t3lib_Singleton {
+       public $o;
+       public function injectCyclic1(t3lib_object_tests_resolveablecyclic1 $o) {
+               $this->o = $o;
+       }
+}
+
+
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Mapper/DataMapFactory_testcase.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Mapper/DataMapFactory_testcase.php
new file mode 100644 (file)
index 0000000..665abf6
--- /dev/null
@@ -0,0 +1,344 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+require_once(PATH_tslib . 'class.tslib_content.php');
+
+class Tx_Extbase_Persistence_Mapper_DataMapFactory_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function setRelationsDetectsOneToOneRelation() {
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+           $columnConfiguration = array(
+                       'type' => 'select',
+                       'foreign_table' => 'tx_myextension_bar',
+                       'foreign_field' => 'parentid',
+                       );
+               $propertyMetaData = array(
+                       'type' => 'Tx_Myext_Domain_Model_Foo',
+                       'elementType' => NULL
+                       );
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'), array(), '', FALSE);
+               $mockDataMapFactory->expects($this->once())->method('setOneToOneRelation');
+               $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
+               $mockDataMapFactory->expects($this->never())->method('setManyToManyRelation');
+               $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
+       }
+
+       /**
+        * @test
+        */
+       public function setRelationsDetectsOneToOneRelationWithIntermediateTable() {
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+           $columnConfiguration = array(
+                       'type' => 'select',
+                       'foreign_table' => 'tx_myextension_bar',
+                       'MM' => 'tx_myextension_mm'
+                       );
+               $propertyMetaData = array(
+                       'type' => 'Tx_Myext_Domain_Model_Foo',
+                       'elementType' => NULL
+                       );
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'), array(), '', FALSE);
+               $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
+               $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
+               $mockDataMapFactory->expects($this->once())->method('setManyToManyRelation');
+               $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
+       }
+
+       /**
+        * @test
+        */
+       public function setRelationsDetectsOneToManyRelation() {
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+           $columnConfiguration = array(
+                       'type' => 'select',
+                       'foreign_table' => 'tx_myextension_bar',
+                       'foreign_field' => 'parentid',
+                       'foreign_table_field' => 'parenttable',
+                       );
+               $propertyMetaData = array(
+                       'type' => 'Tx_Extbase_Persistence_ObjectStorage',
+                       'elementType' => 'Tx_Myext_Domain_Model_Foo'
+                       );
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'), array(), '', FALSE);
+               $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
+               $mockDataMapFactory->expects($this->once())->method('setOneToManyRelation');
+               $mockDataMapFactory->expects($this->never())->method('setManyToManyRelation');
+               $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
+       }
+
+       /**
+        * @test
+        */
+       public function setRelationsDetectsManyToManyRelationOfTypeSelect() {
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+           $columnConfiguration = array(
+                       'type' => 'select',
+                       'foreign_table' => 'tx_myextension_bar',
+                       'MM' => 'tx_myextension_mm'
+                       );
+               $propertyMetaData = array(
+                       'type' => 'Tx_Extbase_Persistence_ObjectStorage',
+                       'elementType' => 'Tx_Myext_Domain_Model_Foo'
+                       );
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'), array(), '', FALSE);
+               $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
+               $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
+               $mockDataMapFactory->expects($this->once())->method('setManyToManyRelation');
+               $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
+       }
+
+       /**
+        * @test
+        */
+       public function setRelationsDetectsManyToManyRelationOfTypeInlineWithIntermediateTable() {
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+           $columnConfiguration = array(
+                       'type' => 'inline',
+                       'foreign_table' => 'tx_myextension_righttable',
+                       'MM' => 'tx_myextension_mm'
+                       );
+               $propertyMetaData = array(
+                       'type' => 'Tx_Extbase_Persistence_ObjectStorage',
+                       'elementType' => 'Tx_Myext_Domain_Model_Foo'
+                       );
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'), array(), '', FALSE);
+               $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
+               $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
+               $mockDataMapFactory->expects($this->once())->method('setManyToManyRelation');
+               $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
+       }
+
+       /**
+        * @test
+        */
+       public function setRelationsDetectsManyToManyRelationOfTypeInlineWithForeignSelector() {
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+           $columnConfiguration = array(
+                       'type' => 'inline',
+                       'foreign_table' => 'tx_myextension_mm',
+                       'foreign_field' => 'uid_local',
+                       'foreign_selector' => 'uid_foreign'
+                       );
+               $propertyMetaData = array(
+                       'type' => 'Tx_Extbase_Persistence_ObjectStorage',
+                       'elementType' => 'Tx_Myext_Domain_Model_Foo'
+                       );
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'), array(), '', FALSE);
+               $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
+               $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
+               $mockDataMapFactory->expects($this->once())->method('setManyToManyRelation');
+               $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
+       }
+
+       /**
+        * @test
+        */
+       public function columnMapIsInitializedWithManyToManyRelationOfTypeSelect() {
+               $leftColumnsDefinition = array(
+                       'rights' => array(
+                               'type' => 'select',
+                               'foreign_table' => 'tx_myextension_righttable',
+                               'foreign_table_where' => 'WHERE 1=1',
+                               'MM' => 'tx_myextension_mm',
+                               'MM_table_where' => 'WHERE 2=2',
+                               ),
+                       );
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+               $mockColumnMap->expects($this->once())->method('setTypeOfRelation')->with($this->equalTo(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY));
+               $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
+               $mockColumnMap->expects($this->once())->method('setChildTableName')->with($this->equalTo('tx_myextension_righttable'));
+               $mockColumnMap->expects($this->once())->method('setChildTableWhereStatement')->with($this->equalTo('WHERE 1=1'));
+               $mockColumnMap->expects($this->once())->method('setChildSortbyFieldName')->with($this->equalTo('sorting'));
+               $mockColumnMap->expects($this->once())->method('setParentKeyFieldName')->with($this->equalTo('uid_local'));
+               $mockColumnMap->expects($this->never())->method('setParentTableFieldName');
+               $mockColumnMap->expects($this->never())->method('setRelationTableMatchFields');
+               $mockColumnMap->expects($this->never())->method('setRelationTableInsertFields');
+
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('dummy'), array(), '', FALSE);
+               $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
+       }
+
+       /**
+        * @test
+        */
+       public function columnMapIsInitializedWithOppositeManyToManyRelationOfTypeSelect() {
+               $rightColumnsDefinition = array(
+                       'lefts' => array(
+                               'type' => 'select',
+                               'foreign_table' => 'tx_myextension_lefttable',
+                               'MM' => 'tx_myextension_mm',
+                               'MM_opposite_field' => 'rights'
+                               ),
+                       );
+               $leftColumnsDefinition['rights']['MM_opposite_field'] = 'opposite_field';
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+               $mockColumnMap->expects($this->once())->method('setTypeOfRelation')->with($this->equalTo(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY));
+               $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
+               $mockColumnMap->expects($this->once())->method('setChildTableName')->with($this->equalTo('tx_myextension_lefttable'));
+               $mockColumnMap->expects($this->once())->method('setChildTableWhereStatement')->with(NULL);
+               $mockColumnMap->expects($this->once())->method('setChildSortbyFieldName')->with($this->equalTo('sorting_foreign'));
+               $mockColumnMap->expects($this->once())->method('setParentKeyFieldName')->with($this->equalTo('uid_foreign'));
+               $mockColumnMap->expects($this->never())->method('setParentTableFieldName');
+               $mockColumnMap->expects($this->never())->method('setRelationTableMatchFields');
+               $mockColumnMap->expects($this->never())->method('setRelationTableInsertFields');
+
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('dummy'), array(), '', FALSE);
+               $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $rightColumnsDefinition['lefts']);
+       }
+
+       /**
+        * @test
+        */
+       public function columnMapIsInitializedWithManyToManyRelationOfTypeInlineAndIntermediateTable() {
+           $leftColumnsDefinition = array(
+                       'rights' => array(
+                               'type' => 'inline',
+                               'foreign_table' => 'tx_myextension_righttable',
+                               'MM' => 'tx_myextension_mm',
+                               'foreign_sortby' => 'sorting'
+                               )
+                       );
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+               $mockColumnMap->expects($this->once())->method('setTypeOfRelation')->with($this->equalTo(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY));
+               $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
+               $mockColumnMap->expects($this->once())->method('setChildTableName')->with($this->equalTo('tx_myextension_righttable'));
+               $mockColumnMap->expects($this->once())->method('setChildTableWhereStatement');
+               $mockColumnMap->expects($this->once())->method('setChildSortbyFieldName')->with($this->equalTo('sorting'));
+               $mockColumnMap->expects($this->once())->method('setParentKeyFieldName')->with($this->equalTo('uid_local'));
+               $mockColumnMap->expects($this->never())->method('setParentTableFieldName');
+               $mockColumnMap->expects($this->never())->method('setRelationTableMatchFields');
+               $mockColumnMap->expects($this->never())->method('setRelationTableInsertFields');
+
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('getColumnsDefinition'), array(), '', FALSE);
+               $mockDataMapFactory->expects($this->never())->method('getColumnsDefinition');
+               $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
+       }
+
+       /**
+        * @test
+        */
+       public function columnMapIsInitializedWithManyToManyRelationOfTypeInlineAndForeignSelector() {
+           $leftColumnsDefinition = array(
+                       'rights' => array(
+                               'type' => 'inline',
+                               'foreign_table' => 'tx_myextension_mm',
+                               'foreign_field' => 'uid_local',
+                               'foreign_selector' => 'uid_foreign',
+                               'foreign_sortby' => 'sorting'
+                               )
+                       );
+           $relationTableColumnsDefiniton = array(
+                       'uid_local' => array(
+                               'config' => array('foreign_table' => 'tx_myextension_localtable')
+                               ),
+                       'uid_foreign' => array(
+                               'config' => array('foreign_table' => 'tx_myextension_righttable')
+                               )
+                       );
+           $rightColumnsDefinition = array(
+                       'lefts' => array(
+                               'type' => 'inline',
+                               'foreign_table' => 'tx_myextension_mm',
+                               'foreign_field' => 'uid_foreign',
+                               'foreign_selector' => 'uid_local',
+                               'foreign_sortby' => 'sorting_foreign'
+                               )
+                       );
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+               $mockColumnMap->expects($this->once())->method('setTypeOfRelation')->with($this->equalTo(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY));
+               $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
+               $mockColumnMap->expects($this->once())->method('setChildTableName')->with($this->equalTo('tx_myextension_righttable'));
+               $mockColumnMap->expects($this->never())->method('setChildTableWhereStatement');
+               $mockColumnMap->expects($this->once())->method('setChildSortbyFieldName')->with($this->equalTo('sorting'));
+               $mockColumnMap->expects($this->once())->method('setParentKeyFieldName')->with($this->equalTo('uid_local'));
+               $mockColumnMap->expects($this->never())->method('setParentTableFieldName');
+               $mockColumnMap->expects($this->never())->method('setRelationTableMatchFields');
+               $mockColumnMap->expects($this->never())->method('setRelationTableInsertFields');
+
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('getColumnsDefinition'), array(), '', FALSE);
+               $mockDataMapFactory->expects($this->once())->method('getColumnsDefinition')->with($this->equalTo('tx_myextension_mm'))->will($this->returnValue($relationTableColumnsDefiniton));
+               $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
+       }
+
+       /**
+        * @test
+        */
+       public function columnMapIsInitializedWithManyToManyRelationWithoutPidColumn() {
+               $leftColumnsDefinition = array(
+                       'rights' => array(
+                               'type' => 'select',
+                               'foreign_table' => 'tx_myextension_righttable',
+                               'foreign_table_where' => 'WHERE 1=1',
+                               'MM' => 'tx_myextension_mm',
+                               ),
+                       );
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+               $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
+               $mockColumnMap->expects($this->once())->method('getRelationTableName')->will($this->returnValue('tx_myextension_mm'));
+               $mockColumnMap->expects($this->never())->method('setrelationTablePageIdColumnName');
+
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('getControlSection'), array(), '', FALSE);
+               $mockDataMapFactory->expects($this->once())->method('getControlSection')->with($this->equalTo('tx_myextension_mm'))->will($this->returnValue(NULL));
+               $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
+       }
+
+       /**
+        * @test
+        */
+       public function columnMapIsInitializedWithManyToManyRelationWithPidColumn() {
+               $leftColumnsDefinition = array(
+                       'rights' => array(
+                               'type' => 'select',
+                               'foreign_table' => 'tx_myextension_righttable',
+                               'foreign_table_where' => 'WHERE 1=1',
+                               'MM' => 'tx_myextension_mm',
+                               ),
+                       );
+               $mockColumnMap = $this->getMock('Tx_Extbase_Persistence_Mapper_ColumnMap', array(), array(), '', FALSE);
+               $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
+               $mockColumnMap->expects($this->once())->method('getRelationTableName')->will($this->returnValue('tx_myextension_mm'));
+               $mockColumnMap->expects($this->once())->method('setrelationTablePageIdColumnName')->with($this->equalTo('pid'));
+
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('getControlSection'), array(), '', FALSE);
+               $mockDataMapFactory->expects($this->once())->method('getControlSection')->with($this->equalTo('tx_myextension_mm'))->will($this->returnValue(array('ctrl' => array('foo' => 'bar'))));
+               $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Persistence_Exception_InvalidClass
+        */
+       public function buildDataMapThrowsExceptionIfClassNameIsNotKnown() {
+               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Mapper_DataMapFactory'), array('getControlSection'), array(), '', FALSE);
+               $mockDataMapFactory->buildDataMap('UnknownObject');
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/ObjectStorage_testcase.php b/typo3/sysext/extbase/Tests/Unit/Persistence/ObjectStorage_testcase.php
new file mode 100644 (file)
index 0000000..53a134a
--- /dev/null
@@ -0,0 +1,195 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_Persistence_ObjectStorage_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function anObjectCanBeAttached() {
+               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $objectStorage->attach($object1);
+               $objectStorage->attach($object2, 'foo');
+               $this->assertEquals($objectStorage[$object1], NULL);
+               $this->assertEquals($objectStorage[$object2], 'foo');
+       }
+
+       /**
+        * @test
+        */
+       public function anObjectCanBeDetached() {
+               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $objectStorage->attach($object1);
+               $objectStorage->attach($object2, 'foo');
+               $this->assertEquals(count($objectStorage), 2);
+               $objectStorage->detach($object1);
+               $this->assertEquals(count($objectStorage), 1);
+               $objectStorage->detach($object2);
+               $this->assertEquals(count($objectStorage), 0);
+       }
+
+       /**
+        * @test
+        */
+       public function offsetSetAssociatesDataToAnObjectInTheStorage() {
+               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $objectStorage->offsetSet($object1, 'foo');
+               $this->assertEquals(count($objectStorage), 1);
+               $objectStorage[$object2] = 'bar';
+               $this->assertEquals(count($objectStorage), 2);
+       }
+
+       /**
+        * @test
+        */
+       public function offsetUnsetRemovesAnObjectFromTheStorage() {
+               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $objectStorage->attach($object1);
+               $objectStorage->attach($object2, 'foo');
+               $this->assertEquals(count($objectStorage), 2);
+               $objectStorage->offsetUnset($object2);
+               $this->assertEquals(count($objectStorage), 1);
+               $objectStorage->offsetUnset($object1);
+               $this->assertEquals(count($objectStorage), 0);
+       }
+
+       /**
+        * @test
+        */
+       public function offsetGetReturnsTheDataAssociatedWithAnObject() {
+               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $objectStorage[$object1] = 'foo';
+               $objectStorage->attach($object2);
+               $this->assertEquals($objectStorage->offsetGet($object1), 'foo');
+               $this->assertEquals($objectStorage->offsetGet($object2), NULL);
+       }
+
+       /**
+        * @test
+        */
+       public function offsetExistsChecksWhetherAnObjectExistsInTheStorage() {
+               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $objectStorage->attach($object1);
+               $this->assertEquals($objectStorage->offsetExists($object1), TRUE);
+               $this->assertEquals($objectStorage->offsetExists($object2), FALSE);
+       }
+
+       /**
+        * @test
+        */
+       public function getInfoReturnsTheDataAssociatedWithTheCurrentIteratorEntry() {
+               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $object3 = new StdClass;
+               $objectStorage->attach($object1, 42);
+               $objectStorage->attach($object2, 'foo');
+               $objectStorage->attach($object3, array('bar', 'baz'));
+               $objectStorage->rewind();
+               $this->assertEquals($objectStorage->getInfo(), 42);
+               $objectStorage->next();
+               $this->assertEquals($objectStorage->getInfo(), 'foo');
+               $objectStorage->next();
+               $this->assertEquals($objectStorage->getInfo(), array('bar', 'baz'));
+       }
+
+       /**
+        * @test
+        */
+       public function setInfoSetsTheDataAssociatedWithTheCurrentIteratorEntry() {
+               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $objectStorage->attach($object1);
+               $objectStorage->attach($object2, 'foo');
+               $objectStorage->rewind();
+               $objectStorage->setInfo(42);
+               $objectStorage->next();
+               $objectStorage->setInfo('bar');
+               $this->assertEquals($objectStorage[$object1], 42);
+               $this->assertEquals($objectStorage[$object2], 'bar');
+       }
+
+       /**
+        * @test
+        */
+       public function removeAllRemovesObjectsContainedInAnotherStorageFromTheCurrentStorage() {
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $objectStorageA = new Tx_Extbase_Persistence_ObjectStorage();
+               $objectStorageA->attach($object1, 'foo');
+               $objectStorageB = new Tx_Extbase_Persistence_ObjectStorage();
+               $objectStorageB->attach($object1, 'bar');
+               $objectStorageB->attach($object2, 'baz');
+               $this->assertEquals(count($objectStorageB), 2);
+               $objectStorageB->removeAll($objectStorageA);
+               $this->assertEquals(count($objectStorageB), 1);
+       }
+
+       /**
+        * @test
+        */
+       public function addAllAddsAllObjectsFromAnotherStorage() {
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $objectStorageA = new Tx_Extbase_Persistence_ObjectStorage(); // It might be better to mock this
+               $objectStorageA->attach($object1, 'foo');
+               $objectStorageB = new Tx_Extbase_Persistence_ObjectStorage();
+               $objectStorageB->attach($object2, 'baz');
+               $this->assertEquals($objectStorageB->offsetExists($object1), FALSE);
+               $objectStorageB->addAll($objectStorageA);
+               $this->assertEquals($objectStorageB[$object1], 'foo');
+               $this->assertEquals($objectStorageB[$object2], 'baz');
+       }
+
+
+       /**
+        * @test
+        */
+       public function theStorageCanBeRetrievedAsArray() {
+               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+               $object1 = new StdClass;
+               $object2 = new StdClass;
+               $objectStorage->attach($object1, 'foo');
+               $objectStorage->attach($object2, 'bar');
+               $this->assertEquals($objectStorage->toArray(), array($object1, $object2));
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/QueryResult_testcase.php b/typo3/sysext/extbase/Tests/Unit/Persistence/QueryResult_testcase.php
new file mode 100644 (file)
index 0000000..67b2a2e
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Bastian Waidelich <bastian@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_Persistence_QueryResult_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @var Tx_Extbase_Persistence_QueryResult
+        */
+       protected $queryResult;
+
+       /**
+        * @var Tx_Extbase_Persistence_QueryInterface
+        */
+       protected $query;
+
+       /**
+        * @var Tx_Extbase_Persistence_ManagerInterface
+        */
+       protected $persistenceManager;
+
+       /**
+        * @var Tx_Extbase_Persistence_DataMapper
+        */
+       protected $dataMapper;
+
+       /**
+        * Sets up this test case
+        *
+        * @return void
+        */
+       public function setUp() {
+               $this->persistenceManager = $this->getMock('Tx_Extbase_Persistence_ManagerInterface');
+               $this->persistenceManager->expects($this->any())->method('getObjectDataByQuery')->will($this->returnValue(array('one', 'two')));
+               $this->persistenceManager->expects($this->any())->method('getObjectCountByQuery')->will($this->returnValue(2));
+               $this->dataMapper = $this->getMock('Tx_Extbase_Persistence_Mapper_DataMapper');
+               $this->query = $this->getMock('Tx_Extbase_Persistence_QueryInterface');
+               $this->queryResult = new Tx_Extbase_Persistence_QueryResult($this->query);
+               $this->queryResult->injectPersistenceManager($this->persistenceManager);
+               $this->queryResult->injectDataMapper($this->dataMapper);
+               $this->sampleResult = array(array('foo' => 'Foo1', 'bar' => 'Bar1'), array('foo' => 'Foo2', 'bar' => 'Bar2'));
+               $this->dataMapper->expects($this->any())->method('map')->will($this->returnValue($this->sampleResult));
+       }
+
+       /**
+        * @test
+        */
+       public function getQueryReturnsQueryObject() {
+               $this->assertType('Tx_Extbase_Persistence_QueryInterface', $this->queryResult->getQuery());
+       }
+
+       /**
+        * @test
+        */
+       public function getQueryReturnsAClone() {
+               $this->assertNotSame($this->query, $this->queryResult->getQuery());
+       }
+
+       /**
+        * @test
+        */
+       public function offsetExistsWorksAsExpected() {
+               $this->assertTrue($this->queryResult->offsetExists(0));
+               $this->assertFalse($this->queryResult->offsetExists(2));
+               $this->assertFalse($this->queryResult->offsetExists('foo'));
+       }
+
+       /**
+        * @test
+        */
+       public function offsetGetWorksAsExpected() {
+               $this->assertEquals(array('foo' => 'Foo1', 'bar' => 'Bar1'), $this->queryResult->offsetGet(0));
+               $this->assertNull($this->queryResult->offsetGet(2));
+               $this->assertNull($this->queryResult->offsetGet('foo'));
+       }
+
+       /**
+        * @test
+        */
+       public function offsetSetWorksAsExpected() {
+               $this->queryResult->offsetSet(0, array('foo' => 'FooOverridden', 'bar' => 'BarOverridden'));
+               $this->assertEquals(array('foo' => 'FooOverridden', 'bar' => 'BarOverridden'), $this->queryResult->offsetGet(0));
+       }
+
+       /**
+        * @test
+        */
+       public function offsetUnsetWorksAsExpected() {
+               $this->queryResult->offsetUnset(0);
+               $this->assertFalse($this->queryResult->offsetExists(0));
+       }
+
+       /**
+        * @test
+        */
+       public function countDoesNotInitializeProxy() {
+               $queryResult = $this->getMock('Tx_Extbase_Persistence_QueryResult', array('initialize'), array($this->query));
+               $queryResult->injectPersistenceManager($this->persistenceManager);
+               $queryResult->expects($this->never())->method('initialize');
+               $queryResult->count();
+       }
+
+       /**
+        * @test
+        */
+       public function countCallsGetObjectCountByQueryOnPersistenceManager() {
+               $queryResult = $this->getMock('Tx_Extbase_Persistence_QueryResult', array('initialize'), array($this->query));
+               $queryResult->injectPersistenceManager($this->persistenceManager);
+               $this->assertEquals(2, $queryResult->count());
+       }
+
+       /**
+        * @test
+        */
+       public function iteratorMethodsAreCorrectlyImplemented() {
+               $array1 = array('foo' => 'Foo1', 'bar' => 'Bar1');
+               $array2 = array('foo' => 'Foo2', 'bar' => 'Bar2');
+               $this->assertEquals($array1, $this->queryResult->current());
+               $this->assertTrue($this->queryResult->valid());
+               $this->queryResult->next();
+               $this->assertEquals($array2, $this->queryResult->current());
+               $this->assertTrue($this->queryResult->valid());
+               $this->assertEquals(1, $this->queryResult->key());
+               $this->queryResult->next();
+               $this->assertFalse($this->queryResult->current());
+               $this->assertFalse($this->queryResult->valid());
+               $this->assertNull($this->queryResult->key());
+               $this->queryResult->rewind();
+               $this->assertEquals(0, $this->queryResult->key());
+               $this->assertEquals($array1, $this->queryResult->current());
+       }
+
+       /**
+        * @test
+        */
+       public function initializeExecutesQueryWithArrayFetchMode() {
+               $queryResult = $this->getAccessibleMock('Tx_Extbase_Persistence_QueryResult', array('dummy'), array($this->query));
+               $queryResult->injectPersistenceManager($this->persistenceManager);
+               $queryResult->injectDataMapper($this->dataMapper);
+               $this->persistenceManager->expects($this->once())->method('getObjectDataByQuery')->with($this->query)->will($this->returnValue(array('FAKERESULT')));
+               $queryResult->_call('initialize');
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Query_testcase.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Query_testcase.php
new file mode 100644 (file)
index 0000000..62382bf
--- /dev/null
@@ -0,0 +1,131 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Christopher Hlubek <hlubek@networkteam.com>
+*  (c) 2010 Bastian Waidelich <bastian@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_Persistence_Query_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @var Tx_Extbase_Persistence_Query
+        */
+       protected $query;
+
+       /**
+        * @var Tx_Extbase_Persistence_QuerySettingsInterface
+        */
+       protected $querySettings;
+
+       /**
+        * @var Tx_Extbase_Object_ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
+        * @var Tx_Extbase_Persistence_ManagerInterface
+        */
+       protected $persistenceManager;
+
+       /**
+        * @var Tx_Extbase_Persistence_BackendInterface
+        */
+       protected $backend;
+
+       /**
+        * @var Tx_Extbase_Persistence_DataMapper
+        */
+       protected $dataMapper;
+
+       /**
+        * Sets up this test case
+        * @return void
+        */
+       public function setUp() {
+               $this->objectManager = $this->getMock('Tx_Extbase_Object_ObjectManagerInterface');
+               $this->query = new Tx_Extbase_Persistence_Query('someType');
+               $this->query->injectObjectManager($this->objectManager);
+               $this->querySettings = $this->getMock('Tx_Extbase_Persistence_QuerySettingsInterface');
+               $this->query->setQuerySettings($this->querySettings);
+               $this->persistenceManager = $this->getMock('Tx_Extbase_Persistence_ManagerInterface');
+               $this->backend = $this->getMock('Tx_Extbase_Persistence_BackendInterface');
+               $this->backend->expects($this->any())->method('getQomFactory')->will($this->returnValue(NULL));
+               $this->persistenceManager->expects($this->any())->method('getBackend')->will($this->returnValue($this->backend));
+               $this->query->injectPersistenceManager($this->persistenceManager);
+               $this->dataMapper = $this->getMock('Tx_Extbase_Persistence_Mapper_DataMapper');
+               $this->query->injectDataMapper($this->dataMapper);
+       }
+
+       /**
+        * @test
+        */
+       public function executeReturnsQueryResultInstanceAndInjectsItself() {
+               $queryResult = $this->getMock('Tx_Extbase_Persistence_QueryResult', array(), array(), '', FALSE);
+               $this->objectManager->expects($this->once())->method('create')->with('Tx_Extbase_Persistence_QueryResultInterface', $this->query)->will($this->returnValue($queryResult));
+               $actualResult = $this->query->execute();
+               $this->assertSame($queryResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function executeReturnsRawObjectDataIfRawQueryResultSettingIsTrue() {
+               $this->querySettings->expects($this->once())->method('getReturnRawQueryResult')->will($this->returnValue(TRUE));
+               $this->persistenceManager->expects($this->once())->method('getObjectDataByQuery')->with($this->query)->will($this->returnValue('rawQueryResult'));
+               $expectedResult = 'rawQueryResult';
+               $actualResult = $this->query->execute();
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        * @expectedException InvalidArgumentException
+        */
+       public function setLimitAcceptsOnlyIntegers() {
+               $this->query->setLimit(1.5);
+       }
+
+       /**
+        * @test
+        * @expectedException InvalidArgumentException
+        */
+       public function setLimitRejectsIntegersLessThanOne() {
+               $this->query->setLimit(0);
+       }
+
+       /**
+        * @test
+        * @expectedException InvalidArgumentException
+        */
+       public function setOffsetAcceptsOnlyIntegers() {
+               $this->query->setOffset(1.5);
+       }
+
+       /**
+        * @test
+        * @expectedException InvalidArgumentException
+        */
+       public function setOffsetRejectsIntegersLessThanZero() {
+               $this->query->setOffset(-1);
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Repository_testcase.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Repository_testcase.php
new file mode 100644 (file)
index 0000000..b1abd98
--- /dev/null
@@ -0,0 +1,414 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Bastian Waidelich <bastian@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_Persistence_Repository_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @var Tx_Extbase_Persistence_Repository
+        */
+       protected $repository;
+
+       /**
+        * @var Tx_Extbase_Persistence_IdentityMap
+        */
+       protected $identityMap;
+
+       /**
+        * @var Tx_Extbase_Persistence_QueryFactory
+        */
+       protected $queryFactory;
+
+       /**
+        * @var Tx_Extbase_Persistence_ManagerInterface
+        */
+       protected $persistenceManager;
+
+       /**
+        * @var Tx_Extbase_Persistence_QueryInterface
+        */
+       protected $query;
+
+       /**
+        * @var Tx_Extbase_Persistence_QuerySettingsInterface
+        */
+       protected $querySettings;
+
+       public function setUp() {
+               $this->identityMap = $this->getMock('Tx_Extbase_Persistence_IdentityMap');
+               $this->queryFactory = $this->getMock('Tx_Extbase_Persistence_QueryFactory');
+               $this->query = $this->getMock('Tx_Extbase_Persistence_QueryInterface');
+               $this->querySettings = $this->getMock('Tx_Extbase_Persistence_QuerySettingsInterface');
+               $this->query->expects($this->any())->method('getQuerySettings')->will($this->returnValue($this->querySettings));
+               $this->queryFactory->expects($this->any())->method('create')->will($this->returnValue($this->query));
+               $this->persistenceManager = $this->getMock('Tx_Extbase_Persistence_ManagerInterface');
+               $this->repository = $this->getAccessibleMock('Tx_Extbase_Persistence_Repository', array('dummy'), array($this->identityMap, $this->queryFactory, $this->persistenceManager));
+       }
+
+       /**
+        * @test
+        */
+       public function abstractRepositoryImplementsRepositoryInterface() {
+               $this->assertTrue($this->repository instanceof Tx_Extbase_Persistence_RepositoryInterface);
+       }
+
+       /**
+        * @test
+        */
+       public function addActuallyAddsAnObjectToTheInternalObjectsArray() {
+               $someObject = new stdClass();
+               $this->repository->_set('objectType', get_class($someObject));
+               $this->repository->add($someObject);
+
+               $this->assertTrue($this->repository->getAddedObjects()->contains($someObject));
+       }
+
+       /**
+        * @test
+        */
+       public function removeActuallyRemovesAnObjectFromTheInternalObjectsArray() {
+               $object1 = new stdClass();
+               $object2 = new stdClass();
+               $object3 = new stdClass();
+
+               $this->repository->_set('objectType', get_class($object1));
+               $this->repository->add($object1);
+               $this->repository->add($object2);
+               $this->repository->add($object3);
+
+               $this->repository->remove($object2);
+
+               $this->assertTrue($this->repository->getAddedObjects()->contains($object1));
+               $this->assertFalse($this->repository->getAddedObjects()->contains($object2));
+               $this->assertTrue($this->repository->getAddedObjects()->contains($object3));
+       }
+
+       /**
+        * @test
+        */
+       public function removeRemovesTheRightObjectEvenIfItHasBeenModifiedSinceItsAddition() {
+               $object1 = new ArrayObject(array('val' => '1'));
+               $object2 = new ArrayObject(array('val' => '2'));
+               $object3 = new ArrayObject(array('val' => '3'));
+
+               $this->repository->_set('objectType', get_class($object1));
+               $this->repository->add($object1);
+               $this->repository->add($object2);
+               $this->repository->add($object3);
+
+               $object2['foo'] = 'bar';
+               $object3['val'] = '2';
+
+               $this->repository->remove($object2);
+
+               $this->assertTrue($this->repository->getAddedObjects()->contains($object1));
+               $this->assertFalse($this->repository->getAddedObjects()->contains($object2));
+               $this->assertTrue($this->repository->getAddedObjects()->contains($object3));
+       }
+
+       /**
+        * Make sure we remember the objects that are not currently add()ed
+        * but might be in persistent storage.
+        *
+        * @test
+        */
+       public function removeRetainsObjectForObjectsNotInCurrentSession() {
+               $object = new ArrayObject(array('val' => '1'));
+               $this->repository->_set('objectType', get_class($object));
+               $this->repository->remove($object);
+
+               $this->assertTrue($this->repository->getRemovedObjects()->contains($object));
+       }
+
+       /**
+        * dataProvider for createQueryCallsQueryFactoryWithExpectedType
+        */
+       public function modelAndRepositoryClassNames() {
+               return array(
+                       array('Tx_BlogExample_Domain_Repository_BlogRepository', 'Tx_BlogExample_Domain_Model_Blog'),
+                       array('_Domain_Repository_Content_PageRepository', '_Domain_Model_Content_Page')
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider modelAndRepositoryClassNames
+        */
+       public function constructSetsObjectTypeFromClassName($repositoryClassName, $modelClassName) {
+               $mockClassName = 'MockRepository' . uniqid();
+               eval('class ' . $mockClassName . ' extends Tx_Extbase_Persistence_Repository {
+                       protected function getRepositoryClassName() {
+                               return \'' . $repositoryClassName . '\';
+                       }
+                       public function _getObjectType() {
+                               return $this->objectType;
+                       }
+               }');
+
+               $this->repository = new $mockClassName($this->identityMap, $this->queryFactory, $this->persistenceManager);
+               $this->assertEquals($modelClassName, $this->repository->_getObjectType());
+       }
+
+       /**
+        * @test
+        */
+       public function createQueryCallsQueryFactoryWithExpectedClassName() {
+               $this->queryFactory->expects($this->once())->method('create')->with('ExpectedType');
+               $this->repository->_set('objectType', 'ExpectedType');
+               $this->repository->createQuery();
+       }
+
+       /**
+        * @test
+        */
+       public function findAllCreatesQueryAndReturnsResultOfExecuteCall() {
+               $expectedResult = $this->getMock('Tx_Extbase_Persistence_QueryResultInterface');
+               $this->query->expects($this->once())->method('execute')->with()->will($this->returnValue($expectedResult));
+               $this->assertSame($expectedResult, $this->repository->findAll());
+       }
+
+       /**
+        * @test
+        */
+       public function findByUidReturnsResultOfGetObjectByIdentifierCall() {
+               $fakeUid = '123';
+               $object = new stdClass();
+
+               $this->persistenceManager->expects($this->once())->method('getObjectByIdentifier')->with($fakeUid)->will($this->returnValue($object));
+               $this->repository->_set('objectType', 'stdClass');
+
+               $this->assertSame($object, $this->repository->findByUid($fakeUid));
+       }
+
+       /**
+        * @test
+        */
+       public function findByUidReturnsNullIfObjectOfMismatchingTypeWasFoundByGetObjectByIdentifierCall() {
+               $fakeUUID = '123';
+               $object = new stdClass();
+
+               $this->persistenceManager->expects($this->once())->method('getObjectByIdentifier')->with($fakeUUID)->will($this->returnValue($object));
+               $this->repository->_set('objectType', 'otherExpectedClass');
+
+               $this->assertNULL($this->repository->findByUuid($fakeUUID));
+       }
+
+       /**
+        * Replacing a reconstituted object (which has a uuid) by a new object
+        * will ask the persistence backend to replace them accordingly in the
+        * identity map.
+        *
+        * @test
+        * @return void
+        */
+       public function replaceReconstitutedEntityByNewObject() {
+               $existingObject = new stdClass;
+               $newObject = new stdClass;
+
+               $this->persistenceManager->expects($this->once())->method('getIdentifierByObject')->with($existingObject)->will($this->returnValue('86ea8820-19f6-11de-8c30-0800200c9a66'));
+               $this->persistenceManager->expects($this->once())->method('replaceObject')->with($existingObject, $newObject);
+
+               $this->repository->_set('objectType', get_class($newObject));
+               $this->repository->replace($existingObject, $newObject);
+       }
+
+       /**
+        * Replacing a reconstituted object which during this session has been
+        * marked for removal (by calling the repository's remove method)
+        * additionally registers the "newObject" for removal and removes the
+        * "existingObject" from the list of removed objects.
+        *
+        * @test
+        * @return void
+        */
+       public function replaceReconstitutedObjectWhichIsMarkedToBeRemoved() {
+               $existingObject = new stdClass;
+               $newObject = new stdClass;
+
+               $removedObjects = new SplObjectStorage;
+               $removedObjects->attach($existingObject);
+
+               $this->persistenceManager->expects($this->once())->method('getIdentifierByObject')->with($existingObject)->will($this->returnValue('86ea8820-19f6-11de-8c30-0800200c9a66'));
+               $this->persistenceManager->expects($this->once())->method('replaceObject')->with($existingObject, $newObject);
+
+               $this->repository->_set('objectType', get_class($newObject));
+               $this->repository->_set('removedObjects', $removedObjects);
+               $this->repository->replace($existingObject, $newObject);
+
+               $this->assertFalse($removedObjects->contains($existingObject));
+               $this->assertTrue($removedObjects->contains($newObject));
+       }
+
+       /**
+        * Replacing a new object which has not yet been persisted by another
+        * new object will just replace them in the repository's list of added
+        * objects.
+        *
+        * @test
+        * @return void
+        */
+       public function replaceNewObjectByNewObject() {
+               $existingObject = new stdClass;
+               $newObject = new stdClass;
+
+               $addedObjects = new SplObjectStorage;
+               $addedObjects->attach($existingObject);
+
+               $this->persistenceManager->expects($this->once())->method('getIdentifierByObject')->with($existingObject)->will($this->returnValue(NULL));
+               $this->persistenceManager->expects($this->never())->method('replaceObject');
+
+               $this->repository->_set('objectType', get_class($newObject));
+               $this->repository->_set('addedObjects', $addedObjects);
+               $this->repository->replace($existingObject, $newObject);
+
+               $this->assertFalse($addedObjects->contains($existingObject));
+               $this->assertTrue($addedObjects->contains($newObject));
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Persistence_Exception_IllegalObjectType
+        */
+       public function replaceChecksObjectType() {
+               $this->repository->_set('objectType', 'ExpectedObjectType');
+
+               $this->repository->replace(new stdClass(), new stdClass());
+       }
+
+       /**
+        * @test
+        */
+       public function updateReplacesAnObjectWithTheSameUuidByTheGivenObject() {
+               $existingObject = new stdClass;
+               $modifiedObject = $this->getMock('FooBar' . uniqid(), array('FLOW3_Persistence_isClone'));
+               $modifiedObject->expects($this->once())->method('FLOW3_Persistence_isClone')->will($this->returnValue(TRUE));
+
+               $this->persistenceManager->expects($this->once())->method('getIdentifierByObject')->with($modifiedObject)->will($this->returnValue('86ea8820-19f6-11de-8c30-0800200c9a66'));
+               $this->persistenceManager->expects($this->once())->method('getObjectByIdentifier')->with('86ea8820-19f6-11de-8c30-0800200c9a66')->will($this->returnValue($existingObject));
+
+               $this->repository->expects($this->once())->method('replaceObject')->with($existingObject, $modifiedObject);
+
+               $this->repository->_set('objectType', get_class($modifiedObject));
+               $this->repository->update($modifiedObject);
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Persistence_Exception_IllegalObjectType
+        */
+       public function updateRejectsNonClonedObjects() {
+               $someObject = $this->getMock('FooBar' . uniqid(), array('FLOW3_Persistence_isClone'));
+               $someObject->expects($this->once())->method('FLOW3_Persistence_isClone')->will($this->returnValue(FALSE));
+
+               $this->repository->_set('objectType', get_class($someObject));
+
+               $this->repository->update($someObject);
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Persistence_Exception_IllegalObjectType
+        */
+       public function updateRejectsObjectsOfWrongType() {
+               $this->repository->_set('objectType', 'Foo');
+               $this->repository->update(new stdClass());
+       }
+
+       /**
+        * @test
+        */
+       public function magicCallMethodAcceptsFindBySomethingCallsAndExecutesAQueryWithThatCriteria() {
+               $mockQueryResult = $this->getMock('Tx_Extbase_Persistence_QueryResultInterface');
+               $mockQuery = $this->getMock('Tx_Extbase_Persistence_QueryInterface');
+               $mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
+               $mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($mockQuery));
+               $mockQuery->expects($this->once())->method('execute')->with()->will($this->returnValue($mockQueryResult));
+
+               $this->repository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
+
+               $this->assertSame($mockQueryResult, $this->repository->findByFoo('bar'));
+       }
+
+       /**
+        * @test
+        */
+       public function magicCallMethodAcceptsFindOneBySomethingCallsAndExecutesAQueryWithThatCriteria() {
+               $object = new stdClass();
+               $mockQueryResult = $this->getMock('Tx_Extbase_Persistence_QueryResultInterface');
+               $mockQueryResult->expects($this->once())->method('getFirst')->will($this->returnValue($object));
+               $mockQuery = $this->getMock('Tx_Extbase_Persistence_QueryInterface');
+               $mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
+               $mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($mockQuery));
+               $mockQuery->expects($this->once())->method('execute')->will($this->returnValue($mockQueryResult));
+
+               $this->repository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
+
+               $this->assertSame($object, $this->repository->findOneByFoo('bar'));
+       }
+
+       /**
+        * @test
+        */
+       public function magicCallMethodAcceptsCountBySomethingCallsAndExecutesAQueryWithThatCriteria() {
+               $mockQueryResult = $this->getMock('Tx_Extbase_Persistence_QueryResultInterface');
+               $mockQueryResult->expects($this->once())->method('count')->will($this->returnValue(2));
+               $mockQuery = $this->getMock('Tx_Extbase_Persistence_QueryInterface');
+               $mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
+               $mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($mockQuery));
+               $mockQuery->expects($this->once())->method('execute')->will($this->returnValue($mockQueryResult));
+
+               $this->repository->expects($this->once())->method('createQuery')->will($this->returnValue($mockQuery));
+
+               $this->assertSame(2, $this->repository->countByFoo('bar'));
+       }
+
+       /**
+        * @test
+        * @expectedException Exception
+        */
+       public function magicCallMethodTriggersAnErrorIfUnknownMethodsAreCalled() {
+               $this->repository->__call('foo', array());
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Persistence_Exception_IllegalObjectType
+        */
+       public function addChecksObjectType() {
+               $this->repository->_set('objectType', 'ExpectedObjectType');
+
+               $this->repository->add(new stdClass());
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Persistence_Exception_IllegalObjectType
+        */
+       public function removeChecksObjectType() {
+               $this->repository->_set('objectType', 'ExpectedObjectType');
+
+               $this->repository->remove(new stdClass());
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Session_testcase.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Session_testcase.php
new file mode 100644 (file)
index 0000000..3d71fa6
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+require_once(PATH_tslib . 'class.tslib_content.php');
+
+class Tx_Extbase_Persistence_Session_testcase extends tx_phpunit_testcase {
+
+       /**
+        * @test
+        */
+       public function newSessionIsEmpty() {
+               $persistenceSession = new Tx_Extbase_Persistence_Session;
+               $reconstitutedObjects = $persistenceSession->getReconstitutedObjects();
+               $this->assertEquals(0, count($reconstitutedObjects), 'The reconstituted objects storage was not empty.');
+       }
+
+       /**
+        * @test
+        */
+       public function objectCanBeRegisteredAsReconstituted() {
+               $persistenceSession = new Tx_Extbase_Persistence_Session;
+               $entity = $this->getMock('Tx_Extbase_DomainObject_AbstractEntity');
+               $persistenceSession->registerReconstitutedObject($entity);
+               $reconstitutedObjects = $persistenceSession->getReconstitutedObjects();
+               $this->assertTrue($reconstitutedObjects->contains($entity), 'The object was not registered as reconstituted.');
+       }
+
+       /**
+        * @test
+        */
+       public function objectCanBeUnregisteredAsReconstituted() {
+               $persistenceSession = new Tx_Extbase_Persistence_Session;
+               $entity = $this->getMock('Tx_Extbase_DomainObject_AbstractEntity');
+               $persistenceSession->registerReconstitutedObject($entity);
+               $persistenceSession->unregisterReconstitutedObject($entity);
+               $reconstitutedObjects = $persistenceSession->getReconstitutedObjects();
+
+               $this->assertEquals(0, count($reconstitutedObjects), 'The reconstituted objects storage was not empty.');
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Storage/Typo3DbBackend_testcase.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Storage/Typo3DbBackend_testcase.php
new file mode 100644 (file)
index 0000000..08744e1
--- /dev/null
@@ -0,0 +1,155 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ *  All rights reserved
+ *
+ *  This class is a backport of the corresponding class of FLOW3.
+ *  All credits go to the v5 team.
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+class Tx_Extbase_Persistence_Storage_Typo3DbBackend_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * This is the data provider for the statement generation with a basic comparison
+        *
+        * @return array An array of data
+        */
+       public function providerForBasicComparison() {
+               return array(
+                       'equal' => array(
+                               Tx_Extbase_Persistence_QueryInterface::OPERATOR_EQUAL_TO,
+                               "SELECT table_name_from_selector.* FROM table_name_from_selector WHERE table_name_from_property.foo = 'baz'"
+                               ),
+                       'less' => array(
+                               Tx_Extbase_Persistence_QueryInterface::OPERATOR_LESS_THAN,
+                               "SELECT table_name_from_selector.* FROM table_name_from_selector WHERE table_name_from_property.foo < 'baz'"
+                               ),
+                       'less or equal' => array(
+                               Tx_Extbase_Persistence_QueryInterface::OPERATOR_LESS_THAN_OR_EQUAL_TO,
+                               "SELECT table_name_from_selector.* FROM table_name_from_selector WHERE table_name_from_property.foo <= 'baz'"
+                               ),
+                       'greater' => array(
+                               Tx_Extbase_Persistence_QueryInterface::OPERATOR_GREATER_THAN,
+                               "SELECT table_name_from_selector.* FROM table_name_from_selector WHERE table_name_from_property.foo > 'baz'"
+                               ),
+                       'greater or equal' => array(
+                               Tx_Extbase_Persistence_QueryInterface::OPERATOR_GREATER_THAN_OR_EQUAL_TO,
+                               "SELECT table_name_from_selector.* FROM table_name_from_selector WHERE table_name_from_property.foo >= 'baz'"
+                               ),
+
+                       );
+       }
+
+       /**
+        * @test
+        */
+       public function getStatementWorksWithMinimalisticQueryObjectModel() {
+               $this->markTestIncomplete();
+       }
+
+       /**
+        * @test
+        */
+       public function getStatementWorksWithBasicEqualsCondition() {
+               $this->markTestIncomplete();
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Persistence_Storage_Exception_BadConstraint
+        */
+       public function countRowsWithStatementConstraintResultsInAnException() {
+               $this->markTestIncomplete();
+       }
+
+       /**
+        * @test
+        */
+       public function joinStatementGenerationWorks() {
+               $this->markTestIncomplete();
+       }
+
+       /**
+        * @test
+        */
+       public function orderStatementGenerationWorks() {
+               $mockSource = $this->getMock('Tx_Extbase_Persistence_QOM_Selector', array('getNodeTypeName'), array(), '', FALSE);
+               $mockSource->expects($this->any())->method('getNodeTypeName')->will($this->returnValue('Tx_MyExt_ClassName'));
+
+               $mockDataMapper = $this->getMock('Tx_Extbase_Persistence_Mapper_DataMapper', array('convertPropertyNameToColumnName', 'convertClassNameToTableName'), array(), '', FALSE);
+               $mockDataMapper->expects($this->once())->method('convertClassNameToTableName')->with('Tx_MyExt_ClassName')->will($this->returnValue('tx_myext_tablename'));
+               $mockDataMapper->expects($this->once())->method('convertPropertyNameToColumnName')->with('fooProperty', 'Tx_MyExt_ClassName')->will($this->returnValue('converted_fieldname'));
+
+               $sql = array();
+               $orderings = array('fooProperty' => Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_ORDER_ASCENDING);
+               $mockTypo3DbBackend = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Storage_Typo3DbBackend'), array('parserOrderings'), array(), '', FALSE);
+               $mockTypo3DbBackend->_set('dataMapper', $mockDataMapper);
+               $mockTypo3DbBackend->_callRef('parseOrderings', $orderings, $mockSource, $sql);
+
+               $expecedSql = array('orderings' => array('tx_myext_tablename.converted_fieldname ASC'));
+               $this->assertSame($expecedSql, $sql);
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Persistence_Exception_UnsupportedOrder
+        */
+       public function orderStatementGenerationThrowsExceptionOnUnsupportedOrder() {
+               $mockSource = $this->getMock('Tx_Extbase_Persistence_QOM_Selector', array('getNodeTypeName'), array(), '', FALSE);
+               $mockSource->expects($this->never())->method('getNodeTypeName');
+
+               $mockDataMapper = $this->getMock('Tx_Extbase_Persistence_Mapper_DataMapper', array('convertPropertyNameToColumnName', 'convertClassNameToTableName'), array(), '', FALSE);
+               $mockDataMapper->expects($this->never())->method('convertClassNameToTableName');
+               $mockDataMapper->expects($this->never())->method('convertPropertyNameToColumnName');
+
+               $sql = array();
+               $orderings = array('fooProperty' => 'unsupported_order');
+               $mockTypo3DbBackend = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Storage_Typo3DbBackend'), array('parserOrderings'), array(), '', FALSE);
+               $mockTypo3DbBackend->_set('dataMapper', $mockDataMapper);
+               $mockTypo3DbBackend->_callRef('parseOrderings', $orderings, $mockSource, $sql);
+       }
+
+       /**
+        * @test
+        */
+       public function orderStatementGenerationWorksWithMultipleOrderings() {
+               $mockSource = $this->getMock('Tx_Extbase_Persistence_QOM_Selector', array('getNodeTypeName'), array(), '', FALSE);
+               $mockSource->expects($this->any())->method('getNodeTypeName')->will($this->returnValue('Tx_MyExt_ClassName'));
+
+               $mockDataMapper = $this->getMock('Tx_Extbase_Persistence_Mapper_DataMapper', array('convertPropertyNameToColumnName', 'convertClassNameToTableName'), array(), '', FALSE);
+               $mockDataMapper->expects($this->any())->method('convertClassNameToTableName')->with('Tx_MyExt_ClassName')->will($this->returnValue('tx_myext_tablename'));
+               $mockDataMapper->expects($this->any())->method('convertPropertyNameToColumnName')->will($this->returnValue('converted_fieldname'));
+
+               $sql = array();
+               $orderings = array(
+                       'fooProperty' => Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_ORDER_ASCENDING,
+                       'barProperty' => Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_ORDER_DESCENDING
+                       );
+               $mockTypo3DbBackend = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Storage_Typo3DbBackend'), array('parserOrderings'), array(), '', FALSE);
+               $mockTypo3DbBackend->_set('dataMapper', $mockDataMapper);
+               $mockTypo3DbBackend->_callRef('parseOrderings', $orderings, $mockSource, $sql);
+
+               $expecedSql = array('orderings' => array('tx_myext_tablename.converted_fieldname ASC', 'tx_myext_tablename.converted_fieldname DESC'));
+               $this->assertSame($expecedSql, $sql);
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Reflection/Service_testcase.php b/typo3/sysext/extbase/Tests/Unit/Reflection/Service_testcase.php
new file mode 100644 (file)
index 0000000..66a07aa
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Christopher Hlubek <hlubek@networkteam.com>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Some functional tests for the backport of the reflection service
+ */
+class Tx_Extbase_Reflection_Service_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @param array $foo The foo parameter
+        * @return nothing
+        */
+       public function fixtureMethodForMethodTagsValues(array $foo) {
+
+       }
+
+       public function test_GetMethodTagsValues() {
+               $service = new Tx_Extbase_Reflection_Service();
+               $tagsValues = $service->getMethodTagsValues('Tx_Extbase_Reflection_Service_testcase', 'fixtureMethodForMethodTagsValues');
+
+               $this->assertEquals(array(
+                       'param' => array('array $foo The foo parameter'),
+                       'return' => array('nothing')
+               ), $tagsValues);
+       }
+
+       public function test_GetMethodParameters() {
+               $service = new Tx_Extbase_Reflection_Service();
+               $parameters = $service->getMethodParameters('Tx_Extbase_Reflection_Service_testcase', 'fixtureMethodForMethodTagsValues');
+
+               $this->assertEquals(array(
+                       'foo' => array(
+                               'position' => 0,
+                               'byReference' => FALSE,
+                               'array' => TRUE,
+                               'optional' => FALSE,
+                               'allowsNull' => FALSE,
+                               'class' => NULL,
+                               'type' => 'array'
+                       )
+               ), $parameters);
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Security/Channel/RequestHashService_testcase.php b/typo3/sysext/extbase/Tests/Unit/Security/Channel/RequestHashService_testcase.php
new file mode 100644 (file)
index 0000000..6857541
--- /dev/null
@@ -0,0 +1,427 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Sebastian Kurfürst <sebastian@typo3.org>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the Request Hash Service
+ *
+ * @version $Id: RequestHashService_testcase.php 2334 2010-06-14 16:28:25Z sebastian $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser Public License, version 3 or later
+ */
+class Tx_Extbase_Security_Channel_RequestHashService_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       public function dataProviderForGenerateRequestHash() {
+               return array(
+                       // Simple cases
+                       array(
+                               array(),
+                               array(),
+                       ),
+                       array(
+                               array('field1'),
+                               array('field1' => 1),
+                       ),
+                       array(
+                               array('field1', 'field2'),
+                               array(
+                                       'field1' => 1,
+                                       'field2' => 1
+                               ),
+                       ),
+                       // recursion
+                       array(
+                               array('field1', 'field[subfield1]', 'field[subfield2]'),
+                               array(
+                                       'field1' => 1,
+                                       'field' => array(
+                                               'subfield1' => 1,
+                                               'subfield2' => 1
+                                       )
+                               ),
+                       ),
+                       // recursion with duplicated field name
+                       array(
+                               array('field1', 'field[subfield1]', 'field[subfield2]', 'field1'),
+                               array(
+                                       'field1' => 1,
+                                       'field' => array(
+                                               'subfield1' => 1,
+                                               'subfield2' => 1
+                                       )
+                               ),
+                       ),
+                       // Recursion with un-named fields at the end (...[]). There, they should be made explicit by increasing the counter
+                       array(
+                               array('field1', 'field[subfield1][]', 'field[subfield1][]', 'field[subfield2]'),
+                               array(
+                                       'field1' => 1,
+                                       'field' => array(
+                                               'subfield1' => array(
+                                                       0 => 1,
+                                                       1 => 1
+                                               ),
+                                               'subfield2' => 1
+                                       )
+                               ),
+                       ),
+               );
+       }
+
+       // Data provider for error cases which should throw an exception
+       public function dataProviderForGenerateRequestHashWithUnallowedValues() {
+               return array(
+                       // Overriding form fields (string overridden by array)
+                       array(
+                               array('field1', 'field2', 'field2[bla]', 'field2[blubb]'),
+                       ),
+                       array(
+                               array('field1', 'field2[bla]', 'field2[bla][blubb][blubb]'),
+                       ),
+                       // Overriding form fields (array overridden by string)
+                       array(
+                               array('field1', 'field2[bla]', 'field2[blubb]', 'field2'),
+                       ),
+                       array(
+                               array('field1', 'field2[bla][blubb][blubb]', 'field2[bla]'),
+                       ),
+                       // Empty [] not as last argument
+                       array(
+                               array('field1', 'field2[][bla]'),
+                       )
+
+               );
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @dataProvider dataProviderForGenerateRequestHash
+        */
+       public function generateRequestHashGeneratesTheCorrectHashesInNormalOperation($input, $expected) {
+               $requestHashService = $this->getMock('Tx_Extbase_Security_Channel_RequestHashService', array('serializeAndHashFormFieldArray'));
+               $requestHashService->expects($this->once())->method('serializeAndHashFormFieldArray')->with($expected);
+               $requestHashService->generateRequestHash($input);
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @dataProvider dataProviderForGenerateRequestHashWithUnallowedValues
+        * @expectedException Tx_Extbase_Security_Exception_InvalidArgumentForRequestHashGeneration
+        */
+       public function generateRequestHashThrowsExceptionInWrongCases($input) {
+               $requestHashService = $this->getMock('Tx_Extbase_Security_Channel_RequestHashService', array('serializeAndHashFormFieldArray'));
+               $requestHashService->generateRequestHash($input);
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       public function serializeAndHashFormFieldArrayWorks() {
+               $formFieldArray = array(
+                       'bla' => array(
+                               'blubb' => 1,
+                               'hu' => 1
+                       )
+               );
+               $mockHash = '12345';
+
+               $hashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Cryptography_HashService'), array('generateHash'));
+               $hashService->expects($this->once())->method('generateHash')->with(serialize($formFieldArray))->will($this->returnValue($mockHash));
+
+               $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('dummy'));
+               $requestHashService->_set('hashService', $hashService);
+
+               $expected = serialize($formFieldArray) . $mockHash;
+               $actual = $requestHashService->_call('serializeAndHashFormFieldArray', $formFieldArray);
+               $this->assertEquals($expected, $actual);
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst
+        */
+       public function verifyRequestHashSetsHmacVerifiedToFalseIfRequestDoesNotHaveAnHmacArgument() {
+               $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'setHmacVerified'));
+               $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(FALSE));
+               $request->expects($this->once())->method('setHmacVerified')->with(FALSE);
+               $requestHashService = new Tx_Extbase_Security_Channel_RequestHashService;
+               $requestHashService->verifyRequest($request);
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Security_Exception_SyntacticallyWrongRequestHash
+        * @author Sebastian Kurfürst
+        */
+       public function verifyRequestHashThrowsExceptionIfHmacIsShortherThan40Characters() {
+               $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'setHmacVerified'));
+               $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE));
+               $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue('abc'));
+               $requestHashService = new Tx_Extbase_Security_Channel_RequestHashService;
+               $requestHashService->verifyRequest($request);
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst
+        */
+       public function verifyRequestHashValidatesTheHashAndSetsHmacVerifiedToFalseIfHashCouldNotBeVerified() {
+               $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'setHmacVerified'));
+               $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE));
+               $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue('11111' . '0000000000000000000000000000000000000000'));
+               $request->expects($this->once())->method('setHmacVerified')->with(FALSE);
+
+               $hashService = $this->getMock('Tx_Extbase_Security_Cryptography_HashService', array('validateHash'));
+               $hashService->expects($this->once())->method('validateHash')->with('11111', '0000000000000000000000000000000000000000')->will($this->returnValue(FALSE));
+
+               $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('dummy'));
+               $requestHashService->_set('hashService', $hashService);
+               $requestHashService->verifyRequest($request);
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst
+        */
+       public function verifyRequestHashValidatesTheHashAndSetsHmacVerifiedToTrueIfArgumentsAreIncludedInTheAllowedArgumentList() {
+               $data = serialize(array('a' => 1));
+               $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'getArguments', 'setHmacVerified'));
+               $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE));
+               $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue($data . '0000000000000000000000000000000000000000'));
+               $request->expects($this->once())->method('getArguments')->will($this->returnValue(array(
+                       '__hmac' => 'ABC',
+                       '__referrer' => '...',
+                       'a' => 'bla'
+               )));
+               $request->expects($this->once())->method('setHmacVerified')->with(TRUE);
+
+               $hashService = $this->getMock('Tx_Extbase_Security_Cryptography_HashService', array('validateHash'));
+               $hashService->expects($this->once())->method('validateHash')->with($data, '0000000000000000000000000000000000000000')->will($this->returnValue(TRUE));
+
+               $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('checkFieldNameInclusion'));
+               $requestHashService->expects($this->once())->method('checkFieldNameInclusion')->with(array('a' => 'bla'), array('a' => 1))->will($this->returnValue(TRUE));
+               $requestHashService->_set('hashService', $hashService);
+               $requestHashService->verifyRequest($request);
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst
+        */
+       public function verifyRequestHashValidatesTheHashAndSetsHmacVerifiedToFalseIfNotAllArgumentsAreIncludedInTheAllowedArgumentList() {
+               $data = serialize(array('a' => 1));
+               $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'getArguments', 'setHmacVerified'));
+               $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE));
+               $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue($data . '0000000000000000000000000000000000000000'));
+               $request->expects($this->once())->method('getArguments')->will($this->returnValue(array(
+                       '__hmac' => 'ABC',
+                       '__referrer' => '...',
+                       'a' => 'bla',
+                       'b' => 'blubb'
+               )));
+               $request->expects($this->once())->method('setHmacVerified')->with(FALSE);
+
+               $hashService = $this->getMock('Tx_Extbase_Security_Cryptography_HashService', array('validateHash'));
+               $hashService->expects($this->once())->method('validateHash')->with($data, '0000000000000000000000000000000000000000')->will($this->returnValue(TRUE));
+
+               $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('checkFieldNameInclusion'));
+               $requestHashService->expects($this->once())->method('checkFieldNameInclusion')->with(array('a' => 'bla', 'b' => 'blubb'), array('a' => 1))->will($this->returnValue(FALSE));
+               $requestHashService->_set('hashService', $hashService);
+               $requestHashService->verifyRequest($request);
+       }
+
+       /**
+        * Data Provider for checkFieldNameInclusionWorks
+        */
+       public function dataProviderForCheckFieldNameInclusion() {
+               return array(
+                       // Simple fields with requestfields = responsefields
+                       array(
+                               // Request
+                               array(
+                                       'a' => 'X',
+                                       'b' => 'X',
+                                       'c' => 'X'
+                               ),
+                               // Allowed
+                               array(
+                                       'a' => 1,
+                                       'b' => 1,
+                                       'c' => 1
+                               ),
+                               // Expected result
+                               TRUE
+                       ),
+                       // Simple fields with requestfields < responsefields
+                       array(
+                               // Request
+                               array(
+                                       'a' => 'X',
+                                       'c' => 'X'
+                               ),
+                               // Allowed
+                               array(
+                                       'a' => 1,
+                                       'b' => 1,
+                                       'c' => 1
+                               ),
+                               // Expected result
+                               TRUE
+                       ),
+                       // Simple fields with requestfields > responsefields
+                       array(
+                               // Request
+                               array(
+                                       'a' => 'X',
+                                       'b' => 'X',
+                                       'c' => 'X'
+                               ),
+                               // Allowed
+                               array(
+                                       'a' => 1,
+                                       'b' => 1
+                               ),
+                               // Expected result
+                               FALSE
+                       ),
+                       // Hierarchical fields with requestfields < responsefields
+                       array(
+                               // Request
+                               array(
+                                       'a' => array(
+                                               'b' => 'X'
+                                       ),
+                                       'c' => 'X'
+                               ),
+                               // Allowed
+                               array(
+                                       'a' => array(
+                                               'b' => 1,
+                                               'abc' => 1
+                                       ),
+                                       'c' => 1
+                               ),
+                               // Expected result
+                               TRUE
+                       ),
+                       // Hierarchical fields with requestfields > responsefields
+                       array(
+                               // Request
+                               array(
+                                       'a' => array(
+                                               'b' => 'X',
+                                               'abc' => 'X'
+                                       ),
+                                       'c' => 'X'
+                               ),
+                               // Allowed
+                               array(
+                                       'a' => array(
+                                               'b' => 1
+                                       ),
+                                       'c' => 1
+                               ),
+                               // Expected result
+                               FALSE
+                       ),
+                       // hierarchical fields with requestfields != responsefields (different types) - 1
+                       array(
+                               // Request
+                               array(
+                                       'a' => array(
+                                               'b' => 'X',
+                                               'c' => 'X'
+                                       ),
+                                       'b' => 'X',
+                                       'c' => 'X'
+                               ),
+                               // Allowed
+                               array(
+                                       'a' => 1,
+                                       'b' => 1,
+                                       'c' => 1
+                               ),
+                               // Expected result
+                               FALSE
+                       ),
+                       // hierarchical fields with requestfields != responsefields (different types) - 2
+                       array(
+                               // Request
+                               array(
+                                       'a' => 'X',
+                                       'b' => 'X',
+                                       'c' => 'X'
+                               ),
+                               // Allowed
+                               array(
+                                       'a' => array(
+                                               'x' => 1,
+                                               'y' => 1
+                                       ),
+                                       'b' => 1,
+                                       'c' => 1
+                               ),
+                               // Expected result
+                               FALSE
+                       ),
+
+                       // hierarchical fields with requestfields != responsefields (different types)
+                       // This case happens if an array of checkboxes is rendered, in case they are fully unchecked.
+                       array(
+                               // Request
+                               array(
+                                       'a' => '', // this is the only allowed value.
+                                       'b' => 'X',
+                                       'c' => 'X'
+                               ),
+                               // Allowed
+                               array(
+                                       'a' => array(
+                                               'x' => 1,
+                                               'y' => 1
+                                       ),
+                                       'b' => 1,
+                                       'c' => 1
+                               ),
+                               // Expected result
+                               TRUE
+                       ),
+               );
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @dataProvider dataProviderForCheckFieldNameInclusion
+        */
+       public function checkFieldNameInclusionWorks($requestArguments, $allowedFields, $expectedResult) {
+               $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('dummy'));
+               $this->assertEquals($expectedResult, $requestHashService->_call('checkFieldNameInclusion', $requestArguments, $allowedFields));
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Security/Cryptography/HashService_testcase.php b/typo3/sysext/extbase/Tests/Unit/Security/Cryptography/HashService_testcase.php
new file mode 100644 (file)
index 0000000..81841a8
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Sebastian Kurfürst <sebastian@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the Hash Service
+ *
+ * @version $Id: HashService_testcase.php 1729 2009-11-25 21:37:20Z stucki $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser Public License, version 3 or later
+ */
+class Tx_Extbase_Security_Cryptography_HashService_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       protected $hashService;
+
+       public function setUp() {
+               $this->hashService = new Tx_Extbase_Security_Cryptography_HashService();
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst
+        */
+       public function generateHashReturnsHashStringIfStringIsGiven() {
+               $hash = $this->hashService->generateHash('asdf');
+               $this->assertTrue(is_string($hash));
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst
+        */
+       public function generateHashReturnsHashStringWhichContainsSomeSalt() {
+               $hash = $this->hashService->generateHash('asdf');
+               $this->assertNotEquals(sha1('asdf'), $hash);
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst
+        */
+       public function generateHashReturnsDifferentHashStringsForDifferentInputStrings() {
+               $hash1 = $this->hashService->generateHash('asdf');
+               $hash2 = $this->hashService->generateHash('blubb');
+               $this->assertNotEquals($hash1, $hash2);
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Security_Exception_InvalidArgumentForHashGeneration
+        * @author Sebastian Kurfürst
+        */
+       public function generateHashThrowsExceptionIfNoStringGiven() {
+               $hash = $this->hashService->generateHash(NULL);
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       public function generatedHashCanBeValidatedAgain() {
+               $string = 'asdf';
+               $hash = $this->hashService->generateHash($string);
+               $this->assertTrue($this->hashService->validateHash($string, $hash));
+       }
+
+       /**
+        * @test
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       public function generatedHashWillNotBeValidatedIfHashHasBeenChanged() {
+               $string = 'asdf';
+               $hash = 'myhash';
+               $this->assertFalse($this->hashService->validateHash($string, $hash));
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Utility/Extension_testcase.php b/typo3/sysext/extbase/Tests/Unit/Utility/Extension_testcase.php
new file mode 100644 (file)
index 0000000..5ed56e5
--- /dev/null
@@ -0,0 +1,518 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Oliver Hader <oliver@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for class Tx_Extbase_Utility_Extension
+ *
+ * @package Extbase
+ * @subpackage extbase
+ */
+class Tx_Extbase_Utility_Extension_testcase extends tx_phpunit_testcase {
+
+       /**
+        * Contains backup of $TYPO3_CONF_VARS
+        * @var array
+        */
+       protected $typo3ConfVars = array();
+
+       /**
+        * @var t3lib_DB
+        */
+       protected $typo3DbBackup;
+
+       /**
+        * @var t3lib_fe contains a backup of the current $GLOBALS['TSFE']
+        */
+       protected $tsfeBackup;
+
+       public function setUp() {
+               global $TYPO3_CONF_VARS;
+               $this->typo3ConfVars = $TYPO3_CONF_VARS;
+               $this->typo3DbBackup = $GLOBALS['TYPO3_DB'];
+               $GLOBALS['TYPO3_DB'] = $this->getMock('t3lib_DB', array('fullQuoteStr', 'exec_SELECTgetRows'));
+               $this->tsfeBackup = $GLOBALS['TSFE'];
+               if (!isset($GLOBALS['TSFE']->tmpl)) {
+                       $GLOBALS['TSFE']->tmpl = new stdClass();
+               }
+               if (!isset($GLOBALS['TSFE']->tmpl->setup)) {
+                       $GLOBALS['TSFE']->tmpl->setup = array();
+               }
+               $GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.'] = array(
+                       '9' => 'CASE',
+                       '9.' => array(
+                               'key.' => array(
+                                       'field' => 'layout'),
+                                       0 => '< plugin.tt_news'
+                               ),
+                       'extensionname_someplugin' => 'USER',
+                       'extensionname_someplugin.' => array(
+                               'userFunc' => 'tx_extbase_dispatcher->dispatch',
+                               'pluginName' => 'SomePlugin',
+                               'extensionName' => 'ExtensionName',
+                               'controller' => 'ControllerName',
+                               'action' => 'index',
+                               'switchableControllerActions.' => array(
+                                       'ControllerName.' => array(
+                                               'actions' => 'index,otherAction',
+                                       ),
+                               ),
+                       ),
+                       'someotherextensionname_secondplugin' => 'USER',
+                       'someotherextensionname_secondplugin.' => array(
+                               'userFunc' => 'tx_extbase_dispatcher->dispatch',
+                               'pluginName' => 'SecondPlugin',
+                               'extensionName' => 'SomeOtherExtensionName',
+                               'controller' => 'ControllerName',
+                               'action' => 'index',
+                               'switchableControllerActions.' => array(
+                                       'ControllerName.' => array(
+                                               'actions' => 'index,otherAction',
+                                       ),
+                                       'SecondControllerName.' => array(
+                                               'actions' => 'someAction,someOtherAction',
+                                               'nonCacheableActions' => 'someOtherAction',
+                                       ),
+                               ),
+                       ),
+                       'extensionname_thirdplugin' => 'USER',
+                       'extensionname_thirdplugin.' => array(
+                               'userFunc' => 'tx_extbase_dispatcher->dispatch',
+                               'pluginName' => 'ThirdPlugin',
+                               'extensionName' => 'ExtensionName',
+                               'controller' => 'ControllerName',
+                               'action' => 'index',
+                               'switchableControllerActions.' => array(
+                                       'ControllerName.' => array(
+                                               'actions' => 'otherAction,thirdAction',
+                                       ),
+                               ),
+                       ),
+               );
+       }
+
+       public function tearDown() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS = $this->typo3ConfVars;
+               $GLOBALS['TSFE'] = $this->tsfeBackup;
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Extension::registerPlugin
+        */
+       public function configurePluginWorksForMinimalisticSetup() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Extension::configurePlugin(
+                       'MyExtension',
+                       'Pi1',
+                       array('Blog' => 'index')
+               );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
+               $this->assertContains('
+       pluginName = Pi1
+       extensionName = MyExtension', $staticTypoScript);
+
+       $this->assertNotContains('USER_INT', $staticTypoScript);
+       }
+
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Extension::registerPlugin
+        */
+       public function configurePluginCreatesCorrectDefaultTypoScriptSetup() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Extension::configurePlugin(
+                       'MyExtension',
+                       'Pi1',
+                       array('Blog' => 'index')
+               );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+               $defaultTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup'];
+               $this->assertContains('tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
+               $this->assertContains('
+plugin.tx_myextension {
+       settings {
+       }
+       persistence {
+               storagePid =
+               classes {
+               }
+       }
+       view {
+               templateRootPath =
+               layoutRootPath =
+               partialRootPath =
+                # with defaultPid you can specify the default page uid of this plugin. If you set this to the string "auto" the target page will be determined automatically. Defaults to an empty string that expects the target page to be the current page.
+               defaultPid =
+       }
+}', $defaultTypoScript);
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Extension::registerPlugin
+        */
+       public function configurePluginWorksForASingleControllerAction() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Extension::configurePlugin(
+                       'MyExtension',
+                       'Pi1',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
+               $this->assertContains('
+       pluginName = Pi1
+       extensionName = MyExtension', $staticTypoScript);
+               $this->assertContains('
+       controller = FirstController
+       action = index', $staticTypoScript);
+               $this->assertNotContains('USER_INT', $staticTypoScript);
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Extension::registerPlugin
+        */
+       public function configurePluginWithEmptyPluginNameResultsInAnError() {
+               $this->setExpectedException('InvalidArgumentException');
+               Tx_Extbase_Utility_Extension::configurePlugin(
+                       'MyExtension',
+                       '',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Extension::registerPlugin
+        */
+       public function configurePluginWithEmptyExtensionNameResultsInAnError() {
+               $this->setExpectedException('InvalidArgumentException');
+               Tx_Extbase_Utility_Extension::configurePlugin(
+                       '',
+                       'Pi1',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Extension::registerPlugin
+        */
+       public function configurePluginRespectsDefaultActionAsANonCacheableAction() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Extension::configurePlugin(
+                       'MyExtension',
+                       'Pi1',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update'
+                               ),
+                       array(
+                               'FirstController' => 'index,show'
+                               )
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+               $this->assertContains('
+tt_content.list.20.myextension_pi1 = USER
+tt_content.list.20.myextension_pi1 {', $staticTypoScript);
+               $this->assertContains('FirstController.nonCacheableActions = index,show
+', $staticTypoScript);
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Extension::registerPlugin
+        */
+       public function configurePluginRespectsNonDefaultActionAsANonCacheableAction() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Extension::configurePlugin(
+                       'MyExtension',
+                       'Pi1',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update'
+                               ),
+                       array(
+                               'FirstController' => 'show,new'
+                               )
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('
+tt_content.list.20.myextension_pi1 = USER
+tt_content.list.20.myextension_pi1 {', $staticTypoScript);
+               $this->assertContains('FirstController.nonCacheableActions = show,new
+', $staticTypoScript);
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Extension::registerPlugin
+        */
+       public function configurePluginWorksForMultipleControllerActionsWithCacheableActionAsDefault() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Extension::configurePlugin(
+                       'MyExtension',
+                       'Pi1',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update',
+                               'SecondController' => 'index,show,delete',
+                               'ThirdController' => 'create'
+                               ),
+                       array(
+                               'FirstController' => 'new,create,edit,update',
+                               'SecondController' => 'delete',
+                               'ThirdController' => 'create'
+                               )
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('
+tt_content.list.20.myextension_pi1 = USER
+tt_content.list.20.myextension_pi1 {', $staticTypoScript);
+
+               $this->assertContains('FirstController.nonCacheableActions = new,create,edit,update
+', $staticTypoScript);
+
+               $this->assertContains('SecondController.nonCacheableActions = delete
+', $staticTypoScript);
+
+               $this->assertContains('ThirdController.nonCacheableActions = create
+', $staticTypoScript);
+       }
+
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Extension::registerPlugin
+        */
+       public function configurePluginWorksForMultipleControllerActionsWithNonCacheableActionAsDefault() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Extension::configurePlugin(
+                       'MyExtension',
+                       'Pi1',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update',
+                               'SecondController' => 'index,show,delete',
+                               'ThirdController' => 'create'
+                               ),
+                       array(
+                               'FirstController' => 'index,new,create,edit,update',
+                               'SecondController' => 'delete',
+                               'ThirdController' => 'create'
+                               )
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('
+tt_content.list.20.myextension_pi1 = USER
+tt_content.list.20.myextension_pi1 {', $staticTypoScript);
+
+               $this->assertContains('FirstController.nonCacheableActions = index,new,create,edit,update
+', $staticTypoScript);
+
+               $this->assertContains('SecondController.nonCacheableActions = delete
+', $staticTypoScript);
+
+               $this->assertContains('ThirdController.nonCacheableActions = create
+', $staticTypoScript);
+       }
+
+       /**
+        * DataProvider for getPluginNamespaceByPluginSignatureTests()
+        *
+        * @return array
+        */
+       public function getPluginNamespaceByPluginSignatureDataProvider() {
+               return array(
+                       array('someextension_someplugin', 'tx_someextension_someplugin'),
+                       array('nonexistingextension_someplugin', 'tx_nonexistingextension_someplugin'),
+                       array('InvalidPluginNamespace', 'tx_InvalidPluginNamespace'),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider getPluginNamespaceByPluginSignatureDataProvider
+        */
+       public function getPluginNamespaceByPluginSignatureTests($pluginSignature, $expectedResult) {
+               $dispatcher = new Tx_Extbase_Dispatcher();
+               $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_ConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'getTypoScriptSetup'));
+               $dispatcher->injectConfigurationManager($mockConfigurationManager);
+               $actualResult = Tx_Extbase_Utility_Extension::getPluginNamespaceByPluginSignature($pluginSignature);
+               $this->assertEquals($expectedResult, $actualResult, 'Failing for $pluginSignature: "' . $pluginSignature . '"');
+       }
+
+       /**
+        * @test
+        */
+       public function pluginNamespaceCanBeOverridden() {
+               $dispatcher = new Tx_Extbase_Dispatcher();
+               $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_ConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'getTypoScriptSetup', 'getConfiguration'));
+               $mockConfigurationManager->expects($this->once())->method('getConfiguration')->will($this->returnValue(array('view' => array('pluginNamespace' => 'overridden_plugin_namespace'))));
+               $dispatcher->injectConfigurationManager($mockConfigurationManager);
+               $expectedResult = 'overridden_plugin_namespace';
+               $actualResult = Tx_Extbase_Utility_Extension::getPluginNamespaceByPluginSignature('somePluginSignature');
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * DataProvider for getPluginNameByActionTests()
+        *
+        * @return array
+        */
+       public function getPluginNameByActionDataProvider() {
+               return array(
+                       array('ExtensionName', 'ControllerName', 'someNonExistingAction', NULL),
+                       array('ExtensionName', 'ControllerName', 'index', 'SomePlugin'),
+                       array('ExtensionName', 'ControllerName', 'thirdAction', 'ThirdPlugin'),
+                       array('eXtEnSiOnNaMe', 'cOnTrOlLeRnAmE', 'thirdAction', 'ThirdPlugin'),
+                       array('eXtEnSiOnNaMe', 'cOnTrOlLeRnAmE', 'ThIrDaCtIoN', NULL),
+                       array('SomeOtherExtensionName', 'ControllerName', 'otherAction', 'SecondPlugin'),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider getPluginNameByActionDataProvider
+        */
+       public function getPluginNameByActionTests($extensionName, $controllerName, $actionName, $expectedResult) {
+               $actualResult = Tx_Extbase_Utility_Extension::getPluginNameByAction($extensionName, $controllerName, $actionName);
+               $this->assertEquals($expectedResult, $actualResult, 'Failing for $extensionName: "' . $extensionName . '", $controllerName: "' . $controllerName . '", $actionName: "' . $actionName . '" - ');
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Exception
+        */
+       public function getPluginNameByActionThrowsExceptionIfMoreThanOnePluginMatches() {
+               Tx_Extbase_Utility_Extension::getPluginNameByAction('ExtensionName', 'ControllerName', 'otherAction');
+       }
+
+       /**
+        * @test
+        */
+       public function getTargetPidByPluginSignatureReturnsNullIfConfigurationManagerIsNotInitialized() {
+               $this->assertNull(Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature('plugin_signature'));
+       }
+
+       /**
+        * @test
+        */
+       public function getTargetPidByPluginSignatureReturnsNullIfDefaultPidIsNotConfigured() {
+               $dispatcher = new Tx_Extbase_Dispatcher();
+               $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_ConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'getTypoScriptSetup', 'getConfiguration'));
+               $mockConfigurationManager->expects($this->once())->method('getConfiguration')->with($GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['extensionname_someplugin.'])->will($this->returnValue(array()));
+               $dispatcher->injectConfigurationManager($mockConfigurationManager);
+               $this->assertNull(Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature('extensionname_someplugin'));
+       }
+
+       /**
+        * @test
+        */
+       public function getTargetPidByPluginSignatureReturnsTheConfiguredDefaultPid() {
+               $dispatcher = new Tx_Extbase_Dispatcher();
+               $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_ConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'getTypoScriptSetup', 'getConfiguration'));
+               $mockConfigurationManager->expects($this->once())->method('getConfiguration')->with($GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['extensionname_someplugin.'])->will($this->returnValue(array('view' => array('defaultPid' => '123'))));
+               $dispatcher->injectConfigurationManager($mockConfigurationManager);
+               $expectedResult = 123;
+               $actualResult = Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature('extensionname_someplugin');
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function getTargetPidByPluginSignatureDeterminesTheTargetPidIfDefaultPidIsAuto() {
+               $dispatcher = new Tx_Extbase_Dispatcher();
+               $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_ConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'getTypoScriptSetup', 'getConfiguration'));
+               $mockConfigurationManager->expects($this->once())->method('getConfiguration')->with($GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['extensionname_someplugin.'])->will($this->returnValue(array('view' => array('defaultPid' => 'auto'))));
+               $dispatcher->injectConfigurationManager($mockConfigurationManager);
+               $pluginSignature = 'extensionname_someplugin';
+               $GLOBALS['TSFE']->sys_page = $this->getMock('t3lib_pageSelect', array('enableFields'));
+               $GLOBALS['TSFE']->sys_page->expects($this->once())->method('enableFields')->with('tt_content')->will($this->returnValue(' AND enable_fields'));
+               $GLOBALS['TYPO3_DB']->expects($this->once())->method('fullQuoteStr')->with($pluginSignature, 'tt_content')->will($this->returnValue('"pluginSignature"'));
+               $GLOBALS['TYPO3_DB']->expects($this->once())->method('exec_SELECTgetRows')->with(
+                       'pid',
+                       'tt_content',
+                       'list_type="pluginSignature" AND enable_fields',
+                       '',
+                       ''
+               )->will($this->returnValue(array(array('pid' => '321'))));
+               $expectedResult = 321;
+               $actualResult = Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature($pluginSignature);
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function getTargetPidByPluginSignatureReturnsNullIfTargetPidCouldNotBeDetermined() {
+               $dispatcher = new Tx_Extbase_Dispatcher();
+               $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_ConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'getTypoScriptSetup', 'getConfiguration'));
+               $mockConfigurationManager->expects($this->once())->method('getConfiguration')->with($GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['extensionname_someplugin.'])->will($this->returnValue(array('view' => array('defaultPid' => 'auto'))));
+               $dispatcher->injectConfigurationManager($mockConfigurationManager);
+               $GLOBALS['TSFE']->sys_page = $this->getMock('t3lib_pageSelect', array('enableFields'));
+               $GLOBALS['TSFE']->sys_page->expects($this->once())->method('enableFields')->will($this->returnValue(' AND enable_fields'));
+               $GLOBALS['TYPO3_DB']->expects($this->once())->method('fullQuoteStr')->will($this->returnValue('"pluginSignature"'));
+               $GLOBALS['TYPO3_DB']->expects($this->once())->method('exec_SELECTgetRows')->will($this->returnValue(array()));
+               $this->assertNull(Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature('extensionname_someplugin'));
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Exception
+        */
+       public function getTargetPidByPluginSignatureThrowsExceptionIfMoreThanOneTargetPidsWereFound() {
+               $dispatcher = new Tx_Extbase_Dispatcher();
+               $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_ConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'getTypoScriptSetup', 'getConfiguration'));
+               $mockConfigurationManager->expects($this->once())->method('getConfiguration')->with($GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['extensionname_someplugin.'])->will($this->returnValue(array('view' => array('defaultPid' => 'auto'))));
+               $dispatcher->injectConfigurationManager($mockConfigurationManager);
+               $GLOBALS['TSFE']->sys_page = $this->getMock('t3lib_pageSelect', array('enableFields'));
+               $GLOBALS['TSFE']->sys_page->expects($this->once())->method('enableFields')->will($this->returnValue(' AND enable_fields'));
+               $GLOBALS['TYPO3_DB']->expects($this->once())->method('fullQuoteStr')->will($this->returnValue('"pluginSignature"'));
+               $GLOBALS['TYPO3_DB']->expects($this->once())->method('exec_SELECTgetRows')->will($this->returnValue(array(array('pid' => 123), array('pid' => 124))));
+               Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature('extensionname_someplugin');
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Utility/TypoScript_testcase.php b/typo3/sysext/extbase/Tests/Unit/Utility/TypoScript_testcase.php
new file mode 100644 (file)
index 0000000..428e95b
--- /dev/null
@@ -0,0 +1,243 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Christian Müller <christian@kitsunet.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+
+/**
+ * Testcase for class Tx_Extbase_Utility_TypoScript
+ *
+ * @package Extbase
+ * @subpackage extbase
+ */
+
+class Tx_Extbase_Utility_TypoScript_testcase extends tx_phpunit_testcase {
+
+       /**
+        * @return array
+        */
+       public function convertTypoScriptArrayToPlainArrayTestdata(){
+               $testdata = array();
+               //convert TypoScript Array To Plain Array Removes Trailing Dots
+               $testdata[0] = array(
+                       'typoScriptSettings' => array(
+                               '10.' => array(
+                                       'value' => 'Hello World!',
+                                       'foo.' => array(
+                                               'bar' => 5,
+                                               ),
+                                       ),
+                               '10' => 'TEXT', // This line was moved down
+                               ),
+                       'expectedSettings' => array(
+                               '10' => array(
+                                       'value' => 'Hello World!',
+                                       'foo' => array(
+                                               'bar' => 5,
+                                               ),
+                                       '_typoScriptNodeValue' => 'TEXT',
+                               ),
+                       )               
+               );
+               
+               //convert TypoScript Array To Plain Array Removes Trailing Dots With Changed Order In The TypoScript Array
+               $testdata[1] = array(
+                       'typoScriptSettings' => array(
+                               '10' => 'TEXT',
+                               '10.' => array(
+                                       'value' => 'Hello World!',
+                                       'foo.' => array(
+                                               'bar' => 5,
+                                       ),
+                               ),
+                       ),
+                       'expectedSettings' => array(
+                               '10' => array(
+                                       'value' => 'Hello World!',
+                                       'foo' => array(
+                                               'bar' => 5,
+                                               ),
+                                       '_typoScriptNodeValue' => 'TEXT',
+                               ),
+                       )       
+               );
+               
+               $testdata[2] = array(
+                       'typoScriptSettings' => array(
+                               '10' => 'COA',
+                               '10.' => array(
+                                       '10' => 'TEXT',
+                                       '10.' => array(
+                                               'value' => 'Hello World!',
+                                               'foo.' => array(
+                                                       'bar' => 5,
+                                               )
+                                       ),
+                                       '20' => 'COA',
+                                       '20.' => array(
+                                               '10' => 'TEXT',
+                                               '10.' => array(
+                                                       'value' => 'Test',
+                                                       'wrap' => '[|]'
+                                               ),
+                                               '20' => 'TEXT',
+                                               '20.' => array(
+                                                       'value' => 'Test',
+                                                       'wrap' => '[|]'
+                                               )
+                                       ),
+                                       '30' => 'custom'
+                               ),
+                       ),
+                       'expectedSettings' => array(
+                               '10' => array(
+                                       '10' => array(
+                                               'value' => 'Hello World!',
+                                               'foo' => array(
+                                                       'bar' => 5,
+                                                       ),
+                                               '_typoScriptNodeValue' => 'TEXT'        
+                                       ),
+                                       '20' => array(
+                                                       '10' => array(
+                                                               'value' => 'Test',
+                                                               'wrap' => '[|]',
+                                                               '_typoScriptNodeValue' => 'TEXT',                                       
+                                                       ),
+                                                       '20' => array(
+                                                               'value' => 'Test',
+                                                               'wrap' => '[|]',                                                        
+                                                               '_typoScriptNodeValue' => 'TEXT',
+                                                       ),
+                                                       '_typoScriptNodeValue' => 'COA',
+                                               ),
+                                       '30' => 'custom',
+                                       '_typoScriptNodeValue' => 'COA',
+                               ),
+                       )       
+               );                      
+               
+               return $testdata;
+               
+       }
+       
+       /**
+        * @test
+        * @dataProvider convertTypoScriptArrayToPlainArrayTestdata
+        */
+       public function convertTypoScriptArrayToPlainArrayRemovesTrailingDotsWithChangedOrderInTheTypoScriptArray($typoScriptSettings,$expectedSettings) {
+               $processedSettings = Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($typoScriptSettings);
+               $this->assertEquals($expectedSettings, $processedSettings);
+       }
+
+
+       /**
+        * Dataprovider for testcase "convertPlainArrayToTypoScriptArray"
+        * 
+        * @return array
+        */
+       public function convertPlainArrayToTypoScriptArrayTestdata() {
+               $testdata = array();
+               
+               $testdata[0] = array(
+                       'extbaseTS' => array(
+                               '10' => array(
+                                       'value' => 'Hallo',
+                                       '_typoScriptNodeValue' => 'TEXT'
+                               )
+                       ),
+       
+                       'classic' => array(
+                               '10' => 'TEXT',
+                               '10.' => array(
+                                       'value' => 'Hallo'
+                               )
+                       )
+               );
+
+               $testdata[1] = array(
+                       'extbaseTS' => array(
+                               '10' => array(
+                                       '10' => array(
+                                               'value' => 'Hello World!',
+                                               'foo' => array(
+                                                       'bar' => 5,
+                                                       ),
+                                               '_typoScriptNodeValue' => 'TEXT'        
+                                       ),
+                                       '20' => array(
+                                                       '10' => array(
+                                                               'value' => 'Test',
+                                                               'wrap' => '[|]',
+                                                               '_typoScriptNodeValue' => 'TEXT',                                       
+                                                       ),
+                                                       '20' => array(
+                                                               'value' => 'Test',
+                                                               'wrap' => '[|]',                                                        
+                                                               '_typoScriptNodeValue' => 'TEXT',
+                                                       ),
+                                                       '_typoScriptNodeValue' => 'COA',
+                                               ),
+                                       '_typoScriptNodeValue' => 'COA',
+                               ),
+                       ),
+       
+                       'classic' => array(
+                               '10' => 'COA',
+                               '10.' => array(
+                                       '10' => 'TEXT',
+                                       '10.' => array(
+                                               'value' => 'Hello World!',
+                                               'foo.' => array(
+                                                       'bar' => 5,
+                                               )
+                                       ),
+                                       '20' => 'COA',
+                                       '20.' => array(
+                                               '10' => 'TEXT',
+                                               '10.' => array(
+                                                       'value' => 'Test',
+                                                       'wrap' => '[|]'
+                                               ),
+                                               '20' => 'TEXT',
+                                               '20.' => array(
+                                                       'value' => 'Test',
+                                                       'wrap' => '[|]'
+                                               )
+                                       )
+                               )
+                       )
+               );
+               
+               return $testdata;
+       }
+       
+       /**
+        * @test
+        * @dataProvider convertPlainArrayToTypoScriptArrayTestdata
+        */
+       public function convertPlainArrayToTypoScriptArray($extbaseTS, $classic) {
+               $converted = Tx_Extbase_Utility_TypoScript::convertPlainArrayToTypoScriptArray($extbaseTS);
+               $this->assertEquals($converted, $classic);
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/AlphanumericValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/AlphanumericValidator_testcase.php
new file mode 100644 (file)
index 0000000..f9dec9d
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the alphanumeric validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: AlphanumericValidator_testcase.php 2428 2010-07-20 10:18:51Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_AlphanumericValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function alphanumericValidatorReturnsTrueForAnAlphanumericString() {
+               $alphanumericValidator = new Tx_Extbase_Validation_Validator_AlphanumericValidator();
+               $this->assertTrue($alphanumericValidator->isValid('12ssDF34daweidf'));
+       }
+
+       /**
+        * @test
+        */
+       public function alphanumericValidatorReturnsFalseForAStringWithSpecialCharacters() {
+       $alphanumericValidator = $this->getMock('Tx_Extbase_Validation_Validator_AlphanumericValidator', array('addError'), array(), '', FALSE);
+       $this->assertFalse($alphanumericValidator->isValid('adsf%&/$jklsfdö'));
+       }
+
+       /**
+        * @test
+        */
+       public function alphanumericValidatorCreatesTheCorrectErrorForAnInvalidSubject() {
+               $alphanumericValidator = $this->getMock('Tx_Extbase_Validation_Validator_AlphanumericValidator', array('addError'), array(), '', FALSE);
+               $alphanumericValidator->expects($this->once())->method('addError')->with('The given subject was not a valid alphanumeric string.', 1221551320);
+               $alphanumericValidator->isValid('adsf%&/$jklsfdö');
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/ConjunctionValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/ConjunctionValidator_testcase.php
new file mode 100644 (file)
index 0000000..fd86cfa
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the Conjunction Validators
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: ConjunctionValidator_testcase.php 1729 2009-11-25 21:37:20Z stucki $
+ */
+class Tx_Extbase_Validation_Validator_ConjunctionValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function addingValidatorsToAJunctionValidatorWorks() {
+               $proxyClassName = $this->buildAccessibleProxy('Tx_Extbase_Validation_Validator_ConjunctionValidator');
+               $conjunctionValidator = new $proxyClassName;
+
+               $mockValidator = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+               $conjunctionValidator->addValidator($mockValidator);
+               $this->assertTrue($conjunctionValidator->_get('validators')->contains($mockValidator));
+       }
+
+       /**
+        * @test
+        */
+       public function allValidatorsInTheConjunctionAreCalledEvenIfOneReturnsFalse() {
+               $validatorConjunction = new Tx_Extbase_Validation_Validator_ConjunctionValidator();
+               $validatorObject = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+               $validatorObject->expects($this->once())->method('isValid')->will($this->returnValue(TRUE));
+
+               $secondValidatorObject = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+               $secondValidatorObject->expects($this->once())->method('isValid')->will($this->returnValue(FALSE));
+               $secondValidatorObject->expects($this->any())->method('getErrors')->will($this->returnValue(array()));
+
+               $thirdValidatorObject = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+               $thirdValidatorObject->expects($this->once())->method('isValid')->will($this->returnValue(TRUE));
+
+               $validatorConjunction->addValidator($validatorObject);
+               $validatorConjunction->addValidator($secondValidatorObject);
+               $validatorConjunction->addValidator($thirdValidatorObject);
+
+               $validatorConjunction->isValid('some subject');
+       }
+
+       /**
+        * @test
+        */
+       public function validatorConjunctionReturnsTrueIfAllJunctionedValidatorsReturnTrue() {
+               $validatorConjunction = new Tx_Extbase_Validation_Validator_ConjunctionValidator();
+               $validatorObject = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+               $validatorObject->expects($this->any())->method('isValid')->will($this->returnValue(TRUE));
+
+               $secondValidatorObject = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+               $secondValidatorObject->expects($this->any())->method('isValid')->will($this->returnValue(TRUE));
+
+               $validatorConjunction->addValidator($validatorObject);
+               $validatorConjunction->addValidator($secondValidatorObject);
+
+               $this->assertTrue($validatorConjunction->isValid('some subject'));
+       }
+
+       /**
+        * @test
+        */
+       public function validatorConjunctionReturnsFalseIfOneValidatorReturnsFalse() {
+               $validatorConjunction = new Tx_Extbase_Validation_Validator_ConjunctionValidator();
+               $validatorObject = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+               $validatorObject->expects($this->any())->method('isValid')->will($this->returnValue(FALSE));
+               $validatorObject->expects($this->any())->method('getErrors')->will($this->returnValue(array()));
+
+               $validatorConjunction->addValidator($validatorObject);
+
+               $this->assertFalse($validatorConjunction->isValid('some subject'));
+       }
+
+       /**
+        * @test
+        */
+       public function removingAValidatorOfTheValidatorConjunctionWorks() {
+               $validatorConjunction = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Validation_Validator_ConjunctionValidator'), array('dummy'), array(), '', TRUE);
+
+               $validator1 = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+               $validator2 = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+
+               $validatorConjunction->addValidator($validator1);
+               $validatorConjunction->addValidator($validator2);
+
+               $validatorConjunction->removeValidator($validator1);
+
+               $this->assertFalse($validatorConjunction->_get('validators')->contains($validator1));
+               $this->assertTrue($validatorConjunction->_get('validators')->contains($validator2));
+       }
+
+       /**
+        * @test
+        * @expectedException Tx_Extbase_Validation_Exception_NoSuchValidator
+        */
+       public function removingANotExistingValidatorIndexThrowsException() {
+               $validatorConjunction = new Tx_Extbase_Validation_Validator_ConjunctionValidator();
+               $validator = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+               $validatorConjunction->removeValidator($validator);
+       }
+
+       /**
+        * @test
+        */
+       public function countReturnesTheNumberOfValidatorsContainedInTheConjunction() {
+               $validatorConjunction = new Tx_Extbase_Validation_Validator_ConjunctionValidator();
+
+               $validator1 = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+               $validator2 = $this->getMock('Tx_Extbase_Validation_Validator_ValidatorInterface');
+
+               $this->assertSame(0, count($validatorConjunction));
+
+               $validatorConjunction->addValidator($validator1);
+               $validatorConjunction->addValidator($validator2);
+
+               $this->assertSame(2, count($validatorConjunction));
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/DateTimeValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/DateTimeValidator_testcase.php
new file mode 100644 (file)
index 0000000..bba253f
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the DateTime validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: DateTimeValidator_testcase.php 1408 2009-10-08 13:15:09Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_DateTimeValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function dateTimeValidatorReturnsTrueForAValidDateTimeObject() {
+               $dateTimeValidator = new Tx_Extbase_Validation_Validator_DateTimeValidator();
+               $this->assertTrue($dateTimeValidator->isValid(new DateTime));
+       }
+
+       /**
+        * @test
+        */
+       public function dateTimeValidatorReturnsFalseForAnInvalidDateTimeObject() {
+               $dateTimeValidator = $this->getMock('Tx_Extbase_Validation_Validator_DateTimeValidator', array('addError'), array(), '', FALSE);
+               $this->assertFalse($dateTimeValidator->isValid('blah'));
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/EmailAddressValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/EmailAddressValidator_testcase.php
new file mode 100644 (file)
index 0000000..4e10fcb
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the email address validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: EmailAddressValidator_testcase.php 2428 2010-07-20 10:18:51Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_EmailAddressValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * Data provider with valid email addresses
+        *
+        * @return array
+        */
+       public function validAddresses() {
+               return array(
+                       array('andreas.foerthner@netlogix.de'),
+                       array('user@localhost'),
+                       array('user@localhost.localdomain'),
+                       array('info@guggenheim.museum'),
+                       array('just@test.invalid'),
+                       array('just+spam@test.de'),
+                       array('local@192.168.0.2')
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider validAddresses
+        */
+       public function emailAddressValidatorReturnsTrueForAValidEmailAddress($address) {
+               $emailAddressValidator = new Tx_Extbase_Validation_Validator_EmailAddressValidator();
+               foreach ($this->validAddresses as $address) {
+                       $this->assertTrue($emailAddressValidator->isValid($address), "$address was declared to be invalid, but it is valid.");
+               }
+       }
+
+       /**
+        * Data provider with invalid email addresses
+        *
+        * @return array
+        */
+       public function invalidAddresses() {
+               return array(
+                       array('andreas.foerthner@'),
+                       array('andreas@foerthner@example.com'),
+                       array('@typo3.org'),
+                       array('someone@typo3.'),
+                       array('local@192.168.2'),
+                       array('local@192.168.270.1')
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider invalidAddresses
+        */
+       public function emailAddressValidatorReturnsFalseForAnInvalidEmailAddress($address) {
+               $emailAddressValidator = $this->getMock('Tx_Extbase_Validation_Validator_EmailAddressValidator', array('addError'), array(), '', FALSE);
+               $this->assertFalse($emailAddressValidator->isValid($address));
+       }
+
+       /**
+        * @test
+        */
+       public function emailValidatorCreatesTheCorrectErrorForAnInvalidEmailAddress() {
+               $emailAddressValidator = $this->getMock('Tx_Extbase_Validation_Validator_EmailAddressValidator', array('addError'), array(), '', FALSE);
+               $emailAddressValidator->expects($this->once())->method('addError')->with('The given subject was not a valid email address.', 1221559976);
+               $emailAddressValidator->isValid('notAValidMail@Address');
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/FloatValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/FloatValidator_testcase.php
new file mode 100644 (file)
index 0000000..4ed0a8b
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the float validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: FloatValidator_testcase.php 2428 2010-07-20 10:18:51Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_FloatValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * An array of valid floating point numbers addresses
+        * @var array
+        */
+       protected $validFloatingPointNumbers;
+
+       /**
+        * An array of invalid floating point numbers addresses
+        * @var array
+        */
+       protected $invalidFloatingPointNumbers;
+
+       public function setUp() {
+               $this->validFloatingPointNumbers = array(
+                       1029437.234726,
+                       '123.45',
+                       '+123.45',
+                       '-123.45',
+                       '123.45e3',
+                       123.45e3
+                       );
+
+               $this->invalidFloatingPointNumbers = array(
+                       1029437,
+                       '1029437',
+                       'not a number'
+                       );
+       }
+
+       /**
+        * @test
+        */
+       public function floatValidatorReturnsTrueForAValidFloat() {
+               $floatValidator = new Tx_Extbase_Validation_Validator_FloatValidator();
+               foreach ($this->validFloatingPointNumbers as $floatingPointNumber) {
+                       $this->assertTrue($floatValidator->isValid($floatingPointNumber), "$floatingPointNumber was declared to be invalid, but it is valid.");
+               }
+       }
+
+       /**
+        * @test
+        */
+       public function floatValidatorReturnsFalseForAnInvalidFloat() {
+               $floatValidator = $this->getMock('Tx_Extbase_Validation_Validator_FloatValidator', array('addError'), array(), '', FALSE);
+               foreach ($this->invalidFloatingPointNumbers as $floatingPointNumber) {
+                       $this->assertFalse($floatValidator->isValid($floatingPointNumber), "$floatingPointNumber was declared to be valid, but it is invalid.");
+               }
+       }
+
+       /**
+        * @test
+        */
+       public function floatValidatorCreatesTheCorrectErrorForAnInvalidSubject() {
+               $floatValidator = new Tx_Extbase_Validation_Validator_FloatValidator();
+               $floatValidator = $this->getMock('Tx_Extbase_Validation_Validator_FloatValidator', array('addError'), array(), '', FALSE);
+               $floatValidator->expects($this->once())->method('addError')->with('The given subject was not a valid float.', 1221560288);
+               $floatValidator->isValid(123456);
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/GenericObjectValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/GenericObjectValidator_testcase.php
new file mode 100644 (file)
index 0000000..679329d
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the Generic Object Validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: GenericObjectValidator_testcase.php 1408 2009-10-08 13:15:09Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_GenericObjectValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function isValidReturnsFalseIfTheValueIsNoObject() {
+               $validator = $this->getMock('Tx_Extbase_Validation_Validator_GenericObjectValidator', array('addError'), array(), '', FALSE);
+               $this->assertFalse($validator->isValid('foo'));
+       }
+
+       /**
+        * @test
+        */
+       public function isValidChecksAllPropertiesForWhichAPropertyValidatorExists() {
+               $mockPropertyValidators = array('foo' => 'validator', 'bar' => 'validator');
+               $mockObject = new stdClass;
+
+               $validator = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Validation_Validator_GenericObjectValidator'), array('addError', 'isPropertyValid'), array(), '', FALSE);
+               $validator->_set('propertyValidators', $mockPropertyValidators);
+
+               $validator->expects($this->at(0))->method('isPropertyValid')->with($mockObject, 'foo')->will($this->returnValue(TRUE));
+               $validator->expects($this->at(1))->method('isPropertyValid')->with($mockObject, 'bar')->will($this->returnValue(TRUE));
+
+               $validator->isValid($mockObject);
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/IntegerValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/IntegerValidator_testcase.php
new file mode 100644 (file)
index 0000000..fea006c
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the integer validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: IntegerValidator_testcase.php 2428 2010-07-20 10:18:51Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_IntegerValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * An array of valid floating point numbers addresses
+        * @var array
+        */
+       protected $validIntegerNumbers;
+
+       /**
+        * An array of invalid floating point numbers addresses
+        * @var array
+        */
+       protected $invalidIntegerNumbers;
+
+       public function setUp() {
+               $this->validIntegerNumbers = array(
+                       1029437,
+                       '12345',
+                       '+12345',
+                       '-12345'
+                       );
+
+               $this->invalidIntegerNumbers = array(
+                       'not a number',
+                       3.1415,
+                       '12345.987'
+                       );
+       }
+
+       /**
+        * @test
+        */
+       public function integerValidatorReturnsTrueForAValidInteger() {
+               $integerValidator = new Tx_Extbase_Validation_Validator_IntegerValidator();
+               foreach ($this->validIntegerNumbers as $integerNumber) {
+                       $this->assertTrue($integerValidator->isValid($integerNumber), "$integerNumber was declared to be invalid, but it is valid.");
+               }
+       }
+
+       /**
+        * Data provider with invalid email addresses
+        *
+        * @return array
+        */
+       public function invalidIntegers() {
+               return array(
+                       array('not a number'),
+                       array(3.1415),
+                       array('12345.987')
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider invalidIntegers
+        */
+       public function integerValidatorReturnsTrueForAnInvalidInteger() {
+               $integerValidator = $this->getMock('Tx_Extbase_Validation_Validator_IntegerValidator', array('addError'), array(), '', FALSE);
+               foreach ($this->invalidIntegerNumbers as $integerNumber) {
+                       $this->assertFalse($integerValidator->isValid($integerNumber), "$integerNumber was declared to be valid, but it is invalid.");
+               }
+       }
+
+       /**
+        * @test
+        */
+       public function integerValidatorCreatesTheCorrectErrorForAnInvalidSubject() {
+               $integerValidator = $this->getMock('Tx_Extbase_Validation_Validator_IntegerValidator', array('addError'), array(), '', FALSE);
+               $integerValidator->expects($this->once())->method('addError')->with('The given subject was not a valid integer.', 1221560494);
+               $integerValidator->isValid('not a number');
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/NotEmptyValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/NotEmptyValidator_testcase.php
new file mode 100644 (file)
index 0000000..86dcefc
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the not empty validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: NotEmptyValidator_testcase.php 2428 2010-07-20 10:18:51Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_NotEmptyValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function notEmptyValidatorReturnsTrueForASimpleString() {
+               $notEmptyValidator = new Tx_Extbase_Validation_Validator_NotEmptyValidator();
+               $this->assertTrue($notEmptyValidator->isValid('a not empty string'));
+       }
+
+       /**
+        * @test
+        */
+       public function notEmptyValidatorReturnsFalseForAnEmptyString() {
+               $notEmptyValidator = $this->getMock('Tx_Extbase_Validation_Validator_NotEmptyValidator', array('addError'), array(), '', FALSE);
+               $this->assertFalse($notEmptyValidator->isValid(''));
+       }
+
+       /**
+        * @test
+        */
+       public function notEmptyValidatorReturnsFalseForANullValue() {
+               $notEmptyValidator = $this->getMock('Tx_Extbase_Validation_Validator_NotEmptyValidator', array('addError'), array(), '', FALSE);
+               $this->assertFalse($notEmptyValidator->isValid(NULL));
+       }
+
+       /**
+        * @test
+        */
+       public function notEmptyValidatorCreatesTheCorrectErrorForAnEmptySubject() {
+               $notEmptyValidator = $this->getMock('Tx_Extbase_Validation_Validator_NotEmptyValidator', array('addError'), array(), '', FALSE);
+               $notEmptyValidator->expects($this->once())->method('addError')->with('The given subject was empty.', 1221560718);
+               $notEmptyValidator->isValid('');
+       }
+
+       /**
+        * @test
+        */
+       public function notEmptyValidatorCreatesTheCorrectErrorForANullValue() {
+               $notEmptyValidator = $this->getMock('Tx_Extbase_Validation_Validator_NotEmptyValidator', array('addError'), array(), '', FALSE);
+               $notEmptyValidator->expects($this->once())->method('addError')->with('The given subject was NULL.', 1221560910);
+               $notEmptyValidator->isValid(NULL);
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/NumberRangeValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/NumberRangeValidator_testcase.php
new file mode 100644 (file)
index 0000000..baae7ed
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the number range validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: NumberRangeValidator_testcase.php 2428 2010-07-20 10:18:51Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_NumberRangeValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function numberRangeValidatorReturnsTrueForASimpleIntegerInRange() {
+               $numberRangeValidator = new Tx_Extbase_Validation_Validator_NumberRangeValidator();
+               $numberRangeValidator->setOptions(array('startRange' => 0, 'endRange' => 1000));
+
+               $this->assertTrue($numberRangeValidator->isValid(10.5));
+       }
+
+       /**
+        * @test
+        */
+       public function numberRangeValidatorReturnsFalseForANumberOutOfRange() {
+               $numberRangeValidator = $this->getMock('Tx_Extbase_Validation_Validator_NumberRangeValidator', array('addError'), array(), '', FALSE);
+               $numberRangeValidator->setOptions(array('startRange' => 0, 'endRange' => 1000));
+               $this->assertFalse($numberRangeValidator->isValid(1000.1));
+       }
+
+       /**
+        * @test
+        */
+       public function numberRangeValidatorReturnsTrueForANumberInReversedRange() {
+               $numberRangeValidator = $this->getMock('Tx_Extbase_Validation_Validator_NumberRangeValidator', array('addError'), array(), '', FALSE);
+               $numberRangeValidator->setOptions(array('startRange' => 1000, 'endRange' => 0));
+               $this->assertTrue($numberRangeValidator->isValid(100));
+       }
+
+       /**
+        * @test
+        */
+       public function numberRangeValidatorReturnsFalseForAString() {
+               $numberRangeValidator = $this->getMock('Tx_Extbase_Validation_Validator_NumberRangeValidator', array('addError'), array(), '', FALSE);
+               $numberRangeValidator->setOptions(array('startRange' => 0, 'endRange' => 1000));
+               $this->assertFalse($numberRangeValidator->isValid('not a number'));
+       }
+
+       /**
+        * @test
+        */
+       public function numberRangeValidatorCreatesTheCorrectErrorForANumberOutOfRange() {
+               $numberRangeValidator = $this->getMock('Tx_Extbase_Validation_Validator_NumberRangeValidator', array('addError'), array(), '', FALSE);
+               $numberRangeValidator->expects($this->once())->method('addError')->with('The given subject was not in the valid range (1 - 42).', 1221561046);
+               $numberRangeValidator->setOptions(array('startRange' => 1, 'endRange' => 42));
+               $numberRangeValidator->isValid(4711);
+       }
+
+       /**
+        * @test
+        */
+       public function numberRangeValidatorCreatesTheCorrectErrorForAStringSubject() {
+               $numberRangeValidator = $this->getMock('Tx_Extbase_Validation_Validator_NumberRangeValidator', array('addError'), array(), '', FALSE);
+               $numberRangeValidator->expects($this->once())->method('addError')->with('The given subject was not a valid number.', 1221563685);
+               $numberRangeValidator->setOptions(array('startRange' => 0, 'endRange' => 42));
+               $numberRangeValidator->isValid('this is not between 0 an 42');
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/NumberValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/NumberValidator_testcase.php
new file mode 100644 (file)
index 0000000..6c9150a
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the number validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: NumberValidator_testcase.php 2428 2010-07-20 10:18:51Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_NumberValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function numberValidatorReturnsTrueForASimpleInteger() {
+               $numberValidator = new Tx_Extbase_Validation_Validator_NumberValidator();
+               $this->assertTrue($numberValidator->isValid(1029437));
+       }
+
+       /**
+        * @test
+        */
+       public function numberValidatorReturnsFalseForAString() {
+               $numberValidator = $this->getMock('Tx_Extbase_Validation_Validator_NumberValidator', array('addError'), array(), '', FALSE);
+               $this->assertFalse($numberValidator->isValid('not a number'));
+       }
+
+       /**
+        * @test
+        */
+       public function numberValidatorCreatesTheCorrectErrorForAnInvalidSubject() {
+               $numberValidator = $this->getMock('Tx_Extbase_Validation_Validator_NumberValidator', array('addError'), array(), '', FALSE);
+               $numberValidator->expects($this->once())->method('addError')->with('The given subject was not a valid number.', 1221563685);
+               $numberValidator->isValid('this is not a number');
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/RawValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/RawValidator_testcase.php
new file mode 100644 (file)
index 0000000..752ac66
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the raw validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: RawValidator_testcase.php 1408 2009-10-08 13:15:09Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_RawValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function theRawValidatorAlwaysReturnsTRUE() {
+               $rawValidator = new Tx_Extbase_Validation_Validator_RawValidator();
+
+               $this->assertTrue($rawValidator->isValid('simple1expression'));
+               $this->assertTrue($rawValidator->isValid(''));
+               $this->assertTrue($rawValidator->isValid(NULL));
+               $this->assertTrue($rawValidator->isValid(FALSE));
+               $this->assertTrue($rawValidator->isValid(new ArrayObject()));
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/RegularExpressionValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/RegularExpressionValidator_testcase.php
new file mode 100644 (file)
index 0000000..f995126
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the regular expression validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: RegularExpressionValidator_testcase.php 2428 2010-07-20 10:18:51Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_RegularExpressionValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function regularExpressionValidatorMatchesABasicExpressionCorrectly() {
+               $regularExpressionValidator = $this->getMock('Tx_Extbase_Validation_Validator_RegularExpressionValidator', array('addError'), array(), '', FALSE);
+               $regularExpressionValidator->setOptions(array('regularExpression' => '/^simple[0-9]expression$/'));
+
+               $this->assertTrue($regularExpressionValidator->isValid('simple1expression'));
+               $this->assertFalse($regularExpressionValidator->isValid('simple1expressions'));
+       }
+
+       /**
+        * @test
+        */
+       public function regularExpressionValidatorCreatesTheCorrectErrorIfTheExpressionDidNotMatch() {
+               $regularExpressionValidator = $this->getMock('Tx_Extbase_Validation_Validator_RegularExpressionValidator', array('addError'), array(), '', FALSE);
+               $regularExpressionValidator->expects($this->once())->method('addError')->with('The given subject did not match the pattern.', 1221565130);
+               $regularExpressionValidator->setOptions(array('regularExpression' => '/^simple[0-9]expression$/'));
+               $regularExpressionValidator->isValid('some subject that will not match');
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/Validator/StringLengthValidator_testcase.php b/typo3/sysext/extbase/Tests/Unit/Validation/Validator/StringLengthValidator_testcase.php
new file mode 100644 (file)
index 0000000..37ad93a
--- /dev/null
@@ -0,0 +1,190 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Testcase for the string length validator
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: StringLengthValidator_testcase.php 1408 2009-10-08 13:15:09Z jocrau $
+ */
+class Tx_Extbase_Validation_Validator_StringLengthValidator_testcase extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
+       /**
+        * @test
+        */
+       public function stgringLengthValidatorReturnsTrueForAStringShorterThanMaxLengthAndLongerThanMinLength() {
+               $stringLengthValidator = $this->getMock('Tx_Extbase_Validation_Validator_StringLengthValidator', array('addError'), array(), '', FALSE);
+               $stringLengthValidator->setOptions(array('minimum' => 0, 'maximum' => 50));
+               $this->assertTrue($stringLengthValidator->isValid('this is a very simple string'));
+       }
+
+       /**
+        * @test
+        */
+       public function stringLengthValidatorReturnsFalseForAStringShorterThanThanMinLength() {
+               $stringLengthValidator = $this->getMock('Tx_Extbase_Validation_Validator_StringLengthValidator', array('addError'), array(), '', FALSE);
+               $stringLengthValidator->setOptions(array('minimum' => 50, 'maximum' => 100));
+               $this->assertFalse($stringLengthValidator->isValid('this is a very short string'));
+       }
+
+       /**
+        * @test
+        */
+       public function stringLengthValidatorReturnsFalseForAStringLongerThanThanMaxLength() {
+               $stringLengthValidator = $this->getMock('Tx_Extbase_Validation_Validator_StringLengthValidator', array('addError'), array(), '', FALSE);
+               $stringLengthValidator->setOptions(array('minimum' => 5, 'maximum' => 10));
+               $this->assertFalse($stringLengthValidator->isValid('this is a very short string'));
+       }
+
+       /**
+        * @test
+        */
+       public function stringLengthValidatorReturnsTrueForAStringLongerThanThanMinLengthAndMaxLengthNotSpecified() {
+               $stringLengthValidator = $this->getMock('Tx_Extbase_Validation_Validator_StringLengthValidator', array('addError'), array(), '', FALSE);
+               $stringLengthValidator->setOptions(array('minimum' => 5));
+               $this->assertTrue($stringLengthValidator->isValid('this is a very short string'));
+       }
+
+       /**
+        * @test
+        */
+       public function stringLengthValidatorReturnsTrueForAStringShorterThanThanMaxLengthAndMinLengthNotSpecified() {
+               $stringLengthValidator = $this->getMock('Tx_Extbase_Validation_Validator_StringLengthValidator', array('addError'), array(), '', FALSE);
+               $stringLengthValidator->setOptions(array('maximum' => 100));
+               $this->assertTrue($stringLengthValidator->isValid('this is a very short string'));
+       }
+
+       /**
+        * @test
+        */
+