~tcuthbert/wordpress/openstack-objectstorage

« back to all changes in this revision

Viewing changes to vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php

  • Committer: Jacek Nykis
  • Date: 2015-02-11 15:35:31 UTC
  • Revision ID: jacek.nykis@canonical.com-20150211153531-hmy6zi0ov2qfkl0b
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/*
 
3
 * This file is part of the PHP_CodeCoverage package.
 
4
 *
 
5
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 
6
 *
 
7
 * For the full copyright and license information, please view the LICENSE
 
8
 * file that was distributed with this source code.
 
9
 */
 
10
 
 
11
/**
 
12
 * Factory for PHP_CodeCoverage_Report_Node_* object graphs.
 
13
 *
 
14
 * @category   PHP
 
15
 * @package    CodeCoverage
 
16
 * @author     Sebastian Bergmann <sebastian@phpunit.de>
 
17
 * @copyright  Sebastian Bergmann <sebastian@phpunit.de>
 
18
 * @license    http://www.opensource.org/licenses/BSD-3-Clause  The BSD 3-Clause License
 
19
 * @link       http://github.com/sebastianbergmann/php-code-coverage
 
20
 * @since      Class available since Release 1.1.0
 
21
 */
 
22
class PHP_CodeCoverage_Report_Factory
 
23
{
 
24
    /**
 
25
     * @param PHP_CodeCoverage $coverage
 
26
     */
 
27
    public function create(PHP_CodeCoverage $coverage)
 
28
    {
 
29
        $files      = $coverage->getData();
 
30
        $commonPath = $this->reducePaths($files);
 
31
        $root       = new PHP_CodeCoverage_Report_Node_Directory(
 
32
            $commonPath, null
 
33
        );
 
34
 
 
35
        $this->addItems(
 
36
            $root,
 
37
            $this->buildDirectoryStructure($files),
 
38
            $coverage->getTests(),
 
39
            $coverage->getCacheTokens()
 
40
        );
 
41
 
 
42
        return $root;
 
43
    }
 
44
 
 
45
    /**
 
46
     * @param PHP_CodeCoverage_Report_Node_Directory $root
 
47
     * @param array                                  $items
 
48
     * @param array                                  $tests
 
49
     * @param boolean                                $cacheTokens
 
50
     */
 
51
    private function addItems(PHP_CodeCoverage_Report_Node_Directory $root, array $items, array $tests, $cacheTokens)
 
52
    {
 
53
        foreach ($items as $key => $value) {
 
54
            if (substr($key, -2) == '/f') {
 
55
                $key = substr($key, 0, -2);
 
56
 
 
57
                if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) {
 
58
                    $root->addFile($key, $value, $tests, $cacheTokens);
 
59
                }
 
60
            } else {
 
61
                $child = $root->addDirectory($key);
 
62
                $this->addItems($child, $value, $tests, $cacheTokens);
 
63
            }
 
64
        }
 
65
    }
 
66
 
 
67
    /**
 
68
     * Builds an array representation of the directory structure.
 
69
     *
 
70
     * For instance,
 
71
     *
 
72
     * <code>
 
73
     * Array
 
74
     * (
 
75
     *     [Money.php] => Array
 
76
     *         (
 
77
     *             ...
 
78
     *         )
 
79
     *
 
80
     *     [MoneyBag.php] => Array
 
81
     *         (
 
82
     *             ...
 
83
     *         )
 
84
     * )
 
85
     * </code>
 
86
     *
 
87
     * is transformed into
 
88
     *
 
89
     * <code>
 
90
     * Array
 
91
     * (
 
92
     *     [.] => Array
 
93
     *         (
 
94
     *             [Money.php] => Array
 
95
     *                 (
 
96
     *                     ...
 
97
     *                 )
 
98
     *
 
99
     *             [MoneyBag.php] => Array
 
100
     *                 (
 
101
     *                     ...
 
102
     *                 )
 
103
     *         )
 
104
     * )
 
105
     * </code>
 
106
     *
 
107
     * @param  array $files
 
108
     * @return array
 
109
     */
 
110
    private function buildDirectoryStructure($files)
 
