]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11151 Use changed lines in the Scanner report to calculate metrics concerning...
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Tue, 14 Aug 2018 11:39:54 +0000 (13:39 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 19 Sep 2018 08:51:39 +0000 (10:51 +0200)
26 files changed:
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/CounterInitializationContext.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/CreateMeasureContext.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/FormulaExecutorComponentVisitor.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewEffortAggregator.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/period/PeriodHolder.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepository.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/ComputeFileSourceData.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepository.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/SignificantCodeRepository.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/NewCoverageMeasuresStep.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/NewSizeMeasuresStep.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/AverageFormulaTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/DistributionFormulaTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/DumbCreateMeasureContext.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/IntSumFormulaTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/LongSumFormulaTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ReportFormulaExecutorComponentVisitorTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ViewsFormulaExecutorComponentVisitorTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/coverage/CoverageUtilsTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepositoryTest.java [new file with mode: 0644]
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/NewSizeMeasuresStepTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportNewCoverageMeasuresStepTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsNewCoverageMeasuresStepTest.java

index 55b2be91c7018fa3ea319fa917e38693e15f66d5..39911cc9047dbff5aac0554073748ebe508f7187 100644 (file)
@@ -112,6 +112,7 @@ import org.sonar.ce.task.projectanalysis.scm.ScmInfoDbLoader;
 import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryImpl;
 import org.sonar.ce.task.projectanalysis.source.DbLineHashVersion;
 import org.sonar.ce.task.projectanalysis.source.LastCommitVisitor;
+import org.sonar.ce.task.projectanalysis.source.NewLinesRepository;
 import org.sonar.ce.task.projectanalysis.source.SignificantCodeRepository;
 import org.sonar.ce.task.projectanalysis.source.SourceHashRepositoryImpl;
 import org.sonar.ce.task.projectanalysis.source.SourceLinesDiffImpl;
@@ -205,6 +206,7 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop
       DbLineHashVersion.class,
       SignificantCodeRepository.class,
       SourceLinesHashCache.class,
+      NewLinesRepository.class,
 
       // issues
       RuleRepositoryImpl.class,
index febac2da9a0b6890790e328b1e55df51aea2716f..f952bf15ca9c03073e9eb1afdcf6aa3fb3ddd9ce 100644 (file)
@@ -21,10 +21,7 @@ package org.sonar.ce.task.projectanalysis.formula;
 
 import com.google.common.base.Optional;
 import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
-import org.sonar.ce.task.projectanalysis.period.Period;
 
 /**
  * The context passing information to {@link Counter#initialize(CounterInitializationContext)}.
@@ -41,14 +38,4 @@ public interface CounterInitializationContext {
    */
   Optional<Measure> getMeasure(String metricKey);
 
-  /**
-   * Return Period defined for the current project. It can be used to retrieve variation Measure.
-   */
-  Period getPeriod();
-
-  /**
-   * Finds out whether the a period is definfed or not
-   */
-  boolean hasPeriod();
-
 }
index ce626a1d9bcc5036fdcedc726e1da10e6c0ca7df..0af44936204437dbdb3eac539a1e77b729cead25 100644 (file)
@@ -21,10 +21,6 @@ package org.sonar.ce.task.projectanalysis.formula;
 
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.metric.Metric;
-import org.sonar.ce.task.projectanalysis.period.Period;
 
 /**
  * Context passing information to implementation of {@link Formula#createMeasure(Counter, CreateMeasureContext)} method.
@@ -40,13 +36,4 @@ public interface CreateMeasureContext {
    */
   Metric getMetric();
 
-  /**
-   * The period for which variation of the measure can be created.
-   */
-  Period getPeriod();
-
-  /**
-   * Finds out whether the a period is definfed or not
-   */
-  boolean hasPeriod();
 }
index 84f5a9105412d161e964c4528e964b3a961b664a..5cd56d376523a823a64ee378565f894884886b08 100644 (file)
@@ -30,18 +30,10 @@ import org.sonar.ce.task.projectanalysis.component.ComponentVisitor;
 import org.sonar.ce.task.projectanalysis.component.PathAwareVisitorAdapter;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
 import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolder;
-import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.ComponentVisitor;
 import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit;
-import org.sonar.ce.task.projectanalysis.component.PathAwareVisitorAdapter;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
-import org.sonar.ce.task.projectanalysis.metric.Metric;
-import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolder;
+
 
 import static java.util.Objects.requireNonNull;
 
@@ -66,15 +58,12 @@ public class FormulaExecutorComponentVisitor extends PathAwareVisitorAdapter<For
     }
   };
 
-  @CheckForNull
-  private final PeriodHolder periodHolder;
   private final MetricRepository metricRepository;
   private final MeasureRepository measureRepository;
   private final List<Formula> formulas;
 
   private FormulaExecutorComponentVisitor(Builder builder, Iterable<Formula> formulas) {
     super(CrawlerDepthLimit.LEAVES, ComponentVisitor.Order.POST_ORDER, COUNTERS_FACTORY);
-    this.periodHolder = builder.periodHolder;
     this.measureRepository = builder.measureRepository;
     this.metricRepository = builder.metricRepository;
     this.formulas = ImmutableList.copyOf(formulas);
@@ -87,8 +76,6 @@ public class FormulaExecutorComponentVisitor extends PathAwareVisitorAdapter<For
   public static class Builder {
     private final MetricRepository metricRepository;
     private final MeasureRepository measureRepository;
-    @CheckForNull
-    private PeriodHolder periodHolder;
 
     private Builder(MetricRepository metricRepository, MeasureRepository measureRepository) {
       this.metricRepository = requireNonNull(metricRepository);
@@ -99,11 +86,6 @@ public class FormulaExecutorComponentVisitor extends PathAwareVisitorAdapter<For
       return new Builder(metricRepository, measureRepository);
     }
 
-    public Builder withVariationSupport(PeriodHolder periodHolder) {
-      this.periodHolder = requireNonNull(periodHolder);
-      return this;
-    }
-
     public FormulaExecutorComponentVisitor buildFor(Iterable<Formula> formulas) {
       return new FormulaExecutorComponentVisitor(this, formulas);
     }
@@ -212,15 +194,6 @@ public class FormulaExecutorComponentVisitor extends PathAwareVisitorAdapter<For
       return measureRepository.getRawMeasure(file, metricRepository.getByKey(metricKey));
     }
 
-    @Override
-    public Period getPeriod() {
-      return periodHolder.getPeriod();
-    }
-
-    @Override
-    public boolean hasPeriod() {
-      return periodHolder.hasPeriod();
-    }
   }
 
   public static class Counters {
@@ -263,14 +236,5 @@ public class FormulaExecutorComponentVisitor extends PathAwareVisitorAdapter<For
       return metric;
     }
 
-    @Override
-    public Period getPeriod() {
-      return periodHolder.getPeriod();
-    }
-
-    @Override
-    public boolean hasPeriod() {
-      return periodHolder.hasPeriod();
-    }
   }
 }
index 7c7f9e0473f2e84de1f6b2d386108ade8200d18b..acb3e5198637c81889d912202076b93dddd80e40 100644 (file)
@@ -25,7 +25,6 @@ import java.util.Map;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.core.issue.DefaultIssue;
-import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
index 937d8ce874da4a3a2cb3bdf839f0168c25ffea21..ba7d733c79a0b28d5f455454293eb584ec81aab4 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.ce.task.projectanalysis.period;
 
+import javax.annotation.CheckForNull;
+
 /**
  * Repository of period used to compute differential measures.
  * Here are the steps to retrieve the period :
@@ -40,6 +42,7 @@ public interface PeriodHolder {
    *
    * @throws IllegalStateException if the periods haven't been initialized
    */
+  @CheckForNull
   Period getPeriod();
 
 }
index e4be7a7294bab2023ded6e2f207a43eec20e4494..2fed329b51affb487e54f70b4a28a6efc58f4d5f 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.ce.task.projectanalysis.qualitymodel;
 
 import com.google.common.base.Optional;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.utils.KeyValueFormat;
@@ -35,11 +36,7 @@ import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
 import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolder;
-import org.sonar.ce.task.projectanalysis.scm.Changeset;
-import org.sonar.ce.task.projectanalysis.scm.ScmInfo;
-import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepository;
+import org.sonar.ce.task.projectanalysis.source.NewLinesRepository;
 
 import static org.sonar.api.measures.CoreMetrics.NCLOC_DATA_KEY;
 import static org.sonar.api.measures.CoreMetrics.NEW_DEVELOPMENT_COST_KEY;
