Added tests for Cyclo

This commit is contained in:
oowekyala
2017-07-16 16:33:21 +02:00
parent 1c1e97e7e4
commit 2a53d2e532
6 changed files with 66 additions and 39 deletions

View File

@ -25,23 +25,20 @@ import net.sourceforge.pmd.lang.java.oom.metrics.visitors.StandardCycloVisitor;
* <p>The standard version of the metric complies with McCabe's original definition:
*
* <ul>
* <li>+1 for every control flow statement ({@code if, case, catch, finally, do, while, for, break, continue}) and
* conditional expression ({@code ? : }). Notice switch cases count as one, but not the switch itself: the point is
* that a switch should have the same complexity value as the equivalent series of {@code if} statements.
* <li>{@code else} and {@code default} don't count;
* <li>+1 for every boolean operator in the guard condition of a control flow statement. That's because Java has
* short-circuit evaluation semantics for boolean operators, which makes every boolean operator kind of a control flow
* statement in itself.
* <li>+1 for every control flow statement ({@code if, case, catch, throw, do, while, for, break, continue}) and
* conditional expression ({@code ? : }). Notice switch cases count as one, but not the switch itself: the point is that
* a switch should have the same complexity value as the equivalent series of {@code if} statements.
* <li>{@code else}, {@code finally} and {@code default} don't count;
* <li>+1 for every boolean operator ({@code &&, ||}) in the guard condition of a control flow statement. That's because
* Java has short-circuit evaluation semantics for boolean operators, which makes every boolean operator kind of a
* control flow statement in itself.
* </ul>
*
* <p>Version {@link Version#IGNORE_BOOLEAN_PATHS}: Boolean operators are not counted, which means that empty
* fall-through cases in {@code switch} statements are not counted as well.
*
* <p>References:
* <ul>
* <li> [1] Lanza, Object-Oriented Metrics in Practice, 2005.
* <li> [2] McCabe, A Complexity Measure, in Proceedings of the 2nd ICSE (1976).
* </ul>
* <p>References: <ul> <li> [1] Lanza, Object-Oriented Metrics in Practice, 2005. <li> [2] McCabe, A Complexity Measure,
* in Proceedings of the 2nd ICSE (1976). </ul>
*
* @author Clément Fournier
* @since June 2017

View File

@ -12,7 +12,7 @@ import net.sourceforge.pmd.lang.java.oom.api.ResultOption;
/**
* Weighed Method Count. It is the sum of the statical complexity of all operations of a class. We use
* {@link CycloMetric} to quantify the complexity of a metric. [1]
* the standard version of {@link CycloMetric} to quantify the complexity of a metric. [1]
*
* <p>[1] Lanza. Object-Oriented Metrics in Practice.
*

View File

@ -15,6 +15,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTForStatement;
import net.sourceforge.pmd.lang.java.ast.ASTIfStatement;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement;
import net.sourceforge.pmd.lang.java.ast.ASTThrowStatement;
import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter;
@ -75,14 +76,6 @@ public class CycloPathUnawareOperationVisitor extends JavaParserVisitorAdapter {
}
@Override
public Object visit(ASTCatchStatement node, Object data) {
((MutableInt) data).increment();
super.visit(node, data);
return data;
}
@Override
public Object visit(ASTForStatement node, Object data) {
((MutableInt) data).increment();
@ -97,4 +90,21 @@ public class CycloPathUnawareOperationVisitor extends JavaParserVisitorAdapter {
super.visit(node, data);
return data;
}
@Override
public Object visit(ASTCatchStatement node, Object data) {
((MutableInt) data).increment();
super.visit(node, data);
return data;
}
@Override
public Object visit(ASTThrowStatement node, Object data) {
((MutableInt) data).increment();
super.visit(node, data);
return data;
}
}

View File

@ -44,19 +44,6 @@ import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter;
*/
public class DefaultNcssVisitor extends JavaParserVisitorAdapter {
@Override
public Object visit(ASTImportDeclaration node, Object data) {
((MutableInt) data).increment();
return data;
}
@Override
public Object visit(ASTPackageDeclaration node, Object data) {
((MutableInt) data).increment();
return data;
}
@Override
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {

View File

@ -97,4 +97,5 @@ public class StandardCycloVisitor extends CycloPathUnawareOperationVisitor {
}
return data;
}
}

View File

@ -4,6 +4,20 @@
<code-fragment id="full-example">
<![CDATA[
public class Complicated {
public void exception() {
try {
int k = 0;
k++;
} catch (IOException ioe) {
ioe.printStackTrace();
throw new Exception("surprise", ioe);
} catch (Exception e) {
// do nothing
}
}
public void example() {
int x = 0, y = 1, z = 2, t = 2;
boolean a = false, b = true, c = false, d = true;
@ -12,7 +26,7 @@
if (y == z) {
x = 2;
} else if (y == t && !d) {
x = 2;
x = a ? z : b ? y : x;
} else {
x = 2;
}
@ -24,6 +38,11 @@
for (int n = 0; n < t; n++) {
x = 2;
}
} else if (b) {
do {
x++;
y--;
} while (b);
} else {
switch (x) {
case 1:
@ -46,11 +65,24 @@
</code-fragment>
<test-code>
<description>Complicated method</description>
<expected-problems>2</expected-problems>
<description>Complicated method - Standard</description>
<expected-problems>3</expected-problems>
<expected-messages>
<message>'.Complicated' has value 18 highest 17.</message>
<message>'.Complicated#example()' has value 17.</message>
<message>'.Complicated' has value 13 highest 21.</message>
<message>'.Complicated#exception()' has value 4.</message>
<message>'.Complicated#example()' has value 21.</message>
</expected-messages>
<code-ref id="full-example"/>
</test-code>
<test-code>
<description>Complicated method - Ignore boolean path version</description>
<expected-problems>3</expected-problems>
<rule-property name="metricVersion">ignoreBooleanPaths</rule-property>
<expected-messages>
<message>'.Complicated' has value 10 highest 14.</message>
<message>'.Complicated#exception()' has value 4.</message>
<message>'.Complicated#example()' has value 14.</message>
</expected-messages>
<code-ref id="full-example"/>
</test-code>