Completed
Pull Request — master (#204)
by
unknown
02:26
created

TestFileLoader::__construct()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 9.4285
cc 3
eloc 4
nc 2
nop 1
crap 3
1
<?php
2
3
4
namespace ParaTest\Runners\PHPUnit;
5
6
7
class TestFileLoader
8
{
9
    /**
10
     * The pattern used for grabbing test files. Uses the *Test.php convention
11
     * that PHPUnit defaults to.
12
     */
13
    const TEST_PATTERN = '/.+Test\.php$/';
14
15
    /**
16
     * Matches php files
17
     */
18
    const FILE_PATTERN = '/.+\.php$/';
19
20
    /**
21
     * Used to ignore directory paths '.' and '..'
22
     *
23
     * @var string
24
     */
25
    private static $dotPattern = '/([.]+)$/';
26
27
    /**
28
     * The collection of loaded files for this test suite
29
     *
30
     * @var array
31
     */
32
    protected $files = array();
33
34
    /**
35
     * The collection of excluded files
36
     *
37
     * @var array
38
     */
39
    protected $excludedFiles = array();
40
41
    /**
42
     * When true, the SuiteLoader add the files to excluded files
43
     *
44
     * @var bool
45
     */
46
    protected $excludingFiles = false;
47
48
49 25
    public function __construct($options = null)
50
    {
51 25
        if ($options && !$options instanceof Options) {
52 1
            throw new \InvalidArgumentException("SuiteLoader options must be null or of type Options");
53
        }
54
55 24
        $this->options = $options;
0 ignored issues
show
Bug introduced by
The property options does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
56 24
    }
57
58
    /**
59
     * Loads a SuitePath and makes sure to
60
     * take into account the excluded directory / files
61
     *
62
     * @param SuitePath $path
63
     * @return string[]
64
     */
65 12
    public function loadSuitePath(SuitePath $path)
66
    {
67
        // First initialize the list of files and excluded files
68 12
        $this->files          = array();
69 12
        $this->excludedFiles  = array();
70 12
        $this->excludingFiles = true;
71 12
        foreach ($path->getExcludedPaths() as $excludedPath) {
72 2
            $this->loadPath($excludedPath, $path->getPattern());
73 12
        }
74
75
        // Load the SuitePath
76 12
        $this->excludingFiles = false;
77 12
        $this->loadPath($path->getPath(), $path->getPattern());
78
79
        // Reinitialise the excluded files
80 12
        $this->excludedFiles = array();
81
82 12
        return $this->files;
83
    }
84
85
    /**
86
     * Loads suites based on a specific path.
87
     * A valid path can be a directory or file
88
     *
89
     * @param $path
90
     * @param $pattern
91
     * @throws \InvalidArgumentException
92
     * @return string[]
93
     */
94 22
    public function loadPath($path, $pattern = null)
95
    {
96 22
        $this->files = array();
97 22
        $path        = $path ?: $this->options->path;
98 22
        $pattern     = is_null($pattern) ? self::TEST_PATTERN : $pattern;
99
100 22
        if (!file_exists($path)) {
101 2
            throw new \InvalidArgumentException("$path is not a valid directory or file");
102
        }
103 20
        if (is_dir($path)) {
104 13
            $this->loadDir($path, $pattern);
105 20
        } elseif (file_exists($path)) {
106 11
            $this->loadFile($path);
107 11
        }
108
109 20
        return $this->files;
110
    }
111
112
    /**
113
     * Loads suites from a directory
114
     *
115
     * @param string $path
116
     * @param string $pattern
117
     */
118 13
    private function loadDir($path, $pattern = self::TEST_PATTERN)
119
    {
120 13
        $files = scandir($path);
121 13
        foreach ($files as $file) {
122 13
            $this->tryLoadTests($path.DIRECTORY_SEPARATOR.$file, $pattern);
123 13
        }
124 13
    }
125
126
    /**
127
     * Load a single suite file
128
     *
129
     * @param $path
130
     */
131 11
    private function loadFile($path)
132
    {
133 11
        $this->tryLoadTests($path, self::FILE_PATTERN);
134 11
    }
135
136
    /**
137
     * Attempts to load suites from a path.
138
     *
139
     * @param string $path
140
     * @param string $pattern regular expression for matching file names
141
     */
142 20
    private function tryLoadTests($path, $pattern = self::TEST_PATTERN)
143
    {
144 20
        if (preg_match($pattern, $path)) {
145 20
            if ($this->excludingFiles) {
146 2
                $this->excludedFiles[$path] = $path;
147 20
            } elseif (!array_key_exists($path, $this->excludedFiles)) {
148 20
                $this->files[] = $path;
149 20
            }
150 20
        }
151
152 20
        if (!preg_match(self::$dotPattern, $path) && is_dir($path)) {
153 8
            $this->loadDir($path, $pattern);
154 8
        }
155 20
    }
156
157
}