111
    {
 
112
        $result = array();
 
113
 
 
114
        foreach ($files as $path => $file) {
 
115
            $path    = explode('/', $path);
 
116
            $pointer = &$result;
 
117
            $max     = count($path);
 
118
 
 
119
            for ($i = 0; $i < $max; $i++) {
 
120
                if ($i == ($max - 1)) {
 
121
                    $type = '/f';
 
122
                } else {
 
123
                    $type = '';
 
124
                }
 
125
 
 
126
                $pointer = &$pointer[$path[$i] . $type];
 
127
            }
 
128
 
 
129
            $pointer = $file;
 
130
        }
 
131
 
 
132
        return $result;
 
133
    }
 
134
 
 
135
    /**
 
136
     * Reduces the paths by cutting the longest common start path.
 
137
     *
 
138
     * For instance,
 
139
     *
 
140
     * <code>
 
141
     * Array
 
142
     * (
 
143
     *     [/home/sb/Money/Money.php] => Array
 
144
     *         (
 
145
     *             ...
 
146
     *         )
 
147
     *
 
148
     *     [/home/sb/Money/MoneyBag.php] => Array
 
149
     *         (
 
150
     *             ...
 
151
     *         )
 
152
     * )
 
153
     * </code>
 
154
     *
 
155
     * is reduced to
 
156
     *
 
157
     * <code>
 
158
     * Array
 
159
     * (
 
160
     *     [Money.php] => Array
 
161
     *         (
 
162
     *             ...
 
163
     *         )
 
164
     *
 
165
     *     [MoneyBag.php] => Array
 
166
     *         (
 
167
     *             ...
 
168
     *         )
 
169
     * )
 
170
     * </code>
 
171
     *
 
172
     * @param  array  $files
 
173
     * @return string
 
174
     */
 
175
    private function reducePaths(&$files)
 
176
    {
 
177
        if (empty($files)) {
 
178
            return '.';
 
179
        }
 
180
 
 
181
        $commonPath = '';
 
182
        $paths      = array_keys($files);
 
183
 
 
184
        if (count($files) == 1) {
 
185
            $commonPath                 = dirname($paths[0]) . '/';
 
186
            $files[basename($paths[0])] = $files[$paths[0]];
 
187
 
 
188
            unset($files[$paths[0]]);
 
189
 
 
190
            return $commonPath;
 
191
        }
 
192
 
 
193
        $max = count($paths);
 
194
 
 
195
        for ($i = 0; $i < $max; $i++) {
 
196
            // strip phar:// prefixes
 
197
            if (strpos($paths[$i], 'phar://') === 0) {
 
198
                $paths[$i] = substr($paths[$i], 7);
 
199
                $paths[$i] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
 
200
            }
 
201
            $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
 
202
 
 
203
            if (empty($paths[$i][0])) {
 
204
                $paths[$i][0] = DIRECTORY_SEPARATOR;
 
205
            }
 
206
        }
 
207
 
 
208
        $done = false;
 
209
        $max  = count($paths);
 
210
 
 
211
        while (!$done) {
 
212
            for ($i = 0; $i < $max - 1; $i++) {
 
213
                if (!isset($paths[$i][0]) ||
 
214
                    !isset($paths[$i+1][0]) ||
 
215
                    $paths[$i][0] != $paths[$i+1][0]) {
 
216
                    $done = true;
 
217
                    break;
 
218
                }
 
219
            }
 
220
 
 
221
            if (!$done) {
 
222
                $commonPath .= $paths[0][0];
 
223
 
 
224
                if ($paths[0][0] != DIRECTORY_SEPARATOR) {
 
225
                    $commonPath .= DIRECTORY_SEPARATOR;
 
226
                }
 
227
 
 
228
                for ($i = 0; $i < $max; $i++) {
 
229
                    array_shift($paths[$i]);
 
230
                }
 
231
            }
 
232
        }
 
233
 
 
234
        $original = array_keys($files);
 
235
        $max      = count($original);
 
236
 
 
237
        for ($i = 0; $i < $max; $i++) {
 
238
            $files[join('/', $paths[$i])] = $files[$original[$i]];
 
239
            unset($files[$original[$i]]);
 
240
        }
 
241
 
 
242
        ksort($files);
 
243
 
 
244
        return substr($commonPath, 0, -1);
 
245
    }
 
246
}