]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6370 move batch extensions out of core plugin
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Wed, 27 May 2015 07:38:17 +0000 (09:38 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 28 May 2015 07:29:03 +0000 (09:29 +0200)
Decorators temporarily moved to package org.sonar.batch.compute of sonar-batch.

125 files changed:
plugins/sonar-core-plugin/pom.xml
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountFalsePositivesDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/SeverityUtils.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AbstractCoverageDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CommentDensityDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/DirectoriesDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItBranchCoverageDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItCoverageDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItLineCoverageDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ManualMeasureDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/OverallBranchCoverageDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/OverallCoverageDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/OverallLineCoverageDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/UnitTestDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzer.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewItCoverageFileAnalyzer.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewOverallCoverageFileAnalyzer.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/package-info.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/CorePluginTest.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/CountFalsePositivesDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/ApplyProjectRolesDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/BranchCoverageDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CommentDensityDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/DirectoriesDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FilesDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ItBranchCoverageDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ItCoverageDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ItLineCoverageDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/LineCoverageDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ManualMeasureDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/OverallBranchCoverageDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/OverallCoverageDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/OverallLineCoverageDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/UnitTestDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageAggregatorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ManualMeasureDecoratorTest/testCopyManualMeasures.xml [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldSaveLinks.xml [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest/shared.xml [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest/shouldSaveConfigurationInSnapshotsTable-result.xml [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationPersisterDecoratorTest/shared.xml [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationPersisterDecoratorTest/shouldCopyPermanentIdFromReferenceViolation-result.xml [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationPersisterDecoratorTest/shouldSaveViolations-result.xml [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v1.txt [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v2.txt [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v1.txt [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v2.txt [deleted file]
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java
sonar-batch/src/main/java/org/sonar/batch/compute/AbstractCoverageDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/AbstractNewCoverageFileAnalyzer.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/ApplyProjectRolesDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/BranchCoverageDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/CommentDensityDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/CountFalsePositivesDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/CountUnresolvedIssuesDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/CoverageDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/DirectoriesDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/FilesDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/ItBranchCoverageDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/ItCoverageDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/ItLineCoverageDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/LineCoverageDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/ManualMeasureDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/NewCoverageAggregator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/NewCoverageFileAnalyzer.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/NewItCoverageFileAnalyzer.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/NewOverallCoverageFileAnalyzer.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/OverallBranchCoverageDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/OverallCoverageDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/OverallLineCoverageDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/SeverityUtils.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/TimeMachineConfigurationPersister.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/UnitTestDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/VariationDecorator.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/compute/package-info.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/ApplyProjectRolesDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/BranchCoverageDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/CommentDensityDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/CountFalsePositivesDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/CountUnresolvedIssuesDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/CoverageDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/DirectoriesDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/FilesDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/ItBranchCoverageDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/ItCoverageDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/ItLineCoverageDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/LineCoverageDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/ManualMeasureDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/NewCoverageAggregatorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/NewCoverageFileAnalyzerTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/OverallBranchCoverageDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/OverallCoverageDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/OverallLineCoverageDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/TimeMachineConfigurationPersisterTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/UnitTestDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/compute/VariationDecoratorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java
sonar-batch/src/test/resources/org/sonar/batch/compute/ManualMeasureDecoratorTest/testCopyManualMeasures.xml [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/ProjectLinksSensorTest/shouldSaveLinks.xml [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/TimeMachineConfigurationPersisterTest/shared.xml [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/TimeMachineConfigurationPersisterTest/shouldSaveConfigurationInSnapshotsTable-result.xml [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationPersisterDecoratorTest/shared.xml [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationPersisterDecoratorTest/shouldCopyPermanentIdFromReferenceViolation-result.xml [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationPersisterDecoratorTest/shouldSaveViolations-result.xml [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example1-v1.txt [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example1-v2.txt [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example2-v1.txt [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example2-v2.txt [new file with mode: 0644]

index 3df82a925398606a62ff297fddadd8fffee00c40..58ead2cf637827046635f53b8b8d4023bbc3739e 100644 (file)
       <artifactId>jfreechart</artifactId>
       <scope>provided</scope>
     </dependency>
-    <dependency>
-      <groupId>org.codehaus.sonar</groupId>
-      <artifactId>sonar-batch</artifactId>
-      <version>${project.version}</version>
-      <scope>provided</scope>
-    </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-plugin-api</artifactId>
index 0b1883d954b953d7914169b4a1c0329c41c0e993..cd0b8687a3cb962105ae07bb256ca11a84d82626 100644 (file)
@@ -26,30 +26,7 @@ import org.sonar.api.Properties;
 import org.sonar.api.Property;
 import org.sonar.api.PropertyType;
 import org.sonar.api.SonarPlugin;
-import org.sonar.plugins.core.issue.CountFalsePositivesDecorator;
-import org.sonar.plugins.core.issue.CountUnresolvedIssuesDecorator;
 import org.sonar.plugins.core.notifications.alerts.NewAlerts;
-import org.sonar.plugins.core.security.ApplyProjectRolesDecorator;
-import org.sonar.plugins.core.sensors.BranchCoverageDecorator;
-import org.sonar.plugins.core.sensors.CommentDensityDecorator;
-import org.sonar.plugins.core.sensors.CoverageDecorator;
-import org.sonar.plugins.core.sensors.DirectoriesDecorator;
-import org.sonar.plugins.core.sensors.FilesDecorator;
-import org.sonar.plugins.core.sensors.ItBranchCoverageDecorator;
-import org.sonar.plugins.core.sensors.ItCoverageDecorator;
-import org.sonar.plugins.core.sensors.ItLineCoverageDecorator;
-import org.sonar.plugins.core.sensors.LineCoverageDecorator;
-import org.sonar.plugins.core.sensors.ManualMeasureDecorator;
-import org.sonar.plugins.core.sensors.OverallBranchCoverageDecorator;
-import org.sonar.plugins.core.sensors.OverallCoverageDecorator;
-import org.sonar.plugins.core.sensors.OverallLineCoverageDecorator;
-import org.sonar.plugins.core.sensors.UnitTestDecorator;
-import org.sonar.plugins.core.timemachine.NewCoverageAggregator;
-import org.sonar.plugins.core.timemachine.NewCoverageFileAnalyzer;
-import org.sonar.plugins.core.timemachine.NewItCoverageFileAnalyzer;
-import org.sonar.plugins.core.timemachine.NewOverallCoverageFileAnalyzer;
-import org.sonar.plugins.core.timemachine.TimeMachineConfigurationPersister;
-import org.sonar.plugins.core.timemachine.VariationDecorator;
 
 @Properties({
   @Property(
@@ -219,35 +196,6 @@ public final class CorePlugin extends SonarPlugin {
       DefaultResourceTypes.class,
       UserManagedMetrics.class,
 
-      // issues
-      CountUnresolvedIssuesDecorator.class,
-      CountFalsePositivesDecorator.class,
-
-      // batch
-      UnitTestDecorator.class,
-      LineCoverageDecorator.class,
-      CoverageDecorator.class,
-      BranchCoverageDecorator.class,
-      ItLineCoverageDecorator.class,
-      ItCoverageDecorator.class,
-      ItBranchCoverageDecorator.class,
-      OverallLineCoverageDecorator.class,
-      OverallCoverageDecorator.class,
-      OverallBranchCoverageDecorator.class,
-      ApplyProjectRolesDecorator.class,
-      CommentDensityDecorator.class,
-      DirectoriesDecorator.class,
-      FilesDecorator.class,
-      ManualMeasureDecorator.class,
-
-      // time machine
-      VariationDecorator.class,
-      TimeMachineConfigurationPersister.class,
-      NewCoverageFileAnalyzer.class,
-      NewItCoverageFileAnalyzer.class,
-      NewOverallCoverageFileAnalyzer.class,
-      NewCoverageAggregator.class,
-
       // Notify alerts on my favourite projects
       NewAlerts.class,
       NewAlerts.newMetadata());
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountFalsePositivesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountFalsePositivesDecorator.java
deleted file mode 100644 (file)
index c962544..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.issue;
-
-import org.sonar.api.batch.*;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.issue.Issuable;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-
-/**
- * Computes the number of false-positives
- *
- * @since 3.6
- */
-@DependsUpon(DecoratorBarriers.END_OF_VIOLATION_TRACKING)
-public class CountFalsePositivesDecorator implements Decorator {
-
-  private final ResourcePerspectives perspectives;
-
-  public CountFalsePositivesDecorator(ResourcePerspectives perspectives) {
-    this.perspectives = perspectives;
-  }
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  @DependedUpon
-  public Metric generatesFalsePositiveMeasure() {
-    return CoreMetrics.FALSE_POSITIVE_ISSUES;
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    Issuable issuable = perspectives.as(Issuable.class, resource);
-    if (issuable != null) {
-      int falsePositives = 0;
-      for (Issue issue : issuable.resolvedIssues()) {
-        if (Issue.RESOLUTION_FALSE_POSITIVE.equals(issue.resolution())) {
-          falsePositives++;
-        }
-      }
-      saveMeasure(context, CoreMetrics.FALSE_POSITIVE_ISSUES, falsePositives);
-    }
-  }
-
-  private void saveMeasure(DecoratorContext context, Metric metric, int value) {
-    context.saveMeasure(metric, (double) (value + sumChildren(context, metric)));
-  }
-
-  private int sumChildren(DecoratorContext context, Metric metric) {
-    return MeasureUtils.sum(true, context.getChildrenMeasures(metric)).intValue();
-  }
-
-  @Override
-  public String toString() {
-    return getClass().getSimpleName();
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecorator.java
deleted file mode 100644 (file)
index 1606b3a..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.issue;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.*;
-import org.apache.commons.lang.time.DateUtils;
-import org.sonar.api.batch.*;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.issue.Issuable;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.measures.*;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.RulePriority;
-import org.sonar.batch.components.Period;
-import org.sonar.batch.components.TimeMachineConfiguration;
-
-import javax.annotation.Nullable;
-
-import java.util.*;
-
-/**
- * Computes metrics related to number of issues.
- *
- * @since 3.6
- */
-@DependsUpon(DecoratorBarriers.ISSUES_TRACKED)
-@RequiresDB
-public class CountUnresolvedIssuesDecorator implements Decorator {
-
-  private final ResourcePerspectives perspectives;
-  private final TimeMachineConfiguration timeMachineConfiguration;
-
-  public CountUnresolvedIssuesDecorator(ResourcePerspectives perspectives, TimeMachineConfiguration timeMachineConfiguration) {
-    this.perspectives = perspectives;
-    this.timeMachineConfiguration = timeMachineConfiguration;
-  }
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  @DependedUpon
-  public List<Metric> generatesIssuesMetrics() {
-    return ImmutableList.<Metric>of(
-      CoreMetrics.VIOLATIONS,
-      CoreMetrics.BLOCKER_VIOLATIONS,
-      CoreMetrics.CRITICAL_VIOLATIONS,
-      CoreMetrics.MAJOR_VIOLATIONS,
-      CoreMetrics.MINOR_VIOLATIONS,
-      CoreMetrics.INFO_VIOLATIONS,
-      CoreMetrics.NEW_VIOLATIONS,
-      CoreMetrics.NEW_BLOCKER_VIOLATIONS,
-      CoreMetrics.NEW_CRITICAL_VIOLATIONS,
-      CoreMetrics.NEW_MAJOR_VIOLATIONS,
-      CoreMetrics.NEW_MINOR_VIOLATIONS,
-      CoreMetrics.NEW_INFO_VIOLATIONS,
-      CoreMetrics.OPEN_ISSUES,
-      CoreMetrics.REOPENED_ISSUES,
-      CoreMetrics.CONFIRMED_ISSUES
-      );
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    Issuable issuable = perspectives.as(Issuable.class, resource);
-    if (issuable != null) {
-      Collection<Issue> issues = issuable.issues();
-      boolean shouldSaveNewMetrics = shouldSaveNewMetrics(context);
-
-      Multiset<RulePriority> severityBag = HashMultiset.create();
-      Map<RulePriority, Multiset<RuleKey>> rulesPerSeverity = Maps.newHashMap();
-      ListMultimap<RulePriority, Issue> issuesPerSeverity = ArrayListMultimap.create();
-      int countOpen = 0;
-      int countReopened = 0;
-      int countConfirmed = 0;
-
-      for (Issue issue : issues) {
-        severityBag.add(RulePriority.valueOf(issue.severity()));
-        Multiset<RuleKey> rulesBag = initRules(rulesPerSeverity, RulePriority.valueOf(issue.severity()));
-        rulesBag.add(issue.ruleKey());
-        issuesPerSeverity.put(RulePriority.valueOf(issue.severity()), issue);
-
-        if (Issue.STATUS_OPEN.equals(issue.status())) {
-          countOpen++;
-        } else if (Issue.STATUS_REOPENED.equals(issue.status())) {
-          countReopened++;
-        } else if (Issue.STATUS_CONFIRMED.equals(issue.status())) {
-          countConfirmed++;
-        }
-      }
-
-      for (RulePriority ruleSeverity : RulePriority.values()) {
-        saveIssuesForSeverity(context, ruleSeverity, severityBag);
-        saveIssuesPerRules(context, ruleSeverity, rulesPerSeverity);
-        saveNewIssuesForSeverity(context, ruleSeverity, issuesPerSeverity, shouldSaveNewMetrics);
-        saveNewIssuesPerRule(context, ruleSeverity, issues, shouldSaveNewMetrics);
-      }
-
-      saveTotalIssues(context, issues);
-      saveNewIssues(context, issues, shouldSaveNewMetrics);
-
-      saveMeasure(context, CoreMetrics.OPEN_ISSUES, countOpen);
-      saveMeasure(context, CoreMetrics.REOPENED_ISSUES, countReopened);
-      saveMeasure(context, CoreMetrics.CONFIRMED_ISSUES, countConfirmed);
-    }
-  }
-
-  private void saveTotalIssues(DecoratorContext context, Collection<Issue> issues) {
-    if (context.getMeasure(CoreMetrics.VIOLATIONS) == null) {
-      Collection<Measure> childrenIssues = context.getChildrenMeasures(CoreMetrics.VIOLATIONS);
-      Double sum = MeasureUtils.sum(true, childrenIssues);
-      context.saveMeasure(CoreMetrics.VIOLATIONS, sum + issues.size());
-    }
-  }
-
-  private void saveNewIssues(DecoratorContext context, Collection<Issue> issues, boolean shouldSaveNewMetrics) {
-    if (shouldSaveNewMetrics) {
-      Measure measure = new Measure(CoreMetrics.NEW_VIOLATIONS);
-      saveNewIssues(context, measure, issues);
-    }
-  }
-
-  private void saveIssuesForSeverity(DecoratorContext context, RulePriority ruleSeverity, Multiset<RulePriority> severitiesBag) {
-    Metric metric = SeverityUtils.severityToIssueMetric(ruleSeverity);
-    if (context.getMeasure(metric) == null) {
-      Collection<Measure> children = context.getChildrenMeasures(MeasuresFilters.metric(metric));
-      int sum = MeasureUtils.sum(true, children).intValue() + severitiesBag.count(ruleSeverity);
-      context.saveMeasure(metric, (double) sum);
-    }
-  }
-
-  private void saveNewIssuesForSeverity(DecoratorContext context, RulePriority severity, ListMultimap<RulePriority, Issue> issuesPerSeverities, boolean shouldSaveNewMetrics) {
-    if (shouldSaveNewMetrics) {
-      Metric metric = SeverityUtils.severityToNewMetricIssue(severity);
-      Measure measure = new Measure(metric);
-      saveNewIssues(context, measure, issuesPerSeverities.get(severity));
-    }
-  }
-
-  private void saveIssuesPerRules(DecoratorContext context, RulePriority severity, Map<RulePriority, Multiset<RuleKey>> rulesPerSeverity) {
-    Metric metric = SeverityUtils.severityToIssueMetric(severity);
-
-    Collection<Measure> children = context.getChildrenMeasures(MeasuresFilters.rules(metric));
-    for (Measure child : children) {
-      RuleMeasure childRuleMeasure = (RuleMeasure) child;
-      RuleKey ruleKey = childRuleMeasure.ruleKey();
-      if (ruleKey != null && MeasureUtils.hasValue(childRuleMeasure)) {
-        Multiset<RuleKey> rulesBag = initRules(rulesPerSeverity, severity);
-        rulesBag.add(ruleKey, childRuleMeasure.getIntValue());
-      }
-    }
-
-    Multiset<RuleKey> rulesBag = rulesPerSeverity.get(severity);
-    if (rulesBag != null) {
-      for (Multiset.Entry<RuleKey> entry : rulesBag.entrySet()) {
-        RuleMeasure measure = RuleMeasure.createForRule(metric, entry.getElement(), (double) entry.getCount());
-        measure.setSeverity(severity);
-        context.saveMeasure(measure);
-      }
-    }
-  }
-
-  private void saveNewIssuesPerRule(DecoratorContext context, RulePriority severity, Collection<Issue> issues, boolean shouldSaveNewMetrics) {
-    if (shouldSaveNewMetrics) {
-      Metric metric = SeverityUtils.severityToNewMetricIssue(severity);
-      ListMultimap<RuleKey, Measure> childMeasuresPerRuleKeys = ArrayListMultimap.create();
-      ListMultimap<RuleKey, Issue> issuesPerRuleKeys = ArrayListMultimap.create();
-      Set<RuleKey> ruleKeys = Sets.newHashSet();
-
-      Collection<Measure> children = context.getChildrenMeasures(MeasuresFilters.rules(metric));
-      for (Measure child : children) {
-        RuleMeasure childRuleMeasure = (RuleMeasure) child;
-        RuleKey ruleKey = childRuleMeasure.ruleKey();
-        if (ruleKey != null) {
-          childMeasuresPerRuleKeys.put(ruleKey, childRuleMeasure);
-          ruleKeys.add(ruleKey);
-        }
-      }
-
-      for (Issue issue : issues) {
-        if (RulePriority.valueOf(issue.severity()).equals(severity)) {
-          ruleKeys.add(issue.ruleKey());
-          issuesPerRuleKeys.put(issue.ruleKey(), issue);
-        }
-      }
-
-      for (RuleKey ruleKey : ruleKeys) {
-        RuleMeasure measure = RuleMeasure.createForRule(metric, ruleKey, null);
-        measure.setSeverity(severity);
-        for (Period period : timeMachineConfiguration.periods()) {
-          int variationIndex = period.getIndex();
-          double sum = MeasureUtils.sumOnVariation(true, variationIndex, childMeasuresPerRuleKeys.get(ruleKey)) + countIssues(issuesPerRuleKeys.get(ruleKey), period);
-          measure.setVariation(variationIndex, sum);
-        }
-        context.saveMeasure(measure);
-      }
-    }
-  }
-
-  private void saveNewIssues(DecoratorContext context, Measure measure, Collection<Issue> issues) {
-    for (Period period : timeMachineConfiguration.periods()) {
-      int variationIndex = period.getIndex();
-      Collection<Measure> children = context.getChildrenMeasures(measure.getMetric());
-      double sum = MeasureUtils.sumOnVariation(true, variationIndex, children) + countIssues(issues, period);
-      measure.setVariation(variationIndex, sum);
-    }
-    context.saveMeasure(measure);
-  }
-
-  private void saveMeasure(DecoratorContext context, Metric metric, int value) {
-    context.saveMeasure(metric, (double) (value + sumChildren(context, metric)));
-  }
-
-  private int sumChildren(DecoratorContext context, Metric metric) {
-    int sum = 0;
-    if (!ResourceUtils.isFile(context.getResource())) {
-      sum = MeasureUtils.sum(true, context.getChildrenMeasures(metric)).intValue();
-    }
-    return sum;
-  }
-
-  private Multiset<RuleKey> initRules(Map<RulePriority, Multiset<RuleKey>> rulesPerSeverity, RulePriority severity) {
-    Multiset<RuleKey> rulesBag = rulesPerSeverity.get(severity);
-    if (rulesBag == null) {
-      rulesBag = HashMultiset.create();
-      rulesPerSeverity.put(severity, rulesBag);
-    }
-    return rulesBag;
-  }
-
-  private int countIssues(Collection<Issue> issues, Period period) {
-    // SONAR-3647 Use real snapshot date and not target date in order to stay consistent with other measure variations
-    Date datePlusOneSecond = period.getDate() != null ? DateUtils.addSeconds(period.getDate(), 1) : null;
-    return countIssuesAfterDate(issues, datePlusOneSecond);
-  }
-
-  @VisibleForTesting
-  int countIssuesAfterDate(Collection<Issue> issues, @Nullable Date date) {
-    if (issues == null) {
-      return 0;
-    }
-    int count = 0;
-    for (Issue issue : issues) {
-      if (isAfter(issue, date)) {
-        count++;
-      }
-    }
-    return count;
-  }
-
-  private boolean isAfter(Issue issue, @Nullable Date date) {
-    return date == null || (issue.creationDate() != null && DateUtils.truncatedCompareTo(issue.creationDate(), date, Calendar.SECOND) > 0);
-  }
-
-  private boolean shouldSaveNewMetrics(DecoratorContext context) {
-    return context.getMeasure(CoreMetrics.NEW_VIOLATIONS) == null;
-  }
-
-  @Override
-  public String toString() {
-    return getClass().getSimpleName();
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/SeverityUtils.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/SeverityUtils.java
deleted file mode 100644 (file)
index e1a1d5b..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.issue;
-
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.rules.RulePriority;
-
-final class SeverityUtils {
-  private SeverityUtils() {
-    // only static methods
-  }
-
-  static Metric severityToIssueMetric(RulePriority severity) {
-    Metric metric;
-    if (severity.equals(RulePriority.BLOCKER)) {
-      metric = CoreMetrics.BLOCKER_VIOLATIONS;
-    } else if (severity.equals(RulePriority.CRITICAL)) {
-      metric = CoreMetrics.CRITICAL_VIOLATIONS;
-    } else if (severity.equals(RulePriority.MAJOR)) {
-      metric = CoreMetrics.MAJOR_VIOLATIONS;
-    } else if (severity.equals(RulePriority.MINOR)) {
-      metric = CoreMetrics.MINOR_VIOLATIONS;
-    } else if (severity.equals(RulePriority.INFO)) {
-      metric = CoreMetrics.INFO_VIOLATIONS;
-    } else {
-      throw new IllegalArgumentException("Unsupported severity: " + severity);
-    }
-    return metric;
-  }
-
-  static Metric severityToNewMetricIssue(RulePriority severity) {
-    Metric metric;
-    if (severity.equals(RulePriority.BLOCKER)) {
-      metric = CoreMetrics.NEW_BLOCKER_VIOLATIONS;
-    } else if (severity.equals(RulePriority.CRITICAL)) {
-      metric = CoreMetrics.NEW_CRITICAL_VIOLATIONS;
-    } else if (severity.equals(RulePriority.MAJOR)) {
-      metric = CoreMetrics.NEW_MAJOR_VIOLATIONS;
-    } else if (severity.equals(RulePriority.MINOR)) {
-      metric = CoreMetrics.NEW_MINOR_VIOLATIONS;
-    } else if (severity.equals(RulePriority.INFO)) {
-      metric = CoreMetrics.NEW_INFO_VIOLATIONS;
-    } else {
-      throw new IllegalArgumentException("Unsupported severity: " + severity);
-    }
-    return metric;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java
deleted file mode 100644 (file)
index c93eb0e..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.security;
-
-import org.sonar.api.batch.RequiresDB;
-
-import com.google.common.collect.ImmutableSet;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.security.ResourcePermissions;
-
-import java.util.Set;
-
-@RequiresDB
-public class ApplyProjectRolesDecorator implements Decorator {
-
-  private static final Set<String> QUALIFIERS = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.SUBVIEW);
-  private final ResourcePermissions resourcePermissions;
-
-  public ApplyProjectRolesDecorator(ResourcePermissions resourcePermissions) {
-    this.resourcePermissions = resourcePermissions;
-  }
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    if (shouldDecorateResource(resource)) {
-      LoggerFactory.getLogger(ApplyProjectRolesDecorator.class).info("Grant default permissions to {}", resource.getKey());
-      resourcePermissions.grantDefaultRoles(resource);
-    }
-  }
-
-  private boolean shouldDecorateResource(Resource resource) {
-    return resource.getId() != null && QUALIFIERS.contains(resource.getQualifier()) && !resourcePermissions.hasRoles(resource);
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AbstractCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AbstractCoverageDecorator.java
deleted file mode 100644 (file)
index 8b28750..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-public abstract class AbstractCoverageDecorator implements Decorator {
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  @DependedUpon
-  public Collection<Metric> generatedMetrics() {
-    return Arrays.asList(getGeneratedMetric(), getGeneratedMetricForNewCode());
-  }
-
-  @Override
-  public void decorate(final Resource resource, final DecoratorContext context) {
-    if (shouldDecorate(resource)) {
-      computeMeasure(context);
-      computeMeasureForNewCode(context);
-    }
-  }
-
-  protected boolean shouldDecorate(final Resource resource) {
-    return !ResourceUtils.isUnitTestFile(resource);
-  }
-
-  private void computeMeasure(DecoratorContext context) {
-    if (context.getMeasure(getGeneratedMetric()) == null) {
-      Long elements = countElements(context);
-      if (elements != null && elements > 0L) {
-        Long coveredElements = countCoveredElements(context);
-        context.saveMeasure(getGeneratedMetric(), calculateCoverage(coveredElements, elements));
-      }
-    }
-  }
-
-  private void computeMeasureForNewCode(DecoratorContext context) {
-    if (context.getMeasure(getGeneratedMetricForNewCode()) == null) {
-      Measure measure = new Measure(getGeneratedMetricForNewCode());
-      boolean hasValue = false;
-      /* TODO remove this magic number */
-      for (int periodIndex = 1; periodIndex <= 5; periodIndex++) {
-        Long elements = countElementsForNewCode(context, periodIndex);
-
-        if (elements != null && elements > 0L) {
-          long coveredElements = countCoveredElementsForNewCode(context, periodIndex);
-          measure.setVariation(periodIndex, calculateCoverage(coveredElements, elements));
-          hasValue = true;
-        }
-      }
-      if (hasValue) {
-        context.saveMeasure(measure);
-      }
-    }
-  }
-
-  private double calculateCoverage(final long coveredLines, final long lines) {
-    return (100.0 * coveredLines) / lines;
-  }
-
-  protected abstract Metric getGeneratedMetric();
-
-  protected abstract Long countElements(DecoratorContext context);
-
-  protected abstract long countCoveredElements(DecoratorContext context);
-
-  protected abstract Metric getGeneratedMetricForNewCode();
-
-  protected abstract Long countElementsForNewCode(DecoratorContext context, int periodIndex);
-
-  protected abstract long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex);
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java
deleted file mode 100644 (file)
index c154440..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-import org.sonar.batch.sensor.coverage.CoverageConstants;
-
-import java.util.Collection;
-
-public final class BranchCoverageDecorator extends AbstractCoverageDecorator {
-
-  @DependsUpon
-  public Collection<Metric> dependsUponMetrics() {
-    return CoverageConstants.BRANCH_COVERAGE_METRICS;
-  }
-
-  @Override
-  protected Metric getGeneratedMetric() {
-    return CoreMetrics.BRANCH_COVERAGE;
-  }
-
-  @Override
-  protected Long countElements(DecoratorContext context) {
-    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L);
-  }
-
-  @Override
-  protected long countCoveredElements(DecoratorContext context) {
-    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS), 0L);
-    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L);
-
-    return conditions - uncoveredConditions;
-  }
-
-  @Override
-  protected Metric getGeneratedMetricForNewCode() {
-    return CoreMetrics.NEW_BRANCH_COVERAGE;
-  }
-
-  @Override
-  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
-    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex);
-  }
-
-  @Override
-  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
-    long uncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_CONDITIONS), periodIndex, 0L);
-    long conditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex, 0L);
-
-    return conditions - uncoveredConditions;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CommentDensityDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CommentDensityDecorator.java
deleted file mode 100644 (file)
index 76a54e7..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class CommentDensityDecorator implements Decorator {
-
-  @DependsUpon
-  public List<Metric> dependsUponMetrics() {
-    return Arrays.<Metric>asList(CoreMetrics.NCLOC, CoreMetrics.COMMENT_LINES, CoreMetrics.PUBLIC_API, CoreMetrics.PUBLIC_UNDOCUMENTED_API);
-  }
-
-  @DependedUpon
-  public List<Metric> generatesMetrics() {
-    return Arrays.<Metric>asList(CoreMetrics.COMMENT_LINES_DENSITY, CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY);
-  }
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    saveCommentsDensity(context);
-    savePublicApiDensity(context);
-  }
-
-  private void saveCommentsDensity(DecoratorContext context) {
-    if (context.getMeasure(CoreMetrics.COMMENT_LINES_DENSITY) != null) {
-      return;
-    }
-
-    Measure ncloc = context.getMeasure(CoreMetrics.NCLOC);
-    Measure comments = context.getMeasure(CoreMetrics.COMMENT_LINES);
-    if (MeasureUtils.hasValue(ncloc) && MeasureUtils.hasValue(comments) && (comments.getValue() + ncloc.getValue()) > 0) {
-      double val = 100.0 * (comments.getValue() / (comments.getValue() + ncloc.getValue()));
-      context.saveMeasure(new Measure(CoreMetrics.COMMENT_LINES_DENSITY, val));
-    }
-  }
-
-  private void savePublicApiDensity(DecoratorContext context) {
-    if (context.getMeasure(CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY) != null) {
-      return;
-    }
-
-    Measure publicApi = context.getMeasure(CoreMetrics.PUBLIC_API);
-    Measure publicUndocApi = context.getMeasure(CoreMetrics.PUBLIC_UNDOCUMENTED_API);
-
-    if (MeasureUtils.hasValue(publicApi) && MeasureUtils.hasValue(publicUndocApi) && publicApi.getValue() > 0) {
-      double documentedAPI = publicApi.getValue() - publicUndocApi.getValue();
-      Double value = 100.0 * (documentedAPI / publicApi.getValue());
-      context.saveMeasure(new Measure(CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY, value));
-    }
-  }
-
-  @Override
-  public String toString() {
-    return getClass().getSimpleName();
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java
deleted file mode 100644 (file)
index 0eb539f..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-import org.sonar.batch.sensor.coverage.CoverageConstants;
-
-import java.util.Collection;
-
-public final class CoverageDecorator extends AbstractCoverageDecorator {
-
-  @DependsUpon
-  public Collection<Metric> usedMetrics() {
-    return CoverageConstants.COVERAGE_METRICS;
-  }
-
-  @Override
-  protected Metric getGeneratedMetric() {
-    return CoreMetrics.COVERAGE;
-  }
-
-  @Override
-  protected Long countElements(DecoratorContext context) {
-    long linesToCover = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L);
-    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L);
-
-    return linesToCover + conditions;
-  }
-
-  @Override
-  protected long countCoveredElements(DecoratorContext context) {
-    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_LINES), 0L);
-    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L);
-    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS), 0L);
-    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L);
-
-    return lines + conditions - uncoveredConditions - uncoveredLines;
-  }
-
-  @Override
-  protected Metric getGeneratedMetricForNewCode() {
-    return CoreMetrics.NEW_COVERAGE;
-  }
-
-  @Override
-  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
-    Long newLinesToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex);
-    if (newLinesToCover == null) {
-      return null;
-    }
-
-    long newConditionsToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex, 0L);
-
-    return newLinesToCover + newConditionsToCover;
-  }
-
-  @Override
-  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
-    long newLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex, 0L);
-    long newUncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_LINES), periodIndex, 0L);
-    long newUncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_CONDITIONS), periodIndex, 0L);
-    long newConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex, 0L);
-
-    return newLines + newConditions - newUncoveredConditions - newUncoveredLines;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/DirectoriesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/DirectoriesDecorator.java
deleted file mode 100644 (file)
index b8dddd4..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-
-import java.util.Collection;
-
-/**
- * @since 2.2
- */
-public final class DirectoriesDecorator implements Decorator {
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  @DependedUpon
-  public Metric generateDirectoriesMetric() {
-    return CoreMetrics.DIRECTORIES;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    if (MeasureUtils.hasValue(context.getMeasure(CoreMetrics.DIRECTORIES))) {
-      return;
-    }
-
-    if (Resource.QUALIFIER_DIRECTORY.equals(resource.getQualifier())) {
-      context.saveMeasure(CoreMetrics.DIRECTORIES, 1.0);
-
-    } else if (ResourceUtils.isSet(resource)) {
-      Collection<Measure> childrenMeasures = context.getChildrenMeasures(CoreMetrics.DIRECTORIES);
-      Double sum = MeasureUtils.sum(false, childrenMeasures);
-      if (sum != null) {
-        context.saveMeasure(CoreMetrics.DIRECTORIES, sum);
-      }
-    }
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java
deleted file mode 100644 (file)
index 67f1620..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-
-import java.util.Collection;
-
-/**
- * @since 2.2
- */
-public final class FilesDecorator implements Decorator {
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  @DependedUpon
-  public Metric generateDirectoriesMetric() {
-    return CoreMetrics.FILES;
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    if (MeasureUtils.hasValue(context.getMeasure(CoreMetrics.FILES))) {
-      return;
-    }
-
-    if (Resource.QUALIFIER_CLASS.equals(resource.getQualifier()) || Resource.QUALIFIER_FILE.equals(resource.getQualifier())) {
-      context.saveMeasure(CoreMetrics.FILES, 1.0);
-
-    } else {
-      Collection<Measure> childrenMeasures = context.getChildrenMeasures(CoreMetrics.FILES);
-      Double sum = MeasureUtils.sum(false, childrenMeasures);
-      if (sum != null) {
-        context.saveMeasure(CoreMetrics.FILES, sum);
-      }
-    }
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItBranchCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItBranchCoverageDecorator.java
deleted file mode 100644 (file)
index eb515e3..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import com.google.common.collect.ImmutableList;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-
-import java.util.List;
-
-public final class ItBranchCoverageDecorator extends AbstractCoverageDecorator {
-
-  @DependsUpon
-  public List<Metric> dependsUponMetrics() {
-    return ImmutableList.<Metric>of(CoreMetrics.IT_UNCOVERED_CONDITIONS, CoreMetrics.IT_CONDITIONS_TO_COVER,
-      CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER);
-  }
-
-  @Override
-  protected Metric getGeneratedMetric() {
-    return CoreMetrics.IT_BRANCH_COVERAGE;
-  }
-
-  @Override
-  protected Long countElements(DecoratorContext context) {
-    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
-  }
-
-  @Override
-  protected long countCoveredElements(DecoratorContext context) {
-    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS), 0L);
-    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
-
-    return conditions - uncoveredConditions;
-  }
-
-  @Override
-  protected Metric getGeneratedMetricForNewCode() {
-    return CoreMetrics.NEW_IT_BRANCH_COVERAGE;
-  }
-
-  @Override
-  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
-    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex);
-  }
-
-  @Override
-  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
-    long uncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS), periodIndex, 0L);
-    long conditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex, 0L);
-
-    return conditions - uncoveredConditions;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItCoverageDecorator.java
deleted file mode 100644 (file)
index 9b2d990..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import com.google.common.collect.ImmutableList;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-
-import java.util.Collection;
-
-public final class ItCoverageDecorator extends AbstractCoverageDecorator {
-
-  @DependsUpon
-  public Collection<Metric> usedMetrics() {
-    return ImmutableList.<Metric>of(CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_LINES_TO_COVER,
-      CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.IT_CONDITIONS_TO_COVER, CoreMetrics.IT_UNCOVERED_CONDITIONS,
-      CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS);
-  }
-
-  @Override
-  protected Metric getGeneratedMetric() {
-    return CoreMetrics.IT_COVERAGE;
-  }
-
-  @Override
-  protected Long countElements(DecoratorContext context) {
-    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
-    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
-
-    return lines + conditions;
-  }
-
-  @Override
-  protected long countCoveredElements(DecoratorContext context) {
-    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES), 0L);
-    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
-    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS), 0L);
-    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
-
-    return lines + conditions - uncoveredConditions - uncoveredLines;
-  }
-
-  @Override
-  protected Metric getGeneratedMetricForNewCode() {
-    return CoreMetrics.NEW_IT_COVERAGE;
-  }
-
-  @Override
-  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
-    Long newLinesToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex);
-    if (newLinesToCover == null) {
-      return null;
-    }
-
-    long newConditionsToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex, 0L);
-    return newLinesToCover + newConditionsToCover;
-  }
-
-  @Override
-  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
-    long newLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex, 0L);
-    long newUncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_LINES), periodIndex, 0L);
-    long newUncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS), periodIndex, 0L);
-    long newConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex, 0L);
-
-    return newLines + newConditions - newUncoveredConditions - newUncoveredLines;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItLineCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItLineCoverageDecorator.java
deleted file mode 100644 (file)
index f829393..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import com.google.common.collect.ImmutableList;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-
-import java.util.List;
-
-public final class ItLineCoverageDecorator extends AbstractCoverageDecorator {
-
-  @DependsUpon
-  public List<Metric> dependsUponMetrics() {
-    return ImmutableList.<Metric>of(CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_LINES,
-      CoreMetrics.NEW_IT_LINES_TO_COVER);
-  }
-
-  @Override
-  protected Metric getGeneratedMetric() {
-    return CoreMetrics.IT_LINE_COVERAGE;
-  }
-
-  @Override
-  protected Long countElements(DecoratorContext context) {
-    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
-  }
-
-  @Override
-  protected long countCoveredElements(DecoratorContext context) {
-    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES), 0L);
-    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
-
-    return lines - uncoveredLines;
-  }
-
-  @Override
-  protected Metric getGeneratedMetricForNewCode() {
-    return CoreMetrics.NEW_IT_LINE_COVERAGE;
-  }
-
-  @Override
-  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
-    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex);
-  }
-
-  @Override
-  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
-    long uncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_LINES), periodIndex, 0L);
-    long lines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex, 0L);
-
-    return lines - uncoveredLines;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java
deleted file mode 100644 (file)
index ebc29af..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-import org.sonar.batch.sensor.coverage.CoverageConstants;
-
-import java.util.Collection;
-
-public final class LineCoverageDecorator extends AbstractCoverageDecorator {
-
-  @DependsUpon
-  public Collection<Metric> dependsUponMetrics() {
-    return CoverageConstants.LINE_COVERAGE_METRICS;
-  }
-
-  @Override
-  protected Metric getGeneratedMetric() {
-    return CoreMetrics.LINE_COVERAGE;
-  }
-
-  @Override
-  protected Long countElements(DecoratorContext context) {
-    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L);
-  }
-
-  @Override
-  protected long countCoveredElements(DecoratorContext context) {
-    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_LINES), 0L);
-    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L);
-
-    return lines - uncoveredLines;
-  }
-
-  @Override
-  protected Metric getGeneratedMetricForNewCode() {
-    return CoreMetrics.NEW_LINE_COVERAGE;
-  }
-
-  @Override
-  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
-    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex);
-  }
-
-  @Override
-  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
-    long uncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_LINES), periodIndex, 0L);
-    long lines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex, 0L);
-
-    return lines - uncoveredLines;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ManualMeasureDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ManualMeasureDecorator.java
deleted file mode 100644 (file)
index a62c1af..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.Phase;
-import org.sonar.api.batch.RequiresDB;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.MetricFinder;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.jpa.entity.ManualMeasure;
-
-import java.util.List;
-
-import static com.google.common.base.Preconditions.checkState;
-
-@Phase(name = Phase.Name.PRE)
-@RequiresDB
-public class ManualMeasureDecorator implements Decorator {
-
-  private DatabaseSession session;
-  private MetricFinder metricFinder;
-
-  public ManualMeasureDecorator(DatabaseSession session, MetricFinder metricFinder) {
-    this.session = session;
-    this.metricFinder = metricFinder;
-  }
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    if (resource.getId() != null) {
-      List<ManualMeasure> manualMeasures = session.getResults(ManualMeasure.class, "resourceId", resource.getId());
-      for (ManualMeasure manualMeasure : manualMeasures) {
-        context.saveMeasure(copy(manualMeasure));
-      }
-    }
-  }
-
-  private Measure copy(ManualMeasure manualMeasure) {
-    Metric metric = metricFinder.findById(manualMeasure.getMetricId());
-    checkState(metric != null, "Unable to find manual metric with id: " + manualMeasure.getMetricId());
-
-    Measure measure = new Measure(metric);
-    measure.setValue(manualMeasure.getValue(), 5);
-    measure.setData(manualMeasure.getTextValue());
-    measure.setDescription(manualMeasure.getDescription());
-    return measure;
-  }
-
-  @Override
-  public String toString() {
-    return getClass().getSimpleName();
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/OverallBranchCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/OverallBranchCoverageDecorator.java
deleted file mode 100644 (file)
index 2407269..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import com.google.common.collect.ImmutableList;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-
-import java.util.List;
-
-public final class OverallBranchCoverageDecorator extends AbstractCoverageDecorator {
-
-  @DependsUpon
-  public List<Metric> dependsUponMetrics() {
-    return ImmutableList.<Metric>of(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS, CoreMetrics.OVERALL_CONDITIONS_TO_COVER,
-      CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS, CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER);
-  }
-
-  @Override
-  protected Metric getGeneratedMetric() {
-    return CoreMetrics.OVERALL_BRANCH_COVERAGE;
-  }
-
-  @Override
-  protected Long countElements(DecoratorContext context) {
-    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER), 0L);
-  }
-
-  @Override
-  protected long countCoveredElements(DecoratorContext context) {
-    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS), 0L);
-    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER), 0L);
-
-    return conditions - uncoveredConditions;
-  }
-
-  @Override
-  protected Metric getGeneratedMetricForNewCode() {
-    return CoreMetrics.NEW_OVERALL_BRANCH_COVERAGE;
-  }
-
-  @Override
-  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
-    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER), periodIndex);
-  }
-
-  @Override
-  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
-    long uncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS), periodIndex, 0L);
-    long conditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER), periodIndex, 0L);
-
-    return conditions - uncoveredConditions;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/OverallCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/OverallCoverageDecorator.java
deleted file mode 100644 (file)
index 49602e6..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import com.google.common.collect.ImmutableList;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-
-import java.util.Collection;
-
-public final class OverallCoverageDecorator extends AbstractCoverageDecorator {
-
-  @DependsUpon
-  public Collection<Metric> usedMetrics() {
-    return ImmutableList.<Metric>of(CoreMetrics.OVERALL_LINES_TO_COVER, CoreMetrics.OVERALL_UNCOVERED_LINES, CoreMetrics.NEW_OVERALL_LINES_TO_COVER,
-      CoreMetrics.NEW_OVERALL_UNCOVERED_LINES, CoreMetrics.OVERALL_CONDITIONS_TO_COVER, CoreMetrics.OVERALL_UNCOVERED_CONDITIONS,
-      CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS);
-  }
-
-  @Override
-  protected Metric getGeneratedMetric() {
-    return CoreMetrics.OVERALL_COVERAGE;
-  }
-
-  @Override
-  protected Long countElements(DecoratorContext context) {
-    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER), 0L);
-    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER), 0L);
-
-    return lines + conditions;
-  }
-
-  @Override
-  protected long countCoveredElements(DecoratorContext context) {
-    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_LINES), 0L);
-    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER), 0L);
-    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS), 0L);
-    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER), 0L);
-
-    return lines + conditions - uncoveredConditions - uncoveredLines;
-  }
-
-  @Override
-  protected Metric getGeneratedMetricForNewCode() {
-    return CoreMetrics.NEW_OVERALL_COVERAGE;
-  }
-
-  @Override
-  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
-    Long newLinesToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_LINES_TO_COVER), periodIndex);
-    if (newLinesToCover == null) {
-      return null;
-    }
-
-    long newConditionsToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER), periodIndex, 0L);
-
-    return newLinesToCover + newConditionsToCover;
-  }
-
-  @Override
-  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
-    long newLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_LINES_TO_COVER), periodIndex, 0L);
-    long newUncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES), periodIndex, 0L);
-    long newUncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS), periodIndex, 0L);
-    long newConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER), periodIndex, 0L);
-
-    return newLines + newConditions - newUncoveredConditions - newUncoveredLines;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/OverallLineCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/OverallLineCoverageDecorator.java
deleted file mode 100644 (file)
index c6f53a2..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import com.google.common.collect.ImmutableList;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-
-import java.util.List;
-
-public final class OverallLineCoverageDecorator extends AbstractCoverageDecorator {
-
-  @DependsUpon
-  public List<Metric> dependsUponMetrics() {
-    return ImmutableList.<Metric>of(CoreMetrics.OVERALL_UNCOVERED_LINES, CoreMetrics.OVERALL_LINES_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES,
-      CoreMetrics.NEW_OVERALL_LINES_TO_COVER);
-  }
-
-  @Override
-  protected Metric getGeneratedMetric() {
-    return CoreMetrics.OVERALL_LINE_COVERAGE;
-  }
-
-  @Override
-  protected Long countElements(DecoratorContext context) {
-    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER), 0L);
-  }
-
-  @Override
-  protected long countCoveredElements(DecoratorContext context) {
-    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_LINES), 0L);
-    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER), 0L);
-
-    return lines - uncoveredLines;
-  }
-
-  @Override
-  protected Metric getGeneratedMetricForNewCode() {
-    return CoreMetrics.NEW_OVERALL_LINE_COVERAGE;
-  }
-
-  @Override
-  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
-    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_LINES_TO_COVER), periodIndex);
-  }
-
-  @Override
-  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
-    long uncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES), periodIndex, 0L);
-    long lines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_LINES_TO_COVER), periodIndex, 0L);
-
-    return lines - uncoveredLines;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/UnitTestDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/UnitTestDecorator.java
deleted file mode 100644 (file)
index 7e4680f..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-public class UnitTestDecorator implements Decorator {
-
-  @DependedUpon
-  public List<Metric> generatesMetrics() {
-    return Arrays.<Metric>asList(CoreMetrics.TEST_EXECUTION_TIME, CoreMetrics.TESTS, CoreMetrics.TEST_ERRORS, CoreMetrics.TEST_FAILURES, CoreMetrics.TEST_SUCCESS_DENSITY);
-  }
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return !Project.AnalysisType.STATIC.equals(project.getAnalysisType());
-  }
-
-  public boolean shouldDecorateResource(Resource resource) {
-    return ResourceUtils.isUnitTestFile(resource) || !ResourceUtils.isEntity(resource);
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    if (shouldDecorateResource(resource)) {
-      sumChildren(context, CoreMetrics.TEST_EXECUTION_TIME);
-      sumChildren(context, CoreMetrics.SKIPPED_TESTS);
-      Double tests = sumChildren(context, CoreMetrics.TESTS);
-      Double errors = sumChildren(context, CoreMetrics.TEST_ERRORS);
-      Double failures = sumChildren(context, CoreMetrics.TEST_FAILURES);
-
-      if (isPositive(tests, true) && isPositive(errors, false) && isPositive(failures, false)) {
-        Double errorsAndFailuresRatio = (errors + failures) * 100.0 / tests;
-        context.saveMeasure(CoreMetrics.TEST_SUCCESS_DENSITY, 100.0 - errorsAndFailuresRatio);
-      }
-    }
-  }
-
-  private boolean isPositive(Double d, boolean strict) {
-    return d != null && (strict ? d > 0.0 : d >= 0.0);
-  }
-
-  private Double sumChildren(DecoratorContext jobContext, Metric metric) {
-    Collection<Measure> childrenMeasures = jobContext.getChildrenMeasures(metric);
-    if (childrenMeasures != null && !childrenMeasures.isEmpty()) {
-      Double sum = 0.0;
-      boolean hasChildrenMeasures = false;
-      for (Measure measure : childrenMeasures) {
-        if (MeasureUtils.hasValue(measure)) {
-          sum += measure.getValue();
-          hasChildrenMeasures = true;
-        }
-      }
-      if (hasChildrenMeasures) {
-        jobContext.saveMeasure(metric, sum);
-        return sum;
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public String toString() {
-    return getClass().getSimpleName();
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java
deleted file mode 100644 (file)
index 35d8a35..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.commons.lang.ObjectUtils;
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorBarriers;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.batch.RequiresDB;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.batch.components.Period;
-import org.sonar.batch.components.TimeMachineConfiguration;
-import org.sonar.batch.index.BatchComponentCache;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.batch.protocol.output.BatchReport.Changesets.Changeset;
-import org.sonar.batch.protocol.output.BatchReportReader;
-import org.sonar.batch.report.ReportPublisher;
-
-import javax.annotation.Nullable;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @since 2.7
- */
-@RequiresDB
-@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE)
-public abstract class AbstractNewCoverageFileAnalyzer implements Decorator {
-
-  private final List<PeriodStruct> structs;
-  private final ReportPublisher publishReportJob;
-  private final BatchComponentCache resourceCache;
-
-  public AbstractNewCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
-    this(Lists.<PeriodStruct>newArrayList(), publishReportJob, resourceCache);
-    for (Period period : timeMachineConfiguration.periods()) {
-      structs.add(new PeriodStruct(period.getIndex(), period.getDate()));
-    }
-  }
-
-  AbstractNewCoverageFileAnalyzer(List<PeriodStruct> structs, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
-    this.resourceCache = resourceCache;
-    this.publishReportJob = publishReportJob;
-    this.structs = structs;
-  }
-
-  public abstract Metric getCoverageLineHitsDataMetric();
-
-  public abstract Metric getConditionsByLineMetric();
-
-  public abstract Metric getCoveredConditionsByLineMetric();
-
-  public abstract Metric getNewLinesToCoverMetric();
-
-  public abstract Metric getNewUncoveredLinesMetric();
-
-  public abstract Metric getNewConditionsToCoverMetric();
-
-  public abstract Metric getNewUncoveredConditionsMetric();
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return !structs.isEmpty();
-  }
-
-  private boolean shouldDecorate(Resource resource) {
-    return Scopes.isFile(resource) && !Qualifiers.UNIT_TEST_FILE.equals(resource.getQualifier());
-  }
-
-  @DependsUpon
-  public List<Metric> dependsOnMetrics() {
-
-    return Arrays.asList(getCoverageLineHitsDataMetric(), getConditionsByLineMetric(), getCoveredConditionsByLineMetric());
-  }
-
-  @DependedUpon
-  public List<Metric> generatesNewCoverageMetrics() {
-    return Arrays.asList(getNewLinesToCoverMetric(), getNewUncoveredLinesMetric(), getNewConditionsToCoverMetric(), getNewUncoveredConditionsMetric());
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    if (shouldDecorate(resource)) {
-      doDecorate(context);
-    }
-  }
-
-  void doDecorate(DecoratorContext context) {
-    if (parse(context)) {
-      compute(context);
-    }
-  }
-
-  private boolean parse(DecoratorContext context) {
-    BatchReportReader reader = new BatchReportReader(publishReportJob.getReportDir());
-    BatchReport.Changesets componentScm = reader.readChangesets(resourceCache.get(context.getResource()).batchId());
-    Measure hitsByLineMeasure = context.getMeasure(getCoverageLineHitsDataMetric());
-
-    if (componentScm != null && hitsByLineMeasure != null && hitsByLineMeasure.hasData()) {
-      Map<Integer, Integer> hitsByLine = parseCountByLine(hitsByLineMeasure);
-      Map<Integer, Integer> conditionsByLine = parseCountByLine(context.getMeasure(getConditionsByLineMetric()));
-      Map<Integer, Integer> coveredConditionsByLine = parseCountByLine(context.getMeasure(getCoveredConditionsByLineMetric()));
-
-      reset();
-
-      for (Map.Entry<Integer, Integer> entry : hitsByLine.entrySet()) {
-        int lineId = entry.getKey();
-        int hits = entry.getValue();
-        int conditions = (Integer) ObjectUtils.defaultIfNull(conditionsByLine.get(lineId), 0);
-        int coveredConditions = (Integer) ObjectUtils.defaultIfNull(coveredConditionsByLine.get(lineId), 0);
-        Changeset changeset = componentScm.getChangeset(componentScm.getChangesetIndexByLine(lineId - 1));
-        Date date = changeset.hasDate() ? new Date(changeset.getDate()) : null;
-        for (PeriodStruct struct : structs) {
-          struct.analyze(date, hits, conditions, coveredConditions);
-        }
-      }
-
-      return true;
-    }
-    return false;
-  }
-
-  private void reset() {
-    for (PeriodStruct struct : structs) {
-      struct.reset();
-    }
-  }
-
-  private void compute(DecoratorContext context) {
-    Measure newLines = new Measure(getNewLinesToCoverMetric());
-    Measure newUncoveredLines = new Measure(getNewUncoveredLinesMetric());
-    Measure newConditions = new Measure(getNewConditionsToCoverMetric());
-    Measure newUncoveredConditions = new Measure(getNewUncoveredConditionsMetric());
-
-    for (PeriodStruct struct : structs) {
-      if (struct.hasNewCode()) {
-        newLines.setVariation(struct.index, (double) struct.getNewLines());
-        newUncoveredLines.setVariation(struct.index, (double) (struct.getNewLines() - struct.getNewCoveredLines()));
-        newConditions.setVariation(struct.index, (double) struct.getNewConditions());
-        newUncoveredConditions.setVariation(struct.index, (double) struct.getNewConditions() - struct.getNewCoveredConditions());
-      }
-    }
-
-    context.saveMeasure(newLines);
-    context.saveMeasure(newUncoveredLines);
-    context.saveMeasure(newConditions);
-    context.saveMeasure(newUncoveredConditions);
-  }
-
-  private Map<Integer, Integer> parseCountByLine(@Nullable Measure measure) {
-    if (measure != null && measure.hasData()) {
-      return KeyValueFormat.parseIntInt(measure.getData());
-    }
-    return Maps.newHashMap();
-  }
-
-  public static final class PeriodStruct {
-    int index;
-    Date date;
-    Integer newLines;
-    Integer newCoveredLines;
-    Integer newConditions;
-    Integer newCoveredConditions;
-
-    PeriodStruct(int index, @Nullable Date date) {
-      this.index = index;
-      this.date = date;
-    }
-
-    void reset() {
-      newLines = null;
-      newCoveredLines = null;
-      newConditions = null;
-      newCoveredConditions = null;
-    }
-
-    void analyze(@Nullable Date lineDate, int hits, int conditions, int coveredConditions) {
-      if (lineDate == null) {
-        // TODO warning
-
-      } else if (date == null || lineDate.after(date)) {
-        // TODO test if string comparison is faster or not
-        addLine(hits > 0);
-        addConditions(conditions, coveredConditions);
-      }
-    }
-
-    void addLine(boolean covered) {
-      if (newLines == null) {
-        newLines = 0;
-      }
-      newLines += 1;
-      if (covered) {
-        if (newCoveredLines == null) {
-          newCoveredLines = 0;
-        }
-        newCoveredLines += 1;
-      }
-    }
-
-    void addConditions(int count, int countCovered) {
-      if (newConditions == null) {
-        newConditions = 0;
-      }
-      newConditions += count;
-      if (count > 0) {
-        if (newCoveredConditions == null) {
-          newCoveredConditions = 0;
-        }
-        newCoveredConditions += countCovered;
-      }
-    }
-
-    boolean hasNewCode() {
-      return newLines != null;
-    }
-
-    public int getNewLines() {
-      return newLines != null ? newLines : 0;
-    }
-
-    public int getNewCoveredLines() {
-      return newCoveredLines != null ? newCoveredLines : 0;
-    }
-
-    public int getNewConditions() {
-      return newConditions != null ? newConditions : 0;
-    }
-
-    public int getNewCoveredConditions() {
-      return newCoveredConditions != null ? newCoveredConditions : 0;
-    }
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java
deleted file mode 100644 (file)
index 70735e6..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import org.apache.commons.lang.ArrayUtils;
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorBarriers;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.Scopes;
-
-import java.util.Arrays;
-import java.util.List;
-
-@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE)
-public final class NewCoverageAggregator implements Decorator {
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  @DependedUpon
-  public List<Metric> generatesNewCoverageMetrics() {
-    return Arrays.<Metric>asList(
-      CoreMetrics.NEW_LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS,
-      CoreMetrics.NEW_IT_LINES_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS,
-      CoreMetrics.NEW_OVERALL_LINES_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES, CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS);
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    if (shouldDecorate(resource)) {
-      int maxPeriods = Qualifiers.isView(resource, true) ? 3 : 5;
-      aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_UNCOVERED_LINES, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_CONDITIONS_TO_COVER, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_UNCOVERED_CONDITIONS, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_IT_LINES_TO_COVER, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_IT_UNCOVERED_LINES, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_OVERALL_LINES_TO_COVER, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER, maxPeriods);
-      aggregate(context, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS, maxPeriods);
-    }
-  }
-
-  void aggregate(DecoratorContext context, Metric metric, int maxPeriods) {
-    int[] variations = {0, 0, 0, 0, 0};
-    boolean[] hasValues = {false, false, false, false, false};
-    for (Measure child : context.getChildrenMeasures(metric)) {
-      for (int indexPeriod = 1; indexPeriod <= maxPeriods; indexPeriod++) {
-        Double variation = child.getVariation(indexPeriod);
-        if (variation != null) {
-          variations[indexPeriod - 1] = variations[indexPeriod - 1] + variation.intValue();
-          hasValues[indexPeriod - 1] = true;
-        }
-      }
-    }
-
-    if (ArrayUtils.contains(hasValues, true)) {
-      Measure measure = new Measure(metric);
-      for (int index = 0; index < 5; index++) {
-        if (hasValues[index]) {
-          measure.setVariation(index + 1, (double) variations[index]);
-        }
-      }
-      context.saveMeasure(measure);
-    }
-  }
-
-  boolean shouldDecorate(Resource resource) {
-    return Scopes.isHigherThan(resource, Scopes.FILE);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzer.java
deleted file mode 100644 (file)
index 79f0289..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-import org.sonar.batch.components.TimeMachineConfiguration;
-import org.sonar.batch.index.BatchComponentCache;
-import org.sonar.batch.report.ReportPublisher;
-
-import java.util.List;
-
-public class NewCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {
-
-  public NewCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
-    super(timeMachineConfiguration, publishReportJob, resourceCache);
-  }
-
-  NewCoverageFileAnalyzer(List<PeriodStruct> structs, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
-    super(structs, publishReportJob, resourceCache);
-  }
-
-  @Override
-  public Metric getCoverageLineHitsDataMetric() {
-    return CoreMetrics.COVERAGE_LINE_HITS_DATA;
-  }
-
-  @Override
-  public Metric getConditionsByLineMetric() {
-    return CoreMetrics.CONDITIONS_BY_LINE;
-  }
-
-  @Override
-  public Metric getCoveredConditionsByLineMetric() {
-    return CoreMetrics.COVERED_CONDITIONS_BY_LINE;
-  }
-
-  @Override
-  public Metric getNewLinesToCoverMetric() {
-    return CoreMetrics.NEW_LINES_TO_COVER;
-  }
-
-  @Override
-  public Metric getNewUncoveredLinesMetric() {
-    return CoreMetrics.NEW_UNCOVERED_LINES;
-  }
-
-  @Override
-  public Metric getNewConditionsToCoverMetric() {
-    return CoreMetrics.NEW_CONDITIONS_TO_COVER;
-  }
-
-  @Override
-  public Metric getNewUncoveredConditionsMetric() {
-    return CoreMetrics.NEW_UNCOVERED_CONDITIONS;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewItCoverageFileAnalyzer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewItCoverageFileAnalyzer.java
deleted file mode 100644 (file)
index 2aacf34..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-import org.sonar.batch.components.TimeMachineConfiguration;
-import org.sonar.batch.index.BatchComponentCache;
-import org.sonar.batch.report.ReportPublisher;
-
-public class NewItCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {
-
-  public NewItCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
-    super(timeMachineConfiguration, publishReportJob, resourceCache);
-  }
-
-  @Override
-  public Metric getCoverageLineHitsDataMetric() {
-    return CoreMetrics.IT_COVERAGE_LINE_HITS_DATA;
-  }
-
-  @Override
-  public Metric getConditionsByLineMetric() {
-    return CoreMetrics.IT_CONDITIONS_BY_LINE;
-  }
-
-  @Override
-  public Metric getCoveredConditionsByLineMetric() {
-    return CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE;
-  }
-
-  @Override
-  public Metric getNewLinesToCoverMetric() {
-    return CoreMetrics.NEW_IT_LINES_TO_COVER;
-  }
-
-  @Override
-  public Metric getNewUncoveredLinesMetric() {
-    return CoreMetrics.NEW_IT_UNCOVERED_LINES;
-  }
-
-  @Override
-  public Metric getNewConditionsToCoverMetric() {
-    return CoreMetrics.NEW_IT_CONDITIONS_TO_COVER;
-  }
-
-  @Override
-  public Metric getNewUncoveredConditionsMetric() {
-    return CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewOverallCoverageFileAnalyzer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewOverallCoverageFileAnalyzer.java
deleted file mode 100644 (file)
index f80da94..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-import org.sonar.batch.components.TimeMachineConfiguration;
-import org.sonar.batch.index.BatchComponentCache;
-import org.sonar.batch.report.ReportPublisher;
-
-public class NewOverallCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {
-
-  public NewOverallCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
-    super(timeMachineConfiguration, publishReportJob, resourceCache);
-  }
-
-  @Override
-  public Metric getCoverageLineHitsDataMetric() {
-    return CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA;
-  }
-
-  @Override
-  public Metric getConditionsByLineMetric() {
-    return CoreMetrics.OVERALL_CONDITIONS_BY_LINE;
-  }
-
-  @Override
-  public Metric getCoveredConditionsByLineMetric() {
-    return CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE;
-  }
-
-  @Override
-  public Metric getNewLinesToCoverMetric() {
-    return CoreMetrics.NEW_OVERALL_LINES_TO_COVER;
-  }
-
-  @Override
-  public Metric getNewUncoveredLinesMetric() {
-    return CoreMetrics.NEW_OVERALL_UNCOVERED_LINES;
-  }
-
-  @Override
-  public Metric getNewConditionsToCoverMetric() {
-    return CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER;
-  }
-
-  @Override
-  public Metric getNewUncoveredConditionsMetric() {
-    return CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java
deleted file mode 100644 (file)
index 7427654..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import org.sonar.api.batch.*;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-import org.sonar.batch.components.PastSnapshot;
-import org.sonar.batch.components.TimeMachineConfiguration;
-import org.sonar.batch.index.BatchComponentCache;
-
-import java.util.List;
-
-import static org.sonar.api.utils.DateUtils.dateToLong;
-
-@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE)
-@RequiresDB
-public final class TimeMachineConfigurationPersister implements Decorator {
-
-  private final TimeMachineConfiguration timeMachineConfiguration;
-  private BatchComponentCache resourceCache;
-  private DatabaseSession session;
-
-  public TimeMachineConfigurationPersister(TimeMachineConfiguration timeMachineConfiguration, BatchComponentCache resourceCache, DatabaseSession session) {
-    this.timeMachineConfiguration = timeMachineConfiguration;
-    this.resourceCache = resourceCache;
-    this.session = session;
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    if (ResourceUtils.isProject(resource)) {
-      persistConfiguration(resource);
-    }
-  }
-
-  void persistConfiguration(Resource module) {
-    List<PastSnapshot> pastSnapshots = timeMachineConfiguration.getProjectPastSnapshots();
-    Snapshot projectSnapshot = resourceCache.get(module).snapshot();
-    for (PastSnapshot pastSnapshot : pastSnapshots) {
-      Snapshot snapshot = session.reattach(Snapshot.class, projectSnapshot.getId());
-      updatePeriodParams(snapshot, pastSnapshot);
-      updatePeriodParams(projectSnapshot, pastSnapshot);
-      session.save(snapshot);
-    }
-    session.commit();
-  }
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  private void updatePeriodParams(Snapshot snapshot, PastSnapshot pastSnapshot) {
-    int periodIndex = pastSnapshot.getIndex();
-    snapshot.setPeriodMode(periodIndex, pastSnapshot.getMode());
-    snapshot.setPeriodModeParameter(periodIndex, pastSnapshot.getModeParameter());
-    snapshot.setPeriodDateMs(periodIndex, dateToLong(pastSnapshot.getDate()));
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java
deleted file mode 100644 (file)
index 36e525e..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import com.google.common.collect.Maps;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.batch.*;
-import org.sonar.api.measures.*;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.technicaldebt.batch.Characteristic;
-import org.sonar.batch.components.PastMeasuresLoader;
-import org.sonar.batch.components.PastSnapshot;
-import org.sonar.batch.components.TimeMachineConfiguration;
-
-import javax.annotation.Nullable;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE)
-@RequiresDB
-public class VariationDecorator implements Decorator {
-
-  private List<PastSnapshot> projectPastSnapshots;
-  private MetricFinder metricFinder;
-  private PastMeasuresLoader pastMeasuresLoader;
-  private RuleFinder ruleFinder;
-
-  public VariationDecorator(PastMeasuresLoader pastMeasuresLoader, MetricFinder metricFinder, TimeMachineConfiguration timeMachineConfiguration, RuleFinder ruleFinder) {
-    this(pastMeasuresLoader, metricFinder, timeMachineConfiguration.getProjectPastSnapshots(), ruleFinder);
-  }
-
-  VariationDecorator(PastMeasuresLoader pastMeasuresLoader, MetricFinder metricFinder, List<PastSnapshot> projectPastSnapshots, RuleFinder ruleFinder) {
-    this.pastMeasuresLoader = pastMeasuresLoader;
-    this.projectPastSnapshots = projectPastSnapshots;
-    this.metricFinder = metricFinder;
-    this.ruleFinder = ruleFinder;
-  }
-
-  @Override
-  public boolean shouldExecuteOnProject(Project project) {
-    return true;
-  }
-
-  @DependsUpon
-  public Collection<Metric> dependsUponMetrics() {
-    return pastMeasuresLoader.getMetrics();
-  }
-
-  @Override
-  public void decorate(Resource resource, DecoratorContext context) {
-    for (PastSnapshot projectPastSnapshot : projectPastSnapshots) {
-      if (shouldComputeVariation(resource)) {
-        computeVariation(resource, context, projectPastSnapshot);
-      }
-    }
-  }
-
-  boolean shouldComputeVariation(Resource resource) {
-    if (Scopes.FILE.equals(resource.getScope()) && !Qualifiers.UNIT_TEST_FILE.equals(resource.getQualifier())) {
-      return false;
-    }
-
-    // measures on files are currently purged, so past measures are not available on files
-    return StringUtils.equals(Scopes.PROJECT, resource.getScope()) || StringUtils.equals(Scopes.DIRECTORY, resource.getScope());
-  }
-
-  private void computeVariation(Resource resource, DecoratorContext context, PastSnapshot pastSnapshot) {
-    List<Object[]> pastMeasures = pastMeasuresLoader.getPastMeasures(resource, pastSnapshot);
-    compareWithPastMeasures(context, pastSnapshot.getIndex(), pastMeasures);
-  }
-
-  private void compareWithPastMeasures(DecoratorContext context, int index, List<Object[]> pastMeasures) {
-    Map<MeasureKey, Object[]> pastMeasuresByKey = Maps.newHashMap();
-    for (Object[] pastMeasure : pastMeasures) {
-      pastMeasuresByKey.put(new MeasureKey(pastMeasure), pastMeasure);
-    }
-
-    // for each measure, search equivalent past measure
-    for (Measure measure : context.getMeasures(MeasuresFilters.all())) {
-      // compare with past measure
-      Integer metricId = measure.getMetric().getId();
-      if (metricId == null) {
-        Metric metric = metricFinder.findByKey(measure.getMetric().getKey());
-        if (metric == null) {
-          throw new IllegalStateException("Unknow metric with key: " + measure.getMetric().getKey());
-        }
-        metricId = metric.getId();
-      }
-      Characteristic characteristic = measure.getCharacteristic();
-      Integer characteristicId = characteristic != null ? characteristic.id() : null;
-      Integer personId = measure.getPersonId();
-      Integer ruleId = null;
-      if (measure instanceof RuleMeasure) {
-        Rule rule = ruleFinder.findByKey(((RuleMeasure) measure).ruleKey());
-        if (rule != null) {
-          ruleId = rule.getId();
-        }
-      }
-
-      Object[] pastMeasure = pastMeasuresByKey.get(new MeasureKey(metricId, characteristicId, personId, ruleId));
-      if (updateVariation(measure, pastMeasure, index)) {
-        context.saveMeasure(measure);
-      }
-    }
-  }
-
-  boolean updateVariation(Measure measure, Object[] pastMeasure, int index) {
-    if (pastMeasure != null && PastMeasuresLoader.hasValue(pastMeasure) && measure.getValue() != null) {
-      double variation = measure.getValue() - PastMeasuresLoader.getValue(pastMeasure);
-      measure.setVariation(index, variation);
-      return true;
-    }
-    return false;
-  }
-
-  @Override
-  public String toString() {
-    return getClass().getSimpleName();
-  }
-
-  static final class MeasureKey {
-    int metricId;
-    Integer characteristicId;
-    Integer personId;
-    Integer ruleId;
-
-    MeasureKey(Object[] pastFields) {
-      metricId = PastMeasuresLoader.getMetricId(pastFields);
-      characteristicId = PastMeasuresLoader.getCharacteristicId(pastFields);
-      personId = PastMeasuresLoader.getPersonId(pastFields);
-      ruleId = PastMeasuresLoader.getRuleId(pastFields);
-    }
-
-    MeasureKey(int metricId, @Nullable Integer characteristicId, @Nullable Integer personId, @Nullable Integer ruleId) {
-      this.metricId = metricId;
-      this.characteristicId = characteristicId;
-      this.personId = personId;
-      this.ruleId = ruleId;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (this == o) {
-        return true;
-      }
-      if (o == null || getClass() != o.getClass()) {
-        return false;
-      }
-      MeasureKey that = (MeasureKey) o;
-      if (metricId != that.metricId) {
-        return false;
-      }
-      if (characteristicId != null ? !characteristicId.equals(that.characteristicId) : that.characteristicId != null) {
-        return false;
-      }
-      if (personId != null ? !personId.equals(that.personId) : that.personId != null) {
-        return false;
-      }
-      if (ruleId != null ? !ruleId.equals(that.ruleId) : that.ruleId != null) {
-        return false;
-      }
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      int result = metricId;
-      result = 31 * result + (characteristicId != null ? characteristicId.hashCode() : 0);
-      result = 31 * result + (personId != null ? personId.hashCode() : 0);
-      result = 31 * result + (ruleId != null ? ruleId.hashCode() : 0);
-      return result;
-    }
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/package-info.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/package-info.java
deleted file mode 100644 (file)
index 8d487ae..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.plugins.core.timemachine;
-
-import javax.annotation.ParametersAreNonnullByDefault;
index 0e312383c2cfb4b12e9e8fa5dec57e8e26e90559..f21fb3bbaca4b7234673f6b062bec219f084f876 100644 (file)
@@ -26,6 +26,6 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class CorePluginTest {
   @Test
   public void should_define_extensions() {
-    assertThat(new CorePlugin().getExtensions().size()).isGreaterThan(10);
+    assertThat(new CorePlugin().getExtensions().size()).isGreaterThan(2);
   }
 }
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/CountFalsePositivesDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/CountFalsePositivesDecoratorTest.java
deleted file mode 100644 (file)
index 28327ac..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.issue;
-
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.issue.Issuable;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.java.api.JavaClass;
-
-import java.util.Arrays;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class CountFalsePositivesDecoratorTest {
-
-  ResourcePerspectives perspectives = mock(ResourcePerspectives.class);
-  CountFalsePositivesDecorator decorator = new CountFalsePositivesDecorator(perspectives);
-
-  @Test
-  public void should_count_false_positives() {
-    DefaultIssue falsePositive = new DefaultIssue().setRuleKey(RuleKey.parse("squid:AvoidCycles"))
-      .setResolution(Issue.RESOLUTION_FALSE_POSITIVE).setStatus(Issue.STATUS_RESOLVED);
-    DefaultIssue fixed = new DefaultIssue().setRuleKey(RuleKey.parse("squid:AvoidCycles"))
-      .setResolution(Issue.RESOLUTION_FIXED).setStatus(Issue.STATUS_RESOLVED);
-
-    File file = File.create("foo.c");
-    Issuable issuable = mock(Issuable.class);
-    when(perspectives.as(Issuable.class, file)).thenReturn(issuable);
-    when(issuable.resolvedIssues()).thenReturn(Arrays.<Issue>asList(falsePositive, fixed));
-
-    DecoratorContext context = mock(DecoratorContext.class);
-    decorator.decorate(file, context);
-
-    verify(context).saveMeasure(CoreMetrics.FALSE_POSITIVE_ISSUES, 1.0);
-  }
-
-  @Test
-  public void should_declare_metadata() {
-    assertThat(decorator.shouldExecuteOnProject(new Project("foo"))).isTrue();
-    assertThat(decorator.generatesFalsePositiveMeasure()).isEqualTo(CoreMetrics.FALSE_POSITIVE_ISSUES);
-    assertThat(decorator.toString()).isEqualTo("CountFalsePositivesDecorator");
-  }
-
-  @Test
-  public void should_ignore_classes_and_methods() {
-    JavaClass javaClass = JavaClass.create("Foo.java");
-    when(perspectives.as(Issuable.class, javaClass)).thenReturn(null);
-
-    DecoratorContext context = mock(DecoratorContext.class);
-    decorator.decorate(javaClass, context);
-
-    verifyZeroInteractions(context);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecoratorTest.java
deleted file mode 100644 (file)
index ebd2b99..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.issue;
-
-import org.sonar.batch.components.Period;
-
-import org.sonar.batch.components.TimeMachineConfiguration;
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.commons.lang.time.DateUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.issue.Issuable;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.measures.*;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.Severity;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RulePriority;
-import org.sonar.api.test.IsRuleMeasure;
-
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.*;
-
-public class CountUnresolvedIssuesDecoratorTest {
-
-  CountUnresolvedIssuesDecorator decorator;
-  TimeMachineConfiguration timeMachineConfiguration;
-  Issuable issuable;
-  DecoratorContext context;
-  Resource resource;
-  Project project;
-  Rule ruleA1;
-  Rule ruleA2;
-  Rule ruleB1;
-  Date rightNow;
-  Date tenDaysAgo;
-  Date afterTenDaysAgo;
-  Date fiveDaysAgo;
-  Date afterFiveDaysAgo;
-  Date sameSecond;
-
-  @Before
-  public void before() {
-    ruleA1 = Rule.create().setRepositoryKey("ruleA1").setKey("ruleA1").setName("nameA1");
-    ruleA2 = Rule.create().setRepositoryKey("ruleA2").setKey("ruleA2").setName("nameA2");
-    ruleB1 = Rule.create().setRepositoryKey("ruleB1").setKey("ruleB1").setName("nameB1");
-
-    rightNow = new Date();
-    tenDaysAgo = DateUtils.addDays(rightNow, -10);
-    afterTenDaysAgo = DateUtils.addDays(tenDaysAgo, 1);
-    fiveDaysAgo = DateUtils.addDays(rightNow, -5);
-    afterFiveDaysAgo = DateUtils.addDays(fiveDaysAgo, 1);
-    sameSecond = DateUtils.truncate(rightNow, Calendar.SECOND);
-
-    timeMachineConfiguration = mock(TimeMachineConfiguration.class);
-    when(timeMachineConfiguration.periods()).thenReturn(newArrayList(new Period(1, afterFiveDaysAgo), new Period(2, afterTenDaysAgo)));
-
-    project = mock(Project.class);
-    resource = mock(Resource.class);
-    context = mock(DecoratorContext.class);
-    when(context.getResource()).thenReturn(resource);
-    when(context.getProject()).thenReturn(project);
-    when(context.getMeasure(CoreMetrics.NEW_VIOLATIONS)).thenReturn(null);
-
-    issuable = mock(Issuable.class);
-    ResourcePerspectives perspectives = mock(ResourcePerspectives.class);
-    when(perspectives.as(Issuable.class, resource)).thenReturn(issuable);
-    decorator = new CountUnresolvedIssuesDecorator(perspectives, timeMachineConfiguration);
-  }
-
-  @Test
-  public void should_be_depended_upon_metric() {
-    assertThat(decorator.generatesIssuesMetrics()).hasSize(15);
-  }
-
-  @Test
-  public void should_count_issues() {
-    when(resource.getScope()).thenReturn(Scopes.PROJECT);
-    when(issuable.issues()).thenReturn(createIssues());
-    when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Collections.<Measure>emptyList());
-
-    decorator.decorate(resource, context);
-
-    verify(context).saveMeasure(CoreMetrics.VIOLATIONS, 4.0);
-  }
-
-  @Test
-  public void should_do_nothing_when_issuable_is_null() {
-    ResourcePerspectives perspectives = mock(ResourcePerspectives.class);
-    when(perspectives.as(Issuable.class, resource)).thenReturn(null);
-    CountUnresolvedIssuesDecorator decorator = new CountUnresolvedIssuesDecorator(perspectives, timeMachineConfiguration);
-
-    decorator.decorate(resource, context);
-
-    verifyZeroInteractions(context);
-  }
-
-  /**
-   * See http://jira.codehaus.org/browse/SONAR-1729
-   */
-  @Test
-  public void should_not_count_issues_if_measure_already_exists() {
-    when(resource.getScope()).thenReturn(Scopes.PROJECT);
-    when(issuable.issues()).thenReturn(createIssues());
-    when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Collections.<Measure>emptyList());
-    when(context.getMeasure(CoreMetrics.VIOLATIONS)).thenReturn(new Measure(CoreMetrics.VIOLATIONS, 3000.0));
-    when(context.getMeasure(CoreMetrics.MAJOR_VIOLATIONS)).thenReturn(new Measure(CoreMetrics.MAJOR_VIOLATIONS, 500.0));
-
-    decorator.decorate(resource, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.VIOLATIONS), anyDouble());// not changed
-    verify(context, never()).saveMeasure(eq(CoreMetrics.MAJOR_VIOLATIONS), anyDouble());// not changed
-    verify(context, times(1)).saveMeasure(eq(CoreMetrics.CRITICAL_VIOLATIONS), anyDouble());// did not exist
-  }
-
-  @Test
-  public void should_save_zero_on_projects() {
-    when(resource.getScope()).thenReturn(Scopes.PROJECT);
-    when(issuable.issues()).thenReturn(Lists.<Issue>newArrayList());
-    when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Collections.<Measure>emptyList());
-
-    decorator.decorate(resource, context);
-
-    verify(context).saveMeasure(CoreMetrics.VIOLATIONS, 0.0);
-  }
-
-  @Test
-  public void should_save_zero_on_directories() {
-    when(resource.getScope()).thenReturn(Scopes.DIRECTORY);
-    when(issuable.issues()).thenReturn(Lists.<Issue>newArrayList());
-    when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Collections.<Measure>emptyList());
-
-    decorator.decorate(resource, context);
-
-    verify(context).saveMeasure(CoreMetrics.VIOLATIONS, 0.0);
-  }
-
-  @Test
-  public void should_count_issues_by_severity() {
-    when(resource.getScope()).thenReturn(Scopes.PROJECT);
-    when(issuable.issues()).thenReturn(createIssues());
-    when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Collections.<Measure>emptyList());
-
-    decorator.decorate(resource, context);
-
-    verify(context).saveMeasure(CoreMetrics.BLOCKER_VIOLATIONS, 0.0);
-    verify(context).saveMeasure(CoreMetrics.CRITICAL_VIOLATIONS, 2.0);
-    verify(context).saveMeasure(CoreMetrics.MAJOR_VIOLATIONS, 1.0);
-    verify(context).saveMeasure(CoreMetrics.MINOR_VIOLATIONS, 1.0);
-    verify(context).saveMeasure(CoreMetrics.INFO_VIOLATIONS, 0.0);
-  }
-
-  @Test
-  public void should_count_issues_per_rule() {
-    List<Issue> issues = newArrayList();
-    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()));
-    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()));
-    issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setSeverity(RulePriority.MAJOR.name()));
-    when(issuable.issues()).thenReturn(issues);
-
-    decorator.decorate(resource, context);
-
-    verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.CRITICAL_VIOLATIONS, ruleA1, 2.0)));
-    verify(context, never()).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.MAJOR_VIOLATIONS, ruleA1, 0.0)));
-    verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.MAJOR_VIOLATIONS, ruleA2, 1.0)));
-  }
-
-  @Test
-  public void same_rule_should_have_different_severities() {
-    List<Issue> issues = newArrayList();
-    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()));
-    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()));
-    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.MINOR.name()));
-    when(issuable.issues()).thenReturn(issues);
-
-    decorator.decorate(resource, context);
-
-    verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.CRITICAL_VIOLATIONS, ruleA1, 2.0)));
-    verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.MINOR_VIOLATIONS, ruleA1, 1.0)));
-  }
-
-  @Test
-  public void should_count_issues_after_date() {
-    List<Issue> issues = createIssuesForNewMetrics();
-
-    assertThat(decorator.countIssuesAfterDate(null, fiveDaysAgo)).isEqualTo(0);
-    assertThat(decorator.countIssuesAfterDate(issues, fiveDaysAgo)).isEqualTo(1); // 1 rightNow
-    assertThat(decorator.countIssuesAfterDate(issues, tenDaysAgo)).isEqualTo(3); // 1 rightNow + 2 fiveDaysAgo
-    assertThat(decorator.countIssuesAfterDate(issues, sameSecond)).isEqualTo(0); // 0
-  }
-
-  @Test
-  public void should_clear_cache_after_execution() {
-    Issue issue1 = new DefaultIssue().setRuleKey(RuleKey.of(ruleA1.getRepositoryKey(), ruleA1.getKey())).setSeverity(RulePriority.CRITICAL.name()).setCreationDate(rightNow);
-    Issue issue2 = new DefaultIssue().setRuleKey(RuleKey.of(ruleA2.getRepositoryKey(), ruleA2.getKey())).setSeverity(RulePriority.CRITICAL.name()).setCreationDate(rightNow);
-    when(issuable.issues()).thenReturn(newArrayList(issue1)).thenReturn(newArrayList(issue2));
-
-    decorator.decorate(resource, context);
-    decorator.decorate(resource, context);
-
-    verify(context, times(2)).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 1.0, 1.0)));
-    verify(context, never()).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 2.0, 2.0)));
-  }
-
-  @Test
-  public void should_save_severity_new_issues() {
-    when(issuable.issues()).thenReturn(createIssuesForNewMetrics());
-
-    decorator.decorate(resource, context);
-
-    // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_BLOCKER_VIOLATIONS, 0.0, 0.0)));
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 1.0, 1.0)));
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_MAJOR_VIOLATIONS, 0.0, 1.0)));
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_MINOR_VIOLATIONS, 0.0, 1.0)));
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_INFO_VIOLATIONS, 0.0, 0.0)));
-  }
-
-  @Test
-  public void should_save_rule_new_issues() {
-    when(issuable.issues()).thenReturn(createIssuesForNewMetrics());
-
-    decorator.decorate(resource, context);
-
-    // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS, ruleA1, 1.0, 1.0)));
-    verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_MAJOR_VIOLATIONS, ruleA2, 0.0, 1.0)));
-    verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_MINOR_VIOLATIONS, ruleB1, 0.0, 1.0)));
-  }
-
-  @Test
-  public void should_not_save_new_issues_if_measure_already_computed() {
-    when(context.getMeasure(CoreMetrics.NEW_VIOLATIONS)).thenReturn(new Measure());
-    when(issuable.issues()).thenReturn(createIssuesForNewMetrics());
-
-    decorator.decorate(resource, context);
-
-    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_BLOCKER_VIOLATIONS)));
-    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS)));
-    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_MAJOR_VIOLATIONS)));
-    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_MINOR_VIOLATIONS)));
-    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_INFO_VIOLATIONS)));
-    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS)));
-  }
-
-  List<Issue> createIssues() {
-    List<Issue> issues = newArrayList();
-    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(Severity.CRITICAL).setStatus(Issue.STATUS_OPEN));
-    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(Severity.CRITICAL).setStatus(Issue.STATUS_REOPENED));
-    issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setSeverity(Severity.MAJOR).setStatus(Issue.STATUS_REOPENED));
-    issues.add(new DefaultIssue().setRuleKey(ruleB1.ruleKey()).setSeverity(Severity.MINOR).setStatus(Issue.STATUS_OPEN));
-    return issues;
-  }
-
-  List<Issue> createIssuesForNewMetrics() {
-    List<Issue> issues = newArrayList();
-    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()).setCreationDate(rightNow).setStatus(Issue.STATUS_OPEN));
-    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()).setCreationDate(tenDaysAgo).setStatus(Issue.STATUS_OPEN));
-    issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setSeverity(RulePriority.MAJOR.name()).setCreationDate(fiveDaysAgo).setStatus(Issue.STATUS_REOPENED));
-    issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setSeverity(RulePriority.MAJOR.name()).setCreationDate(tenDaysAgo).setStatus(Issue.STATUS_REOPENED));
-    issues.add(new DefaultIssue().setRuleKey(ruleB1.ruleKey()).setSeverity(RulePriority.MINOR.name()).setCreationDate(fiveDaysAgo).setStatus(Issue.STATUS_OPEN));
-    issues.add(new DefaultIssue().setRuleKey(ruleB1.ruleKey()).setSeverity(RulePriority.MINOR.name()).setCreationDate(tenDaysAgo).setStatus(Issue.STATUS_OPEN));
-    return issues;
-  }
-
-  class IsVariationRuleMeasure extends ArgumentMatcher<Measure> {
-    Metric metric = null;
-    Rule rule = null;
-    Double var1 = null;
-    Double var2 = null;
-
-    public IsVariationRuleMeasure(Metric metric, Rule rule, Double var1, Double var2) {
-      this.metric = metric;
-      this.rule = rule;
-      this.var1 = var1;
-      this.var2 = var2;
-    }
-
-    public boolean matches(Object o) {
-      if (!(o instanceof RuleMeasure)) {
-        return false;
-      }
-      RuleMeasure m = (RuleMeasure) o;
-      return ObjectUtils.equals(metric, m.getMetric()) &&
-        ObjectUtils.equals(rule.ruleKey(), m.ruleKey()) &&
-        ObjectUtils.equals(var1, m.getVariation1()) &&
-        ObjectUtils.equals(var2, m.getVariation2());
-    }
-  }
-
-  class IsVariationMeasure extends ArgumentMatcher<Measure> {
-    Metric metric = null;
-    Double var1 = null;
-    Double var2 = null;
-
-    public IsVariationMeasure(Metric metric, Double var1, Double var2) {
-      this.metric = metric;
-      this.var1 = var1;
-      this.var2 = var2;
-    }
-
-    public boolean matches(Object o) {
-      if (!(o instanceof Measure)) {
-        return false;
-      }
-      Measure m = (Measure) o;
-      return ObjectUtils.equals(metric, m.getMetric()) &&
-        ObjectUtils.equals(var1, m.getVariation1()) &&
-        ObjectUtils.equals(var2, m.getVariation2()) &&
-        !(m instanceof RuleMeasure);
-    }
-  }
-
-  class IsMetricMeasure extends ArgumentMatcher<Measure> {
-    Metric metric = null;
-
-    public IsMetricMeasure(Metric metric) {
-      this.metric = metric;
-    }
-
-    public boolean matches(Object o) {
-      if (!(o instanceof Measure)) {
-        return false;
-      }
-      Measure m = (Measure) o;
-      return ObjectUtils.equals(metric, m.getMetric());
-    }
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/ApplyProjectRolesDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/ApplyProjectRolesDecoratorTest.java
deleted file mode 100644 (file)
index dd55186..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.security;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.resources.Project;
-import org.sonar.api.security.ResourcePermissions;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.*;
-
-public class ApplyProjectRolesDecoratorTest {
-
-  private ResourcePermissions resourcePermissions;
-  private ApplyProjectRolesDecorator decorator;
-
-  @Before
-  public void init() {
-    resourcePermissions = mock(ResourcePermissions.class);
-    decorator = new ApplyProjectRolesDecorator(resourcePermissions);
-  }
-
-  @Test
-  public void alwaysExecute() {
-    assertThat(decorator.shouldExecuteOnProject(new Project("project"))).isTrue();
-  }
-
-  @Test
-  public void doNotGrantDefaultRolesWhenExistingPermissions() {
-    Project project = new Project("project");
-    project.setId(10);
-    when(resourcePermissions.hasRoles(project)).thenReturn(true);
-
-    decorator.decorate(project, null);
-
-    verify(resourcePermissions, never()).grantDefaultRoles(project);
-  }
-
-  @Test
-  public void doNotApplySecurityOnModules() {
-    Project project = new Project("project");
-    Project module = new Project("module").setParent(project);
-    module.setId(10);
-    when(resourcePermissions.hasRoles(project)).thenReturn(false);
-
-    decorator.decorate(module, null);
-
-    verify(resourcePermissions, never()).grantDefaultRoles(module);
-  }
-
-  @Test
-  public void grantDefaultRolesWhenNoPermissions() {
-    Project project = new Project("project");
-    project.setId(10);
-    when(resourcePermissions.hasRoles(project)).thenReturn(false);
-
-    decorator.decorate(project, null);
-
-    verify(resourcePermissions).grantDefaultRoles(project);
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/BranchCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/BranchCoverageDecoratorTest.java
deleted file mode 100644 (file)
index 6c88fb9..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
-
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class BranchCoverageDecoratorTest {
-  private final BranchCoverageDecorator decorator = new BranchCoverageDecorator();
-  private final Project resource = mock(Project.class);
-
-  @Before
-  public void setUp() {
-    when(resource.getScope()).thenReturn(Scopes.PROJECT);
-    when(resource.getQualifier()).thenReturn(Qualifiers.PROJECT);
-  }
-
-  @Test
-  public void shouldSaveBranchCoverage() {
-    DecoratorContext context = mockContext(20, 15);
-
-    decorator.decorate(resource, context);
-
-    verify(context).saveMeasure(CoreMetrics.BRANCH_COVERAGE, 25.0);
-  }
-
-  @Test
-  public void shouldNotSaveBranchCoverageIfMissingConditions() {
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    decorator.decorate(resource, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.BRANCH_COVERAGE), anyDouble());
-  }
-
-  private static DecoratorContext mockContext(int conditions, int uncoveredConditions) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.CONDITIONS_TO_COVER, (double) conditions));
-    when(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, (double) uncoveredConditions));
-    return context;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CommentDensityDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CommentDensityDecoratorTest.java
deleted file mode 100644 (file)
index eae5100..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.test.IsMeasure;
-
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class CommentDensityDecoratorTest {
-
-  @Test
-  public void densityIsBalancedByNcloc() {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 300.0));
-    when(context.getMeasure(CoreMetrics.COMMENT_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 200.0));
-    CommentDensityDecorator decorator = new CommentDensityDecorator();
-    decorator.decorate(null, context);
-    // 200 / (200 + 300) = 40%
-    verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY, 40.0)));
-  }
-
-  @Test
-  public void noDensityIfUnknownComments() {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 300.0));
-    CommentDensityDecorator decorator = new CommentDensityDecorator();
-    decorator.decorate(null, context);
-    verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY)));
-  }
-
-  @Test
-  public void noDensityIfZeroNcloc() {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 0.0));
-    when(context.getMeasure(CoreMetrics.COMMENT_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 0.0));
-    CommentDensityDecorator decorator = new CommentDensityDecorator();
-    decorator.decorate(null, context);
-    verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY)));
-  }
-
-  @Test
-  public void zeroDensityWhenZeroComments() {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 40.0));
-    when(context.getMeasure(CoreMetrics.COMMENT_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 0.0));
-    CommentDensityDecorator decorator = new CommentDensityDecorator();
-    decorator.decorate(null, context);
-    verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY, 0.0)));
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageDecoratorTest.java
deleted file mode 100644 (file)
index 0404cde..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Scopes;
-
-import java.util.Collection;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class CoverageDecoratorTest {
-  private CoverageDecorator decorator;
-  private final Project project = mock(Project.class);
-
-  @Before
-  public void before() {
-    when(project.getScope()).thenReturn(Scopes.PROJECT);
-    decorator = new CoverageDecorator();
-  }
-
-  @Test
-  public void should_use_metrics() {
-    Collection<Metric> metrics = decorator.usedMetrics();
-
-    assertThat(metrics).containsOnly(CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.NEW_LINES_TO_COVER,
-      CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS,
-      CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS);
-  }
-
-  @Test
-  public void coverage() {
-    DecoratorContext context = mockContext(50, 40, 10, 8);
-
-    decorator.decorate(project, context);
-
-    // (50-40 covered lines + 10-8 covered conditions) / (50 lines + 10 conditions)
-    verify(context).saveMeasure(CoreMetrics.COVERAGE, 20.0);
-  }
-
-  @Test
-  public void coverageCanBe0() {
-    DecoratorContext context = mockContext(50, 50, 5, 5);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.COVERAGE, 0.0);
-  }
-
-  @Test
-  public void coverageCanBe100() {
-    DecoratorContext context = mockContext(50, 0, 5, 0);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.COVERAGE, 100.0);
-  }
-
-  @Test
-  public void noCoverageIfNoElements() {
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    decorator.decorate(project, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.COVERAGE), anyDouble());
-  }
-
-  @Test
-  public void should_count_elements_for_new_code() {
-    Measure newLines = measureWithVariation(1, 100.0);
-    Measure newConditions = measureWithVariation(1, 1.0);
-    DecoratorContext context = mockNewContext(newLines, null, null, newConditions);
-
-    long count = decorator.countElementsForNewCode(context, 1);
-
-    assertThat(count).isEqualTo(101).isEqualTo(100 + 1);
-  }
-
-  @Test
-  public void should_count_covered_elements_for_new_code() {
-    Measure newLines = measureWithVariation(1, 100.0);
-    Measure newUncoveredConditions = measureWithVariation(1, 10.0);
-    Measure newUncoveredLines = measureWithVariation(1, 5.0);
-    Measure newConditions = measureWithVariation(1, 1.0);
-    DecoratorContext context = mockNewContext(newLines, newUncoveredConditions, newUncoveredLines, newConditions);
-
-    long count = decorator.countCoveredElementsForNewCode(context, 1);
-
-    assertThat(count).isEqualTo(86).isEqualTo(100 + 1 - 10 - 5);
-  }
-
-  private static DecoratorContext mockContext(int lines, int uncoveredLines, int conditions, int uncoveredConditions) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.LINES_TO_COVER, (double) lines));
-    when(context.getMeasure(CoreMetrics.UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.UNCOVERED_LINES, (double) uncoveredLines));
-    when(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.CONDITIONS_TO_COVER, (double) conditions));
-    when(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, (double) uncoveredConditions));
-    return context;
-  }
-
-  private static DecoratorContext mockNewContext(Measure newLines, Measure newUncoveredConditions, Measure newUncoveredLines, Measure newConditions) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(newLines);
-    when(context.getMeasure(CoreMetrics.NEW_UNCOVERED_LINES)).thenReturn(newUncoveredLines);
-    when(context.getMeasure(CoreMetrics.NEW_UNCOVERED_CONDITIONS)).thenReturn(newUncoveredConditions);
-    when(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER)).thenReturn(newConditions);
-    return context;
-  }
-
-  private static Measure measureWithVariation(int period, double variation) {
-    Measure measure = mock(Measure.class);
-    when(measure.getVariation(period)).thenReturn(variation);
-    return measure;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/DirectoriesDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/DirectoriesDecoratorTest.java
deleted file mode 100644 (file)
index 0152487..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.Directory;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class DirectoriesDecoratorTest {
-
-  @Test
-  public void doNotInsertZeroOnFiles() {
-    DirectoriesDecorator decorator = new DirectoriesDecorator();
-    Resource file = File.create("foo.php");
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    decorator.decorate(file, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.DIRECTORIES), anyDouble());
-  }
-
-  @Test
-  public void directoryCountsForOne() {
-    DirectoriesDecorator decorator = new DirectoriesDecorator();
-    Resource directory = Directory.create("org/foo");
-    DecoratorContext context = mock(DecoratorContext.class);
-    decorator.decorate(directory, context);
-    verify(context).saveMeasure(CoreMetrics.DIRECTORIES, 1.0);
-  }
-
-  @Test
-  public void countProjectDirectories() {
-    DirectoriesDecorator decorator = new DirectoriesDecorator();
-    Resource project = new Project("project");
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    when(context.getChildrenMeasures(CoreMetrics.DIRECTORIES)).thenReturn(Arrays.<Measure>asList(
-      new Measure(CoreMetrics.DIRECTORIES, 1.0),
-      new Measure(CoreMetrics.DIRECTORIES, 1.0),
-      new Measure(CoreMetrics.DIRECTORIES, 1.0)
-      ));
-    decorator.decorate(project, context);
-    verify(context).saveMeasure(CoreMetrics.DIRECTORIES, 3.0);
-  }
-
-  @Test
-  public void noProjectValueWhenOnlyPackages() {
-    DirectoriesDecorator decorator = new DirectoriesDecorator();
-    Resource project = new Project("project");
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getChildrenMeasures(CoreMetrics.DIRECTORIES)).thenReturn(Collections.<Measure>emptyList());
-    when(context.getChildrenMeasures(CoreMetrics.PACKAGES)).thenReturn(Arrays.<Measure>asList(
-      new Measure(CoreMetrics.PACKAGES, 1.0),
-      new Measure(CoreMetrics.PACKAGES, 1.0)
-      ));
-    decorator.decorate(project, context);
-    verify(context, never()).saveMeasure(eq(CoreMetrics.DIRECTORIES), anyDouble());
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FilesDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FilesDecoratorTest.java
deleted file mode 100644 (file)
index 76cb6ab..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-
-import java.util.Arrays;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class FilesDecoratorTest {
-
-  private FilesDecorator decorator;
-
-  @Mock
-  private DecoratorContext context;
-
-  @Mock
-  private Resource resource;
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Before
-  public void setUp() {
-    MockitoAnnotations.initMocks(this);
-
-    decorator = new FilesDecorator();
-  }
-
-  @Test
-  public void generatesMetrics() {
-    assertThat(decorator.generateDirectoriesMetric()).isEqualTo(CoreMetrics.FILES);
-  }
-
-  @Test
-  public void shouldExecute() {
-    assertThat(decorator.shouldExecuteOnProject(mock(Project.class))).isEqualTo(true);
-  }
-
-  @Test
-  public void shouldNotSaveIfMeasureAlreadyExists() {
-    when(context.getMeasure(CoreMetrics.FILES)).thenReturn(new Measure(CoreMetrics.FILES, 1.0));
-
-    decorator.decorate(resource, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.FILES), anyDouble());
-  }
-
-  @Test
-  public void shouldSaveOneForFile() {
-    when(resource.getQualifier()).thenReturn(Qualifiers.FILE);
-
-    decorator.decorate(resource, context);
-
-    verify(context, times(1)).saveMeasure(eq(CoreMetrics.FILES), eq(1d));
-  }
-
-  @Test
-  public void shouldSaveOneForClass() {
-    when(resource.getQualifier()).thenReturn(Qualifiers.CLASS);
-
-    decorator.decorate(resource, context);
-
-    verify(context, times(1)).saveMeasure(eq(CoreMetrics.FILES), eq(1d));
-  }
-
-  @Test
-  public void shouldSumChildren() {
-    when(context.getChildrenMeasures(CoreMetrics.FILES)).thenReturn(Arrays.asList(new Measure(CoreMetrics.FILES, 2.0), new Measure(CoreMetrics.FILES, 3.0)));
-
-    decorator.decorate(resource, context);
-
-    verify(context).saveMeasure(eq(CoreMetrics.FILES), eq(5.0));
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ItBranchCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ItBranchCoverageDecoratorTest.java
deleted file mode 100644 (file)
index 14ba49d..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
-
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class ItBranchCoverageDecoratorTest {
-  private final ItBranchCoverageDecorator decorator = new ItBranchCoverageDecorator();
-  private final Project resource = mock(Project.class);
-
-  @Before
-  public void setUp() {
-    when(resource.getScope()).thenReturn(Scopes.PROJECT);
-    when(resource.getQualifier()).thenReturn(Qualifiers.PROJECT);
-  }
-
-  @Test
-  public void shouldSaveBranchCoverage() {
-    DecoratorContext context = mockContext(20, 15);
-
-    decorator.decorate(resource, context);
-
-    verify(context).saveMeasure(CoreMetrics.IT_BRANCH_COVERAGE, 25.0);
-  }
-
-  @Test
-  public void shouldNotSaveBranchCoverageIfMissingConditions() {
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    decorator.decorate(resource, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.IT_BRANCH_COVERAGE), anyDouble());
-  }
-
-  private static DecoratorContext mockContext(int conditions, int uncoveredConditions) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.IT_CONDITIONS_TO_COVER, (double) conditions));
-    when(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.IT_UNCOVERED_CONDITIONS, (double) uncoveredConditions));
-    return context;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ItCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ItCoverageDecoratorTest.java
deleted file mode 100644 (file)
index 08a8203..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Scopes;
-
-import java.util.Collection;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class ItCoverageDecoratorTest {
-  private final ItCoverageDecorator decorator = new ItCoverageDecorator();
-  private final Project project = mock(Project.class);
-
-  @Before
-  public void before() {
-    when(project.getScope()).thenReturn(Scopes.PROJECT);
-  }
-
-  @Test
-  public void should_use_metrics() {
-    Collection<Metric> metrics = decorator.usedMetrics();
-
-    assertThat(metrics).containsOnly(CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_LINES_TO_COVER,
-      CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.IT_CONDITIONS_TO_COVER, CoreMetrics.IT_UNCOVERED_CONDITIONS,
-      CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS);
-  }
-
-  @Test
-  public void coverage() {
-    DecoratorContext context = mockContext(50, 40, 10, 8);
-
-    decorator.decorate(project, context);
-
-    // (50-40 covered lines + 10-8 covered conditions) / (50 lines + 10 conditions)
-    verify(context).saveMeasure(CoreMetrics.IT_COVERAGE, 20.0);
-  }
-
-  @Test
-  public void coverageCanBe0() {
-    DecoratorContext context = mockContext(50, 50, 5, 5);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.IT_COVERAGE, 0.0);
-  }
-
-  @Test
-  public void coverageCanBe100() {
-    DecoratorContext context = mockContext(50, 0, 5, 0);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.IT_COVERAGE, 100.0);
-  }
-
-  @Test
-  public void noCoverageIfNoElements() {
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    decorator.decorate(project, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.IT_COVERAGE), anyDouble());
-  }
-
-  @Test
-  public void should_count_elements_for_new_code() {
-    Measure newLines = measureWithVariation(1, 100.0);
-    Measure newConditions = measureWithVariation(1, 1.0);
-    DecoratorContext context = mockNewContext(newLines, null, null, newConditions);
-
-    long count = decorator.countElementsForNewCode(context, 1);
-
-    assertThat(count).isEqualTo(101).isEqualTo(100 + 1);
-  }
-
-  @Test
-  public void should_count_covered_elements_for_new_code() {
-    Measure newLines = measureWithVariation(1, 100.0);
-    Measure newUncoveredConditions = measureWithVariation(1, 10.0);
-    Measure newUncoveredLines = measureWithVariation(1, 5.0);
-    Measure newConditions = measureWithVariation(1, 1.0);
-    DecoratorContext context = mockNewContext(newLines, newUncoveredConditions, newUncoveredLines, newConditions);
-
-    long count = decorator.countCoveredElementsForNewCode(context, 1);
-
-    assertThat(count).isEqualTo(86).isEqualTo(100 + 1 - 10 - 5);
-  }
-
-  private static DecoratorContext mockContext(int lines, int uncoveredLines, int conditions, int uncoveredConditions) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.IT_LINES_TO_COVER, (double) lines));
-    when(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.IT_UNCOVERED_LINES, (double) uncoveredLines));
-    when(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.IT_CONDITIONS_TO_COVER, (double) conditions));
-    when(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.IT_UNCOVERED_CONDITIONS, (double) uncoveredConditions));
-    return context;
-  }
-
-  private static DecoratorContext mockNewContext(Measure newLines, Measure newUncoveredConditions, Measure newUncoveredLines, Measure newConditions) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER)).thenReturn(newLines);
-    when(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_LINES)).thenReturn(newUncoveredLines);
-    when(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS)).thenReturn(newUncoveredConditions);
-    when(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER)).thenReturn(newConditions);
-    return context;
-  }
-
-  private static Measure measureWithVariation(int period, double variation) {
-    Measure measure = mock(Measure.class);
-    when(measure.getVariation(period)).thenReturn(variation);
-    return measure;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ItLineCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ItLineCoverageDecoratorTest.java
deleted file mode 100644 (file)
index 976b044..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Scopes;
-
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class ItLineCoverageDecoratorTest {
-  private final ItLineCoverageDecorator decorator = new ItLineCoverageDecorator();
-  private final Project project = mock(Project.class);
-
-  @Before
-  public void before() {
-    when(project.getScope()).thenReturn(Scopes.PROJECT);
-  }
-
-  @Test
-  public void should_depend_on_coverage_metrics() {
-    List<Metric> metrics = decorator.dependsUponMetrics();
-
-    assertThat(metrics).containsOnly(CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_LINES_TO_COVER);
-  }
-
-  @Test
-  public void lineCoverage() {
-    DecoratorContext context = mockContext(50, 10);
-
-    decorator.decorate(project, context);
-
-    // 50-10 covered lines / 50 lines
-    verify(context).saveMeasure(CoreMetrics.IT_LINE_COVERAGE, 80.0);
-  }
-
-  @Test
-  public void zeroCoveredLines() {
-    DecoratorContext context = mockContext(50, 50);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.IT_LINE_COVERAGE, 0.0);
-  }
-
-  @Test
-  public void allCoveredLines() {
-    DecoratorContext context = mockContext(50, 00);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.IT_LINE_COVERAGE, 100.0);
-  }
-
-  @Test
-  public void noLineCoverageIfNoLines() {
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    decorator.decorate(project, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.IT_LINE_COVERAGE), anyDouble());
-  }
-
-  private static DecoratorContext mockContext(int lines, int uncoveredLines) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.IT_LINES_TO_COVER, (double) lines));
-    when(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.IT_UNCOVERED_LINES, (double) uncoveredLines));
-    return context;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/LineCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/LineCoverageDecoratorTest.java
deleted file mode 100644 (file)
index 3381182..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Scopes;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class LineCoverageDecoratorTest {
-
-  private LineCoverageDecorator decorator;
-  private final Project project = mock(Project.class);
-
-  @Before
-  public void before() {
-    when(project.getScope()).thenReturn(Scopes.PROJECT);
-    decorator = new LineCoverageDecorator();
-  }
-
-  @Test
-  public void should_depend_on_coverage_metrics() {
-    assertThat(decorator.dependsUponMetrics()).containsOnly(CoreMetrics.UNCOVERED_LINES, CoreMetrics.LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES,
-      CoreMetrics.NEW_LINES_TO_COVER);
-  }
-
-  @Test
-  public void lineCoverage() {
-    DecoratorContext context = mockContext(50, 10);
-
-    decorator.decorate(project, context);
-
-    // 50-10 covered lines / 50 lines
-    verify(context).saveMeasure(CoreMetrics.LINE_COVERAGE, 80.0);
-  }
-
-  @Test
-  public void zeroCoveredLines() {
-    DecoratorContext context = mockContext(50, 50);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.LINE_COVERAGE, 0.0);
-  }
-
-  @Test
-  public void allCoveredLines() {
-    DecoratorContext context = mockContext(50, 00);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.LINE_COVERAGE, 100.0);
-  }
-
-  @Test
-  public void noLineCoverageIfNoLines() {
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    decorator.decorate(project, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.LINE_COVERAGE), anyDouble());
-  }
-
-  private static DecoratorContext mockContext(int lines, int uncoveredLines) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.LINES_TO_COVER, (double) lines));
-    when(context.getMeasure(CoreMetrics.UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.UNCOVERED_LINES, (double) uncoveredLines));
-    return context;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ManualMeasureDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ManualMeasureDecoratorTest.java
deleted file mode 100644 (file)
index 02793e1..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.File;
-import org.sonar.api.test.IsMeasure;
-import org.sonar.core.metric.DefaultMetricFinder;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class ManualMeasureDecoratorTest extends AbstractDbUnitTestCase {
-
-  private Metric reviewNote = new Metric.Builder("review_note", "Note", Metric.ValueType.FLOAT).create().setId(2);
-
-  @Test
-  public void testCopyManualMeasures() throws Exception {
-    setupData("testCopyManualMeasures");
-
-    File javaFile = File.create("Foo.java");
-    javaFile.setId(40);
-
-    ManualMeasureDecorator decorator = new ManualMeasureDecorator(getSession(), new DefaultMetricFinder(getSessionFactory()));
-    DecoratorContext context = mock(DecoratorContext.class);
-    decorator.decorate(javaFile, context);
-
-    verify(context).saveMeasure(argThat(new IsMeasure(reviewNote, 6.0, "six")));
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/OverallBranchCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/OverallBranchCoverageDecoratorTest.java
deleted file mode 100644 (file)
index 9f18f71..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
-
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class OverallBranchCoverageDecoratorTest {
-  private final OverallBranchCoverageDecorator decorator = new OverallBranchCoverageDecorator();
-  private final Project resource = mock(Project.class);
-
-  @Before
-  public void setUp() {
-    when(resource.getScope()).thenReturn(Scopes.PROJECT);
-    when(resource.getQualifier()).thenReturn(Qualifiers.PROJECT);
-  }
-
-  @Test
-  public void shouldSaveBranchCoverage() {
-    DecoratorContext context = mockContext(20, 15);
-
-    decorator.decorate(resource, context);
-
-    verify(context).saveMeasure(CoreMetrics.OVERALL_BRANCH_COVERAGE, 25.0);
-  }
-
-  @Test
-  public void shouldNotSaveBranchCoverageIfMissingConditions() {
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    decorator.decorate(resource, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.OVERALL_BRANCH_COVERAGE), anyDouble());
-  }
-
-  private static DecoratorContext mockContext(int conditions, int uncoveredConditions) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER, (double) conditions));
-    when(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS, (double) uncoveredConditions));
-    return context;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/OverallCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/OverallCoverageDecoratorTest.java
deleted file mode 100644 (file)
index 9aa79b1..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Scopes;
-
-import java.util.Collection;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class OverallCoverageDecoratorTest {
-  private final OverallCoverageDecorator decorator = new OverallCoverageDecorator();
-  private final Project project = mock(Project.class);
-
-  @Before
-  public void before() {
-    when(project.getScope()).thenReturn(Scopes.PROJECT);
-  }
-
-  @Test
-  public void should_use_metrics() {
-    Collection<Metric> metrics = decorator.usedMetrics();
-
-    assertThat(metrics).containsOnly(CoreMetrics.OVERALL_LINES_TO_COVER, CoreMetrics.OVERALL_UNCOVERED_LINES, CoreMetrics.NEW_OVERALL_LINES_TO_COVER,
-      CoreMetrics.NEW_OVERALL_UNCOVERED_LINES, CoreMetrics.OVERALL_CONDITIONS_TO_COVER, CoreMetrics.OVERALL_UNCOVERED_CONDITIONS,
-      CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS);
-  }
-
-  @Test
-  public void coverage() {
-    DecoratorContext context = mockContext(50, 40, 10, 8);
-
-    decorator.decorate(project, context);
-
-    // (50-40 covered lines + 10-8 covered conditions) / (50 lines + 10 conditions)
-    verify(context).saveMeasure(CoreMetrics.OVERALL_COVERAGE, 20.0);
-  }
-
-  @Test
-  public void coverageCanBe0() {
-    DecoratorContext context = mockContext(50, 50, 5, 5);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.OVERALL_COVERAGE, 0.0);
-  }
-
-  @Test
-  public void coverageCanBe100() {
-    DecoratorContext context = mockContext(50, 0, 5, 0);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.OVERALL_COVERAGE, 100.0);
-  }
-
-  @Test
-  public void noCoverageIfNoElements() {
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    decorator.decorate(project, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.OVERALL_COVERAGE), anyDouble());
-  }
-
-  @Test
-  public void should_count_elements_for_new_code() {
-    Measure newLines = measureWithVariation(1, 100.0);
-    Measure newConditions = measureWithVariation(1, 1.0);
-    DecoratorContext context = mockNewContext(newLines, null, null, newConditions);
-
-    long count = decorator.countElementsForNewCode(context, 1);
-
-    assertThat(count).isEqualTo(101).isEqualTo(100 + 1);
-  }
-
-  @Test
-  public void should_count_covered_elements_for_new_code() {
-    Measure newLines = measureWithVariation(1, 100.0);
-    Measure newUncoveredConditions = measureWithVariation(1, 10.0);
-    Measure newUncoveredLines = measureWithVariation(1, 5.0);
-    Measure newConditions = measureWithVariation(1, 1.0);
-    DecoratorContext context = mockNewContext(newLines, newUncoveredConditions, newUncoveredLines, newConditions);
-
-    long count = decorator.countCoveredElementsForNewCode(context, 1);
-
-    assertThat(count).isEqualTo(86).isEqualTo(100 + 1 - 10 - 5);
-  }
-
-  private static DecoratorContext mockContext(int lines, int uncoveredLines, int conditions, int uncoveredConditions) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.OVERALL_LINES_TO_COVER, (double) lines));
-    when(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.OVERALL_UNCOVERED_LINES, (double) uncoveredLines));
-    when(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER, (double) conditions));
-    when(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS, (double) uncoveredConditions));
-    return context;
-  }
-
-  private static DecoratorContext mockNewContext(Measure newLines, Measure newUncoveredConditions, Measure newUncoveredLines, Measure newConditions) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.NEW_OVERALL_LINES_TO_COVER)).thenReturn(newLines);
-    when(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES)).thenReturn(newUncoveredLines);
-    when(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS)).thenReturn(newUncoveredConditions);
-    when(context.getMeasure(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER)).thenReturn(newConditions);
-    return context;
-  }
-
-  private static Measure measureWithVariation(int period, double variation) {
-    Measure measure = mock(Measure.class);
-    when(measure.getVariation(period)).thenReturn(variation);
-    return measure;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/OverallLineCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/OverallLineCoverageDecoratorTest.java
deleted file mode 100644 (file)
index c19e517..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Scopes;
-
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class OverallLineCoverageDecoratorTest {
-  private final OverallLineCoverageDecorator decorator = new OverallLineCoverageDecorator();
-  private final Project project = mock(Project.class);
-
-  @Before
-  public void before() {
-    when(project.getScope()).thenReturn(Scopes.PROJECT);
-  }
-
-  @Test
-  public void should_depend_on_coverage_metrics() {
-    List<Metric> metrics = decorator.dependsUponMetrics();
-
-    assertThat(metrics).containsOnly(CoreMetrics.OVERALL_UNCOVERED_LINES, CoreMetrics.OVERALL_LINES_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES,
-      CoreMetrics.NEW_OVERALL_LINES_TO_COVER);
-  }
-
-  @Test
-  public void lineCoverage() {
-    DecoratorContext context = mockContext(50, 10);
-
-    decorator.decorate(project, context);
-
-    // 50-10 covered lines / 50 lines
-    verify(context).saveMeasure(CoreMetrics.OVERALL_LINE_COVERAGE, 80.0);
-  }
-
-  @Test
-  public void zeroCoveredLines() {
-    DecoratorContext context = mockContext(50, 50);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.OVERALL_LINE_COVERAGE, 0.0);
-  }
-
-  @Test
-  public void allCoveredLines() {
-    DecoratorContext context = mockContext(50, 00);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(CoreMetrics.OVERALL_LINE_COVERAGE, 100.0);
-  }
-
-  @Test
-  public void noLineCoverageIfNoLines() {
-    DecoratorContext context = mock(DecoratorContext.class);
-
-    decorator.decorate(project, context);
-
-    verify(context, never()).saveMeasure(eq(CoreMetrics.OVERALL_LINE_COVERAGE), anyDouble());
-  }
-
-  private static DecoratorContext mockContext(int lines, int uncoveredLines) {
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.OVERALL_LINES_TO_COVER, (double) lines));
-    when(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.OVERALL_UNCOVERED_LINES, (double) uncoveredLines));
-    return context;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/UnitTestDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/UnitTestDecoratorTest.java
deleted file mode 100644 (file)
index 966b647..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.sensors;
-
-import org.hamcrest.Matchers;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-
-import java.util.Arrays;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.doubleThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class UnitTestDecoratorTest {
-
-  private UnitTestDecorator decorator;
-  private DecoratorContext context;
-
-  @Before
-  public void setUp() {
-    decorator = new UnitTestDecorator();
-    context = mock(DecoratorContext.class);
-  }
-
-  @Test
-  public void generatesMetrics() {
-    assertThat(decorator.generatesMetrics()).hasSize(5);
-  }
-
-  @Test
-  public void doNotDecorateStaticAnalysis() {
-    Project project = mock(Project.class);
-    when(project.getAnalysisType()).thenReturn(Project.AnalysisType.STATIC);
-    assertThat(decorator.shouldExecuteOnProject(project)).isFalse();
-
-    when(project.getAnalysisType()).thenReturn(Project.AnalysisType.DYNAMIC);
-    assertThat(decorator.shouldExecuteOnProject(project)).isTrue();
-  }
-
-  @Test
-  public void shouldSumChildren() {
-    Project project = mock(Project.class);
-    mockChildrenMeasures(CoreMetrics.TESTS, 3.0);
-    mockChildrenMeasures(CoreMetrics.TEST_ERRORS, 1.0);
-    mockChildrenMeasures(CoreMetrics.TEST_FAILURES, 1.0);
-    mockChildrenMeasures(CoreMetrics.SKIPPED_TESTS, 1.0);
-    mockChildrenMeasures(CoreMetrics.TEST_EXECUTION_TIME, 1.0);
-
-    decorator.decorate(project, context);
-
-    verify(context).saveMeasure(eq(CoreMetrics.TESTS), eq(6.0));
-    verify(context).saveMeasure(eq(CoreMetrics.TEST_ERRORS), eq(2.0));
-    verify(context).saveMeasure(eq(CoreMetrics.TEST_FAILURES), eq(2.0));
-    verify(context).saveMeasure(eq(CoreMetrics.SKIPPED_TESTS), eq(2.0));
-    verify(context).saveMeasure(eq(CoreMetrics.TEST_EXECUTION_TIME), eq(2.0));
-    verify(context).saveMeasure(eq(CoreMetrics.TEST_SUCCESS_DENSITY), doubleThat(Matchers.closeTo(33.3, 0.1)));
-  }
-
-  private void mockChildrenMeasures(Metric metric, double value) {
-    when(context.getChildrenMeasures(metric)).thenReturn(Arrays.asList(new Measure(metric, value), new Measure(metric, value)));
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageAggregatorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageAggregatorTest.java
deleted file mode 100644 (file)
index c85e24d..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Matchers;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class NewCoverageAggregatorTest {
-
-  @Test
-  public void shouldNotSaveDataWhenNoMeasures() {
-    NewCoverageAggregator aggregator = new NewCoverageAggregator();
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getChildrenMeasures(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(Collections.<Measure>emptyList());
-
-    aggregator.aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, 3);
-
-    verify(context, never()).saveMeasure(Matchers.<Measure>anyObject());
-  }
-
-  @Test
-  public void shouldNotsetZeroWhenNoValueOnPeriod() {
-    NewCoverageAggregator aggregator = new NewCoverageAggregator();
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getChildrenMeasures(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(Arrays.asList(newMeasure(null, 3.0, 2.0), newMeasure(null, 13.0, null)));
-
-    aggregator.aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, 3);
-
-    verify(context).saveMeasure(argThat(new ArgumentMatcher<Measure>() {
-      @Override
-      public boolean matches(Object o) {
-        Measure m = (Measure)o;
-        return m.getVariation1()==null;
-      }
-    }));
-  }
-
-  @Test
-  public void shouldSumValues() {
-    NewCoverageAggregator aggregator = new NewCoverageAggregator();
-    DecoratorContext context = mock(DecoratorContext.class);
-    when(context.getChildrenMeasures(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(Arrays.asList(newMeasure(null, 3.0, 2.0), newMeasure(null, 13.0, null)));
-
-    aggregator.aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, 3);
-
-    verify(context).saveMeasure(argThat(new ArgumentMatcher<Measure>() {
-      @Override
-      public boolean matches(Object o) {
-        Measure m = (Measure)o;
-        return m.getVariation2()==16.0 && m.getVariation3()==2.0;
-      }
-    }));
-  }
-
-  private Measure newMeasure(Double variation1, Double variation2, Double variation3) {
-    return new Measure(CoreMetrics.NEW_LINES_TO_COVER)
-        .setVariation1(variation1)
-        .setVariation2(variation2)
-        .setVariation3(variation3);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java
deleted file mode 100644 (file)
index adc6f08..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.ArgumentMatcher;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.batch.index.BatchComponentCache;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.batch.protocol.output.BatchReport.Changesets.Changeset;
-import org.sonar.batch.protocol.output.BatchReportWriter;
-import org.sonar.batch.report.ReportPublisher;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class NewCoverageFileAnalyzerTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  private DecoratorContext context;
-  private NewCoverageFileAnalyzer decorator;
-  private BatchReportWriter writer;
-
-  @Before
-  public void prepare() throws Exception {
-    context = mock(DecoratorContext.class);
-    Resource f = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java");
-    when(context.getResource()).thenReturn(f);
-    BatchComponentCache cache = new BatchComponentCache();
-    cache.add(f, null);
-    List<AbstractNewCoverageFileAnalyzer.PeriodStruct> structs = Arrays.asList(
-      new AbstractNewCoverageFileAnalyzer.PeriodStruct(1, newDate("2009-12-25")),
-      new AbstractNewCoverageFileAnalyzer.PeriodStruct(3, newDate("2011-02-18")));
-    ReportPublisher publishReportJob = mock(ReportPublisher.class);
-    java.io.File reportBaseDir = temp.newFolder();
-    when(publishReportJob.getReportDir()).thenReturn(reportBaseDir);
-    writer = new BatchReportWriter(reportBaseDir);
-    decorator = new NewCoverageFileAnalyzer(structs, publishReportJob, cache);
-
-  }
-
-  @Test
-  public void shouldDoNothingIfNoScmData() {
-    when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA))
-      .thenReturn(new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "1=10"));
-
-    decorator.doDecorate(context);
-    verify(context, never()).saveMeasure(any(Measure.class));
-  }
-
-  @Test
-  public void shouldDoNothingIfNoCoverageData() {
-    writer.writeComponentChangesets(BatchReport.Changesets.newBuilder()
-      .setComponentRef(1)
-      .addChangeset(Changeset.newBuilder()
-        .setDate(DateUtils.parseDateTime("2008-05-18T00:00:00+0000").getTime())
-        .build())
-      .addChangesetIndexByLine(0)
-      .build());
-
-    decorator.doDecorate(context);
-
-    verify(context, never()).saveMeasure(any(Measure.class));
-  }
-
-  @Test
-  public void shouldGetNewLines() {
-    when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn(
-      new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3"));
-    writer.writeComponentChangesets(BatchReport.Changesets.newBuilder()
-      .setComponentRef(1)
-      .addChangeset(Changeset.newBuilder()
-        .build())
-      .addChangeset(Changeset.newBuilder()
-        .setDate(DateUtils.parseDateTime("2007-01-15T00:00:00+0000").getTime())
-        .build())
-      .addChangeset(Changeset.newBuilder()
-        .setDate(DateUtils.parseDateTime("2011-01-01T00:00:00+0000").getTime())
-        .build())
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(1)
-      .addChangesetIndexByLine(2)
-      .build());
-
-    decorator.doDecorate(context);
-
-    // line 11 has been updated after date1 (2009-12-25). This line is covered.
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 1, 1.0)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 1, 0.0)));
-
-    // no line have been updated after date3 (2011-02-18)
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 3, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 3, null)));
-
-    // no data on other periods
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 2, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 4, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 5, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 2, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 4, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 5, null)));
-  }
-
-  @Test
-  public void shouldGetNewConditions() {
-    when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn(
-      new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3"));
-    when(context.getMeasure(CoreMetrics.CONDITIONS_BY_LINE)).thenReturn(
-      new Measure(CoreMetrics.CONDITIONS_BY_LINE, "11=4"));
-    when(context.getMeasure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)).thenReturn(
-      new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "11=1"));
-    writer.writeComponentChangesets(BatchReport.Changesets.newBuilder()
-      .setComponentRef(1)
-      .addChangeset(Changeset.newBuilder()
-        .build())
-      .addChangeset(Changeset.newBuilder()
-        .setDate(DateUtils.parseDateTime("2007-01-15T00:00:00+0000").getTime())
-        .build())
-      .addChangeset(Changeset.newBuilder()
-        .setDate(DateUtils.parseDateTime("2011-01-01T00:00:00+0000").getTime())
-        .build())
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(1)
-      .addChangesetIndexByLine(2)
-      .build());
-
-    decorator.doDecorate(context);
-
-    // line 11 has been updated after date1 (2009-12-25). This line has 1 covered condition amongst 4
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 1, 4.0)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 1, 3.0)));
-
-    // no line have been updated after date3 (2011-02-18)
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 3, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 3, null)));
-
-    // no data on other periods
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 2, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 4, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 5, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 2, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 4, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 5, null)));
-  }
-
-  @Test
-  public void shouldNotGetNewConditionsWhenNewLineHasNoConditions() {
-    when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn(
-      new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3"));
-    when(context.getMeasure(CoreMetrics.CONDITIONS_BY_LINE)).thenReturn(
-      new Measure(CoreMetrics.CONDITIONS_BY_LINE, "10=1"));
-    when(context.getMeasure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)).thenReturn(
-      new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "10=1"));
-    writer.writeComponentChangesets(BatchReport.Changesets.newBuilder()
-      .setComponentRef(1)
-      .addChangeset(Changeset.newBuilder()
-        .build())
-      .addChangeset(Changeset.newBuilder()
-        .setDate(DateUtils.parseDateTime("2007-01-15T00:00:00+0000").getTime())
-        .build())
-      .addChangeset(Changeset.newBuilder()
-        .setDate(DateUtils.parseDateTime("2011-01-01T00:00:00+0000").getTime())
-        .build())
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(1)
-      .addChangesetIndexByLine(2)
-      .build());
-
-    decorator.doDecorate(context);
-
-    // line 11 has been updated after date1 (2009-12-25) but it has no conditions
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 1, 0.0)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 1, 0.0)));
-  }
-
-  @Test
-  public void shouldLeaveNullValueWhenNothingHasChanged() {
-
-    when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn(
-      new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "2=1;3=1"));
-    when(context.getMeasure(CoreMetrics.CONDITIONS_BY_LINE)).thenReturn(
-      new Measure(CoreMetrics.CONDITIONS_BY_LINE, "2=1"));
-    when(context.getMeasure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)).thenReturn(
-      new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "2=1"));
-    writer.writeComponentChangesets(BatchReport.Changesets.newBuilder()
-      .setComponentRef(1)
-      .addChangeset(Changeset.newBuilder()
-        .setDate(DateUtils.parseDateTime("2008-08-02T13:56:37+0200").getTime())
-        .build())
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .addChangesetIndexByLine(0)
-      .build());
-
-    decorator.doDecorate(context);
-
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 1, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 1, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 1, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 1, null)));
-
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 3, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 3, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 3, null)));
-    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 3, null)));
-  }
-
-  static class VariationMatcher extends ArgumentMatcher<Measure> {
-    Metric metric;
-    int index;
-    Double variation;
-
-    VariationMatcher(Metric metric, int index, Double variation) {
-      this.metric = metric;
-      this.index = index;
-      this.variation = variation;
-    }
-
-    @Override
-    public boolean matches(Object o) {
-      Measure m = (Measure) o;
-      if (m.getMetric().equals(metric)) {
-        if ((variation == null && m.getVariation(index) == null) ||
-          (variation != null && variation.equals(m.getVariation(index)))) {
-          return true;
-        }
-      }
-      return false;
-    }
-  }
-
-  private Date newDate(String s) throws ParseException {
-    return new SimpleDateFormat(DateUtils.DATE_FORMAT).parse(s);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest.java
deleted file mode 100644 (file)
index ca8c36a..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import org.sonar.batch.components.TimeMachineConfiguration;
-
-import org.sonar.batch.components.PastSnapshot;
-import org.junit.Test;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.Project;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.batch.index.BatchComponentCache;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.util.Arrays;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class TimeMachineConfigurationPersisterTest extends AbstractDbUnitTestCase {
-
-  @Test
-  public void shouldSaveConfigurationInSnapshotsTable() {
-    setupData("shared");
-
-    TimeMachineConfiguration timeMachineConfiguration = mock(TimeMachineConfiguration.class);
-    PastSnapshot vs1 = new PastSnapshot("days", DateUtils.parseDate("2009-01-25"), getSession().getSingleResult(Snapshot.class, "id", 100))
-      .setModeParameter("30").setIndex(1);
-    PastSnapshot vs3 = new PastSnapshot("version", DateUtils.parseDate("2008-12-13"), getSession().getSingleResult(Snapshot.class, "id", 300))
-      .setModeParameter("1.2.3").setIndex(3);
-    when(timeMachineConfiguration.getProjectPastSnapshots()).thenReturn(Arrays.asList(vs1, vs3));
-    Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1000);
-
-    BatchComponentCache resourceCache = new BatchComponentCache();
-    Project project = new Project("foo");
-    resourceCache.add(project, null).setSnapshot(projectSnapshot);
-
-    TimeMachineConfigurationPersister persister = new TimeMachineConfigurationPersister(timeMachineConfiguration, resourceCache, getSession());
-
-    persister.persistConfiguration(project);
-
-    checkTables("shouldSaveConfigurationInSnapshotsTable", "snapshots");
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java
deleted file mode 100644 (file)
index 223abad..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.sonar.plugins.core.timemachine;
-
-import org.sonar.batch.components.TimeMachineConfiguration;
-
-import org.sonar.batch.components.PastSnapshot;
-import org.sonar.batch.components.PastMeasuresLoader;
-import org.junit.Test;
-import org.mockito.Matchers;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasuresFilter;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.MetricFinder;
-import org.sonar.api.measures.RuleMeasure;
-import org.sonar.api.resources.Directory;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.util.Arrays;
-import java.util.Date;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class VariationDecoratorTest extends AbstractDbUnitTestCase {
-
-  public static final int NCLOC_ID = 12;
-  public static final Metric NCLOC = new Metric("ncloc").setId(NCLOC_ID);
-
-  public static final int COVERAGE_ID = 16;
-  public static final Metric COVERAGE = new Metric("coverage").setId(COVERAGE_ID);
-
-  public static final int VIOLATIONS_ID = 17;
-  public static final Metric VIOLATIONS = new Metric("violations").setId(VIOLATIONS_ID);
-
-  @Test
-  public void shouldComputeVariations() {
-    TimeMachineConfiguration timeMachineConfiguration = mock(TimeMachineConfiguration.class);
-    VariationDecorator decorator = new VariationDecorator(mock(PastMeasuresLoader.class), mock(MetricFinder.class), timeMachineConfiguration, mock(RuleFinder.class));
-
-    assertThat(decorator.shouldComputeVariation(new Project("foo"))).isTrue();
-    assertThat(decorator.shouldComputeVariation(File.create("foo/bar.c"))).isFalse();
-  }
-
-  @Test
-  public void shouldCompareAndSaveVariation() {
-    Resource dir = Directory.create("org/foo");
-
-    PastMeasuresLoader pastMeasuresLoader = mock(PastMeasuresLoader.class);
-    PastSnapshot pastSnapshot1 = new PastSnapshot("days", new Date()).setIndex(1);
-    PastSnapshot pastSnapshot3 = new PastSnapshot("days", new Date()).setIndex(3);
-
-    // first past analysis
-    when(pastMeasuresLoader.getPastMeasures(dir, pastSnapshot1)).thenReturn(Arrays.asList(
-      new Object[] {NCLOC_ID, null, null, null, 180.0},
-      new Object[] {COVERAGE_ID, null, null, null, 75.0}));
-
-    // second past analysis
-    when(pastMeasuresLoader.getPastMeasures(dir, pastSnapshot3)).thenReturn(Arrays.<Object[]>asList(
-      new Object[] {NCLOC_ID, null, null, null, 240.0}));
-
-    // current analysis
-    DecoratorContext context = mock(DecoratorContext.class);
-    Measure currentNcloc = newMeasure(NCLOC, 200.0);
-    Measure currentCoverage = newMeasure(COVERAGE, 80.0);
-    when(context.getMeasures(Matchers.<MeasuresFilter>anyObject())).thenReturn(Arrays.asList(currentNcloc, currentCoverage));
-
-    VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1, pastSnapshot3), mock(RuleFinder.class));
-    decorator.decorate(dir, context);
-
-    // context updated for each variation : 2 times for ncloc and 1 time for coverage
-    verify(context, times(3)).saveMeasure(Matchers.<Measure>anyObject());
-
-    assertThat(currentNcloc.getVariation1()).isEqualTo(20.0);
-    assertThat(currentNcloc.getVariation2()).isNull();
-    assertThat(currentNcloc.getVariation3()).isEqualTo(-40.0);
-
-    assertThat(currentCoverage.getVariation1()).isEqualTo(5.0);
-    assertThat(currentCoverage.getVariation2()).isNull();
-    assertThat(currentCoverage.getVariation3()).isNull();
-  }
-
-  @Test
-  public void shouldComputeVariationOfRuleMeasures() {
-    RuleFinder ruleFinder = mock(RuleFinder.class);
-
-    Rule rule1 = Rule.create("repo", "rule1");
-    rule1.setId(1);
-    Rule rule2 = Rule.create("repo", "rule2");
-    rule2.setId(2);
-
-    when(ruleFinder.findByKey(rule1.ruleKey())).thenReturn(rule1);
-    when(ruleFinder.findByKey(rule2.ruleKey())).thenReturn(rule2);
-
-    Resource dir = Directory.create("org/foo");
-
-    PastMeasuresLoader pastMeasuresLoader = mock(PastMeasuresLoader.class);
-    PastSnapshot pastSnapshot1 = new PastSnapshot("days", new Date()).setIndex(1);
-
-    // first past analysis
-    when(pastMeasuresLoader.getPastMeasures(dir, pastSnapshot1)).thenReturn(Arrays.asList(
-      new Object[] {VIOLATIONS_ID, null, null, null, 180.0},// total
-      new Object[] {VIOLATIONS_ID, null, null, rule1.getId(), 100.0},// rule 1
-      new Object[] {VIOLATIONS_ID, null, null, rule2.getId(), 80.0})); // rule 2
-
-    // current analysis
-    DecoratorContext context = mock(DecoratorContext.class);
-    Measure violations = newMeasure(VIOLATIONS, 200.0);
-    Measure violationsRule1 = RuleMeasure.createForRule(VIOLATIONS, rule1, 130.0);
-    Measure violationsRule2 = RuleMeasure.createForRule(VIOLATIONS, rule2, 70.0);
-    when(context.getMeasures(Matchers.<MeasuresFilter>anyObject())).thenReturn(Arrays.asList(violations, violationsRule1, violationsRule2));
-
-    VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1), ruleFinder);
-    decorator.decorate(dir, context);
-
-    // context updated for each variation
-    verify(context, times(3)).saveMeasure(Matchers.<Measure>anyObject());
-
-    assertThat(violations.getVariation1()).isEqualTo(20.0);
-  }
-
-  private Measure newMeasure(Metric metric, double value) {
-    return new Measure(metric, value);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ManualMeasureDecoratorTest/testCopyManualMeasures.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ManualMeasureDecoratorTest/testCopyManualMeasures.xml
deleted file mode 100644 (file)
index 0307f16..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<dataset>
-  <metrics delete_historical_data="[null]" id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]"  domain="[null]" short_name=""
-           enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
-  <metrics delete_historical_data="[null]" id="2" NAME="review_note" VAL_TYPE="INT" DESCRIPTION="[null]"  domain="[null]" short_name=""
-           enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
-
-
-  <manual_measures id="1" metric_id="2" resource_id="30" value="3.14" text_value="pi" created_at="[null]" updated_at="[null]" description="this is pi" user_login="me"/>
-  <manual_measures id="2" metric_id="2" resource_id="40" value="6" text_value="six" created_at="[null]" updated_at="[null]" description="this is six" user_login="me"/>
-
-</dataset>
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml
deleted file mode 100644 (file)
index 836bb46..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>org.codehaus.sonar</groupId>
-  <artifactId>sonar</artifactId>
-  <packaging>pom</packaging>
-  <version>1.8-SNAPSHOT</version>
-
-</project>
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldSaveLinks.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldSaveLinks.xml
deleted file mode 100644 (file)
index a44ea42..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>org.codehaus.sonar</groupId>
-  <artifactId>sonar</artifactId>
-  <packaging>pom</packaging>
-  <version>1.8-SNAPSHOT</version>
-  <url>http://sonar.codehaus.org</url>
-
-  <organization>
-    <name>SonarSource SA</name>
-    <url>http://www.sonarsource.com</url>
-  </organization>
-  <inceptionYear>2009</inceptionYear>
-
-  <issueManagement>
-    <system>jira</system>
-    <url>http://jira.codehaus.org/browse/SONAR</url>
-  </issueManagement>
-
-  <mailingLists>
-    <mailingList>
-      <name>Sonar users mailing list</name>
-      <subscribe>http://xircles.codehaus.org/projects/sonar/lists</subscribe>
-      <unsubscribe>http://xircles.codehaus.org/projects/sonar/lists</unsubscribe>
-      <post>user@sonar.codehaus.org</post>
-      <archive>http://www.nabble.com/Sonar-f30151.html</archive>
-    </mailingList>
-  </mailingLists>
-
-  <scm>
-    <connection>scm:svn:http://svn.codehaus.org/sonar/trunk</connection>
-    <developerConnection>scm:svn:https://svn.codehaus.org/sonar/trunk</developerConnection>
-    <url>http://svn.sonar.codehaus.org</url>
-  </scm>
-
-  <ciManagement>
-    <system>bamboo</system>
-    <url>http://bamboo.ci.codehaus.org/browse/SONAR/</url>
-  </ciManagement>
-
-  <licenses>
-    <license>
-      <name>GNU Lesser General Public License (LGPL), v.3</name>
-      <url>http://www.gnu.org/licenses/lgpl.txt</url>
-      <distribution>repo</distribution>
-    </license>
-  </licenses>
-
-</project>
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest/shared.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest/shared.xml
deleted file mode 100644 (file)
index 70c8178..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<dataset>
-  <snapshots purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             id="100" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-             scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
-             status="P" islast="false" depth="0" />
-
-  <snapshots purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             id="200" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-             scope="PRJ" qualifier="TRK" created_at="1229345880000" build_date="1229345880000" version="[null]" path=""
-             status="P" islast="false" depth="0" />
-
-  <!-- Snapshot of previous version -->
-  <snapshots purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             id="300" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-             scope="PRJ" qualifier="TRK" created_at="1229173080000" build_date="1229173080000" version="1.2.3" path=""
-             status="P" islast="false" depth="0" />
-
-  <snapshots purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-             scope="PRJ" qualifier="TRK" created_at="1235566680000" build_date="1235566680000" version="[null]" path=""
-             status="P" islast="false" depth="0" />
-</dataset>
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest/shouldSaveConfigurationInSnapshotsTable-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest/shouldSaveConfigurationInSnapshotsTable-result.xml
deleted file mode 100644 (file)
index 34fdf2d..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<dataset>
-  <snapshots purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             id="100" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-             scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
-             status="P" islast="false" depth="0" />
-
-  <snapshots purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             id="200" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-             scope="PRJ" qualifier="TRK" created_at="1229345880000" build_date="1229345880000" version="[null]" path=""
-             status="P" islast="false" depth="0" />
-
-  <!-- Snapshot of previous version -->
-  <snapshots purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             id="300" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-             scope="PRJ" qualifier="TRK" created_at="1229173080000" build_date="1229173080000" version="1.2.3" path=""
-             status="P" islast="false" depth="0" />
-
-  <snapshots purge_status="[null]"
-             period1_mode="days" period1_param="30" period1_date="1225544280000"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="version" period3_param="1.2.3" period3_date="1229173080000"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-             scope="PRJ" qualifier="TRK" created_at="1235566680000" build_date="1235566680000" version="[null]" path=""
-             status="P" islast="false" depth="0" />
-</dataset>
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationPersisterDecoratorTest/shared.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationPersisterDecoratorTest/shared.xml
deleted file mode 100644 (file)
index 519ce8d..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<dataset>
-
-  <rules tags="[null]" system_tags="[null]" id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
-         plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
-         is_template="[false]" template_id="[null]"/>
-
-  <rules tags="[null]" system_tags="[null]" id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
-         plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
-         is_template="[false]" template_id="[null]"/>
-
-  <projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
-            name="Bar" long_name="org.foo.Bar" description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
-
-  <snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]"
-             period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
-             scope="FIL" qualifier="CLA" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
-             status="U" islast="false" depth="3"/>
-
-</dataset>
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationPersisterDecoratorTest/shouldCopyPermanentIdFromReferenceViolation-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationPersisterDecoratorTest/shouldCopyPermanentIdFromReferenceViolation-result.xml
deleted file mode 100644 (file)
index 0610418..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<dataset>
-
-  <rules tags="[null]" system_tags="[null]" id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
-         plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
-         is_template="[false]" template_id="[null]"/>
-
-  <rules tags="[null]" system_tags="[null]" id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
-         plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
-         is_template="[false]" template_id="[null]"/>
-
-  <projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
-            name="Bar" long_name="org.foo.Bar" description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
-
-  <snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]"
-             period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000" project_id="200"
-             parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
-             scope="FIL" qualifier="CLA" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
-             status="U" islast="false" depth="3"/>
-
-</dataset>
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationPersisterDecoratorTest/shouldSaveViolations-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationPersisterDecoratorTest/shouldSaveViolations-result.xml
deleted file mode 100644 (file)
index f1bbc0b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<dataset>
-  <rules tags="[null]" system_tags="[null]" id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
-         plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
-         is_template="[false]" template_id="[null]"/>
-
-  <rules tags="[null]" system_tags="[null]" id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
-         plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
-         is_template="[false]" template_id="[null]"/>
-
-  <projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
-            name="Bar" long_name="org.foo.Bar" description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
-
-  <snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]"
-             period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000" project_id="200"
-             parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
-             scope="FIL" qualifier="CLA" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
-             status="U" islast="false" depth="3"/>
-
-</dataset>
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v1.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v1.txt
deleted file mode 100644 (file)
index 1920333..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package example1;
-
-public class Toto {
-
-    public void doSomething() {
-        // doSomething
-        }
-
-    public void doSomethingElse() {
-        // doSomethingElse
-        }
-}
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v2.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v2.txt
deleted file mode 100644 (file)
index 2315324..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package example1;
-
-public class Toto {
-
-    public Toto(){}
-
-    public void doSomethingNew() {
-        // doSomethingNew
-        }
-
-    public void doSomethingElseNew() {
-        // doSomethingElseNew
-        }
-
-    public void doSomething() {
-        // doSomething
-        }
-
-    public void doSomethingElse() {
-        // doSomethingElse
-        }
-}
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v1.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v1.txt
deleted file mode 100644 (file)
index a920afe..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package example2;
-
-public class Toto {
-  void method1() {
-    System.out.println("toto");
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v2.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v2.txt
deleted file mode 100644 (file)
index c5c8250..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-package example2;
-
-public class Toto {
-
-  void method2() {
-    System.out.println("toto");
-  }
-
-  void method1() {
-    System.out.println("toto");
-  }
-
-  void method3() {
-    System.out.println("toto");
-  }
-}
index c584274eaf5e079bf88074ab5c51fa748605e3bb..ba42319b7bd324f8ecefb464ec36bd0af656cd05 100644 (file)
@@ -23,6 +23,29 @@ import com.google.common.collect.Lists;
 import java.util.Collection;
 import java.util.List;
 import org.sonar.batch.components.TimeMachineConfiguration;
+import org.sonar.batch.compute.ApplyProjectRolesDecorator;
+import org.sonar.batch.compute.BranchCoverageDecorator;
+import org.sonar.batch.compute.CommentDensityDecorator;
+import org.sonar.batch.compute.CountFalsePositivesDecorator;
+import org.sonar.batch.compute.CountUnresolvedIssuesDecorator;
+import org.sonar.batch.compute.CoverageDecorator;
+import org.sonar.batch.compute.DirectoriesDecorator;
+import org.sonar.batch.compute.FilesDecorator;
+import org.sonar.batch.compute.ItBranchCoverageDecorator;
+import org.sonar.batch.compute.ItCoverageDecorator;
+import org.sonar.batch.compute.ItLineCoverageDecorator;
+import org.sonar.batch.compute.LineCoverageDecorator;
+import org.sonar.batch.compute.ManualMeasureDecorator;
+import org.sonar.batch.compute.NewCoverageAggregator;
+import org.sonar.batch.compute.NewCoverageFileAnalyzer;
+import org.sonar.batch.compute.NewItCoverageFileAnalyzer;
+import org.sonar.batch.compute.NewOverallCoverageFileAnalyzer;
+import org.sonar.batch.compute.OverallBranchCoverageDecorator;
+import org.sonar.batch.compute.OverallCoverageDecorator;
+import org.sonar.batch.compute.OverallLineCoverageDecorator;
+import org.sonar.batch.compute.TimeMachineConfigurationPersister;
+import org.sonar.batch.compute.UnitTestDecorator;
+import org.sonar.batch.compute.VariationDecorator;
 import org.sonar.batch.cpd.CpdComponents;
 import org.sonar.batch.debt.DebtDecorator;
 import org.sonar.batch.debt.IssueChangelogDebtCalculator;
@@ -103,8 +126,31 @@ public class BatchComponents {
       IssueHandlers.class,
       InitialOpenIssuesSensor.class,
 
+      // to be moved to compute engine
       QProfileEventsDecorator.class,
-
+      CountUnresolvedIssuesDecorator.class,
+      CountFalsePositivesDecorator.class,
+      UnitTestDecorator.class,
+      LineCoverageDecorator.class,
+      CoverageDecorator.class,
+      BranchCoverageDecorator.class,
+      ItLineCoverageDecorator.class,
+      ItCoverageDecorator.class,
+      ItBranchCoverageDecorator.class,
+      OverallLineCoverageDecorator.class,
+      OverallCoverageDecorator.class,
+      OverallBranchCoverageDecorator.class,
+      ApplyProjectRolesDecorator.class,
+      CommentDensityDecorator.class,
+      DirectoriesDecorator.class,
+      FilesDecorator.class,
+      ManualMeasureDecorator.class,
+      VariationDecorator.class,
+      TimeMachineConfigurationPersister.class,
+      NewCoverageFileAnalyzer.class,
+      NewItCoverageFileAnalyzer.class,
+      NewOverallCoverageFileAnalyzer.class,
+      NewCoverageAggregator.class,
       TimeMachineConfiguration.class
       );
     components.addAll(CorePropertyDefinitions.all());
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/AbstractCoverageDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/AbstractCoverageDecorator.java
new file mode 100644 (file)
index 0000000..4960f99
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import java.util.Collection;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.ResourceUtils;
+
+public abstract class AbstractCoverageDecorator implements Decorator {
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  @DependedUpon
+  public Collection<Metric> generatedMetrics() {
+    return Arrays.asList(getGeneratedMetric(), getGeneratedMetricForNewCode());
+  }
+
+  @Override
+  public void decorate(final Resource resource, final DecoratorContext context) {
+    if (shouldDecorate(resource)) {
+      computeMeasure(context);
+      computeMeasureForNewCode(context);
+    }
+  }
+
+  protected boolean shouldDecorate(final Resource resource) {
+    return !ResourceUtils.isUnitTestFile(resource);
+  }
+
+  private void computeMeasure(DecoratorContext context) {
+    if (context.getMeasure(getGeneratedMetric()) == null) {
+      Long elements = countElements(context);
+      if (elements != null && elements > 0L) {
+        Long coveredElements = countCoveredElements(context);
+        context.saveMeasure(getGeneratedMetric(), calculateCoverage(coveredElements, elements));
+      }
+    }
+  }
+
+  private void computeMeasureForNewCode(DecoratorContext context) {
+    if (context.getMeasure(getGeneratedMetricForNewCode()) == null) {
+      Measure measure = new Measure(getGeneratedMetricForNewCode());
+      boolean hasValue = false;
+      /* TODO remove this magic number */
+      for (int periodIndex = 1; periodIndex <= 5; periodIndex++) {
+        Long elements = countElementsForNewCode(context, periodIndex);
+
+        if (elements != null && elements > 0L) {
+          long coveredElements = countCoveredElementsForNewCode(context, periodIndex);
+          measure.setVariation(periodIndex, calculateCoverage(coveredElements, elements));
+          hasValue = true;
+        }
+      }
+      if (hasValue) {
+        context.saveMeasure(measure);
+      }
+    }
+  }
+
+  private double calculateCoverage(final long coveredLines, final long lines) {
+    return (100.0 * coveredLines) / lines;
+  }
+
+  protected abstract Metric getGeneratedMetric();
+
+  protected abstract Long countElements(DecoratorContext context);
+
+  protected abstract long countCoveredElements(DecoratorContext context);
+
+  protected abstract Metric getGeneratedMetricForNewCode();
+
+  protected abstract Long countElementsForNewCode(DecoratorContext context, int periodIndex);
+
+  protected abstract long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex);
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/AbstractNewCoverageFileAnalyzer.java b/sonar-batch/src/main/java/org/sonar/batch/compute/AbstractNewCoverageFileAnalyzer.java
new file mode 100644 (file)
index 0000000..446c082
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.ObjectUtils;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorBarriers;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.batch.RequiresDB;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.utils.KeyValueFormat;
+import org.sonar.batch.components.Period;
+import org.sonar.batch.components.TimeMachineConfiguration;
+import org.sonar.batch.index.BatchComponentCache;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReport.Changesets.Changeset;
+import org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.batch.report.ReportPublisher;
+
+/**
+ * @since 2.7
+ */
+@RequiresDB
+@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE)
+public abstract class AbstractNewCoverageFileAnalyzer implements Decorator {
+
+  private final List<PeriodStruct> structs;
+  private final ReportPublisher publishReportJob;
+  private final BatchComponentCache resourceCache;
+
+  public AbstractNewCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
+    this(new ArrayList<PeriodStruct>(), publishReportJob, resourceCache);
+    for (Period period : timeMachineConfiguration.periods()) {
+      structs.add(new PeriodStruct(period.getIndex(), period.getDate()));
+    }
+  }
+
+  AbstractNewCoverageFileAnalyzer(List<PeriodStruct> structs, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
+    this.resourceCache = resourceCache;
+    this.publishReportJob = publishReportJob;
+    this.structs = structs;
+  }
+
+  public abstract Metric getCoverageLineHitsDataMetric();
+
+  public abstract Metric getConditionsByLineMetric();
+
+  public abstract Metric getCoveredConditionsByLineMetric();
+
+  public abstract Metric getNewLinesToCoverMetric();
+
+  public abstract Metric getNewUncoveredLinesMetric();
+
+  public abstract Metric getNewConditionsToCoverMetric();
+
+  public abstract Metric getNewUncoveredConditionsMetric();
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return !structs.isEmpty();
+  }
+
+  private boolean shouldDecorate(Resource resource) {
+    return Scopes.isFile(resource) && !Qualifiers.UNIT_TEST_FILE.equals(resource.getQualifier());
+  }
+
+  @DependsUpon
+  public List<Metric> dependsOnMetrics() {
+
+    return Arrays.asList(getCoverageLineHitsDataMetric(), getConditionsByLineMetric(), getCoveredConditionsByLineMetric());
+  }
+
+  @DependedUpon
+  public List<Metric> generatesNewCoverageMetrics() {
+    return Arrays.asList(getNewLinesToCoverMetric(), getNewUncoveredLinesMetric(), getNewConditionsToCoverMetric(), getNewUncoveredConditionsMetric());
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    if (shouldDecorate(resource)) {
+      doDecorate(context);
+    }
+  }
+
+  void doDecorate(DecoratorContext context) {
+    if (parse(context)) {
+      compute(context);
+    }
+  }
+
+  private boolean parse(DecoratorContext context) {
+    BatchReportReader reader = new BatchReportReader(publishReportJob.getReportDir());
+    BatchReport.Changesets componentScm = reader.readChangesets(resourceCache.get(context.getResource()).batchId());
+    Measure hitsByLineMeasure = context.getMeasure(getCoverageLineHitsDataMetric());
+
+    if (componentScm != null && hitsByLineMeasure != null && hitsByLineMeasure.hasData()) {
+      Map<Integer, Integer> hitsByLine = parseCountByLine(hitsByLineMeasure);
+      Map<Integer, Integer> conditionsByLine = parseCountByLine(context.getMeasure(getConditionsByLineMetric()));
+      Map<Integer, Integer> coveredConditionsByLine = parseCountByLine(context.getMeasure(getCoveredConditionsByLineMetric()));
+
+      reset();
+
+      for (Map.Entry<Integer, Integer> entry : hitsByLine.entrySet()) {
+        int lineId = entry.getKey();
+        int hits = entry.getValue();
+        int conditions = (Integer) ObjectUtils.defaultIfNull(conditionsByLine.get(lineId), 0);
+        int coveredConditions = (Integer) ObjectUtils.defaultIfNull(coveredConditionsByLine.get(lineId), 0);
+        Changeset changeset = componentScm.getChangeset(componentScm.getChangesetIndexByLine(lineId - 1));
+        Date date = changeset.hasDate() ? new Date(changeset.getDate()) : null;
+        for (PeriodStruct struct : structs) {
+          struct.analyze(date, hits, conditions, coveredConditions);
+        }
+      }
+
+      return true;
+    }
+    return false;
+  }
+
+  private void reset() {
+    for (PeriodStruct struct : structs) {
+      struct.reset();
+    }
+  }
+
+  private void compute(DecoratorContext context) {
+    Measure newLines = new Measure(getNewLinesToCoverMetric());
+    Measure newUncoveredLines = new Measure(getNewUncoveredLinesMetric());
+    Measure newConditions = new Measure(getNewConditionsToCoverMetric());
+    Measure newUncoveredConditions = new Measure(getNewUncoveredConditionsMetric());
+
+    for (PeriodStruct struct : structs) {
+      if (struct.hasNewCode()) {
+        newLines.setVariation(struct.index, (double) struct.getNewLines());
+        newUncoveredLines.setVariation(struct.index, (double) (struct.getNewLines() - struct.getNewCoveredLines()));
+        newConditions.setVariation(struct.index, (double) struct.getNewConditions());
+        newUncoveredConditions.setVariation(struct.index, (double) struct.getNewConditions() - struct.getNewCoveredConditions());
+      }
+    }
+
+    context.saveMeasure(newLines);
+    context.saveMeasure(newUncoveredLines);
+    context.saveMeasure(newConditions);
+    context.saveMeasure(newUncoveredConditions);
+  }
+
+  private Map<Integer, Integer> parseCountByLine(@Nullable Measure measure) {
+    if (measure != null && measure.hasData()) {
+      return KeyValueFormat.parseIntInt(measure.getData());
+    }
+    return new HashMap<>();
+  }
+
+  public static final class PeriodStruct {
+    int index;
+    Date date;
+    Integer newLines;
+    Integer newCoveredLines;
+    Integer newConditions;
+    Integer newCoveredConditions;
+
+    PeriodStruct(int index, @Nullable Date date) {
+      this.index = index;
+      this.date = date;
+    }
+
+    void reset() {
+      newLines = null;
+      newCoveredLines = null;
+      newConditions = null;
+      newCoveredConditions = null;
+    }
+
+    void analyze(@Nullable Date lineDate, int hits, int conditions, int coveredConditions) {
+      if (lineDate == null) {
+        // TODO warning
+
+      } else if (date == null || lineDate.after(date)) {
+        // TODO test if string comparison is faster or not
+        addLine(hits > 0);
+        addConditions(conditions, coveredConditions);
+      }
+    }
+
+    void addLine(boolean covered) {
+      if (newLines == null) {
+        newLines = 0;
+      }
+      newLines += 1;
+      if (covered) {
+        if (newCoveredLines == null) {
+          newCoveredLines = 0;
+        }
+        newCoveredLines += 1;
+      }
+    }
+
+    void addConditions(int count, int countCovered) {
+      if (newConditions == null) {
+        newConditions = 0;
+      }
+      newConditions += count;
+      if (count > 0) {
+        if (newCoveredConditions == null) {
+          newCoveredConditions = 0;
+        }
+        newCoveredConditions += countCovered;
+      }
+    }
+
+    boolean hasNewCode() {
+      return newLines != null;
+    }
+
+    public int getNewLines() {
+      return newLines != null ? newLines : 0;
+    }
+
+    public int getNewCoveredLines() {
+      return newCoveredLines != null ? newCoveredLines : 0;
+    }
+
+    public int getNewConditions() {
+      return newConditions != null ? newConditions : 0;
+    }
+
+    public int getNewCoveredConditions() {
+      return newCoveredConditions != null ? newCoveredConditions : 0;
+    }
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/ApplyProjectRolesDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/ApplyProjectRolesDecorator.java
new file mode 100644 (file)
index 0000000..8861e13
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.RequiresDB;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.security.ResourcePermissions;
+
+@RequiresDB
+public class ApplyProjectRolesDecorator implements Decorator {
+
+  private static final Set<String> QUALIFIERS = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.SUBVIEW);
+  private final ResourcePermissions resourcePermissions;
+
+  public ApplyProjectRolesDecorator(ResourcePermissions resourcePermissions) {
+    this.resourcePermissions = resourcePermissions;
+  }
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    if (shouldDecorateResource(resource)) {
+      LoggerFactory.getLogger(ApplyProjectRolesDecorator.class).info("Grant default permissions to {}", resource.getKey());
+      resourcePermissions.grantDefaultRoles(resource);
+    }
+  }
+
+  private boolean shouldDecorateResource(Resource resource) {
+    return resource.getId() != null && QUALIFIERS.contains(resource.getQualifier()) && !resourcePermissions.hasRoles(resource);
+  }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/BranchCoverageDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/BranchCoverageDecorator.java
new file mode 100644 (file)
index 0000000..637ea6e
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Collection;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+import org.sonar.batch.sensor.coverage.CoverageConstants;
+
+public final class BranchCoverageDecorator extends AbstractCoverageDecorator {
+
+  @DependsUpon
+  public Collection<Metric> dependsUponMetrics() {
+    return CoverageConstants.BRANCH_COVERAGE_METRICS;
+  }
+
+  @Override
+  protected Metric getGeneratedMetric() {
+    return CoreMetrics.BRANCH_COVERAGE;
+  }
+
+  @Override
+  protected Long countElements(DecoratorContext context) {
+    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L);
+  }
+
+  @Override
+  protected long countCoveredElements(DecoratorContext context) {
+    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS), 0L);
+    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L);
+
+    return conditions - uncoveredConditions;
+  }
+
+  @Override
+  protected Metric getGeneratedMetricForNewCode() {
+    return CoreMetrics.NEW_BRANCH_COVERAGE;
+  }
+
+  @Override
+  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex);
+  }
+
+  @Override
+  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+    long uncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_CONDITIONS), periodIndex, 0L);
+    long conditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex, 0L);
+
+    return conditions - uncoveredConditions;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/CommentDensityDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/CommentDensityDecorator.java
new file mode 100644 (file)
index 0000000..0379552
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import java.util.List;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+
+public class CommentDensityDecorator implements Decorator {
+
+  @DependsUpon
+  public List<Metric> dependsUponMetrics() {
+    return Arrays.<Metric>asList(CoreMetrics.NCLOC, CoreMetrics.COMMENT_LINES, CoreMetrics.PUBLIC_API, CoreMetrics.PUBLIC_UNDOCUMENTED_API);
+  }
+
+  @DependedUpon
+  public List<Metric> generatesMetrics() {
+    return Arrays.<Metric>asList(CoreMetrics.COMMENT_LINES_DENSITY, CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY);
+  }
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    saveCommentsDensity(context);
+    savePublicApiDensity(context);
+  }
+
+  private void saveCommentsDensity(DecoratorContext context) {
+    if (context.getMeasure(CoreMetrics.COMMENT_LINES_DENSITY) != null) {
+      return;
+    }
+
+    Measure ncloc = context.getMeasure(CoreMetrics.NCLOC);
+    Measure comments = context.getMeasure(CoreMetrics.COMMENT_LINES);
+    if (MeasureUtils.hasValue(ncloc) && MeasureUtils.hasValue(comments) && (comments.getValue() + ncloc.getValue()) > 0) {
+      double val = 100.0 * (comments.getValue() / (comments.getValue() + ncloc.getValue()));
+      context.saveMeasure(new Measure(CoreMetrics.COMMENT_LINES_DENSITY, val));
+    }
+  }
+
+  private void savePublicApiDensity(DecoratorContext context) {
+    if (context.getMeasure(CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY) != null) {
+      return;
+    }
+
+    Measure publicApi = context.getMeasure(CoreMetrics.PUBLIC_API);
+    Measure publicUndocApi = context.getMeasure(CoreMetrics.PUBLIC_UNDOCUMENTED_API);
+
+    if (MeasureUtils.hasValue(publicApi) && MeasureUtils.hasValue(publicUndocApi) && publicApi.getValue() > 0) {
+      double documentedAPI = publicApi.getValue() - publicUndocApi.getValue();
+      Double value = 100.0 * (documentedAPI / publicApi.getValue());
+      context.saveMeasure(new Measure(CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY, value));
+    }
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName();
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/CountFalsePositivesDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/CountFalsePositivesDecorator.java
new file mode 100644 (file)
index 0000000..1eb5456
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorBarriers;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.component.ResourcePerspectives;
+import org.sonar.api.issue.Issuable;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+
+/**
+ * Computes the number of false-positives
+ *
+ * @since 3.6
+ */
+@DependsUpon(DecoratorBarriers.END_OF_VIOLATION_TRACKING)
+public class CountFalsePositivesDecorator implements Decorator {
+
+  private final ResourcePerspectives perspectives;
+
+  public CountFalsePositivesDecorator(ResourcePerspectives perspectives) {
+    this.perspectives = perspectives;
+  }
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  @DependedUpon
+  public Metric generatesFalsePositiveMeasure() {
+    return CoreMetrics.FALSE_POSITIVE_ISSUES;
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    Issuable issuable = perspectives.as(Issuable.class, resource);
+    if (issuable != null) {
+      int falsePositives = 0;
+      for (Issue issue : issuable.resolvedIssues()) {
+        if (Issue.RESOLUTION_FALSE_POSITIVE.equals(issue.resolution())) {
+          falsePositives++;
+        }
+      }
+      saveMeasure(context, CoreMetrics.FALSE_POSITIVE_ISSUES, falsePositives);
+    }
+  }
+
+  private void saveMeasure(DecoratorContext context, Metric metric, int value) {
+    context.saveMeasure(metric, (double) (value + sumChildren(context, metric)));
+  }
+
+  private int sumChildren(DecoratorContext context, Metric metric) {
+    return MeasureUtils.sum(true, context.getChildrenMeasures(metric)).intValue();
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName();
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/CountUnresolvedIssuesDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/CountUnresolvedIssuesDecorator.java
new file mode 100644 (file)
index 0000000..cd57819
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multiset;
+import com.google.common.collect.Sets;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.time.DateUtils;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorBarriers;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.batch.RequiresDB;
+import org.sonar.api.component.ResourcePerspectives;
+import org.sonar.api.issue.Issuable;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.MeasuresFilters;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.RuleMeasure;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.ResourceUtils;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.RulePriority;
+import org.sonar.batch.components.Period;
+import org.sonar.batch.components.TimeMachineConfiguration;
+
+/**
+ * Computes metrics related to number of issues.
+ *
+ * @since 3.6
+ */
+@DependsUpon(DecoratorBarriers.ISSUES_TRACKED)
+@RequiresDB
+public class CountUnresolvedIssuesDecorator implements Decorator {
+
+  private final ResourcePerspectives perspectives;
+  private final TimeMachineConfiguration timeMachineConfiguration;
+
+  public CountUnresolvedIssuesDecorator(ResourcePerspectives perspectives, TimeMachineConfiguration timeMachineConfiguration) {
+    this.perspectives = perspectives;
+    this.timeMachineConfiguration = timeMachineConfiguration;
+  }
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  @DependedUpon
+  public List<Metric> generatesIssuesMetrics() {
+    return ImmutableList.<Metric>of(
+      CoreMetrics.VIOLATIONS,
+      CoreMetrics.BLOCKER_VIOLATIONS,
+      CoreMetrics.CRITICAL_VIOLATIONS,
+      CoreMetrics.MAJOR_VIOLATIONS,
+      CoreMetrics.MINOR_VIOLATIONS,
+      CoreMetrics.INFO_VIOLATIONS,
+      CoreMetrics.NEW_VIOLATIONS,
+      CoreMetrics.NEW_BLOCKER_VIOLATIONS,
+      CoreMetrics.NEW_CRITICAL_VIOLATIONS,
+      CoreMetrics.NEW_MAJOR_VIOLATIONS,
+      CoreMetrics.NEW_MINOR_VIOLATIONS,
+      CoreMetrics.NEW_INFO_VIOLATIONS,
+      CoreMetrics.OPEN_ISSUES,
+      CoreMetrics.REOPENED_ISSUES,
+      CoreMetrics.CONFIRMED_ISSUES
+      );
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    Issuable issuable = perspectives.as(Issuable.class, resource);
+    if (issuable != null) {
+      Collection<Issue> issues = issuable.issues();
+      boolean shouldSaveNewMetrics = shouldSaveNewMetrics(context);
+
+      Multiset<RulePriority> severityBag = HashMultiset.create();
+      Map<RulePriority, Multiset<RuleKey>> rulesPerSeverity = Maps.newHashMap();
+      ListMultimap<RulePriority, Issue> issuesPerSeverity = ArrayListMultimap.create();
+      int countOpen = 0;
+      int countReopened = 0;
+      int countConfirmed = 0;
+
+      for (Issue issue : issues) {
+        severityBag.add(RulePriority.valueOf(issue.severity()));
+        Multiset<RuleKey> rulesBag = initRules(rulesPerSeverity, RulePriority.valueOf(issue.severity()));
+        rulesBag.add(issue.ruleKey());
+        issuesPerSeverity.put(RulePriority.valueOf(issue.severity()), issue);
+
+        if (Issue.STATUS_OPEN.equals(issue.status())) {
+          countOpen++;
+        } else if (Issue.STATUS_REOPENED.equals(issue.status())) {
+          countReopened++;
+        } else if (Issue.STATUS_CONFIRMED.equals(issue.status())) {
+          countConfirmed++;
+        }
+      }
+
+      for (RulePriority ruleSeverity : RulePriority.values()) {
+        saveIssuesForSeverity(context, ruleSeverity, severityBag);
+        saveIssuesPerRules(context, ruleSeverity, rulesPerSeverity);
+        saveNewIssuesForSeverity(context, ruleSeverity, issuesPerSeverity, shouldSaveNewMetrics);
+        saveNewIssuesPerRule(context, ruleSeverity, issues, shouldSaveNewMetrics);
+      }
+
+      saveTotalIssues(context, issues);
+      saveNewIssues(context, issues, shouldSaveNewMetrics);
+
+      saveMeasure(context, CoreMetrics.OPEN_ISSUES, countOpen);
+      saveMeasure(context, CoreMetrics.REOPENED_ISSUES, countReopened);
+      saveMeasure(context, CoreMetrics.CONFIRMED_ISSUES, countConfirmed);
+    }
+  }
+
+  private void saveTotalIssues(DecoratorContext context, Collection<Issue> issues) {
+    if (context.getMeasure(CoreMetrics.VIOLATIONS) == null) {
+      Collection<Measure> childrenIssues = context.getChildrenMeasures(CoreMetrics.VIOLATIONS);
+      Double sum = MeasureUtils.sum(true, childrenIssues);
+      context.saveMeasure(CoreMetrics.VIOLATIONS, sum + issues.size());
+    }
+  }
+
+  private void saveNewIssues(DecoratorContext context, Collection<Issue> issues, boolean shouldSaveNewMetrics) {
+    if (shouldSaveNewMetrics) {
+      Measure measure = new Measure(CoreMetrics.NEW_VIOLATIONS);
+      saveNewIssues(context, measure, issues);
+    }
+  }
+
+  private void saveIssuesForSeverity(DecoratorContext context, RulePriority ruleSeverity, Multiset<RulePriority> severitiesBag) {
+    Metric metric = SeverityUtils.severityToIssueMetric(ruleSeverity);
+    if (context.getMeasure(metric) == null) {
+      Collection<Measure> children = context.getChildrenMeasures(MeasuresFilters.metric(metric));
+      int sum = MeasureUtils.sum(true, children).intValue() + severitiesBag.count(ruleSeverity);
+      context.saveMeasure(metric, (double) sum);
+    }
+  }
+
+  private void saveNewIssuesForSeverity(DecoratorContext context, RulePriority severity, ListMultimap<RulePriority, Issue> issuesPerSeverities, boolean shouldSaveNewMetrics) {
+    if (shouldSaveNewMetrics) {
+      Metric metric = SeverityUtils.severityToNewMetricIssue(severity);
+      Measure measure = new Measure(metric);
+      saveNewIssues(context, measure, issuesPerSeverities.get(severity));
+    }
+  }
+
+  private void saveIssuesPerRules(DecoratorContext context, RulePriority severity, Map<RulePriority, Multiset<RuleKey>> rulesPerSeverity) {
+    Metric metric = SeverityUtils.severityToIssueMetric(severity);
+
+    Collection<Measure> children = context.getChildrenMeasures(MeasuresFilters.rules(metric));
+    for (Measure child : children) {
+      RuleMeasure childRuleMeasure = (RuleMeasure) child;
+      RuleKey ruleKey = childRuleMeasure.ruleKey();
+      if (ruleKey != null && MeasureUtils.hasValue(childRuleMeasure)) {
+        Multiset<RuleKey> rulesBag = initRules(rulesPerSeverity, severity);
+        rulesBag.add(ruleKey, childRuleMeasure.getIntValue());
+      }
+    }
+
+    Multiset<RuleKey> rulesBag = rulesPerSeverity.get(severity);
+    if (rulesBag != null) {
+      for (Multiset.Entry<RuleKey> entry : rulesBag.entrySet()) {
+        RuleMeasure measure = RuleMeasure.createForRule(metric, entry.getElement(), (double) entry.getCount());
+        measure.setSeverity(severity);
+        context.saveMeasure(measure);
+      }
+    }
+  }
+
+  private void saveNewIssuesPerRule(DecoratorContext context, RulePriority severity, Collection<Issue> issues, boolean shouldSaveNewMetrics) {
+    if (shouldSaveNewMetrics) {
+      Metric metric = SeverityUtils.severityToNewMetricIssue(severity);
+      ListMultimap<RuleKey, Measure> childMeasuresPerRuleKeys = ArrayListMultimap.create();
+      ListMultimap<RuleKey, Issue> issuesPerRuleKeys = ArrayListMultimap.create();
+      Set<RuleKey> ruleKeys = Sets.newHashSet();
+
+      Collection<Measure> children = context.getChildrenMeasures(MeasuresFilters.rules(metric));
+      for (Measure child : children) {
+        RuleMeasure childRuleMeasure = (RuleMeasure) child;
+        RuleKey ruleKey = childRuleMeasure.ruleKey();
+        if (ruleKey != null) {
+          childMeasuresPerRuleKeys.put(ruleKey, childRuleMeasure);
+          ruleKeys.add(ruleKey);
+        }
+      }
+
+      for (Issue issue : issues) {
+        if (RulePriority.valueOf(issue.severity()).equals(severity)) {
+          ruleKeys.add(issue.ruleKey());
+          issuesPerRuleKeys.put(issue.ruleKey(), issue);
+        }
+      }
+
+      for (RuleKey ruleKey : ruleKeys) {
+        RuleMeasure measure = RuleMeasure.createForRule(metric, ruleKey, null);
+        measure.setSeverity(severity);
+        for (Period period : timeMachineConfiguration.periods()) {
+          int variationIndex = period.getIndex();
+          double sum = MeasureUtils.sumOnVariation(true, variationIndex, childMeasuresPerRuleKeys.get(ruleKey)) + countIssues(issuesPerRuleKeys.get(ruleKey), period);
+          measure.setVariation(variationIndex, sum);
+        }
+        context.saveMeasure(measure);
+      }
+    }
+  }
+
+  private void saveNewIssues(DecoratorContext context, Measure measure, Collection<Issue> issues) {
+    for (Period period : timeMachineConfiguration.periods()) {
+      int variationIndex = period.getIndex();
+      Collection<Measure> children = context.getChildrenMeasures(measure.getMetric());
+      double sum = MeasureUtils.sumOnVariation(true, variationIndex, children) + countIssues(issues, period);
+      measure.setVariation(variationIndex, sum);
+    }
+    context.saveMeasure(measure);
+  }
+
+  private void saveMeasure(DecoratorContext context, Metric metric, int value) {
+    context.saveMeasure(metric, (double) (value + sumChildren(context, metric)));
+  }
+
+  private int sumChildren(DecoratorContext context, Metric metric) {
+    int sum = 0;
+    if (!ResourceUtils.isFile(context.getResource())) {
+      sum = MeasureUtils.sum(true, context.getChildrenMeasures(metric)).intValue();
+    }
+    return sum;
+  }
+
+  private Multiset<RuleKey> initRules(Map<RulePriority, Multiset<RuleKey>> rulesPerSeverity, RulePriority severity) {
+    Multiset<RuleKey> rulesBag = rulesPerSeverity.get(severity);
+    if (rulesBag == null) {
+      rulesBag = HashMultiset.create();
+      rulesPerSeverity.put(severity, rulesBag);
+    }
+    return rulesBag;
+  }
+
+  private int countIssues(Collection<Issue> issues, Period period) {
+    // SONAR-3647 Use real snapshot date and not target date in order to stay consistent with other measure variations
+    Date datePlusOneSecond = period.getDate() != null ? DateUtils.addSeconds(period.getDate(), 1) : null;
+    return countIssuesAfterDate(issues, datePlusOneSecond);
+  }
+
+  @VisibleForTesting
+  int countIssuesAfterDate(Collection<Issue> issues, @Nullable Date date) {
+    if (issues == null) {
+      return 0;
+    }
+    int count = 0;
+    for (Issue issue : issues) {
+      if (isAfter(issue, date)) {
+        count++;
+      }
+    }
+    return count;
+  }
+
+  private boolean isAfter(Issue issue, @Nullable Date date) {
+    return date == null || (issue.creationDate() != null && DateUtils.truncatedCompareTo(issue.creationDate(), date, Calendar.SECOND) > 0);
+  }
+
+  private boolean shouldSaveNewMetrics(DecoratorContext context) {
+    return context.getMeasure(CoreMetrics.NEW_VIOLATIONS) == null;
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName();
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/CoverageDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/CoverageDecorator.java
new file mode 100644 (file)
index 0000000..7d8bed2
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Collection;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+import org.sonar.batch.sensor.coverage.CoverageConstants;
+
+public final class CoverageDecorator extends AbstractCoverageDecorator {
+
+  @DependsUpon
+  public Collection<Metric> usedMetrics() {
+    return CoverageConstants.COVERAGE_METRICS;
+  }
+
+  @Override
+  protected Metric getGeneratedMetric() {
+    return CoreMetrics.COVERAGE;
+  }
+
+  @Override
+  protected Long countElements(DecoratorContext context) {
+    long linesToCover = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L);
+    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L);
+
+    return linesToCover + conditions;
+  }
+
+  @Override
+  protected long countCoveredElements(DecoratorContext context) {
+    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_LINES), 0L);
+    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L);
+    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS), 0L);
+    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L);
+
+    return lines + conditions - uncoveredConditions - uncoveredLines;
+  }
+
+  @Override
+  protected Metric getGeneratedMetricForNewCode() {
+    return CoreMetrics.NEW_COVERAGE;
+  }
+
+  @Override
+  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+    Long newLinesToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex);
+    if (newLinesToCover == null) {
+      return null;
+    }
+
+    long newConditionsToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex, 0L);
+
+    return newLinesToCover + newConditionsToCover;
+  }
+
+  @Override
+  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+    long newLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex, 0L);
+    long newUncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_LINES), periodIndex, 0L);
+    long newUncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_CONDITIONS), periodIndex, 0L);
+    long newConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex, 0L);
+
+    return newLines + newConditions - newUncoveredConditions - newUncoveredLines;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/DirectoriesDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/DirectoriesDecorator.java
new file mode 100644 (file)
index 0000000..e1dc25e
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Collection;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.ResourceUtils;
+
+/**
+ * @since 2.2
+ */
+public final class DirectoriesDecorator implements Decorator {
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  @DependedUpon
+  public Metric generateDirectoriesMetric() {
+    return CoreMetrics.DIRECTORIES;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    if (MeasureUtils.hasValue(context.getMeasure(CoreMetrics.DIRECTORIES))) {
+      return;
+    }
+
+    if (Resource.QUALIFIER_DIRECTORY.equals(resource.getQualifier())) {
+      context.saveMeasure(CoreMetrics.DIRECTORIES, 1.0);
+
+    } else if (ResourceUtils.isSet(resource)) {
+      Collection<Measure> childrenMeasures = context.getChildrenMeasures(CoreMetrics.DIRECTORIES);
+      Double sum = MeasureUtils.sum(false, childrenMeasures);
+      if (sum != null) {
+        context.saveMeasure(CoreMetrics.DIRECTORIES, sum);
+      }
+    }
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/FilesDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/FilesDecorator.java
new file mode 100644 (file)
index 0000000..27b0cbd
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Collection;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+
+/**
+ * @since 2.2
+ */
+public final class FilesDecorator implements Decorator {
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  @DependedUpon
+  public Metric generateDirectoriesMetric() {
+    return CoreMetrics.FILES;
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    if (MeasureUtils.hasValue(context.getMeasure(CoreMetrics.FILES))) {
+      return;
+    }
+
+    if (Resource.QUALIFIER_CLASS.equals(resource.getQualifier()) || Resource.QUALIFIER_FILE.equals(resource.getQualifier())) {
+      context.saveMeasure(CoreMetrics.FILES, 1.0);
+
+    } else {
+      Collection<Measure> childrenMeasures = context.getChildrenMeasures(CoreMetrics.FILES);
+      Double sum = MeasureUtils.sum(false, childrenMeasures);
+      if (sum != null) {
+        context.saveMeasure(CoreMetrics.FILES, sum);
+      }
+    }
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/ItBranchCoverageDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/ItBranchCoverageDecorator.java
new file mode 100644 (file)
index 0000000..926a34d
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+
+public final class ItBranchCoverageDecorator extends AbstractCoverageDecorator {
+
+  @DependsUpon
+  public List<Metric> dependsUponMetrics() {
+    return ImmutableList.<Metric>of(CoreMetrics.IT_UNCOVERED_CONDITIONS, CoreMetrics.IT_CONDITIONS_TO_COVER,
+      CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER);
+  }
+
+  @Override
+  protected Metric getGeneratedMetric() {
+    return CoreMetrics.IT_BRANCH_COVERAGE;
+  }
+
+  @Override
+  protected Long countElements(DecoratorContext context) {
+    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
+  }
+
+  @Override
+  protected long countCoveredElements(DecoratorContext context) {
+    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS), 0L);
+    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
+
+    return conditions - uncoveredConditions;
+  }
+
+  @Override
+  protected Metric getGeneratedMetricForNewCode() {
+    return CoreMetrics.NEW_IT_BRANCH_COVERAGE;
+  }
+
+  @Override
+  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex);
+  }
+
+  @Override
+  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+    long uncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS), periodIndex, 0L);
+    long conditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex, 0L);
+
+    return conditions - uncoveredConditions;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/ItCoverageDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/ItCoverageDecorator.java
new file mode 100644 (file)
index 0000000..4d99b75
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+
+public final class ItCoverageDecorator extends AbstractCoverageDecorator {
+
+  @DependsUpon
+  public Collection<Metric> usedMetrics() {
+    return ImmutableList.<Metric>of(CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_LINES_TO_COVER,
+      CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.IT_CONDITIONS_TO_COVER, CoreMetrics.IT_UNCOVERED_CONDITIONS,
+      CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS);
+  }
+
+  @Override
+  protected Metric getGeneratedMetric() {
+    return CoreMetrics.IT_COVERAGE;
+  }
+
+  @Override
+  protected Long countElements(DecoratorContext context) {
+    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
+    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
+
+    return lines + conditions;
+  }
+
+  @Override
+  protected long countCoveredElements(DecoratorContext context) {
+    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES), 0L);
+    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
+    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS), 0L);
+    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
+
+    return lines + conditions - uncoveredConditions - uncoveredLines;
+  }
+
+  @Override
+  protected Metric getGeneratedMetricForNewCode() {
+    return CoreMetrics.NEW_IT_COVERAGE;
+  }
+
+  @Override
+  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+    Long newLinesToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex);
+    if (newLinesToCover == null) {
+      return null;
+    }
+
+    long newConditionsToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex, 0L);
+    return newLinesToCover + newConditionsToCover;
+  }
+
+  @Override
+  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+    long newLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex, 0L);
+    long newUncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_LINES), periodIndex, 0L);
+    long newUncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS), periodIndex, 0L);
+    long newConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex, 0L);
+
+    return newLines + newConditions - newUncoveredConditions - newUncoveredLines;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/ItLineCoverageDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/ItLineCoverageDecorator.java
new file mode 100644 (file)
index 0000000..dddddd0
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+
+public final class ItLineCoverageDecorator extends AbstractCoverageDecorator {
+
+  @DependsUpon
+  public List<Metric> dependsUponMetrics() {
+    return ImmutableList.<Metric>of(CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_LINES,
+      CoreMetrics.NEW_IT_LINES_TO_COVER);
+  }
+
+  @Override
+  protected Metric getGeneratedMetric() {
+    return CoreMetrics.IT_LINE_COVERAGE;
+  }
+
+  @Override
+  protected Long countElements(DecoratorContext context) {
+    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
+  }
+
+  @Override
+  protected long countCoveredElements(DecoratorContext context) {
+    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES), 0L);
+    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
+
+    return lines - uncoveredLines;
+  }
+
+  @Override
+  protected Metric getGeneratedMetricForNewCode() {
+    return CoreMetrics.NEW_IT_LINE_COVERAGE;
+  }
+
+  @Override
+  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex);
+  }
+
+  @Override
+  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+    long uncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_LINES), periodIndex, 0L);
+    long lines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex, 0L);
+
+    return lines - uncoveredLines;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/LineCoverageDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/LineCoverageDecorator.java
new file mode 100644 (file)
index 0000000..71c6a03
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Collection;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+import org.sonar.batch.sensor.coverage.CoverageConstants;
+
+public final class LineCoverageDecorator extends AbstractCoverageDecorator {
+
+  @DependsUpon
+  public Collection<Metric> dependsUponMetrics() {
+    return CoverageConstants.LINE_COVERAGE_METRICS;
+  }
+
+  @Override
+  protected Metric getGeneratedMetric() {
+    return CoreMetrics.LINE_COVERAGE;
+  }
+
+  @Override
+  protected Long countElements(DecoratorContext context) {
+    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L);
+  }
+
+  @Override
+  protected long countCoveredElements(DecoratorContext context) {
+    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_LINES), 0L);
+    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L);
+
+    return lines - uncoveredLines;
+  }
+
+  @Override
+  protected Metric getGeneratedMetricForNewCode() {
+    return CoreMetrics.NEW_LINE_COVERAGE;
+  }
+
+  @Override
+  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex);
+  }
+
+  @Override
+  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+    long uncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_LINES), periodIndex, 0L);
+    long lines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex, 0L);
+
+    return lines - uncoveredLines;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/ManualMeasureDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/ManualMeasureDecorator.java
new file mode 100644 (file)
index 0000000..94346b3
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.List;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.Phase;
+import org.sonar.api.batch.RequiresDB;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.jpa.entity.ManualMeasure;
+
+import static com.google.common.base.Preconditions.checkState;
+
+@Phase(name = Phase.Name.PRE)
+@RequiresDB
+public class ManualMeasureDecorator implements Decorator {
+
+  private DatabaseSession session;
+  private MetricFinder metricFinder;
+
+  public ManualMeasureDecorator(DatabaseSession session, MetricFinder metricFinder) {
+    this.session = session;
+    this.metricFinder = metricFinder;
+  }
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    if (resource.getId() != null) {
+      List<ManualMeasure> manualMeasures = session.getResults(ManualMeasure.class, "resourceId", resource.getId());
+      for (ManualMeasure manualMeasure : manualMeasures) {
+        context.saveMeasure(copy(manualMeasure));
+      }
+    }
+  }
+
+  private Measure copy(ManualMeasure manualMeasure) {
+    Metric metric = metricFinder.findById(manualMeasure.getMetricId());
+    checkState(metric != null, "Unable to find manual metric with id: " + manualMeasure.getMetricId());
+
+    Measure measure = new Measure(metric);
+    measure.setValue(manualMeasure.getValue(), 5);
+    measure.setData(manualMeasure.getTextValue());
+    measure.setDescription(manualMeasure.getDescription());
+    return measure;
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName();
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/NewCoverageAggregator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/NewCoverageAggregator.java
new file mode 100644 (file)
index 0000000..1923d52
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import java.util.List;
+import org.apache.commons.lang.ArrayUtils;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorBarriers;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.Scopes;
+
+@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE)
+public final class NewCoverageAggregator implements Decorator {
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  @DependedUpon
+  public List<Metric> generatesNewCoverageMetrics() {
+    return Arrays.<Metric>asList(
+      CoreMetrics.NEW_LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS,
+      CoreMetrics.NEW_IT_LINES_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS,
+      CoreMetrics.NEW_OVERALL_LINES_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES, CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS);
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    if (shouldDecorate(resource)) {
+      int maxPeriods = Qualifiers.isView(resource, true) ? 3 : 5;
+      aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_UNCOVERED_LINES, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_CONDITIONS_TO_COVER, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_UNCOVERED_CONDITIONS, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_IT_LINES_TO_COVER, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_IT_UNCOVERED_LINES, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_OVERALL_LINES_TO_COVER, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER, maxPeriods);
+      aggregate(context, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS, maxPeriods);
+    }
+  }
+
+  void aggregate(DecoratorContext context, Metric metric, int maxPeriods) {
+    int[] variations = {0, 0, 0, 0, 0};
+    boolean[] hasValues = {false, false, false, false, false};
+    for (Measure child : context.getChildrenMeasures(metric)) {
+      for (int indexPeriod = 1; indexPeriod <= maxPeriods; indexPeriod++) {
+        Double variation = child.getVariation(indexPeriod);
+        if (variation != null) {
+          variations[indexPeriod - 1] = variations[indexPeriod - 1] + variation.intValue();
+          hasValues[indexPeriod - 1] = true;
+        }
+      }
+    }
+
+    if (ArrayUtils.contains(hasValues, true)) {
+      Measure measure = new Measure(metric);
+      for (int index = 0; index < 5; index++) {
+        if (hasValues[index]) {
+          measure.setVariation(index + 1, (double) variations[index]);
+        }
+      }
+      context.saveMeasure(measure);
+    }
+  }
+
+  boolean shouldDecorate(Resource resource) {
+    return Scopes.isHigherThan(resource, Scopes.FILE);
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/NewCoverageFileAnalyzer.java b/sonar-batch/src/main/java/org/sonar/batch/compute/NewCoverageFileAnalyzer.java
new file mode 100644 (file)
index 0000000..ba36d5b
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.List;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Metric;
+import org.sonar.batch.components.TimeMachineConfiguration;
+import org.sonar.batch.index.BatchComponentCache;
+import org.sonar.batch.report.ReportPublisher;
+
+public class NewCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {
+
+  public NewCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
+    super(timeMachineConfiguration, publishReportJob, resourceCache);
+  }
+
+  NewCoverageFileAnalyzer(List<PeriodStruct> structs, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
+    super(structs, publishReportJob, resourceCache);
+  }
+
+  @Override
+  public Metric getCoverageLineHitsDataMetric() {
+    return CoreMetrics.COVERAGE_LINE_HITS_DATA;
+  }
+
+  @Override
+  public Metric getConditionsByLineMetric() {
+    return CoreMetrics.CONDITIONS_BY_LINE;
+  }
+
+  @Override
+  public Metric getCoveredConditionsByLineMetric() {
+    return CoreMetrics.COVERED_CONDITIONS_BY_LINE;
+  }
+
+  @Override
+  public Metric getNewLinesToCoverMetric() {
+    return CoreMetrics.NEW_LINES_TO_COVER;
+  }
+
+  @Override
+  public Metric getNewUncoveredLinesMetric() {
+    return CoreMetrics.NEW_UNCOVERED_LINES;
+  }
+
+  @Override
+  public Metric getNewConditionsToCoverMetric() {
+    return CoreMetrics.NEW_CONDITIONS_TO_COVER;
+  }
+
+  @Override
+  public Metric getNewUncoveredConditionsMetric() {
+    return CoreMetrics.NEW_UNCOVERED_CONDITIONS;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/NewItCoverageFileAnalyzer.java b/sonar-batch/src/main/java/org/sonar/batch/compute/NewItCoverageFileAnalyzer.java
new file mode 100644 (file)
index 0000000..48d6230
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Metric;
+import org.sonar.batch.components.TimeMachineConfiguration;
+import org.sonar.batch.index.BatchComponentCache;
+import org.sonar.batch.report.ReportPublisher;
+
+public class NewItCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {
+
+  public NewItCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
+    super(timeMachineConfiguration, publishReportJob, resourceCache);
+  }
+
+  @Override
+  public Metric getCoverageLineHitsDataMetric() {
+    return CoreMetrics.IT_COVERAGE_LINE_HITS_DATA;
+  }
+
+  @Override
+  public Metric getConditionsByLineMetric() {
+    return CoreMetrics.IT_CONDITIONS_BY_LINE;
+  }
+
+  @Override
+  public Metric getCoveredConditionsByLineMetric() {
+    return CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE;
+  }
+
+  @Override
+  public Metric getNewLinesToCoverMetric() {
+    return CoreMetrics.NEW_IT_LINES_TO_COVER;
+  }
+
+  @Override
+  public Metric getNewUncoveredLinesMetric() {
+    return CoreMetrics.NEW_IT_UNCOVERED_LINES;
+  }
+
+  @Override
+  public Metric getNewConditionsToCoverMetric() {
+    return CoreMetrics.NEW_IT_CONDITIONS_TO_COVER;
+  }
+
+  @Override
+  public Metric getNewUncoveredConditionsMetric() {
+    return CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/NewOverallCoverageFileAnalyzer.java b/sonar-batch/src/main/java/org/sonar/batch/compute/NewOverallCoverageFileAnalyzer.java
new file mode 100644 (file)
index 0000000..1c2688c
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Metric;
+import org.sonar.batch.components.TimeMachineConfiguration;
+import org.sonar.batch.index.BatchComponentCache;
+import org.sonar.batch.report.ReportPublisher;
+
+public class NewOverallCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {
+
+  public NewOverallCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
+    super(timeMachineConfiguration, publishReportJob, resourceCache);
+  }
+
+  @Override
+  public Metric getCoverageLineHitsDataMetric() {
+    return CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA;
+  }
+
+  @Override
+  public Metric getConditionsByLineMetric() {
+    return CoreMetrics.OVERALL_CONDITIONS_BY_LINE;
+  }
+
+  @Override
+  public Metric getCoveredConditionsByLineMetric() {
+    return CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE;
+  }
+
+  @Override
+  public Metric getNewLinesToCoverMetric() {
+    return CoreMetrics.NEW_OVERALL_LINES_TO_COVER;
+  }
+
+  @Override
+  public Metric getNewUncoveredLinesMetric() {
+    return CoreMetrics.NEW_OVERALL_UNCOVERED_LINES;
+  }
+
+  @Override
+  public Metric getNewConditionsToCoverMetric() {
+    return CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER;
+  }
+
+  @Override
+  public Metric getNewUncoveredConditionsMetric() {
+    return CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/OverallBranchCoverageDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/OverallBranchCoverageDecorator.java
new file mode 100644 (file)
index 0000000..271cfcd
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+
+public final class OverallBranchCoverageDecorator extends AbstractCoverageDecorator {
+
+  @DependsUpon
+  public List<Metric> dependsUponMetrics() {
+    return ImmutableList.<Metric>of(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS, CoreMetrics.OVERALL_CONDITIONS_TO_COVER,
+      CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS, CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER);
+  }
+
+  @Override
+  protected Metric getGeneratedMetric() {
+    return CoreMetrics.OVERALL_BRANCH_COVERAGE;
+  }
+
+  @Override
+  protected Long countElements(DecoratorContext context) {
+    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER), 0L);
+  }
+
+  @Override
+  protected long countCoveredElements(DecoratorContext context) {
+    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS), 0L);
+    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER), 0L);
+
+    return conditions - uncoveredConditions;
+  }
+
+  @Override
+  protected Metric getGeneratedMetricForNewCode() {
+    return CoreMetrics.NEW_OVERALL_BRANCH_COVERAGE;
+  }
+
+  @Override
+  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER), periodIndex);
+  }
+
+  @Override
+  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+    long uncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS), periodIndex, 0L);
+    long conditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER), periodIndex, 0L);
+
+    return conditions - uncoveredConditions;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/OverallCoverageDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/OverallCoverageDecorator.java
new file mode 100644 (file)
index 0000000..c4a4d03
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+
+public final class OverallCoverageDecorator extends AbstractCoverageDecorator {
+
+  @DependsUpon
+  public Collection<Metric> usedMetrics() {
+    return ImmutableList.<Metric>of(CoreMetrics.OVERALL_LINES_TO_COVER, CoreMetrics.OVERALL_UNCOVERED_LINES, CoreMetrics.NEW_OVERALL_LINES_TO_COVER,
+      CoreMetrics.NEW_OVERALL_UNCOVERED_LINES, CoreMetrics.OVERALL_CONDITIONS_TO_COVER, CoreMetrics.OVERALL_UNCOVERED_CONDITIONS,
+      CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS);
+  }
+
+  @Override
+  protected Metric getGeneratedMetric() {
+    return CoreMetrics.OVERALL_COVERAGE;
+  }
+
+  @Override
+  protected Long countElements(DecoratorContext context) {
+    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER), 0L);
+    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER), 0L);
+
+    return lines + conditions;
+  }
+
+  @Override
+  protected long countCoveredElements(DecoratorContext context) {
+    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_LINES), 0L);
+    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER), 0L);
+    long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS), 0L);
+    long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER), 0L);
+
+    return lines + conditions - uncoveredConditions - uncoveredLines;
+  }
+
+  @Override
+  protected Metric getGeneratedMetricForNewCode() {
+    return CoreMetrics.NEW_OVERALL_COVERAGE;
+  }
+
+  @Override
+  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+    Long newLinesToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_LINES_TO_COVER), periodIndex);
+    if (newLinesToCover == null) {
+      return null;
+    }
+
+    long newConditionsToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER), periodIndex, 0L);
+
+    return newLinesToCover + newConditionsToCover;
+  }
+
+  @Override
+  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+    long newLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_LINES_TO_COVER), periodIndex, 0L);
+    long newUncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES), periodIndex, 0L);
+    long newUncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS), periodIndex, 0L);
+    long newConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER), periodIndex, 0L);
+
+    return newLines + newConditions - newUncoveredConditions - newUncoveredLines;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/OverallLineCoverageDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/OverallLineCoverageDecorator.java
new file mode 100644 (file)
index 0000000..a41440e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+
+public final class OverallLineCoverageDecorator extends AbstractCoverageDecorator {
+
+  @DependsUpon
+  public List<Metric> dependsUponMetrics() {
+    return ImmutableList.<Metric>of(CoreMetrics.OVERALL_UNCOVERED_LINES, CoreMetrics.OVERALL_LINES_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES,
+      CoreMetrics.NEW_OVERALL_LINES_TO_COVER);
+  }
+
+  @Override
+  protected Metric getGeneratedMetric() {
+    return CoreMetrics.OVERALL_LINE_COVERAGE;
+  }
+
+  @Override
+  protected Long countElements(DecoratorContext context) {
+    return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER), 0L);
+  }
+
+  @Override
+  protected long countCoveredElements(DecoratorContext context) {
+    long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_LINES), 0L);
+    long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER), 0L);
+
+    return lines - uncoveredLines;
+  }
+
+  @Override
+  protected Metric getGeneratedMetricForNewCode() {
+    return CoreMetrics.NEW_OVERALL_LINE_COVERAGE;
+  }
+
+  @Override
+  protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+    return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_LINES_TO_COVER), periodIndex);
+  }
+
+  @Override
+  protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+    long uncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES), periodIndex, 0L);
+    long lines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_OVERALL_LINES_TO_COVER), periodIndex, 0L);
+
+    return lines - uncoveredLines;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/SeverityUtils.java b/sonar-batch/src/main/java/org/sonar/batch/compute/SeverityUtils.java
new file mode 100644 (file)
index 0000000..fd92039
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.rules.RulePriority;
+
+final class SeverityUtils {
+  private SeverityUtils() {
+    // only static methods
+  }
+
+  static Metric severityToIssueMetric(RulePriority severity) {
+    Metric metric;
+    if (severity.equals(RulePriority.BLOCKER)) {
+      metric = CoreMetrics.BLOCKER_VIOLATIONS;
+    } else if (severity.equals(RulePriority.CRITICAL)) {
+      metric = CoreMetrics.CRITICAL_VIOLATIONS;
+    } else if (severity.equals(RulePriority.MAJOR)) {
+      metric = CoreMetrics.MAJOR_VIOLATIONS;
+    } else if (severity.equals(RulePriority.MINOR)) {
+      metric = CoreMetrics.MINOR_VIOLATIONS;
+    } else if (severity.equals(RulePriority.INFO)) {
+      metric = CoreMetrics.INFO_VIOLATIONS;
+    } else {
+      throw new IllegalArgumentException("Unsupported severity: " + severity);
+    }
+    return metric;
+  }
+
+  static Metric severityToNewMetricIssue(RulePriority severity) {
+    Metric metric;
+    if (severity.equals(RulePriority.BLOCKER)) {
+      metric = CoreMetrics.NEW_BLOCKER_VIOLATIONS;
+    } else if (severity.equals(RulePriority.CRITICAL)) {
+      metric = CoreMetrics.NEW_CRITICAL_VIOLATIONS;
+    } else if (severity.equals(RulePriority.MAJOR)) {
+      metric = CoreMetrics.NEW_MAJOR_VIOLATIONS;
+    } else if (severity.equals(RulePriority.MINOR)) {
+      metric = CoreMetrics.NEW_MINOR_VIOLATIONS;
+    } else if (severity.equals(RulePriority.INFO)) {
+      metric = CoreMetrics.NEW_INFO_VIOLATIONS;
+    } else {
+      throw new IllegalArgumentException("Unsupported severity: " + severity);
+    }
+    return metric;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/TimeMachineConfigurationPersister.java b/sonar-batch/src/main/java/org/sonar/batch/compute/TimeMachineConfigurationPersister.java
new file mode 100644 (file)
index 0000000..1255c64
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.List;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorBarriers;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.RequiresDB;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.ResourceUtils;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.TimeMachineConfiguration;
+import org.sonar.batch.index.BatchComponentCache;
+
+import static org.sonar.api.utils.DateUtils.dateToLong;
+
+@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE)
+@RequiresDB
+public final class TimeMachineConfigurationPersister implements Decorator {
+
+  private final TimeMachineConfiguration timeMachineConfiguration;
+  private BatchComponentCache resourceCache;
+  private DatabaseSession session;
+
+  public TimeMachineConfigurationPersister(TimeMachineConfiguration timeMachineConfiguration, BatchComponentCache resourceCache, DatabaseSession session) {
+    this.timeMachineConfiguration = timeMachineConfiguration;
+    this.resourceCache = resourceCache;
+    this.session = session;
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    if (ResourceUtils.isProject(resource)) {
+      persistConfiguration(resource);
+    }
+  }
+
+  void persistConfiguration(Resource module) {
+    List<PastSnapshot> pastSnapshots = timeMachineConfiguration.getProjectPastSnapshots();
+    Snapshot projectSnapshot = resourceCache.get(module).snapshot();
+    for (PastSnapshot pastSnapshot : pastSnapshots) {
+      Snapshot snapshot = session.reattach(Snapshot.class, projectSnapshot.getId());
+      updatePeriodParams(snapshot, pastSnapshot);
+      updatePeriodParams(projectSnapshot, pastSnapshot);
+      session.save(snapshot);
+    }
+    session.commit();
+  }
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  private void updatePeriodParams(Snapshot snapshot, PastSnapshot pastSnapshot) {
+    int periodIndex = pastSnapshot.getIndex();
+    snapshot.setPeriodMode(periodIndex, pastSnapshot.getMode());
+    snapshot.setPeriodModeParameter(periodIndex, pastSnapshot.getModeParameter());
+    snapshot.setPeriodDateMs(periodIndex, dateToLong(pastSnapshot.getDate()));
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/UnitTestDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/UnitTestDecorator.java
new file mode 100644 (file)
index 0000000..3f5d641
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MeasureUtils;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.ResourceUtils;
+
+public class UnitTestDecorator implements Decorator {
+
+  @DependedUpon
+  public List<Metric> generatesMetrics() {
+    return Arrays.<Metric>asList(CoreMetrics.TEST_EXECUTION_TIME, CoreMetrics.TESTS, CoreMetrics.TEST_ERRORS, CoreMetrics.TEST_FAILURES, CoreMetrics.TEST_SUCCESS_DENSITY);
+  }
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return !Project.AnalysisType.STATIC.equals(project.getAnalysisType());
+  }
+
+  public boolean shouldDecorateResource(Resource resource) {
+    return ResourceUtils.isUnitTestFile(resource) || !ResourceUtils.isEntity(resource);
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    if (shouldDecorateResource(resource)) {
+      sumChildren(context, CoreMetrics.TEST_EXECUTION_TIME);
+      sumChildren(context, CoreMetrics.SKIPPED_TESTS);
+      Double tests = sumChildren(context, CoreMetrics.TESTS);
+      Double errors = sumChildren(context, CoreMetrics.TEST_ERRORS);
+      Double failures = sumChildren(context, CoreMetrics.TEST_FAILURES);
+
+      if (isPositive(tests, true) && isPositive(errors, false) && isPositive(failures, false)) {
+        Double errorsAndFailuresRatio = (errors + failures) * 100.0 / tests;
+        context.saveMeasure(CoreMetrics.TEST_SUCCESS_DENSITY, 100.0 - errorsAndFailuresRatio);
+      }
+    }
+  }
+
+  private boolean isPositive(Double d, boolean strict) {
+    return d != null && (strict ? d > 0.0 : d >= 0.0);
+  }
+
+  private Double sumChildren(DecoratorContext jobContext, Metric metric) {
+    Collection<Measure> childrenMeasures = jobContext.getChildrenMeasures(metric);
+    if (childrenMeasures != null && !childrenMeasures.isEmpty()) {
+      Double sum = 0.0;
+      boolean hasChildrenMeasures = false;
+      for (Measure measure : childrenMeasures) {
+        if (MeasureUtils.hasValue(measure)) {
+          sum += measure.getValue();
+          hasChildrenMeasures = true;
+        }
+      }
+      if (hasChildrenMeasures) {
+        jobContext.saveMeasure(metric, sum);
+        return sum;
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName();
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/VariationDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/VariationDecorator.java
new file mode 100644 (file)
index 0000000..f3885ef
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorBarriers;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.batch.RequiresDB;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MeasuresFilters;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.measures.RuleMeasure;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.technicaldebt.batch.Characteristic;
+import org.sonar.batch.components.PastMeasuresLoader;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.TimeMachineConfiguration;
+
+@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE)
+@RequiresDB
+public class VariationDecorator implements Decorator {
+
+  private List<PastSnapshot> projectPastSnapshots;
+  private MetricFinder metricFinder;
+  private PastMeasuresLoader pastMeasuresLoader;
+  private RuleFinder ruleFinder;
+
+  public VariationDecorator(PastMeasuresLoader pastMeasuresLoader, MetricFinder metricFinder, TimeMachineConfiguration timeMachineConfiguration, RuleFinder ruleFinder) {
+    this(pastMeasuresLoader, metricFinder, timeMachineConfiguration.getProjectPastSnapshots(), ruleFinder);
+  }
+
+  VariationDecorator(PastMeasuresLoader pastMeasuresLoader, MetricFinder metricFinder, List<PastSnapshot> projectPastSnapshots, RuleFinder ruleFinder) {
+    this.pastMeasuresLoader = pastMeasuresLoader;
+    this.projectPastSnapshots = projectPastSnapshots;
+    this.metricFinder = metricFinder;
+    this.ruleFinder = ruleFinder;
+  }
+
+  @Override
+  public boolean shouldExecuteOnProject(Project project) {
+    return true;
+  }
+
+  @DependsUpon
+  public Collection<Metric> dependsUponMetrics() {
+    return pastMeasuresLoader.getMetrics();
+  }
+
+  @Override
+  public void decorate(Resource resource, DecoratorContext context) {
+    for (PastSnapshot projectPastSnapshot : projectPastSnapshots) {
+      if (shouldComputeVariation(resource)) {
+        computeVariation(resource, context, projectPastSnapshot);
+      }
+    }
+  }
+
+  boolean shouldComputeVariation(Resource resource) {
+    if (Scopes.FILE.equals(resource.getScope()) && !Qualifiers.UNIT_TEST_FILE.equals(resource.getQualifier())) {
+      return false;
+    }
+
+    // measures on files are currently purged, so past measures are not available on files
+    return StringUtils.equals(Scopes.PROJECT, resource.getScope()) || StringUtils.equals(Scopes.DIRECTORY, resource.getScope());
+  }
+
+  private void computeVariation(Resource resource, DecoratorContext context, PastSnapshot pastSnapshot) {
+    List<Object[]> pastMeasures = pastMeasuresLoader.getPastMeasures(resource, pastSnapshot);
+    compareWithPastMeasures(context, pastSnapshot.getIndex(), pastMeasures);
+  }
+
+  private void compareWithPastMeasures(DecoratorContext context, int index, List<Object[]> pastMeasures) {
+    Map<MeasureKey, Object[]> pastMeasuresByKey = new HashMap<>();
+    for (Object[] pastMeasure : pastMeasures) {
+      pastMeasuresByKey.put(new MeasureKey(pastMeasure), pastMeasure);
+    }
+
+    // for each measure, search equivalent past measure
+    for (Measure measure : context.getMeasures(MeasuresFilters.all())) {
+      // compare with past measure
+      Integer metricId = measure.getMetric().getId();
+      if (metricId == null) {
+        Metric metric = metricFinder.findByKey(measure.getMetric().getKey());
+        if (metric == null) {
+          throw new IllegalStateException("Unknow metric with key: " + measure.getMetric().getKey());
+        }
+        metricId = metric.getId();
+      }
+      Characteristic characteristic = measure.getCharacteristic();
+      Integer characteristicId = characteristic != null ? characteristic.id() : null;
+      Integer personId = measure.getPersonId();
+      Integer ruleId = null;
+      if (measure instanceof RuleMeasure) {
+        Rule rule = ruleFinder.findByKey(((RuleMeasure) measure).ruleKey());
+        if (rule != null) {
+          ruleId = rule.getId();
+        }
+      }
+
+      Object[] pastMeasure = pastMeasuresByKey.get(new MeasureKey(metricId, characteristicId, personId, ruleId));
+      if (updateVariation(measure, pastMeasure, index)) {
+        context.saveMeasure(measure);
+      }
+    }
+  }
+
+  boolean updateVariation(Measure measure, Object[] pastMeasure, int index) {
+    if (pastMeasure != null && PastMeasuresLoader.hasValue(pastMeasure) && measure.getValue() != null) {
+      double variation = measure.getValue() - PastMeasuresLoader.getValue(pastMeasure);
+      measure.setVariation(index, variation);
+      return true;
+    }
+    return false;
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName();
+  }
+
+  static final class MeasureKey {
+    int metricId;
+    Integer characteristicId;
+    Integer personId;
+    Integer ruleId;
+
+    MeasureKey(Object[] pastFields) {
+      metricId = PastMeasuresLoader.getMetricId(pastFields);
+      characteristicId = PastMeasuresLoader.getCharacteristicId(pastFields);
+      personId = PastMeasuresLoader.getPersonId(pastFields);
+      ruleId = PastMeasuresLoader.getRuleId(pastFields);
+    }
+
+    MeasureKey(int metricId, @Nullable Integer characteristicId, @Nullable Integer personId, @Nullable Integer ruleId) {
+      this.metricId = metricId;
+      this.characteristicId = characteristicId;
+      this.personId = personId;
+      this.ruleId = ruleId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) {
+        return true;
+      }
+      if (o == null || getClass() != o.getClass()) {
+        return false;
+      }
+      MeasureKey that = (MeasureKey) o;
+      if (metricId != that.metricId) {
+        return false;
+      }
+      if (characteristicId != null ? !characteristicId.equals(that.characteristicId) : that.characteristicId != null) {
+        return false;
+      }
+      if (personId != null ? !personId.equals(that.personId) : that.personId != null) {
+        return false;
+      }
+      if (ruleId != null ? !ruleId.equals(that.ruleId) : that.ruleId != null) {
+        return false;
+      }
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int result = metricId;
+      result = 31 * result + (characteristicId != null ? characteristicId.hashCode() : 0);
+      result = 31 * result + (personId != null ? personId.hashCode() : 0);
+      result = 31 * result + (ruleId != null ? ruleId.hashCode() : 0);
+      return result;
+    }
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/compute/package-info.java
new file mode 100644 (file)
index 0000000..7fd21f3
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.batch.compute;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/ApplyProjectRolesDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/ApplyProjectRolesDecoratorTest.java
new file mode 100644 (file)
index 0000000..cd48e6a
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.resources.Project;
+import org.sonar.api.security.ResourcePermissions;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ApplyProjectRolesDecoratorTest {
+
+  private ResourcePermissions resourcePermissions;
+  private ApplyProjectRolesDecorator decorator;
+
+  @Before
+  public void init() {
+    resourcePermissions = mock(ResourcePermissions.class);
+    decorator = new ApplyProjectRolesDecorator(resourcePermissions);
+  }
+
+  @Test
+  public void alwaysExecute() {
+    assertThat(decorator.shouldExecuteOnProject(new Project("project"))).isTrue();
+  }
+
+  @Test
+  public void doNotGrantDefaultRolesWhenExistingPermissions() {
+    Project project = new Project("project");
+    project.setId(10);
+    when(resourcePermissions.hasRoles(project)).thenReturn(true);
+
+    decorator.decorate(project, null);
+
+    verify(resourcePermissions, never()).grantDefaultRoles(project);
+  }
+
+  @Test
+  public void doNotApplySecurityOnModules() {
+    Project project = new Project("project");
+    Project module = new Project("module").setParent(project);
+    module.setId(10);
+    when(resourcePermissions.hasRoles(project)).thenReturn(false);
+
+    decorator.decorate(module, null);
+
+    verify(resourcePermissions, never()).grantDefaultRoles(module);
+  }
+
+  @Test
+  public void grantDefaultRolesWhenNoPermissions() {
+    Project project = new Project("project");
+    project.setId(10);
+    when(resourcePermissions.hasRoles(project)).thenReturn(false);
+
+    decorator.decorate(project, null);
+
+    verify(resourcePermissions).grantDefaultRoles(project);
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/BranchCoverageDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/BranchCoverageDecoratorTest.java
new file mode 100644 (file)
index 0000000..a7f9e09
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class BranchCoverageDecoratorTest {
+  private final BranchCoverageDecorator decorator = new BranchCoverageDecorator();
+  private final Project resource = mock(Project.class);
+
+  @Before
+  public void setUp() {
+    when(resource.getScope()).thenReturn(Scopes.PROJECT);
+    when(resource.getQualifier()).thenReturn(Qualifiers.PROJECT);
+  }
+
+  @Test
+  public void shouldSaveBranchCoverage() {
+    DecoratorContext context = mockContext(20, 15);
+
+    decorator.decorate(resource, context);
+
+    verify(context).saveMeasure(CoreMetrics.BRANCH_COVERAGE, 25.0);
+  }
+
+  @Test
+  public void shouldNotSaveBranchCoverageIfMissingConditions() {
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    decorator.decorate(resource, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.BRANCH_COVERAGE), anyDouble());
+  }
+
+  private static DecoratorContext mockContext(int conditions, int uncoveredConditions) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.CONDITIONS_TO_COVER, (double) conditions));
+    when(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, (double) uncoveredConditions));
+    return context;
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/CommentDensityDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/CommentDensityDecoratorTest.java
new file mode 100644 (file)
index 0000000..dadbb94
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.test.IsMeasure;
+
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class CommentDensityDecoratorTest {
+
+  @Test
+  public void densityIsBalancedByNcloc() {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 300.0));
+    when(context.getMeasure(CoreMetrics.COMMENT_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 200.0));
+    CommentDensityDecorator decorator = new CommentDensityDecorator();
+    decorator.decorate(null, context);
+    // 200 / (200 + 300) = 40%
+    verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY, 40.0)));
+  }
+
+  @Test
+  public void noDensityIfUnknownComments() {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 300.0));
+    CommentDensityDecorator decorator = new CommentDensityDecorator();
+    decorator.decorate(null, context);
+    verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY)));
+  }
+
+  @Test
+  public void noDensityIfZeroNcloc() {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 0.0));
+    when(context.getMeasure(CoreMetrics.COMMENT_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 0.0));
+    CommentDensityDecorator decorator = new CommentDensityDecorator();
+    decorator.decorate(null, context);
+    verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY)));
+  }
+
+  @Test
+  public void zeroDensityWhenZeroComments() {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 40.0));
+    when(context.getMeasure(CoreMetrics.COMMENT_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 0.0));
+    CommentDensityDecorator decorator = new CommentDensityDecorator();
+    decorator.decorate(null, context);
+    verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY, 0.0)));
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/CountFalsePositivesDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/CountFalsePositivesDecoratorTest.java
new file mode 100644 (file)
index 0000000..37eea57
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.component.ResourcePerspectives;
+import org.sonar.api.issue.Issuable;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Project;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.java.api.JavaClass;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+public class CountFalsePositivesDecoratorTest {
+
+  ResourcePerspectives perspectives = mock(ResourcePerspectives.class);
+  CountFalsePositivesDecorator decorator = new CountFalsePositivesDecorator(perspectives);
+
+  @Test
+  public void should_count_false_positives() {
+    DefaultIssue falsePositive = new DefaultIssue().setRuleKey(RuleKey.parse("squid:AvoidCycles"))
+      .setResolution(Issue.RESOLUTION_FALSE_POSITIVE).setStatus(Issue.STATUS_RESOLVED);
+    DefaultIssue fixed = new DefaultIssue().setRuleKey(RuleKey.parse("squid:AvoidCycles"))
+      .setResolution(Issue.RESOLUTION_FIXED).setStatus(Issue.STATUS_RESOLVED);
+
+    File file = File.create("foo.c");
+    Issuable issuable = mock(Issuable.class);
+    when(perspectives.as(Issuable.class, file)).thenReturn(issuable);
+    when(issuable.resolvedIssues()).thenReturn(Arrays.<Issue>asList(falsePositive, fixed));
+
+    DecoratorContext context = mock(DecoratorContext.class);
+    decorator.decorate(file, context);
+
+    verify(context).saveMeasure(CoreMetrics.FALSE_POSITIVE_ISSUES, 1.0);
+  }
+
+  @Test
+  public void should_declare_metadata() {
+    assertThat(decorator.shouldExecuteOnProject(new Project("foo"))).isTrue();
+    assertThat(decorator.generatesFalsePositiveMeasure()).isEqualTo(CoreMetrics.FALSE_POSITIVE_ISSUES);
+    assertThat(decorator.toString()).isEqualTo("CountFalsePositivesDecorator");
+  }
+
+  @Test
+  public void should_ignore_classes_and_methods() {
+    JavaClass javaClass = JavaClass.create("Foo.java");
+    when(perspectives.as(Issuable.class, javaClass)).thenReturn(null);
+
+    DecoratorContext context = mock(DecoratorContext.class);
+    decorator.decorate(javaClass, context);
+
+    verifyZeroInteractions(context);
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/CountUnresolvedIssuesDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/CountUnresolvedIssuesDecoratorTest.java
new file mode 100644 (file)
index 0000000..8473e0a
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import com.google.common.collect.Lists;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.commons.lang.time.DateUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.component.ResourcePerspectives;
+import org.sonar.api.issue.Issuable;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MeasuresFilter;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.RuleMeasure;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RulePriority;
+import org.sonar.api.test.IsRuleMeasure;
+import org.sonar.batch.components.Period;
+import org.sonar.batch.components.TimeMachineConfiguration;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyDouble;
+import static org.mockito.Mockito.argThat;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+public class CountUnresolvedIssuesDecoratorTest {
+
+  CountUnresolvedIssuesDecorator decorator;
+  TimeMachineConfiguration timeMachineConfiguration;
+  Issuable issuable;
+  DecoratorContext context;
+  Resource resource;
+  Project project;
+  Rule ruleA1;
+  Rule ruleA2;
+  Rule ruleB1;
+  Date rightNow;
+  Date tenDaysAgo;
+  Date afterTenDaysAgo;
+  Date fiveDaysAgo;
+  Date afterFiveDaysAgo;
+  Date sameSecond;
+
+  @Before
+  public void before() {
+    ruleA1 = Rule.create().setRepositoryKey("ruleA1").setKey("ruleA1").setName("nameA1");
+    ruleA2 = Rule.create().setRepositoryKey("ruleA2").setKey("ruleA2").setName("nameA2");
+    ruleB1 = Rule.create().setRepositoryKey("ruleB1").setKey("ruleB1").setName("nameB1");
+
+    rightNow = new Date();
+    tenDaysAgo = DateUtils.addDays(rightNow, -10);
+    afterTenDaysAgo = DateUtils.addDays(tenDaysAgo, 1);
+    fiveDaysAgo = DateUtils.addDays(rightNow, -5);
+    afterFiveDaysAgo = DateUtils.addDays(fiveDaysAgo, 1);
+    sameSecond = DateUtils.truncate(rightNow, Calendar.SECOND);
+
+    timeMachineConfiguration = mock(TimeMachineConfiguration.class);
+    when(timeMachineConfiguration.periods()).thenReturn(newArrayList(new Period(1, afterFiveDaysAgo), new Period(2, afterTenDaysAgo)));
+
+    project = mock(Project.class);
+    resource = mock(Resource.class);
+    context = mock(DecoratorContext.class);
+    when(context.getResource()).thenReturn(resource);
+    when(context.getProject()).thenReturn(project);
+    when(context.getMeasure(CoreMetrics.NEW_VIOLATIONS)).thenReturn(null);
+
+    issuable = mock(Issuable.class);
+    ResourcePerspectives perspectives = mock(ResourcePerspectives.class);
+    when(perspectives.as(Issuable.class, resource)).thenReturn(issuable);
+    decorator = new CountUnresolvedIssuesDecorator(perspectives, timeMachineConfiguration);
+  }
+
+  @Test
+  public void should_be_depended_upon_metric() {
+    assertThat(decorator.generatesIssuesMetrics()).hasSize(15);
+  }
+
+  @Test
+  public void should_count_issues() {
+    when(resource.getScope()).thenReturn(Scopes.PROJECT);
+    when(issuable.issues()).thenReturn(createIssues());
+    when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Collections.<Measure>emptyList());
+
+    decorator.decorate(resource, context);
+
+    verify(context).saveMeasure(CoreMetrics.VIOLATIONS, 4.0);
+  }
+
+  @Test
+  public void should_do_nothing_when_issuable_is_null() {
+    ResourcePerspectives perspectives = mock(ResourcePerspectives.class);
+    when(perspectives.as(Issuable.class, resource)).thenReturn(null);
+    CountUnresolvedIssuesDecorator decorator = new CountUnresolvedIssuesDecorator(perspectives, timeMachineConfiguration);
+
+    decorator.decorate(resource, context);
+
+    verifyZeroInteractions(context);
+  }
+
+  /**
+   * See http://jira.codehaus.org/browse/SONAR-1729
+   */
+  @Test
+  public void should_not_count_issues_if_measure_already_exists() {
+    when(resource.getScope()).thenReturn(Scopes.PROJECT);
+    when(issuable.issues()).thenReturn(createIssues());
+    when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Collections.<Measure>emptyList());
+    when(context.getMeasure(CoreMetrics.VIOLATIONS)).thenReturn(new Measure(CoreMetrics.VIOLATIONS, 3000.0));
+    when(context.getMeasure(CoreMetrics.MAJOR_VIOLATIONS)).thenReturn(new Measure(CoreMetrics.MAJOR_VIOLATIONS, 500.0));
+
+    decorator.decorate(resource, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.VIOLATIONS), anyDouble());// not changed
+    verify(context, never()).saveMeasure(eq(CoreMetrics.MAJOR_VIOLATIONS), anyDouble());// not changed
+    verify(context, times(1)).saveMeasure(eq(CoreMetrics.CRITICAL_VIOLATIONS), anyDouble());// did not exist
+  }
+
+  @Test
+  public void should_save_zero_on_projects() {
+    when(resource.getScope()).thenReturn(Scopes.PROJECT);
+    when(issuable.issues()).thenReturn(Lists.<Issue>newArrayList());
+    when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Collections.<Measure>emptyList());
+
+    decorator.decorate(resource, context);
+
+    verify(context).saveMeasure(CoreMetrics.VIOLATIONS, 0.0);
+  }
+
+  @Test
+  public void should_save_zero_on_directories() {
+    when(resource.getScope()).thenReturn(Scopes.DIRECTORY);
+    when(issuable.issues()).thenReturn(Lists.<Issue>newArrayList());
+    when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Collections.<Measure>emptyList());
+
+    decorator.decorate(resource, context);
+
+    verify(context).saveMeasure(CoreMetrics.VIOLATIONS, 0.0);
+  }
+
+  @Test
+  public void should_count_issues_by_severity() {
+    when(resource.getScope()).thenReturn(Scopes.PROJECT);
+    when(issuable.issues()).thenReturn(createIssues());
+    when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Collections.<Measure>emptyList());
+
+    decorator.decorate(resource, context);
+
+    verify(context).saveMeasure(CoreMetrics.BLOCKER_VIOLATIONS, 0.0);
+    verify(context).saveMeasure(CoreMetrics.CRITICAL_VIOLATIONS, 2.0);
+    verify(context).saveMeasure(CoreMetrics.MAJOR_VIOLATIONS, 1.0);
+    verify(context).saveMeasure(CoreMetrics.MINOR_VIOLATIONS, 1.0);
+    verify(context).saveMeasure(CoreMetrics.INFO_VIOLATIONS, 0.0);
+  }
+
+  @Test
+  public void should_count_issues_per_rule() {
+    List<Issue> issues = newArrayList();
+    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()));
+    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()));
+    issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setSeverity(RulePriority.MAJOR.name()));
+    when(issuable.issues()).thenReturn(issues);
+
+    decorator.decorate(resource, context);
+
+    verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.CRITICAL_VIOLATIONS, ruleA1, 2.0)));
+    verify(context, never()).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.MAJOR_VIOLATIONS, ruleA1, 0.0)));
+    verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.MAJOR_VIOLATIONS, ruleA2, 1.0)));
+  }
+
+  @Test
+  public void same_rule_should_have_different_severities() {
+    List<Issue> issues = newArrayList();
+    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()));
+    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()));
+    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.MINOR.name()));
+    when(issuable.issues()).thenReturn(issues);
+
+    decorator.decorate(resource, context);
+
+    verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.CRITICAL_VIOLATIONS, ruleA1, 2.0)));
+    verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.MINOR_VIOLATIONS, ruleA1, 1.0)));
+  }
+
+  @Test
+  public void should_count_issues_after_date() {
+    List<Issue> issues = createIssuesForNewMetrics();
+
+    assertThat(decorator.countIssuesAfterDate(null, fiveDaysAgo)).isEqualTo(0);
+    assertThat(decorator.countIssuesAfterDate(issues, fiveDaysAgo)).isEqualTo(1); // 1 rightNow
+    assertThat(decorator.countIssuesAfterDate(issues, tenDaysAgo)).isEqualTo(3); // 1 rightNow + 2 fiveDaysAgo
+    assertThat(decorator.countIssuesAfterDate(issues, sameSecond)).isEqualTo(0); // 0
+  }
+
+  @Test
+  public void should_clear_cache_after_execution() {
+    Issue issue1 = new DefaultIssue().setRuleKey(RuleKey.of(ruleA1.getRepositoryKey(), ruleA1.getKey())).setSeverity(RulePriority.CRITICAL.name()).setCreationDate(rightNow);
+    Issue issue2 = new DefaultIssue().setRuleKey(RuleKey.of(ruleA2.getRepositoryKey(), ruleA2.getKey())).setSeverity(RulePriority.CRITICAL.name()).setCreationDate(rightNow);
+    when(issuable.issues()).thenReturn(newArrayList(issue1)).thenReturn(newArrayList(issue2));
+
+    decorator.decorate(resource, context);
+    decorator.decorate(resource, context);
+
+    verify(context, times(2)).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 1.0, 1.0)));
+    verify(context, never()).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 2.0, 2.0)));
+  }
+
+  @Test
+  public void should_save_severity_new_issues() {
+    when(issuable.issues()).thenReturn(createIssuesForNewMetrics());
+
+    decorator.decorate(resource, context);
+
+    // remember : period1 is 5daysAgo, period2 is 10daysAgo
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_BLOCKER_VIOLATIONS, 0.0, 0.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 1.0, 1.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_MAJOR_VIOLATIONS, 0.0, 1.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_MINOR_VIOLATIONS, 0.0, 1.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_INFO_VIOLATIONS, 0.0, 0.0)));
+  }
+
+  @Test
+  public void should_save_rule_new_issues() {
+    when(issuable.issues()).thenReturn(createIssuesForNewMetrics());
+
+    decorator.decorate(resource, context);
+
+    // remember : period1 is 5daysAgo, period2 is 10daysAgo
+    verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS, ruleA1, 1.0, 1.0)));
+    verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_MAJOR_VIOLATIONS, ruleA2, 0.0, 1.0)));
+    verify(context).saveMeasure(argThat(new IsVariationRuleMeasure(CoreMetrics.NEW_MINOR_VIOLATIONS, ruleB1, 0.0, 1.0)));
+  }
+
+  @Test
+  public void should_not_save_new_issues_if_measure_already_computed() {
+    when(context.getMeasure(CoreMetrics.NEW_VIOLATIONS)).thenReturn(new Measure());
+    when(issuable.issues()).thenReturn(createIssuesForNewMetrics());
+
+    decorator.decorate(resource, context);
+
+    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_BLOCKER_VIOLATIONS)));
+    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS)));
+    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_MAJOR_VIOLATIONS)));
+    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_MINOR_VIOLATIONS)));
+    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_INFO_VIOLATIONS)));
+    verify(context, never()).saveMeasure(argThat(new IsMetricMeasure(CoreMetrics.NEW_CRITICAL_VIOLATIONS)));
+  }
+
+  List<Issue> createIssues() {
+    List<Issue> issues = newArrayList();
+    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(Severity.CRITICAL).setStatus(Issue.STATUS_OPEN));
+    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(Severity.CRITICAL).setStatus(Issue.STATUS_REOPENED));
+    issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setSeverity(Severity.MAJOR).setStatus(Issue.STATUS_REOPENED));
+    issues.add(new DefaultIssue().setRuleKey(ruleB1.ruleKey()).setSeverity(Severity.MINOR).setStatus(Issue.STATUS_OPEN));
+    return issues;
+  }
+
+  List<Issue> createIssuesForNewMetrics() {
+    List<Issue> issues = newArrayList();
+    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()).setCreationDate(rightNow).setStatus(Issue.STATUS_OPEN));
+    issues.add(new DefaultIssue().setRuleKey(ruleA1.ruleKey()).setSeverity(RulePriority.CRITICAL.name()).setCreationDate(tenDaysAgo).setStatus(Issue.STATUS_OPEN));
+    issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setSeverity(RulePriority.MAJOR.name()).setCreationDate(fiveDaysAgo).setStatus(Issue.STATUS_REOPENED));
+    issues.add(new DefaultIssue().setRuleKey(ruleA2.ruleKey()).setSeverity(RulePriority.MAJOR.name()).setCreationDate(tenDaysAgo).setStatus(Issue.STATUS_REOPENED));
+    issues.add(new DefaultIssue().setRuleKey(ruleB1.ruleKey()).setSeverity(RulePriority.MINOR.name()).setCreationDate(fiveDaysAgo).setStatus(Issue.STATUS_OPEN));
+    issues.add(new DefaultIssue().setRuleKey(ruleB1.ruleKey()).setSeverity(RulePriority.MINOR.name()).setCreationDate(tenDaysAgo).setStatus(Issue.STATUS_OPEN));
+    return issues;
+  }
+
+  class IsVariationRuleMeasure extends ArgumentMatcher<Measure> {
+    Metric metric = null;
+    Rule rule = null;
+    Double var1 = null;
+    Double var2 = null;
+
+    public IsVariationRuleMeasure(Metric metric, Rule rule, Double var1, Double var2) {
+      this.metric = metric;
+      this.rule = rule;
+      this.var1 = var1;
+      this.var2 = var2;
+    }
+
+    public boolean matches(Object o) {
+      if (!(o instanceof RuleMeasure)) {
+        return false;
+      }
+      RuleMeasure m = (RuleMeasure) o;
+      return ObjectUtils.equals(metric, m.getMetric()) &&
+        ObjectUtils.equals(rule.ruleKey(), m.ruleKey()) &&
+        ObjectUtils.equals(var1, m.getVariation1()) &&
+        ObjectUtils.equals(var2, m.getVariation2());
+    }
+  }
+
+  class IsVariationMeasure extends ArgumentMatcher<Measure> {
+    Metric metric = null;
+    Double var1 = null;
+    Double var2 = null;
+
+    public IsVariationMeasure(Metric metric, Double var1, Double var2) {
+      this.metric = metric;
+      this.var1 = var1;
+      this.var2 = var2;
+    }
+
+    public boolean matches(Object o) {
+      if (!(o instanceof Measure)) {
+        return false;
+      }
+      Measure m = (Measure) o;
+      return ObjectUtils.equals(metric, m.getMetric()) &&
+        ObjectUtils.equals(var1, m.getVariation1()) &&
+        ObjectUtils.equals(var2, m.getVariation2()) &&
+        !(m instanceof RuleMeasure);
+    }
+  }
+
+  class IsMetricMeasure extends ArgumentMatcher<Measure> {
+    Metric metric = null;
+
+    public IsMetricMeasure(Metric metric) {
+      this.metric = metric;
+    }
+
+    public boolean matches(Object o) {
+      if (!(o instanceof Measure)) {
+        return false;
+      }
+      Measure m = (Measure) o;
+      return ObjectUtils.equals(metric, m.getMetric());
+    }
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/CoverageDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/CoverageDecoratorTest.java
new file mode 100644 (file)
index 0000000..5994f3e
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Collection;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Scopes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class CoverageDecoratorTest {
+  private CoverageDecorator decorator;
+  private final Project project = mock(Project.class);
+
+  @Before
+  public void before() {
+    when(project.getScope()).thenReturn(Scopes.PROJECT);
+    decorator = new CoverageDecorator();
+  }
+
+  @Test
+  public void should_use_metrics() {
+    Collection<Metric> metrics = decorator.usedMetrics();
+
+    assertThat(metrics).containsOnly(CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.NEW_LINES_TO_COVER,
+      CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS,
+      CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS);
+  }
+
+  @Test
+  public void coverage() {
+    DecoratorContext context = mockContext(50, 40, 10, 8);
+
+    decorator.decorate(project, context);
+
+    // (50-40 covered lines + 10-8 covered conditions) / (50 lines + 10 conditions)
+    verify(context).saveMeasure(CoreMetrics.COVERAGE, 20.0);
+  }
+
+  @Test
+  public void coverageCanBe0() {
+    DecoratorContext context = mockContext(50, 50, 5, 5);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.COVERAGE, 0.0);
+  }
+
+  @Test
+  public void coverageCanBe100() {
+    DecoratorContext context = mockContext(50, 0, 5, 0);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.COVERAGE, 100.0);
+  }
+
+  @Test
+  public void noCoverageIfNoElements() {
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    decorator.decorate(project, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.COVERAGE), anyDouble());
+  }
+
+  @Test
+  public void should_count_elements_for_new_code() {
+    Measure newLines = measureWithVariation(1, 100.0);
+    Measure newConditions = measureWithVariation(1, 1.0);
+    DecoratorContext context = mockNewContext(newLines, null, null, newConditions);
+
+    long count = decorator.countElementsForNewCode(context, 1);
+
+    assertThat(count).isEqualTo(101).isEqualTo(100 + 1);
+  }
+
+  @Test
+  public void should_count_covered_elements_for_new_code() {
+    Measure newLines = measureWithVariation(1, 100.0);
+    Measure newUncoveredConditions = measureWithVariation(1, 10.0);
+    Measure newUncoveredLines = measureWithVariation(1, 5.0);
+    Measure newConditions = measureWithVariation(1, 1.0);
+    DecoratorContext context = mockNewContext(newLines, newUncoveredConditions, newUncoveredLines, newConditions);
+
+    long count = decorator.countCoveredElementsForNewCode(context, 1);
+
+    assertThat(count).isEqualTo(86).isEqualTo(100 + 1 - 10 - 5);
+  }
+
+  private static DecoratorContext mockContext(int lines, int uncoveredLines, int conditions, int uncoveredConditions) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.LINES_TO_COVER, (double) lines));
+    when(context.getMeasure(CoreMetrics.UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.UNCOVERED_LINES, (double) uncoveredLines));
+    when(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.CONDITIONS_TO_COVER, (double) conditions));
+    when(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, (double) uncoveredConditions));
+    return context;
+  }
+
+  private static DecoratorContext mockNewContext(Measure newLines, Measure newUncoveredConditions, Measure newUncoveredLines, Measure newConditions) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(newLines);
+    when(context.getMeasure(CoreMetrics.NEW_UNCOVERED_LINES)).thenReturn(newUncoveredLines);
+    when(context.getMeasure(CoreMetrics.NEW_UNCOVERED_CONDITIONS)).thenReturn(newUncoveredConditions);
+    when(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER)).thenReturn(newConditions);
+    return context;
+  }
+
+  private static Measure measureWithVariation(int period, double variation) {
+    Measure measure = mock(Measure.class);
+    when(measure.getVariation(period)).thenReturn(variation);
+    return measure;
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/DirectoriesDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/DirectoriesDecoratorTest.java
new file mode 100644 (file)
index 0000000..5e854bc
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import java.util.Collections;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.Directory;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class DirectoriesDecoratorTest {
+
+  @Test
+  public void doNotInsertZeroOnFiles() {
+    DirectoriesDecorator decorator = new DirectoriesDecorator();
+    Resource file = File.create("foo.php");
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    decorator.decorate(file, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.DIRECTORIES), anyDouble());
+  }
+
+  @Test
+  public void directoryCountsForOne() {
+    DirectoriesDecorator decorator = new DirectoriesDecorator();
+    Resource directory = Directory.create("org/foo");
+    DecoratorContext context = mock(DecoratorContext.class);
+    decorator.decorate(directory, context);
+    verify(context).saveMeasure(CoreMetrics.DIRECTORIES, 1.0);
+  }
+
+  @Test
+  public void countProjectDirectories() {
+    DirectoriesDecorator decorator = new DirectoriesDecorator();
+    Resource project = new Project("project");
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    when(context.getChildrenMeasures(CoreMetrics.DIRECTORIES)).thenReturn(Arrays.<Measure>asList(
+      new Measure(CoreMetrics.DIRECTORIES, 1.0),
+      new Measure(CoreMetrics.DIRECTORIES, 1.0),
+      new Measure(CoreMetrics.DIRECTORIES, 1.0)
+      ));
+    decorator.decorate(project, context);
+    verify(context).saveMeasure(CoreMetrics.DIRECTORIES, 3.0);
+  }
+
+  @Test
+  public void noProjectValueWhenOnlyPackages() {
+    DirectoriesDecorator decorator = new DirectoriesDecorator();
+    Resource project = new Project("project");
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getChildrenMeasures(CoreMetrics.DIRECTORIES)).thenReturn(Collections.<Measure>emptyList());
+    when(context.getChildrenMeasures(CoreMetrics.PACKAGES)).thenReturn(Arrays.<Measure>asList(
+      new Measure(CoreMetrics.PACKAGES, 1.0),
+      new Measure(CoreMetrics.PACKAGES, 1.0)
+      ));
+    decorator.decorate(project, context);
+    verify(context, never()).saveMeasure(eq(CoreMetrics.DIRECTORIES), anyDouble());
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/FilesDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/FilesDecoratorTest.java
new file mode 100644 (file)
index 0000000..f750aeb
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class FilesDecoratorTest {
+
+  private FilesDecorator decorator;
+
+  @Mock
+  private DecoratorContext context;
+
+  @Mock
+  private Resource resource;
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Before
+  public void setUp() {
+    MockitoAnnotations.initMocks(this);
+
+    decorator = new FilesDecorator();
+  }
+
+  @Test
+  public void generatesMetrics() {
+    assertThat(decorator.generateDirectoriesMetric()).isEqualTo(CoreMetrics.FILES);
+  }
+
+  @Test
+  public void shouldExecute() {
+    assertThat(decorator.shouldExecuteOnProject(mock(Project.class))).isEqualTo(true);
+  }
+
+  @Test
+  public void shouldNotSaveIfMeasureAlreadyExists() {
+    when(context.getMeasure(CoreMetrics.FILES)).thenReturn(new Measure(CoreMetrics.FILES, 1.0));
+
+    decorator.decorate(resource, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.FILES), anyDouble());
+  }
+
+  @Test
+  public void shouldSaveOneForFile() {
+    when(resource.getQualifier()).thenReturn(Qualifiers.FILE);
+
+    decorator.decorate(resource, context);
+
+    verify(context, times(1)).saveMeasure(eq(CoreMetrics.FILES), eq(1d));
+  }
+
+  @Test
+  public void shouldSaveOneForClass() {
+    when(resource.getQualifier()).thenReturn(Qualifiers.CLASS);
+
+    decorator.decorate(resource, context);
+
+    verify(context, times(1)).saveMeasure(eq(CoreMetrics.FILES), eq(1d));
+  }
+
+  @Test
+  public void shouldSumChildren() {
+    when(context.getChildrenMeasures(CoreMetrics.FILES)).thenReturn(Arrays.asList(new Measure(CoreMetrics.FILES, 2.0), new Measure(CoreMetrics.FILES, 3.0)));
+
+    decorator.decorate(resource, context);
+
+    verify(context).saveMeasure(eq(CoreMetrics.FILES), eq(5.0));
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/ItBranchCoverageDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/ItBranchCoverageDecoratorTest.java
new file mode 100644 (file)
index 0000000..0e5b70a
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ItBranchCoverageDecoratorTest {
+  private final ItBranchCoverageDecorator decorator = new ItBranchCoverageDecorator();
+  private final Project resource = mock(Project.class);
+
+  @Before
+  public void setUp() {
+    when(resource.getScope()).thenReturn(Scopes.PROJECT);
+    when(resource.getQualifier()).thenReturn(Qualifiers.PROJECT);
+  }
+
+  @Test
+  public void shouldSaveBranchCoverage() {
+    DecoratorContext context = mockContext(20, 15);
+
+    decorator.decorate(resource, context);
+
+    verify(context).saveMeasure(CoreMetrics.IT_BRANCH_COVERAGE, 25.0);
+  }
+
+  @Test
+  public void shouldNotSaveBranchCoverageIfMissingConditions() {
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    decorator.decorate(resource, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.IT_BRANCH_COVERAGE), anyDouble());
+  }
+
+  private static DecoratorContext mockContext(int conditions, int uncoveredConditions) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.IT_CONDITIONS_TO_COVER, (double) conditions));
+    when(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.IT_UNCOVERED_CONDITIONS, (double) uncoveredConditions));
+    return context;
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/ItCoverageDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/ItCoverageDecoratorTest.java
new file mode 100644 (file)
index 0000000..839577f
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Collection;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Scopes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ItCoverageDecoratorTest {
+  private final ItCoverageDecorator decorator = new ItCoverageDecorator();
+  private final Project project = mock(Project.class);
+
+  @Before
+  public void before() {
+    when(project.getScope()).thenReturn(Scopes.PROJECT);
+  }
+
+  @Test
+  public void should_use_metrics() {
+    Collection<Metric> metrics = decorator.usedMetrics();
+
+    assertThat(metrics).containsOnly(CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_LINES_TO_COVER,
+      CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.IT_CONDITIONS_TO_COVER, CoreMetrics.IT_UNCOVERED_CONDITIONS,
+      CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS);
+  }
+
+  @Test
+  public void coverage() {
+    DecoratorContext context = mockContext(50, 40, 10, 8);
+
+    decorator.decorate(project, context);
+
+    // (50-40 covered lines + 10-8 covered conditions) / (50 lines + 10 conditions)
+    verify(context).saveMeasure(CoreMetrics.IT_COVERAGE, 20.0);
+  }
+
+  @Test
+  public void coverageCanBe0() {
+    DecoratorContext context = mockContext(50, 50, 5, 5);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.IT_COVERAGE, 0.0);
+  }
+
+  @Test
+  public void coverageCanBe100() {
+    DecoratorContext context = mockContext(50, 0, 5, 0);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.IT_COVERAGE, 100.0);
+  }
+
+  @Test
+  public void noCoverageIfNoElements() {
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    decorator.decorate(project, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.IT_COVERAGE), anyDouble());
+  }
+
+  @Test
+  public void should_count_elements_for_new_code() {
+    Measure newLines = measureWithVariation(1, 100.0);
+    Measure newConditions = measureWithVariation(1, 1.0);
+    DecoratorContext context = mockNewContext(newLines, null, null, newConditions);
+
+    long count = decorator.countElementsForNewCode(context, 1);
+
+    assertThat(count).isEqualTo(101).isEqualTo(100 + 1);
+  }
+
+  @Test
+  public void should_count_covered_elements_for_new_code() {
+    Measure newLines = measureWithVariation(1, 100.0);
+    Measure newUncoveredConditions = measureWithVariation(1, 10.0);
+    Measure newUncoveredLines = measureWithVariation(1, 5.0);
+    Measure newConditions = measureWithVariation(1, 1.0);
+    DecoratorContext context = mockNewContext(newLines, newUncoveredConditions, newUncoveredLines, newConditions);
+
+    long count = decorator.countCoveredElementsForNewCode(context, 1);
+
+    assertThat(count).isEqualTo(86).isEqualTo(100 + 1 - 10 - 5);
+  }
+
+  private static DecoratorContext mockContext(int lines, int uncoveredLines, int conditions, int uncoveredConditions) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.IT_LINES_TO_COVER, (double) lines));
+    when(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.IT_UNCOVERED_LINES, (double) uncoveredLines));
+    when(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.IT_CONDITIONS_TO_COVER, (double) conditions));
+    when(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.IT_UNCOVERED_CONDITIONS, (double) uncoveredConditions));
+    return context;
+  }
+
+  private static DecoratorContext mockNewContext(Measure newLines, Measure newUncoveredConditions, Measure newUncoveredLines, Measure newConditions) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER)).thenReturn(newLines);
+    when(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_LINES)).thenReturn(newUncoveredLines);
+    when(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS)).thenReturn(newUncoveredConditions);
+    when(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER)).thenReturn(newConditions);
+    return context;
+  }
+
+  private static Measure measureWithVariation(int period, double variation) {
+    Measure measure = mock(Measure.class);
+    when(measure.getVariation(period)).thenReturn(variation);
+    return measure;
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/ItLineCoverageDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/ItLineCoverageDecoratorTest.java
new file mode 100644 (file)
index 0000000..95e7177
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Scopes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ItLineCoverageDecoratorTest {
+  private final ItLineCoverageDecorator decorator = new ItLineCoverageDecorator();
+  private final Project project = mock(Project.class);
+
+  @Before
+  public void before() {
+    when(project.getScope()).thenReturn(Scopes.PROJECT);
+  }
+
+  @Test
+  public void should_depend_on_coverage_metrics() {
+    List<Metric> metrics = decorator.dependsUponMetrics();
+
+    assertThat(metrics).containsOnly(CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_LINES_TO_COVER);
+  }
+
+  @Test
+  public void lineCoverage() {
+    DecoratorContext context = mockContext(50, 10);
+
+    decorator.decorate(project, context);
+
+    // 50-10 covered lines / 50 lines
+    verify(context).saveMeasure(CoreMetrics.IT_LINE_COVERAGE, 80.0);
+  }
+
+  @Test
+  public void zeroCoveredLines() {
+    DecoratorContext context = mockContext(50, 50);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.IT_LINE_COVERAGE, 0.0);
+  }
+
+  @Test
+  public void allCoveredLines() {
+    DecoratorContext context = mockContext(50, 00);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.IT_LINE_COVERAGE, 100.0);
+  }
+
+  @Test
+  public void noLineCoverageIfNoLines() {
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    decorator.decorate(project, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.IT_LINE_COVERAGE), anyDouble());
+  }
+
+  private static DecoratorContext mockContext(int lines, int uncoveredLines) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.IT_LINES_TO_COVER, (double) lines));
+    when(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.IT_UNCOVERED_LINES, (double) uncoveredLines));
+    return context;
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/LineCoverageDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/LineCoverageDecoratorTest.java
new file mode 100644 (file)
index 0000000..2a49f83
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Scopes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class LineCoverageDecoratorTest {
+
+  private LineCoverageDecorator decorator;
+  private final Project project = mock(Project.class);
+
+  @Before
+  public void before() {
+    when(project.getScope()).thenReturn(Scopes.PROJECT);
+    decorator = new LineCoverageDecorator();
+  }
+
+  @Test
+  public void should_depend_on_coverage_metrics() {
+    assertThat(decorator.dependsUponMetrics()).containsOnly(CoreMetrics.UNCOVERED_LINES, CoreMetrics.LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES,
+      CoreMetrics.NEW_LINES_TO_COVER);
+  }
+
+  @Test
+  public void lineCoverage() {
+    DecoratorContext context = mockContext(50, 10);
+
+    decorator.decorate(project, context);
+
+    // 50-10 covered lines / 50 lines
+    verify(context).saveMeasure(CoreMetrics.LINE_COVERAGE, 80.0);
+  }
+
+  @Test
+  public void zeroCoveredLines() {
+    DecoratorContext context = mockContext(50, 50);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.LINE_COVERAGE, 0.0);
+  }
+
+  @Test
+  public void allCoveredLines() {
+    DecoratorContext context = mockContext(50, 00);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.LINE_COVERAGE, 100.0);
+  }
+
+  @Test
+  public void noLineCoverageIfNoLines() {
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    decorator.decorate(project, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.LINE_COVERAGE), anyDouble());
+  }
+
+  private static DecoratorContext mockContext(int lines, int uncoveredLines) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.LINES_TO_COVER, (double) lines));
+    when(context.getMeasure(CoreMetrics.UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.UNCOVERED_LINES, (double) uncoveredLines));
+    return context;
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/ManualMeasureDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/ManualMeasureDecoratorTest.java
new file mode 100644 (file)
index 0000000..bd86438
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.File;
+import org.sonar.api.test.IsMeasure;
+import org.sonar.core.metric.DefaultMetricFinder;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class ManualMeasureDecoratorTest extends AbstractDbUnitTestCase {
+
+  private Metric reviewNote = new Metric.Builder("review_note", "Note", Metric.ValueType.FLOAT).create().setId(2);
+
+  @Test
+  public void testCopyManualMeasures() throws Exception {
+    setupData("testCopyManualMeasures");
+
+    File javaFile = File.create("Foo.java");
+    javaFile.setId(40);
+
+    ManualMeasureDecorator decorator = new ManualMeasureDecorator(getSession(), new DefaultMetricFinder(getSessionFactory()));
+    DecoratorContext context = mock(DecoratorContext.class);
+    decorator.decorate(javaFile, context);
+
+    verify(context).saveMeasure(argThat(new IsMeasure(reviewNote, 6.0, "six")));
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/NewCoverageAggregatorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/NewCoverageAggregatorTest.java
new file mode 100644 (file)
index 0000000..7951e3a
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import java.util.Collections;
+import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Matchers;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class NewCoverageAggregatorTest {
+
+  @Test
+  public void shouldNotSaveDataWhenNoMeasures() {
+    NewCoverageAggregator aggregator = new NewCoverageAggregator();
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getChildrenMeasures(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(Collections.<Measure>emptyList());
+
+    aggregator.aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, 3);
+
+    verify(context, never()).saveMeasure(Matchers.<Measure>anyObject());
+  }
+
+  @Test
+  public void shouldNotsetZeroWhenNoValueOnPeriod() {
+    NewCoverageAggregator aggregator = new NewCoverageAggregator();
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getChildrenMeasures(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(Arrays.asList(newMeasure(null, 3.0, 2.0), newMeasure(null, 13.0, null)));
+
+    aggregator.aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, 3);
+
+    verify(context).saveMeasure(argThat(new ArgumentMatcher<Measure>() {
+      @Override
+      public boolean matches(Object o) {
+        Measure m = (Measure) o;
+        return m.getVariation1() == null;
+      }
+    }));
+  }
+
+  @Test
+  public void shouldSumValues() {
+    NewCoverageAggregator aggregator = new NewCoverageAggregator();
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getChildrenMeasures(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(Arrays.asList(newMeasure(null, 3.0, 2.0), newMeasure(null, 13.0, null)));
+
+    aggregator.aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, 3);
+
+    verify(context).saveMeasure(argThat(new ArgumentMatcher<Measure>() {
+      @Override
+      public boolean matches(Object o) {
+        Measure m = (Measure) o;
+        return m.getVariation2() == 16.0 && m.getVariation3() == 2.0;
+      }
+    }));
+  }
+
+  private Measure newMeasure(Double variation1, Double variation2, Double variation3) {
+    return new Measure(CoreMetrics.NEW_LINES_TO_COVER)
+      .setVariation1(variation1)
+      .setVariation2(variation2)
+      .setVariation3(variation3);
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/NewCoverageFileAnalyzerTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/NewCoverageFileAnalyzerTest.java
new file mode 100644 (file)
index 0000000..6deb673
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.ArgumentMatcher;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.batch.index.BatchComponentCache;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReport.Changesets.Changeset;
+import org.sonar.batch.protocol.output.BatchReportWriter;
+import org.sonar.batch.report.ReportPublisher;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class NewCoverageFileAnalyzerTest {
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  private DecoratorContext context;
+  private NewCoverageFileAnalyzer decorator;
+  private BatchReportWriter writer;
+
+  @Before
+  public void prepare() throws Exception {
+    context = mock(DecoratorContext.class);
+    Resource f = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java");
+    when(context.getResource()).thenReturn(f);
+    BatchComponentCache cache = new BatchComponentCache();
+    cache.add(f, null);
+    List<AbstractNewCoverageFileAnalyzer.PeriodStruct> structs = Arrays.asList(
+      new AbstractNewCoverageFileAnalyzer.PeriodStruct(1, newDate("2009-12-25")),
+      new AbstractNewCoverageFileAnalyzer.PeriodStruct(3, newDate("2011-02-18")));
+    ReportPublisher publishReportJob = mock(ReportPublisher.class);
+    java.io.File reportBaseDir = temp.newFolder();
+    when(publishReportJob.getReportDir()).thenReturn(reportBaseDir);
+    writer = new BatchReportWriter(reportBaseDir);
+    decorator = new NewCoverageFileAnalyzer(structs, publishReportJob, cache);
+
+  }
+
+  @Test
+  public void shouldDoNothingIfNoScmData() {
+    when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA))
+      .thenReturn(new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "1=10"));
+
+    decorator.doDecorate(context);
+    verify(context, never()).saveMeasure(any(Measure.class));
+  }
+
+  @Test
+  public void shouldDoNothingIfNoCoverageData() {
+    writer.writeComponentChangesets(BatchReport.Changesets.newBuilder()
+      .setComponentRef(1)
+      .addChangeset(Changeset.newBuilder()
+        .setDate(DateUtils.parseDateTime("2008-05-18T00:00:00+0000").getTime())
+        .build())
+      .addChangesetIndexByLine(0)
+      .build());
+
+    decorator.doDecorate(context);
+
+    verify(context, never()).saveMeasure(any(Measure.class));
+  }
+
+  @Test
+  public void shouldGetNewLines() {
+    when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn(
+      new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3"));
+    writer.writeComponentChangesets(BatchReport.Changesets.newBuilder()
+      .setComponentRef(1)
+      .addChangeset(Changeset.newBuilder()
+        .build())
+      .addChangeset(Changeset.newBuilder()
+        .setDate(DateUtils.parseDateTime("2007-01-15T00:00:00+0000").getTime())
+        .build())
+      .addChangeset(Changeset.newBuilder()
+        .setDate(DateUtils.parseDateTime("2011-01-01T00:00:00+0000").getTime())
+        .build())
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(1)
+      .addChangesetIndexByLine(2)
+      .build());
+
+    decorator.doDecorate(context);
+
+    // line 11 has been updated after date1 (2009-12-25). This line is covered.
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 1, 1.0)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 1, 0.0)));
+
+    // no line have been updated after date3 (2011-02-18)
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 3, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 3, null)));
+
+    // no data on other periods
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 2, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 4, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 5, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 2, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 4, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 5, null)));
+  }
+
+  @Test
+  public void shouldGetNewConditions() {
+    when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn(
+      new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3"));
+    when(context.getMeasure(CoreMetrics.CONDITIONS_BY_LINE)).thenReturn(
+      new Measure(CoreMetrics.CONDITIONS_BY_LINE, "11=4"));
+    when(context.getMeasure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)).thenReturn(
+      new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "11=1"));
+    writer.writeComponentChangesets(BatchReport.Changesets.newBuilder()
+      .setComponentRef(1)
+      .addChangeset(Changeset.newBuilder()
+        .build())
+      .addChangeset(Changeset.newBuilder()
+        .setDate(DateUtils.parseDateTime("2007-01-15T00:00:00+0000").getTime())
+        .build())
+      .addChangeset(Changeset.newBuilder()
+        .setDate(DateUtils.parseDateTime("2011-01-01T00:00:00+0000").getTime())
+        .build())
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(1)
+      .addChangesetIndexByLine(2)
+      .build());
+
+    decorator.doDecorate(context);
+
+    // line 11 has been updated after date1 (2009-12-25). This line has 1 covered condition amongst 4
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 1, 4.0)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 1, 3.0)));
+
+    // no line have been updated after date3 (2011-02-18)
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 3, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 3, null)));
+
+    // no data on other periods
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 2, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 4, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 5, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 2, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 4, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 5, null)));
+  }
+
+  @Test
+  public void shouldNotGetNewConditionsWhenNewLineHasNoConditions() {
+    when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn(
+      new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3"));
+    when(context.getMeasure(CoreMetrics.CONDITIONS_BY_LINE)).thenReturn(
+      new Measure(CoreMetrics.CONDITIONS_BY_LINE, "10=1"));
+    when(context.getMeasure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)).thenReturn(
+      new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "10=1"));
+    writer.writeComponentChangesets(BatchReport.Changesets.newBuilder()
+      .setComponentRef(1)
+      .addChangeset(Changeset.newBuilder()
+        .build())
+      .addChangeset(Changeset.newBuilder()
+        .setDate(DateUtils.parseDateTime("2007-01-15T00:00:00+0000").getTime())
+        .build())
+      .addChangeset(Changeset.newBuilder()
+        .setDate(DateUtils.parseDateTime("2011-01-01T00:00:00+0000").getTime())
+        .build())
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(1)
+      .addChangesetIndexByLine(2)
+      .build());
+
+    decorator.doDecorate(context);
+
+    // line 11 has been updated after date1 (2009-12-25) but it has no conditions
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 1, 0.0)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 1, 0.0)));
+  }
+
+  @Test
+  public void shouldLeaveNullValueWhenNothingHasChanged() {
+
+    when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn(
+      new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "2=1;3=1"));
+    when(context.getMeasure(CoreMetrics.CONDITIONS_BY_LINE)).thenReturn(
+      new Measure(CoreMetrics.CONDITIONS_BY_LINE, "2=1"));
+    when(context.getMeasure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)).thenReturn(
+      new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "2=1"));
+    writer.writeComponentChangesets(BatchReport.Changesets.newBuilder()
+      .setComponentRef(1)
+      .addChangeset(Changeset.newBuilder()
+        .setDate(DateUtils.parseDateTime("2008-08-02T13:56:37+0200").getTime())
+        .build())
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .addChangesetIndexByLine(0)
+      .build());
+
+    decorator.doDecorate(context);
+
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 1, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 1, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 1, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 1, null)));
+
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 3, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 3, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 3, null)));
+    verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 3, null)));
+  }
+
+  static class VariationMatcher extends ArgumentMatcher<Measure> {
+    Metric metric;
+    int index;
+    Double variation;
+
+    VariationMatcher(Metric metric, int index, Double variation) {
+      this.metric = metric;
+      this.index = index;
+      this.variation = variation;
+    }
+
+    @Override
+    public boolean matches(Object o) {
+      Measure m = (Measure) o;
+      if (m.getMetric().equals(metric)) {
+        if ((variation == null && m.getVariation(index) == null) ||
+          (variation != null && variation.equals(m.getVariation(index)))) {
+          return true;
+        }
+      }
+      return false;
+    }
+  }
+
+  private Date newDate(String s) throws ParseException {
+    return new SimpleDateFormat(DateUtils.DATE_FORMAT).parse(s);
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/OverallBranchCoverageDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/OverallBranchCoverageDecoratorTest.java
new file mode 100644 (file)
index 0000000..9c5e585
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class OverallBranchCoverageDecoratorTest {
+  private final OverallBranchCoverageDecorator decorator = new OverallBranchCoverageDecorator();
+  private final Project resource = mock(Project.class);
+
+  @Before
+  public void setUp() {
+    when(resource.getScope()).thenReturn(Scopes.PROJECT);
+    when(resource.getQualifier()).thenReturn(Qualifiers.PROJECT);
+  }
+
+  @Test
+  public void shouldSaveBranchCoverage() {
+    DecoratorContext context = mockContext(20, 15);
+
+    decorator.decorate(resource, context);
+
+    verify(context).saveMeasure(CoreMetrics.OVERALL_BRANCH_COVERAGE, 25.0);
+  }
+
+  @Test
+  public void shouldNotSaveBranchCoverageIfMissingConditions() {
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    decorator.decorate(resource, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.OVERALL_BRANCH_COVERAGE), anyDouble());
+  }
+
+  private static DecoratorContext mockContext(int conditions, int uncoveredConditions) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER, (double) conditions));
+    when(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS, (double) uncoveredConditions));
+    return context;
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/OverallCoverageDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/OverallCoverageDecoratorTest.java
new file mode 100644 (file)
index 0000000..d694227
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Collection;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Scopes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class OverallCoverageDecoratorTest {
+  private final OverallCoverageDecorator decorator = new OverallCoverageDecorator();
+  private final Project project = mock(Project.class);
+
+  @Before
+  public void before() {
+    when(project.getScope()).thenReturn(Scopes.PROJECT);
+  }
+
+  @Test
+  public void should_use_metrics() {
+    Collection<Metric> metrics = decorator.usedMetrics();
+
+    assertThat(metrics).containsOnly(CoreMetrics.OVERALL_LINES_TO_COVER, CoreMetrics.OVERALL_UNCOVERED_LINES, CoreMetrics.NEW_OVERALL_LINES_TO_COVER,
+      CoreMetrics.NEW_OVERALL_UNCOVERED_LINES, CoreMetrics.OVERALL_CONDITIONS_TO_COVER, CoreMetrics.OVERALL_UNCOVERED_CONDITIONS,
+      CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS);
+  }
+
+  @Test
+  public void coverage() {
+    DecoratorContext context = mockContext(50, 40, 10, 8);
+
+    decorator.decorate(project, context);
+
+    // (50-40 covered lines + 10-8 covered conditions) / (50 lines + 10 conditions)
+    verify(context).saveMeasure(CoreMetrics.OVERALL_COVERAGE, 20.0);
+  }
+
+  @Test
+  public void coverageCanBe0() {
+    DecoratorContext context = mockContext(50, 50, 5, 5);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.OVERALL_COVERAGE, 0.0);
+  }
+
+  @Test
+  public void coverageCanBe100() {
+    DecoratorContext context = mockContext(50, 0, 5, 0);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.OVERALL_COVERAGE, 100.0);
+  }
+
+  @Test
+  public void noCoverageIfNoElements() {
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    decorator.decorate(project, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.OVERALL_COVERAGE), anyDouble());
+  }
+
+  @Test
+  public void should_count_elements_for_new_code() {
+    Measure newLines = measureWithVariation(1, 100.0);
+    Measure newConditions = measureWithVariation(1, 1.0);
+    DecoratorContext context = mockNewContext(newLines, null, null, newConditions);
+
+    long count = decorator.countElementsForNewCode(context, 1);
+
+    assertThat(count).isEqualTo(101).isEqualTo(100 + 1);
+  }
+
+  @Test
+  public void should_count_covered_elements_for_new_code() {
+    Measure newLines = measureWithVariation(1, 100.0);
+    Measure newUncoveredConditions = measureWithVariation(1, 10.0);
+    Measure newUncoveredLines = measureWithVariation(1, 5.0);
+    Measure newConditions = measureWithVariation(1, 1.0);
+    DecoratorContext context = mockNewContext(newLines, newUncoveredConditions, newUncoveredLines, newConditions);
+
+    long count = decorator.countCoveredElementsForNewCode(context, 1);
+
+    assertThat(count).isEqualTo(86).isEqualTo(100 + 1 - 10 - 5);
+  }
+
+  private static DecoratorContext mockContext(int lines, int uncoveredLines, int conditions, int uncoveredConditions) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.OVERALL_LINES_TO_COVER, (double) lines));
+    when(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.OVERALL_UNCOVERED_LINES, (double) uncoveredLines));
+    when(context.getMeasure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.OVERALL_CONDITIONS_TO_COVER, (double) conditions));
+    when(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS, (double) uncoveredConditions));
+    return context;
+  }
+
+  private static DecoratorContext mockNewContext(Measure newLines, Measure newUncoveredConditions, Measure newUncoveredLines, Measure newConditions) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.NEW_OVERALL_LINES_TO_COVER)).thenReturn(newLines);
+    when(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES)).thenReturn(newUncoveredLines);
+    when(context.getMeasure(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS)).thenReturn(newUncoveredConditions);
+    when(context.getMeasure(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER)).thenReturn(newConditions);
+    return context;
+  }
+
+  private static Measure measureWithVariation(int period, double variation) {
+    Measure measure = mock(Measure.class);
+    when(measure.getVariation(period)).thenReturn(variation);
+    return measure;
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/OverallLineCoverageDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/OverallLineCoverageDecoratorTest.java
new file mode 100644 (file)
index 0000000..17d5452
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Scopes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class OverallLineCoverageDecoratorTest {
+  private final OverallLineCoverageDecorator decorator = new OverallLineCoverageDecorator();
+  private final Project project = mock(Project.class);
+
+  @Before
+  public void before() {
+    when(project.getScope()).thenReturn(Scopes.PROJECT);
+  }
+
+  @Test
+  public void should_depend_on_coverage_metrics() {
+    List<Metric> metrics = decorator.dependsUponMetrics();
+
+    assertThat(metrics).containsOnly(CoreMetrics.OVERALL_UNCOVERED_LINES, CoreMetrics.OVERALL_LINES_TO_COVER, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES,
+      CoreMetrics.NEW_OVERALL_LINES_TO_COVER);
+  }
+
+  @Test
+  public void lineCoverage() {
+    DecoratorContext context = mockContext(50, 10);
+
+    decorator.decorate(project, context);
+
+    // 50-10 covered lines / 50 lines
+    verify(context).saveMeasure(CoreMetrics.OVERALL_LINE_COVERAGE, 80.0);
+  }
+
+  @Test
+  public void zeroCoveredLines() {
+    DecoratorContext context = mockContext(50, 50);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.OVERALL_LINE_COVERAGE, 0.0);
+  }
+
+  @Test
+  public void allCoveredLines() {
+    DecoratorContext context = mockContext(50, 00);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(CoreMetrics.OVERALL_LINE_COVERAGE, 100.0);
+  }
+
+  @Test
+  public void noLineCoverageIfNoLines() {
+    DecoratorContext context = mock(DecoratorContext.class);
+
+    decorator.decorate(project, context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.OVERALL_LINE_COVERAGE), anyDouble());
+  }
+
+  private static DecoratorContext mockContext(int lines, int uncoveredLines) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.OVERALL_LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.OVERALL_LINES_TO_COVER, (double) lines));
+    when(context.getMeasure(CoreMetrics.OVERALL_UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.OVERALL_UNCOVERED_LINES, (double) uncoveredLines));
+    return context;
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/TimeMachineConfigurationPersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/TimeMachineConfigurationPersisterTest.java
new file mode 100644 (file)
index 0000000..2c48e9c
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import org.junit.Test;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.resources.Project;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.TimeMachineConfiguration;
+import org.sonar.batch.index.BatchComponentCache;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class TimeMachineConfigurationPersisterTest extends AbstractDbUnitTestCase {
+
+  @Test
+  public void shouldSaveConfigurationInSnapshotsTable() {
+    setupData("shared");
+
+    TimeMachineConfiguration timeMachineConfiguration = mock(TimeMachineConfiguration.class);
+    PastSnapshot vs1 = new PastSnapshot("days", DateUtils.parseDate("2009-01-25"), getSession().getSingleResult(Snapshot.class, "id", 100))
+      .setModeParameter("30").setIndex(1);
+    PastSnapshot vs3 = new PastSnapshot("version", DateUtils.parseDate("2008-12-13"), getSession().getSingleResult(Snapshot.class, "id", 300))
+      .setModeParameter("1.2.3").setIndex(3);
+    when(timeMachineConfiguration.getProjectPastSnapshots()).thenReturn(Arrays.asList(vs1, vs3));
+    Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1000);
+
+    BatchComponentCache resourceCache = new BatchComponentCache();
+    Project project = new Project("foo");
+    resourceCache.add(project, null).setSnapshot(projectSnapshot);
+
+    TimeMachineConfigurationPersister persister = new TimeMachineConfigurationPersister(timeMachineConfiguration, resourceCache, getSession());
+
+    persister.persistConfiguration(project);
+
+    checkTables("shouldSaveConfigurationInSnapshotsTable", "snapshots");
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/UnitTestDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/UnitTestDecoratorTest.java
new file mode 100644 (file)
index 0000000..eb9bd93
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.doubleThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class UnitTestDecoratorTest {
+
+  private UnitTestDecorator decorator;
+  private DecoratorContext context;
+
+  @Before
+  public void setUp() {
+    decorator = new UnitTestDecorator();
+    context = mock(DecoratorContext.class);
+  }
+
+  @Test
+  public void generatesMetrics() {
+    assertThat(decorator.generatesMetrics()).hasSize(5);
+  }
+
+  @Test
+  public void doNotDecorateStaticAnalysis() {
+    Project project = mock(Project.class);
+    when(project.getAnalysisType()).thenReturn(Project.AnalysisType.STATIC);
+    assertThat(decorator.shouldExecuteOnProject(project)).isFalse();
+
+    when(project.getAnalysisType()).thenReturn(Project.AnalysisType.DYNAMIC);
+    assertThat(decorator.shouldExecuteOnProject(project)).isTrue();
+  }
+
+  @Test
+  public void shouldSumChildren() {
+    Project project = mock(Project.class);
+    mockChildrenMeasures(CoreMetrics.TESTS, 3.0);
+    mockChildrenMeasures(CoreMetrics.TEST_ERRORS, 1.0);
+    mockChildrenMeasures(CoreMetrics.TEST_FAILURES, 1.0);
+    mockChildrenMeasures(CoreMetrics.SKIPPED_TESTS, 1.0);
+    mockChildrenMeasures(CoreMetrics.TEST_EXECUTION_TIME, 1.0);
+
+    decorator.decorate(project, context);
+
+    verify(context).saveMeasure(eq(CoreMetrics.TESTS), eq(6.0));
+    verify(context).saveMeasure(eq(CoreMetrics.TEST_ERRORS), eq(2.0));
+    verify(context).saveMeasure(eq(CoreMetrics.TEST_FAILURES), eq(2.0));
+    verify(context).saveMeasure(eq(CoreMetrics.SKIPPED_TESTS), eq(2.0));
+    verify(context).saveMeasure(eq(CoreMetrics.TEST_EXECUTION_TIME), eq(2.0));
+    verify(context).saveMeasure(eq(CoreMetrics.TEST_SUCCESS_DENSITY), doubleThat(Matchers.closeTo(33.3, 0.1)));
+  }
+
+  private void mockChildrenMeasures(Metric metric, double value) {
+    when(context.getChildrenMeasures(metric)).thenReturn(Arrays.asList(new Measure(metric, value), new Measure(metric, value)));
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/VariationDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/VariationDecoratorTest.java
new file mode 100644 (file)
index 0000000..21f26e0
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 org.sonar.batch.compute;
+
+import java.util.Arrays;
+import java.util.Date;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MeasuresFilter;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.measures.RuleMeasure;
+import org.sonar.api.resources.Directory;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleFinder;
+import org.sonar.batch.components.PastMeasuresLoader;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.TimeMachineConfiguration;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class VariationDecoratorTest extends AbstractDbUnitTestCase {
+
+  public static final int NCLOC_ID = 12;
+  public static final Metric NCLOC = new Metric("ncloc").setId(NCLOC_ID);
+
+  public static final int COVERAGE_ID = 16;
+  public static final Metric COVERAGE = new Metric("coverage").setId(COVERAGE_ID);
+
+  public static final int VIOLATIONS_ID = 17;
+  public static final Metric VIOLATIONS = new Metric("violations").setId(VIOLATIONS_ID);
+
+  @Test
+  public void shouldComputeVariations() {
+    TimeMachineConfiguration timeMachineConfiguration = mock(TimeMachineConfiguration.class);
+    VariationDecorator decorator = new VariationDecorator(mock(PastMeasuresLoader.class), mock(MetricFinder.class), timeMachineConfiguration, mock(RuleFinder.class));
+
+    assertThat(decorator.shouldComputeVariation(new Project("foo"))).isTrue();
+    assertThat(decorator.shouldComputeVariation(File.create("foo/bar.c"))).isFalse();
+  }
+
+  @Test
+  public void shouldCompareAndSaveVariation() {
+    Resource dir = Directory.create("org/foo");
+
+    PastMeasuresLoader pastMeasuresLoader = mock(PastMeasuresLoader.class);
+    PastSnapshot pastSnapshot1 = new PastSnapshot("days", new Date()).setIndex(1);
+    PastSnapshot pastSnapshot3 = new PastSnapshot("days", new Date()).setIndex(3);
+
+    // first past analysis
+    when(pastMeasuresLoader.getPastMeasures(dir, pastSnapshot1)).thenReturn(Arrays.asList(
+      new Object[] {NCLOC_ID, null, null, null, 180.0},
+      new Object[] {COVERAGE_ID, null, null, null, 75.0}));
+
+    // second past analysis
+    when(pastMeasuresLoader.getPastMeasures(dir, pastSnapshot3)).thenReturn(Arrays.<Object[]>asList(
+      new Object[] {NCLOC_ID, null, null, null, 240.0}));
+
+    // current analysis
+    DecoratorContext context = mock(DecoratorContext.class);
+    Measure currentNcloc = newMeasure(NCLOC, 200.0);
+    Measure currentCoverage = newMeasure(COVERAGE, 80.0);
+    when(context.getMeasures(Matchers.<MeasuresFilter>anyObject())).thenReturn(Arrays.asList(currentNcloc, currentCoverage));
+
+    VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1, pastSnapshot3), mock(RuleFinder.class));
+    decorator.decorate(dir, context);
+
+    // context updated for each variation : 2 times for ncloc and 1 time for coverage
+    verify(context, times(3)).saveMeasure(Matchers.<Measure>anyObject());
+
+    assertThat(currentNcloc.getVariation1()).isEqualTo(20.0);
+    assertThat(currentNcloc.getVariation2()).isNull();
+    assertThat(currentNcloc.getVariation3()).isEqualTo(-40.0);
+
+    assertThat(currentCoverage.getVariation1()).isEqualTo(5.0);
+    assertThat(currentCoverage.getVariation2()).isNull();
+    assertThat(currentCoverage.getVariation3()).isNull();
+  }
+
+  @Test
+  public void shouldComputeVariationOfRuleMeasures() {
+    RuleFinder ruleFinder = mock(RuleFinder.class);
+
+    Rule rule1 = Rule.create("repo", "rule1");
+    rule1.setId(1);
+    Rule rule2 = Rule.create("repo", "rule2");
+    rule2.setId(2);
+
+    when(ruleFinder.findByKey(rule1.ruleKey())).thenReturn(rule1);
+    when(ruleFinder.findByKey(rule2.ruleKey())).thenReturn(rule2);
+
+    Resource dir = Directory.create("org/foo");
+
+    PastMeasuresLoader pastMeasuresLoader = mock(PastMeasuresLoader.class);
+    PastSnapshot pastSnapshot1 = new PastSnapshot("days", new Date()).setIndex(1);
+
+    // first past analysis
+    when(pastMeasuresLoader.getPastMeasures(dir, pastSnapshot1)).thenReturn(Arrays.asList(
+      new Object[] {VIOLATIONS_ID, null, null, null, 180.0},// total
+      new Object[] {VIOLATIONS_ID, null, null, rule1.getId(), 100.0},// rule 1
+      new Object[] {VIOLATIONS_ID, null, null, rule2.getId(), 80.0})); // rule 2
+
+    // current analysis
+    DecoratorContext context = mock(DecoratorContext.class);
+    Measure violations = newMeasure(VIOLATIONS, 200.0);
+    Measure violationsRule1 = RuleMeasure.createForRule(VIOLATIONS, rule1, 130.0);
+    Measure violationsRule2 = RuleMeasure.createForRule(VIOLATIONS, rule2, 70.0);
+    when(context.getMeasures(Matchers.<MeasuresFilter>anyObject())).thenReturn(Arrays.asList(violations, violationsRule1, violationsRule2));
+
+    VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1), ruleFinder);
+    decorator.decorate(dir, context);
+
+    // context updated for each variation
+    verify(context, times(3)).saveMeasure(Matchers.<Measure>anyObject());
+
+    assertThat(violations.getVariation1()).isEqualTo(20.0);
+  }
+
+  private Measure newMeasure(Metric metric, double value) {
+    return new Measure(metric, value);
+  }
+}
index 41bdd9c67dfaa089ed5d2c54447f3fb2dd1737fd..8d24834d97b0bbb5473a04710af3b717d742ab85 100644 (file)
@@ -66,7 +66,7 @@ public class MeasuresMediumTest {
       .newScanTask(new File(projectDir, "sonar-project.properties"))
       .start();
 
-    assertThat(result.allMeasures()).hasSize(61);
+    assertThat(result.allMeasures()).hasSize(90);
   }
 
   @Test
