Skip to content

Commit 779728d

Browse files
authored
Merge pull request #362 from UFOMelkor/hotfix/remain-ccn
Retain the old ccn and add wmc as new metric
2 parents 6e3ebca + c997a20 commit 779728d

File tree

7 files changed

+59
-12
lines changed

7 files changed

+59
-12
lines changed

src/Hal/Metric/Class_/Complexity/CyclomaticComplexityVisitor.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public function leaveNode(Node $node)
5757
) {
5858
$class = $this->metrics->get(MetricClassNameGenerator::getName($node));
5959

60-
$ccn = 0;
60+
$ccn = 1;
61+
$wmc = 0;
6162
$ccnByMethod = [0]; // default maxMethodCcn if no methods are available
6263

6364
foreach ($node->stmts as $stmt) {
@@ -106,11 +107,13 @@ public function leaveNode(Node $node)
106107

107108
$methodCcn = $cb($stmt) + 1; // each method by default is CCN 1 even if it's empty
108109

109-
$ccn += $methodCcn;
110+
$wmc += $methodCcn;
111+
$ccn += $methodCcn - 1;
110112
$ccnByMethod[] = $methodCcn;
111113
}
112114
}
113115

116+
$class->set('wmc', $wmc);
114117
$class->set('ccn', $ccn);
115118
$class->set('ccnMethodMax', max($ccnByMethod));
116119
}

