a2766a6d27cc69539d1358fb0afa30fb4fc7bb43
[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 /**
41 * Bootstraps the system for unit tests.
42 *
43 * @return void
44 */
45 public function bootstrapSystem() {
46 $this->enableDisplayErrors()
47 ->checkForCliDispatch()
48 ->defineSitePath()
49 ->setTypo3Context()
50 ->createNecessaryDirectoriesInDocumentRoot()
51 ->includeAndStartCoreBootstrap()
52 ->initializeConfiguration()
53 ->finishCoreBootstrap();
54 }
55
56 /**
57 * Makes sure error messages during the tests get displayed no matter what is set in php.ini.
58 *
59 * @return UnitTestsBootstrap fluent interface
60 */
61 protected function enableDisplayErrors() {
62 @ini_set('display_errors', 1);
63 return $this;
64 }
65
66 /**
67 * Checks whether the tests are run using the CLI dispatcher. If so, echos a helpful message and exits with
68 * an error code 1.
69 *
70 * @return UnitTestsBootstrap fluent interface
71 */
72 protected function checkForCliDispatch() {
73 if (!defined('TYPO3_MODE')) {
74 return $this;
75 }
76
77 array_shift($_SERVER['argv']);
78 $flatArguments = implode(' ', $_SERVER['argv']);
79 echo 'Please run the unit tests using the following command:' . chr(10) .
80 sprintf('typo3conf/ext/phpunit/Composer/vendor/bin/phpunit %s', $flatArguments) . chr(10) .
81 chr(10);
82
83 exit(1);
84 }
85
86 /**
87 * Defines the PATH_site and PATH_thisScript constant and sets $_SERVER['SCRIPT_NAME'].
88 *
89 * @return UnitTestsBootstrap fluent interface
90 */
91 protected function defineSitePath() {
92 /** @var string */
93 define('PATH_site', $this->getWebRoot());
94 /** @var string */
95 define('PATH_thisScript', PATH_site . 'typo3/cli_dispatch.phpsh');
96 $_SERVER['SCRIPT_NAME'] = PATH_thisScript;
97
98 return $this;
99 }
100
101 /**
102 * Returns the absolute path the TYPO3 document root.
103 *
104 * @return string the TYPO3 document root using Unix path separators
105 */
106 protected function getWebRoot() {
107 if (getenv('TYPO3_PATH_WEB')) {
108 $webRoot = getenv('TYPO3_PATH_WEB') . '/';
109 } else {
110 $webRoot = getcwd() . '/';
111 }
112
113 return strtr($webRoot, '\\', '/');
114 }
115
116 /**
117 * Defines TYPO3_MODE, TYPO3_cliMode and sets the environment variable TYPO3_CONTEXT.
118 *
119 * @return UnitTestsBootstrap fluent interface
120 */
121 protected function setTypo3Context() {
122 /** @var string */
123 define('TYPO3_MODE', 'BE');
124 /** @var string */
125 define('TYPO3_cliMode', TRUE);
126 putenv('TYPO3_CONTEXT=Testing');
127
128 return $this;
129 }
130
131 /**
132 * Creates the following directories in the TYPO3 document root:
133 * - typo3conf
134 * - typo3conf/ext
135 * - typo3temp
136 * - uploads
137 *
138 * @return UnitTestsBootstrap fluent interface
139 */
140 protected function createNecessaryDirectoriesInDocumentRoot() {
141 $this->createDirectory(PATH_site . 'uploads');
142 $this->createDirectory(PATH_site . 'typo3temp');
143 $this->createDirectory(PATH_site . 'typo3conf/ext');
144
145 return $this;
146 }
147
148 /**
149 * Creates the directory $directory (recursively if required).
150 *
151 * If $directory already exists, this method is a no-op.
152 *
153 * @param string $directory absolute path of the directory to be created
154 * @return void
155 * @throws \RuntimeException
156 */
157 protected function createDirectory($directory) {
158 if (is_dir($directory)) {
159 return;
160 }
161 @mkdir($directory, 0777, TRUE);
162 clearstatcache();
163 if (!is_dir($directory)) {
164 throw new \RuntimeException('Directory "' . $directory . '" could not be created', 1423043755);
165 }
166 }
167
168 /**
169 * Includes the Core Bootstrap class and calls its first few functions.
170 *
171 * @return UnitTestsBootstrap fluent interface
172 */
173 protected function includeAndStartCoreBootstrap() {
174 $classLoader = require PATH_site . '/typo3/contrib/vendor/autoload.php';
175
176 Bootstrap::getInstance()
177 ->initializeClassLoader($classLoader)
178 ->baseSetup();
179
180 return $this;
181 }
182
183 /**
184 * Provides the default configuration in $GLOBALS['TYPO3_CONF_VARS'].
185 *
186 * @return UnitTestsBootstrap fluent interface
187 */
188 protected function initializeConfiguration() {
189 $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager();
190 $GLOBALS['TYPO3_CONF_VARS'] = $configurationManager->getDefaultConfiguration();
191
192 // avoid failing tests that rely on HTTP_HOST retrieval
193 $GLOBALS['TYPO3_CONF_VARS']['SYS']['trustedHostsPattern'] = '.*';
194
195 return $this;
196 }
197
198 /**
199 * Finishes the last steps of the Core Bootstrap.
200 *
201 * @return UnitTestsBootstrap fluent interface
202 */
203 protected function finishCoreBootstrap() {
204 Bootstrap::getInstance()
205 ->disableCoreCache()
206 ->initializeCachingFramework()
207 ->initializePackageManagement(\TYPO3\CMS\Core\Package\UnitTestPackageManager::class)
208 ->ensureClassLoadingInformationExists();
209
210 return $this;
211 }
212 }
213
214 $bootstrap = new UnitTestsBootstrap();
215 $bootstrap->bootstrapSystem();
216 unset($bootstrap);