<?php
namespace TYPO3\CMS\Fluid\Tests\Unit\View;

/*                                                                        *
 * This script is backported from the FLOW3 package "TYPO3.Fluid".        *
 *                                                                        *
 * It is free software; you can redistribute it and/or modify it under    *
 * the terms of the GNU Lesser General Public License, either version 3   *
 *  of the License, or (at your option) any later version.                *
 *                                                                        *
 *                                                                        *
 * This script is distributed in the hope that it will be useful, but     *
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
 * General Public License for more details.                               *
 *                                                                        *
 * You should have received a copy of the GNU Lesser General Public       *
 * License along with the script.                                         *
 * If not, see http://www.gnu.org/licenses/lgpl.html                      *
 *                                                                        *
 * The TYPO3 project - inspiring people to share!                         *
 *                                                                        */

use TYPO3\CMS\Core\Tests\UnitTestCase;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;

/**
 * Test case
 */
class StandaloneViewTest extends UnitTestCase {

	/**
	 * @var array A backup of registered singleton instances
	 */
	protected $singletonInstances = array();

	/**
	 * @var StandaloneView|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $view;

	/**
	 * @var \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockRenderingContext;

	/**
	 * @var \TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperVariableContainer|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockViewHelperVariableContainer;

	/**
	 * @var \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockControllerContext;

	/**
	 * @var \TYPO3\CMS\Fluid\Core\Parser\TemplateParser|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockTemplateParser;

	/**
	 * @var \TYPO3\CMS\Extbase\Object\ObjectManager|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockObjectManager;

	/**
	 * @var \TYPO3\CMS\Extbase\Mvc\Web\Request|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockRequest;

	/**
	 * @var \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockUriBuilder;

	/**
	 * @var \TYPO3\CMS\Fluid\Core\Parser\ParsedTemplateInterface|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockParsedTemplate;

	/**
	 * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockConfigurationManager;

	/**
	 * @var \TYPO3\CMS\Extbase\Mvc\Controller\FlashMessageContainer|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockFlashMessageContainer;

	/**
	 * @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockContentObject;

	/**
	 * @var \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler|\PHPUnit_Framework_MockObject_MockObject
	 */
	protected $mockTemplateCompiler;

