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