SHINDIG-1056 by lipeng, BasicRemoteContentTest doesn't depend on static private key...
[shindig.git] / php / external / PHPUnit / Util / Metrics / Class.php
blob0166bbb2e86562448a8f2cdc378137ca55a4d293
1 <?php
2 /**
3 * PHPUnit
5 * Copyright (c) 2002-2008, Sebastian Bergmann <sb@sebastian-bergmann.de>.
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
20 * * Neither the name of Sebastian Bergmann nor the names of his
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
37 * @category Testing
38 * @package PHPUnit
39 * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
40 * @copyright 2002-2008 Sebastian Bergmann <sb@sebastian-bergmann.de>
41 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
42 * @version SVN: $Id: Class.php 1985 2007-12-26 18:11:55Z sb $
43 * @link http://www.phpunit.de/
44 * @since File available since Release 3.2.0
47 require_once 'PHPUnit/Util/Class.php';
48 require_once 'PHPUnit/Util/Metrics.php';
49 require_once 'PHPUnit/Util/Filter.php';
51 PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
53 /**
54 * Class-Level Metrics.
56 * @category Testing
57 * @package PHPUnit
58 * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
59 * @copyright 2002-2008 Sebastian Bergmann <sb@sebastian-bergmann.de>
60 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
61 * @version Release: 3.2.9
62 * @link http://www.phpunit.de/
63 * @since Class available since Release 3.2.0
65 class PHPUnit_Util_Metrics_Class extends PHPUnit_Util_Metrics {
66 protected $aif = 0;
67 protected $ahf = 0;
68 protected $ca = 0;
69 protected $ce = 0;
70 protected $coverage = 0;
71 protected $dit = 0;
72 protected $i = 0;
73 protected $impl = 0;
74 protected $loc = 0;
75 protected $locExecutable = 0;
76 protected $locExecuted = 0;
77 protected $mif = 0;
78 protected $mhf = 0;
79 protected $noc = 0;
80 protected $pf = 0;
81 protected $vars = 0;
82 protected $varsNp = 0;
83 protected $varsI = 0;
84 protected $wmc = 0;
85 protected $wmcNp = 0;
86 protected $wmcI = 0;
88 protected $project;
89 protected $package = '';
90 protected $class;
91 protected $methods = array();
92 protected $inheritedMethods = array();
93 protected $dependencies = array();
94 protected $publicMethods = 0;
96 protected static $cache = array();
97 protected static $nocCache = array();
99 /**
100 * Constructor.
102 * @param ReflectionClass $class
103 * @param array $codeCoverage
104 * @access protected
106 protected function __construct(ReflectionClass $class, &$codeCoverage = array()) {
107 $this->class = $class;
109 $className = $class->getName();
111 $packageInformation = PHPUnit_Util_Class::getPackageInformation($className);
113 if (! empty($packageInformation['fullPackage'])) {
114 $this->package = $packageInformation['fullPackage'];
117 $this->setCoverage($codeCoverage);
119 $this->dit = count(PHPUnit_Util_Class::getHierarchy($class->getName())) - 1;
120 $this->impl = count($class->getInterfaces());
122 foreach ($this->class->getMethods() as $method) {
123 if ($method->getDeclaringClass()->getName() == $className) {
124 $this->methods[$method->getName()] = PHPUnit_Util_Metrics_Function::factory($method, $codeCoverage);
125 } else {
126 $this->inheritedMethods[$method->getName()] = PHPUnit_Util_Metrics_Function::factory($method, $codeCoverage);
130 $this->calculateAttributeMetrics();
131 $this->calculateMethodMetrics();
132 $this->calculateNumberOfChildren();
133 $this->calculatePolymorphismFactor();
134 $this->calculateDependencies();
138 * Factory.
140 * @param ReflectionClass $class
141 * @param array $codeCoverage
142 * @return PHPUnit_Util_Metrics_Class
143 * @access public
144 * @static
146 public static function factory(ReflectionClass $class, &$codeCoverage = array()) {
147 $className = $class->getName();
149 if (! isset(self::$cache[$className])) {
150 self::$cache[$className] = new PHPUnit_Util_Metrics_Class($class, $codeCoverage);
153 else if (! empty($codeCoverage) && self::$cache[$className]->getCoverage() == 0) {
154 self::$cache[$className]->setCoverage($codeCoverage);
157 return self::$cache[$className];
161 * @param array $codeCoverage
162 * @access public
164 public function setCoverage(array &$codeCoverage) {
165 if (! empty($codeCoverage)) {
166 $this->calculateCodeCoverage($codeCoverage);
168 foreach ($this->methods as $method) {
169 $method->setCoverage($codeCoverage);
175 * @param PHPUnit_Util_Metrics_Project $project
176 * @access public
178 public function setProject(PHPUnit_Util_Metrics_Project $project) {
179 $this->project = $project;
181 $this->ca = 0;
182 $this->ce = 0;
183 $this->i = 0;
187 * Returns the class.
189 * @return ReflectionClass
190 * @access public
192 public function getClass() {
193 return $this->class;
197 * Returns the package of this class.
199 * @return string
200 * @access public
202 public function getPackage() {
203 return $this->package;
207 * Returns the methods of this class.
209 * @return array
210 * @access public
212 public function getMethods() {
213 return $this->methods;
217 * Returns the names of the classes this class depends on.
219 * @return array
220 * @access public
222 public function getDependencies() {
223 return $this->dependencies;
227 * Lines of Code (LOC).
229 * @return int
230 * @access public
232 public function getLoc() {
233 return $this->loc;
237 * Executable Lines of Code (ELOC).
239 * @return int
240 * @access public
242 public function getLocExecutable() {
243 return $this->locExecutable;
247 * Executed Lines of Code.
249 * @return int
250 * @access public
252 public function getLocExecuted() {
253 return $this->locExecuted;
257 * Returns the Number of Public Methods of the class.
259 * @return integer
260 * @access public
262 public function getPublicMethods() {
263 return $this->publicMethods;
267 * Returns the Attribute Inheritance Factor (AIF) for the class.
269 * @return integer
270 * @access public
271 * @see http://www.aivosto.com/project/help/pm-oo-mood.html
273 public function getAIF() {
274 return $this->aif;
278 * Returns the Attribute Hiding Factor (AHF) for the class.
280 * @return integer
281 * @access public
282 * @see http://www.aivosto.com/project/help/pm-oo-mood.html
284 public function getAHF() {
285 return $this->ahf;
289 * Returns the Afferent Couplings (Ca) for the class.
291 * The number of other classes that depend upon a class is an indicator of
292 * the class' responsibility.
294 * @return integer
295 * @access public
297 public function getCa() {
298 $this->calculateDependencyMetrics();
300 return $this->ca;
304 * Returns the Efferent Couplings (Ce) for the class.
306 * The number of other classes that the class depends upon is an indicator
307 * of the class' independence.
309 * @return integer
310 * @access public
312 public function getCe() {
313 $this->calculateDependencyMetrics();
315 return $this->ce;
319 * Returns the Class Size (CSZ) of the class.
321 * @return integer
322 * @access public
323 * @see http://www.aivosto.com/project/help/pm-oo-misc.html
325 public function getCSZ() {
326 return count($this->methods) + $this->vars;
330 * Returns the Class Interface Size (CIS) of the class.
332 * @return integer
333 * @access public
334 * @see http://www.aivosto.com/project/help/pm-oo-misc.html
336 public function getCIS() {
337 return $this->publicMethods + $this->varsNp;
341 * Returns the Code Coverage for the class.
343 * @return float
344 * @access public
346 public function getCoverage() {
347 return $this->coverage;
351 * Returns the Depth of Inheritance Tree (DIT) for the class.
353 * @return integer
354 * @access public
355 * @see http://www.aivosto.com/project/help/pm-oo-ck.html
357 public function getDIT() {
358 return $this->dit;
362 * Returns the Instability (I) for the class.
364 * The ratio of efferent coupling (Ce) to total coupling (Ce + Ca) such that
365 * I = Ce / (Ce + Ca). This metric is an indicator of the class' resilience
366 * to change.
368 * The range for this metric is 0 to 1, with I=0 indicating a completely
369 * stable class and I=1 indicating a completely instable class.
371 * @return float
372 * @access public
374 public function getI() {
375 $this->calculateDependencyMetrics();
377 return $this->i;
381 * Returns the Number of Interfaces Implemented by the class (IMPL).
383 * @return integer
384 * @access public
385 * @see http://www.aivosto.com/project/help/pm-oo-misc.html
387 public function getIMPL() {
388 return $this->impl;
392 * Returns the Method Inheritance Factor (MIF) for the class.
394 * @return float
395 * @access public
396 * @see http://www.aivosto.com/project/help/pm-oo-mood.html
398 public function getMIF() {
399 return $this->mif;
403 * Returns the Method Hiding Factor (MHF) for the class.
405 * @return float
406 * @access public
407 * @see http://www.aivosto.com/project/help/pm-oo-mood.html
409 public function getMHF() {
410 return $this->mhf;
414 * Returns the Number of Children (NOC) for the class.
416 * @return integer
417 * @access public
418 * @see http://www.aivosto.com/project/help/pm-oo-ck.html
420 public function getNOC() {
421 return $this->noc;
425 * Returns the Polymorphism Factor (PF) for the class.
427 * @return float
428 * @access public
429 * @see http://www.aivosto.com/project/help/pm-oo-mood.html
431 public function getPF() {
432 return $this->pf;
436 * Returns the Number of Variables (VARS) defined by the class.
438 * @return integer
439 * @access public
440 * @see http://www.aivosto.com/project/help/pm-oo-misc.html
442 public function getVARS() {
443 return $this->vars;
447 * Returns the Number of Non-Private Variables (VARSnp) defined by the class.
449 * @return integer
450 * @access public
451 * @see http://www.aivosto.com/project/help/pm-oo-misc.html
453 public function getVARSnp() {
454 return $this->varsNp;
458 * Returns the Number of Variables (VARSi) defined and inherited by the class.
460 * @return integer
461 * @access public
462 * @see http://www.aivosto.com/project/help/pm-oo-misc.html
464 public function getVARSi() {
465 return $this->varsI;
469 * Returns the Weighted Methods Per Class (WMC) for the class.
471 * @return integer
472 * @access public
473 * @see http://www.aivosto.com/project/help/pm-oo-ck.html
475 public function getWMC() {
476 return $this->wmc;
480 * Returns the Weighted Non-Private Methods Per Class (WMCnp) for the class.
482 * @return integer
483 * @access public
484 * @see http://www.aivosto.com/project/help/pm-oo-misc.html
486 public function getWMCnp() {
487 return $this->wmcNp;
491 * Returns the Weighted Inherited Methods Per Class (WMCi) for the class.
493 * @return integer
494 * @access public
495 * @see http://www.aivosto.com/project/help/pm-oo-misc.html
497 public function getWMCi() {
498 return $this->wmcI;
502 * Calculates the Attribute Inheritance Factor (AIF) and
503 * Attribute Hiding Factor (AHF) metrics for the class.
505 * @access protected
507 protected function calculateAttributeMetrics() {
508 $attributes = 0;
509 $hiddenAttributes = 0;
510 $inheritedAttributes = 0;
512 foreach ($this->class->getProperties() as $attribute) {
513 if ($attribute->isPublic()) {
514 $this->varsNp ++;
515 } else {
516 $hiddenAttributes ++;
519 if ($attribute->getDeclaringClass()->getName() == $this->class->getName()) {
520 $this->vars ++;
521 } else {
522 $inheritedAttributes ++;
525 $this->varsI ++;
526 $attributes ++;
529 if ($attributes > 0) {
530 $this->aif = (100 * $inheritedAttributes) / $attributes;
531 $this->ahf = (100 * $hiddenAttributes) / $attributes;
536 * Calculates the Method Inheritance Factor (MIF)
537 * Method Hiding Factor (MHF), Weighted Methods Per Class (WMC),
538 * Weighted Non-Private Methods Per Class (WMCnp), and
539 * Weighted Inherited Methods Per Class (WMCi) metrics for the class.
541 * @access protected
543 protected function calculateMethodMetrics() {
544 $numMethods = 0;
545 $hiddenMethods = 0;
546 $inheritedMethods = 0;
548 $methods = array_merge($this->methods, $this->inheritedMethods);
550 foreach ($methods as $method) {
551 $ccn = $method->getCCN();
553 if ($method->getMethod()->getDeclaringClass()->getName() == $this->class->getName()) {
554 $this->wmc += $ccn;
556 if ($method->getMethod()->isPublic()) {
557 $this->publicMethods ++;
558 $this->wmcNp += $ccn;
560 } else {
561 $inheritedMethods ++;
564 if (! $method->getMethod()->isPublic()) {
565 $hiddenMethods ++;
568 $this->wmcI += $ccn;
569 $numMethods ++;
572 if ($numMethods > 0) {
573 $this->mif = (100 * $inheritedMethods) / $numMethods;
574 $this->mhf = (100 * $hiddenMethods) / $numMethods;
579 * Calculates the Number of Children (NOC) metric for the class.
581 * @access protected
583 protected function calculateNumberOfChildren() {
584 $className = $this->class->getName();
586 if (! isset(self::$nocCache[$className])) {
587 self::$nocCache = array();
590 if (empty(self::$nocCache)) {
591 foreach (get_declared_classes() as $_className) {
592 $class = new ReflectionClass($_className);
593 $parent = $class->getParentClass();
595 if ($parent !== FALSE) {
596 $parentName = $parent->getName();
598 if (isset(self::$nocCache[$parentName])) {
599 self::$nocCache[$parentName] ++;
600 } else {
601 self::$nocCache[$parentName] = 1;
607 if (isset(self::$nocCache[$className])) {
608 $this->noc = self::$nocCache[$className];
613 * Calculates the Polymorphism Factor (PF) metric for the class.
615 * @param ReflectionClass $class
616 * @access protected
618 protected function calculatePolymorphismFactor() {
619 $parentClass = $this->class->getParentClass();
621 if ($parentClass !== FALSE) {
622 $overridableMethods = array();
624 foreach ($parentClass->getMethods() as $method) {
625 if (! $method->isPrivate() && ! $method->isFinal() && ! $method->isAbstract()) {
626 $overridableMethods[] = $method->getName();
630 if (! empty($overridableMethods)) {
631 $overriddenMethods = 0;
633 foreach ($this->class->getMethods() as $method) {
634 if ($method->getDeclaringClass()->getName() == $this->class->getName()) {
635 $methodName = $method->getName();
637 if (in_array($methodName, $overridableMethods)) {
638 $overriddenMethods ++;
643 $this->pf = (100 * $overriddenMethods) / count($overridableMethods);
649 * Calculates the Code Coverage for the class.
651 * @param array $codeCoverage
652 * @access protected
654 protected function calculateCodeCoverage(&$codeCoverage) {
655 $statistics = PHPUnit_Util_CodeCoverage::getStatistics($codeCoverage, $this->class->getFileName(), $this->class->getStartLine(), $this->class->getEndLine());
657 $this->coverage = $statistics['coverage'];
658 $this->loc = $statistics['loc'];
659 $this->locExecutable = $statistics['locExecutable'];
660 $this->locExecuted = $statistics['locExecuted'];
664 * Calculates the dependencies for this class.
666 * @access protected
668 protected function calculateDependencies() {
669 $parent = $this->class->getParentClass();
671 if ($parent && $parent->isUserDefined() && ! in_array($parent->getName(), $this->dependencies)) {
672 $this->dependencies[] = $parent->getName();
675 $interfaces = $this->class->getInterfaces();
677 foreach ($interfaces as $interface) {
678 if ($interface->isUserDefined() && ! in_array($interface->getName(), $this->dependencies)) {
679 $this->dependencies[] = $interface->getName();
683 $methods = array_merge($this->methods, $this->inheritedMethods);
685 foreach ($methods as $method) {
686 foreach ($method->getDependencies() as $dependency) {
687 if (! in_array($dependency, $this->dependencies)) {
688 $this->dependencies[] = $dependency;
695 * Calculates the dependency-based metrics for this class.
697 * @access protected
699 protected function calculateDependencyMetrics() {
700 if ($this->ca == 0 && $this->ce == 0 && $this->i == 0) {
701 $className = $this->class->getName();
702 $dependencies = $this->project->getDependencies();
704 foreach ($dependencies[$className] as $dependency) {
705 if ($dependency > 0) {
706 $this->ce ++;
710 unset($dependencies[$className]);
712 foreach ($dependencies as $_className => $_dependencies) {
713 if ($_dependencies[$className] > 0) {
714 $this->ca ++;
718 $sum = $this->ce + $this->ca;
720 if ($sum > 0) {
721 $this->i = $this->ce / $sum;