ErrorCoverage::mapIssues()   B
last analyzed

Complexity

Conditions 6
Paths 4

Size

Total Lines 48
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 27
nc 4
nop 2
dl 0
loc 48
rs 8.8657
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Coverage
5
 *
6
 * PHP Version 5.3.2
7
 *
8
 * Copyright (c) 2007-2010, Mayflower GmbH
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 *
15
 *   * Redistributions of source code must retain the above copyright
16
 *     notice, this list of conditions and the following disclaimer.
17
 *
18
 *   * Redistributions in binary form must reproduce the above copyright
19
 *     notice, this list of conditions and the following disclaimer in
20
 *     the documentation and/or other materials provided with the
21
 *     distribution.
22
 *
23
 *   * Neither the name of Mayflower GmbH nor the names of his
24
 *     contributors may be used to endorse or promote products derived
25
 *     from this software without specific prior written permission.
26
 *
27
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
 * POSSIBILITY OF SUCH DAMAGE.
39
 *
40
 * @category PHP_CodeBrowser
41
 *
42
 * @author Elger Thiele <[email protected]>
43
 * @author Michel Hartmann <[email protected]>
44
 *
45
 * @copyright 2007-2010 Mayflower GmbH
46
 *
47
 * @license http://www.opensource.org/licenses/bsd-license.php  BSD License
48
 *
49
 * @version SVN: $Id$
50
 *
51
 * @link http://www.phpunit.de/
52
 *
53
 * @since File available since  0.1.0
54
 */
55
56
namespace PHPCodeBrowser\Plugins;
57
58
use DOMElement;
59
use DOMNode;
60
use DOMNodeList;
61
use PHPCodeBrowser\AbstractPlugin;
62
use PHPCodeBrowser\Issue;
63
64
/**
65
 * ErrorCoverage
66
 *
67
 * @category PHP_CodeBrowser
68
 *
69
 * @author Elger Thiele <[email protected]>
70
 * @author Michel Hartmann <[email protected]>
71
 *
72
 * @copyright 2007-2010 Mayflower GmbH
73
 *
74
 * @license http://www.opensource.org/licenses/bsd-license.php  BSD License
75
 *
76
 * @version Release: @package_version@
77
 *
78
 * @link http://www.phpunit.de/
79
 *
80
 * @since Class available since  0.1.0
81
 */
82
class ErrorCoverage extends AbstractPlugin
83
{
84
    /**
85
     * Name of this plugin.
86
     * Used to read issues from XML.
87
     *
88
     * @var string
89
     */
90
    protected $pluginName = 'coverage';
91
92
    /**
93
     * Name of the attribute that holds the number of the first line
94
     * of the issue.
95
     *
96
     * @var string
97
     */
98
    protected $lineStartAttr = 'num';
99
100
    /**
101
     * Name of the attribute that holds the number of the last line
102
     * of the issue.
103
     *
104
     * @var string
105
     */
106
    protected $lineEndAttr = 'num';
107
108
    /**
109
     * Default string to use as source for issue.
110
     *
111
     * @var string
112
     */
113
    protected $source = 'Coverage';
114
115
    /**
116
     * The detailed mapper method for each single plugin, returning an array
117
     * of Issue objects.
118
     * This method provides a default behaviour an can be overloaded to
119
     * implement special behavior for other plugins.
120
     *
121
     * @param DOMNode $element  The XML plugin node with its errors
122
     * @param string  $filename Name of the file to return issues for.
123
     *
124
     * @return array<Issue>
125
     */
126
    public function mapIssues(DOMNode $element, string $filename): array
127
    {
128
        $errorList = [];
129
130
        $children   = $element->childNodes;
131
        $childCount = $children->length;
132
133
        for ($next = 0; $next < $childCount; ++$next) {
134
            /** @var DOMElement $child */
135
            $child = $children->item($next);
136
137
            if (!$this->representsUncoveredLOC($child)) {
138
                continue;
139
            }
140
141
            $begin = (int) $child->getAttribute('num');
142
            $end   = $begin;
143
144
            ++$next;
145
146
            while ($next < $childCount) {
147
                $child = $children->item($next);
148
149
                if (!$child instanceof DOMElement) {
150
                    ++$next;
151
152
                    continue;
153
                }
154
155
                if (!$this->representsUncoveredLOC($child)) {
156
                    break;
157
                }
158
159
                $end = (int) $child->getAttribute('num');
160
                ++$next;
161
            }
162
163
            $errorList[] = new Issue(
164
                $filename,
165
                $begin,
166
                $end,
167
                'Coverage',
168
                'Not covered',
169
                'Notice'
170
            );
171
        }
172
173
        return $errorList;
174
    }
175
176
    /**
177
     * Get an array with all files that have issues.
178
     *
179
     * @return array
180
     */
181
    public function getFilesWithIssues(): array
182
    {
183
        $fileNames  = [];
184
        $issueNodes = $this->issueXml->query(
185
            '/*/'.$this->pluginName.'/*//file[@name]'
186
        );
187
188
        foreach ($issueNodes as $node) {
189
            if (!($node instanceof DOMElement)) {
190
                continue;
191
            }
192
193
            $fileNames[] = $node->getAttribute('name');
194
        }
195
196
        return \array_unique($fileNames);
197
    }
198
199
    /**
200
     * Get all DOMNodes that represent issues for a specific file.
201
     *
202
     * @param string $filename Name of the file to get nodes for.
203
     *
204
     * @return DOMNodeList
205
     */
206
    protected function getIssueNodes(string $filename): DOMNodeList
207
    {
208
        return $this->issueXml->query(
209
            '/*/'.$this->pluginName.'/*//file[@name="'.$filename.'"]'
210
        );
211
    }
212
213
    /**
214
     * Check if the given object is a DOMElement representing an
215
     * uncovered line of code.
216
     *
217
     * @param DOMNode $elem
218
     *
219
     * @return bool
220
     */
221
    private function representsUncoveredLOC(DOMNode $elem): bool
222
    {
223
        return ($elem instanceof DOMElement &&
224
            0 === (int) $elem->getAttribute('count')
225
            && 'line' === $elem->nodeName
226
            && 'stmt' === $elem->getAttribute('type'));
227
    }
228
}
229