src/Hal/Metric/Consolidated.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public function __construct(Metrics $metrics)
7474
'nbMethods' => 0,
7575
];
7676
$avg = (object)[
77+
'wmc' => [],
7778
'ccn' => [],
7879
'bugs' => [],
7980
'kanDefect' => [],

src/Hal/Report/Cli/Reporter.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public function generate(Metrics $metrics)
8787
8888
Complexity
8989
Average Cyclomatic complexity by class {$avg->ccn}
90+
Average Weighted method count by class {$avg->wmc}
9091
Average Relative system complexity {$avg->relativeSystemComplexity}
9192
Average Difficulty {$avg->difficulty}
9293

src/Hal/Report/Html/template/complexity.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
require __DIR__ . '/_header.php'; ?>
33

44
<div class="row">
5+
<div class="column">
6+
<div class="bloc bloc-number">
7+
<div class="label">Average weighted method count by class <small>(CC)</small></div>
8+
<div class="number">
9+
<?php echo $avg->wmc; ?>
10+
</div>
11+
<?php echo $this->getTrend('avg', 'wmc', true); ?>
12+
</div>
13+
</div>
514
<div class="column">
615
<div class="bloc bloc-number">
716
<div class="label">Average cyclomatic complexity by class</div>
@@ -22,34 +31,32 @@
2231
</div>
2332
<div class="column">
2433
<div class="bloc bloc-number">
25-
<div class="label">Average bugs by class
26-
<small>(Halstead)</small> <?php echo $this->getTrend('avg', 'bugs', true); ?>
27-
</div>
34+
<div class="label">Average bugs by class<small>(Halstead)</small></div>
2835
<div class="number">
2936
<?php echo $avg->bugs; ?>
3037
</div>
38+
<?php echo $this->getTrend('avg', 'bugs', true); ?>
3139
</div>
3240
</div>
3341
<div class="column">
3442
<div class="bloc bloc-number">
35-
<div class="label">average defects by class
36-
<small>(Kan)</small> <?php echo $this->getTrend('avg', 'kanDefect', true); ?>
37-
</div>
43+
<div class="label">average defects by class <small>(Kan)</small></div>
3844
<div class="number">
3945
<?php echo $avg->kanDefect; ?>
4046
</div>
47+
<?php echo $this->getTrend('avg', 'kanDefect', true); ?>
4148
</div>
4249
</div>
4350
</div>
4451

45-
4652
<div class="row">
4753
<div class="column">
4854
<div class="bloc">
4955
<table class="js-sort-table" id="table-length">
5056
<thead>
5157
<tr>
5258
<th>Class</th>
59+
<th class="js-sort-number">WMC</th>
5360
<th class="js-sort-number">Class cycl.</th>
5461
<th class="js-sort-number">Max method cycl.</th>
5562
<?php if ($config->has('junit')) { ?>
@@ -65,6 +72,7 @@
6572
foreach ($classes as $class) { ?>
6673
<tr>
6774
<td><?php echo $class['name']; ?></td>
75+
<td><?php echo isset($class['wmc']) ? $class['wmc'] : ''; ?></td>
6876
<td><?php echo isset($class['ccn']) ? $class['ccn'] : ''; ?></td>
6977
<td><?php echo isset($class['ccnMethodMax']) ? $class['ccnMethodMax'] : ''; ?></td>
7078
<?php if ($config->has('junit')) { ?>

src/Hal/Report/Html/template/index.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
<div class="column">
1212
<div class="bloc bloc-number">
1313
<div class="label"><a href="loc.html">Lines of code</a></div>
14-
<?php echo $this->getTrend('sum', 'loc'); ?>
1514
<div class="number"><?php echo $sum->loc; ?></div>
15+
<?php echo $this->getTrend('sum', 'loc'); ?>
1616
</div>
1717
</div>
1818
<div class="column">

src/Hal/Violation/Class_/TooComplexClassCode.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function apply(Metric $metric)
2929

3030
$this->metric = $metric;
3131

32-
if ($metric->get('ccn') > 50) {
32+
if ($metric->get('wmc') > 50) {
3333
$metric->get('violations')->add($this);
3434
}
3535
}

tests/Metric/Class_/Complexity/CyclomaticComplexityVisitorTest.php

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,26 @@
1010

1111
class CyclomaticComplexityVisitorTest extends \PHPUnit_Framework_TestCase
1212
{
13+
/**
14+
* @dataProvider provideExamplesForCcn
15+
*/
16+
public function testCcnOfClassesIsWellCalculated($example, $classname, $expectedCcn)
17+
{
18+
$metrics = new Metrics();
19+
20+
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
21+
$traverser = new NodeTraverser();
22+
$traverser->addVisitor(new NameResolver());
23+
$traverser->addVisitor(new ClassEnumVisitor($metrics));
24+
$traverser->addVisitor(new CyclomaticComplexityVisitor($metrics));
25+
26+
$code = file_get_contents($example);
27+
$stmts = $parser->parse($code);
28+
$traverser->traverse($stmts);
29+
30+
$this->assertSame($expectedCcn, $metrics->get($classname)->get('ccn'));
31+
}
32+
1333
/**
1434
* @dataProvider provideExamplesForWmc
1535
*/
@@ -27,7 +47,7 @@ public function testWeightedMethodCountOfClassesIsWellCalculated($example, $clas
2747
$stmts = $parser->parse($code);
2848
$traverser->traverse($stmts);
2949

30-
$this->assertSame($expectedWmc, $metrics->get($classname)->get('ccn'));
50+
$this->assertSame($expectedWmc, $metrics->get($classname)->get('wmc'));
3151
}
3252

3353
/**
@@ -64,6 +84,20 @@ public static function provideExamplesForWmc()
6484
];
6585
}
6686

87+
public static function provideExamplesForCcn()
88+
{
89+
return [
90+
'A' => [__DIR__ . '/../../examples/cyclomatic1.php', 'A', 8],
91+
'B' => [__DIR__ . '/../../examples/cyclomatic1.php', 'B', 4],
92+
'Foo\\C' => [__DIR__ . '/../../examples/cyclomatic_anon.php', 'Foo\\C', 1],
93+
'SwitchCase' => [__DIR__ . '/../../examples/cyclomatic_full.php', 'SwitchCase', 4],
94+
'IfElseif' => [__DIR__ . '/../../examples/cyclomatic_full.php', 'IfElseif', 7],
95+
'Loops' => [__DIR__ . '/../../examples/cyclomatic_full.php', 'Loops', 5],
96+
'CatchIt' => [__DIR__ . '/../../examples/cyclomatic_full.php', 'CatchIt', 3],
97+
'Logical' => [__DIR__ . '/../../examples/cyclomatic_full.php', 'Logical', 11],
98+
];
99+
}
100+
67101
public static function provideExamplesForMaxCc()
68102
{
69103
return [

0 commit comments

Comments
 (0)