Merge pull request #4809 from totten/master-cs2
[civicrm-core.git] / Civi / CiUtil / PHPUnitScanner.php
1 <?php
2 namespace Civi\CiUtil;
3 use Symfony\Component\Finder\Finder;
4
5 /**
6 * Search for PHPUnit test cases
7 */
8 class PHPUnitScanner {
9 /**
10 * @return array<string> class names
11 */
12 public static function _findTestClasses($path) {
13 // print_r(array(
14 // 'loading' => $path,
15 // get_included_files()
16 // ));
17
18 $origClasses = get_declared_classes();
19 require_once $path;
20 $newClasses = get_declared_classes();
21
22 return preg_grep('/Test$/', array_diff(
23 $newClasses,
24 $origClasses
25 ));
26 }
27
28 /**
29 * @return array (string $file => string $class)
30 */
31 public static function findTestClasses($paths) {
32 $testClasses = array();
33 $finder = new Finder();
34
35 foreach ($paths as $path) {
36 if (is_dir($path)) {
37 foreach ($finder->files()->in($paths)->name('*Test.php') as $file) {
38 $testClass = self::_findTestClasses((string) $file);
39 if (count($testClass) == 1) {
40 $testClasses[(string) $file] = array_shift($testClass);
41 }
42 elseif (count($testClass) > 1) {
43 throw new \Exception("Too many classes in $file");
44 }
45 else {
46 throw new \Exception("Too few classes in $file");
47 }
48 }
49 }
50 elseif (is_file($path)) {
51 $testClass = self::_findTestClasses($path);
52 if (count($testClass) == 1) {
53 $testClasses[$path] = array_shift($testClass);
54 }
55 elseif (count($testClass) > 1) {
56 throw new \Exception("Too many classes in $path");
57 }
58 else {
59 throw new \Exception("Too few classes in $path");
60 }
61 }
62 }
63
64 return $testClasses;
65 }
66
67 /**
68 * @param array $testClasses
69 * @return array each element is an array with keys:
70 * - file: string
71 * - class: string
72 * - method: string
73 */
74 public static function findTestsByPath($paths) {
75 $r = array();
76 $testClasses = self::findTestClasses($paths);
77 foreach ($testClasses as $testFile => $testClass) {
78 $clazz = new \ReflectionClass($testClass);
79 foreach ($clazz->getMethods() as $method) {
80 if (preg_match('/^test/', $method->name)) {
81 $r[] = array(
82 'file' => $testFile,
83 'class' => $testClass,
84 'method' => $method->name
85 );
86 }
87 }
88 }
89 return $r;
90 }
91 }