]> source.dussan.org Git - sonarqube.git/commitdiff
change NewCoverageVariationSumFormula into VariationSumFormula
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 27 Aug 2015 09:45:48 +0000 (11:45 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Sat, 29 Aug 2015 13:58:42 +0000 (15:58 +0200)
make it more generic to be used for other NEW_* metrics

server/sonar-server/src/main/java/org/sonar/server/computation/formula/VariationSumFormula.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/formula/coverage/CoverageUtils.java
server/sonar-server/src/main/java/org/sonar/server/computation/formula/coverage/LinesAndConditionsWithUncoveredVariationCounter.java
server/sonar-server/src/main/java/org/sonar/server/computation/formula/coverage/NewCoverageVariationSumFormula.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/period/PeriodPredicates.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputeQProfileMeasureStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/NewCoverageMeasuresStep.java
server/sonar-server/src/test/java/org/sonar/server/computation/period/PeriodPredicatesTest.java [new file with mode: 0644]

diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/VariationSumFormula.java b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/VariationSumFormula.java
new file mode 100644 (file)
index 0000000..cf066b7
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.formula;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import org.sonar.server.computation.component.CrawlerDepthLimit;
+import org.sonar.server.computation.formula.counter.DoubleVariationValue;
+import org.sonar.server.computation.measure.Measure;
+import org.sonar.server.computation.measure.MeasureVariations;
+import org.sonar.server.computation.period.Period;
+
+import static com.google.common.collect.FluentIterable.from;
+import static java.util.Objects.requireNonNull;
+import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
+
+/**
+ * A Formula which aggregates variations of a specific metric by simply making the sums of its variations. It supports
+ * make the sum of only specific periods.
+ */
+public class VariationSumFormula implements Formula<VariationSumFormula.VariationSumCounter> {
+  private final String metricKey;
+  private final Predicate<Period> supportedPeriods;
+
+  public VariationSumFormula(String metricKey, Predicate<Period> supportedPeriods) {
+    this.supportedPeriods = supportedPeriods;
+    this.metricKey = requireNonNull(metricKey, "Metric key cannot be null");
+  }
+
+  @Override
+  public VariationSumCounter createNewCounter() {
+    return new VariationSumCounter(metricKey, supportedPeriods);
+  }
+
+  @Override
+  public Optional<Measure> createMeasure(VariationSumCounter counter, CreateMeasureContext context) {
+    if (!CrawlerDepthLimit.LEAVES.isDeeperThan(context.getComponent().getType())) {
+      return Optional.absent();
+    }
+    MeasureVariations.Builder variations = createAndPopulateBuilder(counter.array, context);
+    if (variations.isEmpty()) {
+      return Optional.absent();
+    }
+    return Optional.of(newMeasureBuilder().setVariations(variations.build()).createNoValue());
+  }
+
+  private MeasureVariations.Builder createAndPopulateBuilder(DoubleVariationValue.Array array, CreateMeasureContext context) {
+    MeasureVariations.Builder builder = MeasureVariations.newMeasureVariationsBuilder();
+    for (Period period : from(context.getPeriods()).filter(supportedPeriods)) {
+      DoubleVariationValue elements = array.get(period);
+      if (elements.isSet()) {
+        builder.setVariation(period, elements.getValue());
+      }
+    }
+    return builder;
+  }
+
+  @Override
+  public String[] getOutputMetricKeys() {
+    return new String[] {metricKey};
+  }
+
+  public static final class VariationSumCounter implements Counter<VariationSumCounter> {
+    private final DoubleVariationValue.Array array = DoubleVariationValue.newArray();
+    private final String metricKey;
+    private final Predicate<Period> supportedPeriods;
+
+    private VariationSumCounter(String metricKey, Predicate<Period> supportedPeriods) {
+      this.metricKey = metricKey;
+      this.supportedPeriods = supportedPeriods;
+    }
+
+    @Override
+    public void aggregate(VariationSumCounter counter) {
+      array.incrementAll(counter.array);
+    }
+
+    @Override
+    public void initialize(CounterInitializationContext context) {
+      Optional<Measure> measure = context.getMeasure(metricKey);
+      if (!measure.isPresent() || !measure.get().hasVariations()) {
+        return;
+      }
+      MeasureVariations variations = measure.get().getVariations();
+      for (Period period : from(context.getPeriods()).filter(supportedPeriods)) {
+        if (variations.hasVariation(period.getIndex())) {
+          double variation = variations.getVariation(period.getIndex());
+          if (variation > 0) {
+            array.increment(period, variations.getVariation(period.getIndex()));
+          }
+        }
+      }
+    }
+  }
+}
index 58e4ce1efa376c8293fe47de59b6d3e159a897af..fe84439c83dd6975e1a7037e887c02d1214ceffd 100644 (file)
@@ -20,9 +20,6 @@
 package org.sonar.server.computation.formula.coverage;
 
 import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import java.util.List;
-import javax.annotation.Nonnull;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.formula.CounterInitializationContext;
 import org.sonar.server.computation.formula.CreateMeasureContext;
@@ -32,6 +29,7 @@ import org.sonar.server.computation.period.Period;
 
 import static com.google.common.collect.FluentIterable.from;
 import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
+import static org.sonar.server.computation.period.PeriodPredicates.viewsRestrictedPeriods;
 
 public final class CoverageUtils {
   private static final Measure DEFAULT_MEASURE = newMeasureBuilder().create(0L);
@@ -87,19 +85,11 @@ public final class CoverageUtils {
     return supportedPeriods(context.getLeaf().getType(), context.getPeriods());
   }
 
-  private static Iterable<Period> supportedPeriods(Component.Type type, List<Period> periods) {
+  private static Iterable<Period> supportedPeriods(Component.Type type, Iterable<Period> periods) {
     if (type.isReportType()) {
       return periods;
     }
-    return from(periods).filter(ViewsSupportedPeriods.INSTANCE);
+    return from(periods).filter(viewsRestrictedPeriods());
   }
 
-  private enum ViewsSupportedPeriods implements Predicate<Period> {
-    INSTANCE;
-
-    @Override
-    public boolean apply(@Nonnull Period input) {
-      return input.getIndex() < 4;
-    }
-  }
 }
index 96fc9422021c18b54f04036a9afd338d38539b0e..946ddaf7dd94b80daaa8df90821809dcbd1f500f 100644 (file)
@@ -25,6 +25,7 @@ import org.sonar.server.computation.measure.Measure;
 import org.sonar.server.computation.measure.MeasureVariations;
 import org.sonar.server.computation.period.Period;
 
+import static org.sonar.server.computation.formula.coverage.CoverageUtils.getLongVariation;
 import static org.sonar.server.computation.formula.coverage.CoverageUtils.supportedPeriods;
 
 public final class LinesAndConditionsWithUncoveredVariationCounter extends ElementsAndCoveredElementsVariationCounter {
@@ -49,11 +50,11 @@ public final class LinesAndConditionsWithUncoveredVariationCounter extends Eleme
       if (!newLines.hasVariation(period.getIndex())) {
         continue;
       }
-      long elements = (long) newLines.getVariation(period.getIndex()) + CoverageUtils.getLongVariation(newConditions, period);
+      long elements = (long) newLines.getVariation(period.getIndex()) + getLongVariation(newConditions, period);
       this.elements.increment(period, elements);
       coveredElements.increment(
         period,
-        elements - CoverageUtils.getLongVariation(uncoveredConditions, period) - CoverageUtils.getLongVariation(uncoveredLines, period));
+        elements - getLongVariation(uncoveredConditions, period) - getLongVariation(uncoveredLines, period));
     }
   }
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/coverage/NewCoverageVariationSumFormula.java b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/coverage/NewCoverageVariationSumFormula.java
deleted file mode 100644 (file)
index 6bcf790..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation.formula.coverage;
-
-import com.google.common.base.Optional;
-import org.sonar.server.computation.component.CrawlerDepthLimit;
-import org.sonar.server.computation.formula.Counter;
-import org.sonar.server.computation.formula.CounterInitializationContext;
-import org.sonar.server.computation.formula.CreateMeasureContext;
-import org.sonar.server.computation.formula.Formula;
-import org.sonar.server.computation.formula.counter.DoubleVariationValue;
-import org.sonar.server.computation.measure.Measure;
-import org.sonar.server.computation.measure.MeasureVariations;
-import org.sonar.server.computation.period.Period;
-
-import static java.util.Objects.requireNonNull;
-import static org.sonar.server.computation.formula.coverage.CoverageUtils.supportedPeriods;
-import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
-
-/**
- * A Formula which aggregates a new coverage measure by simply making the sums of its variations.
- */
-public class NewCoverageVariationSumFormula implements Formula<NewCoverageVariationSumFormula.VariationSumCounter> {
-  private final String metricKey;
-
-  public NewCoverageVariationSumFormula(String metricKey) {
-    this.metricKey = requireNonNull(metricKey, "Metric key cannot be null");
-  }
-
-  @Override
-  public VariationSumCounter createNewCounter() {
-    return new VariationSumCounter(metricKey);
-  }
-
-  @Override
-  public Optional<Measure> createMeasure(VariationSumCounter counter, CreateMeasureContext context) {
-    if (!CrawlerDepthLimit.LEAVES.isDeeperThan(context.getComponent().getType())) {
-      return Optional.absent();
-    }
-    MeasureVariations.Builder variations = createAndPopulateBuilder(counter.array, context);
-    if (variations.isEmpty()) {
-      return Optional.absent();
-    }
-    return Optional.of(newMeasureBuilder().setVariations(variations.build()).createNoValue());
-  }
-
-  private static MeasureVariations.Builder createAndPopulateBuilder(DoubleVariationValue.Array array, CreateMeasureContext context) {
-    MeasureVariations.Builder builder = MeasureVariations.newMeasureVariationsBuilder();
-    for (Period period : supportedPeriods(context)) {
-      DoubleVariationValue elements = array.get(period);
-      if (elements.isSet()) {
-        builder.setVariation(period, elements.getValue());
-      }
-    }
-    return builder;
-  }
-
-  @Override
-  public String[] getOutputMetricKeys() {
-    return new String[] { metricKey };
-  }
-
-  public static final class VariationSumCounter implements Counter<VariationSumCounter> {
-    private final DoubleVariationValue.Array array = DoubleVariationValue.newArray();
-    private final String metricKey;
-
-    private VariationSumCounter(String metricKey) {
-      this.metricKey = metricKey;
-    }
-
-    @Override
-    public void aggregate(VariationSumCounter counter) {
-      array.incrementAll(counter.array);
-    }
-
-    @Override
-    public void initialize(CounterInitializationContext context) {
-      Optional<Measure> measure = context.getMeasure(metricKey);
-      if (!measure.isPresent() || !measure.get().hasVariations()) {
-        return;
-      }
-      MeasureVariations variations = measure.get().getVariations();
-      for (Period period : supportedPeriods(context)) {
-        if (variations.hasVariation(period.getIndex())) {
-          double variation = variations.getVariation(period.getIndex());
-          if (variation > 0) {
-            array.increment(period, variations.getVariation(period.getIndex()));
-          }
-        }
-      }
-    }
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/period/PeriodPredicates.java b/server/sonar-server/src/main/java/org/sonar/server/computation/period/PeriodPredicates.java
new file mode 100644 (file)
index 0000000..d5806e4
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.period;
+
+import com.google.common.base.Predicate;
+import javax.annotation.Nonnull;
+
+public final class PeriodPredicates {
+  private PeriodPredicates() {
+    // prevents instantiation
+  }
+
+  /**
+   * Since Periods 4 and 5 can be customized per project and/or per view/subview, aggregating variation on these periods
+   * for NEW_* metrics will only generate garbage data which will make no sense. These Periods should be ignored
+   * when processing views/subviews.
+   */
+  public static Predicate<Period> viewsRestrictedPeriods() {
+    return ViewsSupportedPeriods.INSTANCE;
+  }
+
+  private enum ViewsSupportedPeriods implements Predicate<Period> {
+    INSTANCE;
+
+    @Override
+    public boolean apply(@Nonnull Period input) {
+      return input.getIndex() < 4;
+    }
+  }
+}
index e92741f065319946a031c0179b6f69352b7eb83e..12806b26c391c1f8cb62097d5ed85e0b915ee2d5 100644 (file)
@@ -57,15 +57,15 @@ public class ComputeQProfileMeasureStep implements ComputationStep {
   @Override
   public void execute() {
     Metric qProfilesMetric = metricRepository.getByKey(CoreMetrics.QUALITY_PROFILES_KEY);
-    new PathAwareCrawler<>(new NewCoverageAggregationComponentCrawler(qProfilesMetric))
+    new PathAwareCrawler<>(new NewCoverageAggregationComponentVisitor(qProfilesMetric))
       .visit(treeRootHolder.getRoot());
   }
 
-  private class NewCoverageAggregationComponentCrawler extends PathAwareVisitorAdapter<QProfiles> {
+  private class NewCoverageAggregationComponentVisitor extends PathAwareVisitorAdapter<QProfiles> {
 
     private final Metric qProfilesMetric;
 
-    public NewCoverageAggregationComponentCrawler(Metric qProfilesMetric) {
+    public NewCoverageAggregationComponentVisitor(Metric qProfilesMetric) {
       super(CrawlerDepthLimit.MODULE, POST_ORDER, new SimpleStackElementFactory<QProfiles>() {
         @Override
         public QProfiles createForAny(Component component) {
index d503f5077d5f81088dc7ce6ffb18ea6bece55b48..eee963c6af00b8db25efe54902a55347f07e8d17 100644 (file)
@@ -41,7 +41,7 @@ import org.sonar.server.computation.formula.CounterInitializationContext;
 import org.sonar.server.computation.formula.CreateMeasureContext;
 import org.sonar.server.computation.formula.Formula;
 import org.sonar.server.computation.formula.FormulaExecutorComponentVisitor;
-import org.sonar.server.computation.formula.coverage.NewCoverageVariationSumFormula;
+import org.sonar.server.computation.formula.VariationSumFormula;
 import org.sonar.server.computation.formula.counter.IntVariationValue;
 import org.sonar.server.computation.formula.coverage.LinesAndConditionsWithUncoveredMetricKeys;
 import org.sonar.server.computation.formula.coverage.LinesAndConditionsWithUncoveredVariationFormula;
@@ -56,6 +56,7 @@ import org.sonar.server.computation.period.Period;
 import org.sonar.server.computation.period.PeriodsHolder;
 
 import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
+import static org.sonar.server.computation.period.PeriodPredicates.viewsRestrictedPeriods;
 
 /**
  * Computes measures related to the New Coverage. These measures do not have values, only variations.
@@ -63,8 +64,7 @@ import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
 public class NewCoverageMeasuresStep implements ComputationStep {
   private static final List<Formula> FORMULAS = ImmutableList.<Formula>of(
     // UT coverage
-    new NewCoverageFormula()
-      ,
+    new NewCoverageFormula(),
     new NewBranchCoverageFormula(),
     new NewLineCoverageFormula(),
     // IT File coverage
@@ -74,8 +74,7 @@ public class NewCoverageMeasuresStep implements ComputationStep {
     // Overall coverage
     new NewOverallCodeCoverageFormula(),
     new NewOverallBranchCoverageFormula(),
-    new NewOverallLineCoverageFormula()
-  );
+    new NewOverallLineCoverageFormula());
 
   private final TreeRootHolder treeRootHolder;
   private final PeriodsHolder periodsHolder;
@@ -132,7 +131,7 @@ public class NewCoverageMeasuresStep implements ComputationStep {
     private static final NewCoverageOutputMetricKeys OUTPUT_METRIC_KEYS = new NewCoverageOutputMetricKeys(
       CoreMetrics.NEW_LINES_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_LINES_KEY,
       CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY);
-    private static final Iterable<Formula<?>> VIEWS_FORMULAS = intSumFormulas(OUTPUT_METRIC_KEYS);
+    private static final Iterable<Formula<?>> VIEWS_FORMULAS = variationSumFormulas(OUTPUT_METRIC_KEYS);
 
     private NewLinesAndConditionsCoverageFormula(BatchReportReader batchReportReader) {
       super(batchReportReader,
@@ -180,7 +179,7 @@ public class NewCoverageMeasuresStep implements ComputationStep {
     private static final NewCoverageOutputMetricKeys OUTPUT_METRIC_KEYS = new NewCoverageOutputMetricKeys(
       CoreMetrics.NEW_IT_LINES_TO_COVER_KEY, CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY,
       CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY);
-    private static final Iterable<Formula<?>> VIEWS_FORMULAS = intSumFormulas(OUTPUT_METRIC_KEYS);
+    private static final Iterable<Formula<?>> VIEWS_FORMULAS = variationSumFormulas(OUTPUT_METRIC_KEYS);
 
     private NewItLinesAndConditionsCoverageFormula(BatchReportReader batchReportReader) {
       super(batchReportReader,
@@ -229,7 +228,7 @@ public class NewCoverageMeasuresStep implements ComputationStep {
     private static final NewCoverageOutputMetricKeys OUTPUT_METRIC_KEYS = new NewCoverageOutputMetricKeys(
       CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY,
       CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY);
-    private static final Iterable<Formula<?>> VIEWS_FORMULAS = intSumFormulas(OUTPUT_METRIC_KEYS);
+    private static final Iterable<Formula<?>> VIEWS_FORMULAS = variationSumFormulas(OUTPUT_METRIC_KEYS);
 
     private NewOverallLinesAndConditionsCoverageFormula(BatchReportReader batchReportReader) {
       super(batchReportReader,
@@ -278,12 +277,12 @@ public class NewCoverageMeasuresStep implements ComputationStep {
    * Creates a List of {@link org.sonar.server.computation.formula.SumFormula.IntSumFormula} for each
    * metric key of the specified {@link NewCoverageOutputMetricKeys} instance.
    */
-  private static Iterable<Formula<?>> intSumFormulas(NewCoverageOutputMetricKeys outputMetricKeys) {
+  private static Iterable<Formula<?>> variationSumFormulas(NewCoverageOutputMetricKeys outputMetricKeys) {
     return ImmutableList.<Formula<?>>of(
-      new NewCoverageVariationSumFormula(outputMetricKeys.getNewLinesToCover()),
-      new NewCoverageVariationSumFormula(outputMetricKeys.getNewUncoveredLines()),
-      new NewCoverageVariationSumFormula(outputMetricKeys.getNewConditionsToCover()),
-      new NewCoverageVariationSumFormula(outputMetricKeys.getNewUncoveredConditions()));
+      new VariationSumFormula(outputMetricKeys.getNewLinesToCover(), viewsRestrictedPeriods()),
+      new VariationSumFormula(outputMetricKeys.getNewUncoveredLines(), viewsRestrictedPeriods()),
+      new VariationSumFormula(outputMetricKeys.getNewConditionsToCover(), viewsRestrictedPeriods()),
+      new VariationSumFormula(outputMetricKeys.getNewUncoveredConditions(), viewsRestrictedPeriods()));
   }
 
   public static class NewLinesAndConditionsFormula implements Formula<NewCoverageCounter> {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/period/PeriodPredicatesTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/period/PeriodPredicatesTest.java
new file mode 100644 (file)
index 0000000..103494f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.period;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PeriodPredicatesTest {
+
+  @Test(expected = NullPointerException.class)
+  public void viewsRestrictedPeriods_throws_NPE_if_Period_is_null() {
+    PeriodPredicates.viewsRestrictedPeriods().apply(null);
+  }
+
+  @Test
+  public void viewsRestrictedPeriods() {
+    assertThat(PeriodPredicates.viewsRestrictedPeriods().apply(createPeriod(1))).isTrue();
+    assertThat(PeriodPredicates.viewsRestrictedPeriods().apply(createPeriod(2))).isTrue();
+    assertThat(PeriodPredicates.viewsRestrictedPeriods().apply(createPeriod(3))).isTrue();
+    assertThat(PeriodPredicates.viewsRestrictedPeriods().apply(createPeriod(4))).isFalse();
+    assertThat(PeriodPredicates.viewsRestrictedPeriods().apply(createPeriod(5))).isFalse();
+  }
+
+  private Period createPeriod(int index) {
+    return new Period(index, "don't care", null, 1l, 1l);
+  }
+}