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 | * | |
2a6da8d7 EM |
104 | * @param PHPUnit_Framework_TestSuite $suite |
105 | * @param $myfile | |
106 | * @param SplFileInfo $dirInfo | |
107 | * | |
108 | * @internal param $ &object Test suite object to add tests to | |
109 | * @internal param \Directory $object to scan | |
6a488035 TO |
110 | * @return Test suite has been updated |
111 | */ | |
112 | protected function addAllTests(PHPUnit_Framework_TestSuite & $suite, | |
113 | $myfile, SplFileInfo $dirInfo | |
114 | ) { | |
115 | //echo get_class($this)."::addAllTests($myfile,".$dirInfo->getRealPath().")\n"; | |
116 | if (!$dirInfo->isReadable() | |
117 | || !$dirInfo->isDir() | |
118 | ) { | |
119 | return; | |
120 | } | |
121 | ||
122 | // Pass 1: Check all *Tests.php files | |
123 | $addTests = array(); // array(callable) | |
124 | //echo "start Pass 1 on {$dirInfo->getRealPath()}\n"; | |
125 | $dir = new DirectoryIterator($dirInfo->getRealPath()); | |
126 | foreach ($dir as $fileInfo) { | |
127 | if ($fileInfo->isReadable() && $fileInfo->isFile() | |
128 | && preg_match('/Tests.php$/', | |
129 | $fileInfo->getFilename() | |
130 | ) | |
131 | ) { | |
132 | if ($fileInfo->getRealPath() == $myfile) { | |
133 | // Don't create an infinite loop | |
134 | //echo "ignoring {$fileInfo->getRealPath()}\n"; | |
135 | continue; | |
136 | } | |
137 | //echo "checking file ".$fileInfo->getRealPath( )."\n"; | |
138 | // This is a file with a name ending in 'Tests.php'. | |
139 | // Get all classes defined in the file and add those | |
140 | // with a class name ending in 'Test' to the test suite | |
141 | $oldClassNames = get_declared_classes(); | |
142 | require_once $fileInfo->getRealPath(); | |
143 | $newClassNames = get_declared_classes(); | |
144 | foreach (array_diff($newClassNames, | |
145 | $oldClassNames | |
146 | ) as $name) { | |
147 | if (preg_match('/Tests$/', $name)) { | |
148 | $addTests[] = $name . '::suite'; | |
149 | } | |
150 | } | |
151 | } | |
152 | } | |
153 | sort($addTests); | |
154 | foreach ($addTests as $addTest) { | |
155 | $suite->addTest(call_user_func($addTest)); | |
156 | } | |
157 | ||
158 | // Pass 2: Scan all subdirectories | |
159 | $addAllTests = array(); // array(array(0 => $suite, 1 => $file, 2 => SplFileinfo)) | |
160 | $dir = new DirectoryIterator($dirInfo->getRealPath()); | |
161 | //echo "start Pass 2 on {$dirInfo->getRealPath()}\n"; | |
162 | foreach ($dir as $fileInfo) { | |
163 | if ($fileInfo->isDir() | |
164 | && (substr($fileInfo->getFilename(), 0, 1) != '.') | |
165 | ) { | |
166 | // This is a directory that may contain tests so scan it | |
167 | $addAllTests[] = clone $fileInfo; | |
168 | } | |
169 | } | |
170 | //$addAllTests = CRM_Utils_Array::crmArraySortByField($addAllTests, '1'); | |
171 | usort($addAllTests, function ($a, $b) { | |
172 | return strnatcmp($a->getRealPath(), $b->getRealPath()); | |
173 | }); | |
174 | foreach ($addAllTests as $addAllTest) { | |
175 | $this->addAllTests($suite, $myfile, $addAllTest); | |
176 | } | |
177 | ||
178 | // Pass 3: Check all *Test.php files in this directory | |
179 | //echo "start Pass 3 on {$dirInfo->getRealPath()}\n"; | |
180 | $addTestSuites = array(); // array(className) | |
181 | $dir = new DirectoryIterator($dirInfo->getRealPath()); | |
182 | foreach ($dir as $fileInfo) { | |
183 | if ($fileInfo->isReadable() && $fileInfo->isFile() | |
184 | && preg_match('/Test.php$/', | |
185 | $fileInfo->getFilename() | |
186 | ) | |
187 | ) { | |
188 | //echo "checking file ".$fileInfo->getRealPath( )."\n"; | |
189 | // This is a file with a name ending in 'Tests?.php'. | |
190 | // Get all classes defined in the file and add those | |
191 | // with a class name ending in 'Test' to the test suite | |
192 | $oldClassNames = get_declared_classes(); | |
193 | require_once $fileInfo->getRealPath(); | |
194 | $newClassNames = get_declared_classes(); | |
195 | foreach (array_diff($newClassNames, | |
196 | $oldClassNames | |
197 | ) as $name) { | |
4339bc55 | 198 | if (strpos($fileInfo->getRealPath(), strtr($name, '_\\', '//') . ".php") !== FALSE) { |
61f3a620 RN |
199 | if (preg_match('/Test$/', $name)) { |
200 | $addTestSuites[] = $name; | |
201 | } | |
6a488035 TO |
202 | } |
203 | } | |
204 | } | |
205 | } | |
206 | sort($addTestSuites); | |
207 | foreach ($addTestSuites as $addTestSuite) { | |
208 | $suite->addTestSuite($addTestSuite); | |
209 | } | |
210 | ||
211 | // print_r(array($prefix, 'addTests' => $addTests, 'addAllTests' => $addAllTests, 'addTestSuites' => $addTestSuites)); | |
212 | } | |
213 | } |