From f8703a4155668ee958bd38d59776c1415fce0f82 Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Thu, 20 Oct 2016 11:14:12 +0200 Subject: [PATCH] SONAR-8281 Update SensorContextTester to no more expose coverage type --- .../xoo/coverage/ItCoverageSensorTest.java | 14 +++-- .../coverage/OverallCoverageSensorTest.java | 14 +++-- .../xoo/coverage/UtCoverageSensorTest.java | 20 +++----- .../internal/InMemorySensorStorage.java | 11 ++-- .../sensor/internal/SensorContextTester.java | 51 +++++++++++-------- .../internal/SensorContextTesterTest.java | 50 ++++++++---------- 6 files changed, 74 insertions(+), 86 deletions(-) diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/ItCoverageSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/ItCoverageSensorTest.java index 2175768d03e..0b8c81f6c81 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/ItCoverageSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/ItCoverageSensorTest.java @@ -19,6 +19,8 @@ */ package org.sonar.xoo.coverage; +import java.io.File; +import java.io.IOException; import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Rule; @@ -26,13 +28,9 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.coverage.CoverageType; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; import org.sonar.api.batch.sensor.internal.SensorContextTester; -import java.io.File; -import java.io.IOException; - import static org.assertj.core.api.Assertions.assertThat; public class ItCoverageSensorTest { @@ -76,7 +74,7 @@ public class ItCoverageSensorTest { sensor.execute(context); - assertThat(context.lineHits("foo:src/foo.xoo", CoverageType.IT, 1)).isEqualTo(3); + assertThat(context.lineHits("foo:src/foo.xoo", 1)).isEqualTo(3); } @Test @@ -88,8 +86,8 @@ public class ItCoverageSensorTest { sensor.execute(context); - assertThat(context.lineHits("foo:src/foo.xoo", CoverageType.IT, 1)).isEqualTo(3); - assertThat(context.conditions("foo:src/foo.xoo", CoverageType.IT, 1)).isEqualTo(4); - assertThat(context.coveredConditions("foo:src/foo.xoo", CoverageType.IT, 1)).isEqualTo(2); + assertThat(context.lineHits("foo:src/foo.xoo", 1)).isEqualTo(3); + assertThat(context.conditions("foo:src/foo.xoo", 1)).isEqualTo(4); + assertThat(context.coveredConditions("foo:src/foo.xoo", 1)).isEqualTo(2); } } diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/OverallCoverageSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/OverallCoverageSensorTest.java index 401c0b6f388..825760416e3 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/OverallCoverageSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/OverallCoverageSensorTest.java @@ -19,6 +19,8 @@ */ package org.sonar.xoo.coverage; +import java.io.File; +import java.io.IOException; import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Rule; @@ -26,13 +28,9 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.coverage.CoverageType; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; import org.sonar.api.batch.sensor.internal.SensorContextTester; -import java.io.File; -import java.io.IOException; - import static org.assertj.core.api.Assertions.assertThat; public class OverallCoverageSensorTest { @@ -76,7 +74,7 @@ public class OverallCoverageSensorTest { sensor.execute(context); - assertThat(context.lineHits("foo:src/foo.xoo", CoverageType.OVERALL, 1)).isEqualTo(3); + assertThat(context.lineHits("foo:src/foo.xoo", 1)).isEqualTo(3); } @Test @@ -88,8 +86,8 @@ public class OverallCoverageSensorTest { sensor.execute(context); - assertThat(context.lineHits("foo:src/foo.xoo", CoverageType.OVERALL, 1)).isEqualTo(3); - assertThat(context.conditions("foo:src/foo.xoo", CoverageType.OVERALL, 1)).isEqualTo(4); - assertThat(context.coveredConditions("foo:src/foo.xoo", CoverageType.OVERALL, 1)).isEqualTo(2); + assertThat(context.lineHits("foo:src/foo.xoo", 1)).isEqualTo(3); + assertThat(context.conditions("foo:src/foo.xoo", 1)).isEqualTo(4); + assertThat(context.coveredConditions("foo:src/foo.xoo", 1)).isEqualTo(2); } } diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/UtCoverageSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/UtCoverageSensorTest.java index 62fb62b8449..129e430f0c6 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/UtCoverageSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/UtCoverageSensorTest.java @@ -19,6 +19,8 @@ */ package org.sonar.xoo.coverage; +import java.io.File; +import java.io.IOException; import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Rule; @@ -26,13 +28,9 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.coverage.CoverageType; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; import org.sonar.api.batch.sensor.internal.SensorContextTester; -import java.io.File; -import java.io.IOException; - import static org.assertj.core.api.Assertions.assertThat; public class UtCoverageSensorTest { @@ -76,9 +74,7 @@ public class UtCoverageSensorTest { sensor.execute(context); - assertThat(context.lineHits("foo:src/foo.xoo", CoverageType.UNIT, 1)).isEqualTo(3); - assertThat(context.lineHits("foo:src/foo.xoo", CoverageType.IT, 1)).isNull(); - assertThat(context.lineHits("foo:src/foo.xoo", CoverageType.OVERALL, 1)).isNull(); + assertThat(context.lineHits("foo:src/foo.xoo", 1)).isEqualTo(3); } @Test @@ -90,12 +86,8 @@ public class UtCoverageSensorTest { sensor.execute(context); - assertThat(context.lineHits("foo:src/foo.xoo", CoverageType.UNIT, 1)).isEqualTo(3); - assertThat(context.conditions("foo:src/foo.xoo", CoverageType.UNIT, 1)).isEqualTo(4); - assertThat(context.conditions("foo:src/foo.xoo", CoverageType.IT, 1)).isNull(); - assertThat(context.conditions("foo:src/foo.xoo", CoverageType.OVERALL, 1)).isNull(); - assertThat(context.coveredConditions("foo:src/foo.xoo", CoverageType.UNIT, 1)).isEqualTo(2); - assertThat(context.coveredConditions("foo:src/foo.xoo", CoverageType.IT, 1)).isNull(); - assertThat(context.coveredConditions("foo:src/foo.xoo", CoverageType.OVERALL, 1)).isNull(); + assertThat(context.lineHits("foo:src/foo.xoo", 1)).isEqualTo(3); + assertThat(context.conditions("foo:src/foo.xoo", 1)).isEqualTo(4); + assertThat(context.coveredConditions("foo:src/foo.xoo", 1)).isEqualTo(2); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java index 6cc91e10760..c9f75b08000 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java @@ -19,13 +19,14 @@ */ package org.sonar.api.batch.sensor.internal; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Multimap; import com.google.common.collect.Table; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.sonar.api.batch.sensor.coverage.CoverageType; import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage; import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens; import org.sonar.api.batch.sensor.error.AnalysisError; @@ -46,7 +47,7 @@ class InMemorySensorStorage implements SensorStorage { Map highlightingByComponent = new HashMap<>(); Map cpdTokensByComponent = new HashMap<>(); - Table coverageByComponentAndType = HashBasedTable.create(); + Multimap coverageByComponent = ArrayListMultimap.create(); Map symbolsPerComponent = new HashMap<>(); Map contextProperties = new HashMap<>(); @@ -79,11 +80,7 @@ class InMemorySensorStorage implements SensorStorage { @Override public void store(DefaultCoverage defaultCoverage) { String fileKey = defaultCoverage.inputFile().key(); - // Emulate duplicate storage check - if (coverageByComponentAndType.contains(fileKey, defaultCoverage.type())) { - throw new UnsupportedOperationException("Trying to save coverage twice for the same file is not supported: " + defaultCoverage.inputFile().relativePath()); - } - coverageByComponentAndType.row(fileKey).put(defaultCoverage.type(), defaultCoverage); + coverageByComponent.put(fileKey, defaultCoverage); } @Override diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java index fc7e4b169ad..e1820ef53c9 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java @@ -28,7 +28,9 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.stream.Stream; import javax.annotation.CheckForNull; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarRuntime; @@ -41,7 +43,6 @@ import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; -import org.sonar.api.batch.sensor.coverage.CoverageType; import org.sonar.api.batch.sensor.coverage.NewCoverage; import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage; import org.sonar.api.batch.sensor.cpd.NewCpdTokens; @@ -61,8 +62,8 @@ import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.batch.sensor.symbol.NewSymbolTable; import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; -import org.sonar.api.config.Settings; import org.sonar.api.config.MapSettings; +import org.sonar.api.config.Settings; import org.sonar.api.internal.ApiVersion; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.measures.Metric; @@ -210,30 +211,40 @@ public class SensorContextTester implements SensorContext { } @CheckForNull - public Integer lineHits(String fileKey, CoverageType type, int line) { - DefaultCoverage defaultCoverage = sensorStorage.coverageByComponentAndType.get(fileKey, type); - if (defaultCoverage == null) { - return null; - } - return defaultCoverage.hitsByLine().get(line); + public Integer lineHits(String fileKey, int line) { + return sensorStorage.coverageByComponent.get(fileKey).stream() + .map(c -> c.hitsByLine().get(line)) + .flatMap(Stream::of) + .filter(Objects::nonNull) + .reduce(null, SensorContextTester::sumOrNull); } @CheckForNull - public Integer conditions(String fileKey, CoverageType type, int line) { - DefaultCoverage defaultCoverage = sensorStorage.coverageByComponentAndType.get(fileKey, type); - if (defaultCoverage == null) { - return null; - } - return defaultCoverage.conditionsByLine().get(line); + public static Integer sumOrNull(Integer o1, Integer o2) { + return o1 == null ? o2 : (o1 + o2); } @CheckForNull - public Integer coveredConditions(String fileKey, CoverageType type, int line) { - DefaultCoverage defaultCoverage = sensorStorage.coverageByComponentAndType.get(fileKey, type); - if (defaultCoverage == null) { - return null; - } - return defaultCoverage.coveredConditionsByLine().get(line); + public Integer conditions(String fileKey, int line) { + return sensorStorage.coverageByComponent.get(fileKey).stream() + .map(c -> c.conditionsByLine().get(line)) + .flatMap(Stream::of) + .filter(Objects::nonNull) + .reduce(null, SensorContextTester::maxOrNull); + } + + @CheckForNull + public Integer coveredConditions(String fileKey, int line) { + return sensorStorage.coverageByComponent.get(fileKey).stream() + .map(c -> c.coveredConditionsByLine().get(line)) + .flatMap(Stream::of) + .filter(Objects::nonNull) + .reduce(null, SensorContextTester::maxOrNull); + } + + @CheckForNull + public static Integer maxOrNull(Integer o1, Integer o2) { + return o1 == null ? o2 : Math.max(o1, o2); } @CheckForNull diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java index 807d8663773..4acdbc92dc2 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java @@ -34,15 +34,13 @@ import org.sonar.api.batch.fs.internal.DefaultTextPointer; import org.sonar.api.batch.fs.internal.FileMetadata; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; -import org.sonar.api.batch.sensor.coverage.CoverageType; -import org.sonar.api.batch.sensor.coverage.NewCoverage; import org.sonar.api.batch.sensor.error.AnalysisError; import org.sonar.api.batch.sensor.error.NewAnalysisError; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.batch.sensor.issue.NewIssue; import org.sonar.api.batch.sensor.symbol.NewSymbolTable; -import org.sonar.api.config.Settings; import org.sonar.api.config.MapSettings; +import org.sonar.api.config.Settings; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.SonarException; @@ -234,71 +232,65 @@ public class SensorContextTesterTest { @Test public void testCoverageAtLineZero() { - assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 1)).isNull(); - assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 4)).isNull(); + assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull(); + assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull(); exception.expect(IllegalStateException.class); - NewCoverage coverage = tester.newCoverage() + tester.newCoverage() .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar")))) - .ofType(CoverageType.UNIT) .lineHits(0, 3); } @Test public void testCoverageAtLineOutOfRange() { - assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 1)).isNull(); - assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 4)).isNull(); + assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull(); + assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull(); exception.expect(IllegalStateException.class); - NewCoverage coverage = tester.newCoverage() + tester.newCoverage() .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar")))) - .ofType(CoverageType.UNIT) .lineHits(4, 3); } @Test public void testLineHits() { - assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 1)).isNull(); - assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 4)).isNull(); + assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull(); + assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull(); tester.newCoverage() .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasdas")))) - .ofType(CoverageType.UNIT) .lineHits(1, 2) .lineHits(2, 3) .save(); - assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 1)).isEqualTo(2); - assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.IT, 1)).isNull(); - assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 2)).isEqualTo(3); + assertThat(tester.lineHits("foo:src/Foo.java", 1)).isEqualTo(2); + assertThat(tester.lineHits("foo:src/Foo.java", 2)).isEqualTo(3); } - @Test(expected = UnsupportedOperationException.class) - public void duplicateCoverage() { + public void multipleCoverage() { tester.newCoverage() .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasdas")))) - .ofType(CoverageType.UNIT) .lineHits(1, 2) + .conditions(3, 4, 2) .save(); tester.newCoverage() .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasdas")))) - .ofType(CoverageType.UNIT) .lineHits(1, 2) + .conditions(3, 4, 3) .save(); + assertThat(tester.lineHits("foo:src/Foo.java", 1)).isEqualTo(4); + assertThat(tester.conditions("foo:src/Foo.java", 3)).isEqualTo(4); + assertThat(tester.coveredConditions("foo:src/Foo.java", 3)).isEqualTo(3); } @Test public void testConditions() { - assertThat(tester.conditions("foo:src/Foo.java", CoverageType.UNIT, 1)).isNull(); - assertThat(tester.coveredConditions("foo:src/Foo.java", CoverageType.UNIT, 1)).isNull(); + assertThat(tester.conditions("foo:src/Foo.java", 1)).isNull(); + assertThat(tester.coveredConditions("foo:src/Foo.java", 1)).isNull(); tester.newCoverage() .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasd\nasdas\nasdfas")))) - .ofType(CoverageType.UNIT) .conditions(1, 4, 2) .save(); - assertThat(tester.conditions("foo:src/Foo.java", CoverageType.UNIT, 1)).isEqualTo(4); - assertThat(tester.coveredConditions("foo:src/Foo.java", CoverageType.UNIT, 1)).isEqualTo(2); - - assertThat(tester.conditions("foo:src/Foo.java", CoverageType.IT, 1)).isNull(); - assertThat(tester.coveredConditions("foo:src/Foo.java", CoverageType.IT, 1)).isNull(); + assertThat(tester.conditions("foo:src/Foo.java", 1)).isEqualTo(4); + assertThat(tester.coveredConditions("foo:src/Foo.java", 1)).isEqualTo(2); } @Test -- 2.39.5