Bläddra i källkod

SONAR-8760 Define 'Cognitive Complexity' metric

tags/6.3-RC1
Julien Lancelot 7 år sedan
förälder
incheckning
7afdd2432c
14 ändrade filer med 143 tillägg och 6 borttagningar
  1. 2
    0
      it/it-projects/shared/xoo-multi-modules-sample/module_a/module_a1/src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo.measures
  2. 3
    0
      it/it-projects/shared/xoo-multi-modules-sample/module_a/module_a2/src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo.measures
  3. 3
    1
      it/it-projects/shared/xoo-multi-modules-sample/module_b/module_b1/src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo.measures
  4. 3
    1
      it/it-projects/shared/xoo-multi-modules-sample/module_b/module_b2/src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo.measures
  5. 1
    0
      it/it-projects/shared/xoo-sample/src/main/xoo/sample/Sample.xoo.measures
  6. 4
    1
      it/it-tests/src/test/java/it/Category1Suite.java
  7. 90
    0
      it/it-tests/src/test/java/it/complexity/ComplexityMeasuresTest.java
  8. 2
    0
      server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ComplexityMeasuresStep.java
  9. 10
    1
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportComplexityMeasuresStepTest.java
  10. 10
    1
      server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsComplexityMeasuresStepTest.java
  11. 2
    0
      sonar-core/src/main/java/org/sonar/core/metric/ScannerMetrics.java
  12. 2
    0
      sonar-core/src/main/resources/org/sonar/l10n/core.properties
  13. 1
    1
      sonar-core/src/test/java/org/sonar/core/metric/ScannerMetricsTest.java
  14. 10
    0
      sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java

+ 2
- 0
it/it-projects/shared/xoo-multi-modules-sample/module_a/module_a1/src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo.measures Visa fil

@@ -1,2 +1,4 @@
ncloc:12
classes:1
complexity:3
cognitive_complexity:4

+ 3
- 0
it/it-projects/shared/xoo-multi-modules-sample/module_a/module_a2/src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo.measures Visa fil

@@ -1,2 +1,5 @@
ncloc:15
classes:1
complexity:4
cognitive_complexity:5


+ 3
- 1
it/it-projects/shared/xoo-multi-modules-sample/module_b/module_b1/src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo.measures Visa fil

@@ -1,2 +1,4 @@
ncloc:12
classes:1
classes:1
complexity:3
cognitive_complexity:4

+ 3
- 1
it/it-projects/shared/xoo-multi-modules-sample/module_b/module_b2/src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo.measures Visa fil

@@ -1,2 +1,4 @@
ncloc:12
classes:1
classes:1
complexity:3
cognitive_complexity:4

+ 1
- 0
it/it-projects/shared/xoo-sample/src/main/xoo/sample/Sample.xoo.measures Visa fil

@@ -2,6 +2,7 @@ ncloc:13
#Used by dashboard/widgets tests
complexity:3
complexity_in_classes:3
cognitive_complexity:4
classes:1
comment_lines:3
public_api:5

+ 4
- 1
it/it-tests/src/test/java/it/Category1Suite.java Visa fil

@@ -26,6 +26,7 @@ import it.authorisation.IssuePermissionTest;
import it.authorisation.PermissionSearchTest;
import it.authorisation.ProvisioningPermissionTest;
import it.authorisation.QualityProfileAdminPermissionTest;
import it.complexity.ComplexityMeasuresTest;
import it.customMeasure.CustomMeasuresTest;
import it.i18n.I18nTest;
import it.measure.MeasuresWsTest;
@@ -98,7 +99,9 @@ import static util.ItUtils.xooPlugin;
// source code
EncodingTest.class,
HighlightingTest.class,
ProjectCodeTest.class
ProjectCodeTest.class,
// complexity
ComplexityMeasuresTest.class
})
public class Category1Suite {


+ 90
- 0
it/it-tests/src/test/java/it/complexity/ComplexityMeasuresTest.java Visa fil

@@ -0,0 +1,90 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package it.complexity;

import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.SonarScanner;
import it.Category1Suite;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Java6Assertions.entry;
import static util.ItUtils.getMeasuresAsDoubleByMetricKey;
import static util.ItUtils.projectDir;

// TODO complete the test with other complexity metrics
public class ComplexityMeasuresTest {

private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample";
private static final String MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a";
private static final String SUB_MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1";
private static final String DIRECTORY = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1";
private static final String FILE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo";

private static final String COMPLEXITY_METRIC = "complexity";
private static final String COGNITIVE_COMPLEXITY_METRIC = "cognitive_complexity";

@ClassRule
public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;

@BeforeClass
public static void inspectProject() {
orchestrator.resetData();
orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample")));
}

@Test
public void compute_complexity_metrics_on_file() {
assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, FILE, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
entry(COMPLEXITY_METRIC, 3d),
entry(COGNITIVE_COMPLEXITY_METRIC, 4d));
}

@Test
public void compute_complexity_metrics_on_directory() {
assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, DIRECTORY, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
entry(COMPLEXITY_METRIC, 3d),
entry(COGNITIVE_COMPLEXITY_METRIC, 4d));
}