@@ -61,9 +58,8 @@ import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilde
 public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<NewMaintainabilityMeasuresVisitor.Counter> {
   private static final Logger LOG = Loggers.get(NewMaintainabilityMeasuresVisitor.class);
 
-  private final ScmInfoRepository scmInfoRepository;
   private final MeasureRepository measureRepository;
-  private final PeriodHolder periodHolder;
+  private final NewLinesRepository newLinesRepository;
   private final RatingSettings ratingSettings;
 
   private final Metric newDebtMetric;
@@ -73,12 +69,11 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N
   private final Metric newDebtRatioMetric;
   private final Metric newMaintainabilityRatingMetric;
 
-  public NewMaintainabilityMeasuresVisitor(MetricRepository metricRepository, MeasureRepository measureRepository, ScmInfoRepository scmInfoRepository,
-    PeriodHolder periodHolder, RatingSettings ratingSettings) {
+  public NewMaintainabilityMeasuresVisitor(MetricRepository metricRepository, MeasureRepository measureRepository, NewLinesRepository newLinesRepository,
+    RatingSettings ratingSettings) {
     super(CrawlerDepthLimit.FILE, POST_ORDER, CounterFactory.INSTANCE);
     this.measureRepository = measureRepository;
-    this.scmInfoRepository = scmInfoRepository;
-    this.periodHolder = periodHolder;
+    this.newLinesRepository = newLinesRepository;
     this.ratingSettings = ratingSettings;
 
     // computed by NewDebtAggregator which is executed by IntegrateIssuesVisitor
@@ -117,7 +112,7 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N
   }
 
   private void computeAndSaveNewDebtRatioMeasure(Component component, Path<Counter> path) {
-    if (!periodHolder.hasPeriod()) {
+    if (!newLinesRepository.newLinesAvailable()) {
       return;
     }
     double density = computeDensity(path.current());
@@ -156,37 +151,33 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N
 
   private void initNewDebtRatioCounter(Component file, Path<Counter> path) {
     // first analysis, no period, no differential value to compute, save processing time and return now
-    if (!periodHolder.hasPeriod()) {
+    if (!newLinesRepository.newLinesAvailable()) {
       return;
     }
 
-    Optional<Measure> nclocDataMeasure = measureRepository.getRawMeasure(file, this.nclocDataMetric);
-    if (!nclocDataMeasure.isPresent()) {
+    java.util.Optional<Set<Integer>> changedLines = newLinesRepository.getNewLines(file);
+
+    if (!changedLines.isPresent()) {
+      LOG.trace(String.format("No information about changed lines is available for file '%s'. Dev cost will be zero.", file.getKey()));
       return;
     }
 
-    java.util.Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(file);
-    if (!scmInfoOptional.isPresent()) {
-      LOG.trace(String.format("No changeset for file %s. Dev cost will be zero.", file.getKey()));
+    Optional<Measure> nclocDataMeasure = measureRepository.getRawMeasure(file, this.nclocDataMetric);
+    if (!nclocDataMeasure.isPresent()) {
       return;
     }
 
-    ScmInfo scmInfo = scmInfoOptional.get();
-    initNewDebtRatioCounter(path.current(), file, nclocDataMeasure.get(), scmInfo);
+    initNewDebtRatioCounter(path.current(), file, nclocDataMeasure.get(), changedLines.get());
   }
 
-  private void initNewDebtRatioCounter(Counter devCostCounter, Component file, Measure nclocDataMeasure, ScmInfo scmInfo) {
+  private void initNewDebtRatioCounter(Counter devCostCounter, Component file, Measure nclocDataMeasure, Set<Integer> changedLines) {
     boolean hasDevCost = false;
 
     long lineDevCost = ratingSettings.getDevCost(file.getFileAttributes().getLanguageKey());
     for (Integer nclocLineIndex : nclocLineIndexes(nclocDataMeasure)) {
-      if (scmInfo.hasChangesetForLine(nclocLineIndex)) {
-        Changeset changeset = scmInfo.getChangesetForLine(nclocLineIndex);
-        Period period = periodHolder.getPeriod();
-        if (isLineInPeriod(changeset.getDate(), period)) {
-          devCostCounter.incrementDevCost(lineDevCost);
-          hasDevCost = true;
-        }
+      if (changedLines.contains(nclocLineIndex)) {
+        devCostCounter.incrementDevCost(lineDevCost);
+        hasDevCost = true;
       }
     }
     if (hasDevCost) {
@@ -199,13 +190,6 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N
     path.parent().add(path.current());
   }
 
-  /**
-   * A line belongs to a Period if its date is older than the SNAPSHOT's date of the period.
-   */
-  private static boolean isLineInPeriod(long lineDate, Period period) {
-    return lineDate > period.getSnapshotDate();
-  }
-
   /**
    * NCLOC_DATA contains Key-value pairs, where key - is a number of line, and value - is an indicator of whether line
    * contains code (1) or not (0).
index 605815b508382e9dc9681ac02ea4519a6296a5f7..cd4c2d187babaccbf5e3a5c6adf06800a9f7fb9c 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.ce.task.projectanalysis.scm;
 
 import java.util.Optional;
 import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.Component;
 
 /**
  * Return SCM information of components.
@@ -33,10 +32,10 @@ public interface ScmInfoRepository {
   /**
    * Returns Scm info for the specified component if there is any, first looking into the report, then into the database
    * <p>
-   * If there's nothing in the report and in the db (on first analysis for instance), then it return a {@link Optional#absent()}.
+   * If there's nothing in the report and in the db (on first analysis for instance), then it return a {@link Optional#empty()}.
    * </p>
    * <p>
-   * This method will always return {@link Optional#absent()} if the specified component's type is not {@link Component.Type#FILE}.
+   * This method will always return {@link Optional#empty()} if the specified component's type is not {@link Component.Type#FILE}.
    * </p>
    *
    * @throws NullPointerException if argument is {@code null}
index c492be64aeef389d8c80807342df7a1e0fc135e4..37abda331622b2552730a59b09cc9342512ba3a8 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.ce.task.projectanalysis.source;
 
-import com.google.common.base.Joiner;
 import java.util.Iterator;
 import java.util.List;
 import org.sonar.core.hash.SourceHashComputer;
@@ -28,8 +27,6 @@ import org.sonar.ce.task.projectanalysis.source.SourceLinesHashRepositoryImpl.Li
 import org.sonar.ce.task.projectanalysis.source.linereader.LineReader;
 
 public class ComputeFileSourceData {
-  private static final Joiner LINE_RETURN_JOINER = Joiner.on('\n');
-
   private final List<LineReader> lineReaders;
   private final Iterator<String> linesIterator;
   private final SourceHashComputer sourceHashComputer;
index d2d0c9b562dbaa88bd896dae5ac118f2efc9823a..38e14292a97861ae1028b7a965e59bf24ff505ae 100644 (file)
@@ -24,7 +24,6 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
-import javax.annotation.Nullable;
 import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
 import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
 import org.sonar.ce.task.projectanalysis.component.Component;
@@ -38,24 +37,18 @@ public class NewLinesRepository {
   private final BatchReportReader reportReader;
   private final AnalysisMetadataHolder analysisMetadataHolder;
   private final ScmInfoRepository scmInfoRepository;
-  @Nullable
-  private final Period period;
+  private final PeriodHolder periodHolder;
   private final Map<Component, Optional<Set<Integer>>> changedLinesCache = new HashMap<>();
 
   public NewLinesRepository(BatchReportReader reportReader, AnalysisMetadataHolder analysisMetadataHolder, PeriodHolder periodHolder, ScmInfoRepository scmInfoRepository) {
     this.reportReader = reportReader;
     this.analysisMetadataHolder = analysisMetadataHolder;
     this.scmInfoRepository = scmInfoRepository;
-    this.period = periodHolder.getPeriod();
+    this.periodHolder = periodHolder;
   }
 
-  public boolean newLinesAvailable(Component component) {
-    return getNewLines(component).isPresent();
-  }
-
-  public boolean isLineNew(Component component, int line) {
-    return getNewLines(component).map(s -> s.contains(line))
-      .orElseThrow(() -> new IllegalStateException("No data about new lines available"));
+  public boolean newLinesAvailable() {
+    return periodHolder.hasPeriod();
   }
 
   public Optional<Set<Integer>> getNewLines(Component component) {
@@ -67,11 +60,16 @@ public class NewLinesRepository {
     if (reportChangedLines.isPresent()) {
       return reportChangedLines;
     }
-    return generateNewLinesFromScm(component);
+    return computeNewLinesFromScm(component);
   }
 
-  private Optional<Set<Integer>> generateNewLinesFromScm(Component component) {
-    if (period == null) {
+  /**
+   * If the changed lines are not in the report or if we are not analyzing a short lived branch (or P/R) we fall back to this method.
+   * If there is a period and SCM information, we compare the change dates of each line with the start of the period to figure out
+   * if a line is new or not.
+   */
+  private Optional<Set<Integer>> computeNewLinesFromScm(Component component) {
+    if (!periodHolder.hasPeriod()) {
       return Optional.empty();
     }
 
@@ -85,7 +83,7 @@ public class NewLinesRepository {
     Set<Integer> lines = new HashSet<>();
 
     for (Map.Entry<Integer, Changeset> e : allChangesets.entrySet()) {
-      if (isLineInPeriod(e.getValue().getDate(), period)) {
+      if (isLineInPeriod(e.getValue().getDate(), periodHolder.getPeriod())) {
         lines.add(e.getKey());
       }
     }
index 64974bc273c958c7adfc510aeb12e7a07e163202..0138915b272b674f922ab89b8a14bfe4e37504d8 100644 (file)
@@ -25,7 +25,6 @@ import org.sonar.core.hash.LineRange;
 import org.sonar.core.util.CloseableIterator;
 import org.sonar.scanner.protocol.output.ScannerReport.LineSgnificantCode;
 import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
-import org.sonar.ce.task.projectanalysis.component.Component;
 
 public class SignificantCodeRepository {
   private final BatchReportReader reportReader;
index 6048a183f24724718d5539809fec8f8f332cb5ff..ed00e29c9332ca70a3662c52ccc8fa9099507dd0 100644 (file)
@@ -25,13 +25,12 @@ import com.google.common.collect.Iterables;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import javax.annotation.CheckForNull;
+import java.util.Set;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.Immutable;
 import org.apache.commons.lang.ObjectUtils;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.component.PathAwareCrawler;
 import org.sonar.ce.task.projectanalysis.component.TreeRootHolder;
@@ -50,10 +49,7 @@ import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
 import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolder;
-import org.sonar.ce.task.projectanalysis.scm.ScmInfo;
-import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepository;
+import org.sonar.ce.task.projectanalysis.source.NewLinesRepository;
 import org.sonar.ce.task.step.ComputationStep;
 
 import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
@@ -70,44 +66,39 @@ public class NewCoverageMeasuresStep implements ComputationStep {
     new NewLineCoverageFormula());
 
   private final TreeRootHolder treeRootHolder;
-  private final PeriodHolder periodHolder;
   private final MetricRepository metricRepository;
   private final MeasureRepository measureRepository;
-  @CheckForNull
-  private final ScmInfoRepository scmInfoRepository;
+  @Nullable
+  private final NewLinesRepository newLinesRepository;
 
   /**
-   * Constructor used when processing a Report (ie. a {@link BatchReportReader} instance is available in the container)
+   * Constructor used when processing a Report (ie. a {@link NewLinesRepository} instance is available in the container)
    */
-  public NewCoverageMeasuresStep(TreeRootHolder treeRootHolder, PeriodHolder periodHolder,
-    MeasureRepository measureRepository, final MetricRepository metricRepository, ScmInfoRepository scmInfoRepository) {
+  public NewCoverageMeasuresStep(TreeRootHolder treeRootHolder,
+    MeasureRepository measureRepository, MetricRepository metricRepository, NewLinesRepository newLinesRepository) {
     this.treeRootHolder = treeRootHolder;
-    this.periodHolder = periodHolder;
     this.metricRepository = metricRepository;
     this.measureRepository = measureRepository;
-    this.scmInfoRepository = scmInfoRepository;
+    this.newLinesRepository = newLinesRepository;
   }
 
   /**
-   * Constructor used when processing Views (ie. no {@link BatchReportReader} instance is available in the container)
+   * Constructor used when processing Views (ie. no {@link NewLinesRepository} instance is available in the container)
    */
-  public NewCoverageMeasuresStep(TreeRootHolder treeRootHolder, PeriodHolder periodHolder,
-    MeasureRepository measureRepository, final MetricRepository metricRepository) {
+  public NewCoverageMeasuresStep(TreeRootHolder treeRootHolder, MeasureRepository measureRepository, MetricRepository metricRepository) {
     this.treeRootHolder = treeRootHolder;
-    this.periodHolder = periodHolder;
     this.metricRepository = metricRepository;
     this.measureRepository = measureRepository;
-    this.scmInfoRepository = null;
+    this.newLinesRepository = null;
   }
 
   @Override
   public void execute(ComputationStep.Context context) {
     new PathAwareCrawler<>(
       FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository)
-        .withVariationSupport(periodHolder)
         .buildFor(
-          Iterables.concat(NewLinesAndConditionsCoverageFormula.from(scmInfoRepository), FORMULAS)))
-            .visit(treeRootHolder.getRoot());
+          Iterables.concat(NewLinesAndConditionsCoverageFormula.from(newLinesRepository), FORMULAS)))
+      .visit(treeRootHolder.getRoot());
   }
 
   @Override
@@ -122,18 +113,18 @@ public class NewCoverageMeasuresStep implements ComputationStep {
       CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY);
     private static final Iterable<Formula<?>> VIEWS_FORMULAS = variationSumFormulas(OUTPUT_METRIC_KEYS);
 
-    private NewLinesAndConditionsCoverageFormula(ScmInfoRepository scmInfoRepository) {
-      super(scmInfoRepository,
+    private NewLinesAndConditionsCoverageFormula(NewLinesRepository newLinesRepository) {
+      super(newLinesRepository,
         new NewCoverageInputMetricKeys(
           CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, CoreMetrics.CONDITIONS_BY_LINE_KEY, CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY),
         OUTPUT_METRIC_KEYS);
     }
 
-    public static Iterable<Formula<?>> from(@Nullable ScmInfoRepository scmInfoRepository) {
-      if (scmInfoRepository == null) {
+    public static Iterable<Formula<?>> from(@Nullable NewLinesRepository newLinesRepository) {
+      if (newLinesRepository == null) {
         return VIEWS_FORMULAS;
       }
-      return Collections.singleton(new NewLinesAndConditionsCoverageFormula(scmInfoRepository));
+      return Collections.singleton(new NewLinesAndConditionsCoverageFormula(newLinesRepository));
     }
 
     /**
@@ -176,19 +167,19 @@ public class NewCoverageMeasuresStep implements ComputationStep {
   }
 
   public static class NewLinesAndConditionsFormula implements Formula<NewCoverageCounter> {
-    private final ScmInfoRepository scmInfoRepository;
+    private final NewLinesRepository newLinesRepository;
     private final NewCoverageInputMetricKeys inputMetricKeys;
     private final NewCoverageOutputMetricKeys outputMetricKeys;
 
-    public NewLinesAndConditionsFormula(ScmInfoRepository scmInfoRepository, NewCoverageInputMetricKeys inputMetricKeys, NewCoverageOutputMetricKeys outputMetricKeys) {
-      this.scmInfoRepository = scmInfoRepository;
+    public NewLinesAndConditionsFormula(NewLinesRepository newLinesRepository, NewCoverageInputMetricKeys inputMetricKeys, NewCoverageOutputMetricKeys outputMetricKeys) {
+      this.newLinesRepository = newLinesRepository;
       this.inputMetricKeys = inputMetricKeys;
       this.outputMetricKeys = outputMetricKeys;
     }
 
     @Override
     public NewCoverageCounter createNewCounter() {
-      return new NewCoverageCounter(scmInfoRepository, inputMetricKeys);
+      return new NewCoverageCounter(newLinesRepository, inputMetricKeys);
     }
 
     @Override
@@ -232,11 +223,11 @@ public class NewCoverageMeasuresStep implements ComputationStep {
     private final IntValue newCoveredLines = new IntValue();
     private final IntValue newConditions = new IntValue();
     private final IntValue newCoveredConditions = new IntValue();
-    private final ScmInfoRepository scmInfoRepository;
+    private final NewLinesRepository newLinesRepository;
     private final NewCoverageInputMetricKeys metricKeys;
 
-    public NewCoverageCounter(ScmInfoRepository scmInfoRepository, NewCoverageInputMetricKeys metricKeys) {
-      this.scmInfoRepository = scmInfoRepository;
+    public NewCoverageCounter(NewLinesRepository newLinesRepository, NewCoverageInputMetricKeys metricKeys) {
+      this.newLinesRepository = newLinesRepository;
       this.metricKeys = metricKeys;
     }
 
@@ -251,11 +242,10 @@ public class NewCoverageMeasuresStep implements ComputationStep {
     @Override
     public void initialize(CounterInitializationContext context) {
       Component fileComponent = context.getLeaf();
-      java.util.Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(fileComponent);
-      if (!scmInfoOptional.isPresent() || !context.hasPeriod()) {
+      java.util.Optional<Set<Integer>> newLinesSet = newLinesRepository.getNewLines(fileComponent);
+      if (!newLinesSet.isPresent()) {
         return;
       }
-      ScmInfo componentScm = scmInfoOptional.get();
 
       newLines.increment(0);
       newCoveredLines.increment(0);
@@ -272,9 +262,8 @@ public class NewCoverageMeasuresStep implements ComputationStep {
         int hits = entry.getValue();
         int conditions = (Integer) ObjectUtils.defaultIfNull(conditionsByLine.get(lineId), 0);
         int coveredConditions = (Integer) ObjectUtils.defaultIfNull(coveredConditionsByLine.get(lineId), 0);
-        if (componentScm.hasChangesetForLine(lineId)) {
-          long date = componentScm.getChangesetForLine(lineId).getDate();
-          analyze(context.getPeriod(), date, hits, conditions, coveredConditions);
+        if (newLinesSet.get().contains(lineId)) {
+          analyze(hits, conditions, coveredConditions);
         }
       }
     }
@@ -286,18 +275,9 @@ public class NewCoverageMeasuresStep implements ComputationStep {
       return Collections.emptyMap();
     }
 
-    void analyze(Period period, long lineDate, int hits, int conditions, int coveredConditions) {
-      if (isLineInPeriod(lineDate, period)) {
-        incrementLines(hits);
-        incrementConditions(conditions, coveredConditions);
-      }
-    }
-
-    /**
-     * A line belongs to a Period if its date is older than the SNAPSHOT's date of the period.
-     */
-    private static boolean isLineInPeriod(long lineDate, Period period) {
-      return lineDate > period.getSnapshotDate();
+    void analyze(int hits, int conditions, int coveredConditions) {
+      incrementLines(hits);
+      incrementConditions(conditions, coveredConditions);
     }
 
     private void incrementLines(int hits) {
index c4abc14afd91ef3f690860dd4180cb86f9aa058e..bc1b3c2f5b6ba8e070d64a714e05f83cb75f45aa 100644 (file)
@@ -40,11 +40,7 @@ import org.sonar.ce.task.projectanalysis.formula.counter.IntValue;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
 import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolder;
-import org.sonar.ce.task.projectanalysis.scm.Changeset;
-import org.sonar.ce.task.projectanalysis.scm.ScmInfo;
-import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepository;
+import org.sonar.ce.task.projectanalysis.source.NewLinesRepository;
 import org.sonar.ce.task.step.ComputationStep;
 
 import static org.sonar.api.measures.CoreMetrics.NEW_BLOCKS_DUPLICATED_KEY;
@@ -58,18 +54,16 @@ import static org.sonar.api.measures.CoreMetrics.NEW_LINES_KEY;
 public class NewSizeMeasuresStep implements ComputationStep {
 
   private final TreeRootHolder treeRootHolder;
-  private final PeriodHolder periodHolder;
   private final MetricRepository metricRepository;
   private final MeasureRepository measureRepository;
   private final NewDuplicationFormula duplicationFormula;
 
-  public NewSizeMeasuresStep(TreeRootHolder treeRootHolder, PeriodHolder periodHolder, MetricRepository metricRepository, MeasureRepository measureRepository,
-    ScmInfoRepository scmInfoRepository, DuplicationRepository duplicationRepository) {
+  public NewSizeMeasuresStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository,
+    NewLinesRepository newLinesRepository, DuplicationRepository duplicationRepository) {
     this.treeRootHolder = treeRootHolder;
-    this.periodHolder = periodHolder;
     this.metricRepository = metricRepository;
     this.measureRepository = measureRepository;
-    this.duplicationFormula = new NewDuplicationFormula(scmInfoRepository, duplicationRepository);
+    this.duplicationFormula = new NewDuplicationFormula(newLinesRepository, duplicationRepository);
   }
 
   @Override
@@ -81,22 +75,21 @@ public class NewSizeMeasuresStep implements ComputationStep {
   public void execute(ComputationStep.Context context) {
     new PathAwareCrawler<>(
       FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository)
-        .withVariationSupport(periodHolder)
         .buildFor(ImmutableList.of(duplicationFormula)))
-          .visit(treeRootHolder.getRoot());
+      .visit(treeRootHolder.getRoot());
   }
 
   private static class NewSizeCounter implements Counter<NewSizeCounter> {
     private final DuplicationRepository duplicationRepository;
-    private final ScmInfoRepository scmInfoRepository;
+    private final NewLinesRepository newLinesRepository;
+
     private final IntValue newLines = new IntValue();
     private final IntValue newDuplicatedLines = new IntValue();
     private final IntValue newDuplicatedBlocks = new IntValue();
 
-    private NewSizeCounter(DuplicationRepository duplicationRepository,
-      ScmInfoRepository scmInfoRepository) {
+    private NewSizeCounter(DuplicationRepository duplicationRepository, NewLinesRepository newLinesRepository) {
       this.duplicationRepository = duplicationRepository;
-      this.scmInfoRepository = scmInfoRepository;
+      this.newLinesRepository = newLinesRepository;
     }
 
     @Override
@@ -109,8 +102,8 @@ public class NewSizeMeasuresStep implements ComputationStep {
     @Override
     public void initialize(CounterInitializationContext context) {
       Component leaf = context.getLeaf();
-      java.util.Optional<ScmInfo> scmInfo = scmInfoRepository.getScmInfo(leaf);
-      if (!scmInfo.isPresent() || !context.hasPeriod()) {
+      java.util.Optional<Set<Integer>> changedLines = newLinesRepository.getNewLines(leaf);
+      if (!changedLines.isPresent()) {
         return;
       }
 
@@ -118,21 +111,18 @@ public class NewSizeMeasuresStep implements ComputationStep {
       if (leaf.getType() != Component.Type.FILE) {
         newDuplicatedLines.increment(0);
         newDuplicatedBlocks.increment(0);
-        return;
+      } else {
+        initNewLines(changedLines.get());
+        initNewDuplicated(leaf, changedLines.get());
       }
-
-      initNewLines(scmInfo.get(), context.getPeriod());
-      initNewDuplicated(leaf, scmInfo.get(), context.getPeriod());
     }
 
-    private void initNewLines(ScmInfo scmInfo, Period period) {
-      scmInfo.getAllChangesets().values().stream()
-        .filter(changeset -> isLineInPeriod(changeset, period))
-        .forEach(changeset -> newLines.increment(1));
+    private void initNewLines(Set<Integer> changedLines) {
+      newLines.increment(changedLines.size());
     }
 
-    private void initNewDuplicated(Component component, ScmInfo scmInfo, Period period) {
-      DuplicationCounters duplicationCounters = new DuplicationCounters(scmInfo, period, scmInfo.getAllChangesets().size());
+    private void initNewDuplicated(Component component, Set<Integer> changedLines) {
+      DuplicationCounters duplicationCounters = new DuplicationCounters(changedLines);
       Iterable<Duplication> duplications = duplicationRepository.getDuplications(component);
       for (Duplication duplication : duplications) {
         duplicationCounters.addBlock(duplication.getOriginal());
@@ -145,29 +135,22 @@ public class NewSizeMeasuresStep implements ComputationStep {
       newDuplicatedLines.increment(duplicationCounters.getNewLinesDuplicated());
       newDuplicatedBlocks.increment(duplicationCounters.getNewBlocksDuplicated());
     }
-
-    private static boolean isLineInPeriod(Changeset changeset, Period period) {
-      return changeset.getDate() > period.getSnapshotDate();
-    }
   }
 
   private static class DuplicationCounters {
-    private final ScmInfo scmInfo;
-    private final Period period;
+    private final Set<Integer> changedLines;
     private final Set<Integer> lineCounts;
     private int blockCounts;
 
-    private DuplicationCounters(ScmInfo scmInfo, Period period, int changesetSize) {
-      this.scmInfo = scmInfo;
-      this.period = period;
-      this.lineCounts = new HashSet<>(changesetSize);
+    private DuplicationCounters(Set<Integer> changedLines) {
+      this.changedLines = changedLines;
+      this.lineCounts = new HashSet<>(changedLines.size());
     }
 
     void addBlock(TextBlock textBlock) {
       Boolean[] newBlock = new Boolean[] {false};
       IntStream.rangeClosed(textBlock.getStart(), textBlock.getEnd())
-        .filter(scmInfo::hasChangesetForLine)
-        .filter(line -> isLineInPeriod(line, period))
+        .filter(changedLines::contains)
         .forEach(line -> {
           lineCounts.add(line);
           newBlock[0] = true;
@@ -184,25 +167,20 @@ public class NewSizeMeasuresStep implements ComputationStep {
     int getNewBlocksDuplicated() {
       return blockCounts;
     }
-
-    private boolean isLineInPeriod(int lineNumber, Period period) {
-      return scmInfo.getChangesetForLine(lineNumber).getDate() > period.getSnapshotDate();
-    }
   }
 
   private static final class NewDuplicationFormula implements Formula<NewSizeCounter> {
     private final DuplicationRepository duplicationRepository;
-    private final ScmInfoRepository scmInfoRepository;
+    private final NewLinesRepository newLinesRepository;
 
-    private NewDuplicationFormula(ScmInfoRepository scmInfoRepository,
-      DuplicationRepository duplicationRepository) {
+    private NewDuplicationFormula(NewLinesRepository newLinesRepository, DuplicationRepository duplicationRepository) {
       this.duplicationRepository = duplicationRepository;
-      this.scmInfoRepository = scmInfoRepository;
+      this.newLinesRepository = newLinesRepository;
     }
 
     @Override
     public NewSizeCounter createNewCounter() {
-      return new NewSizeCounter(duplicationRepository, scmInfoRepository);
+      return new NewSizeCounter(duplicationRepository, newLinesRepository);
     }
 
     @Override
index 96e93cc96d98ebea7b0324f7190bc68fdde8dfda..9a355b83701d8789478b37949cae02b7e25674fb 100644 (file)
@@ -28,7 +28,6 @@ import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.component.ReportComponent;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolder;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -49,7 +48,7 @@ public class AverageFormulaTest {
 
   CounterInitializationContext counterInitializationContext = mock(CounterInitializationContext.class);
   CreateMeasureContext createMeasureContext = new DumbCreateMeasureContext(
-    ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class), mock(PeriodHolder.class));
+    ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class));
 
   @Rule
   public ExpectedException thrown = ExpectedException.none();
index 7515afe2d651d4b4212c705965d0ef96649b3e81..58637b42e18e6fb6556dbef68052fc0ed6e6ff4e 100644 (file)
@@ -28,7 +28,6 @@ import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.component.ReportComponent;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolder;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -44,9 +43,9 @@ public class DistributionFormulaTest {
 
   CounterInitializationContext counterInitializationContext = mock(CounterInitializationContext.class);
   CreateMeasureContext projectCreateMeasureContext = new DumbCreateMeasureContext(
-    ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class), mock(PeriodHolder.class));
+    ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class));
   CreateMeasureContext fileCreateMeasureContext = new DumbCreateMeasureContext(
-    ReportComponent.builder(Component.Type.FILE, 1).build(), mock(Metric.class), mock(PeriodHolder.class));
+    ReportComponent.builder(Component.Type.FILE, 1).build(), mock(Metric.class));
 
   @Test
   public void check_new_counter_class() {
index c9e89b12603cc81d3e423899ded887f5183cb3cb..a34bc9973a7d3e98e05c6c470f4313a8c0713a9b 100644 (file)
@@ -21,18 +21,14 @@ package org.sonar.ce.task.projectanalysis.formula;
 
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolder;
 
 public class DumbCreateMeasureContext implements CreateMeasureContext {
   private final Component component;
   private final Metric metric;
-  private final PeriodHolder periodHolder;
 
-  public DumbCreateMeasureContext(Component component, Metric metric, PeriodHolder periodHolder) {
+  public DumbCreateMeasureContext(Component component, Metric metric) {
     this.component = component;
     this.metric = metric;
-    this.periodHolder = periodHolder;
   }
 
   @Override
@@ -45,13 +41,4 @@ public class DumbCreateMeasureContext implements CreateMeasureContext {
     return metric;
   }
 
-  @Override
-  public Period getPeriod() {
-    return periodHolder.getPeriod();
-  }
-
-  @Override
-  public boolean hasPeriod() {
-    return periodHolder.hasPeriod();
-  }
 }
index 1bdf830b58ab52acc97e3315c9f7432602968184..3338ae9f1ce5270e7ba776bb85679f8c3d519e4e 100644 (file)
@@ -31,7 +31,6 @@ import org.sonar.ce.task.projectanalysis.formula.SumFormula.IntSumFormula;
 import org.sonar.ce.task.projectanalysis.formula.counter.IntSumCounter;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolder;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -49,9 +48,9 @@ public class IntSumFormulaTest {
   public ExpectedException thrown = ExpectedException.none();
 
   CreateMeasureContext projectCreateMeasureContext = new DumbCreateMeasureContext(
-    ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class), mock(PeriodHolder.class));
+    ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class));
   CreateMeasureContext fileCreateMeasureContext = new DumbCreateMeasureContext(
-    ReportComponent.builder(Component.Type.FILE, 2).build(), mock(Metric.class), mock(PeriodHolder.class));
+    ReportComponent.builder(Component.Type.FILE, 2).build(), mock(Metric.class));
 
   @Test
   public void check_create_new_counter_class() {
index b2945f8f6d153b8d90b12045eeb6f846eeff4ed0..3bb9101060da2ee4ed800be113c6c7ee51d492f1 100644 (file)
@@ -30,7 +30,6 @@ import org.sonar.ce.task.projectanalysis.component.ReportComponent;
 import org.sonar.ce.task.projectanalysis.formula.counter.LongSumCounter;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolder;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -48,9 +47,9 @@ public class LongSumFormulaTest {
   public ExpectedException thrown = ExpectedException.none();
 
   CreateMeasureContext projectCreateMeasureContext = new DumbCreateMeasureContext(
-    ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class), mock(PeriodHolder.class));
+    ReportComponent.builder(Component.Type.PROJECT, 1).build(), mock(Metric.class));
   CreateMeasureContext fileCreateMeasureContext = new DumbCreateMeasureContext(
-    ReportComponent.builder(Component.Type.FILE, 2).build(), mock(Metric.class), mock(PeriodHolder.class));
+    ReportComponent.builder(Component.Type.FILE, 2).build(), mock(Metric.class));
 
   @Test
   public void check_create_new_counter_class() {
index fca007a2c9c468fe9dc7e0395940f62b531b5cf0..7d4944a18ab027ae5dcb4b5233c210359484390f 100644 (file)
@@ -34,8 +34,6 @@ import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
 import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
@@ -92,8 +90,6 @@ public class ReportFormulaExecutorComponentVisitorTest {
     .add(CoreMetrics.NEW_COVERAGE);
   @Rule
   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
-  @Rule
-  public PeriodHolderRule periodsHolder = new PeriodHolderRule().setPeriod(new Period("some mode", null, 95l, "756l"));
 
   @Test
   public void verify_aggregation_on_value() {
@@ -294,7 +290,6 @@ public class ReportFormulaExecutorComponentVisitorTest {
 
   private FormulaExecutorComponentVisitor formulaExecutorComponentVisitor(Formula formula) {
     return FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository)
-      .withVariationSupport(periodsHolder)
       .buildFor(ImmutableList.of(formula));
   }
 
@@ -321,7 +316,6 @@ public class ReportFormulaExecutorComponentVisitorTest {
     @Override
     public Optional<Measure> createMeasure(FakeCounter counter, CreateMeasureContext context) {
       // verify the context which is passed to the method
-      assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod());
       assertThat(context.getComponent()).isNotNull();
       assertThat(context.getMetric()).isSameAs(metricRepository.getByKey(NCLOC_KEY));
 
@@ -344,7 +338,6 @@ public class ReportFormulaExecutorComponentVisitorTest {
     @Override
     public Optional<Measure> createMeasure(FakeCounter counter, CreateMeasureContext context) {
       // verify the context which is passed to the method
-      assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod());
       assertThat(context.getComponent()).isNotNull();
       assertThat(context.getMetric())
         .isIn(metricRepository.getByKey(NEW_LINES_TO_COVER_KEY), metricRepository.getByKey(NEW_COVERAGE_KEY));
@@ -380,7 +373,6 @@ public class ReportFormulaExecutorComponentVisitorTest {
     public void initialize(CounterInitializationContext context) {
       // verify the context which is passed to the method
       assertThat(context.getLeaf().getChildren()).isEmpty();
-      assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod());
 
       Optional<Measure> measureOptional = context.getMeasure(LINES_KEY);
       if (measureOptional.isPresent()) {
@@ -399,7 +391,6 @@ public class ReportFormulaExecutorComponentVisitorTest {
     @Override
     public Optional<Measure> createMeasure(FakeVariationCounter counter, CreateMeasureContext context) {
       // verify the context which is passed to the method
-      assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod());
       assertThat(context.getComponent()).isNotNull();
       assertThat(context.getMetric()).isSameAs(metricRepository.getByKey(NEW_COVERAGE_KEY));
 
@@ -431,10 +422,9 @@ public class ReportFormulaExecutorComponentVisitorTest {
     public void initialize(CounterInitializationContext context) {
       // verify the context which is passed to the method
       assertThat(context.getLeaf().getChildren()).isEmpty();
-      assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod());
 
       Optional<Measure> measureOptional = context.getMeasure(NEW_LINES_TO_COVER_KEY);
-      if (!measureOptional.isPresent() || !context.hasPeriod()) {
+      if (!measureOptional.isPresent()) {
         return;
       }
       this.values.increment((int) measureOptional.get().getVariation());
index 266c68877e6f0c4ecb433473545b52debf9ce657..2dac82ceef74590e976b8af3c0b8ecc2464e62c7 100644 (file)
@@ -32,8 +32,6 @@ import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
 import org.sonar.ce.task.projectanalysis.metric.Metric;
 import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.guava.api.Assertions.assertThat;
@@ -86,8 +84,6 @@ public class ViewsFormulaExecutorComponentVisitorTest {
     .add(CoreMetrics.NEW_COVERAGE);
   @Rule
   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
-  @Rule
-  public PeriodHolderRule periodsHolder = new PeriodHolderRule().setPeriod(new Period("some mode", null, 95l, "u1"));
 
   @Test
   public void verify_aggregation_on_value() {
@@ -213,7 +209,6 @@ public class ViewsFormulaExecutorComponentVisitorTest {
     @Override
     public Optional<Measure> createMeasure(FakeCounter counter, CreateMeasureContext context) {
       // verify the context which is passed to the method
-      assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod());
       assertThat(context.getComponent()).isNotNull();
       assertThat(context.getMetric()).isSameAs(metricRepository.getByKey(NCLOC_KEY));
 
@@ -236,7 +231,6 @@ public class ViewsFormulaExecutorComponentVisitorTest {
     @Override
     public Optional<Measure> createMeasure(FakeCounter counter, CreateMeasureContext context) {
       // verify the context which is passed to the method
-      assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod());
       assertThat(context.getComponent()).isNotNull();
       assertThat(context.getMetric())
         .isIn(metricRepository.getByKey(NEW_LINES_TO_COVER_KEY), metricRepository.getByKey(NEW_COVERAGE_KEY));
@@ -289,7 +283,6 @@ public class ViewsFormulaExecutorComponentVisitorTest {
     @Override
     public Optional<Measure> createMeasure(FakeVariationCounter counter, CreateMeasureContext context) {
       // verify the context which is passed to the method
-      assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod());
       assertThat(context.getComponent()).isNotNull();
       assertThat(context.getMetric()).isSameAs(metricRepository.getByKey(NEW_COVERAGE_KEY));
 
@@ -322,7 +315,7 @@ public class ViewsFormulaExecutorComponentVisitorTest {
       verifyLeafContext(context);
 
       Optional<Measure> measureOptional = context.getMeasure(NEW_LINES_TO_COVER_KEY);
-      if (!measureOptional.isPresent() || !context.hasPeriod()) {
+      if (!measureOptional.isPresent()) {
         return;
       }
       this.values.increment((int) measureOptional.get().getVariation());
@@ -332,7 +325,6 @@ public class ViewsFormulaExecutorComponentVisitorTest {
 
   private FormulaExecutorComponentVisitor formulaExecutorComponentVisitor(Formula formula) {
     return FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository)
-      .withVariationSupport(periodsHolder)
       .buildFor(ImmutableList.of(formula));
   }
 
@@ -361,7 +353,6 @@ public class ViewsFormulaExecutorComponentVisitorTest {
 
   private void verifyLeafContext(CounterInitializationContext context) {
     assertThat(context.getLeaf().getChildren()).isEmpty();
-    assertThat(context.getPeriod()).isEqualTo(periodsHolder.getPeriod());
   }
 
 }
index 10e22c55cdde010a420983869b01423a9ae72d19..b0933675b2f4cebb5bb0fd42f14b0af128923be4 100644 (file)
@@ -29,7 +29,6 @@ import org.junit.rules.ExternalResource;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.formula.CounterInitializationContext;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
-import org.sonar.ce.task.projectanalysis.period.Period;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
@@ -134,14 +133,5 @@ public class CoverageUtilsTest {
       return Optional.fromNullable(measures.get(metricKey));
     }
 
-    @Override
-    public Period getPeriod() {
-      throw new UnsupportedOperationException("getPeriod is not supported");
-    }
-
-    @Override
-    public boolean hasPeriod() {
-      throw new UnsupportedOperationException("hasPeriod is not supported");
-    }
   }
 }
index 2d126d090cd9c7ae69426e7ce34cdce2e4147ce6..4acca918552466e848a5508a50d6a5b4f560e849 100644 (file)
@@ -23,9 +23,9 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Ordering;
 import java.util.Arrays;
-import java.util.Map;
+import java.util.HashSet;
+import java.util.Optional;
 import java.util.Set;
-import java.util.stream.Collectors;
 import org.assertj.core.data.Offset;
 import org.junit.Before;
 import org.junit.Rule;
@@ -39,10 +39,7 @@ import org.sonar.ce.task.projectanalysis.component.VisitorsCrawler;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
 import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule;
-import org.sonar.ce.task.projectanalysis.scm.Changeset;
-import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryRule;
+import org.sonar.ce.task.projectanalysis.source.NewLinesRepository;
 import org.sonar.server.measure.DebtRatingGrid;
 import org.sonar.server.measure.Rating;
 
@@ -74,15 +71,10 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   private static final String LANGUAGE_1_KEY = "language 1 key";
   private static final long LANGUAGE_1_DEV_COST = 30l;
-  private static final long PERIOD_SNAPSHOT_DATE = 12323l;
-  private static final String SOME_ANALYSIS_UUID = "9993l";
-  private static final String SOME_PERIOD_MODE = "some mode";
   private static final int ROOT_REF = 1;
   private static final int LANGUAGE_1_FILE_REF = 11111;
   private static final Offset<Double> VARIATION_COMPARISON_OFFSET = Offset.offset(0.01);
 
-  @Rule
-  public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule();
   @Rule
   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
   @Rule
@@ -94,9 +86,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
     .add(NEW_DEVELOPMENT_COST);
   @Rule
   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
-  @Rule
-  public PeriodHolderRule periodsHolder = new PeriodHolderRule();
 
+  private NewLinesRepository newLinesRepository = mock(NewLinesRepository.class);
   private RatingSettings ratingSettings = mock(RatingSettings.class);
 
   private VisitorsCrawler underTest;
@@ -104,13 +95,12 @@ public class NewMaintainabilityMeasuresVisitorTest {
   @Before
   public void setUp() throws Exception {
     when(ratingSettings.getDebtRatingGrid()).thenReturn(new DebtRatingGrid(RATING_GRID));
-    underTest = new VisitorsCrawler(Arrays.asList(new NewMaintainabilityMeasuresVisitor(metricRepository, measureRepository, scmInfoRepository,
-      periodsHolder, ratingSettings)));
+    underTest = new VisitorsCrawler(Arrays.asList(new NewMaintainabilityMeasuresVisitor(metricRepository, measureRepository, newLinesRepository, ratingSettings)));
   }
 
   @Test
-  public void project_has_new_measures_for_each_defined_period() {
-    setPeriod();
+  public void project_has_new_measures() {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
     treeRootHolder.setRoot(builder(PROJECT, ROOT_REF).build());
 
     underTest.visit(treeRootHolder.getRoot());
@@ -120,8 +110,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
   }
 
   @Test
-  public void project_has_no_measure_if_there_is_no_period() {
-    periodsHolder.setPeriod(null);
+  public void project_has_no_measure_if_new_lines_not_available() {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(false);
     treeRootHolder.setRoot(builder(PROJECT, ROOT_REF).build());
 
     underTest.visit(treeRootHolder.getRoot());
@@ -131,10 +121,10 @@ public class NewMaintainabilityMeasuresVisitorTest {
   }
 
   @Test
-  public void file_has_no_new_debt_ratio_variation_if_there_is_no_period() {
-    periodsHolder.setPeriod(null);
+  public void file_has_no_new_debt_ratio_variation_if_new_lines_not_available() {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(false);
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
+    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -144,16 +134,15 @@ public class NewMaintainabilityMeasuresVisitorTest {
   }
 
   @Test
-  public void file_has_0_new_debt_ratio_if_all_scm_dates_are_before_snapshot_dates() {
-    setPeriod();
+  public void file_has_0_new_debt_ratio_if_no_line_is_new() {
+    ReportComponent file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build();
     treeRootHolder.setRoot(
       builder(PROJECT, ROOT_REF)
-        .addChildren(
-          builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build())
+        .addChildren(file)
         .build());
     measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));
     measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4));
-    scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 4));
+    setNewLines(file);
 
     underTest.visit(treeRootHolder.getRoot());
 
@@ -162,23 +151,10 @@ public class NewMaintainabilityMeasuresVisitorTest {
   }
 
   @Test
-  public void file_has_new_debt_ratio_if_some_scm_dates_are_after_snapshot_dates() {
-    setPeriod();
-    when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
-    measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));
-
-    underTest.visit(treeRootHolder.getRoot());
-
-    assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 83.33);
-    assertNewDebtRatioValues(ROOT_REF, 83.33);
-  }
-
-  @Test
-  public void file_has_new_debt_ratio_if_only_has_some_scm_dates_which_are_after_snapshot_dates() {
-    setPeriod();
+  public void file_has_new_debt_ratio_if_some_lines_are_new() {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProjectWithPartialChangesets(50, Flag.SRC_FILE, Flag.WITH_NCLOC);
+    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -189,9 +165,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void new_debt_ratio_changes_with_language_cost() {
-    setPeriod();
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST * 10);
-    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
+    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -202,9 +177,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void new_debt_ratio_changes_with_new_technical_debt() {
-    setPeriod();
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProject(500, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
+    setupOneFileAloneInAProject(500, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(500));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -215,9 +189,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void new_debt_ratio_on_non_file_level_is_based_on_new_technical_debt_of_that_level() {
-    setPeriod();
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProject(500, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
+    setupOneFileAloneInAProject(500, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(1200));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -228,9 +201,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void new_debt_ratio_when_file_is_unit_test() {
-    setPeriod();
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProject(500, Flag.UT_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
+    setupOneFileAloneInAProject(500, Flag.UT_FILE, Flag.WITH_NCLOC, Flag.WITH_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(1200));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -240,10 +212,10 @@ public class NewMaintainabilityMeasuresVisitorTest {
   }
 
   @Test
-  public void new_debt_ratio_is_0_when_file_has_no_changesets() {
-    setPeriod();
+  public void new_debt_ratio_is_0_when_file_has_no_new_lines() {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_CHANGESET);
+    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -253,10 +225,10 @@ public class NewMaintainabilityMeasuresVisitorTest {
   }
 
   @Test
-  public void new_debt_ratio_is_0_on_non_file_level_when_no_file_has_changesets() {
-    setPeriod();
+  public void new_debt_ratio_is_0_on_non_file_level_when_no_file_has_new_lines() {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_CHANGESET);
+    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(200));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -267,9 +239,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void new_debt_ratio_is_0_when_there_is_no_ncloc_in_file() {
-    setPeriod();
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_CHANGESET);
+    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -280,9 +251,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void new_debt_ratio_is_0_on_non_file_level_when_one_file_has_zero_new_debt_because_of_no_changeset() {
-    setPeriod();
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_CHANGESET);
+    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(200));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -293,9 +263,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void new_debt_ratio_is_0_when_ncloc_measure_is_missing() {
-    setPeriod();
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
-    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.MISSING_MEASURE_NCLOC, Flag.WITH_CHANGESET);
+    setupOneFileAloneInAProject(50, Flag.SRC_FILE, Flag.MISSING_MEASURE_NCLOC, Flag.WITH_NEW_LINES);
     measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50));
 
     underTest.visit(treeRootHolder.getRoot());
@@ -306,16 +275,15 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void leaf_components_always_have_a_measure_when_at_least_one_period_exist_and_ratio_is_computed_from_current_level_new_debt() {
-    setPeriod();
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
+    Component file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build();
     treeRootHolder.setRoot(
       builder(PROJECT, ROOT_REF)
         .addChildren(
           builder(MODULE, 11)
             .addChildren(
               builder(DIRECTORY, 111)
-                .addChildren(
-                  builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build())
+                .addChildren(file)
                 .build())
             .build())
         .build());
@@ -328,8 +296,7 @@ public class NewMaintainabilityMeasuresVisitorTest {
     // 4 lines file, only first one is not ncloc
     measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4));
     // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date
-    scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 2, PERIOD_SNAPSHOT_DATE + 100, 2));
-
+    setNewLines(file, 3, 4);
     underTest.visit(treeRootHolder.getRoot());
 
     assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 83.33);
@@ -340,16 +307,15 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void compute_new_maintainability_rating() {
-    setPeriod();
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
+    ReportComponent file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build();
     treeRootHolder.setRoot(
       builder(PROJECT, ROOT_REF)
         .addChildren(
           builder(MODULE, 11)
             .addChildren(
               builder(DIRECTORY, 111)
-                .addChildren(
-                  builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build())
+                .addChildren(file)
                 .build())
             .build())
         .build());
@@ -362,7 +328,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
     // 4 lines file, only first one is not ncloc
     measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4));
     // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date
-    scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 2, PERIOD_SNAPSHOT_DATE + 100, 2));
+
+    setNewLines(file, 3, 4);
 
     underTest.visit(treeRootHolder.getRoot());
 
@@ -374,7 +341,8 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void compute_new_development_cost() {
-    setPeriod();
+    ReportComponent file1 = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 4)).build();
+    ReportComponent file2 = builder(FILE, 22_222).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 6)).build();
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
     treeRootHolder.setRoot(
       builder(PROJECT, ROOT_REF)
@@ -382,9 +350,7 @@ public class NewMaintainabilityMeasuresVisitorTest {
           builder(MODULE, 11)
             .addChildren(
               builder(DIRECTORY, 111)
-                .addChildren(
-                  builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 4)).build(),
-                  builder(FILE, 22_222).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 6)).build())
+                .addChildren(file1, file2)
                 .build())
             .build())
         .build());
@@ -392,11 +358,12 @@ public class NewMaintainabilityMeasuresVisitorTest {
     // 4 lines file, only first one is not ncloc
     measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4));
     // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date
-    scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 2, PERIOD_SNAPSHOT_DATE + 100, 2));
+    setNewLines(file1, 3, 4);
+
     // 6 lines file, only last one is not ncloc
     measureRepository.addRawMeasure(22_222, NCLOC_DATA_KEY, createNclocDataMeasure(1, 2, 3, 4, 5));
     // first 2 lines are before all snapshots, 4 last lines are after PERIOD 2's snapshot date
-    scmInfoRepository.setScmInfo(22_222, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 2, PERIOD_SNAPSHOT_DATE + 100, 4));
+    setNewLines(file2, 3, 4, 5, 6);
 
     underTest.visit(treeRootHolder.getRoot());
 
@@ -407,7 +374,7 @@ public class NewMaintainabilityMeasuresVisitorTest {
 
   @Test
   public void compute_new_maintainability_rating_to_A_when_no_debt() {
-    setPeriod();
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
     when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
     treeRootHolder.setRoot(
       builder(PROJECT, ROOT_REF)
@@ -429,15 +396,15 @@ public class NewMaintainabilityMeasuresVisitorTest {
     assertNewMaintainability(ROOT_REF, A);
   }
 
-  private void setupOneFileAloneInAProject(int newDebt, Flag isUnitTest, Flag withNclocLines, Flag withChangeSets) {
+  private void setupOneFileAloneInAProject(int newDebt, Flag isUnitTest, Flag withNclocLines, Flag withNewLines) {
     checkArgument(isUnitTest == Flag.UT_FILE || isUnitTest == Flag.SRC_FILE);
     checkArgument(withNclocLines == Flag.WITH_NCLOC || withNclocLines == Flag.NO_NCLOC || withNclocLines == Flag.MISSING_MEASURE_NCLOC);
-    checkArgument(withChangeSets == Flag.WITH_CHANGESET || withChangeSets == Flag.NO_CHANGESET);
+    checkArgument(withNewLines == Flag.WITH_NEW_LINES || withNewLines == Flag.NO_NEW_LINES);
 
+    Component file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(isUnitTest == Flag.UT_FILE, LANGUAGE_1_KEY, 1)).build();
     treeRootHolder.setRoot(
       builder(PROJECT, ROOT_REF)
-        .addChildren(
-          builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(isUnitTest == Flag.UT_FILE, LANGUAGE_1_KEY, 1)).build())
+        .addChildren(file)
         .build());
 
     Measure newDebtMeasure = createNewDebtMeasure(newDebt);
@@ -449,37 +416,24 @@ public class NewMaintainabilityMeasuresVisitorTest {
       // 4 lines file, none of which is ncloc
       measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNoNclocDataMeasure(4));
     }
-    if (withChangeSets == Flag.WITH_CHANGESET) {
-      // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date
-      scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_SNAPSHOT_DATE - 100, 2, PERIOD_SNAPSHOT_DATE + 100, 2));
+    if (withNewLines == Flag.WITH_NEW_LINES) {
+      // 2 last lines are new
+      setNewLines(file, 3, 4);
     }
   }
 
-  private void setupOneFileAloneInAProjectWithPartialChangesets(int newDebt, Flag isUnitTest, Flag withNclocLines) {
-    checkArgument(isUnitTest == Flag.UT_FILE || isUnitTest == Flag.SRC_FILE);
-    checkArgument(withNclocLines == Flag.WITH_NCLOC || withNclocLines == Flag.NO_NCLOC || withNclocLines == Flag.MISSING_MEASURE_NCLOC);
-
-    treeRootHolder.setRoot(
-      builder(PROJECT, ROOT_REF)
-        .addChildren(
-          builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(isUnitTest == Flag.UT_FILE, LANGUAGE_1_KEY, 1)).build())
-        .build());
-
-    Measure newDebtMeasure = createNewDebtMeasure(newDebt);
-    measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NEW_TECHNICAL_DEBT_KEY, newDebtMeasure);
-    if (withNclocLines == Flag.WITH_NCLOC) {
-      // 4 lines file, only first one is not ncloc
-      measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4));
-    } else if (withNclocLines == Flag.NO_NCLOC) {
-      // 4 lines file, none of which is ncloc
-      measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNoNclocDataMeasure(4));
+  private void setNewLines(Component component, int... lineNumbers) {
+    HashSet<Integer> newLines = new HashSet<>();
+    for (int i : lineNumbers) {
+      newLines.add(i);
     }
-    // 2 last lines are after PERIOD 2's snapshot date
-    scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesetsForLines(PERIOD_SNAPSHOT_DATE + 100, 3, 4));
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
+    when(newLinesRepository.getNewLines(component)).thenReturn(Optional.of(newLines));
+
   }
 
   private enum Flag {
-    UT_FILE, SRC_FILE, NO_CHANGESET, WITH_CHANGESET, WITH_NCLOC, NO_NCLOC, MISSING_MEASURE_NCLOC
+    UT_FILE, SRC_FILE, NO_NEW_LINES, WITH_NEW_LINES, WITH_NCLOC, NO_NCLOC, MISSING_MEASURE_NCLOC
   }
 
   public static ReportComponent.Builder builder(Component.Type type, int ref) {
@@ -508,43 +462,6 @@ public class NewMaintainabilityMeasuresVisitorTest {
     return newMeasureBuilder().create(KeyValueFormat.format(builder.build(), KeyValueFormat.newIntegerConverter(), KeyValueFormat.newIntegerConverter()));
   }
 
-  /**
-   * Creates changesets of {@code lines} lines which all have the same date {@code scmDate}.
-   */
-  private static Changeset[] createChangesets(long scmDate, int lines) {
-    Changeset changetset = Changeset.newChangesetBuilder().setDate(scmDate).setRevision("rev-1").build();
-    Changeset[] changesets = new Changeset[lines];
-    for (int i = 0; i < lines; i++) {
-      changesets[i] = changetset;
-    }
-    return changesets;
-  }
-
-  /**
-   * Creates changesets for specific lines, which all have the same date {@code scmDate}.
-   */
-  private static Map<Integer, Changeset> createChangesetsForLines(long scmDate, int... lines) {
-    Changeset changetset = Changeset.newChangesetBuilder().setDate(scmDate).setRevision("rev-1").build();
-    return Arrays.stream(lines).boxed().collect(Collectors.toMap(l -> l, l -> changetset));
-  }
-
-  /**
-   * Creates a changeset of {@code lineCount} lines which have the date {@code scmDate} and {@code otherLineCount} lines which
-   * have the date {@code otherScmDate}.
-   */
-  private static Changeset[] createChangesets(long scmDate, int lineCount, long otherScmDate, int otherLineCount) {
-    Changeset[] changesets = new Changeset[lineCount + otherLineCount];
-    Changeset changetset1 = Changeset.newChangesetBuilder().setDate(scmDate).setRevision("rev-1").build();
-    for (int i = 0; i < lineCount; i++) {
-      changesets[i] = changetset1;
-    }
-    Changeset changetset2 = Changeset.newChangesetBuilder().setDate(otherScmDate).setRevision("rev-2").build();
-    for (int i = lineCount; i < lineCount + otherLineCount; i++) {
-      changesets[i] = changetset2;
-    }
-    return changesets;
-  }
-
   private void assertNoNewDebtRatioMeasure(int componentRef) {
     assertThat(measureRepository.getAddedRawMeasure(componentRef, NEW_SQALE_DEBT_RATIO_KEY))
       .isAbsent();
@@ -566,8 +483,4 @@ public class NewMaintainabilityMeasuresVisitorTest {
     assertThat(measureRepository.getAddedRawMeasure(componentRef, NEW_MAINTAINABILITY_RATING_KEY))
       .isAbsent();
   }
-
-  private void setPeriod() {
-    periodsHolder.setPeriod(new Period(SOME_PERIOD_MODE, null, PERIOD_SNAPSHOT_DATE, SOME_ANALYSIS_UUID));
-  }
 }
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepositoryTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepositoryTest.java
new file mode 100644 (file)
index 0000000..2a02b34
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.ce.task.projectanalysis.source;
+
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.Set;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
+import org.sonar.ce.task.projectanalysis.analysis.Branch;
+import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
+import org.sonar.ce.task.projectanalysis.component.Component;
+import org.sonar.ce.task.projectanalysis.component.ReportComponent;
+import org.sonar.ce.task.projectanalysis.period.Period;
+import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule;
+import org.sonar.ce.task.projectanalysis.scm.Changeset;
+import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryRule;
+import org.sonar.db.component.BranchType;
+import org.sonar.scanner.protocol.output.ScannerReport;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class NewLinesRepositoryTest {
+  private final static ReportComponent FILE = ReportComponent.builder(Component.Type.FILE, 1).build();
+
+  @Rule
+  public BatchReportReaderRule reader = new BatchReportReaderRule();
+  @Rule
+  public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
+  @Rule
+  public PeriodHolderRule periodHolder = new PeriodHolderRule();
+  @Rule
+  public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule();
+
+  private NewLinesRepository repository = new NewLinesRepository(reader, analysisMetadataHolder, periodHolder, scmInfoRepository);
+
+  @Test
+  public void load_new_lines_from_report_if_available_and_pullrequest() {
+    periodHolder.setPeriod(new Period("", null, Long.MAX_VALUE, ""));
+    setPullRequest();
+    createChangedLinesInReport(1, 2, 5);
+
+    Optional<Set<Integer>> newLines = repository.getNewLines(FILE);
+
+    assertThat(newLines).isPresent();
+    assertThat(newLines.get()).containsOnly(1, 2, 5);
+    assertThat(repository.newLinesAvailable()).isTrue();
+  }
+
+  @Test
+  public void calculate_new_lines_from_period() {
+    periodHolder.setPeriod(new Period("", null, 1000L, ""));
+    scmInfoRepository.setScmInfo(FILE.getReportAttributes().getRef(), createChangesets(1100L, 900L, 1000L, 800L));
+
+    Optional<Set<Integer>> newLines = repository.getNewLines(FILE);
+
+    assertThat(newLines).isPresent();
+    assertThat(newLines.get()).containsOnly(1);
+    assertThat(repository.newLinesAvailable()).isTrue();
+  }
+
+  @Test
+  public void return_empty_if_no_period() {
+    periodHolder.setPeriod(null);
+
+    // even though we have lines in the report and scm data, nothing should be returned since we have no period
+    createChangedLinesInReport(1, 2, 5);
+    scmInfoRepository.setScmInfo(FILE.getReportAttributes().getRef(), createChangesets(1100L, 900L, 1000L, 800L));
+
+    Optional<Set<Integer>> newLines = repository.getNewLines(FILE);
+
+    assertThat(newLines).isNotPresent();
+    assertThat(repository.newLinesAvailable()).isFalse();
+  }
+
+  @Test
+  public void return_empty_if_no_report_and_no_scm_info() {
+    periodHolder.setPeriod(new Period("", null, 1000L, ""));
+
+    Optional<Set<Integer>> newLines = repository.getNewLines(FILE);
+
+    assertThat(newLines).isNotPresent();
+    assertThat(repository.newLinesAvailable()).isTrue();
+  }
+
+  private void setPullRequest() {
+    Branch branch = mock(Branch.class);
+    when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
+    analysisMetadataHolder.setBranch(branch);
+  }
+
+  private Changeset[] createChangesets(Long... dates) {
+    return Arrays.stream(dates)
+      .map(l -> Changeset.newChangesetBuilder().setDate(l).build())
+      .toArray(Changeset[]::new);
+  }
+
+  private void createChangedLinesInReport(Integer... lines) {
+    ScannerReport.ChangedLines changedLines = ScannerReport.ChangedLines.newBuilder()
+      .addAllLine(Arrays.asList(lines))
+      .build();
+    reader.putChangedLines(FILE.getReportAttributes().getRef(), changedLines);
+  }
+}
index 2b983b6c1a4fe01b99e297a63726e93ed60add64..2bbd57d3c8fca2b20858b94f2dbd2bdf9ed526b6 100644 (file)
 package org.sonar.ce.task.projectanalysis.step;
 
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
 import org.assertj.core.data.Offset;
 import org.junit.Rule;
 import org.junit.Test;
+import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.ce.task.projectanalysis.duplication.DuplicationRepositoryRule;
 import org.sonar.ce.task.projectanalysis.duplication.TextBlock;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
 import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule;
-import org.sonar.ce.task.projectanalysis.scm.Changeset;
-import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryRule;
+import org.sonar.ce.task.projectanalysis.source.NewLinesRepository;
 import org.sonar.ce.task.step.TestComputationStepContext;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.guava.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 import static org.sonar.api.measures.CoreMetrics.NEW_BLOCKS_DUPLICATED;
 import static org.sonar.api.measures.CoreMetrics.NEW_BLOCKS_DUPLICATED_KEY;
 import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES;
@@ -45,7 +48,6 @@ import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_KE
 import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_KEY;
 import static org.sonar.api.measures.CoreMetrics.NEW_LINES;
 import static org.sonar.api.measures.CoreMetrics.NEW_LINES_KEY;
-import static org.sonar.api.utils.DateUtils.parseDate;
 import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY;
 import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
 import static org.sonar.ce.task.projectanalysis.component.Component.Type.MODULE;
@@ -66,6 +68,11 @@ public class NewSizeMeasuresStepTest {
   private static final int FILE_2_REF = 12342;
   private static final int FILE_3_REF = 1261;
   private static final int FILE_4_REF = 1262;
+  private static final Component FILE_1 = builder(FILE, FILE_1_REF).build();
+  private static final Component FILE_2 = builder(FILE, FILE_2_REF).build();
+  private static final Component FILE_3 = builder(FILE, FILE_3_REF).build();
+  private static final Component FILE_4 = builder(FILE, FILE_4_REF).build();
+
   private static final String SOME_FILE_KEY = "some file key";
 
   @Rule
@@ -78,27 +85,16 @@ public class NewSizeMeasuresStepTest {
               builder(MODULE, SUB_MODULE_1_REF)
                 .addChildren(
                   builder(DIRECTORY, DIRECTORY_REF)
-                    .addChildren(
-                      builder(FILE, FILE_1_REF).build(),
-                      builder(FILE, FILE_2_REF).build())
+                    .addChildren(FILE_1, FILE_2)
                     .build(),
                   builder(DIRECTORY, DIRECTORY_2_REF).build())
                 .build(),
               builder(MODULE, SUB_MODULE_2_REF)
-                .addChildren(
-                  builder(FILE, FILE_3_REF).build(),
-                  builder(FILE, FILE_4_REF).build())
+                .addChildren(FILE_3, FILE_4)
                 .build())
             .build())
         .build());
 
-  @Rule
-  public PeriodHolderRule periodsHolder = new PeriodHolderRule().setPeriod(
-    new Period("mode_p_1", null, parseDate("2009-12-25").getTime(), "u1"));
-
-  @Rule
-  public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule();
-
   @Rule
   public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
     .add(NEW_LINES)
@@ -111,14 +107,13 @@ public class NewSizeMeasuresStepTest {
 
   @Rule
   public DuplicationRepositoryRule duplicationRepository = DuplicationRepositoryRule.create(treeRootHolder);
+  private NewLinesRepository newLinesRepository = mock(NewLinesRepository.class);
 
-  private NewSizeMeasuresStep underTest = new NewSizeMeasuresStep(treeRootHolder, periodsHolder, metricRepository, measureRepository, scmInfoRepository,
-    duplicationRepository);
+  private NewSizeMeasuresStep underTest = new NewSizeMeasuresStep(treeRootHolder, metricRepository, measureRepository, newLinesRepository, duplicationRepository);
 
   @Test
   public void compute_new_lines() {
-    setChangesets(FILE_1_REF, FILE_2_REF, FILE_4_REF);
-
+    setNewLines(FILE_1, FILE_2, FILE_4);
     underTest.execute(new TestComputationStepContext());
 
     assertRawMeasureValueOnPeriod(FILE_1_REF, NEW_LINES_KEY, 11);
@@ -135,7 +130,7 @@ public class NewSizeMeasuresStepTest {
 
   @Test
   public void compute_new_lines_with_only_some_lines_having_changesets() {
-    setChangesetsForFirstThreeLines(FILE_1_REF, FILE_2_REF, FILE_4_REF);
+    setFirstTwoLinesAsNew(FILE_1, FILE_2, FILE_4);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -161,7 +156,7 @@ public class NewSizeMeasuresStepTest {
   @Test
   public void compute_duplicated_lines_counts_lines_from_original_and_InnerDuplicate_of_a_single_line() {
     duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), new TextBlock(2, 2));
-    setChangesets(FILE_1_REF);
+    setNewLines(FILE_1);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -172,7 +167,7 @@ public class NewSizeMeasuresStepTest {
   public void compute_duplicated_lines_counts_lines_from_original_and_ignores_InProjectDuplicate() {
     TextBlock original = new TextBlock(1, 1);
     duplicationRepository.addDuplication(FILE_1_REF, original, FILE_2_REF, new TextBlock(2, 2));
-    setChangesets(FILE_1_REF);
+    setNewLines(FILE_1);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -183,7 +178,7 @@ public class NewSizeMeasuresStepTest {
   public void compute_duplicated_lines_counts_lines_from_original_and_ignores_CrossProjectDuplicate() {
     TextBlock original = new TextBlock(1, 1);
     duplicationRepository.addDuplication(FILE_1_REF, original, SOME_FILE_KEY, new TextBlock(2, 2));
-    setChangesets(FILE_1_REF);
+    setNewLines(FILE_1);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -194,7 +189,7 @@ public class NewSizeMeasuresStepTest {
   public void compute_duplicated_lines_counts_lines_from_original_and_InnerDuplicate() {
     TextBlock original = new TextBlock(1, 5);
     duplicationRepository.addDuplication(FILE_1_REF, original, new TextBlock(10, 11));
-    setChangesets(FILE_1_REF);
+    setNewLines(FILE_1);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -206,7 +201,7 @@ public class NewSizeMeasuresStepTest {
     TextBlock original = new TextBlock(1, 10);
     duplicationRepository.addDuplication(FILE_1_REF, original, new TextBlock(10, 11), new TextBlock(11, 12));
     duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(2, 2), new TextBlock(4, 4));
-    setChangesets(FILE_1_REF);
+    setNewLines(FILE_1);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -218,10 +213,7 @@ public class NewSizeMeasuresStepTest {
     addDuplicatedBlock(FILE_1_REF, 2);
     addDuplicatedBlock(FILE_3_REF, 10);
     addDuplicatedBlock(FILE_4_REF, 12);
-    setChangesets(FILE_1_REF);
-    setChangesets(FILE_2_REF);
-    setChangesets(FILE_3_REF);
-    setChangesets(FILE_4_REF);
+    setNewLines(FILE_1, FILE_2, FILE_3, FILE_4);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -243,10 +235,7 @@ public class NewSizeMeasuresStepTest {
     addDuplicatedBlock(FILE_1_REF, 2);
     addDuplicatedBlock(FILE_3_REF, 10);
     addDuplicatedBlock(FILE_4_REF, 12);
-    setChangesetsForFirstThreeLines(FILE_1_REF);
-    setChangesetsForFirstThreeLines(FILE_2_REF);
-    setChangesetsForFirstThreeLines(FILE_3_REF);
-    setChangesetsForFirstThreeLines(FILE_4_REF);
+    setFirstTwoLinesAsNew(FILE_1, FILE_2, FILE_3, FILE_4);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -264,10 +253,7 @@ public class NewSizeMeasuresStepTest {
 
   @Test
   public void compute_and_aggregate_zero_duplicated_line_when_no_duplication() {
-    setChangesets(FILE_1_REF);
-    setChangesets(FILE_2_REF);
-    setChangesets(FILE_3_REF);
-    setChangesets(FILE_4_REF);
+    setNewLines(FILE_1, FILE_2, FILE_3, FILE_4);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -278,7 +264,7 @@ public class NewSizeMeasuresStepTest {
   public void compute_duplicated_blocks_one_for_original_one_for_each_InnerDuplicate() {
     TextBlock original = new TextBlock(1, 1);
     duplicationRepository.addDuplication(FILE_1_REF, original, new TextBlock(2, 2), new TextBlock(4, 4), new TextBlock(3, 4));
-    setChangesets(FILE_1_REF);
+    setNewLines(FILE_1);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -289,7 +275,7 @@ public class NewSizeMeasuresStepTest {
   public void compute_duplicated_blocks_does_not_count_blocks_only_once_it_assumes_consistency_from_duplication_data() {
     duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), new TextBlock(4, 4));
     duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(2, 2), new TextBlock(4, 4));
-    setChangesets(FILE_1_REF);
+    setNewLines(FILE_1);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -299,7 +285,7 @@ public class NewSizeMeasuresStepTest {
   @Test
   public void compute_duplicated_blocks_one_for_original_and_ignores_InProjectDuplicate() {
     duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), FILE_2_REF, new TextBlock(2, 2));
-    setChangesets(FILE_1_REF);
+    setNewLines(FILE_1);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -309,7 +295,7 @@ public class NewSizeMeasuresStepTest {
   @Test
   public void compute_duplicated_blocks_one_for_original_and_ignores_CrossProjectDuplicate() {
     duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), SOME_FILE_KEY, new TextBlock(2, 2));
-    setChangesets(FILE_1_REF);
+    setNewLines(FILE_1);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -321,7 +307,7 @@ public class NewSizeMeasuresStepTest {
     addDuplicatedBlock(FILE_1_REF, 11);
     addDuplicatedBlock(FILE_2_REF, 2);
     addDuplicatedBlock(FILE_4_REF, 7);
-    setChangesets(FILE_1_REF, FILE_2_REF, FILE_3_REF, FILE_4_REF);
+    setNewLines(FILE_1, FILE_2, FILE_3, FILE_4);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -338,7 +324,7 @@ public class NewSizeMeasuresStepTest {
 
   @Test
   public void compute_and_aggregate_duplicated_blocks_to_zero_when_no_duplication() {
-    setChangesets(FILE_1_REF, FILE_2_REF, FILE_3_REF, FILE_4_REF);
+    setNewLines(FILE_1, FILE_2, FILE_3, FILE_4);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -347,7 +333,7 @@ public class NewSizeMeasuresStepTest {
 
   @Test
   public void compute_new_duplicated_lines_density() {
-    setChangesets(FILE_1_REF, FILE_2_REF, FILE_4_REF);
+    setNewLines(FILE_1, FILE_2, FILE_4);
     addDuplicatedBlock(FILE_1_REF, 2);
     addDuplicatedBlock(FILE_3_REF, 10);
     addDuplicatedBlock(FILE_4_REF, 12);
@@ -375,7 +361,6 @@ public class NewSizeMeasuresStepTest {
 
   /**
    * Adds duplication blocks of a single line (each line is specific to its block).
-   *
    * This is a very simple use case, convenient for unit tests but more realistic and complex use cases must be tested separately.
    */
   private void addDuplicatedBlock(int fileRef, int blockCount) {
@@ -388,31 +373,20 @@ public class NewSizeMeasuresStepTest {
     duplicationRepository.addDuplication(fileRef, original, duplicates);
   }
 
-  private void setChangesetsForFirstThreeLines(int... componentRefs) {
-    Arrays.stream(componentRefs)
-      .forEach(componentRef -> scmInfoRepository.setScmInfo(componentRef,
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        // line 3 is older, part of no period
-        Changeset.newChangesetBuilder().setDate(parseDate("2007-01-15").getTime()).setRevision("rev-2").build()));
+  private void setFirstTwoLinesAsNew(Component... components) {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
+    Set<Integer> newLines = new HashSet<>(Arrays.asList(1, 2));
+    for (Component c : components) {
+      when(newLinesRepository.getNewLines(c)).thenReturn(Optional.of(newLines));
+    }
   }
 
-  private void setChangesets(int... componentRefs) {
-    Arrays.stream(componentRefs)
-      .forEach(componentRef -> scmInfoRepository.setScmInfo(componentRef,
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        // line 3 is older, part of no period
-        Changeset.newChangesetBuilder().setDate(parseDate("2007-01-15").getTime()).setRevision("rev-2").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-        Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build()));
+  private void setNewLines(Component... components) {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
+    Set<Integer> newLines = new HashSet<>(Arrays.asList(1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12));
+    for (Component c : components) {
+      when(newLinesRepository.getNewLines(c)).thenReturn(Optional.of(newLines));
+    }
   }
 
   private void assertRawMeasureValueOnPeriod(int componentRef, String metricKey, double expectedVariation) {
index 6fe3ec3571c97d1742cc0045b10b1014686490b0..cb4a3ce600b22320c7f8404966b37868b7d8003b 100644 (file)
  */
 package org.sonar.ce.task.projectanalysis.step;
 
-import org.junit.Before;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.measures.CoreMetrics;
@@ -32,14 +36,14 @@ import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepoEntry;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
 import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule;
 import org.sonar.ce.task.projectanalysis.scm.Changeset;
-import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryRule;
+import org.sonar.ce.task.projectanalysis.source.NewLinesRepository;
 import org.sonar.ce.task.step.TestComputationStepContext;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.guava.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 import static org.sonar.api.measures.CoreMetrics.CONDITIONS_BY_LINE_KEY;
 import static org.sonar.api.measures.CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY;
 import static org.sonar.api.measures.CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY;
@@ -67,6 +71,9 @@ public class ReportNewCoverageMeasuresStepTest {
   private static final int DIRECTORY_2_REF = 1112;
   private static final int FILE_2_REF = 11121;
   private static final int FILE_3_REF = 11122;
+  private static final Component FILE_1 = builder(FILE, FILE_1_REF).build();
+  private static final Component FILE_2 = builder(FILE, FILE_2_REF).build();
+  private static final Component FILE_3 = builder(FILE, FILE_3_REF).build();
 
   private static final ReportComponent MULTIPLE_FILES_TREE = builder(PROJECT, ROOT_REF)
     .addChildren(
@@ -75,25 +82,18 @@ public class ReportNewCoverageMeasuresStepTest {
           builder(MODULE, SUB_MODULE_REF)
             .addChildren(
               builder(DIRECTORY, DIRECTORY_1_REF)
-                .addChildren(
-                  builder(FILE, FILE_1_REF).build())
+                .addChildren(FILE_1)
                 .build(),
               builder(DIRECTORY, DIRECTORY_2_REF)
-                .addChildren(
-                  builder(FILE, FILE_2_REF).build(),
-                  builder(FILE, FILE_3_REF).build())
+                .addChildren(FILE_2, FILE_3)
                 .build())
             .build())
         .build())
     .build();
 
-  @Rule
-  public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule();
   @Rule
   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
   @Rule
-  public PeriodHolderRule periodsHolder = new PeriodHolderRule();
-  @Rule
   public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
     .add(CoreMetrics.COVERAGE_LINE_HITS_DATA)
     .add(CoreMetrics.CONDITIONS_BY_LINE)
@@ -108,16 +108,11 @@ public class ReportNewCoverageMeasuresStepTest {
 
   @Rule
   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
-
-  private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, periodsHolder, measureRepository, metricRepository, scmInfoRepository);
+  private NewLinesRepository newLinesRepository = mock(NewLinesRepository.class);
+  private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, measureRepository, metricRepository, newLinesRepository);
   public static final ReportComponent FILE_COMPONENT = ReportComponent.builder(Component.Type.FILE, FILE_1_REF)
     .setFileAttributes(new FileAttributes(false, null, 1)).build();
 
-  @Before
-  public void setUp() {
-    periodsHolder.setPeriod(new Period("mode_p_1", null, parseDate("2009-12-25").getTime(), "u1"));
-  }
-
   @Test
   public void no_measure_for_PROJECT_component() {
     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, ROOT_REF).build());
@@ -166,13 +161,8 @@ public class ReportNewCoverageMeasuresStepTest {
   @Test
   public void zero_measures_when_nothing_has_changed() {
     treeRootHolder.setRoot(FILE_COMPONENT);
-    scmInfoRepository.setScmInfo(FILE_1_REF,
-      Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build());
-
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
+    when(newLinesRepository.getNewLines(FILE_COMPONENT)).thenReturn(Optional.of(Collections.emptySet()));
     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERAGE_LINE_HITS_DATA_KEY, newMeasureBuilder().create("2=1;3=1"));
     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1"));
     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERED_CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1"));
@@ -185,9 +175,7 @@ public class ReportNewCoverageMeasuresStepTest {
   @Test
   public void zero_measures_for_FILE_component_without_CoverageData() {
     treeRootHolder.setRoot(FILE_COMPONENT);
-    scmInfoRepository.setScmInfo(FILE_1_REF,
-      Changeset.newChangesetBuilder().setDate(parseDate("2008-05-18").getTime()).setRevision("rev-1").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2008-05-18").getTime()).setRevision("rev-1").build());
+    setNewLines(FILE_1);
 
     underTest.execute(new TestComputationStepContext());
 
@@ -196,6 +184,8 @@ public class ReportNewCoverageMeasuresStepTest {
 
   @Test
   public void verify_computation_of_measures_for_new_lines_for_FILE() {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
+
     String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY;
     String newLinesToCover = NEW_LINES_TO_COVER_KEY;
     String newUncoveredLines = NEW_UNCOVERED_LINES_KEY;
@@ -209,11 +199,7 @@ public class ReportNewCoverageMeasuresStepTest {
   private void verify_computation_of_measures_for_new_lines(String coverageLineHitsData,
     String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) {
     treeRootHolder.setRoot(FILE_COMPONENT);
-    scmInfoRepository.setScmInfo(FILE_1_REF,
-      Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2007-01-15").getTime()).setRevision("rev-2").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build());
+    setNewLines(FILE_1, 1, 2, 4);
 
     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=3"));
 
@@ -228,6 +214,8 @@ public class ReportNewCoverageMeasuresStepTest {
 
   @Test
   public void verify_computation_of_measures_for_new_conditions_for_FILE() {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
+
     String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY;
     String conditionsByLine = CONDITIONS_BY_LINE_KEY;
     String coveredConditionsByLine = COVERED_CONDITIONS_BY_LINE_KEY;
@@ -242,6 +230,8 @@ public class ReportNewCoverageMeasuresStepTest {
 
   @Test
   public void verify_aggregation_of_measures_for_new_conditions() {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
+
     String coverageLineHitsData = CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY;
     String conditionsByLine = CoreMetrics.CONDITIONS_BY_LINE_KEY;
     String coveredConditionsByLine = CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY;
@@ -254,9 +244,9 @@ public class ReportNewCoverageMeasuresStepTest {
       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
 
     treeRootHolder.setRoot(MULTIPLE_FILES_TREE);
-    defineChangeSetsAndMeasures(FILE_1_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
-    defineChangeSetsAndMeasures(FILE_2_REF, metricKeys, new MeasureValues(0, 14, 6), new MeasureValues(0, 13, 7));
-    defineChangeSetsAndMeasures(FILE_3_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(1, 13, 7));
+    defineNewLinesAndMeasures(FILE_1, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
+    defineNewLinesAndMeasures(FILE_2, metricKeys, new MeasureValues(0, 14, 6), new MeasureValues(0, 13, 7));
+    defineNewLinesAndMeasures(FILE_3, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(1, 13, 7));
 
     underTest.execute(new TestComputationStepContext());
 
@@ -365,19 +355,11 @@ public class ReportNewCoverageMeasuresStepTest {
       entryOf(NEW_UNCOVERED_CONDITIONS_KEY, createMeasure(0d)));
   }
 
-  private void defineChangeSetsAndMeasures(int componentRef, MetricKeys metricKeys, MeasureValues line4, MeasureValues line6) {
-    scmInfoRepository.setScmInfo(componentRef,
-      Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2007-01-15").getTime()).setRevision("rev-2").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2012-02-23").getTime()).setRevision("rev-3").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2012-02-23").getTime()).setRevision("rev-3").build(),
-      Changeset.newChangesetBuilder().setDate(parseDate("2012-02-23").getTime()).setRevision("rev-3").build());
-
-    measureRepository.addRawMeasure(componentRef, metricKeys.coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=" + line4.lineHits + ";5=1;6=" + line6.lineHits + ";7=0"));
-    measureRepository.addRawMeasure(componentRef, metricKeys.conditionsByLine, newMeasureBuilder().create("4=" + line4.coveredConditions + ";6=" + line6.coveredConditions));
-    measureRepository.addRawMeasure(componentRef, metricKeys.coveredConditionsByLine,
+  private void defineNewLinesAndMeasures(Component c, MetricKeys metricKeys, MeasureValues line4, MeasureValues line6) {
+    setNewLines(c, 1, 2, 4,5,6,7);
+    measureRepository.addRawMeasure(c.getReportAttributes().getRef(), metricKeys.coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=" + line4.lineHits + ";5=1;6=" + line6.lineHits + ";7=0"));
+    measureRepository.addRawMeasure(c.getReportAttributes().getRef(), metricKeys.conditionsByLine, newMeasureBuilder().create("4=" + line4.coveredConditions + ";6=" + line6.coveredConditions));
+    measureRepository.addRawMeasure(c.getReportAttributes().getRef(), metricKeys.coveredConditionsByLine,
       newMeasureBuilder().create("4=" + line4.uncoveredConditions + ";6=" + line6.uncoveredConditions));
   }
 
@@ -416,7 +398,7 @@ public class ReportNewCoverageMeasuresStepTest {
 
   private void verify_computation_of_measures_for_new_conditions(MetricKeys metricKeys) {
     treeRootHolder.setRoot(FILE_COMPONENT);
-    defineChangeSetsAndMeasures(FILE_COMPONENT.getReportAttributes().getRef(), metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
+    defineNewLinesAndMeasures(FILE_COMPONENT, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
 
     underTest.execute(new TestComputationStepContext());
 
@@ -433,4 +415,9 @@ public class ReportNewCoverageMeasuresStepTest {
       .createNoValue();
   }
 
+  private void setNewLines(Component c, Integer... lines) {
+    when(newLinesRepository.newLinesAvailable()).thenReturn(true);
+    Set<Integer> newLines = new HashSet<>(Arrays.asList(lines));
+    when(newLinesRepository.getNewLines(c)).thenReturn(Optional.of(newLines));
+  }
 }
index 0e93781e7c72df81a12d6166868a62bf25bdfca3..f655c5f8f97a54f9eeb0ad1dcb6b41aba8152f13 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.ce.task.projectanalysis.step;
 
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.measures.CoreMetrics;
@@ -29,13 +28,12 @@ import org.sonar.ce.task.projectanalysis.formula.coverage.LinesAndConditionsWith
 import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
 import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
-import org.sonar.ce.task.projectanalysis.period.Period;
-import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule;
+import org.sonar.ce.task.projectanalysis.source.NewLinesRepository;
 import org.sonar.ce.task.step.TestComputationStepContext;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.guava.api.Assertions.assertThat;
-import static org.sonar.api.utils.DateUtils.parseDate;
+import static org.mockito.Mockito.mock;
 import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT_VIEW;
 import static org.sonar.ce.task.projectanalysis.component.Component.Type.SUBVIEW;
 import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW;
@@ -74,8 +72,7 @@ public class ViewsNewCoverageMeasuresStepTest {
 
   @Rule
   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
-  @Rule
-  public PeriodHolderRule periodsHolder = new PeriodHolderRule();
+
   @Rule
   public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
     .add(CoreMetrics.COVERAGE_LINE_HITS_DATA)
@@ -91,13 +88,7 @@ public class ViewsNewCoverageMeasuresStepTest {
   @Rule
   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
 
-  private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, periodsHolder,
-    measureRepository, metricRepository);
-
-  @Before
-  public void setUp() {
-    periodsHolder.setPeriod(new Period("mode_p_1", null, parseDate("2009-12-25").getTime(), "U1"));
-  }
+  private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, measureRepository, metricRepository);
 
   @Test
   public void verify_aggregation_of_measures_for_new_conditions() {