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