@Test
public void compute_complexity_metrics_on_sub_module() {
assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, SUB_MODULE, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
entry(COMPLEXITY_METRIC, 3d),
entry(COGNITIVE_COMPLEXITY_METRIC, 4d));
}

@Test
public void compute_complexity_metrics_on_module() {
assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, MODULE, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
entry(COMPLEXITY_METRIC, 7d),
entry(COGNITIVE_COMPLEXITY_METRIC, 9d));
}

@Test
public void compute_complexity_metrics_on_project() {
assertThat(getMeasuresAsDoubleByMetricKey(orchestrator, PROJECT, COMPLEXITY_METRIC, COGNITIVE_COMPLEXITY_METRIC)).containsOnly(
entry(COMPLEXITY_METRIC, 13d),
entry(COGNITIVE_COMPLEXITY_METRIC, 17d));
}

}

+ 2
- 0
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ComplexityMeasuresStep.java Visa fil

@@ -33,6 +33,7 @@ import org.sonar.server.computation.task.step.ComputationStep;
import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY;
import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION_KEY;
import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_KEY;
import static org.sonar.api.measures.CoreMetrics.COGNITIVE_COMPLEXITY_KEY;
import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_CLASSES_KEY;
import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_FUNCTIONS_KEY;
import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_KEY;
@@ -53,6 +54,7 @@ public class ComplexityMeasuresStep implements ComputationStep {
createIntSumFormula(COMPLEXITY_KEY),
createIntSumFormula(COMPLEXITY_IN_CLASSES_KEY),
createIntSumFormula(COMPLEXITY_IN_FUNCTIONS_KEY),
createIntSumFormula(COGNITIVE_COMPLEXITY_KEY),
new DistributionFormula(FUNCTION_COMPLEXITY_DISTRIBUTION_KEY),
new DistributionFormula(FILE_COMPLEXITY_DISTRIBUTION_KEY),
new DistributionFormula(CLASS_COMPLEXITY_DISTRIBUTION_KEY),

+ 10
- 1
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportComplexityMeasuresStepTest.java Visa fil

@@ -35,6 +35,8 @@ import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY;
import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION;
import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION_KEY;
import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_KEY;
import static org.sonar.api.measures.CoreMetrics.COGNITIVE_COMPLEXITY;
import static org.sonar.api.measures.CoreMetrics.COGNITIVE_COMPLEXITY_KEY;
import static org.sonar.api.measures.CoreMetrics.COMPLEXITY;
import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_CLASSES;
import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_CLASSES_KEY;
@@ -102,7 +104,9 @@ public class ReportComplexityMeasuresStepTest {
.add(CLASS_COMPLEXITY)
.add(CLASSES)
.add(FUNCTION_COMPLEXITY)
.add(FUNCTIONS);
.add(FUNCTIONS)
.add(COGNITIVE_COMPLEXITY);

@Rule
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);

@@ -123,6 +127,11 @@ public class ReportComplexityMeasuresStepTest {
verify_sum_aggregation(COMPLEXITY_IN_FUNCTIONS_KEY);
}

@Test
public void aggregate_cognitive_complexity() throws Exception {
verify_sum_aggregation(COGNITIVE_COMPLEXITY_KEY);
}

private void verify_sum_aggregation(String metricKey) {
measureRepository.addRawMeasure(FILE_1_REF, metricKey, newMeasureBuilder().create(10));
measureRepository.addRawMeasure(FILE_2_REF, metricKey, newMeasureBuilder().create(40));

+ 10
- 1
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsComplexityMeasuresStepTest.java Visa fil

@@ -35,6 +35,8 @@ import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY;
import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION;
import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION_KEY;
import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_KEY;
import static org.sonar.api.measures.CoreMetrics.COGNITIVE_COMPLEXITY;
import static org.sonar.api.measures.CoreMetrics.COGNITIVE_COMPLEXITY_KEY;
import static org.sonar.api.measures.CoreMetrics.COMPLEXITY;
import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_CLASSES;
import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_CLASSES_KEY;
@@ -101,7 +103,9 @@ public class ViewsComplexityMeasuresStepTest {
.add(CLASS_COMPLEXITY)
.add(CLASSES)
.add(FUNCTION_COMPLEXITY)
.add(FUNCTIONS);
.add(FUNCTIONS)
.add(COGNITIVE_COMPLEXITY);

@Rule
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);

@@ -122,6 +126,11 @@ public class ViewsComplexityMeasuresStepTest {
verify_sum_aggregation(COMPLEXITY_IN_FUNCTIONS_KEY);
}

@Test
public void aggregate_cognitive_complexity_in_functions() throws Exception {
verify_sum_aggregation(COGNITIVE_COMPLEXITY_KEY);
}

private void verify_sum_aggregation(String metricKey) {
addRawMeasureValue(PROJECT_VIEW_1_REF, metricKey, 10);
addRawMeasureValue(PROJECT_VIEW_2_REF, metricKey, 40);

+ 2
- 0
sonar-core/src/main/java/org/sonar/core/metric/ScannerMetrics.java Visa fil

@@ -31,6 +31,7 @@ import org.sonar.api.measures.Metrics;

import static org.sonar.api.measures.CoreMetrics.ACCESSORS;
import static org.sonar.api.measures.CoreMetrics.CLASSES;
import static org.sonar.api.measures.CoreMetrics.COGNITIVE_COMPLEXITY;
import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES;
import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES_DATA;
import static org.sonar.api.measures.CoreMetrics.COMPLEXITY;
@@ -95,6 +96,7 @@ public class ScannerMetrics {
COMPLEXITY,
COMPLEXITY_IN_CLASSES,
COMPLEXITY_IN_FUNCTIONS,
COGNITIVE_COMPLEXITY,
FILE_COMPLEXITY_DISTRIBUTION,
FUNCTION_COMPLEXITY_DISTRIBUTION,


+ 2
- 0
sonar-core/src/main/resources/org/sonar/l10n/core.properties Visa fil

@@ -1930,6 +1930,8 @@ metric.class_complexity_distribution.description=Classes distribution /complexit
metric.class_complexity_distribution.name=Class Distribution / Complexity
metric.code_smells.description=Code Smells
metric.code_smells.name=Code Smells
metric.cognitive_complexity.description=Cognitive complexity
metric.cognitive_complexity.name=Cognitive Complexity
metric.commented_out_code_lines.description=Commented lines of code
metric.commented_out_code_lines.name=Commented-Out LOC
metric.comment_blank_lines.description=Comments that do not contain comments

+ 1
- 1
sonar-core/src/test/java/org/sonar/core/metric/ScannerMetricsTest.java Visa fil

@@ -36,7 +36,7 @@ public class ScannerMetricsTest {

@Test
public void check_number_of_allowed_core_metrics() throws Exception {
assertThat(SENSOR_METRICS_WITHOUT_METRIC_PLUGIN.getMetrics()).hasSize(33);
assertThat(SENSOR_METRICS_WITHOUT_METRIC_PLUGIN.getMetrics()).hasSize(34);
}

@Test

+ 10
- 0
sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java Visa fil

@@ -467,6 +467,16 @@ public final class CoreMetrics {
.setDomain(DOMAIN_COMPLEXITY)
.create();

public static final String COGNITIVE_COMPLEXITY_KEY = "cognitive_complexity";
public static final Metric<Integer> COGNITIVE_COMPLEXITY = new Metric.Builder(COGNITIVE_COMPLEXITY_KEY, "Cognitive Complexity", Metric.ValueType.INT)
.setDescription("Cognitive complexity")
.setDirection(Metric.DIRECTION_WORST)
.setQualitative(false)
.setDomain(DOMAIN_COMPLEXITY)
.setBestValue(0.0)
.setOptimizedBestValue(true)
.create();

// --------------------------------------------------------------------------------------------------------------------
//
// UNIT TESTS

Laddar…
Avbryt
Spara