diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2014-10-13 11:54:50 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2014-10-14 14:26:45 +0200 |
commit | 6882924ef2d57618e9391c20b1a7a54546a7d9dd (patch) | |
tree | de6469b2b4aa3f9599995186317b037c715024c9 /sonar-batch/src | |
parent | 95551739d6659af8c03250a708f075937e607456 (diff) | |
download | sonarqube-6882924ef2d57618e9391c20b1a7a54546a7d9dd.tar.gz sonarqube-6882924ef2d57618e9391c20b1a7a54546a7d9dd.zip |
SONAR-5389 Refactor dependency API
Diffstat (limited to 'sonar-batch/src')
12 files changed, 331 insertions, 84 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java new file mode 100644 index 00000000000..8f01f2c233b --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java @@ -0,0 +1,68 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.dependency; + +import com.persistit.Value; +import com.persistit.encoding.CoderContext; +import com.persistit.encoding.ValueCoder; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; +import org.sonar.batch.scan.filesystem.InputPathCache; + +class DefaultDependencyValueCoder implements ValueCoder { + + private InputPathCache inputPathCache; + + public DefaultDependencyValueCoder(InputPathCache inputPathCache) { + this.inputPathCache = inputPathCache; + } + + @Override + public void put(Value value, Object object, CoderContext context) { + DefaultDependency dep = (DefaultDependency) object; + value.putUTF(((DefaultInputFile) dep.from()).moduleKey()); + value.putUTF(((DefaultInputFile) dep.from()).relativePath()); + value.putUTF(((DefaultInputFile) dep.to()).moduleKey()); + value.putUTF(((DefaultInputFile) dep.to()).relativePath()); + value.put(dep.weight()); + } + + @Override + public Object get(Value value, Class clazz, CoderContext context) { + String fromModuleKey = value.getString(); + String fromRelativePath = value.getString(); + InputFile from = inputPathCache.getFile(fromModuleKey, fromRelativePath); + if (from == null) { + throw new IllegalStateException("Unable to load InputFile " + fromModuleKey + ":" + fromRelativePath); + } + String toModuleKey = value.getString(); + String toRelativePath = value.getString(); + InputFile to = inputPathCache.getFile(toModuleKey, toRelativePath); + if (to == null) { + throw new IllegalStateException("Unable to load InputFile " + toModuleKey + ":" + toRelativePath); + } + int weight = value.getInt(); + return new DefaultDependency() + .from(from) + .to(to) + .weight(weight); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java b/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java index 7a064d520fc..9e3709a5532 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java +++ b/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java @@ -23,41 +23,44 @@ import com.google.common.base.Preconditions; import org.sonar.api.BatchComponent; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.dependency.Dependency; +import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; import org.sonar.batch.index.Cache; import org.sonar.batch.index.Cache.Entry; import org.sonar.batch.index.Caches; +import org.sonar.batch.scan.filesystem.InputPathCache; import javax.annotation.CheckForNull; /** * Cache of all dependencies. This cache is shared amongst all project modules. - * module key -> from key -> to key -> OutgoingDependency + * module key -> from key -> to key -> Dependency */ public class DependencyCache implements BatchComponent { - private final Cache<OutgoingDependency> cache; + private final Cache<Dependency> cache; - public DependencyCache(Caches caches) { + public DependencyCache(Caches caches, InputPathCache inputPathCache) { + caches.registerValueCoder(DefaultDependency.class, new DefaultDependencyValueCoder(inputPathCache)); cache = caches.createCache("dependencies"); } - public Iterable<Entry<OutgoingDependency>> entries() { + public Iterable<Entry<Dependency>> entries() { return cache.entries(); } @CheckForNull - public OutgoingDependency get(String moduleKey, InputFile from, InputFile to) { + public Dependency get(String moduleKey, InputFile from, InputFile to) { Preconditions.checkNotNull(moduleKey); Preconditions.checkNotNull(from); Preconditions.checkNotNull(to); return cache.get(moduleKey, ((DefaultInputFile) from).key(), ((DefaultInputFile) to).key()); } - public DependencyCache put(String moduleKey, InputFile from, OutgoingDependency dependency) { + public DependencyCache put(String moduleKey, Dependency dependency) { Preconditions.checkNotNull(moduleKey); - Preconditions.checkNotNull(from); Preconditions.checkNotNull(dependency); - cache.put(moduleKey, ((DefaultInputFile) from).key(), ((DefaultInputFile) dependency.to()).key(), dependency); + cache.put(moduleKey, ((DefaultInputFile) dependency.from()).key(), ((DefaultInputFile) dependency.to()).key(), dependency); return this; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/dependency/OutgoingDependency.java b/sonar-batch/src/main/java/org/sonar/batch/dependency/OutgoingDependency.java deleted file mode 100644 index 0869ee6cde6..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/dependency/OutgoingDependency.java +++ /dev/null @@ -1,42 +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.batch.dependency; - -import org.sonar.api.batch.fs.InputFile; - -public class OutgoingDependency { - - private final InputFile to; - private final int weight; - - public OutgoingDependency(InputFile to, int weight) { - this.to = to; - this.weight = weight; - } - - public InputFile to() { - return to; - } - - public int weight() { - return weight; - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java index 61a6a062867..596edcdec5f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java +++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java @@ -29,6 +29,7 @@ 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.DefaultInputFile; +import org.sonar.api.batch.sensor.dependency.Dependency; import org.sonar.api.batch.sensor.duplication.DuplicationGroup; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.batch.sensor.issue.Issue; @@ -44,7 +45,6 @@ import org.sonar.batch.bootstrap.TaskProperties; import org.sonar.batch.bootstrapper.Batch; import org.sonar.batch.bootstrapper.EnvironmentInformation; import org.sonar.batch.dependency.DependencyCache; -import org.sonar.batch.dependency.OutgoingDependency; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.highlighting.SyntaxHighlightingData; import org.sonar.batch.highlighting.SyntaxHighlightingRule; @@ -229,8 +229,8 @@ public class BatchMediumTester { private List<Issue> issues = new ArrayList<Issue>(); private List<Measure> measures = new ArrayList<Measure>(); private Map<String, List<DuplicationGroup>> duplications = new HashMap<String, List<DuplicationGroup>>(); - private List<InputFile> inputFiles = new ArrayList<InputFile>(); - private List<InputDir> inputDirs = new ArrayList<InputDir>(); + private Map<String, InputFile> inputFiles = new HashMap<String, InputFile>(); + private Map<String, InputDir> inputDirs = new HashMap<String, InputDir>(); private Map<InputFile, SyntaxHighlightingData> highlightingPerFile = new HashMap<InputFile, SyntaxHighlightingData>(); private Map<InputFile, SymbolData> symbolTablePerFile = new HashMap<InputFile, SymbolData>(); private Map<String, Map<String, TestCase>> testCasesPerFile = new HashMap<String, Map<String, TestCase>>(); @@ -293,7 +293,7 @@ public class BatchMediumTester { private void storeComponentData(ProjectScanContainer container) { ComponentDataCache componentDataCache = container.getComponentByType(ComponentDataCache.class); - for (InputFile file : inputFiles) { + for (InputFile file : inputFiles.values()) { SyntaxHighlightingData highlighting = componentDataCache.getData(((DefaultInputFile) file).key(), SnapshotDataTypes.SYNTAX_HIGHLIGHTING); if (highlighting != null) { highlightingPerFile.put(file, highlighting); @@ -309,16 +309,16 @@ public class BatchMediumTester { InputPathCache inputFileCache = container.getComponentByType(InputPathCache.class); for (InputPath inputPath : inputFileCache.all()) { if (inputPath instanceof InputFile) { - inputFiles.add((InputFile) inputPath); + inputFiles.put(inputPath.relativePath(), (InputFile) inputPath); } else { - inputDirs.add((InputDir) inputPath); + inputDirs.put(inputPath.relativePath(), (InputDir) inputPath); } } } private void storeDependencies(ProjectScanContainer container) { DependencyCache dependencyCache = container.getComponentByType(DependencyCache.class); - for (Entry<OutgoingDependency> entry : dependencyCache.entries()) { + for (Entry<Dependency> entry : dependencyCache.entries()) { String fromKey = entry.key()[1].toString(); String toKey = entry.key()[2].toString(); if (!dependencies.containsKey(fromKey)) { @@ -336,12 +336,22 @@ public class BatchMediumTester { return measures; } - public List<InputFile> inputFiles() { - return inputFiles; + public Collection<InputFile> inputFiles() { + return inputFiles.values(); } - public List<InputDir> inputDirs() { - return inputDirs; + @CheckForNull + public InputFile inputFile(String relativePath) { + return inputFiles.get(relativePath); + } + + public Collection<InputDir> inputDirs() { + return inputDirs.values(); + } + + @CheckForNull + public InputDir inputDir(String relativePath) { + return inputDirs.get(relativePath); } public List<DuplicationGroup> duplicationsFor(InputFile inputFile) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java index 90c00db0ef5..e482d8b86e8 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java @@ -70,6 +70,7 @@ import java.util.List; */ public class SensorContextAdapter extends BaseSensorContext { + private static final String USES = "USES"; private final org.sonar.api.batch.SensorContext sensorContext; private final MetricFinder metricFinder; private final Project project; @@ -241,11 +242,11 @@ public class SensorContextAdapter extends BaseSensorContext { } @Override - public void saveDependency(InputFile from, InputFile to, int weight) { - File fromResource = getFile(from); - File toResource = getFile(to); + public void store(org.sonar.api.batch.sensor.dependency.Dependency dep) { + File fromResource = getFile(dep.from()); + File toResource = getFile(dep.to()); if (sonarIndex.getEdge(fromResource, toResource) != null) { - throw new IllegalStateException("Dependency between " + from + " and " + to + " was already saved."); + throw new IllegalStateException("Dependency between " + dep.from() + " and " + dep.to() + " was already saved."); } Directory fromParent = fromResource.getParent(); Directory toParent = toResource.getParent(); @@ -255,13 +256,13 @@ public class SensorContextAdapter extends BaseSensorContext { if (parentDep != null) { parentDep.setWeight(parentDep.getWeight() + 1); } else { - parentDep = new Dependency(fromParent, toParent).setUsage("USES").setWeight(1); + parentDep = new Dependency(fromParent, toParent).setUsage(USES).setWeight(1); parentDep = sensorContext.saveDependency(parentDep); } } sensorContext.saveDependency(new Dependency(fromResource, toResource) - .setUsage("USES") - .setWeight(weight) + .setUsage(USES) + .setWeight(dep.weight()) .setParent(parentDep)); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java index beb62d97251..bb81865c4b6 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java @@ -26,6 +26,8 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorStorage; +import org.sonar.api.batch.sensor.dependency.Dependency; +import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; import org.sonar.api.batch.sensor.duplication.DuplicationBuilder; import org.sonar.api.batch.sensor.duplication.DuplicationGroup; import org.sonar.api.batch.sensor.duplication.DuplicationTokenBuilder; @@ -155,4 +157,9 @@ public abstract class BaseSensorContext implements SensorContext, SensorStorage return new DefaultTestCase(this); } + @Override + public Dependency newDependency() { + return new DefaultDependency(this); + } + } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java index dff662a8f9e..90fc49ca395 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java @@ -31,6 +31,7 @@ import org.sonar.api.batch.fs.InputPath; import org.sonar.api.batch.measure.Metric; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.internal.DefaultActiveRule; +import org.sonar.api.batch.sensor.dependency.Dependency; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; import org.sonar.api.batch.sensor.measure.Measure; @@ -42,7 +43,6 @@ import org.sonar.api.measures.CoreMetrics; import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.MessageException; import org.sonar.batch.dependency.DependencyCache; -import org.sonar.batch.dependency.OutgoingDependency; import org.sonar.batch.duplication.BlockCache; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.index.ComponentDataCache; @@ -172,11 +172,11 @@ public class DefaultSensorContext extends BaseSensorContext { } @Override - public void saveDependency(InputFile from, InputFile to, int weight) { - Preconditions.checkNotNull(from); - Preconditions.checkNotNull(to); - OutgoingDependency dep = new OutgoingDependency(to, weight); - dependencyCache.put(def.getKey(), from, dep); + public void store(Dependency dep) { + if (dependencyCache.get(def.getKey(), dep.from(), dep.to()) != null) { + throw new IllegalStateException("Dependency between " + dep.from() + " and " + dep.to() + " was already saved."); + } + dependencyCache.put(def.getKey(), dep); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java new file mode 100644 index 00000000000..a6fe43a1b5c --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java @@ -0,0 +1,95 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.mediumtest.dependency; + +import com.google.common.collect.ImmutableMap; +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; +import org.sonar.batch.mediumtest.BatchMediumTester; +import org.sonar.batch.mediumtest.BatchMediumTester.TaskResult; +import org.sonar.xoo.XooPlugin; + +import java.io.File; +import java.io.IOException; + +import static org.fest.assertions.Assertions.assertThat; + +public class DependencyMediumTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public TestName testName = new TestName(); + + public BatchMediumTester tester = BatchMediumTester.builder() + .registerPlugin("xoo", new XooPlugin()) + .addDefaultQProfile("xoo", "Sonar Way") + .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) + .build(); + + @Before + public void prepare() { + tester.start(); + } + + @After + public void stop() { + tester.stop(); + } + + @Test + public void populateDependenciesOnTempProject() throws IOException { + + File baseDir = temp.newFolder(); + File srcDir = new File(baseDir, "src"); + srcDir.mkdir(); + + File xooFile = new File(srcDir, "sample.xoo"); + File xooFile2 = new File(srcDir, "sample2.xoo"); + File xooFile3 = new File(srcDir, "foo/sample3.xoo"); + File xooDepsFile = new File(srcDir, "sample.xoo.deps"); + FileUtils.write(xooFile, "Sample xoo\ncontent"); + FileUtils.write(xooFile2, "Sample xoo\ncontent"); + FileUtils.write(xooFile3, "Sample xoo\ncontent"); + FileUtils.write(xooDepsFile, "src/sample2.xoo:3\nsrc/foo/sample3.xoo:6"); + + TaskResult result = tester.newTask() + .properties(ImmutableMap.<String, String>builder() + .put("sonar.task", "scan") + .put("sonar.projectBaseDir", baseDir.getAbsolutePath()) + .put("sonar.projectKey", "com.foo.project") + .put("sonar.projectName", "Foo Project") + .put("sonar.projectVersion", "1.0-SNAPSHOT") + .put("sonar.projectDescription", "Description of Foo Project") + .put("sonar.sources", "src") + .build()) + .start(); + + assertThat(result.dependencyWeight(result.inputFile("src/sample.xoo"), result.inputFile("src/sample2.xoo"))).isEqualTo(3); + assertThat(result.dependencyWeight(result.inputFile("src/sample.xoo"), result.inputFile("src/foo/sample3.xoo"))).isEqualTo(6); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java index 19d7aea020a..08ac9d7e3cd 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java @@ -94,9 +94,9 @@ public class FileSystemMediumTest { assertThat(result.inputFiles()).hasSize(1); assertThat(result.inputDirs()).hasSize(1); - assertThat(result.inputFiles().get(0).type()).isEqualTo(InputFile.Type.MAIN); - assertThat(result.inputFiles().get(0).relativePath()).isEqualTo("src/sample.xoo"); - assertThat(result.inputDirs().get(0).relativePath()).isEqualTo("src"); + assertThat(result.inputFile("src/sample.xoo").type()).isEqualTo(InputFile.Type.MAIN); + assertThat(result.inputFile("src/sample.xoo").relativePath()).isEqualTo("src/sample.xoo"); + assertThat(result.inputDir("src").relativePath()).isEqualTo("src"); } @Test @@ -115,7 +115,7 @@ public class FileSystemMediumTest { .start(); assertThat(result.inputFiles()).hasSize(1); - assertThat(result.inputFiles().get(0).type()).isEqualTo(InputFile.Type.TEST); + assertThat(result.inputFile("test/sampleTest.xoo").type()).isEqualTo(InputFile.Type.TEST); } /** diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java index b6ce7fb7d52..93ae29ce062 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java @@ -19,8 +19,6 @@ */ package org.sonar.batch.mediumtest.highlighting; -import org.sonar.api.batch.sensor.highlighting.TypeOfText; - import com.google.common.collect.ImmutableMap; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -30,6 +28,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.rules.TestName; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.BatchMediumTester.TaskResult; import org.sonar.xoo.XooPlugin; @@ -87,7 +86,7 @@ public class HighlightingMediumTest { .build()) .start(); - InputFile file = result.inputFiles().get(0); + InputFile file = result.inputFile("src/sample.xoo"); assertThat(result.highlightingTypeFor(file, 0)).containsExactly(TypeOfText.STRING); assertThat(result.highlightingTypeFor(file, 9)).containsExactly(TypeOfText.STRING); assertThat(result.highlightingTypeFor(file, 10)).isEmpty(); @@ -126,7 +125,7 @@ public class HighlightingMediumTest { .start(); System.out.println("Duration: " + (System.currentTimeMillis() - start)); - InputFile file = result.inputFiles().get(0); + InputFile file = result.inputFile("src/sample.xoo"); assertThat(result.highlightingTypeFor(file, 0)).containsExactly(TypeOfText.STRING); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java index 8772d371ba2..10c9f37f47f 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java @@ -80,7 +80,7 @@ public class SymbolMediumTest { .build()) .start(); - InputFile file = result.inputFiles().get(0); + InputFile file = result.inputFile("src/sample.xoo"); assertThat(result.symbolReferencesFor(file, 7, 10)).containsOnly(7, 27); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java index f949f7c544d..df477befe80 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java @@ -28,16 +28,19 @@ import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.InputFile.Type; 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.dependency.internal.DefaultDependency; import org.sonar.api.batch.sensor.issue.Issue.Severity; import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.component.ResourcePerspectives; import org.sonar.api.config.Settings; +import org.sonar.api.design.Dependency; import org.sonar.api.issue.Issuable; import org.sonar.api.issue.Issue; import org.sonar.api.measures.CoreMetrics; @@ -55,6 +58,8 @@ import org.sonar.batch.index.ComponentDataCache; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class SensorContextAdapterTest { @@ -69,6 +74,7 @@ public class SensorContextAdapterTest { private Settings settings; private ResourcePerspectives resourcePerspectives; private Project project; + private SonarIndex sonarIndex; @Before public void prepare() { @@ -83,8 +89,9 @@ public class SensorContextAdapterTest { ComponentDataCache componentDataCache = mock(ComponentDataCache.class); BlockCache blockCache = mock(BlockCache.class); project = new Project("myProject"); + sonarIndex = mock(SonarIndex.class); adaptor = new SensorContextAdapter(sensorContext, metricFinder, project, - resourcePerspectives, settings, fs, activeRules, componentDataCache, blockCache, mock(DuplicationCache.class), mock(SonarIndex.class)); + resourcePerspectives, settings, fs, activeRules, componentDataCache, blockCache, mock(DuplicationCache.class), sonarIndex); } @Test @@ -239,4 +246,103 @@ public class SensorContextAdapterTest { assertThat(issue.effortToFix()).isEqualTo(10.0); } + @Test + public void shouldStoreDependencyInSameFolder() { + + File foo = File.create("src/Foo.java"); + File bar = File.create("src/Bar.java"); + when(sensorContext.getResource(foo)).thenReturn(foo); + when(sensorContext.getResource(bar)).thenReturn(bar); + + adaptor.store(new DefaultDependency() + .from(new DefaultInputFile("foo", "src/Foo.java").setType(Type.MAIN)) + .to(new DefaultInputFile("foo", "src/Bar.java").setType(Type.MAIN)) + .weight(3)); + + ArgumentCaptor<Dependency> argumentCaptor = ArgumentCaptor.forClass(Dependency.class); + + verify(sensorContext).saveDependency(argumentCaptor.capture()); + assertThat(argumentCaptor.getValue().getFrom()).isEqualTo(foo); + assertThat(argumentCaptor.getValue().getTo()).isEqualTo(bar); + assertThat(argumentCaptor.getValue().getWeight()).isEqualTo(3); + assertThat(argumentCaptor.getValue().getUsage()).isEqualTo("USES"); + } + + @Test + public void throw_if_attempt_to_save_same_dep_twice() { + + File foo = File.create("src/Foo.java"); + File bar = File.create("src/Bar.java"); + when(sensorContext.getResource(foo)).thenReturn(foo); + when(sensorContext.getResource(bar)).thenReturn(bar); + when(sonarIndex.getEdge(foo, bar)).thenReturn(new Dependency(foo, bar)); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Dependency between [moduleKey=foo, relative=src/Foo.java, abs=null] and [moduleKey=foo, relative=src/Bar.java, abs=null] was already saved."); + + adaptor.store(new DefaultDependency() + .from(new DefaultInputFile("foo", "src/Foo.java").setType(Type.MAIN)) + .to(new DefaultInputFile("foo", "src/Bar.java").setType(Type.MAIN)) + .weight(3)); + } + + @Test + public void shouldStoreDependencyInDifferentFolder() { + + File foo = File.create("src1/Foo.java"); + File bar = File.create("src2/Bar.java"); + when(sensorContext.getResource(foo)).thenReturn(foo); + when(sensorContext.getResource(bar)).thenReturn(bar); + + adaptor.store(new DefaultDependency() + .from(new DefaultInputFile("foo", "src1/Foo.java").setType(Type.MAIN)) + .to(new DefaultInputFile("foo", "src2/Bar.java").setType(Type.MAIN)) + .weight(3)); + + ArgumentCaptor<Dependency> argumentCaptor = ArgumentCaptor.forClass(Dependency.class); + + verify(sensorContext, times(2)).saveDependency(argumentCaptor.capture()); + assertThat(argumentCaptor.getAllValues()).hasSize(2); + Dependency value1 = argumentCaptor.getAllValues().get(0); + assertThat(value1.getFrom()).isEqualTo(Directory.create("src1")); + assertThat(value1.getTo()).isEqualTo(Directory.create("src2")); + assertThat(value1.getWeight()).isEqualTo(1); + assertThat(value1.getUsage()).isEqualTo("USES"); + + Dependency value2 = argumentCaptor.getAllValues().get(1); + assertThat(value2.getFrom()).isEqualTo(foo); + assertThat(value2.getTo()).isEqualTo(bar); + assertThat(value2.getWeight()).isEqualTo(3); + assertThat(value2.getUsage()).isEqualTo("USES"); + } + + @Test + public void shouldIncrementParentWeight() { + + File foo = File.create("src1/Foo.java"); + File bar = File.create("src2/Bar.java"); + Directory src1 = Directory.create("src1"); + Directory src2 = Directory.create("src2"); + when(sensorContext.getResource(foo)).thenReturn(foo); + when(sensorContext.getResource(bar)).thenReturn(bar); + Dependency parentDep = new Dependency(src1, src2).setWeight(4); + when(sonarIndex.getEdge(src1, src2)).thenReturn(parentDep); + + adaptor.store(new DefaultDependency() + .from(new DefaultInputFile("foo", "src1/Foo.java").setType(Type.MAIN)) + .to(new DefaultInputFile("foo", "src2/Bar.java").setType(Type.MAIN)) + .weight(3)); + + ArgumentCaptor<Dependency> argumentCaptor = ArgumentCaptor.forClass(Dependency.class); + + verify(sensorContext).saveDependency(argumentCaptor.capture()); + + assertThat(parentDep.getWeight()).isEqualTo(5); + + Dependency value = argumentCaptor.getValue(); + assertThat(value.getFrom()).isEqualTo(foo); + assertThat(value.getTo()).isEqualTo(bar); + assertThat(value.getWeight()).isEqualTo(3); + assertThat(value.getUsage()).isEqualTo("USES"); + } } |