Merge branch '4.5' into master
[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
20 $origClasses = get_declared_classes();
21 require_once $path;
22 $newClasses = get_declared_classes();
23
24 return preg_grep('/Test$/', array_diff(
25 $newClasses,
26 $origClasses
27 ));
28 }
29
30 /**
31 * @param $paths
32 * @return array (string $file => string $class)
33 * (string $file => string $class)
34 * @throws \Exception
35 */
36 public static function findTestClasses($paths) {
37 $testClasses = array();
38 $finder = new Finder();
39
40 foreach ($paths as $path) {
41 if (is_dir($path)) {
42 foreach ($finder->files()->in($paths)->name('*Test.php') as $file) {
43 $testClass = self::_findTestClasses((string) $file);
44 if (count($testClass) == 1) {
45 $testClasses[(string) $file] = array_shift($testClass);
46 }
47 elseif (count($testClass) > 1) {
48 throw new \Exception("Too many classes in $file");
49 }
50 else {
51 throw new \Exception("Too few classes in $file");
52 }
53 }
54 }
55 elseif (is_file($path)) {
56 $testClass = self::_findTestClasses($path);
57 if (count($testClass) == 1) {
58 $testClasses[$path] = array_shift($testClass);
59 }
60 elseif (count($testClass) > 1) {
61 throw new \Exception("Too many classes in $path");
62 }
63 else {
64 throw new \Exception("Too few classes in $path");
65 }
66 }
67 }
68
69 return $testClasses;
70 }
71
72 /**
73 * @param array $paths
74 *
75 * @return array
76 * each element is an array with keys:
77 * - file: string
78 * - class: string
79 * - method: string
80 */
81 public static function findTestsByPath($paths) {
82 $r = array();
83 $testClasses = self::findTestClasses($paths);
84 foreach ($testClasses as $testFile => $testClass) {
85 $clazz = new \ReflectionClass($testClass);
86 foreach ($clazz->getMethods() as $method) {
87 if (preg_match('/^test/', $method->name)) {
88 $r[] = array(
89 'file' => $testFile,
90 'class' => $testClass,
91 'method' => $method->name
92 );
93 }
94 }
95 }
96 return $r;
97 }
98 }