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 | ||
29 | /** | |
30 | * Include parent class definition | |
31 | */ | |
32 | require_once 'PHPUnit/Framework/TestSuite.php'; | |
33 | ||
34 | /** | |
35 | * Parent class for test suites | |
36 | * | |
37 | * @package CiviCRM | |
38 | */ | |
39 | class CiviTestSuite extends PHPUnit_Framework_TestSuite { | |
40 | ||
41 | /** | |
42 | * Simple name based constructor | |
43 | */ | |
44 | function __construct($theClass = '', $name = '') { | |
45 | if (empty($name)) { | |
46 | $name = str_replace('_', | |
47 | ' ', | |
48 | get_class($this) | |
49 | ); | |
50 | ||
51 | // also split AllTests to All Tests | |
52 | $name = str_replace('AllTests', 'All Tests', $name); | |
53 | } | |
54 | parent::__construct($name); | |
55 | ||
56 | // also load the class loader | |
57 | require_once 'CRM/Core/ClassLoader.php'; | |
58 | CRM_Core_ClassLoader::singleton()->register(); | |
59 | } | |
60 | ||
61 | /** | |
62 | * Test suite setup | |
63 | */ | |
64 | protected function setUp() { | |
65 | //print __METHOD__ . "\n"; | |
66 | } | |
67 | ||
68 | /** | |
69 | * Test suite teardown | |
70 | */ | |
71 | protected function tearDown() { | |
72 | //print __METHOD__ . "\n"; | |
73 | } | |
74 | ||
75 | /** | |
76 | * suppress failed test error issued by phpunit when it finds | |
77 | * a test suite with no tests | |
78 | */ | |
79 | function testNothing() { | |
80 | } | |
81 | ||
82 | /** | |
83 | * | |
84 | */ | |
85 | protected function implSuite($myfile) { | |
86 | $name = str_replace('_', | |
87 | ' ', | |
88 | get_class($this) | |
89 | ); | |
90 | ||
91 | // also split AllTests to All Tests | |
92 | $name = str_replace('AllTests', 'All Tests', $name); | |
93 | ||
94 | $suite = new PHPUnit_Framework_TestSuite($name); | |
95 | $this->addAllTests($suite, $myfile, | |
96 | new SplFileInfo(dirname($myfile)) | |
97 | ); | |
98 | return $suite; | |
99 | } | |
100 | ||
101 | /** | |
102 | * Add all test classes *Test and all test suites *Tests in subdirectories | |
103 | * | |
104 | * @param &object Test suite object to add tests to | |
105 | * @param object Directory to scan | |
106 | * @return Test suite has been updated | |
107 | */ | |
108 | protected function addAllTests(PHPUnit_Framework_TestSuite & $suite, | |
109 | $myfile, SplFileInfo $dirInfo | |
110 | ) { | |
111 | //echo get_class($this)."::addAllTests($myfile,".$dirInfo->getRealPath().")\n"; | |
112 | if (!$dirInfo->isReadable() | |
113 | || !$dirInfo->isDir() | |
114 | ) { | |
115 | return; | |
116 | } | |
117 | ||
118 | // Pass 1: Check all *Tests.php files | |
119 | $addTests = array(); // array(callable) | |
120 | //echo "start Pass 1 on {$dirInfo->getRealPath()}\n"; | |
121 | $dir = new DirectoryIterator($dirInfo->getRealPath()); | |
122 | foreach ($dir as $fileInfo) { | |
123 | if ($fileInfo->isReadable() && $fileInfo->isFile() | |
124 | && preg_match('/Tests.php$/', | |
125 | $fileInfo->getFilename() | |
126 | ) | |
127 | ) { | |
128 | if ($fileInfo->getRealPath() == $myfile) { | |
129 | // Don't create an infinite loop | |
130 | //echo "ignoring {$fileInfo->getRealPath()}\n"; | |
131 | continue; | |
132 | } | |
133 | //echo "checking file ".$fileInfo->getRealPath( )."\n"; | |
134 | // This is a file with a name ending in 'Tests.php'. | |
135 | // Get all classes defined in the file and add those | |
136 | // with a class name ending in 'Test' to the test suite | |
137 | $oldClassNames = get_declared_classes(); | |
138 | require_once $fileInfo->getRealPath(); | |
139 | $newClassNames = get_declared_classes(); | |
140 | foreach (array_diff($newClassNames, | |
141 | $oldClassNames | |
142 | ) as $name) { | |
143 | if (preg_match('/Tests$/', $name)) { | |
144 | $addTests[] = $name . '::suite'; | |
145 | } | |
146 | } | |
147 | } | |
148 | } | |
149 | sort($addTests); | |
150 | foreach ($addTests as $addTest) { | |
151 | $suite->addTest(call_user_func($addTest)); | |
152 | } | |
153 | ||
154 | // Pass 2: Scan all subdirectories | |
155 | $addAllTests = array(); // array(array(0 => $suite, 1 => $file, 2 => SplFileinfo)) | |
156 | $dir = new DirectoryIterator($dirInfo->getRealPath()); | |
157 | //echo "start Pass 2 on {$dirInfo->getRealPath()}\n"; | |
158 | foreach ($dir as $fileInfo) { | |
159 | if ($fileInfo->isDir() | |
160 | && (substr($fileInfo->getFilename(), 0, 1) != '.') | |
161 | ) { | |
162 | // This is a directory that may contain tests so scan it | |
163 | $addAllTests[] = clone $fileInfo; | |
164 | } | |
165 | } | |
166 | //$addAllTests = CRM_Utils_Array::crmArraySortByField($addAllTests, '1'); | |
167 | usort($addAllTests, function ($a, $b) { | |
168 | return strnatcmp($a->getRealPath(), $b->getRealPath()); | |
169 | }); | |
170 | foreach ($addAllTests as $addAllTest) { | |
171 | $this->addAllTests($suite, $myfile, $addAllTest); | |
172 | } | |
173 | ||
174 | // Pass 3: Check all *Test.php files in this directory | |
175 | //echo "start Pass 3 on {$dirInfo->getRealPath()}\n"; | |
176 | $addTestSuites = array(); // array(className) | |
177 | $dir = new DirectoryIterator($dirInfo->getRealPath()); | |
178 | foreach ($dir as $fileInfo) { | |
179 | if ($fileInfo->isReadable() && $fileInfo->isFile() | |
180 | && preg_match('/Test.php$/', | |
181 | $fileInfo->getFilename() | |
182 | ) | |
183 | ) { | |
184 | //echo "checking file ".$fileInfo->getRealPath( )."\n"; | |
185 | // This is a file with a name ending in 'Tests?.php'. | |
186 | // Get all classes defined in the file and add those | |
187 | // with a class name ending in 'Test' to the test suite | |
188 | $oldClassNames = get_declared_classes(); | |
189 | require_once $fileInfo->getRealPath(); | |
190 | $newClassNames = get_declared_classes(); | |
191 | foreach (array_diff($newClassNames, | |
192 | $oldClassNames | |
193 | ) as $name) { | |
194 | if (preg_match('/Test$/', $name)) { | |
195 | $addTestSuites[] = $name; | |
196 | } | |
197 | } | |
198 | } | |
199 | } | |
200 | sort($addTestSuites); | |
201 | foreach ($addTestSuites as $addTestSuite) { | |
202 | $suite->addTestSuite($addTestSuite); | |
203 | } | |
204 | ||
205 | // print_r(array($prefix, 'addTests' => $addTests, 'addAllTests' => $addAllTests, 'addTestSuites' => $addTestSuites)); | |
206 | } | |
207 | } |