@@ -20,7 +20,9 @@ | |||
package org.sonar.plugins.cpd; | |||
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.config.PropertyDefinitions; | |||
import org.sonar.api.config.Settings; | |||
@@ -28,24 +30,29 @@ import org.sonar.api.resources.Java; | |||
import org.sonar.batch.duplication.BlockCache; | |||
import org.sonar.plugins.cpd.index.IndexFactory; | |||
import java.io.IOException; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
public class CpdSensorTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
JavaCpdEngine sonarEngine; | |||
DefaultCpdEngine sonarBridgeEngine; | |||
CpdSensor sensor; | |||
Settings settings; | |||
@Before | |||
public void setUp() { | |||
public void setUp() throws IOException { | |||
IndexFactory indexFactory = mock(IndexFactory.class); | |||
sonarEngine = new JavaCpdEngine(indexFactory, null, null); | |||
sonarBridgeEngine = new DefaultCpdEngine(indexFactory, new CpdMappings(), null, null, mock(BlockCache.class)); | |||
settings = new Settings(new PropertyDefinitions(CpdPlugin.class)); | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder()); | |||
sensor = new CpdSensor(sonarEngine, sonarBridgeEngine, settings, fs); | |||
} | |||
@@ -31,6 +31,7 @@ import org.sonar.xoo.rule.ChecksSensor; | |||
import org.sonar.xoo.rule.CreateIssueByInternalKeySensor; | |||
import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor; | |||
import org.sonar.xoo.rule.OneIssuePerLineSensor; | |||
import org.sonar.xoo.rule.RandomAccessSensor; | |||
import org.sonar.xoo.rule.XooFakeExporter; | |||
import org.sonar.xoo.rule.XooFakeImporter; | |||
import org.sonar.xoo.rule.XooFakeImporterWithMessages; | |||
@@ -74,6 +75,7 @@ public class XooPlugin extends SonarPlugin { | |||
CoveragePerTestSensor.class, | |||
DependencySensor.class, | |||
ChecksSensor.class, | |||
RandomAccessSensor.class, | |||
OneIssuePerLineSensor.class, | |||
OneIssueOnDirPerFileSensor.class, |
@@ -0,0 +1,73 @@ | |||
/* | |||
* 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.xoo.rule; | |||
import org.apache.commons.io.FileUtils; | |||
import org.sonar.api.batch.fs.FilePredicates; | |||
import org.sonar.api.batch.fs.FileSystem; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.InputFile.Type; | |||
import org.sonar.api.batch.sensor.Sensor; | |||
import org.sonar.api.batch.sensor.SensorContext; | |||
import org.sonar.api.batch.sensor.SensorDescriptor; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.xoo.Xoo; | |||
import java.io.File; | |||
import java.io.IOException; | |||
public class RandomAccessSensor implements Sensor { | |||
private static final String SONAR_XOO_RANDOM_ACCESS_ISSUE_PATHS = "sonar.xoo.randomAccessIssue.paths"; | |||
public static final String RULE_KEY = "RandomAccessIssue"; | |||
@Override | |||
public void describe(SensorDescriptor descriptor) { | |||
descriptor | |||
.name("One Issue Per File with Random Access") | |||
.onlyOnLanguages(Xoo.KEY) | |||
.createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY) | |||
.requireProperty(SONAR_XOO_RANDOM_ACCESS_ISSUE_PATHS); | |||
} | |||
@Override | |||
public void execute(SensorContext context) { | |||
File f = new File(context.settings().getString(SONAR_XOO_RANDOM_ACCESS_ISSUE_PATHS)); | |||
FileSystem fs = context.fileSystem(); | |||
FilePredicates p = fs.predicates(); | |||
try { | |||
for (String path : FileUtils.readLines(f)) { | |||
createIssues(fs.inputFile(p.and(p.hasPath(path), p.hasType(Type.MAIN), p.hasLanguage(Xoo.KEY))), context); | |||
} | |||
} catch (IOException e) { | |||
throw new IllegalStateException(e); | |||
} | |||
} | |||
private void createIssues(InputFile file, SensorContext context) { | |||
RuleKey ruleKey = RuleKey.of(XooRulesDefinition.XOO_REPOSITORY, RULE_KEY); | |||
context.newIssue() | |||
.ruleKey(ruleKey) | |||
.onFile(file) | |||
.atLine(1) | |||
.message("This issue is generated on each file") | |||
.save(); | |||
} | |||
} |
@@ -27,6 +27,6 @@ public class XooPluginTest { | |||
@Test | |||
public void provide_extensions() { | |||
assertThat(new XooPlugin().getExtensions()).hasSize(19); | |||
assertThat(new XooPlugin().getExtensions()).hasSize(20); | |||
} | |||
} |
@@ -57,7 +57,7 @@ public class CoveragePerTestSensorTest { | |||
public void prepare() throws IOException { | |||
baseDir = temp.newFolder(); | |||
sensor = new CoveragePerTestSensor(); | |||
fileSystem = new DefaultFileSystem(); | |||
fileSystem = new DefaultFileSystem(baseDir); | |||
when(context.fileSystem()).thenReturn(fileSystem); | |||
} | |||
@@ -56,7 +56,7 @@ public class DependencySensorTest { | |||
public void prepare() throws IOException { | |||
baseDir = temp.newFolder(); | |||
sensor = new DependencySensor(); | |||
fileSystem = new DefaultFileSystem(); | |||
fileSystem = new DefaultFileSystem(baseDir); | |||
when(context.fileSystem()).thenReturn(fileSystem); | |||
} | |||
@@ -65,7 +65,7 @@ public class MeasureSensorTest { | |||
baseDir = temp.newFolder(); | |||
metricFinder = mock(MetricFinder.class); | |||
sensor = new MeasureSensor(metricFinder); | |||
fileSystem = new DefaultFileSystem(); | |||
fileSystem = new DefaultFileSystem(baseDir); | |||
when(context.fileSystem()).thenReturn(fileSystem); | |||
storage = mock(SensorStorage.class); | |||
when(context.newMeasure()).then(new Answer<DefaultMeasure>() { |
@@ -52,7 +52,7 @@ public class SymbolReferencesSensorTest { | |||
public void prepare() throws IOException { | |||
baseDir = temp.newFolder(); | |||
sensor = new SymbolReferencesSensor(); | |||
fileSystem = new DefaultFileSystem(); | |||
fileSystem = new DefaultFileSystem(baseDir); | |||
when(context.fileSystem()).thenReturn(fileSystem); | |||
} | |||
@@ -52,7 +52,7 @@ public class SyntaxHighlightingSensorTest { | |||
public void prepare() throws IOException { | |||
baseDir = temp.newFolder(); | |||
sensor = new SyntaxHighlightingSensor(); | |||
fileSystem = new DefaultFileSystem(); | |||
fileSystem = new DefaultFileSystem(baseDir); | |||
when(context.fileSystem()).thenReturn(fileSystem); | |||
} | |||
@@ -56,7 +56,7 @@ public class TestCaseSensorTest { | |||
public void prepare() throws IOException { | |||
baseDir = temp.newFolder(); | |||
sensor = new TestCaseSensor(); | |||
fileSystem = new DefaultFileSystem(); | |||
fileSystem = new DefaultFileSystem(baseDir); | |||
when(context.fileSystem()).thenReturn(fileSystem); | |||
} | |||
@@ -57,7 +57,7 @@ public class XooTokenizerSensorTest { | |||
public void prepare() throws IOException { | |||
baseDir = temp.newFolder(); | |||
sensor = new XooTokenizerSensor(); | |||
fileSystem = new DefaultFileSystem(); | |||
fileSystem = new DefaultFileSystem(baseDir); | |||
when(context.fileSystem()).thenReturn(fileSystem); | |||
settings = new Settings(); | |||
when(context.settings()).thenReturn(settings); |
@@ -19,7 +19,9 @@ | |||
*/ | |||
package org.sonar.xoo.rule; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.mockito.ArgumentCaptor; | |||
import org.mockito.invocation.InvocationOnMock; | |||
import org.mockito.stubbing.Answer; | |||
@@ -34,6 +36,8 @@ import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.xoo.Xoo; | |||
import java.io.IOException; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.times; | |||
@@ -42,6 +46,9 @@ import static org.mockito.Mockito.when; | |||
public class OneIssuePerLineSensorTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
private OneIssuePerLineSensor sensor = new OneIssuePerLineSensor(); | |||
@Test | |||
@@ -52,8 +59,8 @@ public class OneIssuePerLineSensorTest { | |||
} | |||
@Test | |||
public void testRule() { | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
public void testRule() throws IOException { | |||
DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder()); | |||
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY).setLines(10); | |||
fs.add(inputFile); | |||
@@ -76,8 +83,8 @@ public class OneIssuePerLineSensorTest { | |||
} | |||
@Test | |||
public void testForceSeverity() { | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
public void testForceSeverity() throws IOException { | |||
DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder()); | |||
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY).setLines(10); | |||
fs.add(inputFile); | |||
@@ -57,7 +57,7 @@ public class XooBlameCommandTest { | |||
@Before | |||
public void prepare() throws IOException { | |||
baseDir = temp.newFolder(); | |||
fs = new DefaultFileSystem(); | |||
fs = new DefaultFileSystem(baseDir); | |||
input = mock(BlameInput.class); | |||
when(input.fileSystem()).thenReturn(fs); | |||
} |
@@ -9,6 +9,10 @@ | |||
<artifactId>sonar-batch</artifactId> | |||
<name>SonarQube :: Batch</name> | |||
<properties> | |||
<enableBenchmarkAssertions>false</enableBenchmarkAssertions> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
@@ -197,4 +201,18 @@ | |||
</plugin> | |||
</plugins> | |||
</build> | |||
<profiles> | |||
<profile> | |||
<id>runBenchmarks</id> | |||
<activation> | |||
<property> | |||
<name>runBenchmarks</name> | |||
</property> | |||
</activation> | |||
<properties> | |||
<enableBenchmarkAssertions>true</enableBenchmarkAssertions> | |||
</properties> | |||
</profile> | |||
</profiles> | |||
</project> |
@@ -36,7 +36,6 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.maven.MavenUtils; | |||
import org.sonar.api.task.TaskExtension; | |||
import org.sonar.api.utils.MessageException; | |||
import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; | |||
import org.sonar.java.api.JavaUtils; | |||
import javax.annotation.Nullable; | |||
@@ -219,15 +218,6 @@ public class MavenProjectConverter implements TaskExtension { | |||
return resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()); | |||
} | |||
public void synchronizeFileSystem(MavenProject pom, DefaultModuleFileSystem into) { | |||
into.resetDirs( | |||
pom.getBasedir(), | |||
getBuildDir(pom), | |||
mainDirs(pom), | |||
testDirs(pom), | |||
Arrays.asList(resolvePath(pom.getBuild().getOutputDirectory(), pom.getBasedir()))); | |||
} | |||
static File resolvePath(@Nullable String path, File basedir) { | |||
if (path != null) { | |||
File file = new File(StringUtils.trim(path)); |
@@ -20,7 +20,7 @@ | |||
package org.sonar.batch.scan.filesystem; | |||
import org.apache.commons.io.FilenameUtils; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; | |||
@@ -34,7 +34,7 @@ class AdditionalFilePredicates { | |||
// only static inner classes | |||
} | |||
static class KeyPredicate implements FilePredicate { | |||
static class KeyPredicate extends AbstractFilePredicate { | |||
private final String key; | |||
KeyPredicate(String key) { | |||
@@ -47,7 +47,7 @@ class AdditionalFilePredicates { | |||
} | |||
} | |||
static class DeprecatedKeyPredicate implements FilePredicate { | |||
static class DeprecatedKeyPredicate extends AbstractFilePredicate { | |||
private final String key; | |||
DeprecatedKeyPredicate(String key) { | |||
@@ -60,7 +60,7 @@ class AdditionalFilePredicates { | |||
} | |||
} | |||
static class SourceRelativePathPredicate implements FilePredicate { | |||
static class SourceRelativePathPredicate extends AbstractFilePredicate { | |||
private final String path; | |||
SourceRelativePathPredicate(String s) { | |||
@@ -73,7 +73,7 @@ class AdditionalFilePredicates { | |||
} | |||
} | |||
static class SourceDirPredicate implements FilePredicate { | |||
static class SourceDirPredicate extends AbstractFilePredicate { | |||
private final String path; | |||
SourceDirPredicate(String s) { |
@@ -80,14 +80,11 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module | |||
private DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, String moduleKey, Settings settings, | |||
FileIndexer indexer, ModuleFileSystemInitializer initializer, | |||
@Nullable ComponentIndexer componentIndexer) { | |||
super(moduleInputFileCache); | |||
super(initializer.baseDir(), moduleInputFileCache); | |||
this.componentIndexer = componentIndexer; | |||
this.moduleKey = moduleKey; | |||
this.settings = settings; | |||
this.indexer = indexer; | |||
if (initializer.baseDir() != null) { | |||
setBaseDir(initializer.baseDir()); | |||
} | |||
setWorkDir(initializer.workingDir()); | |||
this.buildDir = initializer.buildDir(); | |||
this.sourceDirsOrFiles = initializer.sources(); | |||
@@ -219,17 +216,6 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module | |||
} | |||
} | |||
public void resetDirs(File basedir, File buildDir, List<File> sourceDirs, List<File> testDirs, List<File> binaryDirs) { | |||
if (initialized) { | |||
throw MessageException.of("Module filesystem is already initialized. Modifications of filesystem are only allowed during Initializer phase."); | |||
} | |||
setBaseDir(basedir); | |||
this.buildDir = buildDir; | |||
this.sourceDirsOrFiles = existingDirsOrFiles(sourceDirs); | |||
this.testDirsOrFiles = existingDirsOrFiles(testDirs); | |||
this.binaryDirs = existingDirsOrFiles(binaryDirs); | |||
} | |||
public void index() { | |||
if (initialized) { | |||
throw MessageException.of("Module filesystem can only be indexed once"); | |||
@@ -241,16 +227,6 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module | |||
} | |||
} | |||
private List<File> existingDirsOrFiles(List<File> dirsOrFiles) { | |||
ImmutableList.Builder<File> builder = ImmutableList.builder(); | |||
for (File dirOrFile : dirsOrFiles) { | |||
if (dirOrFile.exists()) { | |||
builder.add(dirOrFile); | |||
} | |||
} | |||
return builder.build(); | |||
} | |||
private FilePredicate fromDeprecatedAttribute(String key, Collection<String> value) { | |||
if ("TYPE".equals(key)) { | |||
return predicates().or(Collections2.transform(value, new Function<String, FilePredicate>() { |
@@ -24,7 +24,6 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.fs.InputDir; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultFileSystem; | |||
import org.sonar.api.batch.fs.internal.RelativePathPredicate; | |||
public class ModuleInputFileCache extends DefaultFileSystem.Cache implements BatchComponent { | |||
@@ -37,17 +36,17 @@ public class ModuleInputFileCache extends DefaultFileSystem.Cache implements Bat | |||
} | |||
@Override | |||
protected Iterable<InputFile> inputFiles() { | |||
public Iterable<InputFile> inputFiles() { | |||
return projectCache.filesByModule(moduleKey); | |||
} | |||
@Override | |||
protected InputFile inputFile(RelativePathPredicate predicate) { | |||
return projectCache.getFile(moduleKey, predicate.path()); | |||
public InputFile inputFile(String relativePath) { | |||
return projectCache.getFile(moduleKey, relativePath); | |||
} | |||
@Override | |||
protected InputDir inputDir(String relativePath) { | |||
public InputDir inputDir(String relativePath) { | |||
return projectCache.getDir(moduleKey, relativePath); | |||
} | |||
@@ -73,7 +73,7 @@ public class SqaleRatingDecoratorTest { | |||
public void setUp() throws Exception { | |||
settings = new Settings(); | |||
fs = new DefaultFileSystem(); | |||
fs = new DefaultFileSystem(temp.newFolder()); | |||
fs.add(new DefaultInputFile("foo", file.getPath()) | |||
.setLanguage("java") | |||
.setFile(temp.newFile("Foo.java"))); |
@@ -65,13 +65,14 @@ public class IssueExclusionsLoaderTest { | |||
@Mock | |||
private PatternMatcher patternMatcher; | |||
DefaultFileSystem fs = new DefaultFileSystem().setEncoding(UTF_8); | |||
IssueExclusionsLoader scanner; | |||
File baseDir; | |||
private DefaultFileSystem fs; | |||
private IssueExclusionsLoader scanner; | |||
private File baseDir; | |||
@Before | |||
public void before() throws IOException { | |||
public void before() throws Exception { | |||
baseDir = temp.newFolder(); | |||
fs = new DefaultFileSystem(baseDir).setEncoding(UTF_8); | |||
MockitoAnnotations.initMocks(this); | |||
scanner = new IssueExclusionsLoader(regexpScanner, exclusionPatternInitializer, inclusionPatternInitializer, fs); | |||
} |
@@ -0,0 +1,49 @@ | |||
/* | |||
* 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; | |||
import org.hamcrest.Matchers; | |||
import org.junit.rules.ErrorCollector; | |||
import org.slf4j.LoggerFactory; | |||
public class Benchmark extends ErrorCollector { | |||
private static final boolean ENABLED = "true".equals(System.getProperty("enableBenchmarkAssertions")); | |||
static { | |||
if (ENABLED) { | |||
LoggerFactory.getLogger(Benchmark.class).warn("Assertions are calibrated for SonarSource dedicated box. " + | |||
"They can be disabled by setting the property -DenableBenchmarkAssertions=false."); | |||
} | |||
} | |||
public void expectBetween(String label, long val, long min, long max) { | |||
if (ENABLED) { | |||
checkThat(label, val, Matchers.allOf(Matchers.greaterThan(min), Matchers.lessThan(max))); | |||
} | |||
} | |||
public void expectLessThanOrEqualTo(String label, long val, long max) { | |||
if (ENABLED) { | |||
checkThat(label, val, Matchers.lessThan(max)); | |||
} | |||
} | |||
} |
@@ -0,0 +1,136 @@ | |||
/* | |||
* 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.fs; | |||
import com.google.common.base.Charsets; | |||
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.sonar.batch.mediumtest.BatchMediumTester; | |||
import org.sonar.batch.mediumtest.Benchmark; | |||
import org.sonar.batch.mediumtest.TaskResult; | |||
import org.sonar.batch.protocol.input.ActiveRule; | |||
import org.sonar.xoo.XooPlugin; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class RandomFsAccessMediumTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Rule | |||
public Benchmark bench = new Benchmark(); | |||
public BatchMediumTester tester = BatchMediumTester.builder() | |||
.registerPlugin("xoo", new XooPlugin()) | |||
.addDefaultQProfile("xoo", "Sonar Way") | |||
.activateRule(new ActiveRule("xoo", "RandomAccessIssue", null, "One issue per line", "MAJOR", null, "xoo")) | |||
.build(); | |||
@Before | |||
public void prepare() { | |||
tester.start(); | |||
} | |||
@After | |||
public void stop() { | |||
tester.stop(); | |||
} | |||
@Test | |||
public void testRandomFsAccessByAbsolutePath() throws IOException { | |||
File baseDir = temp.newFolder(); | |||
File srcDir = prepareBigProject(baseDir); | |||
File paths = new File(baseDir, "paths.txt"); | |||
int ISSUE_COUNT = 10000; | |||
for (int i = 0; i < ISSUE_COUNT; i++) { | |||
File xooFile = new File(srcDir, "sample" + (i / 10 + 1) + ".xoo"); | |||
FileUtils.write(paths, xooFile.getAbsolutePath() + "\n", Charsets.UTF_8, true); | |||
} | |||
long start = System.currentTimeMillis(); | |||
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") | |||
.put("sonar.xoo.randomAccessIssue.paths", paths.getAbsolutePath()) | |||
.build()) | |||
.start(); | |||
assertThat(result.issues()).hasSize(ISSUE_COUNT); | |||
bench.expectLessThanOrEqualTo("Time to create " + ISSUE_COUNT + " issues on random files using FileSystem query", System.currentTimeMillis() - start, 2000); | |||
} | |||
@Test | |||
public void testRandomFsAccessByRelativePath() throws IOException { | |||
File baseDir = temp.newFolder(); | |||
File srcDir = prepareBigProject(baseDir); | |||
File paths = new File(baseDir, "paths.txt"); | |||
int ISSUE_COUNT = 10000; | |||
for (int i = 0; i < ISSUE_COUNT; i++) { | |||
FileUtils.write(paths, "src/sample" + (i / 10 + 1) + ".xoo\n", Charsets.UTF_8, true); | |||
} | |||
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") | |||
.put("sonar.xoo.randomAccessIssue.paths", paths.getAbsolutePath()) | |||
.build()) | |||
.start(); | |||
assertThat(result.issues()).hasSize(ISSUE_COUNT); | |||
} | |||
private File prepareBigProject(File baseDir) throws IOException { | |||
File srcDir = new File(baseDir, "src"); | |||
srcDir.mkdir(); | |||
for (int i = 1; i <= 1000; i++) { | |||
File xooFile = new File(srcDir, "sample" + i + ".xoo"); | |||
FileUtils.write(xooFile, "foo"); | |||
} | |||
return srcDir; | |||
} | |||
} |
@@ -19,7 +19,10 @@ | |||
*/ | |||
package org.sonar.batch.rule; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.batch.fs.internal.DefaultFileSystem; | |||
import org.sonar.api.measures.CoreMetrics; | |||
@@ -32,10 +35,15 @@ import java.util.Date; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Matchers.argThat; | |||
import static org.mockito.Mockito.*; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
public class QProfileSensorTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
static final Date DATE = UtcDateUtils.parseDateTime("2014-01-15T12:00:00+0000"); | |||
static final QProfile JAVA_PROFILE = new QProfile().setKey("java-two").setName("Java Two").setLanguage("java") | |||
.setRulesUpdatedAt(DATE); | |||
@@ -45,7 +53,12 @@ public class QProfileSensorTest { | |||
ModuleQProfiles moduleQProfiles = mock(ModuleQProfiles.class); | |||
Project project = mock(Project.class); | |||
SensorContext sensorContext = mock(SensorContext.class); | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
DefaultFileSystem fs; | |||
@Before | |||
public void prepare() throws Exception { | |||
fs = new DefaultFileSystem(temp.newFolder()); | |||
} | |||
@Test | |||
public void to_string() throws Exception { |
@@ -23,24 +23,31 @@ import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
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.config.Settings; | |||
import org.sonar.api.utils.MessageException; | |||
import static org.mockito.Mockito.*; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
public class QProfileVerifierTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
ModuleQProfiles profiles; | |||
Settings settings = new Settings(); | |||
private DefaultFileSystem fs; | |||
private ModuleQProfiles profiles; | |||
private Settings settings = new Settings(); | |||
@Before | |||
public void before() { | |||
public void before() throws Exception { | |||
fs = new DefaultFileSystem(temp.newFolder()); | |||
profiles = mock(ModuleQProfiles.class); | |||
QProfile javaProfile = new QProfile().setKey("p1").setName("My Java profile").setLanguage("java"); | |||
when(profiles.findByLanguage("java")).thenReturn(javaProfile); |
@@ -19,9 +19,11 @@ | |||
*/ | |||
package org.sonar.batch.scan; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.fs.internal.DefaultFileSystem; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.resources.Java; | |||
@@ -34,13 +36,21 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
public class LanguageVerifierTest { | |||
Settings settings = new Settings(); | |||
LanguagesReferential languages = new DefaultLanguagesReferential(new Languages(Java.INSTANCE)); | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
private Settings settings = new Settings(); | |||
private LanguagesReferential languages = new DefaultLanguagesReferential(new Languages(Java.INSTANCE)); | |||
private DefaultFileSystem fs; | |||
@Before | |||
public void prepare() throws Exception { | |||
fs = new DefaultFileSystem(temp.newFolder()); | |||
} | |||
@Test | |||
public void language_is_not_set() throws Exception { | |||
LanguageVerifier verifier = new LanguageVerifier(settings, languages, fs); |
@@ -48,7 +48,7 @@ public class ComponentIndexerTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
private File baseDir; | |||
private DefaultFileSystem fs = new DefaultFileSystem(); | |||
private DefaultFileSystem fs; | |||
private SonarIndex sonarIndex; | |||
private AbstractLanguage cobolLanguage; | |||
private Project project; | |||
@@ -56,6 +56,7 @@ public class ComponentIndexerTest { | |||
@Before | |||
public void prepare() throws IOException { | |||
baseDir = temp.newFolder(); | |||
fs = new DefaultFileSystem(baseDir); | |||
sonarIndex = mock(SonarIndex.class); | |||
project = new Project("myProject"); | |||
cobolLanguage = new AbstractLanguage("cobol") { |
@@ -58,13 +58,13 @@ public class DefaultModuleFileSystemTest { | |||
@Test | |||
public void test_equals_and_hashCode() throws Exception { | |||
DefaultModuleFileSystem foo1 = new DefaultModuleFileSystem(moduleInputFileCache, | |||
DefaultModuleFileSystem foo1 = new DefaultModuleFileSystem(moduleInputFileCache, | |||
new Project("foo"), settings, fileIndexer, initializer, componentIndexer); | |||
DefaultModuleFileSystem foo2 = new DefaultModuleFileSystem(moduleInputFileCache, | |||
DefaultModuleFileSystem foo2 = new DefaultModuleFileSystem(moduleInputFileCache, | |||
new Project("foo"), settings, fileIndexer, initializer, componentIndexer); | |||
DefaultModuleFileSystem bar = new DefaultModuleFileSystem(moduleInputFileCache, | |||
DefaultModuleFileSystem bar = new DefaultModuleFileSystem(moduleInputFileCache, | |||
new Project("bar"), settings, fileIndexer, initializer, componentIndexer); | |||
DefaultModuleFileSystem branch = new DefaultModuleFileSystem(moduleInputFileCache, | |||
DefaultModuleFileSystem branch = new DefaultModuleFileSystem(moduleInputFileCache, | |||
new Project("bar", "branch", "My project"), settings, fileIndexer, initializer, componentIndexer); | |||
assertThat(foo1.moduleKey()).isEqualTo("foo"); | |||
@@ -79,7 +79,7 @@ public class DefaultModuleFileSystemTest { | |||
@Test | |||
public void default_source_encoding() { | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
new Project("foo"), settings, fileIndexer, initializer, componentIndexer); | |||
assertThat(fs.sourceCharset()).isEqualTo(Charset.defaultCharset()); | |||
@@ -89,7 +89,7 @@ public class DefaultModuleFileSystemTest { | |||
@Test | |||
public void source_encoding_is_set() { | |||
settings.setProperty(CoreProperties.ENCODING_PROPERTY, "Cp1124"); | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
new Project("foo"), settings, fileIndexer, initializer, componentIndexer); | |||
assertThat(fs.encoding()).isEqualTo(Charset.forName("Cp1124")); | |||
@@ -119,7 +119,7 @@ public class DefaultModuleFileSystemTest { | |||
javaTest.mkdirs(); | |||
when(initializer.tests()).thenReturn(Arrays.asList(javaTest, additionalTest)); | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
new Project("foo"), settings, fileIndexer, initializer, componentIndexer); | |||
assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(basedir.getCanonicalPath()); | |||
@@ -130,35 +130,9 @@ public class DefaultModuleFileSystemTest { | |||
assertThat(fs.binaryDirs()).hasSize(1); | |||
} | |||
@Test | |||
public void should_reset_dirs() throws IOException { | |||
File basedir = temp.newFolder(); | |||
when(initializer.baseDir()).thenReturn(basedir); | |||
when(initializer.workingDir()).thenReturn(basedir); | |||
when(initializer.sources()).thenReturn(Arrays.asList(new File(basedir, "src/main/java"))); | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
new Project("foo"), settings, fileIndexer, initializer, componentIndexer); | |||
File existingDir = temp.newFolder("new_folder"); | |||
File notExistingDir = new File(existingDir, "not_exist"); | |||
fs.resetDirs(existingDir, existingDir, | |||
Lists.newArrayList(existingDir, notExistingDir), Lists.newArrayList(existingDir, notExistingDir), Lists.newArrayList(existingDir, notExistingDir)); | |||
assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); | |||
assertThat(fs.buildDir().getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); | |||
assertThat(fs.sourceDirs()).hasSize(1); | |||
assertThat(fs.sourceDirs().get(0).getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); | |||
assertThat(fs.testDirs()).hasSize(1); | |||
assertThat(fs.testDirs().get(0).getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); | |||
assertThat(fs.binaryDirs()).hasSize(1); | |||
assertThat(fs.binaryDirs().get(0).getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); | |||
} | |||
@Test | |||
public void should_search_input_files() throws Exception { | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
new Project("foo"), settings, fileIndexer, initializer, componentIndexer); | |||
File mainFile = temp.newFile(); | |||
@@ -176,7 +150,7 @@ public class DefaultModuleFileSystemTest { | |||
@Test | |||
public void should_index() throws Exception { | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, | |||
new Project("foo"), settings, fileIndexer, initializer, componentIndexer); | |||
verifyZeroInteractions(fileIndexer); |
@@ -64,11 +64,11 @@ public class JSONReportTest { | |||
private SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); | |||
@org.junit.Rule | |||
public TemporaryFolder temporaryFolder = new TemporaryFolder(); | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
JSONReport jsonReport; | |||
Resource resource = mock(Resource.class); | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
DefaultFileSystem fs; | |||
Server server = mock(Server.class); | |||
ActiveRules activeRules = mock(ActiveRules.class); | |||
Settings settings = new Settings(); | |||
@@ -76,7 +76,8 @@ public class JSONReportTest { | |||
private UserRepository userRepository; | |||
@Before | |||
public void before() { | |||
public void before() throws Exception { | |||
fs = new DefaultFileSystem(temp.newFolder()); | |||
SIMPLE_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+02:00")); | |||
when(resource.getEffectiveKey()).thenReturn("Action.java"); | |||
when(server.getVersion()).thenReturn("3.6"); | |||
@@ -161,7 +162,7 @@ public class JSONReportTest { | |||
@Test | |||
public void should_export_issues_to_file() throws IOException { | |||
File workDir = temporaryFolder.newFolder("sonar"); | |||
File workDir = temp.newFolder("sonar"); | |||
fs.setWorkDir(workDir); | |||
when(jsonReport.getIssues()).thenReturn(Collections.<DefaultIssue>emptyList()); |
@@ -23,6 +23,7 @@ import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.AnalysisMode; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultFileSystem; | |||
@@ -39,18 +40,20 @@ import static org.mockito.Mockito.when; | |||
public class AnalyzerOptimizerTest { | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
private AnalyzerOptimizer optimizer; | |||
private DefaultFileSystem fs; | |||
private AnalyzerOptimizer optimizer; | |||
private Settings settings; | |||
private AnalysisMode analysisMode; | |||
@Before | |||
public void prepare() { | |||
public void prepare() throws Exception { | |||
fs = new DefaultFileSystem(temp.newFolder()); | |||
settings = new Settings(); | |||
analysisMode = mock(AnalysisMode.class); | |||
optimizer = new AnalyzerOptimizer(fs, new ActiveRulesBuilder().build(), settings, analysisMode); |
@@ -23,6 +23,7 @@ import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.AnalysisMode; | |||
import org.sonar.api.batch.fs.internal.DefaultFileSystem; | |||
import org.sonar.api.batch.measure.MetricFinder; | |||
@@ -41,6 +42,9 @@ import static org.mockito.Mockito.when; | |||
public class DefaultSensorContextTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
@@ -52,9 +56,9 @@ public class DefaultSensorContextTest { | |||
private AnalysisMode analysisMode; | |||
@Before | |||
public void prepare() { | |||
public void prepare() throws Exception { | |||
activeRules = new ActiveRulesBuilder().build(); | |||
fs = new DefaultFileSystem(); | |||
fs = new DefaultFileSystem(temp.newFolder()); | |||
MetricFinder metricFinder = mock(MetricFinder.class); | |||
when(metricFinder.findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC); | |||
when(metricFinder.findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION); |
@@ -23,6 +23,7 @@ import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.mockito.ArgumentCaptor; | |||
import org.sonar.api.batch.fs.InputDir; | |||
import org.sonar.api.batch.fs.InputFile; | |||
@@ -66,6 +67,9 @@ import static org.mockito.Mockito.when; | |||
public class DefaultSensorStorageTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
@@ -78,9 +82,9 @@ public class DefaultSensorStorageTest { | |||
private DefaultIndex sonarIndex; | |||
@Before | |||
public void prepare() { | |||
public void prepare() throws Exception { | |||
activeRules = new ActiveRulesBuilder().build(); | |||
fs = new DefaultFileSystem(); | |||
fs = new DefaultFileSystem(temp.newFolder()); | |||
MetricFinder metricFinder = mock(MetricFinder.class); | |||
when(metricFinder.findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC); | |||
when(metricFinder.findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION); |
@@ -0,0 +1,60 @@ | |||
/* | |||
* 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.fs; | |||
import com.google.common.base.Predicate; | |||
import com.google.common.collect.Iterables; | |||
import org.sonar.api.batch.fs.FileSystem.Index; | |||
/** | |||
* Partial implementation of {@link FilePredicate}. | |||
* @since 5.1 | |||
*/ | |||
public abstract class AbstractFilePredicate implements FilePredicate { | |||
protected static final int DEFAULT_PRIORITY = 10; | |||
protected static final int USE_INDEX = 20; | |||
@Override | |||
public Iterable<InputFile> filter(Iterable<InputFile> target) { | |||
return Iterables.filter(target, new Predicate<InputFile>() { | |||
@Override | |||
public boolean apply(InputFile input) { | |||
return AbstractFilePredicate.this.apply(input); | |||
} | |||
}); | |||
} | |||
@Override | |||
public Iterable<InputFile> get(Index index) { | |||
return filter(index.inputFiles()); | |||
} | |||
@Override | |||
public int priority() { | |||
return DEFAULT_PRIORITY; | |||
} | |||
@Override | |||
public int compareTo(FilePredicate o) { | |||
return o.priority() - priority(); | |||
} | |||
} |
@@ -19,11 +19,35 @@ | |||
*/ | |||
package org.sonar.api.batch.fs; | |||
import org.sonar.api.batch.fs.internal.RelativePathPredicate; | |||
/** | |||
* Determines if a file must be kept in search results. See {@link org.sonar.api.batch.fs.FileSystem} | |||
* and {@link org.sonar.api.batch.fs.FilePredicates}. | |||
* @since 4.2 | |||
*/ | |||
public interface FilePredicate { | |||
public interface FilePredicate extends Comparable<FilePredicate> { | |||
/** | |||
* Test if provided file is valid for this predicate | |||
*/ | |||
boolean apply(InputFile inputFile); | |||
/** | |||
* Filter provided files to keep only the ones that are valid for this predicate | |||
*/ | |||
Iterable<InputFile> filter(Iterable<InputFile> inputFiles); | |||
/** | |||
* Get all files that are valid for this predicate. | |||
*/ | |||
Iterable<InputFile> get(FileSystem.Index index); | |||
/** | |||
* For optimization. FilePredicates will be applied in priority order. For example when doing | |||
* p.and(p1, p2, p3) then p1, p2 and p3 will be applied according to their priority value. Higher priority value | |||
* are applied first. | |||
* Assign a high priority when the predicate will likely highly reduce the set of InputFiles to filter. Also | |||
* {@link RelativePathPredicate} and AbsolutePathPredicate have a high priority since they are using cache index. | |||
*/ | |||
int priority(); | |||
} |
@@ -149,4 +149,17 @@ public interface FileSystem extends BatchComponent { | |||
* @since 5.0 | |||
*/ | |||
File resolvePath(String path); | |||
/** | |||
* Interface of the underlying file index. | |||
*/ | |||
public static interface Index { | |||
Iterable<InputFile> inputFiles(); | |||
@CheckForNull | |||
InputFile inputFile(String relativePath); | |||
@CheckForNull | |||
InputDir inputDir(String relativePath); | |||
} | |||
} |
@@ -19,18 +19,26 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.FileSystem.Index; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.scan.filesystem.PathResolver; | |||
import org.sonar.api.utils.PathUtils; | |||
import java.io.File; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
/** | |||
* @since 4.2 | |||
*/ | |||
class AbsolutePathPredicate implements FilePredicate { | |||
class AbsolutePathPredicate extends AbstractFilePredicate { | |||
private final String path; | |||
private final File baseDir; | |||
AbsolutePathPredicate(String path) { | |||
AbsolutePathPredicate(String path, File baseDir) { | |||
this.baseDir = baseDir; | |||
this.path = PathUtils.sanitize(path); | |||
} | |||
@@ -38,4 +46,19 @@ class AbsolutePathPredicate implements FilePredicate { | |||
public boolean apply(InputFile f) { | |||
return path.equals(f.absolutePath()); | |||
} | |||
@Override | |||
public Iterable<InputFile> get(Index index) { | |||
String relative = PathUtils.sanitize(new PathResolver().relativePath(baseDir, new File(path))); | |||
if (relative == null) { | |||
return Collections.<InputFile>emptyList(); | |||
} | |||
InputFile f = index.inputFile(relative); | |||
return f != null ? Arrays.asList(f) : Collections.<InputFile>emptyList(); | |||
} | |||
@Override | |||
public int priority() { | |||
return USE_INDEX; | |||
} | |||
} |
@@ -19,20 +19,45 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.FileSystem.Index; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.List; | |||
/** | |||
* @since 4.2 | |||
*/ | |||
class AndPredicate implements FilePredicate { | |||
class AndPredicate extends AbstractFilePredicate { | |||
private final Collection<FilePredicate> predicates; | |||
private final List<FilePredicate> predicates = new ArrayList<>(); | |||
AndPredicate(Collection<FilePredicate> predicates) { | |||
this.predicates = predicates; | |||
private AndPredicate() { | |||
} | |||
public static FilePredicate create(Collection<FilePredicate> predicates) { | |||
if (predicates.isEmpty()) { | |||
return TruePredicate.TRUE; | |||
} | |||
AndPredicate result = new AndPredicate(); | |||
for (FilePredicate filePredicate : predicates) { | |||
if (filePredicate == TruePredicate.TRUE) { | |||
continue; | |||
} else if (filePredicate == FalsePredicate.FALSE) { | |||
return FalsePredicate.FALSE; | |||
} else if (filePredicate instanceof AndPredicate) { | |||
result.predicates.addAll(((AndPredicate) filePredicate).predicates); | |||
} else { | |||
result.predicates.add(filePredicate); | |||
} | |||
} | |||
Collections.sort(result.predicates); | |||
return result; | |||
} | |||
@Override | |||
@@ -45,4 +70,31 @@ class AndPredicate implements FilePredicate { | |||
return true; | |||
} | |||
@Override | |||
public Iterable<InputFile> filter(Iterable<InputFile> target) { | |||
Iterable<InputFile> result = target; | |||
for (FilePredicate predicate : predicates) { | |||
result = predicate.filter(result); | |||
} | |||
return result; | |||
} | |||
@Override | |||
public Iterable<InputFile> get(Index index) { | |||
if (predicates.isEmpty()) { | |||
return index.inputFiles(); | |||
} | |||
// Optimization, use get on first predicate then filter with next predicates | |||
Iterable<InputFile> result = predicates.get(0).get(index); | |||
for (int i = 1; i < predicates.size(); i++) { | |||
result = predicates.get(i).filter(result); | |||
} | |||
return result; | |||
} | |||
@VisibleForTesting | |||
Collection<FilePredicate> predicates() { | |||
return predicates; | |||
} | |||
} |
@@ -35,10 +35,14 @@ import java.util.List; | |||
* @since 4.2 | |||
*/ | |||
public class DefaultFilePredicates implements FilePredicates { | |||
private final File baseDir; | |||
/** | |||
* Client code should use {@link org.sonar.api.batch.fs.FileSystem#predicates()} to get an instance | |||
*/ | |||
DefaultFilePredicates() { | |||
DefaultFilePredicates(File baseDir) { | |||
this.baseDir = baseDir; | |||
} | |||
/** | |||
@@ -57,16 +61,13 @@ public class DefaultFilePredicates implements FilePredicates { | |||
return FalsePredicate.FALSE; | |||
} | |||
/** | |||
* Warning - not efficient because absolute path is not indexed yet. | |||
*/ | |||
@Override | |||
public FilePredicate hasAbsolutePath(String s) { | |||
return new AbsolutePathPredicate(s); | |||
return new AbsolutePathPredicate(s, baseDir); | |||
} | |||
/** | |||
* TODO document that non-normalized path and Windows-style path are supported | |||
* non-normalized path and Windows-style path are supported | |||
*/ | |||
@Override | |||
public FilePredicate hasRelativePath(String s) { | |||
@@ -160,31 +161,31 @@ public class DefaultFilePredicates implements FilePredicates { | |||
@Override | |||
public FilePredicate or(Collection<FilePredicate> or) { | |||
return new OrPredicate(or); | |||
return OrPredicate.create(or); | |||
} | |||
@Override | |||
public FilePredicate or(FilePredicate... or) { | |||
return new OrPredicate(Arrays.asList(or)); | |||
return OrPredicate.create(Arrays.asList(or)); | |||
} | |||
@Override | |||
public FilePredicate or(FilePredicate first, FilePredicate second) { | |||
return new OrPredicate(Arrays.asList(first, second)); | |||
return OrPredicate.create(Arrays.asList(first, second)); | |||
} | |||
@Override | |||
public FilePredicate and(Collection<FilePredicate> and) { | |||
return new AndPredicate(and); | |||
return AndPredicate.create(and); | |||
} | |||
@Override | |||
public FilePredicate and(FilePredicate... and) { | |||
return new AndPredicate(Arrays.asList(and)); | |||
return AndPredicate.create(Arrays.asList(and)); | |||
} | |||
@Override | |||
public FilePredicate and(FilePredicate first, FilePredicate second) { | |||
return new AndPredicate(Arrays.asList(first, second)); | |||
return AndPredicate.create(Arrays.asList(first, second)); | |||
} | |||
} |
@@ -19,7 +19,9 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import com.google.common.base.Function; | |||
import com.google.common.base.Preconditions; | |||
import com.google.common.collect.Iterables; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.FilePredicates; | |||
import org.sonar.api.batch.fs.FileSystem; | |||
@@ -35,7 +37,6 @@ import java.io.File; | |||
import java.io.IOException; | |||
import java.nio.charset.Charset; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
@@ -50,25 +51,23 @@ public class DefaultFileSystem implements FileSystem { | |||
private final Cache cache; | |||
private final SortedSet<String> languages = new TreeSet<String>(); | |||
private File baseDir, workDir; | |||
private final File baseDir; | |||
private File workDir; | |||
private Charset encoding; | |||
private final FilePredicates predicates = new DefaultFilePredicates(); | |||
private final FilePredicates predicates; | |||
/** | |||
* Only for testing | |||
*/ | |||
public DefaultFileSystem() { | |||
this.cache = new MapCache(); | |||
public DefaultFileSystem(File baseDir) { | |||
this(baseDir, new MapCache()); | |||
} | |||
protected DefaultFileSystem(Cache cache) { | |||
protected DefaultFileSystem(File baseDir, Cache cache) { | |||
Preconditions.checkNotNull(baseDir, "Base directory can't be null"); | |||
this.baseDir = baseDir.getAbsoluteFile(); | |||
this.cache = cache; | |||
} | |||
public DefaultFileSystem setBaseDir(File d) { | |||
Preconditions.checkNotNull(d, "Base directory can't be null"); | |||
this.baseDir = d.getAbsoluteFile(); | |||
return this; | |||
this.predicates = new DefaultFilePredicates(baseDir); | |||
} | |||
@Override | |||
@@ -102,10 +101,6 @@ public class DefaultFileSystem implements FileSystem { | |||
@Override | |||
public InputFile inputFile(FilePredicate predicate) { | |||
doPreloadFiles(); | |||
if (predicate instanceof RelativePathPredicate) { | |||
return cache.inputFile((RelativePathPredicate) predicate); | |||
} | |||
Iterable<InputFile> files = inputFiles(predicate); | |||
Iterator<InputFile> iterator = files.iterator(); | |||
if (!iterator.hasNext()) { | |||
@@ -133,30 +128,24 @@ public class DefaultFileSystem implements FileSystem { | |||
@Override | |||
public Iterable<InputFile> inputFiles(FilePredicate predicate) { | |||
doPreloadFiles(); | |||
return filter(cache.inputFiles(), predicate); | |||
return predicate.get(cache); | |||
} | |||
@Override | |||
public boolean hasFiles(FilePredicate predicate) { | |||
doPreloadFiles(); | |||
for (InputFile element : cache.inputFiles()) { | |||
if (predicate.apply(element)) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
return predicate.get(cache).iterator().hasNext(); | |||
} | |||
@Override | |||
public Iterable<File> files(FilePredicate predicate) { | |||
doPreloadFiles(); | |||
Collection<File> result = new ArrayList<File>(); | |||
for (InputFile element : inputFiles(predicate)) { | |||
if (predicate.apply(element)) { | |||
result.add(element.file()); | |||
return Iterables.transform(inputFiles(predicate), new Function<InputFile, File>() { | |||
@Override | |||
public File apply(InputFile input) { | |||
return input.file(); | |||
} | |||
} | |||
return result; | |||
}); | |||
} | |||
@Override | |||
@@ -169,16 +158,6 @@ public class DefaultFileSystem implements FileSystem { | |||
return cache.inputDir(relativePath); | |||
} | |||
public static Collection<InputFile> filter(Iterable<InputFile> target, FilePredicate predicate) { | |||
Collection<InputFile> result = new ArrayList<InputFile>(); | |||
for (InputFile element : target) { | |||
if (predicate.apply(element)) { | |||
result.add(element); | |||
} | |||
} | |||
return result; | |||
} | |||
/** | |||
* Adds InputFile to the list and registers its language, if present. | |||
* Synchronized because PersistIt Exchange is not concurrent | |||
@@ -228,14 +207,17 @@ public class DefaultFileSystem implements FileSystem { | |||
// nothing to do by default | |||
} | |||
public abstract static class Cache { | |||
protected abstract Iterable<InputFile> inputFiles(); | |||
public abstract static class Cache implements Index { | |||
@Override | |||
public abstract Iterable<InputFile> inputFiles(); | |||
@Override | |||
@CheckForNull | |||
protected abstract InputFile inputFile(RelativePathPredicate predicate); | |||
public abstract InputFile inputFile(String relativePath); | |||
@Override | |||
@CheckForNull | |||
protected abstract InputDir inputDir(String relativePath); | |||
public abstract InputDir inputDir(String relativePath); | |||
protected abstract void doAdd(InputFile inputFile); | |||
@@ -264,12 +246,12 @@ public class DefaultFileSystem implements FileSystem { | |||
} | |||
@Override | |||
public InputFile inputFile(RelativePathPredicate predicate) { | |||
return fileMap.get(predicate.path()); | |||
public InputFile inputFile(String relativePath) { | |||
return fileMap.get(relativePath); | |||
} | |||
@Override | |||
protected InputDir inputDir(String relativePath) { | |||
public InputDir inputDir(String relativePath) { | |||
return dirMap.get(relativePath); | |||
} | |||
@@ -19,10 +19,14 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.FileSystem.Index; | |||
import org.sonar.api.batch.fs.InputFile; | |||
class FalsePredicate implements FilePredicate { | |||
import java.util.Collections; | |||
class FalsePredicate extends AbstractFilePredicate { | |||
static final FilePredicate FALSE = new FalsePredicate(); | |||
@@ -30,4 +34,14 @@ class FalsePredicate implements FilePredicate { | |||
public boolean apply(InputFile inputFile) { | |||
return false; | |||
} | |||
@Override | |||
public Iterable<InputFile> filter(Iterable<InputFile> target) { | |||
return Collections.emptyList(); | |||
} | |||
@Override | |||
public Iterable<InputFile> get(Index index) { | |||
return Collections.emptyList(); | |||
} | |||
} |
@@ -19,13 +19,14 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.InputFile; | |||
/** | |||
* @since 4.2 | |||
*/ | |||
class LanguagePredicate implements FilePredicate { | |||
class LanguagePredicate extends AbstractFilePredicate { | |||
private final String language; | |||
LanguagePredicate(String language) { |
@@ -19,13 +19,15 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.InputFile; | |||
/** | |||
* @since 4.2 | |||
*/ | |||
class NotPredicate implements FilePredicate { | |||
class NotPredicate extends AbstractFilePredicate { | |||
private final FilePredicate predicate; | |||
@@ -19,25 +19,41 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import java.util.Arrays; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
/** | |||
* @since 4.2 | |||
*/ | |||
class OrPredicate implements FilePredicate { | |||
class OrPredicate extends AbstractFilePredicate { | |||
private final Collection<FilePredicate> predicates; | |||
private final Collection<FilePredicate> predicates = new ArrayList<>(); | |||
OrPredicate(Collection<FilePredicate> predicates) { | |||
private OrPredicate() { | |||
} | |||
public static FilePredicate create(Collection<FilePredicate> predicates) { | |||
if (predicates.isEmpty()) { | |||
this.predicates = Arrays.asList(TruePredicate.TRUE); | |||
} else { | |||
this.predicates = predicates; | |||
return TruePredicate.TRUE; | |||
} | |||
OrPredicate result = new OrPredicate(); | |||
for (FilePredicate filePredicate : predicates) { | |||
if (filePredicate == TruePredicate.TRUE) { | |||
return TruePredicate.TRUE; | |||
} else if (filePredicate == FalsePredicate.FALSE) { | |||
continue; | |||
} else if (filePredicate instanceof OrPredicate) { | |||
result.predicates.addAll(((OrPredicate) filePredicate).predicates); | |||
} else { | |||
result.predicates.add(filePredicate); | |||
} | |||
} | |||
return result; | |||
} | |||
@Override | |||
@@ -50,4 +66,9 @@ class OrPredicate implements FilePredicate { | |||
return false; | |||
} | |||
@VisibleForTesting | |||
Collection<FilePredicate> predicates() { | |||
return predicates; | |||
} | |||
} |
@@ -19,13 +19,14 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.InputFile; | |||
/** | |||
* @since 4.2 | |||
*/ | |||
class PathPatternPredicate implements FilePredicate { | |||
class PathPatternPredicate extends AbstractFilePredicate { | |||
private final PathPattern pattern; | |||
@@ -19,14 +19,18 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.FileSystem.Index; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.utils.PathUtils; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
/** | |||
* @since 4.2 | |||
*/ | |||
public class RelativePathPredicate implements FilePredicate { | |||
public class RelativePathPredicate extends AbstractFilePredicate { | |||
private final String path; | |||
@@ -43,4 +47,15 @@ public class RelativePathPredicate implements FilePredicate { | |||
return path.equals(f.relativePath()); | |||
} | |||
@Override | |||
public Iterable<InputFile> get(Index index) { | |||
InputFile f = index.inputFile(this.path); | |||
return f != null ? Arrays.asList(f) : Collections.<InputFile>emptyList(); | |||
} | |||
@Override | |||
public int priority() { | |||
return USE_INDEX; | |||
} | |||
} |
@@ -19,13 +19,14 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.InputFile; | |||
/** | |||
* @since 4.2 | |||
*/ | |||
class StatusPredicate implements FilePredicate { | |||
class StatusPredicate extends AbstractFilePredicate { | |||
private final InputFile.Status status; | |||
@@ -19,10 +19,12 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.FileSystem.Index; | |||
import org.sonar.api.batch.fs.InputFile; | |||
class TruePredicate implements FilePredicate { | |||
class TruePredicate extends AbstractFilePredicate { | |||
static final FilePredicate TRUE = new TruePredicate(); | |||
@@ -30,4 +32,14 @@ class TruePredicate implements FilePredicate { | |||
public boolean apply(InputFile inputFile) { | |||
return true; | |||
} | |||
@Override | |||
public Iterable<InputFile> get(Index index) { | |||
return index.inputFiles(); | |||
} | |||
@Override | |||
public Iterable<InputFile> filter(Iterable<InputFile> target) { | |||
return target; | |||
} | |||
} |
@@ -19,13 +19,14 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import org.sonar.api.batch.fs.AbstractFilePredicate; | |||
import org.sonar.api.batch.fs.InputFile; | |||
/** | |||
* @since 4.2 | |||
*/ | |||
class TypePredicate implements FilePredicate { | |||
class TypePredicate extends AbstractFilePredicate { | |||
private final InputFile.Type type; | |||
@@ -39,4 +40,3 @@ class TypePredicate implements FilePredicate { | |||
} | |||
} | |||
@@ -0,0 +1,75 @@ | |||
/* | |||
* 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.fs.internal; | |||
import org.junit.Test; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import java.util.Arrays; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class AndPredicateTest { | |||
@Test | |||
public void flattenNestedAnd() { | |||
PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); | |||
PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); | |||
PathPatternPredicate pathPatternPredicate3 = new PathPatternPredicate(PathPattern.create("foo3/**")); | |||
FilePredicate andPredicate = AndPredicate.create(Arrays.<FilePredicate>asList(pathPatternPredicate1, | |||
AndPredicate.create(Arrays.<FilePredicate>asList(pathPatternPredicate2, pathPatternPredicate3)))); | |||
assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2, pathPatternPredicate3); | |||
} | |||
@Test | |||
public void sortPredicatesByPriority() { | |||
PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); | |||
PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); | |||
RelativePathPredicate relativePathPredicate = new RelativePathPredicate("foo"); | |||
FilePredicate andPredicate = AndPredicate.create(Arrays.<FilePredicate>asList(pathPatternPredicate1, | |||
relativePathPredicate, pathPatternPredicate2)); | |||
assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(relativePathPredicate, pathPatternPredicate1, pathPatternPredicate2); | |||
} | |||
@Test | |||
public void simplifyAndExpressionsWhenEmpty() { | |||
FilePredicate andPredicate = AndPredicate.create(Arrays.<FilePredicate>asList()); | |||
assertThat(andPredicate).isEqualTo(TruePredicate.TRUE); | |||
} | |||
@Test | |||
public void simplifyAndExpressionsWhenTrue() { | |||
PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); | |||
PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); | |||
FilePredicate andPredicate = AndPredicate.create(Arrays.<FilePredicate>asList(pathPatternPredicate1, | |||
TruePredicate.TRUE, pathPatternPredicate2)); | |||
assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2); | |||
} | |||
@Test | |||
public void simplifyAndExpressionsWhenFalse() { | |||
PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); | |||
PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); | |||
FilePredicate andPredicate = AndPredicate.create(Arrays.<FilePredicate>asList(pathPatternPredicate1, | |||
FalsePredicate.FALSE, pathPatternPredicate2)); | |||
assertThat(andPredicate).isEqualTo(FalsePredicate.FALSE); | |||
} | |||
} |
@@ -41,10 +41,11 @@ public class DefaultFilePredicatesTest { | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
DefaultInputFile javaFile; | |||
FilePredicates predicates = new DefaultFilePredicates(); | |||
FilePredicates predicates; | |||
@Before | |||
public void before() throws IOException { | |||
predicates = new DefaultFilePredicates(temp.newFolder()); | |||
javaFile = new DefaultInputFile("foo", "src/main/java/struts/Action.java") | |||
.setFile(temp.newFile("Action.java")) | |||
.setLanguage("java") |
@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonar.api.batch.fs.internal; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
@@ -37,12 +38,18 @@ public class DefaultFileSystemTest { | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
private DefaultFileSystem fs; | |||
private File basedir; | |||
@Before | |||
public void prepare() throws Exception { | |||
basedir = temp.newFolder(); | |||
fs = new DefaultFileSystem(basedir); | |||
} | |||
@Test | |||
public void test_directories() throws Exception { | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
File basedir = temp.newFolder(); | |||
fs.setBaseDir(basedir); | |||
assertThat(fs.baseDir()).isAbsolute().isDirectory().exists(); | |||
assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(basedir.getCanonicalPath()); | |||
@@ -54,8 +61,6 @@ public class DefaultFileSystemTest { | |||
@Test | |||
public void test_encoding() throws Exception { | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
assertThat(fs.isDefaultJvmEncoding()).isTrue(); | |||
assertThat(fs.encoding()).isEqualTo(Charset.defaultCharset()); | |||
@@ -66,8 +71,6 @@ public class DefaultFileSystemTest { | |||
@Test | |||
public void add_languages() throws Exception { | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
assertThat(fs.languages()).isEmpty(); | |||
fs.addLanguages("java", "php", "cobol"); | |||
@@ -76,8 +79,6 @@ public class DefaultFileSystemTest { | |||
@Test | |||
public void files() throws Exception { | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
assertThat(fs.inputFiles(fs.predicates().all())).isEmpty(); | |||
fs.add(new DefaultInputFile("foo", "src/Foo.php").setLanguage("php").setFile(temp.newFile())); | |||
@@ -108,7 +109,6 @@ public class DefaultFileSystemTest { | |||
@Test | |||
public void input_file_returns_null_if_file_not_found() throws Exception { | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
assertThat(fs.inputFile(fs.predicates().hasRelativePath("src/Bar.java"))).isNull(); | |||
assertThat(fs.inputFile(fs.predicates().hasLanguage("cobol"))).isNull(); | |||
} | |||
@@ -118,7 +118,6 @@ public class DefaultFileSystemTest { | |||
thrown.expect(IllegalArgumentException.class); | |||
thrown.expectMessage("expected one element"); | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java").setFile(temp.newFile())); | |||
fs.add(new DefaultInputFile("foo", "src/Baz.java").setLanguage("java").setFile(temp.newFile())); | |||
@@ -127,7 +126,6 @@ public class DefaultFileSystemTest { | |||
@Test | |||
public void input_file_supports_non_indexed_predicates() throws Exception { | |||
DefaultFileSystem fs = new DefaultFileSystem(); | |||
fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java").setFile(temp.newFile())); | |||
// it would fail if more than one java file |
@@ -0,0 +1,65 @@ | |||
/* | |||
* 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.fs.internal; | |||
import org.junit.Test; | |||
import org.sonar.api.batch.fs.FilePredicate; | |||
import java.util.Arrays; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class OrPredicateTest { | |||
@Test | |||
public void flattenNestedOr() { | |||
PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); | |||
PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); | |||
PathPatternPredicate pathPatternPredicate3 = new PathPatternPredicate(PathPattern.create("foo3/**")); | |||
FilePredicate orPredicate = OrPredicate.create(Arrays.<FilePredicate>asList(pathPatternPredicate1, | |||
OrPredicate.create(Arrays.<FilePredicate>asList(pathPatternPredicate2, pathPatternPredicate3)))); | |||
assertThat(((OrPredicate) orPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2, pathPatternPredicate3); | |||
} | |||
@Test | |||
public void simplifyOrExpressionsWhenEmpty() { | |||
FilePredicate orPredicate = OrPredicate.create(Arrays.<FilePredicate>asList()); | |||
assertThat(orPredicate).isEqualTo(TruePredicate.TRUE); | |||
} | |||
@Test | |||
public void simplifyOrExpressionsWhenFalse() { | |||
PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); | |||
PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); | |||
FilePredicate andPredicate = OrPredicate.create(Arrays.<FilePredicate>asList(pathPatternPredicate1, | |||
FalsePredicate.FALSE, pathPatternPredicate2)); | |||
assertThat(((OrPredicate) andPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2); | |||
} | |||
@Test | |||
public void simplifyAndExpressionsWhenTrue() { | |||
PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); | |||
PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); | |||
FilePredicate andPredicate = OrPredicate.create(Arrays.<FilePredicate>asList(pathPatternPredicate1, | |||
TruePredicate.TRUE, pathPatternPredicate2)); | |||
assertThat(andPredicate).isEqualTo(TruePredicate.TRUE); | |||
} | |||
} |