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 | */ | |
34 | class CiviTestSuite extends PHPUnit_Framework_TestSuite { | |
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 | ||
58 | /** | |
eceb18cc | 59 | * Test suite setup. |
6a488035 TO |
60 | */ |
61 | protected function setUp() { | |
62 | //print __METHOD__ . "\n"; | |
63 | } | |
64 | ||
65 | /** | |
eceb18cc | 66 | * Test suite teardown. |
6a488035 TO |
67 | */ |
68 | protected function tearDown() { | |
69 | //print __METHOD__ . "\n"; | |
70 | } | |
71 | ||
72 | /** | |
eceb18cc | 73 | * suppress failed test error issued by phpunit when it finds. |
6a488035 TO |
74 | * a test suite with no tests |
75 | */ | |
00be9182 | 76 | public function testNothing() { |
6a488035 TO |
77 | } |
78 | ||
79 | /** | |
1e1fdcf6 EM |
80 | * @param $myfile |
81 | * @return \PHPUnit_Framework_TestSuite | |
6a488035 TO |
82 | */ |
83 | protected function implSuite($myfile) { | |
84 | $name = str_replace('_', | |
85 | ' ', | |
86 | get_class($this) | |
87 | ); | |
88 | ||
89 | // also split AllTests to All Tests | |
90 | $name = str_replace('AllTests', 'All Tests', $name); | |
91 | ||
92 | $suite = new PHPUnit_Framework_TestSuite($name); | |
93 | $this->addAllTests($suite, $myfile, | |
94 | new SplFileInfo(dirname($myfile)) | |
95 | ); | |
96 | return $suite; | |
97 | } | |
98 | ||
99 | /** | |
100 | * Add all test classes *Test and all test suites *Tests in subdirectories | |
101 | * | |
2a6da8d7 | 102 | * @param PHPUnit_Framework_TestSuite $suite |
72b3a70c | 103 | * Test suite object to add tests to |
2a6da8d7 EM |
104 | * @param $myfile |
105 | * @param SplFileInfo $dirInfo | |
72b3a70c | 106 | * object to scan |
2a6da8d7 | 107 | * |
72b3a70c | 108 | * @return void |
6a488035 | 109 | */ |
5896d037 TO |
110 | protected function addAllTests( |
111 | PHPUnit_Framework_TestSuite &$suite, | |
112 | $myfile, SplFileInfo $dirInfo | |
6a488035 TO |
113 | ) { |
114 | //echo get_class($this)."::addAllTests($myfile,".$dirInfo->getRealPath().")\n"; | |
115 | if (!$dirInfo->isReadable() | |
116 | || !$dirInfo->isDir() | |
117 | ) { | |
118 | return; | |
119 | } | |
120 | ||
121 | // Pass 1: Check all *Tests.php files | |
122 | $addTests = array(); // array(callable) | |
123 | //echo "start Pass 1 on {$dirInfo->getRealPath()}\n"; | |
124 | $dir = new DirectoryIterator($dirInfo->getRealPath()); | |
125 | foreach ($dir as $fileInfo) { | |
126 | if ($fileInfo->isReadable() && $fileInfo->isFile() | |
127 | && preg_match('/Tests.php$/', | |
128 | $fileInfo->getFilename() | |
129 | ) | |
130 | ) { | |
131 | if ($fileInfo->getRealPath() == $myfile) { | |
132 | // Don't create an infinite loop | |
133 | //echo "ignoring {$fileInfo->getRealPath()}\n"; | |
134 | continue; | |
135 | } | |
136 | //echo "checking file ".$fileInfo->getRealPath( )."\n"; | |
137 | // This is a file with a name ending in 'Tests.php'. | |
138 | // Get all classes defined in the file and add those | |
139 | // with a class name ending in 'Test' to the test suite | |
140 | $oldClassNames = get_declared_classes(); | |
141 | require_once $fileInfo->getRealPath(); | |
142 | $newClassNames = get_declared_classes(); | |
143 | foreach (array_diff($newClassNames, | |
144 | $oldClassNames | |
145 | ) as $name) { | |
146 | if (preg_match('/Tests$/', $name)) { | |
147 | $addTests[] = $name . '::suite'; | |
148 | } | |
149 | } | |
150 | } | |
151 | } | |
152 | sort($addTests); | |
153 | foreach ($addTests as $addTest) { | |
154 | $suite->addTest(call_user_func($addTest)); | |
155 | } | |
156 | ||
157 | // Pass 2: Scan all subdirectories | |
158 | $addAllTests = array(); // array(array(0 => $suite, 1 => $file, 2 => SplFileinfo)) | |
159 | $dir = new DirectoryIterator($dirInfo->getRealPath()); | |
160 | //echo "start Pass 2 on {$dirInfo->getRealPath()}\n"; | |
161 | foreach ($dir as $fileInfo) { | |
162 | if ($fileInfo->isDir() | |
163 | && (substr($fileInfo->getFilename(), 0, 1) != '.') | |
164 | ) { | |
165 | // This is a directory that may contain tests so scan it | |
166 | $addAllTests[] = clone $fileInfo; | |
167 | } | |
168 | } | |
169 | //$addAllTests = CRM_Utils_Array::crmArraySortByField($addAllTests, '1'); | |
170 | usort($addAllTests, function ($a, $b) { | |
171 | return strnatcmp($a->getRealPath(), $b->getRealPath()); | |
172 | }); | |
173 | foreach ($addAllTests as $addAllTest) { | |
174 | $this->addAllTests($suite, $myfile, $addAllTest); | |
175 | } | |
176 | ||
177 | // Pass 3: Check all *Test.php files in this directory | |
178 | //echo "start Pass 3 on {$dirInfo->getRealPath()}\n"; | |
179 | $addTestSuites = array(); // array(className) | |
180 | $dir = new DirectoryIterator($dirInfo->getRealPath()); | |
181 | foreach ($dir as $fileInfo) { | |
182 | if ($fileInfo->isReadable() && $fileInfo->isFile() | |
183 | && preg_match('/Test.php$/', | |
184 | $fileInfo->getFilename() | |
185 | ) | |
186 | ) { | |
187 | //echo "checking file ".$fileInfo->getRealPath( )."\n"; | |
188 | // This is a file with a name ending in 'Tests?.php'. | |
189 | // Get all classes defined in the file and add those | |
190 | // with a class name ending in 'Test' to the test suite | |
191 | $oldClassNames = get_declared_classes(); | |
192 | require_once $fileInfo->getRealPath(); | |
193 | $newClassNames = get_declared_classes(); | |
194 | foreach (array_diff($newClassNames, | |
195 | $oldClassNames | |
196 | ) as $name) { | |
4339bc55 | 197 | if (strpos($fileInfo->getRealPath(), strtr($name, '_\\', '//') . ".php") !== FALSE) { |
61f3a620 RN |
198 | if (preg_match('/Test$/', $name)) { |
199 | $addTestSuites[] = $name; | |
200 | } | |
6a488035 TO |
201 | } |
202 | } | |
203 | } | |
204 | } | |
205 | sort($addTestSuites); | |
206 | foreach ($addTestSuites as $addTestSuite) { | |
207 | $suite->addTestSuite($addTestSuite); | |
208 | } | |
209 | ||
210 | // print_r(array($prefix, 'addTests' => $addTests, 'addAllTests' => $addAllTests, 'addTestSuites' => $addTestSuites)); | |
211 | } | |
96025800 | 212 | |
6a488035 | 213 | } |