	/**
	 * Sets up this test case
	 *
	 * @return void
	 */
	public function setUp() {
		$this->singletonInstances = GeneralUtility::getSingletonInstances();
		$this->view = $this->getAccessibleMock('TYPO3\\CMS\\Fluid\\View\\StandaloneView', array('testFileExistence', 'buildParserConfiguration'), array(), '', FALSE);
		$this->mockTemplateParser = $this->getMock('TYPO3\\CMS\\Fluid\\Core\\Parser\\TemplateParser');
		$this->mockParsedTemplate = $this->getMock('TYPO3\\CMS\\Fluid\\Core\\Parser\\ParsedTemplateInterface');
		$this->mockTemplateParser->expects($this->any())->method('parse')->will($this->returnValue($this->mockParsedTemplate));
		$this->mockConfigurationManager = $this->getMock('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
		$this->mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
		$this->mockObjectManager->expects($this->any())->method('get')->will($this->returnCallback(array($this, 'objectManagerCallback')));
		$this->mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Request');
		$this->mockUriBuilder = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Routing\\UriBuilder');
		$this->mockFlashMessageContainer = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\FlashMessageContainer');
		$this->mockContentObject = $this->getMock('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
		$this->mockControllerContext = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ControllerContext');
		$this->mockControllerContext->expects($this->any())->method('getRequest')->will($this->returnValue($this->mockRequest));
		$this->mockViewHelperVariableContainer = $this->getMock('TYPO3\\CMS\\Fluid\\Core\\ViewHelper\\ViewHelperVariableContainer');
		$this->mockRenderingContext = $this->getMock('TYPO3\\CMS\\Fluid\\Core\\Rendering\\RenderingContext');
		$this->mockRenderingContext->expects($this->any())->method('getControllerContext')->will($this->returnValue($this->mockControllerContext));
		$this->mockRenderingContext->expects($this->any())->method('getViewHelperVariableContainer')->will($this->returnValue($this->mockViewHelperVariableContainer));
		$this->view->_set('templateParser', $this->mockTemplateParser);
		$this->view->_set('objectManager', $this->mockObjectManager);
		$this->view->setRenderingContext($this->mockRenderingContext);
		$this->mockTemplateCompiler = $this->getMock('TYPO3\\CMS\\Fluid\\Core\\Compiler\\TemplateCompiler');
		$this->view->_set('templateCompiler', $this->mockTemplateCompiler);
		GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager', $this->mockObjectManager);
		GeneralUtility::addInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer', $this->mockContentObject);

		/** @var \TYPO3\CMS\Core\Cache\CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
		$mockCacheManager = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager', array(), array(), '', FALSE);
		$mockCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\PhpFrontend', array(), array(), '', FALSE);
		$mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
		GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Cache\\CacheManager', $mockCacheManager);
	}

	/**
	 * @return void
	 */
	public function tearDown() {
		GeneralUtility::purgeInstances();
		GeneralUtility::resetSingletonInstances($this->singletonInstances);
		parent::tearDown();
	}

	/**
	 * @param string $className
	 * @return object
	 */
	public function objectManagerCallback($className) {
		switch ($className) {
			case 'TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface':
				return $this->mockConfigurationManager;
			case 'TYPO3\\CMS\\Fluid\\Core\\Parser\\TemplateParser':
				return $this->mockTemplateParser;
			case 'TYPO3\\CMS\\Fluid\\Core\\Rendering\\RenderingContext':
				return $this->mockRenderingContext;
			case 'TYPO3\\CMS\\Extbase\\Mvc\\Web\\Request':
				return $this->mockRequest;
			case 'TYPO3\\CMS\\Extbase\\Mvc\\Web\\Routing\\UriBuilder':
				return $this->mockUriBuilder;
			case 'TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ControllerContext':
				return $this->mockControllerContext;
			case 'TYPO3\\CMS\\Extbase\\Mvc\\Controller\\FlashMessageContainer':
				return $this->mockFlashMessageContainer;
			case 'TYPO3\\CMS\\Fluid\\Core\\Compiler\\TemplateCompiler':
				return $this->mockTemplateCompiler;
		}
		throw new \InvalidArgumentException('objectManagerCallback cannot handle class "' . $className . '". Looks like incomplete mocking in the tests.', 1417105493);
	}

	/**
	 * @test
	 */
	public function constructorSetsSpecifiedContentObject() {
		/** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer|\PHPUnit_Framework_MockObject_MockObject $mockContentObject */
		$mockContentObject = $this->getMock('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
		$this->mockConfigurationManager->expects($this->once())->method('setContentObject')->with($this->identicalTo($mockContentObject));
		new StandaloneView($mockContentObject);
	}

	/**
	 * @test
	 */
	public function constructorCreatesContentObjectIfItIsNotSpecified() {
		$this->mockConfigurationManager->expects($this->once())->method('setContentObject')->with($this->identicalTo($this->mockContentObject));
		new StandaloneView();
	}

	/**
	 * @test
	 */
	public function constructorSetsRequestUri() {
		$expectedRequestUri = GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL');
		$this->mockRequest->expects($this->once())->method('setRequestURI')->with($expectedRequestUri);
		new StandaloneView();
	}

	/**
	 * @test
	 */
	public function constructorSetsBaseUri() {
		$expectedBaseUri = GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
		$this->mockRequest->expects($this->once())->method('setBaseURI')->with($expectedBaseUri);
		new StandaloneView();
	}

	/**
	 * @test
	 */
	public function constructorInjectsRequestToUriBuilder() {
		$this->mockUriBuilder->expects($this->once())->method('setRequest')->with($this->mockRequest);
		new StandaloneView();
	}

	/**
	 * @test
	 */
	public function constructorInjectsRequestToControllerContext() {
		$this->mockControllerContext->expects($this->once())->method('setRequest')->with($this->mockRequest);
		new StandaloneView();
	}

	/**
	 * @test
	 */
	public function constructorInjectsUriBuilderToControllerContext() {
		$this->mockControllerContext->expects($this->once())->method('setUriBuilder')->with($this->mockUriBuilder);
		new StandaloneView();
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 */
	public function renderThrowsExceptionIfTemplateIsNotSpecified() {
		$this->view->render();
	}

	/**
	 * @test
	 */
	public function renderPassesSpecifiedTemplateSourceToTemplateParser() {
		$this->view->setTemplateSource('The Template Source');
		$this->mockTemplateParser->expects($this->once())->method('parse')->with('The Template Source');
		$this->view->render();
	}

	/**
	 * @test
	 */
	public function renderLoadsSpecifiedTemplateFileAndPassesSourceToTemplateParser() {
		$templatePathAndFilename = GeneralUtility::fixWindowsFilePath(__DIR__) . '/Fixtures/StandaloneViewFixture.html';
		$expectedResult = file_get_contents($templatePathAndFilename);
		$this->view->setTemplatePathAndFilename($templatePathAndFilename);
		$this->mockTemplateParser->expects($this->once())->method('parse')->with($expectedResult);
		$this->view->render();
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 */
	public function renderThrowsExceptionIfSpecifiedTemplateFileDoesNotExist() {
		$this->view->setTemplatePathAndFilename('NonExistingTemplatePath');
		@$this->view->render();
	}

	/**
	 * @test
	 */
	public function setFormatSetsRequestFormat() {
		$this->mockRequest->expects($this->once())->method('setFormat')->with('xml');
		$this->view->setFormat('xml');
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 */
	public function getLayoutRootPathThrowsExceptionIfLayoutRootPathAndTemplatePathAreNotSpecified() {
		$this->view->getLayoutRootPath();
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 */
	public function getLayoutRootPathsThrowsExceptionIfLayoutRootPathAndTemplatePathAreNotSpecified() {
		$this->view->getLayoutRootPaths();
	}

	/**
	 * @test
	 */
	public function getLayoutRootPathReturnsSpecifiedLayoutRootPathByDefault() {
		$templatePathAndFilename = 'some/template/RootPath/SomeTemplate.html';
		$layoutRootPath = 'some/layout/RootPath';
		$this->view->setTemplatePathAndFilename($templatePathAndFilename);
		$this->view->setLayoutRootPath($layoutRootPath);
		$actualResult = $this->view->getLayoutRootPath();
		$this->assertEquals($layoutRootPath, $actualResult);
	}

	/**
	 * @test
	 */
	public function getLayoutRootPathsReturnsSpecifiedLayoutRootPathByDefault() {
		$templatePathAndFilename = 'some/template/RootPath/SomeTemplate.html';
		$layoutRootPaths = array(
			'some/layout/RootPath'
		);
		$this->view->setTemplatePathAndFilename($templatePathAndFilename);
		$this->view->setLayoutRootPaths($layoutRootPaths);
		$actualResult = $this->view->getLayoutRootPaths();
		$this->assertEquals($layoutRootPaths, $actualResult);
	}

	/**
	 * @test
	 */
	public function getLayoutRootPathReturnsDefaultPathIfNoLayoutRootPathIsSpecified() {
		$templatePathAndFilename = 'some/template/RootPath/SomeTemplate.html';
		$this->view->setTemplatePathAndFilename($templatePathAndFilename);
		$expectedResult = 'some/template/RootPath/Layouts';
		$actualResult = $this->view->getLayoutRootPath();
		$this->assertEquals($expectedResult, $actualResult);
	}

	/**
	 * @test
	 */
	public function getLayoutRootPathsReturnsDefaultPathIfNoLayoutRootPathIsSpecified() {
		$templatePathAndFilename = 'some/template/RootPath/SomeTemplate.html';
		$this->view->setTemplatePathAndFilename($templatePathAndFilename);
		$expectedResult = array('some/template/RootPath/Layouts');
		$actualResult = $this->view->getLayoutRootPaths();
		$this->assertEquals($expectedResult, $actualResult);
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 */
	public function getLayoutSourceThrowsExceptionIfLayoutRootPathDoesNotExist() {
		$this->view->setLayoutRootPath('some/non/existing/Path');
		$this->view->_call('getLayoutSource');
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 */
	public function getLayoutSourceThrowsExceptionIfLayoutRootPathsDoesNotExist() {
		$this->view->setLayoutRootPaths(array('some/non/existing/Path'));
		$this->view->_call('getLayoutSource');
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 */
	public function getLayoutSourceThrowsExceptionIfLayoutFileDoesNotExist() {
		$layoutRootPath = __DIR__ . '/Fixtures';
		$this->view->setLayoutRootPaths(array($layoutRootPath));
		$this->view->_call('getLayoutSource', 'NonExistingLayout');
	}

	/**
	 * @test
	 */
	public function getLayoutSourceReturnsContentOfLayoutFileForTheDefaultFormat() {
		$layoutRootPath = GeneralUtility::fixWindowsFilePath(__DIR__) . '/Fixtures';
		$this->view->setLayoutRootPath($layoutRootPath);
		$this->mockRequest->expects($this->once())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->once())->method('testFileExistence')->with($layoutRootPath . '/LayoutFixture.html')->will($this->returnValue(TRUE));
		$expectedResult = file_get_contents($layoutRootPath . '/LayoutFixture.html');
		$actualResult = $this->view->_call('getLayoutSource', 'LayoutFixture');
		$this->assertEquals($expectedResult, $actualResult);
	}

	/**
	 * @test
	 */
	public function getLayoutSourceReturnsContentOfLayoutFileForTheSpecifiedFormat() {
		$layoutRootPath = GeneralUtility::fixWindowsFilePath(__DIR__) . '/Fixtures';
		$this->view->setLayoutRootPath($layoutRootPath);
		$this->mockRequest->expects($this->once())->method('getFormat')->will($this->returnValue('xml'));
		$this->view->expects($this->once())->method('testFileExistence')->with($layoutRootPath . '/LayoutFixture.xml')->will($this->returnValue(TRUE));
		$expectedResult = file_get_contents($layoutRootPath . '/LayoutFixture.xml');
		$actualResult = $this->view->_call('getLayoutSource', 'LayoutFixture');
		$this->assertEquals($expectedResult, $actualResult);
	}

	/**
	 * @test
	 */
	public function getLayoutSourceReturnsContentOfDefaultLayoutFileIfNoLayoutExistsForTheSpecifiedFormat() {
		$layoutRootPath = GeneralUtility::fixWindowsFilePath(__DIR__) . '/Fixtures';
		$this->view->setLayoutRootPath($layoutRootPath);
		$this->mockRequest->expects($this->once())->method('getFormat')->will($this->returnValue('foo'));
		$this->view->expects($this->at(0))->method('testFileExistence')->with($layoutRootPath . '/LayoutFixture.foo')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(1))->method('testFileExistence')->with($layoutRootPath . '/LayoutFixture')->will($this->returnValue(TRUE));
		$expectedResult = file_get_contents($layoutRootPath . '/LayoutFixture');
		$actualResult = $this->view->_call('getLayoutSource', 'LayoutFixture');
		$this->assertEquals($expectedResult, $actualResult);
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 */
	public function getPartialRootPathThrowsExceptionIfPartialRootPathAndTemplatePathAreNotSpecified() {
		$this->view->getPartialRootPath();
	}

	/**
	 * @test
	 */
	public function getPartialRootPathReturnsSpecifiedPartialRootPathByDefault() {
		$templatePathAndFilename = 'some/template/RootPath/SomeTemplate.html';
		$partialRootPath = 'some/partial/RootPath';
		$this->view->setTemplatePathAndFilename($templatePathAndFilename);
		$this->view->setPartialRootPath($partialRootPath);
		$actualResult = $this->view->getPartialRootPath();
		$this->assertEquals($partialRootPath, $actualResult);
	}

	/**
	 * @test
	 */
	public function getPartialRootPathReturnsDefaultPathIfNoPartialRootPathIsSpecified() {
		$templatePathAndFilename = 'some/template/RootPath/SomeTemplate.html';
		$this->view->setTemplatePathAndFilename($templatePathAndFilename);
		$expectedResult = 'some/template/RootPath/Partials';
		$actualResult = $this->view->getPartialRootPath();
		$this->assertEquals($expectedResult, $actualResult);
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 */
	public function getPartialSourceThrowsExceptionIfPartialRootPathDoesNotExist() {
		$this->view->setPartialRootPath('some/non/existing/Path');
		$this->view->_call('getPartialSource', 'SomePartial');
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 */
	public function getPartialSourceThrowsExceptionIfPartialFileDoesNotExist() {
		$partialRootPath = __DIR__ . '/Fixtures';
		$this->view->setPartialRootPath($partialRootPath);
		$this->view->_call('getPartialSource', 'NonExistingPartial');
	}

	/**
	 * @test
	 */
	public function getPartialSourceReturnsContentOfPartialFileForTheDefaultFormat() {
		$partialRootPath = __DIR__ . '/Fixtures';
		$this->view->setPartialRootPath($partialRootPath);
		$this->mockRequest->expects($this->once())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->once())->method('testFileExistence')->will($this->returnValue(TRUE));
		$expectedResult = file_get_contents($partialRootPath . '/LayoutFixture.html');
		$actualResult = $this->view->_call('getPartialSource', 'LayoutFixture');
		$this->assertEquals($expectedResult, $actualResult);
	}

	/**
	 * @test
	 */
	public function getPartialSourceReturnsContentOfPartialFileForTheSpecifiedFormat() {
		$partialRootPath = __DIR__ . '/Fixtures';
		$this->view->setPartialRootPath($partialRootPath);
		$this->mockRequest->expects($this->once())->method('getFormat')->will($this->returnValue('xml'));
		$this->view->expects($this->once())->method('testFileExistence')->will($this->returnValue(TRUE));
		$expectedResult = file_get_contents($partialRootPath . '/LayoutFixture.xml');
		$actualResult = $this->view->_call('getPartialSource', 'LayoutFixture');
		$this->assertEquals($expectedResult, $actualResult);
	}

	/**
	 * @test
	 */
	public function getPartialSourceReturnsContentOfDefaultPartialFileIfNoPartialExistsForTheSpecifiedFormat() {
		$partialRootPath = __DIR__ . '/Fixtures';
		$this->view->setPartialRootPath($partialRootPath);
		$this->mockRequest->expects($this->once())->method('getFormat')->will($this->returnValue('foo'));
		$this->view->expects($this->at(1))->method('testFileExistence')->will($this->returnValue(TRUE));
		$expectedResult = file_get_contents($partialRootPath . '/LayoutFixture');
		$actualResult = $this->view->_call('getPartialSource', 'LayoutFixture');
		$this->assertEquals($expectedResult, $actualResult);
	}

	/**
	 * @test
	 */
	public function setPartialRootPathsOverridesValueSetBySetPartialRootPath() {
		$this->view->setPartialRootPath('/foo/bar');
		$this->view->setPartialRootPaths(array('/overruled/path'));
		$expected = array('/overruled/path');
		$actual = $this->view->_call('getPartialRootPaths');
		$this->assertEquals($expected, $actual, 'A set partial root path was not returned correctly.');
	}

	/**
	 * @test
	 */
	public function setLayoutRootPathsOverridesValuesSetBySetLayoutRootPath() {
		$this->view->setLayoutRootPath('/foo/bar');
		$this->view->setLayoutRootPaths(array('/overruled/path'));
		$expected = array('/overruled/path');
		$actual = $this->view->_call('getLayoutRootPaths');
		$this->assertEquals($expected, $actual, 'A set layout root path was not returned correctly.');
	}

	/**
	 * @test
	 */
	public function getLayoutPathAndFilenameRespectsCasingOfLayoutName() {
		$this->view->setLayoutRootPaths(array('some/Default/Directory'));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(0))->method('testFileExistence')->with('some/Default/Directory/LayoutName.html')->willReturn(FALSE);
		$this->view->expects($this->at(1))->method('testFileExistence')->with('some/Default/Directory/LayoutName')->willReturn(FALSE);
		$this->view->expects($this->at(2))->method('testFileExistence')->with('some/Default/Directory/layoutName.html')->willReturn(TRUE);
		$this->assertSame('some/Default/Directory/layoutName.html', $this->view->_call('getLayoutPathAndFilename', 'layoutName'));
	}

	/**
	 * @test
	 */
	public function getLayoutPathAndFilenameFindsUpperCasedLayoutName() {
		$this->view->setLayoutRootPaths(array('some/Default/Directory'));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(0))->method('testFileExistence')->with('some/Default/Directory/LayoutName.html')->willReturn(TRUE);
		$this->assertSame('some/Default/Directory/LayoutName.html', $this->view->_call('getLayoutPathAndFilename', 'layoutName'));
	}

	/**
	 * @test
	 */
	public function getLayoutPathAndFilenameResolvesTheSpecificFile() {
		$this->view->setLayoutRootPaths(array(
			'default' => 'some/Default/Directory',
			'specific' => 'specific/Layouts',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->once())->method('testFileExistence')->with('specific/Layouts/Default.html')->will($this->returnValue(TRUE));
		$this->assertEquals('specific/Layouts/Default.html', $this->view->_call('getLayoutPathAndFilename'));
	}

	/**
	 * @test
	 */
	public function getLayoutPathAndFilenameResolvesTheDefaultFile() {
		$this->view->setLayoutRootPaths(array(
			'default' => 'some/Default/Directory',
			'specific' => 'specific/Layouts',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(2))->method('testFileExistence')->with('some/Default/Directory/Default.html')->will($this->returnValue(TRUE));
		$this->assertEquals('some/Default/Directory/Default.html', $this->view->_call('getLayoutPathAndFilename'));
	}

	/**
	 * @test
	 */
	public function getLayoutPathAndFilenameResolvesTheSpecificFileWithNumericIndices() {
		$this->view->setLayoutRootPaths(array(
			'10' => 'some/Default/Directory',
			'25' => 'evenMore/Specific/Layouts',
			'17' => 'specific/Layouts',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(2))->method('testFileExistence')->with('specific/Layouts/Default.html')->will($this->returnValue(TRUE));
		$this->assertEquals('specific/Layouts/Default.html', $this->view->_call('getLayoutPathAndFilename'));
	}

	/**
	 * @test
	 */
	public function getLayoutPathAndFilenameResolvesTheDefaultFileWithNumericIndices() {
		$this->view->setLayoutRootPaths(array(
			'10' => 'some/Default/Directory',
			'25' => 'evenMore/Specific/Layouts',
			'17' => 'specific/Layouts',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(4))->method('testFileExistence')->with('some/Default/Directory/Default.html')->will($this->returnValue(TRUE));
		$this->assertEquals('some/Default/Directory/Default.html', $this->view->_call('getLayoutPathAndFilename'));
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 * @expectedExceptionCode 1288092555
	 */
	public function getLayoutPathAndFilenameThrowsExceptionIfNoFileWasFound() {
		$this->view->setLayoutRootPaths(array(
			'10' => 'some/Default/Directory',
			'25' => 'evenMore/Specific/Layouts',
			'17' => 'specific/Layouts',
		));
		$this->view->expects($this->any())->method('testFileExistence')->will($this->returnValue(FALSE));
		$this->view->_call('getLayoutPathAndFilename');

	}

	/**
	 * @test
	 */
	public function getPartialPathAndFilenameRespectsCasingOfPartialName() {
		$this->view->setPartialRootPaths(array('some/Default/Directory'));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(0))->method('testFileExistence')->with('some/Default/Directory/PartialName.html')->willReturn(FALSE);
		$this->view->expects($this->at(1))->method('testFileExistence')->with('some/Default/Directory/PartialName')->willReturn(FALSE);
		$this->view->expects($this->at(2))->method('testFileExistence')->with('some/Default/Directory/partialName.html')->willReturn(TRUE);
		$this->assertSame('some/Default/Directory/partialName.html', $this->view->_call('getPartialPathAndFilename', 'partialName'));
	}

	/**
	 * @test
	 */
	public function getPartialPathAndFilenameFindsUpperCasedPartialName() {
		$this->view->setPartialRootPaths(array('some/Default/Directory'));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(0))->method('testFileExistence')->with('some/Default/Directory/PartialName.html')->willReturn(TRUE);
		$this->assertSame('some/Default/Directory/PartialName.html', $this->view->_call('getPartialPathAndFilename', 'partialName'));
	}

	/**
	 * @test
	 */
	public function getPartialPathAndFilenameResolvesTheSpecificFile() {
		$this->view->setPartialRootPaths(array(
			'default' => 'some/Default/Directory',
			'specific' => 'specific/Partials',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->once())->method('testFileExistence')->with('specific/Partials/Partial.html')->will($this->returnValue(TRUE));
		$this->assertEquals('specific/Partials/Partial.html', $this->view->_call('getPartialPathAndFilename', 'Partial'));
	}

	/**
	 * @test
	 */
	public function getPartialPathAndFilenameResolvesTheDefaultFile() {
		$this->view->setPartialRootPaths(array(
			'default' => 'some/Default/Directory',
			'specific' => 'specific/Partials',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(2))->method('testFileExistence')->with('some/Default/Directory/Partial.html')->will($this->returnValue(TRUE));
		$this->assertEquals('some/Default/Directory/Partial.html', $this->view->_call('getPartialPathAndFilename', 'Partial'));
	}

	/**
	 * @test
	 */
	public function getPartialPathAndFilenameResolvesTheSpecificFileWithNumericIndices() {
		$this->view->setPartialRootPaths(array(
			'10' => 'some/Default/Directory',
			'25' => 'evenMore/Specific/Partials',
			'17' => 'specific/Partials',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(2))->method('testFileExistence')->with('specific/Partials/Partial.html')->will($this->returnValue(TRUE));
		$this->assertEquals('specific/Partials/Partial.html', $this->view->_call('getPartialPathAndFilename', 'Partial'));
	}

	/**
	 * @test
	 */
	public function getPartialPathAndFilenameResolvesTheDefaultFileWithNumericIndices() {
		$this->view->setPartialRootPaths(array(
			'10' => 'some/Default/Directory',
			'25' => 'evenMore/Specific/Partials',
			'17' => 'specific/Partials',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(4))->method('testFileExistence')->with('some/Default/Directory/Partial.html')->will($this->returnValue(TRUE));
		$this->assertEquals('some/Default/Directory/Partial.html', $this->view->_call('getPartialPathAndFilename', 'Partial'));
	}

	/**
	 * @test
	 * @expectedException \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
	 * @expectedExceptionCode 1288092556
	 */
	public function getPartialPathAndFilenameThrowsExceptionIfNoFileWasFound() {
		$this->view->setPartialRootPaths(array(
			'10' => 'some/Default/Directory',
			'25' => 'evenMore/Specific/Partials',
			'17' => 'specific/Partials',
		));
		$this->view->expects($this->any())->method('testFileExistence')->will($this->returnValue(FALSE));
		$this->view->_call('getPartialPathAndFilename', 'Partial');
	}

	/**
	 * @test
	 */
	public function getPartialPathAndFilenameWalksNumericalIndicesInDescendingOrder() {
		$this->view->setPartialRootPaths(array(
			'10' => 'some/Default/Directory',
			'25' => 'evenMore/Specific/Partials',
			'17' => 'specific/Partials',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(0))->method('testFileExistence')->with('evenMore/Specific/Partials/Partial.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(1))->method('testFileExistence')->with('evenMore/Specific/Partials/Partial')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(2))->method('testFileExistence')->with('specific/Partials/Partial.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(3))->method('testFileExistence')->with('specific/Partials/Partial')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(4))->method('testFileExistence')->with('some/Default/Directory/Partial.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(5))->method('testFileExistence')->with('some/Default/Directory/Partial')->will($this->returnValue(TRUE));
		$this->assertEquals('some/Default/Directory/Partial', $this->view->_call('getPartialPathAndFilename', 'Partial'));
	}

	/**
	 * @test
	 */
	public function getLayoutPathAndFilenameWalksNumericalIndicesInDescendingOrder() {
		$this->view->setLayoutRootPaths(array(
			'10' => 'some/Default/Directory',
			'25' => 'evenMore/Specific/Layouts',
			'17' => 'specific/Layouts',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(0))->method('testFileExistence')->with('evenMore/Specific/Layouts/Default.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(1))->method('testFileExistence')->with('evenMore/Specific/Layouts/Default')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(2))->method('testFileExistence')->with('specific/Layouts/Default.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(3))->method('testFileExistence')->with('specific/Layouts/Default')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(4))->method('testFileExistence')->with('some/Default/Directory/Default.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(5))->method('testFileExistence')->with('some/Default/Directory/Default')->will($this->returnValue(TRUE));
		$this->assertEquals('some/Default/Directory/Default', $this->view->_call('getLayoutPathAndFilename'));
	}

	/**
	 * @test
	 */
	public function getPartialPathAndFilenameWalksStringKeysInReversedOrder() {
		$this->view->setPartialRootPaths(array(
			'default' => 'some/Default/Directory',
			'specific' => 'specific/Partials',
			'verySpecific' => 'evenMore/Specific/Partials',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(0))->method('testFileExistence')->with('evenMore/Specific/Partials/Partial.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(1))->method('testFileExistence')->with('evenMore/Specific/Partials/Partial')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(2))->method('testFileExistence')->with('specific/Partials/Partial.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(3))->method('testFileExistence')->with('specific/Partials/Partial')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(4))->method('testFileExistence')->with('some/Default/Directory/Partial.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(5))->method('testFileExistence')->with('some/Default/Directory/Partial')->will($this->returnValue(TRUE));
		$this->assertEquals('some/Default/Directory/Partial', $this->view->_call('getPartialPathAndFilename', 'Partial'));
	}

	/**
	 * @test
	 */
	public function getLayoutPathAndFilenameWalksStringKeysInReversedOrder() {
		$this->view->setLayoutRootPaths(array(
			'default' => 'some/Default/Directory',
			'specific' => 'specific/Layout',
			'verySpecific' => 'evenMore/Specific/Layout',
		));
		$this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
		$this->view->expects($this->at(0))->method('testFileExistence')->with('evenMore/Specific/Layout/Default.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(1))->method('testFileExistence')->with('evenMore/Specific/Layout/Default')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(2))->method('testFileExistence')->with('specific/Layout/Default.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(3))->method('testFileExistence')->with('specific/Layout/Default')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(4))->method('testFileExistence')->with('some/Default/Directory/Default.html')->will($this->returnValue(FALSE));
		$this->view->expects($this->at(5))->method('testFileExistence')->with('some/Default/Directory/Default')->will($this->returnValue(TRUE));
		$this->assertEquals('some/Default/Directory/Default', $this->view->_call('getLayoutPathAndFilename'));
	}

}
