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;
import org.sonar.batch.duplication.BlockCache;
import org.sonar.plugins.cpd.index.IndexFactory;
+import java.io.IOException;
+
import static org.fest.assertions.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, null);
sonarBridgeEngine = new DefaultCpdEngine(indexFactory, new CpdMappings(), null, null, mock(BlockCache.class), null);
settings = new Settings(new PropertyDefinitions(CpdPlugin.class));
- DefaultFileSystem fs = new DefaultFileSystem();
+ DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder());
sensor = new CpdSensor(sonarEngine, sonarBridgeEngine, settings, fs);
}
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;
SymbolReferencesSensor.class,
XooTokenizerSensor.class,
ChecksSensor.class,
+ RandomAccessSensor.class,
OneIssuePerLineSensor.class,
OneIssueOnDirPerFileSensor.class,
--- /dev/null
+/*
+ * 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")
+ .workOnLanguages(Xoo.KEY)
+ .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ if (!context.settings().hasKey(SONAR_XOO_RANDOM_ACCESS_ISSUE_PATHS)) {
+ return;
+ }
+ 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.addIssue(context.issueBuilder()
+ .ruleKey(ruleKey)
+ .onFile(file)
+ .atLine(1)
+ .message("This issue is generated on each file")
+ .build());
+ }
+}
@Test
public void provide_extensions() {
- assertThat(new XooPlugin().getExtensions()).hasSize(15);
+ assertThat(new XooPlugin().getExtensions()).hasSize(16);
}
}
baseDir = temp.newFolder();
metricFinder = mock(MetricFinder.class);
sensor = new MeasureSensor(metricFinder);
- fileSystem = new DefaultFileSystem();
+ fileSystem = new DefaultFileSystem(baseDir);
when(context.fileSystem()).thenReturn(fileSystem);
}
public void prepare() throws IOException {
baseDir = temp.newFolder();
sensor = new SymbolReferencesSensor();
- fileSystem = new DefaultFileSystem();
+ fileSystem = new DefaultFileSystem(baseDir);
when(context.fileSystem()).thenReturn(fileSystem);
}
public void prepare() throws IOException {
baseDir = temp.newFolder();
sensor = new SyntaxHighlightingSensor();
- fileSystem = new DefaultFileSystem();
+ fileSystem = new DefaultFileSystem(baseDir);
when(context.fileSystem()).thenReturn(fileSystem);
}
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);
<artifactId>sonar-batch</artifactId>
<name>SonarQube :: Batch</name>
+
+ <properties>
+ <enableBenchmarkAssertions>false</enableBenchmarkAssertions>
+ </properties>
<dependencies>
<dependency>
</plugin>
</plugins>
</build>
+
+ <profiles>
+ <profile>
+ <id>runBenchmarks</id>
+ <activation>
+ <property>
+ <name>runBenchmarks</name>
+ </property>
+ </activation>
+ <properties>
+ <enableBenchmarkAssertions>true</enableBenchmarkAssertions>
+ </properties>
+ </profile>
+ </profiles>
</project>
import org.sonar.java.api.JavaUtils;
import javax.annotation.Nullable;
+
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
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.InputFile;
+import org.sonar.api.batch.fs.internal.AbstractFilePredicate;
import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile;
/**
// only static inner classes
}
- static class KeyPredicate implements FilePredicate {
+ static class KeyPredicate extends AbstractFilePredicate {
private final String key;
KeyPredicate(String key) {
}
}
- static class DeprecatedKeyPredicate implements FilePredicate {
+ static class DeprecatedKeyPredicate extends AbstractFilePredicate {
private final String key;
DeprecatedKeyPredicate(String key) {
}
}
- static class SourceRelativePathPredicate implements FilePredicate {
+ static class SourceRelativePathPredicate extends AbstractFilePredicate {
private final String path;
SourceRelativePathPredicate(String s) {
}
}
- static class SourceDirPredicate implements FilePredicate {
+ static class SourceDirPredicate extends AbstractFilePredicate {
private final String path;
SourceDirPredicate(String s) {
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();
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 {
}
@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);
}
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class SqaleRatingDecoratorTest {
public void setUp() throws Exception {
settings = new Settings();
- fs = new DefaultFileSystem();
+ fs = new DefaultFileSystem(temp.newFolder());
fs.add(new DefaultInputFile(file.getPath())
.setLanguage("java")
.setFile(temp.newFile("Foo.java")));
@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);
}
--- /dev/null
+/*
+ * 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));
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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.BatchMediumTester.TaskResult;
+import org.sonar.batch.mediumtest.Benchmark;
+import org.sonar.batch.protocol.input.ActiveRule;
+import org.sonar.xoo.XooPlugin;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.fest.assertions.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"))
+ .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor"))
+ .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;
+ }
+
+}
*/
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;
import static org.fest.assertions.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);
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 {
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);
*/
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;
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);
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.SensorContext;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.index.ComponentDataCache;
+import java.io.IOException;
+
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
@Rule
public ExpectedException thrown = ExpectedException.none();
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
private ActiveRules activeRules;
private DefaultFileSystem fs;
private SensorContextAdaptor adaptor;
private ResourcePerspectives resourcePerspectives;
@Before
- public void prepare() {
+ public void prepare() throws IOException {
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);
sensorContext = mock(SensorContext.class);
@Rule
public TemporaryFolder temp = new TemporaryFolder();
- File baseDir;
- DefaultFileSystem fs = new DefaultFileSystem();
- SonarIndex sonarIndex;
- AbstractLanguage cobolLanguage;
- Project project;
- Settings settings;
+ private File baseDir;
+ private DefaultFileSystem fs;
+ private SonarIndex sonarIndex;
+ private AbstractLanguage cobolLanguage;
+ private Project project;
+ private Settings settings;
- String aClaess;
- String explicacao;
+ private String aClaess;
+ private String explicacao;
@Before
public void prepare() throws IOException {
baseDir = temp.newFolder();
+ fs = new DefaultFileSystem(baseDir);
sonarIndex = mock(SonarIndex.class);
project = mock(Project.class);
settings = new Settings();
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);
RuleFinder ruleFinder = mock(RuleFinder.class);
Settings settings = new Settings();
private UserFinder userFinder;
@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");
@Test
public void should_export_issues_to_file() throws IOException {
- File workDir = temporaryFolder.newFolder("sonar");
+ File workDir = temp.newFolder("sonar");
fs.setWorkDir(workDir);
Rule rule = Rule.create("squid", "AvoidCycles").setName("Avoid Cycles");
*/
package org.sonar.batch.scan2;
-import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
-
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.InputFile;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
+import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
import org.sonar.api.rule.RuleKey;
+
import static org.fest.assertions.Assertions.assertThat;
public class AnalyzerOptimizerTest {
- DefaultFileSystem fs = new DefaultFileSystem();
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
@Rule
public ExpectedException thrown = ExpectedException.none();
+
+ private DefaultFileSystem fs;
private AnalyzerOptimizer optimizer;
@Before
- public void prepare() {
+ public void prepare() throws Exception {
+ fs = new DefaultFileSystem(temp.newFolder());
optimizer = new AnalyzerOptimizer(fs, new ActiveRulesBuilder().build());
}
*/
package org.sonar.api.batch.fs;
+
/**
* 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 {
+ /**
+ * Test if provided file is valid for this predicate
+ */
boolean apply(InputFile inputFile);
+
}
* Languages detected in all files, whatever their type (main or test)
*/
SortedSet<String> languages();
+
+ /**
+ * Interface of the underlying file index.
+ */
+ public static interface Index {
+ Iterable<InputFile> inputFiles();
+
+ @CheckForNull
+ InputFile inputFile(String relativePath);
+
+ @CheckForNull
+ InputDir inputDir(String relativePath);
+ }
}
*/
package org.sonar.api.batch.fs.internal;
-import org.sonar.api.batch.fs.FilePredicate;
+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);
}
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;
+ }
}
--- /dev/null
+/*
+ * 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 com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.sonar.api.batch.fs.FilePredicate;
+import org.sonar.api.batch.fs.FileSystem.Index;
+import org.sonar.api.batch.fs.InputFile;
+
+/**
+ * Partial implementation of {@link FilePredicate}.
+ * @since 5.1
+ */
+public abstract class AbstractFilePredicate implements OptimizedFilePredicate {
+
+ 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 final int compareTo(OptimizedFilePredicate o) {
+ return o.priority() - priority();
+ }
+
+}
*/
package org.sonar.api.batch.fs.internal;
+import com.google.common.annotations.VisibleForTesting;
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<OptimizedFilePredicate> predicates = new ArrayList<OptimizedFilePredicate>();
- 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(OptimizedFilePredicateAdapter.create(filePredicate));
+ }
+ }
+ Collections.sort(result.predicates);
+ return result;
}
@Override
public boolean apply(InputFile f) {
- for (FilePredicate predicate : predicates) {
+ for (OptimizedFilePredicate predicate : predicates) {
if (!predicate.apply(f)) {
return false;
}
return true;
}
+ @Override
+ public Iterable<InputFile> filter(Iterable<InputFile> target) {
+ Iterable<InputFile> result = target;
+ for (OptimizedFilePredicate 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<OptimizedFilePredicate> predicates() {
+ return predicates;
+ }
+
}
* @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;
}
/**
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
*/
public FilePredicate hasRelativePath(String s) {
return new RelativePathPredicate(s);
}
public FilePredicate or(Collection<FilePredicate> or) {
- return new OrPredicate(or);
+ return OrPredicate.create(or);
}
public FilePredicate or(FilePredicate... or) {
- return new OrPredicate(Arrays.asList(or));
+ return OrPredicate.create(Arrays.asList(or));
}
public FilePredicate or(FilePredicate first, FilePredicate second) {
- return new OrPredicate(Arrays.asList(first, second));
+ return OrPredicate.create(Arrays.asList(first, second));
}
public FilePredicate and(Collection<FilePredicate> and) {
- return new AndPredicate(and);
+ return AndPredicate.create(and);
}
public FilePredicate and(FilePredicate... and) {
- return new AndPredicate(Arrays.asList(and));
+ return AndPredicate.create(Arrays.asList(and));
}
public FilePredicate and(FilePredicate first, FilePredicate second) {
- return new AndPredicate(Arrays.asList(first, second));
+ return AndPredicate.create(Arrays.asList(first, second));
}
}
*/
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;
import java.io.File;
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;
private final Cache cache;
private final SortedSet<String> languages = new TreeSet<String>();
- private File baseDir, workDir;
+ private 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
return baseDir;
}
+ public void setBaseDir(File baseDir) {
+ this.baseDir = baseDir;
+ }
+
public DefaultFileSystem setEncoding(@Nullable Charset e) {
this.encoding = e;
return this;
@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()) {
@Override
public Iterable<InputFile> inputFiles(FilePredicate predicate) {
doPreloadFiles();
- return filter(cache.inputFiles(), predicate);
+ return OptimizedFilePredicateAdapter.create(predicate).get(cache);
}
@Override
public boolean hasFiles(FilePredicate predicate) {
- doPreloadFiles();
- for (InputFile element : cache.inputFiles()) {
- if (predicate.apply(element)) {
- return true;
- }
- }
- return false;
+ return inputFiles(predicate).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
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.
*/
// 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);
}
@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);
}
package org.sonar.api.batch.fs.internal;
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();
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();
+ }
}
*/
package org.sonar.api.batch.fs.internal;
-import org.sonar.api.batch.fs.FilePredicate;
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) {
/**
* @since 4.2
*/
-class NotPredicate implements FilePredicate {
+class NotPredicate extends AbstractFilePredicate {
private final FilePredicate predicate;
--- /dev/null
+/*
+ * 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.sonar.api.batch.fs.FilePredicate;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+
+/**
+ * Optimized version of FilePredicate allowing to speed up query by looking at InputFile by index.
+ */
+public interface OptimizedFilePredicate extends FilePredicate, Comparable<OptimizedFilePredicate> {
+
+ /**
+ * 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();
+}
--- /dev/null
+/*
+ * 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.sonar.api.batch.fs.FilePredicate;
+import org.sonar.api.batch.fs.InputFile;
+
+class OptimizedFilePredicateAdapter extends AbstractFilePredicate {
+
+ private FilePredicate unoptimizedPredicate;
+
+ private OptimizedFilePredicateAdapter(FilePredicate unoptimizedPredicate) {
+ this.unoptimizedPredicate = unoptimizedPredicate;
+ }
+
+ @Override
+ public boolean apply(InputFile inputFile) {
+ return unoptimizedPredicate.apply(inputFile);
+ }
+
+ public static OptimizedFilePredicate create(FilePredicate predicate) {
+ if (predicate instanceof OptimizedFilePredicate) {
+ return (OptimizedFilePredicate) predicate;
+ } else {
+ return new OptimizedFilePredicateAdapter(predicate);
+ }
+ }
+
+}
*/
package org.sonar.api.batch.fs.internal;
+import com.google.common.annotations.VisibleForTesting;
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<FilePredicate>();
- 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
return false;
}
+ @VisibleForTesting
+ Collection<FilePredicate> predicates() {
+ return predicates;
+ }
+
}
*/
package org.sonar.api.batch.fs.internal;
-import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.InputFile;
/**
* @since 4.2
*/
-class PathPatternPredicate implements FilePredicate {
+class PathPatternPredicate extends AbstractFilePredicate {
private final PathPattern pattern;
*/
package org.sonar.api.batch.fs.internal;
-import org.sonar.api.batch.fs.FilePredicate;
+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;
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;
+ }
+
}
*/
package org.sonar.api.batch.fs.internal;
-import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.InputFile;
/**
* @since 4.2
*/
-class StatusPredicate implements FilePredicate {
+class StatusPredicate extends AbstractFilePredicate {
private final InputFile.Status status;
package org.sonar.api.batch.fs.internal;
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();
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;
+ }
}
*/
package org.sonar.api.batch.fs.internal;
-import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.InputFile;
/**
* @since 4.2
*/
-class TypePredicate implements FilePredicate {
+class TypePredicate extends AbstractFilePredicate {
private final InputFile.Type type;
}
}
-
--- /dev/null
+/*
+ * 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.fest.assertions.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()).containsOnly(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()).containsOnly(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()).containsOnly(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);
+ }
+
+}
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("src/main/java/struts/Action.java")
.setFile(temp.newFile("Action.java"))
.setLanguage("java")
*/
package org.sonar.api.batch.fs.internal;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@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());
@Test
public void test_encoding() throws Exception {
- DefaultFileSystem fs = new DefaultFileSystem();
-
assertThat(fs.isDefaultJvmEncoding()).isTrue();
assertThat(fs.encoding()).isEqualTo(Charset.defaultCharset());
@Test
public void add_languages() throws Exception {
- DefaultFileSystem fs = new DefaultFileSystem();
-
assertThat(fs.languages()).isEmpty();
fs.addLanguages("java", "php", "cobol");
@Test
public void files() throws Exception {
- DefaultFileSystem fs = new DefaultFileSystem();
-
assertThat(fs.inputFiles(fs.predicates().all())).isEmpty();
fs.add(new DefaultInputFile("src/Foo.php").setLanguage("php").setFile(temp.newFile()));
@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();
}
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("expected one element");
- DefaultFileSystem fs = new DefaultFileSystem();
fs.add(new DefaultInputFile("src/Bar.java").setLanguage("java").setFile(temp.newFile()));
fs.add(new DefaultInputFile("src/Baz.java").setLanguage("java").setFile(temp.newFile()));
@Test
public void input_file_supports_non_indexed_predicates() throws Exception {
- DefaultFileSystem fs = new DefaultFileSystem();
fs.add(new DefaultInputFile("src/Bar.java").setLanguage("java").setFile(temp.newFile()));
// it would fail if more than one java file
--- /dev/null
+/*
+ * 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.fest.assertions.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()).containsOnly(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()).containsOnly(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);
+ }
+
+}