1<?php
2/*
3 * This file is part of the php-code-coverage 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
11namespace SebastianBergmann\CodeCoverage\Node;
12
13use SebastianBergmann\CodeCoverage\Util;
14
15/**
16 * Base class for nodes in the code coverage information tree.
17 */
18abstract class AbstractNode implements \Countable
19{
20    /**
21     * @var string
22     */
23    private $name;
24
25    /**
26     * @var string
27     */
28    private $path;
29
30    /**
31     * @var array
32     */
33    private $pathArray;
34
35    /**
36     * @var AbstractNode
37     */
38    private $parent;
39
40    /**
41     * @var string
42     */
43    private $id;
44
45    /**
46     * Constructor.
47     *
48     * @param string       $name
49     * @param AbstractNode $parent
50     */
51    public function __construct($name, AbstractNode $parent = null)
52    {
53        if (substr($name, -1) == '/') {
54            $name = substr($name, 0, -1);
55        }
56
57        $this->name   = $name;
58        $this->parent = $parent;
59    }
60
61    /**
62     * @return string
63     */
64    public function getName()
65    {
66        return $this->name;
67    }
68
69    /**
70     * @return string
71     */
72    public function getId()
73    {
74        if ($this->id === null) {
75            $parent = $this->getParent();
76
77            if ($parent === null) {
78                $this->id = 'index';
79            } else {
80                $parentId = $parent->getId();
81
82                if ($parentId == 'index') {
83                    $this->id = str_replace(':', '_', $this->name);
84                } else {
85                    $this->id = $parentId . '/' . $this->name;
86                }
87            }
88        }
89
90        return $this->id;
91    }
92
93    /**
94     * @return string
95     */
96    public function getPath()
97    {
98        if ($this->path === null) {
99            if ($this->parent === null || $this->parent->getPath() === null || $this->parent->getPath() === false) {
100                $this->path = $this->name;
101            } else {
102                $this->path = $this->parent->getPath() . '/' . $this->name;
103            }
104        }
105
106        return $this->path;
107    }
108
109    /**
110     * @return array
111     */
112    public function getPathAsArray()
113    {
114        if ($this->pathArray === null) {
115            if ($this->parent === null) {
116                $this->pathArray = [];
117            } else {
118                $this->pathArray = $this->parent->getPathAsArray();
119            }
120
121            $this->pathArray[] = $this;
122        }
123
124        return $this->pathArray;
125    }
126
127    /**
128     * @return AbstractNode
129     */
130    public function getParent()
131    {
132        return $this->parent;
133    }
134
135    /**
136     * Returns the percentage of classes that has been tested.
137     *
138     * @param bool $asString
139     *
140     * @return int
141     */
142    public function getTestedClassesPercent($asString = true)
143    {
144        return Util::percent(
145            $this->getNumTestedClasses(),
146            $this->getNumClasses(),
147            $asString
148        );
149    }
150
151    /**
152     * Returns the percentage of traits that has been tested.
153     *
154     * @param bool $asString
155     *
156     * @return int
157     */
158    public function getTestedTraitsPercent($asString = true)
159    {
160        return Util::percent(
161            $this->getNumTestedTraits(),
162            $this->getNumTraits(),
163            $asString
164        );
165    }
166
167    /**
168     * Returns the percentage of traits that has been tested.
169     *
170     * @param bool $asString
171     *
172     * @return int
173     */
174    public function getTestedClassesAndTraitsPercent($asString = true)
175    {
176        return Util::percent(
177            $this->getNumTestedClassesAndTraits(),
178            $this->getNumClassesAndTraits(),
179            $asString
180        );
181    }
182
183    /**
184     * Returns the percentage of methods that has been tested.
185     *
186     * @param bool $asString
187     *
188     * @return int
189     */
190    public function getTestedMethodsPercent($asString = true)
191    {
192        return Util::percent(
193            $this->getNumTestedMethods(),
194            $this->getNumMethods(),
195            $asString
196        );
197    }
198
199    /**
200     * Returns the percentage of executed lines.
201     *
202     * @param bool $asString
203     *
204     * @return int
205     */
206    public function getLineExecutedPercent($asString = true)
207    {
208        return Util::percent(
209            $this->getNumExecutedLines(),
210            $this->getNumExecutableLines(),
211            $asString
212        );
213    }
214
215    /**
216     * Returns the number of classes and traits.
217     *
218     * @return int
219     */
220    public function getNumClassesAndTraits()
221    {
222        return $this->getNumClasses() + $this->getNumTraits();
223    }
224
225    /**
226     * Returns the number of tested classes and traits.
227     *
228     * @return int
229     */
230    public function getNumTestedClassesAndTraits()
231    {
232        return $this->getNumTestedClasses() + $this->getNumTestedTraits();
233    }
234
235    /**
236     * Returns the classes and traits of this node.
237     *
238     * @return array
239     */
240    public function getClassesAndTraits()
241    {
242        return array_merge($this->getClasses(), $this->getTraits());
243    }
244
245    /**
246     * Returns the classes of this node.
247     *
248     * @return array
249     */
250    abstract public function getClasses();
251
252    /**
253     * Returns the traits of this node.
254     *
255     * @return array
256     */
257    abstract public function getTraits();
258
259    /**
260     * Returns the functions of this node.
261     *
262     * @return array
263     */
264    abstract public function getFunctions();
265
266    /**
267     * Returns the LOC/CLOC/NCLOC of this node.
268     *
269     * @return array
270     */
271    abstract public function getLinesOfCode();
272
273    /**
274     * Returns the number of executable lines.
275     *
276     * @return int
277     */
278    abstract public function getNumExecutableLines();
279
280    /**
281     * Returns the number of executed lines.
282     *
283     * @return int
284     */
285    abstract public function getNumExecutedLines();
286
287    /**
288     * Returns the number of classes.
289     *
290     * @return int
291     */
292    abstract public function getNumClasses();
293
294    /**
295     * Returns the number of tested classes.
296     *
297     * @return int
298     */
299    abstract public function getNumTestedClasses();
300
301    /**
302     * Returns the number of traits.
303     *
304     * @return int
305     */
306    abstract public function getNumTraits();
307
308    /**
309     * Returns the number of tested traits.
310     *
311     * @return int
312     */
313    abstract public function getNumTestedTraits();
314
315    /**
316     * Returns the number of methods.
317     *
318     * @return int
319     */
320    abstract public function getNumMethods();
321
322    /**
323     * Returns the number of tested methods.
324     *
325     * @return int
326     */
327    abstract public function getNumTestedMethods();
328
329    /**
330     * Returns the number of functions.
331     *
332     * @return int
333     */
334    abstract public function getNumFunctions();
335
336    /**
337     * Returns the number of tested functions.
338     *
339     * @return int
340     */
341    abstract public function getNumTestedFunctions();
342}
343