[CLEANUP] Wrap the tests bootstrap code into classes
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Build / UnitTestsBootstrap.php
1 <?php
2 namespace TYPO3\CMS\Core\Build;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Core\Bootstrap;
18
19 /**
20 * This file is defined in UnitTests.xml and called by phpunit
21 * before instantiating the test suites, it must also be included
22 * with phpunit parameter --bootstrap if executing single test case classes.
23 *
24 * For easy access to the PHPUnit and VFS framework, it is recommended to install the phpunit TYPO3 Extension
25 * It does not need to be activated, nor a cli user needs to be present.
26 * But it is also possible to use other installations of PHPUnit and VFS
27 *
28 * * Call whole unit test suite, example:
29 * - cd /var/www/t3master/foo # Document root of TYPO3 CMS instance (location of index.php)
30 * - typo3conf/ext/phpunit/Composer/vendor/bin/phpunit -c typo3/sysext/core/Build/UnitTests.xml
31 *
32 * Call single test case, example:
33 * - cd /var/www/t3master/foo # Document root of TYPO3 CMS instance (location of index.php)
34 * - typo3conf/ext/phpunit/Composer/vendor/bin/phpunit \
35 * --bootstrap typo3/sysext/core/Build/UnitTestsBootstrap.php \
36 * typo3/sysext/core/Tests/Uinit/DataHandling/DataHandlerTest.php
37 */
38 class UnitTestsBootstrap {
39 /**
40 * Bootstraps the system for unit tests.
41 *
42 * @return void
43 */
44 public function bootstrapSystem() {
45 $this->enableDisplayErrors()
46 ->checkForCliDispatch()
47 ->defineSitePath()
48 ->setTypo3Context()
49 ->createNecessaryDirectoriesInDocumentRoot()
50 ->includeAndStartCoreBootstrap()
51 ->initializeConfiguration()
52 ->finishCoreBootstrap();
53 }
54
55 /**
56 * Makes sure error messages during the tests get displayed no matter what is set in php.ini.
57 *
58 * @return UnitTestsBootstrap fluent interface
59 */
60 protected function enableDisplayErrors() {
61 @ini_set('display_errors', 1);
62 return $this;
63 }
64
65 /**
66 * Checks whether the tests are run using the CLI dispatcher. If so, echos a helpful message and exits with
67 * an error code 1.
68 *
69 * @return UnitTestsBootstrap fluent interface
70 */
71 protected function checkForCliDispatch() {
72 if (!defined('TYPO3_MODE')) {
73 return $this;
74 }
75
76 array_shift($_SERVER['argv']);
77 $flatArguments = implode(' ', $_SERVER['argv']);
78 echo 'Please run the unit tests using the following command:' . chr(10) .
79 sprintf('typo3conf/ext/phpunit/Composer/vendor/bin/phpunit %s', $flatArguments) . chr(10) .
80 chr(10);
81
82 exit(1);
83 }
84
85 /**
86 * Defines the PATH_site and PATH_thisScript constant and sets $_SERVER['SCRIPT_NAME'].
87 *
88 * @return UnitTestsBootstrap fluent interface
89 */
90 protected function defineSitePath() {
91 /** @var string */
92 define('PATH_site', $this->getWebRoot());
93 /** @var string */
94 define('PATH_thisScript', PATH_site . 'typo3/cli_dispatch.phpsh');
95 $_SERVER['SCRIPT_NAME'] = PATH_thisScript;
96
97 return $this;
98 }
99
100 /**
101 * Returns the absolute path the TYPO3 document root.
102 *
103 * @return string the TYPO3 document root using Unix path separators
104 *
105 * @throws \RuntimeException
106 */
107 protected function getWebRoot() {
108 if (getenv('TYPO3_PATH_WEB')) {
109 $webRoot = getenv('TYPO3_PATH_WEB') . '/';
110 } else {
111 $webRoot = getcwd() . '/';
112 }
113
114 return strtr($webRoot, '\\', '/');
115 }
116
117 /**
118 * Defines TYPO3_MODE, TYPO3_cliMode and sets the environment variable TYPO3_CONTEXT.
119 *
120 * @return UnitTestsBootstrap fluent interface
121 */
122 protected function setTypo3Context() {
123 /** @var string */
124 define('TYPO3_MODE', 'BE');
125 /** @var string */
126 define('TYPO3_cliMode', TRUE);
127 putenv('TYPO3_CONTEXT=Testing');
128
129 return $this;
130 }
131
132 /**
133 * Creates the following directories in the TYPO3 document root:
134 * - typo3conf
135 * - typo3conf/ext
136 * - typo3temp
137 * - uploads
138 *
139 * @return UnitTestsBootstrap fluent interface
140 */
141 protected function createNecessaryDirectoriesInDocumentRoot() {
142 $this->createDirectory(PATH_site . 'uploads');
143 $this->createDirectory(PATH_site . 'typo3temp');
144 $this->createDirectory(PATH_site . 'typo3conf/ext');
145
146 return $this;
147 }
148
149 /**
150 * Creates the directory $directory (recursively if required).
151 *
152 * If $directory already exists, this method is a no-op.
153 *
154 * @param string $directory absolute path of the directory to be created
155 *
156 * @return void
157 *
158 * @throws \RuntimeException
159 */
160 protected function createDirectory($directory) {
161 if (is_dir($directory)) {
162 return;
163 }
164
165 if (!mkdir($directory, 0777, TRUE)) {
166 throw new \RuntimeException('Directory "' . $directory . '" could not be created', 1404038665);
167 }
168 }
169
170 /**
171 * Includes the Core Bootstrap class and calls its first few functions.
172 *
173 * @return UnitTestsBootstrap fluent interface
174 */
175 protected function includeAndStartCoreBootstrap() {
176 require_once PATH_site . '/typo3/sysext/core/Classes/Core/Bootstrap.php';
177
178 Bootstrap::getInstance()
179 ->baseSetup()
180 ->initializeClassLoader();
181
182 return $this;
183 }
184
185 /**
186 * Provides the default configuration in $GLOBALS['TYPO3_CONF_VARS'].
187 *
188 * @return UnitTestsBootstrap fluent interface
189 */
190 protected function initializeConfiguration() {
191 $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager();
192 $GLOBALS['TYPO3_CONF_VARS'] = $configurationManager->getDefaultConfiguration();
193
194 // avoid failing tests that rely on HTTP_HOST retrieval
195 $GLOBALS['TYPO3_CONF_VARS']['SYS']['trustedHostsPattern'] = '.*';
196
197 return $this;
198 }
199
200 /**
201 * Finishes the last steps of the Core Bootstrap.
202 *
203 * @return UnitTestsBootstrap fluent interface
204 */
205 protected function finishCoreBootstrap() {
206 Bootstrap::getInstance()
207 ->disableCoreAndClassesCache()
208 ->initializeCachingFramework()
209 ->initializeClassLoaderCaches()
210 ->initializePackageManagement(\TYPO3\CMS\Core\Package\UnitTestPackageManager::class);
211
212 return $this;
213 }
214 }
215
216 $bootstrap = new UnitTestsBootstrap();
217 $bootstrap->bootstrapSystem();
218 unset($bootstrap);