@@ -28,7 +28,6 @@ import java.nio.charset.Charset; | |||
import java.nio.file.LinkOption; | |||
import java.nio.file.Path; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.Map; | |||
@@ -53,7 +52,6 @@ import org.sonar.api.utils.PathUtils; | |||
public class DefaultFileSystem implements FileSystem { | |||
private final Cache cache; | |||
private final SortedSet<String> languages = new TreeSet<>(); | |||
private final Path baseDir; | |||
private Path workDir; | |||
private Charset encoding; | |||
@@ -192,10 +190,6 @@ public class DefaultFileSystem implements FileSystem { | |||
public DefaultFileSystem add(InputFile inputFile) { | |||
cache.add(inputFile); | |||
String language = inputFile.language(); | |||
if (language != null) { | |||
languages.add(language); | |||
} | |||
return this; | |||
} | |||
@@ -204,20 +198,10 @@ public class DefaultFileSystem implements FileSystem { | |||
return this; | |||
} | |||
/** | |||
* Adds a language to the list. To be used only for unit tests that need to use {@link #languages()} without | |||
* using {@link #add(InputFile)}. | |||
*/ | |||
public DefaultFileSystem addLanguages(String language, String... others) { | |||
languages.add(language); | |||
Collections.addAll(languages, others); | |||
return this; | |||
} | |||
@Override | |||
public SortedSet<String> languages() { | |||
doPreloadFiles(); | |||
return languages; | |||
return cache.languages(); | |||
} | |||
@Override | |||
@@ -245,6 +229,8 @@ public class DefaultFileSystem implements FileSystem { | |||
public void add(InputDir inputDir) { | |||
doAdd(inputDir); | |||
} | |||
protected abstract SortedSet<String> languages(); | |||
} | |||
/** | |||
@@ -255,6 +241,7 @@ public class DefaultFileSystem implements FileSystem { | |||
private final Map<String, InputDir> dirMap = new HashMap<>(); | |||
private final SetMultimap<String, InputFile> filesByNameCache = LinkedHashMultimap.create(); | |||
private final SetMultimap<String, InputFile> filesByExtensionCache = LinkedHashMultimap.create(); | |||
private SortedSet<String> languages = new TreeSet<>(); | |||
@Override | |||
public Iterable<InputFile> inputFiles() { | |||
@@ -283,6 +270,9 @@ public class DefaultFileSystem implements FileSystem { | |||
@Override | |||
protected void doAdd(InputFile inputFile) { | |||
if (inputFile.language() != null) { | |||
languages.add(inputFile.language()); | |||
} | |||
fileMap.put(inputFile.relativePath(), inputFile); | |||
filesByNameCache.put(FilenamePredicate.getFilename(inputFile), inputFile); | |||
filesByExtensionCache.put(FileExtensionPredicate.getExtension(inputFile), inputFile); | |||
@@ -292,6 +282,11 @@ public class DefaultFileSystem implements FileSystem { | |||
protected void doAdd(InputDir inputDir) { | |||
dirMap.put(inputDir.relativePath(), inputDir); | |||
} | |||
@Override | |||
protected SortedSet<String> languages() { | |||
return languages; | |||
} | |||
} | |||
@Override |
@@ -19,12 +19,14 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import java.io.File; | |||
import java.io.StringReader; | |||
import java.nio.charset.Charset; | |||
import java.nio.file.Path; | |||
import java.nio.file.Paths; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.utils.PathUtils; | |||
@@ -143,4 +145,10 @@ public class TestInputFileBuilder { | |||
inputFile.setPublish(publish); | |||
return inputFile; | |||
} | |||
public static DefaultInputModule newDefaultInputModule(String moduleKey, File baseDir) { | |||
ProjectDefinition definition = ProjectDefinition.create().setKey(moduleKey); | |||
definition.setBaseDir(baseDir); | |||
return new DefaultInputModule(definition, TestInputFileBuilder.nextBatchId()); | |||
} | |||
} |
@@ -79,4 +79,9 @@ public interface SensorDescriptor { | |||
*/ | |||
SensorDescriptor requireProperties(String... propertyKeys); | |||
/** | |||
* This sensor should be executed at the project level, instead of per-module. | |||
* @since 6.4 | |||
*/ | |||
SensorDescriptor global(); | |||
} |
@@ -32,6 +32,7 @@ public class DefaultSensorDescriptor implements SensorDescriptor { | |||
private InputFile.Type type = null; | |||
private String[] ruleRepositories = new String[0]; | |||
private String[] properties = new String[0]; | |||
private boolean global = false; | |||
public String name() { | |||
return name; | |||
@@ -54,6 +55,10 @@ public class DefaultSensorDescriptor implements SensorDescriptor { | |||
return Arrays.asList(properties); | |||
} | |||
public boolean isGlobal() { | |||
return global; | |||
} | |||
@Override | |||
public DefaultSensorDescriptor name(String name) { | |||
this.name = name; | |||
@@ -99,4 +104,10 @@ public class DefaultSensorDescriptor implements SensorDescriptor { | |||
return this; | |||
} | |||
@Override | |||
public SensorDescriptor global() { | |||
this.global = true; | |||
return this; | |||
} | |||
} |
@@ -74,8 +74,10 @@ public class DefaultFileSystemTest { | |||
public void add_languages() { | |||
assertThat(fs.languages()).isEmpty(); | |||
fs.addLanguages("java", "php", "cobol"); | |||
assertThat(fs.languages()).containsOnly("cobol", "java", "php"); | |||
fs.add(new TestInputFileBuilder("foo", "src/Foo.php").setLanguage("php").build()); | |||
fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); | |||
assertThat(fs.languages()).containsOnly("java", "php"); | |||
} | |||
@Test |
@@ -26,6 +26,7 @@ import java.lang.reflect.Modifier; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collection; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.stream.Collectors; | |||
@@ -78,6 +79,25 @@ public class ScannerExtensionDictionnary { | |||
return result; | |||
} | |||
public Collection<org.sonar.api.batch.Sensor> selectSensors(@Nullable DefaultInputModule module, boolean global) { | |||
List<org.sonar.api.batch.Sensor> result = getFilteredExtensions(org.sonar.api.batch.Sensor.class, module, null); | |||
Iterator<org.sonar.api.batch.Sensor> iterator = result.iterator(); | |||
while (iterator.hasNext()) { | |||
org.sonar.api.batch.Sensor sensor = iterator.next(); | |||
if (sensor instanceof SensorWrapper) { | |||
if (global != ((SensorWrapper) sensor).isGlobal()) { | |||
iterator.remove(); | |||
} | |||
} else if (global) { | |||
// only old sensors are not wrapped, and old sensors are never global -> exclude | |||
iterator.remove(); | |||
} | |||
} | |||
return sort(result); | |||
} | |||
private static Phase.Name evaluatePhase(Object extension) { | |||
Object extensionToEvaluate; | |||
if (extension instanceof SensorWrapper) { |
@@ -52,7 +52,8 @@ public class DeprecatedCpdBlockIndexerSensor implements Sensor { | |||
@Override | |||
public void describe(SensorDescriptor descriptor) { | |||
descriptor.name("CPD Block Indexer"); | |||
descriptor.name("CPD Block Indexer") | |||
.global(); | |||
} | |||
@VisibleForTesting | |||
@@ -65,7 +66,6 @@ public class DeprecatedCpdBlockIndexerSensor implements Sensor { | |||
@Override | |||
public void execute(SensorContext context) { | |||
for (String language : fs.languages()) { | |||
CpdBlockIndexer blockIndexer = getBlockIndexer(language); | |||
if (!blockIndexer.isLanguageSupported(language)) { |
@@ -20,6 +20,9 @@ | |||
package org.sonar.scanner.phases; | |||
import com.google.common.collect.Lists; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import org.sonar.api.batch.ScannerSide; | |||
import org.sonar.api.batch.Sensor; | |||
import org.sonar.api.batch.SensorContext; | |||
@@ -27,29 +30,56 @@ import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.scanner.bootstrap.ScannerExtensionDictionnary; | |||
import org.sonar.scanner.events.EventBus; | |||
import java.util.Collection; | |||
import org.sonar.scanner.sensor.SensorStrategy; | |||
@ScannerSide | |||
public class SensorsExecutor { | |||
private final EventBus eventBus; | |||
private final DefaultInputModule module; | |||
private final ScannerExtensionDictionnary selector; | |||
private final DefaultInputModule module; | |||
private final EventBus eventBus; | |||
private final SensorStrategy strategy; | |||
private final boolean isRoot; | |||
public SensorsExecutor(ScannerExtensionDictionnary selector, DefaultInputModule module, EventBus eventBus) { | |||
public SensorsExecutor(ScannerExtensionDictionnary selector, DefaultInputModule module, EventBus eventBus, SensorStrategy strategy) { | |||
this.selector = selector; | |||
this.eventBus = eventBus; | |||
this.module = module; | |||
this.eventBus = eventBus; | |||
this.strategy = strategy; | |||
this.isRoot = module.definition().getParent() == null; | |||
} | |||
public void execute(SensorContext context) { | |||
Collection<Sensor> sensors = selector.select(Sensor.class, module, true, null); | |||
eventBus.fireEvent(new SensorsPhaseEvent(Lists.newArrayList(sensors), true)); | |||
Collection<Sensor> perModuleSensors = selector.selectSensors(module, false); | |||
Collection<Sensor> globalSensors; | |||
if (isRoot) { | |||
boolean orig = strategy.isGlobal(); | |||
strategy.setGlobal(true); | |||
globalSensors = selector.selectSensors(module, true); | |||
strategy.setGlobal(orig); | |||
} else { | |||
globalSensors = Collections.emptyList(); | |||
} | |||
Collection<Sensor> allSensors = new ArrayList<>(perModuleSensors); | |||
allSensors.addAll(globalSensors); | |||
eventBus.fireEvent(new SensorsPhaseEvent(Lists.newArrayList(allSensors), true)); | |||
execute(context, perModuleSensors); | |||
if (isRoot) { | |||
boolean orig = strategy.isGlobal(); | |||
strategy.setGlobal(true); | |||
execute(context, globalSensors); | |||
strategy.setGlobal(orig); | |||
} | |||
eventBus.fireEvent(new SensorsPhaseEvent(Lists.newArrayList(allSensors), false)); | |||
} | |||
private void execute(SensorContext context, Collection<Sensor> sensors) { | |||
for (Sensor sensor : sensors) { | |||
executeSensor(context, sensor); | |||
} | |||
eventBus.fireEvent(new SensorsPhaseEvent(Lists.newArrayList(sensors), false)); | |||
} | |||
private void executeSensor(SensorContext context, Sensor sensor) { |
@@ -70,6 +70,7 @@ import org.sonar.scanner.scan.filesystem.StatusDetectionFactory; | |||
import org.sonar.scanner.scan.report.IssuesReports; | |||
import org.sonar.scanner.sensor.DefaultSensorStorage; | |||
import org.sonar.scanner.sensor.SensorOptimizer; | |||
import org.sonar.scanner.sensor.SensorStrategy; | |||
import org.sonar.scanner.sensor.coverage.CoverageExclusions; | |||
import org.sonar.scanner.source.HighlightableBuilder; | |||
import org.sonar.scanner.source.SymbolizableBuilder; | |||
@@ -137,6 +138,8 @@ public class ModuleScanContainer extends ComponentContainer { | |||
IssueFilters.class, | |||
CoverageExclusions.class, | |||
SensorStrategy.class, | |||
// rules | |||
new RulesProfileProvider(), | |||
CheckFactory.class, |
@@ -245,6 +245,7 @@ public class ProjectScanContainer extends ComponentContainer { | |||
LOG.debug("Start recursive analysis of project modules"); | |||
scanRecursively(tree, tree.root()); | |||
if (analysisMode.isMediumTest()) { | |||
getComponentByType(ScanTaskObservers.class).notifyEndOfScanTask(); | |||
} |
@@ -19,14 +19,19 @@ | |||
*/ | |||
package org.sonar.scanner.scan.filesystem; | |||
import com.google.common.base.Preconditions; | |||
import com.google.common.collect.LinkedHashMultimap; | |||
import com.google.common.collect.SetMultimap; | |||
import com.google.common.collect.Table; | |||
import com.google.common.collect.TreeBasedTable; | |||
import java.nio.file.Path; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.SortedSet; | |||
import java.util.TreeSet; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.api.batch.ScannerSide; | |||
import org.sonar.api.batch.fs.InputComponent; | |||
import org.sonar.api.batch.fs.InputDir; | |||
@@ -34,11 +39,10 @@ import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.InputModule; | |||
import org.sonar.api.batch.fs.internal.DefaultInputDir; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import com.google.common.collect.Table; | |||
import com.google.common.collect.TreeBasedTable; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.FileExtensionPredicate; | |||
import org.sonar.api.batch.fs.internal.FilenamePredicate; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
/** | |||
* Store of all files and dirs. This cache is shared amongst all project modules. Inclusion and | |||
@@ -47,7 +51,12 @@ import org.sonar.api.batch.fs.internal.FilenamePredicate; | |||
@ScannerSide | |||
public class InputComponentStore { | |||
private final PathResolver pathResolver; | |||
private final SortedSet<String> globalLanguagesCache = new TreeSet<>(); | |||
private final Map<String, SortedSet<String>> languagesCache = new HashMap<>(); | |||
private final Map<String, InputFile> globalInputFileCache = new HashMap<>(); | |||
private final Table<String, String, InputFile> inputFileCache = TreeBasedTable.create(); | |||
private final Map<String, InputDir> globalInputDirCache = new HashMap<>(); | |||
private final Table<String, String, InputDir> inputDirCache = TreeBasedTable.create(); | |||
private final Map<String, InputModule> inputModuleCache = new HashMap<>(); | |||
private final Map<String, InputComponent> inputComponents = new HashMap<>(); | |||
@@ -55,6 +64,10 @@ public class InputComponentStore { | |||
private final SetMultimap<String, InputFile> filesByExtensionCache = LinkedHashMultimap.create(); | |||
private InputModule root; | |||
public InputComponentStore(PathResolver pathResolver) { | |||
this.pathResolver = pathResolver; | |||
} | |||
public Collection<InputComponent> all() { | |||
return inputComponents.values(); | |||
} | |||
@@ -77,10 +90,6 @@ public class InputComponentStore { | |||
return inputComponents.get(key); | |||
} | |||
public void setRoot(InputModule root) { | |||
this.root = root; | |||
} | |||
@CheckForNull | |||
public InputModule root() { | |||
return root; | |||
@@ -114,38 +123,79 @@ public class InputComponentStore { | |||
public InputComponentStore put(InputFile inputFile) { | |||
DefaultInputFile file = (DefaultInputFile) inputFile; | |||
addToLanguageCache(file); | |||
inputFileCache.put(file.moduleKey(), inputFile.relativePath(), inputFile); | |||
globalInputFileCache.put(getProjectRelativePath(file), inputFile); | |||
inputComponents.put(inputFile.key(), inputFile); | |||
filesByNameCache.put(FilenamePredicate.getFilename(inputFile), inputFile); | |||
filesByExtensionCache.put(FileExtensionPredicate.getExtension(inputFile), inputFile); | |||
return this; | |||
} | |||
private void addToLanguageCache(DefaultInputFile inputFile) { | |||
String language = inputFile.language(); | |||
if (language != null) { | |||
globalLanguagesCache.add(language); | |||
languagesCache.computeIfAbsent(inputFile.moduleKey(), k -> new TreeSet<>()).add(language); | |||
} | |||
} | |||
public InputComponentStore put(InputDir inputDir) { | |||
DefaultInputDir dir = (DefaultInputDir) inputDir; | |||
inputDirCache.put(dir.moduleKey(), inputDir.relativePath(), inputDir); | |||
globalInputDirCache.put(getProjectRelativePath(dir), inputDir); | |||
inputComponents.put(inputDir.key(), inputDir); | |||
return this; | |||
} | |||
private String getProjectRelativePath(DefaultInputFile file) { | |||
return pathResolver.relativePath(getProjectBaseDir(), file.path()); | |||
} | |||
private String getProjectRelativePath(DefaultInputDir dir) { | |||
return pathResolver.relativePath(getProjectBaseDir(), dir.path()); | |||
} | |||
private Path getProjectBaseDir() { | |||
return ((DefaultInputModule) root).definition().getBaseDir().toPath(); | |||
} | |||
@CheckForNull | |||
public InputFile getFile(String moduleKey, String relativePath) { | |||
return inputFileCache.get(moduleKey, relativePath); | |||
} | |||
@CheckForNull | |||
public InputFile getFile(String relativePath) { | |||
return globalInputFileCache.get(relativePath); | |||
} | |||
@CheckForNull | |||
public InputDir getDir(String moduleKey, String relativePath) { | |||
return inputDirCache.get(moduleKey, relativePath); | |||
} | |||
@CheckForNull | |||
public InputDir getDir(String relativePath) { | |||
return globalInputDirCache.get(relativePath); | |||
} | |||
@CheckForNull | |||
public InputModule getModule(String moduleKey) { | |||
return inputModuleCache.get(moduleKey); | |||
} | |||
public void put(InputModule inputModule) { | |||
public void put(DefaultInputModule inputModule) { | |||
Preconditions.checkState(!inputComponents.containsKey(inputModule.key()), "Module '%s' already indexed", inputModule.key()); | |||
Preconditions.checkState(!inputModuleCache.containsKey(inputModule.key()), "Module '%s' already indexed", inputModule.key()); | |||
inputComponents.put(inputModule.key(), inputModule); | |||
inputModuleCache.put(inputModule.key(), inputModule); | |||
if (inputModule.definition().getParent() == null) { | |||
if (root != null) { | |||
throw new IllegalStateException("Root module already indexed: '" + root.key() + "', '" + inputModule.key() + "'"); | |||
} | |||
root = inputModule; | |||
} | |||
} | |||
public Iterable<InputFile> getFilesByName(String filename) { | |||
@@ -155,4 +205,12 @@ public class InputComponentStore { | |||
public Iterable<InputFile> getFilesByExtension(String extension) { | |||
return filesByExtensionCache.get(extension); | |||
} | |||
public SortedSet<String> getLanguages() { | |||
return globalLanguagesCache; | |||
} | |||
public SortedSet<String> getLanguages(String moduleKey) { | |||
return languagesCache.getOrDefault(moduleKey, Collections.emptySortedSet()); | |||
} | |||
} |
@@ -19,36 +19,61 @@ | |||
*/ | |||
package org.sonar.scanner.scan.filesystem; | |||
import java.util.SortedSet; | |||
import org.sonar.api.batch.ScannerSide; | |||
import org.sonar.api.batch.fs.InputDir; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.InputModule; | |||
import org.sonar.api.batch.fs.internal.DefaultFileSystem; | |||
import org.sonar.scanner.sensor.SensorStrategy; | |||
@ScannerSide | |||
public class ModuleInputComponentStore extends DefaultFileSystem.Cache { | |||
private final String moduleKey; | |||
private final InputComponentStore inputComponentStore; | |||
private final SensorStrategy strategy; | |||
public ModuleInputComponentStore(InputModule module, InputComponentStore inputComponentStore) { | |||
public ModuleInputComponentStore(InputModule module, InputComponentStore inputComponentStore, SensorStrategy strategy) { | |||
this.moduleKey = module.key(); | |||
this.inputComponentStore = inputComponentStore; | |||
this.strategy = strategy; | |||
} | |||
@Override | |||
public Iterable<InputFile> inputFiles() { | |||
return inputComponentStore.filesByModule(moduleKey); | |||
if (strategy.isGlobal()) { | |||
return inputComponentStore.allFiles(); | |||
} else { | |||
return inputComponentStore.filesByModule(moduleKey); | |||
} | |||
} | |||
@Override | |||
public InputFile inputFile(String relativePath) { | |||
return inputComponentStore.getFile(moduleKey, relativePath); | |||
if (strategy.isGlobal()) { | |||
return inputComponentStore.getFile(relativePath); | |||
} else { | |||
return inputComponentStore.getFile(moduleKey, relativePath); | |||
} | |||
} | |||
@Override | |||
public InputDir inputDir(String relativePath) { | |||
return inputComponentStore.getDir(moduleKey, relativePath); | |||
if (strategy.isGlobal()) { | |||
return inputComponentStore.getDir(relativePath); | |||
} else { | |||
return inputComponentStore.getDir(moduleKey, relativePath); | |||
} | |||
} | |||
@Override | |||
public SortedSet<String> languages() { | |||
if (strategy.isGlobal()) { | |||
return inputComponentStore.getLanguages(); | |||
} else { | |||
return inputComponentStore.getLanguages(moduleKey); | |||
} | |||
} | |||
@Override |
@@ -0,0 +1,38 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 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.scanner.sensor; | |||
/** | |||
* A shared, mutable object in the module container. | |||
* It's used during the execution of sensors to decide whether | |||
* sensors should be executed once for the entire project, or per-module. | |||
*/ | |||
public class SensorStrategy { | |||
private boolean global = false; | |||
public boolean isGlobal() { | |||
return global; | |||
} | |||
public void setGlobal(boolean global) { | |||
this.global = global; | |||
} | |||
} |
@@ -61,4 +61,8 @@ public class SensorWrapper implements org.sonar.api.batch.Sensor { | |||
return wrappedSensor.getClass().getName(); | |||
} | |||
} | |||
public boolean isGlobal() { | |||
return descriptor.isGlobal(); | |||
} | |||
} |
@@ -42,7 +42,8 @@ public final class CodeColorizerSensor implements Sensor { | |||
@Override | |||
public void describe(SensorDescriptor descriptor) { | |||
descriptor.name("Code Colorizer Sensor"); | |||
descriptor.name("Code Colorizer Sensor") | |||
.global(); | |||
} | |||
@Override |
@@ -70,7 +70,8 @@ public final class ZeroCoverageSensor implements Sensor { | |||
@Override | |||
public void describe(SensorDescriptor descriptor) { | |||
descriptor.name("Zero Coverage Sensor"); | |||
descriptor.name("Zero Coverage Sensor") | |||
.global(); | |||
} | |||
@Override |
@@ -36,13 +36,13 @@ import org.sonar.api.batch.Sensor; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.postjob.PostJobContext; | |||
import org.sonar.api.batch.sensor.SensorDescriptor; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.core.platform.ComponentContainer; | |||
import org.sonar.scanner.bootstrap.ScannerExtensionDictionnary; | |||
import org.sonar.scanner.bootstrap.ExtensionMatcher; | |||
import org.sonar.scanner.postjob.PostJobOptimizer; | |||
import org.sonar.scanner.sensor.DefaultSensorContext; | |||
import org.sonar.scanner.sensor.SensorOptimizer; | |||
import org.sonar.scanner.sensor.SensorWrapper; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.junit.Assert.assertEquals; | |||
@@ -301,10 +301,7 @@ public class ScannerExtensionDictionnaryTest { | |||
ScannerExtensionDictionnary selector = newSelector(analyze, post, pre); | |||
List extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null)); | |||
assertThat(extensions).hasSize(3); | |||
assertThat(extensions.get(0)).isEqualTo(pre); | |||
assertThat(extensions.get(1)).isEqualTo(analyze); | |||
assertThat(extensions.get(2)).isEqualTo(post); | |||
assertThat(extensions).containsExactly(pre, analyze, post); | |||
} | |||
@Test | |||
@@ -321,6 +318,30 @@ public class ScannerExtensionDictionnaryTest { | |||
assertThat(extensions.get(2)).isEqualTo(checker); | |||
} | |||
@Test | |||
public void querySensors() { | |||
BatchExtension pre = new PreSensorSubclass(); | |||
BatchExtension analyze = new GeneratesSomething("something"); | |||
BatchExtension post = new PostSensorSubclass(); | |||
FakeSensor fakeSensor = new FakeSensor(); | |||
FakeNewSensor fakeNewSensor = new FakeNewSensor(); | |||
FakeNewGlobalSensor fakeNewGlobalSensor = new FakeNewGlobalSensor(); | |||
ScannerExtensionDictionnary selector = newSelector(fakeSensor, fakeNewSensor, fakeNewGlobalSensor); | |||
List extensions = Lists.newArrayList(selector.selectSensors(null, false)); | |||
assertThat(extensions).hasSize(2); | |||
assertThat(extensions).contains(fakeSensor); | |||
extensions.remove(fakeSensor); | |||
assertThat(extensions.get(0)).isInstanceOf(SensorWrapper.class); | |||
assertThat(((SensorWrapper) extensions.get(0)).wrappedSensor()).isEqualTo(fakeNewSensor); | |||
extensions = Lists.newArrayList(selector.selectSensors(null, true)); | |||
assertThat(extensions.get(0)).isInstanceOf(SensorWrapper.class); | |||
assertThat(((SensorWrapper) extensions.get(0)).wrappedSensor()).isEqualTo(fakeNewGlobalSensor); | |||
} | |||
class FakeSensor implements Sensor { | |||
public void analyse(Project project, SensorContext context) { | |||
@@ -332,6 +353,31 @@ public class ScannerExtensionDictionnaryTest { | |||
} | |||
} | |||
class FakeNewSensor implements org.sonar.api.batch.sensor.Sensor { | |||
@Override | |||
public void describe(SensorDescriptor descriptor) { | |||
} | |||
@Override | |||
public void execute(org.sonar.api.batch.sensor.SensorContext context) { | |||
} | |||
} | |||
class FakeNewGlobalSensor implements org.sonar.api.batch.sensor.Sensor { | |||
@Override | |||
public void describe(SensorDescriptor descriptor) { | |||
descriptor.global(); | |||
} | |||
@Override | |||
public void execute(org.sonar.api.batch.sensor.SensorContext context) { | |||
} | |||
} | |||
class MethodDependentOf implements BatchExtension { | |||
private Object dep; | |||
@@ -32,10 +32,10 @@ import org.junit.rules.ExpectedException; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.api.config.MapSettings; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
import org.sonar.api.utils.log.LogTester; | |||
import org.sonar.api.utils.log.LoggerLevel; | |||
import org.sonar.core.util.CloseableIterator; | |||
@@ -86,11 +86,11 @@ public class CpdExecutorTest { | |||
publisher = mock(ReportPublisher.class); | |||
when(publisher.getWriter()).thenReturn(new ScannerReportWriter(outputDir)); | |||
index = new SonarCpdBlockIndex(publisher, settings); | |||
componentStore = new InputComponentStore(); | |||
componentStore = new InputComponentStore(new PathResolver()); | |||
executor = new CpdExecutor(settings, index, publisher, componentStore); | |||
reader = new ScannerReportReader(outputDir); | |||
componentStore.put(new DefaultInputModule("foo")); | |||
componentStore.put(TestInputFileBuilder.newDefaultInputModule("foo", baseDir)); | |||
batchComponent1 = createComponent("src/Foo.php", 5); | |||
batchComponent2 = createComponent("src/Foo2.php", 5); |
@@ -19,15 +19,19 @@ | |||
*/ | |||
package org.sonar.scanner.postjob; | |||
import java.io.IOException; | |||
import java.util.Arrays; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.AnalysisMode; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.api.batch.postjob.issue.PostJobIssue; | |||
import org.sonar.api.batch.rule.Severity; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.config.MapSettings; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
import org.sonar.scanner.issue.IssueCache; | |||
import org.sonar.scanner.issue.tracking.TrackedIssue; | |||
import org.sonar.scanner.scan.filesystem.InputComponentStore; | |||
@@ -38,6 +42,9 @@ import static org.mockito.Mockito.when; | |||
public class DefaultPostJobContextTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
private IssueCache issueCache; | |||
private InputComponentStore componentStore; | |||
private DefaultPostJobContext context; | |||
@@ -47,14 +54,14 @@ public class DefaultPostJobContextTest { | |||
@Before | |||
public void prepare() { | |||
issueCache = mock(IssueCache.class); | |||
componentStore = new InputComponentStore(); | |||
componentStore = new InputComponentStore(new PathResolver()); | |||
settings = new MapSettings(); | |||
analysisMode = mock(AnalysisMode.class); | |||
context = new DefaultPostJobContext(settings, issueCache, componentStore, analysisMode); | |||
} | |||
@Test | |||
public void testIssues() { | |||
public void testIssues() throws IOException { | |||
when(analysisMode.isIssues()).thenReturn(true); | |||
assertThat(context.settings()).isSameAs(settings); | |||
@@ -78,7 +85,10 @@ public class DefaultPostJobContextTest { | |||
assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); | |||
assertThat(issue.inputComponent()).isNull(); | |||
componentStore.put(new TestInputFileBuilder("foo", "src/Foo.php").build()); | |||
String moduleKey = "foo"; | |||
componentStore.put(TestInputFileBuilder.newDefaultInputModule("foo", temp.newFolder())); | |||
componentStore.put(new TestInputFileBuilder(moduleKey, "src/Foo.php").build()); | |||
assertThat(issue.inputComponent()).isNotNull(); | |||
} |
@@ -20,15 +20,16 @@ | |||
package org.sonar.scanner.report; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
import org.sonar.core.util.CloseableIterator; | |||
import org.sonar.scanner.protocol.output.ScannerReport.LineCoverage; | |||
import org.sonar.scanner.protocol.output.ScannerReportReader; | |||
@@ -49,14 +50,14 @@ public class CoveragePublisherTest { | |||
private MeasureCache measureCache; | |||
private CoveragePublisher publisher; | |||
private InputComponentStore componentCache; | |||
private DefaultInputFile inputFile; | |||
@Before | |||
public void prepare() { | |||
inputFile = new TestInputFileBuilder("foo", "src/Foo.php").setLines(5).build(); | |||
componentCache = new InputComponentStore(); | |||
componentCache.put(new DefaultInputModule("foo")); | |||
public void prepare() throws IOException { | |||
String moduleKey = "foo"; | |||
inputFile = new TestInputFileBuilder(moduleKey, "src/Foo.php").setLines(5).build(); | |||
InputComponentStore componentCache = new InputComponentStore(new PathResolver()); | |||
componentCache.put(TestInputFileBuilder.newDefaultInputModule(moduleKey, temp.newFolder())); | |||
componentCache.put(inputFile); | |||
measureCache = mock(MeasureCache.class); |
@@ -33,6 +33,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
import org.sonar.core.util.CloseableIterator; | |||
import org.sonar.scanner.deprecated.test.TestPlanBuilder; | |||
import org.sonar.scanner.protocol.output.ScannerReport; | |||
@@ -58,18 +59,18 @@ public class MeasuresPublisherTest { | |||
private MeasureCache measureCache; | |||
private MeasuresPublisher publisher; | |||
private InputComponentStore componentCache; | |||
private File outputDir; | |||
private ScannerReportWriter writer; | |||
private DefaultInputFile inputFile; | |||
private DefaultInputModule InputModule; | |||
private DefaultInputModule inputModule; | |||
@Before | |||
public void prepare() throws IOException { | |||
InputModule = new DefaultInputModule("foo"); | |||
inputFile = new TestInputFileBuilder("foo", "src/Foo.php").setPublish(true).build(); | |||
componentCache = new InputComponentStore(); | |||
componentCache.put(InputModule); | |||
String moduleKey = "foo"; | |||
inputModule = TestInputFileBuilder.newDefaultInputModule(moduleKey, temp.newFolder()); | |||
inputFile = new TestInputFileBuilder(moduleKey, "src/Foo.php").setPublish(true).build(); | |||
InputComponentStore componentCache = new InputComponentStore(new PathResolver()); | |||
componentCache.put(inputModule); | |||
componentCache.put(inputFile); | |||
measureCache = mock(MeasureCache.class); | |||
when(measureCache.byComponentKey(anyString())).thenReturn(Collections.<DefaultMeasure<?>>emptyList()); | |||
@@ -90,7 +91,7 @@ public class MeasuresPublisherTest { | |||
publisher.publish(writer); | |||
ScannerReportReader reader = new ScannerReportReader(outputDir); | |||
assertThat(reader.readComponentMeasures(InputModule.batchId())).hasSize(0); | |||
assertThat(reader.readComponentMeasures(inputModule.batchId())).hasSize(0); | |||
try (CloseableIterator<ScannerReport.Measure> componentMeasures = reader.readComponentMeasures(inputFile.batchId())) { | |||
assertThat(componentMeasures).hasSize(2); | |||
} |
@@ -28,10 +28,9 @@ import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
import org.sonar.scanner.protocol.output.ScannerReportWriter; | |||
import org.sonar.scanner.report.SourcePublisher; | |||
import org.sonar.scanner.scan.filesystem.InputComponentStore; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -44,20 +43,22 @@ public class SourcePublisherTest { | |||
private File sourceFile; | |||
private ScannerReportWriter writer; | |||
private DefaultInputFile inputFile; | |||
private InputComponentStore componentStore; | |||
@Before | |||
public void prepare() throws IOException { | |||
File baseDir = temp.newFolder(); | |||
sourceFile = new File(baseDir, "src/Foo.php"); | |||
inputFile = new TestInputFileBuilder("foo", "src/Foo.php") | |||
String moduleKey = "foo"; | |||
inputFile = new TestInputFileBuilder(moduleKey, "src/Foo.php") | |||
.setLines(5) | |||
.setModuleBaseDir(baseDir.toPath()) | |||
.setCharset(StandardCharsets.ISO_8859_1) | |||
.build(); | |||
componentStore = new InputComponentStore(); | |||
componentStore.put(new DefaultInputModule("foo")); | |||
InputComponentStore componentStore = new InputComponentStore(new PathResolver()); | |||
componentStore.put(TestInputFileBuilder.newDefaultInputModule(moduleKey, baseDir)); | |||
componentStore.put(inputFile); | |||
publisher = new SourcePublisher(componentStore); | |||
File outputDir = temp.newFolder(); | |||
writer = new ScannerReportWriter(outputDir); |
@@ -26,6 +26,7 @@ import org.junit.rules.ExpectedException; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.slf4j.Logger; | |||
import org.sonar.api.batch.fs.internal.DefaultFileSystem; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.config.MapSettings; | |||
import org.sonar.api.utils.MessageException; | |||
@@ -58,7 +59,9 @@ public class QProfileVerifierTest { | |||
@Test | |||
public void should_log_all_used_profiles() { | |||
fs.addLanguages("java", "cobol"); | |||
fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); | |||
fs.add(new TestInputFileBuilder("foo", "src/Baz.cbl").setLanguage("cobol").build()); | |||
QProfileVerifier profileLogger = new QProfileVerifier(settings, fs, profiles); | |||
Logger logger = mock(Logger.class); | |||
profileLogger.execute(logger); | |||
@@ -69,7 +72,8 @@ public class QProfileVerifierTest { | |||
@Test | |||
public void should_fail_if_default_profile_not_used() { | |||
fs.addLanguages("java", "cobol"); | |||
fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); | |||
settings.setProperty("sonar.profile", "Unknown"); | |||
QProfileVerifier profileLogger = new QProfileVerifier(settings, fs, profiles); | |||
@@ -92,7 +96,8 @@ public class QProfileVerifierTest { | |||
@Test | |||
public void should_not_fail_if_default_profile_used_at_least_once() { | |||
fs.addLanguages("java", "cobol"); | |||
fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); | |||
settings.setProperty("sonar.profile", "My Java profile"); | |||
QProfileVerifier profileLogger = new QProfileVerifier(settings, fs, profiles); |
@@ -19,17 +19,18 @@ | |||
*/ | |||
package org.sonar.scanner.scan; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.fs.InputModule; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
import org.sonar.scanner.scan.filesystem.BatchIdGenerator; | |||
import org.sonar.scanner.scan.filesystem.InputComponentStore; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public class ModuleIndexerTest { | |||
private ModuleIndexer indexer; | |||
private DefaultComponentTree tree; | |||
@@ -40,7 +41,7 @@ public class ModuleIndexerTest { | |||
@Before | |||
public void setUp() { | |||
reactor = mock(ImmutableProjectReactor.class); | |||
componentStore = new InputComponentStore(); | |||
componentStore = new InputComponentStore(new PathResolver()); | |||
tree = new DefaultComponentTree(); | |||
moduleHierarchy = new DefaultInputModuleHierarchy(); | |||
indexer = new ModuleIndexer(reactor, tree, componentStore, new BatchIdGenerator(), moduleHierarchy); |
@@ -19,12 +19,10 @@ | |||
*/ | |||
package org.sonar.scanner.scan.filesystem; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import java.io.File; | |||
import java.nio.charset.StandardCharsets; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
@@ -33,7 +31,11 @@ import org.sonar.api.batch.fs.InputFile.Status; | |||
import org.sonar.api.batch.fs.InputFile.Type; | |||
import org.sonar.api.batch.fs.InputPath; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class InputComponentStoreTest { | |||
@Rule | |||
@@ -41,13 +43,24 @@ public class InputComponentStoreTest { | |||
@Test | |||
public void should_add_input_file() throws Exception { | |||
InputComponentStore cache = new InputComponentStore(); | |||
DefaultInputFile fooFile = new TestInputFileBuilder("struts", "src/main/java/Foo.java") | |||
.setModuleBaseDir(temp.newFolder().toPath()) | |||
InputComponentStore cache = new InputComponentStore(new PathResolver()); | |||
String rootModuleKey = "struts"; | |||
File rootBaseDir = temp.newFolder(); | |||
DefaultInputModule rootModule = TestInputFileBuilder.newDefaultInputModule(rootModuleKey, rootBaseDir); | |||
cache.put(rootModule); | |||
String subModuleKey = "struts-core"; | |||
DefaultInputModule subModule = TestInputFileBuilder.newDefaultInputModule(subModuleKey, temp.newFolder()); | |||
rootModule.definition().addSubProject(subModule.definition()); | |||
cache.put(subModule); | |||
DefaultInputFile fooFile = new TestInputFileBuilder(rootModuleKey, "src/main/java/Foo.java") | |||
.setModuleBaseDir(rootBaseDir.toPath()) | |||
.setPublish(true) | |||
.build(); | |||
cache.put(fooFile); | |||
cache.put(new TestInputFileBuilder("struts-core", "src/main/java/Bar.java") | |||
cache.put(new TestInputFileBuilder(subModuleKey, "src/main/java/Bar.java") | |||
.setLanguage("bla") | |||
.setPublish(false) | |||
.setType(Type.MAIN) | |||
@@ -57,12 +70,12 @@ public class InputComponentStoreTest { | |||
.setModuleBaseDir(temp.newFolder().toPath()) | |||
.build()); | |||
DefaultInputFile loadedFile = (DefaultInputFile) cache.getFile("struts-core", "src/main/java/Bar.java"); | |||
DefaultInputFile loadedFile = (DefaultInputFile) cache.getFile(subModuleKey, "src/main/java/Bar.java"); | |||
assertThat(loadedFile.relativePath()).isEqualTo("src/main/java/Bar.java"); | |||
assertThat(loadedFile.charset()).isEqualTo(StandardCharsets.UTF_8); | |||
assertThat(cache.filesByModule("struts")).hasSize(1); | |||
assertThat(cache.filesByModule("struts-core")).hasSize(1); | |||
assertThat(cache.filesByModule(rootModuleKey)).hasSize(1); | |||
assertThat(cache.filesByModule(subModuleKey)).hasSize(1); | |||
assertThat(cache.allFiles()).hasSize(2); | |||
for (InputPath inputPath : cache.allFiles()) { | |||
assertThat(inputPath.relativePath()).startsWith("src/main/java/"); | |||
@@ -75,9 +88,9 @@ public class InputComponentStoreTest { | |||
cache.remove(fooFile); | |||
assertThat(cache.allFiles()).hasSize(1); | |||
cache.removeModule("struts"); | |||
assertThat(cache.filesByModule("struts")).hasSize(0); | |||
assertThat(cache.filesByModule("struts-core")).hasSize(1); | |||
cache.removeModule(rootModuleKey); | |||
assertThat(cache.filesByModule(rootModuleKey)).hasSize(0); | |||
assertThat(cache.filesByModule(subModuleKey)).hasSize(1); | |||
assertThat(cache.allFiles()).hasSize(1); | |||
} | |||
@@ -20,21 +20,38 @@ | |||
package org.sonar.scanner.scan.filesystem; | |||
import java.io.IOException; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.InputModule; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
import org.sonar.scanner.sensor.SensorStrategy; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
public class ModuleInputComponentStoreTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
private InputComponentStore componentStore; | |||
private final String moduleKey = "dummy key"; | |||
@Before | |||
public void setUp() throws IOException { | |||
componentStore = new InputComponentStore(new PathResolver()); | |||
componentStore.put(TestInputFileBuilder.newDefaultInputModule(moduleKey, temp.newFolder())); | |||
} | |||
@Test | |||
public void should_cache_files_by_filename() throws IOException { | |||
ModuleInputComponentStore store = new ModuleInputComponentStore(mock(InputModule.class), new InputComponentStore()); | |||
ModuleInputComponentStore store = newModuleInputComponentStore(); | |||
String filename = "some name"; | |||
String moduleKey = "dummy key"; | |||
InputFile inputFile1 = new TestInputFileBuilder(moduleKey, "some/path/" + filename).build(); | |||
store.doAdd(inputFile1); | |||
@@ -49,9 +66,8 @@ public class ModuleInputComponentStoreTest { | |||
@Test | |||
public void should_cache_files_by_extension() throws IOException { | |||
ModuleInputComponentStore store = new ModuleInputComponentStore(mock(InputModule.class), new InputComponentStore()); | |||
ModuleInputComponentStore store = newModuleInputComponentStore(); | |||
String moduleKey = "dummy key"; | |||
InputFile inputFile1 = new TestInputFileBuilder(moduleKey, "some/path/Program.java").build(); | |||
store.doAdd(inputFile1); | |||
@@ -66,11 +82,11 @@ public class ModuleInputComponentStoreTest { | |||
@Test | |||
public void should_not_cache_duplicates() throws IOException { | |||
ModuleInputComponentStore store = new ModuleInputComponentStore(mock(InputModule.class), new InputComponentStore()); | |||
ModuleInputComponentStore store = newModuleInputComponentStore(); | |||
String ext = "java"; | |||
String filename = "Program." + ext; | |||
InputFile inputFile = new TestInputFileBuilder("dummy key", "some/path/" + filename).build(); | |||
InputFile inputFile = new TestInputFileBuilder(moduleKey, "some/path/" + filename).build(); | |||
store.doAdd(inputFile); | |||
store.doAdd(inputFile); | |||
store.doAdd(inputFile); | |||
@@ -81,14 +97,18 @@ public class ModuleInputComponentStoreTest { | |||
@Test | |||
public void should_get_empty_iterable_on_cache_miss() { | |||
ModuleInputComponentStore store = new ModuleInputComponentStore(mock(InputModule.class), new InputComponentStore()); | |||
ModuleInputComponentStore store = newModuleInputComponentStore(); | |||
String ext = "java"; | |||
String filename = "Program." + ext; | |||
InputFile inputFile = new TestInputFileBuilder("dummy key", "some/path/" + filename).build(); | |||
InputFile inputFile = new TestInputFileBuilder(moduleKey, "some/path/" + filename).build(); | |||
store.doAdd(inputFile); | |||
assertThat(store.getFilesByName("nonexistent")).isEmpty(); | |||
assertThat(store.getFilesByExtension("nonexistent")).isEmpty(); | |||
} | |||
private ModuleInputComponentStore newModuleInputComponentStore() { | |||
return new ModuleInputComponentStore(mock(InputModule.class), componentStore, mock(SensorStrategy.class)); | |||
} | |||
} |