Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /** | |
3 | * File for the CiviTestSuite class | |
4 | * | |
5 | * (PHP 5) | |
6 | * | |
7 | * @copyright Copyright CiviCRM LLC (C) 2009 | |
8 | * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html | |
9 | * GNU Affero General Public License version 3 | |
10 | * @package CiviCRM | |
11 | * | |
12 | * This file is part of CiviCRM | |
13 | * | |
14 | * CiviCRM is free software; you can redistribute it and/or | |
15 | * modify it under the terms of the GNU Affero General Public License | |
16 | * as published by the Free Software Foundation; either version 3 of | |
17 | * the License, or (at your option) any later version. | |
18 | * | |
19 | * CiviCRM is distributed in the hope that it will be useful, | |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | * GNU Affero General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU Affero General Public | |
25 | * License along with this program. If not, see | |
26 | * <http://www.gnu.org/licenses/>. | |
27 | */ | |
28 | ||
6a488035 TO |
29 | /** |
30 | * Parent class for test suites | |
31 | * | |
32 | * @package CiviCRM | |
33 | */ | |
a6439b6a | 34 | class CiviTestSuite extends PHPUnit\Framework\TestSuite { |
6a488035 TO |
35 | |
36 | /** | |
eceb18cc | 37 | * Simple name based constructor. |
1e1fdcf6 EM |
38 | * @param string $theClass |
39 | * @param string $name | |
6a488035 | 40 | */ |
00be9182 | 41 | public function __construct($theClass = '', $name = '') { |
6a488035 TO |
42 | if (empty($name)) { |
43 | $name = str_replace('_', | |
44 | ' ', | |
45 | get_class($this) | |
46 | ); | |
47 | ||
48 | // also split AllTests to All Tests | |
49 | $name = str_replace('AllTests', 'All Tests', $name); | |
50 | } | |
51 | parent::__construct($name); | |
52 | ||
53 | // also load the class loader | |
54 | require_once 'CRM/Core/ClassLoader.php'; | |
55 | CRM_Core_ClassLoader::singleton()->register(); | |
56 | } | |
57 | ||
6a488035 | 58 | /** |
eceb18cc | 59 | * suppress failed test error issued by phpunit when it finds. |
6a488035 TO |
60 | * a test suite with no tests |
61 | */ | |
00be9182 | 62 | public function testNothing() { |
6a488035 TO |
63 | } |
64 | ||
65 | /** | |
1e1fdcf6 EM |
66 | * @param $myfile |
67 | * @return \PHPUnit_Framework_TestSuite | |
6a488035 TO |
68 | */ |
69 | protected function implSuite($myfile) { | |
70 | $name = str_replace('_', | |
71 | ' ', | |
72 | get_class($this) | |
73 | ); | |
74 | ||
75 | // also split AllTests to All Tests | |
76 | $name = str_replace('AllTests', 'All Tests', $name); | |
77 | ||
a6439b6a | 78 | $suite = new PHPUnit\Framework\TestSuite($name); |
6a488035 TO |
79 | $this->addAllTests($suite, $myfile, |
80 | new SplFileInfo(dirname($myfile)) | |
81 | ); | |
82 | return $suite; | |
83 | } | |
84 | ||
85 | /** | |
86 | * Add all test classes *Test and all test suites *Tests in subdirectories | |
87 | * | |
a6439b6a | 88 | * @param PHPUnit\Framework\TestSuite $suite |
72b3a70c | 89 | * Test suite object to add tests to |
2a6da8d7 EM |
90 | * @param $myfile |
91 | * @param SplFileInfo $dirInfo | |
72b3a70c | 92 | * object to scan |
2a6da8d7 | 93 | * |
72b3a70c | 94 | * @return void |
6a488035 | 95 | */ |
5896d037 | 96 | protected function addAllTests( |
a6439b6a | 97 | PHPUnit\Framework\TestSuite &$suite, |
5896d037 | 98 | $myfile, SplFileInfo $dirInfo |
6a488035 TO |
99 | ) { |
100 | //echo get_class($this)."::addAllTests($myfile,".$dirInfo->getRealPath().")\n"; | |
101 | if (!$dirInfo->isReadable() | |
102 | || !$dirInfo->isDir() | |
103 | ) { | |
104 | return; | |
105 | } | |
106 | ||
107 | // Pass 1: Check all *Tests.php files | |
39b959db | 108 | // array(callable) |
affcc9d2 | 109 | $addTests = []; |
6a488035 TO |
110 | //echo "start Pass 1 on {$dirInfo->getRealPath()}\n"; |
111 | $dir = new DirectoryIterator($dirInfo->getRealPath()); | |
112 | foreach ($dir as $fileInfo) { | |
113 | if ($fileInfo->isReadable() && $fileInfo->isFile() | |
114 | && preg_match('/Tests.php$/', | |
115 | $fileInfo->getFilename() | |
116 | ) | |
117 | ) { | |
118 | if ($fileInfo->getRealPath() == $myfile) { | |
119 | // Don't create an infinite loop | |
120 | //echo "ignoring {$fileInfo->getRealPath()}\n"; | |
121 | continue; | |
122 | } | |
123 | //echo "checking file ".$fileInfo->getRealPath( )."\n"; | |
124 | // This is a file with a name ending in 'Tests.php'. | |
125 | // Get all classes defined in the file and add those | |
126 | // with a class name ending in 'Test' to the test suite | |
127 | $oldClassNames = get_declared_classes(); | |
128 | require_once $fileInfo->getRealPath(); | |
129 | $newClassNames = get_declared_classes(); | |
130 | foreach (array_diff($newClassNames, | |
131 | $oldClassNames | |
132 | ) as $name) { | |
133 | if (preg_match('/Tests$/', $name)) { | |
134 | $addTests[] = $name . '::suite'; | |
135 | } | |
136 | } | |
137 | } | |
138 | } | |
139 | sort($addTests); | |
140 | foreach ($addTests as $addTest) { | |
141 | $suite->addTest(call_user_func($addTest)); | |
142 | } | |
143 | ||
144 | // Pass 2: Scan all subdirectories | |
39b959db | 145 | // array(array(0 => $suite, 1 => $file, 2 => SplFileinfo)) |
affcc9d2 | 146 | $addAllTests = []; |
6a488035 TO |
147 | $dir = new DirectoryIterator($dirInfo->getRealPath()); |
148 | //echo "start Pass 2 on {$dirInfo->getRealPath()}\n"; | |
149 | foreach ($dir as $fileInfo) { | |
150 | if ($fileInfo->isDir() | |
151 | && (substr($fileInfo->getFilename(), 0, 1) != '.') | |
152 | ) { | |
153 | // This is a directory that may contain tests so scan it | |
154 | $addAllTests[] = clone $fileInfo; | |
155 | } | |
156 | } | |
157 | //$addAllTests = CRM_Utils_Array::crmArraySortByField($addAllTests, '1'); | |
158 | usort($addAllTests, function ($a, $b) { | |
159 | return strnatcmp($a->getRealPath(), $b->getRealPath()); | |
160 | }); | |
161 | foreach ($addAllTests as $addAllTest) { | |
162 | $this->addAllTests($suite, $myfile, $addAllTest); | |
163 | } | |
164 | ||
165 | // Pass 3: Check all *Test.php files in this directory | |
166 | //echo "start Pass 3 on {$dirInfo->getRealPath()}\n"; | |
39b959db | 167 | // array(className) |
affcc9d2 | 168 | $addTestSuites = []; |
6a488035 TO |
169 | $dir = new DirectoryIterator($dirInfo->getRealPath()); |
170 | foreach ($dir as $fileInfo) { | |
171 | if ($fileInfo->isReadable() && $fileInfo->isFile() | |
172 | && preg_match('/Test.php$/', | |
173 | $fileInfo->getFilename() | |
174 | ) | |
175 | ) { | |
176 | //echo "checking file ".$fileInfo->getRealPath( )."\n"; | |
177 | // This is a file with a name ending in 'Tests?.php'. | |
178 | // Get all classes defined in the file and add those | |
179 | // with a class name ending in 'Test' to the test suite | |
180 | $oldClassNames = get_declared_classes(); | |
181 | require_once $fileInfo->getRealPath(); | |
182 | $newClassNames = get_declared_classes(); | |
183 | foreach (array_diff($newClassNames, | |
184 | $oldClassNames | |
185 | ) as $name) { | |
4339bc55 | 186 | if (strpos($fileInfo->getRealPath(), strtr($name, '_\\', '//') . ".php") !== FALSE) { |
61f3a620 RN |
187 | if (preg_match('/Test$/', $name)) { |
188 | $addTestSuites[] = $name; | |
189 | } | |
6a488035 TO |
190 | } |
191 | } | |
192 | } | |
193 | } | |
194 | sort($addTestSuites); | |
195 | foreach ($addTestSuites as $addTestSuite) { | |
196 | $suite->addTestSuite($addTestSuite); | |
197 | } | |
198 | ||
199 | // print_r(array($prefix, 'addTests' => $addTests, 'addAllTests' => $addAllTests, 'addTestSuites' => $addTestSuites)); | |
200 | } | |
96025800 | 201 | |
6a488035 | 202 | } |