aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api/src
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2015-02-20 14:57:39 +0100
committerJulien HENRY <julien.henry@sonarsource.com>2015-02-20 15:05:18 +0100
commitee09741a99176e635b310ab295dd898533828d69 (patch)
treeccb54de1e5373e54e9a9feffc2adde4d81ac1a05 /sonar-plugin-api/src
parent38357bb24905509dd775e40bdf09e40aec6af39c (diff)
downloadsonarqube-ee09741a99176e635b310ab295dd898533828d69.tar.gz
sonarqube-ee09741a99176e635b310ab295dd898533828d69.zip
SONAR-5931 Add a tester class for SensorContext
Diffstat (limited to 'sonar-plugin-api/src')
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java303
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java158
2 files changed, 461 insertions, 0 deletions
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
new file mode 100644
index 00000000000..1a41ccefe44
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
@@ -0,0 +1,303 @@
+/*
+ * 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.api.batch.sensor.internal;
+
+import com.google.common.annotations.Beta;
+import org.sonar.api.batch.AnalysisMode;
+import org.sonar.api.batch.fs.InputDir;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputPath;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputDir;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+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.dependency.Dependency;
+import org.sonar.api.batch.sensor.dependency.NewDependency;
+import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency;
+import org.sonar.api.batch.sensor.duplication.Duplication;
+import org.sonar.api.batch.sensor.duplication.NewDuplication;
+import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
+import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
+import org.sonar.api.batch.sensor.highlighting.TypeOfText;
+import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
+import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
+import org.sonar.api.batch.sensor.issue.Issue;
+import org.sonar.api.batch.sensor.issue.NewIssue;
+import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
+import org.sonar.api.batch.sensor.measure.Measure;
+import org.sonar.api.batch.sensor.measure.NewMeasure;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
+import org.sonar.api.config.Settings;
+import org.sonar.api.measures.Metric;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Utility class to help testing {@link Sensor}
+ * @since 5.1
+ */
+@Beta
+public class SensorContextTester implements SensorContext {
+
+ private Settings settings;
+ private DefaultFileSystem fs;
+ private ActiveRules activeRules;
+ private MockAnalysisMode analysisMode;
+ private InMemorySensorStorage sensorStorage;
+
+ private SensorContextTester(File moduleBaseDir) {
+ this.settings = new Settings();
+ this.fs = new DefaultFileSystem(moduleBaseDir);
+ this.activeRules = new ActiveRulesBuilder().build();
+ this.analysisMode = new MockAnalysisMode();
+ this.sensorStorage = new InMemorySensorStorage();
+ }
+
+ public static SensorContextTester create(File moduleBaseDir) {
+ return new SensorContextTester(moduleBaseDir);
+ }
+
+ @Override
+ public Settings settings() {
+ return settings;
+ }
+
+ public void setSettings(Settings settings) {
+ this.settings = settings;
+ }
+
+ @Override
+ public DefaultFileSystem fileSystem() {
+ return fs;
+ }
+
+ public void setFileSystem(DefaultFileSystem fs) {
+ this.fs = fs;
+ }
+
+ @Override
+ public ActiveRules activeRules() {
+ return activeRules;
+ }
+
+ public void setActiveRules(ActiveRules activeRules) {
+ this.activeRules = activeRules;
+ }
+
+ @Override
+ public MockAnalysisMode analysisMode() {
+ return analysisMode;
+ }
+
+ @Override
+ public <G extends Serializable> NewMeasure<G> newMeasure() {
+ return new DefaultMeasure<>(sensorStorage);
+ }
+
+ public Collection<Measure> measures(@Nullable String componetKey) {
+ if (componetKey == null) {
+ return sensorStorage.projectMeasuresByMetric.values();
+ }
+ Map<String, Measure> measures = sensorStorage.measuresByComponentAndMetric.get(componetKey);
+ return measures != null ? measures.values() : Collections.<Measure>emptyList();
+ }
+
+ public <G extends Serializable> Measure<G> measure(String componetKey, Metric<G> metric) {
+ return measure(componetKey, metric.key());
+ }
+
+ public Measure measure(String componetKey, String metricKey) {
+ if (componetKey == null) {
+ return sensorStorage.projectMeasuresByMetric.get(metricKey);
+ }
+ Map<String, Measure> measures = sensorStorage.measuresByComponentAndMetric.get(componetKey);
+ return measures != null ? measures.get(metricKey) : null;
+ }
+
+ @Override
+ public NewIssue newIssue() {
+ return new DefaultIssue(sensorStorage);
+ }
+
+ public Collection<Issue> allIssues() {
+ List<Issue> result = new ArrayList<>();
+ result.addAll(sensorStorage.projectIssues);
+ for (String key : sensorStorage.issuesByComponent.keySet()) {
+ result.addAll(sensorStorage.issuesByComponent.get(key));
+ }
+ return result;
+ }
+
+ /**
+ * @param componentKey null for project issues
+ */
+ public Collection<Issue> issues(@Nullable String componentKey) {
+ if (componentKey != null) {
+ List<Issue> list = sensorStorage.issuesByComponent.get(componentKey);
+ return list != null ? list : Collections.<Issue>emptyList();
+ } else {
+ return sensorStorage.projectIssues;
+ }
+ }
+
+ @Override
+ public NewHighlighting newHighlighting() {
+ return new DefaultHighlighting(sensorStorage);
+ }
+
+ public List<TypeOfText> highlightingTypeFor(String componentKey, int charIndex) {
+ DefaultHighlighting syntaxHighlightingData = sensorStorage.highlightingByComponent.get(componentKey);
+ if (syntaxHighlightingData == null) {
+ return Collections.emptyList();
+ }
+ List<TypeOfText> result = new ArrayList<TypeOfText>();
+ for (SyntaxHighlightingRule sortedRule : syntaxHighlightingData.getSyntaxHighlightingRuleSet()) {
+ if (sortedRule.getStartPosition() <= charIndex && sortedRule.getEndPosition() > charIndex) {
+ result.add(sortedRule.getTextType());
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public NewDuplication newDuplication() {
+ return new DefaultDuplication(sensorStorage);
+ }
+
+ public Collection<Duplication> duplications() {
+ return sensorStorage.duplications;
+ }
+
+ @Override
+ public NewDependency newDependency() {
+ return new DefaultDependency(sensorStorage);
+ }
+
+ public Collection<Dependency> dependencies() {
+ return sensorStorage.dependencies;
+ }
+
+ public static class MockAnalysisMode implements AnalysisMode {
+ private boolean isIncremental = false;
+ private boolean isPreview = false;
+
+ @Override
+ public boolean isIncremental() {
+ return isIncremental;
+ }
+
+ public void setIncremental(boolean value) {
+ this.isIncremental = value;
+ }
+
+ @Override
+ public boolean isPreview() {
+ return isPreview;
+ }
+
+ public void setPreview(boolean value) {
+ this.isPreview = value;
+ }
+ }
+
+ private static class InMemorySensorStorage implements SensorStorage {
+
+ private Map<String, Measure> projectMeasuresByMetric = new HashMap<>();
+ private Map<String, Map<String, Measure>> measuresByComponentAndMetric = new HashMap<>();
+
+ private Collection<Issue> projectIssues = new ArrayList<>();
+ private Map<String, List<Issue>> issuesByComponent = new HashMap<>();
+
+ private Map<String, DefaultHighlighting> highlightingByComponent = new HashMap<>();
+
+ private List<Duplication> duplications = new ArrayList<>();
+ private List<Dependency> dependencies = new ArrayList<>();
+
+ @Override
+ public void store(Measure measure) {
+ String key = getKey(measure.inputFile());
+ if (key == null) {
+ projectMeasuresByMetric.put(measure.metric().key(), measure);
+ } else {
+ if (!measuresByComponentAndMetric.containsKey(key)) {
+ measuresByComponentAndMetric.put(key, new HashMap<String, Measure>());
+ }
+ measuresByComponentAndMetric.get(key).put(measure.metric().key(), measure);
+ }
+ }
+
+ @Override
+ public void store(Issue issue) {
+ String key = getKey(issue.inputPath());
+ if (key == null) {
+ projectIssues.add(issue);
+ } else {
+ if (!issuesByComponent.containsKey(key)) {
+ issuesByComponent.put(key, new ArrayList<Issue>());
+ }
+ issuesByComponent.get(key).add(issue);
+ }
+ }
+
+ @Override
+ public void store(Duplication duplication) {
+ duplications.add(duplication);
+ }
+
+ @Override
+ public void store(Dependency dependency) {
+ dependencies.add(dependency);
+ }
+
+ @Override
+ public void store(DefaultHighlighting highlighting) {
+ highlightingByComponent.put(getKey(highlighting.inputFile()), highlighting);
+ }
+
+ @CheckForNull
+ private String getKey(@Nullable InputPath inputPath) {
+ if (inputPath == null) {
+ return null;
+ }
+ if (inputPath instanceof InputFile) {
+ return ((DefaultInputFile) inputPath).key();
+ }
+ if (inputPath instanceof InputDir) {
+ return ((DefaultInputDir) inputPath).key();
+ }
+ throw new IllegalStateException("Unknow component " + inputPath);
+ }
+
+ }
+
+}
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
new file mode 100644
index 00000000000..090e487ddfe
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
@@ -0,0 +1,158 @@
+package org.sonar.api.batch.sensor.internal;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputDir;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.rule.ActiveRules;
+import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
+import org.sonar.api.batch.sensor.highlighting.TypeOfText;
+import org.sonar.api.config.Settings;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.rule.RuleKey;
+
+import java.io.File;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SensorContextTesterTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+ private SensorContextTester tester;
+ private File baseDir;
+
+ @Before
+ public void prepare() throws Exception {
+ baseDir = temp.newFolder();
+ tester = SensorContextTester.create(baseDir);
+ }
+
+ @Test
+ public void testSettings() {
+ Settings settings = new Settings();
+ settings.setProperty("foo", "bar");
+ tester.setSettings(settings);
+ assertThat(tester.settings().getString("foo")).isEqualTo("bar");
+ }
+
+ @Test
+ public void testActiveRules() {
+ ActiveRules activeRules = new ActiveRulesBuilder().create(RuleKey.of("repo", "rule")).activate().build();
+ tester.setActiveRules(activeRules);
+ assertThat(tester.activeRules().findAll()).hasSize(1);
+ }
+
+ @Test
+ public void testFs() throws Exception {
+ DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder());
+ tester.setFileSystem(fs);
+ assertThat(tester.fileSystem().baseDir()).isNotEqualTo(baseDir);
+ }
+
+ @Test
+ public void testAnalysisMode() {
+ assertThat(tester.analysisMode().isIncremental()).isFalse();
+ assertThat(tester.analysisMode().isPreview()).isFalse();
+ tester.analysisMode().setIncremental(true);
+ assertThat(tester.analysisMode().isIncremental()).isTrue();
+ tester.analysisMode().setPreview(true);
+ assertThat(tester.analysisMode().isPreview()).isTrue();
+ }
+
+ @Test
+ public void testIssues() {
+ assertThat(tester.issues("foo:src/Foo.java")).isEmpty();
+ assertThat(tester.allIssues()).isEmpty();
+ tester.newIssue()
+ .onFile(new DefaultInputFile("foo", "src/Foo.java"))
+ .forRule(RuleKey.of("repo", "rule"))
+ .atLine(1)
+ .save();
+ tester.newIssue()
+ .onFile(new DefaultInputFile("foo", "src/Foo.java"))
+ .forRule(RuleKey.of("repo", "rule"))
+ .atLine(3)
+ .save();
+ assertThat(tester.issues("foo:src/Foo.java")).hasSize(2);
+ assertThat(tester.allIssues()).hasSize(2);
+ tester.newIssue()
+ .onDir(new DefaultInputDir("foo", "src"))
+ .forRule(RuleKey.of("repo", "rule"))
+ .save();
+ assertThat(tester.issues("foo:src")).hasSize(1);
+ assertThat(tester.allIssues()).hasSize(3);
+ tester.newIssue()
+ .onProject()
+ .forRule(RuleKey.of("repo", "rule"))
+ .save();
+ assertThat(tester.issues(null)).hasSize(1);
+ assertThat(tester.allIssues()).hasSize(4);
+ }
+
+ @Test
+ public void testMeasures() {
+ assertThat(tester.measures("foo:src/Foo.java")).isEmpty();
+ assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNull();
+ tester.<Integer>newMeasure()
+ .onFile(new DefaultInputFile("foo", "src/Foo.java"))
+ .forMetric(CoreMetrics.NCLOC)
+ .withValue(2)
+ .save();
+ assertThat(tester.measures("foo:src/Foo.java")).hasSize(1);
+ assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull();
+ tester.<Integer>newMeasure()
+ .onFile(new DefaultInputFile("foo", "src/Foo.java"))
+ .forMetric(CoreMetrics.LINES)
+ .withValue(4)
+ .save();
+ assertThat(tester.measures("foo:src/Foo.java")).hasSize(2);
+ assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull();
+ assertThat(tester.measure("foo:src/Foo.java", "lines")).isNotNull();
+ tester.<Integer>newMeasure()
+ .onProject()
+ .forMetric(CoreMetrics.DIRECTORIES)
+ .withValue(4)
+ .save();
+ assertThat(tester.measures(null)).hasSize(1);
+ assertThat(tester.measure(null, "directories")).isNotNull();
+ }
+
+ @Test
+ public void testHighlighting() {
+ assertThat(tester.highlightingTypeFor("foo:src/Foo.java", 3)).isEmpty();
+ tester.newHighlighting()
+ .onFile(new DefaultInputFile("foo", "src/Foo.java"))
+ .highlight(0, 4, TypeOfText.ANNOTATION)
+ .highlight(8, 10, TypeOfText.CONSTANT)
+ .highlight(9, 10, TypeOfText.COMMENT)
+ .save();
+ assertThat(tester.highlightingTypeFor("foo:src/Foo.java", 3)).containsExactly(TypeOfText.ANNOTATION);
+ assertThat(tester.highlightingTypeFor("foo:src/Foo.java", 9)).containsExactly(TypeOfText.CONSTANT, TypeOfText.COMMENT);
+ }
+
+ @Test
+ public void testDuplication() {
+ assertThat(tester.duplications()).isEmpty();
+ tester.newDuplication()
+ .originBlock(new DefaultInputFile("foo", "src/Foo.java").setLines(40), 1, 30)
+ .isDuplicatedBy(new DefaultInputFile("foo", "src/Foo2.java").setLines(40), 3, 33)
+ .isDuplicatedBy(new DefaultInputFile("foo", "src/Foo3.java").setLines(40), 4, 34)
+ .save();
+ assertThat(tester.duplications()).hasSize(1);
+ }
+
+ @Test
+ public void testDependencies() {
+ assertThat(tester.dependencies()).isEmpty();
+ tester.newDependency()
+ .from(new DefaultInputFile("foo", "src/Foo.java"))
+ .to(new DefaultInputFile("foo", "src/Foo2.java"))
+ .weight(3)
+ .save();
+ assertThat(tester.dependencies()).hasSize(1);
+ }
+}