@@ -93,7 +93,7 @@ public class MeasuresMediumTest {
         .build())
       .start();
 
-    assertThat(result.allMeasures()).hasSize(25);
+    assertThat(result.allMeasures()).hasSize(33);
 
     assertThat(result.allMeasures()).contains(new DefaultMeasure<Integer>()
       .forMetric(CoreMetrics.LINES)
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/ManualMeasureDecoratorTest/testCopyManualMeasures.xml b/sonar-batch/src/test/resources/org/sonar/batch/compute/ManualMeasureDecoratorTest/testCopyManualMeasures.xml
new file mode 100644 (file)
index 0000000..0307f16
--- /dev/null
@@ -0,0 +1,11 @@
+<dataset>
+  <metrics delete_historical_data="[null]" id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]"  domain="[null]" short_name=""
+           enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
+  <metrics delete_historical_data="[null]" id="2" NAME="review_note" VAL_TYPE="INT" DESCRIPTION="[null]"  domain="[null]" short_name=""
+           enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
+
+
+  <manual_measures id="1" metric_id="2" resource_id="30" value="3.14" text_value="pi" created_at="[null]" updated_at="[null]" description="this is pi" user_login="me"/>
+  <manual_measures id="2" metric_id="2" resource_id="40" value="6" text_value="six" created_at="[null]" updated_at="[null]" description="this is six" user_login="me"/>
+
+</dataset>
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml b/sonar-batch/src/test/resources/org/sonar/batch/compute/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml
new file mode 100644 (file)
index 0000000..836bb46
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.codehaus.sonar</groupId>
+  <artifactId>sonar</artifactId>
+  <packaging>pom</packaging>
+  <version>1.8-SNAPSHOT</version>
+
+</project>
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/ProjectLinksSensorTest/shouldSaveLinks.xml b/sonar-batch/src/test/resources/org/sonar/batch/compute/ProjectLinksSensorTest/shouldSaveLinks.xml
new file mode 100644 (file)
index 0000000..a44ea42
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.codehaus.sonar</groupId>
+  <artifactId>sonar</artifactId>
+  <packaging>pom</packaging>
+  <version>1.8-SNAPSHOT</version>
+  <url>http://sonar.codehaus.org</url>
+
+  <organization>
+    <name>SonarSource SA</name>
+    <url>http://www.sonarsource.com</url>
+  </organization>
+  <inceptionYear>2009</inceptionYear>
+
+  <issueManagement>
+    <system>jira</system>
+    <url>http://jira.codehaus.org/browse/SONAR</url>
+  </issueManagement>
+
+  <mailingLists>
+    <mailingList>
+      <name>Sonar users mailing list</name>
+      <subscribe>http://xircles.codehaus.org/projects/sonar/lists</subscribe>
+      <unsubscribe>http://xircles.codehaus.org/projects/sonar/lists</unsubscribe>
+      <post>user@sonar.codehaus.org</post>
+      <archive>http://www.nabble.com/Sonar-f30151.html</archive>
+    </mailingList>
+  </mailingLists>
+
+  <scm>
+    <connection>scm:svn:http://svn.codehaus.org/sonar/trunk</connection>
+    <developerConnection>scm:svn:https://svn.codehaus.org/sonar/trunk</developerConnection>
+    <url>http://svn.sonar.codehaus.org</url>
+  </scm>
+
+  <ciManagement>
+    <system>bamboo</system>
+    <url>http://bamboo.ci.codehaus.org/browse/SONAR/</url>
+  </ciManagement>
+
+  <licenses>
+    <license>
+      <name>GNU Lesser General Public License (LGPL), v.3</name>
+      <url>http://www.gnu.org/licenses/lgpl.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+
+</project>
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/TimeMachineConfigurationPersisterTest/shared.xml b/sonar-batch/src/test/resources/org/sonar/batch/compute/TimeMachineConfigurationPersisterTest/shared.xml
new file mode 100644 (file)
index 0000000..70c8178
--- /dev/null
@@ -0,0 +1,42 @@
+<dataset>
+  <snapshots purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             id="100" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
+             status="P" islast="false" depth="0" />
+
+  <snapshots purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             id="200" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" created_at="1229345880000" build_date="1229345880000" version="[null]" path=""
+             status="P" islast="false" depth="0" />
+
+  <!-- Snapshot of previous version -->
+  <snapshots purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             id="300" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" created_at="1229173080000" build_date="1229173080000" version="1.2.3" path=""
+             status="P" islast="false" depth="0" />
+
+  <snapshots purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" created_at="1235566680000" build_date="1235566680000" version="[null]" path=""
+             status="P" islast="false" depth="0" />
+</dataset>
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/TimeMachineConfigurationPersisterTest/shouldSaveConfigurationInSnapshotsTable-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/compute/TimeMachineConfigurationPersisterTest/shouldSaveConfigurationInSnapshotsTable-result.xml
new file mode 100644 (file)
index 0000000..34fdf2d
--- /dev/null
@@ -0,0 +1,42 @@
+<dataset>
+  <snapshots purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             id="100" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
+             status="P" islast="false" depth="0" />
+
+  <snapshots purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             id="200" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" created_at="1229345880000" build_date="1229345880000" version="[null]" path=""
+             status="P" islast="false" depth="0" />
+
+  <!-- Snapshot of previous version -->
+  <snapshots purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             id="300" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" created_at="1229173080000" build_date="1229173080000" version="1.2.3" path=""
+             status="P" islast="false" depth="0" />
+
+  <snapshots purge_status="[null]"
+             period1_mode="days" period1_param="30" period1_date="1225544280000"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="version" period3_param="1.2.3" period3_date="1229173080000"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" created_at="1235566680000" build_date="1235566680000" version="[null]" path=""
+             status="P" islast="false" depth="0" />
+</dataset>
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationPersisterDecoratorTest/shared.xml b/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationPersisterDecoratorTest/shared.xml
new file mode 100644 (file)
index 0000000..519ce8d
--- /dev/null
@@ -0,0 +1,21 @@
+<dataset>
+
+  <rules tags="[null]" system_tags="[null]" id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
+         plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
+         is_template="[false]" template_id="[null]"/>
+
+  <rules tags="[null]" system_tags="[null]" id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
+         plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
+         is_template="[false]" template_id="[null]"/>
+
+  <projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
+            name="Bar" long_name="org.foo.Bar" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+
+  <snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]"
+             period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
+             scope="FIL" qualifier="CLA" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
+             status="U" islast="false" depth="3"/>
+
+</dataset>
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationPersisterDecoratorTest/shouldCopyPermanentIdFromReferenceViolation-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationPersisterDecoratorTest/shouldCopyPermanentIdFromReferenceViolation-result.xml
new file mode 100644 (file)
index 0000000..0610418
--- /dev/null
@@ -0,0 +1,21 @@
+<dataset>
+
+  <rules tags="[null]" system_tags="[null]" id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
+         plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
+         is_template="[false]" template_id="[null]"/>
+
+  <rules tags="[null]" system_tags="[null]" id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
+         plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
+         is_template="[false]" template_id="[null]"/>
+
+  <projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
+            name="Bar" long_name="org.foo.Bar" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+
+  <snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]"
+             period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000" project_id="200"
+             parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
+             scope="FIL" qualifier="CLA" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
+             status="U" islast="false" depth="3"/>
+
+</dataset>
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationPersisterDecoratorTest/shouldSaveViolations-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationPersisterDecoratorTest/shouldSaveViolations-result.xml
new file mode 100644 (file)
index 0000000..f1bbc0b
--- /dev/null
@@ -0,0 +1,20 @@
+<dataset>
+  <rules tags="[null]" system_tags="[null]" id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
+         plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
+         is_template="[false]" template_id="[null]"/>
+
+  <rules tags="[null]" system_tags="[null]" id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
+         plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" status="READY"
+         is_template="[false]" template_id="[null]"/>
+
+  <projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
+            name="Bar" long_name="org.foo.Bar" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+
+  <snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]"
+             period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000" project_id="200"
+             parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
+             scope="FIL" qualifier="CLA" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
+             status="U" islast="false" depth="3"/>
+
+</dataset>
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example1-v1.txt b/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example1-v1.txt
new file mode 100644 (file)
index 0000000..1920333
--- /dev/null
@@ -0,0 +1,12 @@
+package example1;
+
+public class Toto {
+
+    public void doSomething() {
+        // doSomething
+        }
+
+    public void doSomethingElse() {
+        // doSomethingElse
+        }
+}
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example1-v2.txt b/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example1-v2.txt
new file mode 100644 (file)
index 0000000..2315324
--- /dev/null
@@ -0,0 +1,22 @@
+package example1;
+
+public class Toto {
+
+    public Toto(){}
+
+    public void doSomethingNew() {
+        // doSomethingNew
+        }
+
+    public void doSomethingElseNew() {
+        // doSomethingElseNew
+        }
+
+    public void doSomething() {
+        // doSomething
+        }
+
+    public void doSomethingElse() {
+        // doSomethingElse
+        }
+}
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example2-v1.txt b/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example2-v1.txt
new file mode 100644 (file)
index 0000000..a920afe
--- /dev/null
@@ -0,0 +1,7 @@
+package example2;
+
+public class Toto {
+  void method1() {
+    System.out.println("toto");
+  }
+}
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example2-v2.txt b/sonar-batch/src/test/resources/org/sonar/batch/compute/ViolationTrackingTest/example2-v2.txt
new file mode 100644 (file)
index 0000000..c5c8250
--- /dev/null
@@ -0,0 +1,16 @@
+package example2;
+
+public class Toto {
+
+  void method2() {
+    System.out.println("toto");
+  }
+
+  void method1() {
+    System.out.println("toto");
+  }
+
+  void method3() {
+    System.out.println("toto");
+  }
+}