@@ -108,7 +108,7 @@ public class SensorContextTester implements SensorContext { | |||
private DefaultFileSystem fs; | |||
private ActiveRules activeRules; | |||
private InMemorySensorStorage sensorStorage; | |||
private InputModule module; | |||
private DefaultInputModule module; | |||
private SonarRuntime runtime; | |||
private boolean cancelled; | |||
@@ -220,7 +220,7 @@ public class SensorContextTester implements SensorContext { | |||
@Override | |||
public NewIssue newIssue() { | |||
return new DefaultIssue(sensorStorage); | |||
return new DefaultIssue(module, sensorStorage); | |||
} | |||
public Collection<Issue> allIssues() { | |||
@@ -229,7 +229,7 @@ public class SensorContextTester implements SensorContext { | |||
@Override | |||
public NewExternalIssue newExternalIssue() { | |||
return new DefaultExternalIssue(sensorStorage); | |||
return new DefaultExternalIssue(module, sensorStorage); | |||
} | |||
@Override |
@@ -20,32 +20,42 @@ | |||
package org.sonar.api.batch.sensor.issue.internal; | |||
import com.google.common.base.Preconditions; | |||
import java.nio.file.Path; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.Objects; | |||
import java.util.Optional; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.batch.fs.InputComponent; | |||
import org.sonar.api.batch.fs.internal.DefaultInputDir; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.sensor.internal.DefaultStorable; | |||
import org.sonar.api.batch.sensor.internal.SensorStorage; | |||
import org.sonar.api.batch.sensor.issue.Issue.Flow; | |||
import org.sonar.api.batch.sensor.issue.IssueLocation; | |||
import org.sonar.api.batch.sensor.issue.NewIssueLocation; | |||
import org.sonar.api.utils.PathUtils; | |||
import static com.google.common.base.Preconditions.checkState; | |||
import static com.google.common.base.Strings.isNullOrEmpty; | |||
import static java.util.Collections.unmodifiableList; | |||
import static java.util.stream.Collectors.toList; | |||
public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue> extends DefaultStorable { | |||
public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue> extends DefaultStorable { | |||
protected IssueLocation primaryLocation; | |||
protected List<List<IssueLocation>> flows = new ArrayList<>(); | |||
protected AbstractDefaultIssue() { | |||
super(null); | |||
protected DefaultInputModule projectRoot; | |||
protected AbstractDefaultIssue(DefaultInputModule projectRoot) { | |||
this(projectRoot, null); | |||
} | |||
public AbstractDefaultIssue(@Nullable SensorStorage storage) { | |||
public AbstractDefaultIssue(DefaultInputModule projectRoot, @Nullable SensorStorage storage) { | |||
super(storage); | |||
this.projectRoot = projectRoot; | |||
} | |||
public IssueLocation primaryLocation() { | |||
return primaryLocation; | |||
} | |||
@@ -55,7 +65,7 @@ public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue> exte | |||
.<Flow>map(l -> () -> unmodifiableList(new ArrayList<>(l))) | |||
.collect(toList()); | |||
} | |||
public NewIssueLocation newLocation() { | |||
return new DefaultIssueLocation(); | |||
} | |||
@@ -63,23 +73,50 @@ public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue> exte | |||
public T at(NewIssueLocation primaryLocation) { | |||
Preconditions.checkArgument(primaryLocation != null, "Cannot use a location that is null"); | |||
checkState(this.primaryLocation == null, "at() already called"); | |||
this.primaryLocation = (DefaultIssueLocation) primaryLocation; | |||
this.primaryLocation = rewriteLocation((DefaultIssueLocation) primaryLocation); | |||
Preconditions.checkArgument(this.primaryLocation.inputComponent() != null, "Cannot use a location with no input component"); | |||
return (T) this; | |||
} | |||
public T addLocation(NewIssueLocation secondaryLocation) { | |||
flows.add(Arrays.asList((IssueLocation) secondaryLocation)); | |||
flows.add(Collections.singletonList(rewriteLocation((DefaultIssueLocation) secondaryLocation))); | |||
return (T) this; | |||
} | |||
public T addFlow(Iterable<NewIssueLocation> locations) { | |||
List<IssueLocation> flowAsList = new ArrayList<>(); | |||
for (NewIssueLocation issueLocation : locations) { | |||
flowAsList.add((DefaultIssueLocation) issueLocation); | |||
flowAsList.add(rewriteLocation((DefaultIssueLocation) issueLocation)); | |||
} | |||
flows.add(flowAsList); | |||
return (T) this; | |||
} | |||
private DefaultIssueLocation rewriteLocation(DefaultIssueLocation location) { | |||
InputComponent component = location.inputComponent(); | |||
Optional<Path> dirOrModulePath = Optional.empty(); | |||
if (component instanceof DefaultInputDir) { | |||
DefaultInputDir dirComponent = (DefaultInputDir) component; | |||
dirOrModulePath = Optional.of(projectRoot.getBaseDir().relativize(dirComponent.path())); | |||
} else if (component instanceof DefaultInputModule && !Objects.equals(projectRoot.key(), component.key())) { | |||
DefaultInputModule moduleComponent = (DefaultInputModule) component; | |||
dirOrModulePath = Optional.of(projectRoot.getBaseDir().relativize(moduleComponent.getBaseDir())); | |||
} | |||
if (dirOrModulePath.isPresent()) { | |||
String path = PathUtils.sanitize(dirOrModulePath.get().toString()); | |||
DefaultIssueLocation fixedLocation = new DefaultIssueLocation(); | |||
fixedLocation.on(projectRoot); | |||
StringBuilder fullMessage = new StringBuilder(); | |||
if (!isNullOrEmpty(path)) { | |||
fullMessage.append("[").append(path).append("] "); | |||
} | |||
fullMessage.append(location.message()); | |||
fixedLocation.message(fullMessage.toString()); | |||
return fixedLocation; | |||
} else { | |||
return location; | |||
} | |||
} | |||
} |
@@ -21,6 +21,7 @@ package org.sonar.api.batch.sensor.issue.internal; | |||
import com.google.common.base.Preconditions; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.rule.Severity; | |||
import org.sonar.api.batch.sensor.internal.SensorStorage; | |||
import org.sonar.api.batch.sensor.issue.ExternalIssue; | |||
@@ -39,12 +40,12 @@ public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIs | |||
private String engineId; | |||
private String ruleId; | |||
public DefaultExternalIssue() { | |||
super(null); | |||
public DefaultExternalIssue(DefaultInputModule projectRoot) { | |||
this(projectRoot, null); | |||
} | |||
public DefaultExternalIssue(@Nullable SensorStorage storage) { | |||
super(storage); | |||
public DefaultExternalIssue(DefaultInputModule projectRoot, @Nullable SensorStorage storage) { | |||
super(projectRoot, storage); | |||
} | |||
@Override |
@@ -21,6 +21,7 @@ package org.sonar.api.batch.sensor.issue.internal; | |||
import com.google.common.base.Preconditions; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.rule.Severity; | |||
import org.sonar.api.batch.sensor.internal.SensorStorage; | |||
import org.sonar.api.batch.sensor.issue.Issue; | |||
@@ -37,12 +38,12 @@ public class DefaultIssue extends AbstractDefaultIssue<DefaultIssue> implements | |||
private Double gap; | |||
private Severity overriddenSeverity; | |||
public DefaultIssue() { | |||
super(null); | |||
public DefaultIssue(DefaultInputModule projectRoot) { | |||
this(projectRoot, null); | |||
} | |||
public DefaultIssue(@Nullable SensorStorage storage) { | |||
super(storage); | |||
public DefaultIssue(DefaultInputModule projectRoot, @Nullable SensorStorage storage) { | |||
super(projectRoot, storage); | |||
} | |||
public DefaultIssue forRule(RuleKey ruleKey) { | |||
@@ -54,7 +55,6 @@ public class DefaultIssue extends AbstractDefaultIssue<DefaultIssue> implements | |||
return this.ruleKey; | |||
} | |||
@Override | |||
public DefaultIssue gap(@Nullable Double gap) { | |||
Preconditions.checkArgument(gap == null || gap >= 0, format("Gap must be greater than or equal 0 (got %s)", gap)); |
@@ -19,11 +19,16 @@ | |||
*/ | |||
package org.sonar.api.batch.sensor.issue.internal; | |||
import java.io.IOException; | |||
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.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.fs.InputComponent; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.api.batch.rule.Severity; | |||
import org.sonar.api.batch.sensor.internal.SensorStorage; | |||
@@ -35,6 +40,20 @@ import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
public class DefaultExternalIssueTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
private DefaultInputModule projectRoot; | |||
@Before | |||
public void setup() throws IOException { | |||
projectRoot = new DefaultInputModule(ProjectDefinition.create() | |||
.setKey("foo") | |||
.setBaseDir(temp.newFolder()) | |||
.setWorkDir(temp.newFolder())); | |||
} | |||
@Rule | |||
public ExpectedException exception = ExpectedException.none(); | |||
@@ -45,7 +64,7 @@ public class DefaultExternalIssueTest { | |||
@Test | |||
public void build_file_issue() { | |||
SensorStorage storage = mock(SensorStorage.class); | |||
DefaultExternalIssue issue = new DefaultExternalIssue(storage) | |||
DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot, storage) | |||
.at(new DefaultIssueLocation() | |||
.on(inputFile) | |||
.at(inputFile.selectLine(1)) | |||
@@ -73,7 +92,7 @@ public class DefaultExternalIssueTest { | |||
@Test | |||
public void fail_to_store_if_no_type() { | |||
SensorStorage storage = mock(SensorStorage.class); | |||
DefaultExternalIssue issue = new DefaultExternalIssue(storage) | |||
DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot, storage) | |||
.at(new DefaultIssueLocation() | |||
.on(inputFile) | |||
.at(inputFile.selectLine(1)) | |||
@@ -90,7 +109,7 @@ public class DefaultExternalIssueTest { | |||
@Test | |||
public void fail_to_store_if_primary_location_is_not_a_file() { | |||
SensorStorage storage = mock(SensorStorage.class); | |||
DefaultExternalIssue issue = new DefaultExternalIssue(storage) | |||
DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot, storage) | |||
.at(new DefaultIssueLocation() | |||
.on(mock(InputComponent.class)) | |||
.message("Wrong way!")) | |||
@@ -102,11 +121,11 @@ public class DefaultExternalIssueTest { | |||
exception.expectMessage("External issues must be located in files"); | |||
issue.save(); | |||
} | |||
@Test | |||
public void fail_to_store_if_primary_location_has_no_message() { | |||
SensorStorage storage = mock(SensorStorage.class); | |||
DefaultExternalIssue issue = new DefaultExternalIssue(storage) | |||
DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot, storage) | |||
.at(new DefaultIssueLocation() | |||
.on(inputFile) | |||
.at(inputFile.selectLine(1))) | |||
@@ -123,7 +142,7 @@ public class DefaultExternalIssueTest { | |||
@Test | |||
public void fail_to_store_if_no_severity() { | |||
SensorStorage storage = mock(SensorStorage.class); | |||
DefaultExternalIssue issue = new DefaultExternalIssue(storage) | |||
DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot, storage) | |||
.at(new DefaultIssueLocation() | |||
.on(inputFile) | |||
.at(inputFile.selectLine(1)) |
@@ -19,7 +19,9 @@ | |||
*/ | |||
package org.sonar.api.batch.sensor.issue.internal; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
@@ -41,14 +43,24 @@ public class DefaultIssueTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
private DefaultInputModule projectRoot; | |||
private DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") | |||
.initMetadata("Foo\nBar\n") | |||
.build(); | |||
@Before | |||
public void prepare() throws IOException { | |||
projectRoot = new DefaultInputModule(ProjectDefinition.create() | |||
.setKey("foo") | |||
.setBaseDir(temp.newFolder()) | |||
.setWorkDir(temp.newFolder())); | |||
} | |||
@Test | |||
public void build_file_issue() { | |||
SensorStorage storage = mock(SensorStorage.class); | |||
DefaultIssue issue = new DefaultIssue(storage) | |||
DefaultIssue issue = new DefaultIssue(projectRoot, storage) | |||
.at(new DefaultIssueLocation() | |||
.on(inputFile) | |||
.at(inputFile.selectLine(1)) | |||
@@ -68,19 +80,50 @@ public class DefaultIssueTest { | |||
} | |||
@Test | |||
public void build_directory_issue() { | |||
public void move_directory_issue_to_project_root() { | |||
SensorStorage storage = mock(SensorStorage.class); | |||
DefaultIssue issue = new DefaultIssue(storage) | |||
DefaultIssue issue = new DefaultIssue(projectRoot, storage) | |||
.at(new DefaultIssueLocation() | |||
.on(new DefaultInputDir("foo", "src")) | |||
.on(new DefaultInputDir("foo", "src/main").setModuleBaseDir(projectRoot.getBaseDir())) | |||
.message("Wrong way!")) | |||
.forRule(RuleKey.of("repo", "rule")) | |||
.overrideSeverity(Severity.BLOCKER); | |||
assertThat(issue.primaryLocation().inputComponent()).isEqualTo(new DefaultInputDir("foo", "src")); | |||
assertThat(issue.primaryLocation().inputComponent()).isEqualTo(projectRoot); | |||
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); | |||
assertThat(issue.primaryLocation().textRange()).isNull(); | |||
assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!"); | |||
assertThat(issue.primaryLocation().message()).isEqualTo("[src/main] Wrong way!"); | |||
assertThat(issue.overriddenSeverity()).isEqualTo(Severity.BLOCKER); | |||
issue.save(); | |||
verify(storage).store(issue); | |||
} | |||
@Test | |||
public void move_submodule_issue_to_project_root() { | |||
File subModuleDirectory = new File(projectRoot.getBaseDir().toString(), "bar"); | |||
subModuleDirectory.mkdir(); | |||
ProjectDefinition subModuleDefinition = ProjectDefinition.create() | |||
.setKey("foo/bar") | |||
.setBaseDir(subModuleDirectory) | |||
.setWorkDir(subModuleDirectory); | |||
projectRoot.definition().addSubProject(subModuleDefinition); | |||
DefaultInputModule subModule = new DefaultInputModule(subModuleDefinition); | |||
SensorStorage storage = mock(SensorStorage.class); | |||
DefaultIssue issue = new DefaultIssue(projectRoot, storage) | |||
.at(new DefaultIssueLocation() | |||
.on(subModule) | |||
.message("Wrong way!")) | |||
.forRule(RuleKey.of("repo", "rule")) | |||
.overrideSeverity(Severity.BLOCKER); | |||
assertThat(issue.primaryLocation().inputComponent()).isEqualTo(projectRoot); | |||
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); | |||
assertThat(issue.primaryLocation().textRange()).isNull(); | |||
assertThat(issue.primaryLocation().message()).isEqualTo("[bar] Wrong way!"); | |||
assertThat(issue.overriddenSeverity()).isEqualTo(Severity.BLOCKER); | |||
issue.save(); | |||
@@ -92,7 +135,7 @@ public class DefaultIssueTest { | |||
public void build_project_issue() throws IOException { | |||
SensorStorage storage = mock(SensorStorage.class); | |||
DefaultInputModule inputModule = new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder())); | |||
DefaultIssue issue = new DefaultIssue(storage) | |||
DefaultIssue issue = new DefaultIssue(projectRoot, storage) | |||
.at(new DefaultIssueLocation() | |||
.on(inputModule) | |||
.message("Wrong way!")) |
@@ -36,6 +36,7 @@ import org.sonar.api.batch.AnalysisMode; | |||
import org.sonar.api.batch.fs.InputComponent; | |||
import org.sonar.api.batch.fs.InputDir; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.InputModule; | |||
import org.sonar.api.batch.fs.TextPointer; | |||
import org.sonar.api.batch.fs.TextRange; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
@@ -63,6 +64,7 @@ public class TaskResult implements org.sonar.scanner.mediumtest.ScanTaskObserver | |||
private Map<String, InputFile> inputFiles = new HashMap<>(); | |||
private Map<String, Component> reportComponents = new HashMap<>(); | |||
private Map<String, InputDir> inputDirs = new HashMap<>(); | |||
private InputModule root; | |||
private ScannerReportReader reader; | |||
@Override | |||
@@ -78,6 +80,8 @@ public class TaskResult implements org.sonar.scanner.mediumtest.ScanTaskObserver | |||
Metadata readMetadata = getReportReader().readMetadata(); | |||
int rootComponentRef = readMetadata.getRootComponentRef(); | |||
storeReportComponents(rootComponentRef, null); | |||
InputComponentStore inputFileCache = container.getComponentByType(InputComponentStore.class); | |||
root = inputFileCache.root(); | |||
} | |||
storeFs(container); | |||
@@ -154,6 +158,10 @@ public class TaskResult implements org.sonar.scanner.mediumtest.ScanTaskObserver | |||
return result; | |||
} | |||
public InputModule root() { | |||
return root; | |||
} | |||
public Collection<InputFile> inputFiles() { | |||
return inputFiles.values(); | |||
} |
@@ -27,6 +27,7 @@ import org.sonar.api.batch.fs.FileSystem; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.InputModule; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.InputModuleHierarchy; | |||
import org.sonar.api.batch.rule.ActiveRules; | |||
import org.sonar.api.batch.sensor.SensorContext; | |||
import org.sonar.api.batch.sensor.code.NewSignificantCode; | |||
@@ -79,9 +80,10 @@ public class DefaultSensorContext implements SensorContext { | |||
private final InputModule module; | |||
private final SonarRuntime sonarRuntime; | |||
private final Configuration config; | |||
private final InputModuleHierarchy hierarchy; | |||
public DefaultSensorContext(InputModule module, Configuration config, Settings mutableSettings, FileSystem fs, ActiveRules activeRules, | |||
AnalysisMode analysisMode, SensorStorage sensorStorage, SonarRuntime sonarRuntime) { | |||
AnalysisMode analysisMode, SensorStorage sensorStorage, SonarRuntime sonarRuntime, InputModuleHierarchy hierarchy) { | |||
this.module = module; | |||
this.config = config; | |||
this.mutableSettings = mutableSettings; | |||
@@ -90,6 +92,7 @@ public class DefaultSensorContext implements SensorContext { | |||
this.analysisMode = analysisMode; | |||
this.sensorStorage = sensorStorage; | |||
this.sonarRuntime = sonarRuntime; | |||
this.hierarchy = hierarchy; | |||
} | |||
@Override | |||
@@ -134,7 +137,7 @@ public class DefaultSensorContext implements SensorContext { | |||
@Override | |||
public NewIssue newIssue() { | |||
return new DefaultIssue(sensorStorage); | |||
return new DefaultIssue(hierarchy.root(), sensorStorage); | |||
} | |||
@Override | |||
@@ -142,7 +145,7 @@ public class DefaultSensorContext implements SensorContext { | |||
if (analysisMode.isIssues()) { | |||
return NO_OP_NEW_EXTERNAL_ISSUE; | |||
} | |||
return new DefaultExternalIssue(sensorStorage); | |||
return new DefaultExternalIssue(hierarchy.root(), sensorStorage); | |||
} | |||
@Override |
@@ -19,14 +19,20 @@ | |||
*/ | |||
package org.sonar.scanner.issue; | |||
import java.io.IOException; | |||
import java.util.Collections; | |||
import java.util.HashSet; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.junit.runner.RunWith; | |||
import org.mockito.ArgumentCaptor; | |||
import org.mockito.Mock; | |||
import org.mockito.runners.MockitoJUnitRunner; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; | |||
import org.sonar.api.batch.rule.internal.NewActiveRule; | |||
@@ -57,6 +63,11 @@ public class ModuleIssuesTest { | |||
static final String SQUID_RULE_NAME = "Avoid Cycle"; | |||
private static final RuleKey NOSONAR_RULE_KEY = RuleKey.of("squid", "NoSonarCheck"); | |||
private DefaultInputModule projectRoot; | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Mock | |||
ModuleIssueFilters filters; | |||
@@ -68,11 +79,19 @@ public class ModuleIssuesTest { | |||
DefaultInputFile file = new TestInputFileBuilder("foo", "src/Foo.php").initMetadata("Foo\nBar\nBiz\n").build(); | |||
ReportPublisher reportPublisher = mock(ReportPublisher.class, RETURNS_DEEP_STUBS); | |||
@Before | |||
public void prepare() throws IOException { | |||
projectRoot = new DefaultInputModule(ProjectDefinition.create() | |||
.setKey("foo") | |||
.setBaseDir(temp.newFolder()) | |||
.setWorkDir(temp.newFolder())); | |||
} | |||
@Test | |||
public void ignore_null_active_rule() { | |||
ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME); | |||
initModuleIssues(); | |||
DefaultIssue issue = new DefaultIssue() | |||
DefaultIssue issue = new DefaultIssue(projectRoot) | |||
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo")) | |||
.forRule(SQUID_RULE_KEY); | |||
boolean added = moduleIssues.initAndAddIssue(issue); | |||
@@ -87,7 +106,7 @@ public class ModuleIssuesTest { | |||
activeRulesBuilder.addRule(new NewActiveRule.Builder().setRuleKey(SQUID_RULE_KEY).setQProfileKey("qp-1").build()); | |||
initModuleIssues(); | |||
DefaultIssue issue = new DefaultIssue() | |||
DefaultIssue issue = new DefaultIssue(projectRoot) | |||
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo")) | |||
.forRule(SQUID_RULE_KEY); | |||
boolean added = moduleIssues.initAndAddIssue(issue); | |||
@@ -106,7 +125,7 @@ public class ModuleIssuesTest { | |||
.build()); | |||
initModuleIssues(); | |||
DefaultIssue issue = new DefaultIssue() | |||
DefaultIssue issue = new DefaultIssue(projectRoot) | |||
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo")) | |||
.forRule(SQUID_RULE_KEY) | |||
.overrideSeverity(org.sonar.api.batch.rule.Severity.CRITICAL); | |||
@@ -126,7 +145,7 @@ public class ModuleIssuesTest { | |||
ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME); | |||
initModuleIssues(); | |||
DefaultExternalIssue issue = new DefaultExternalIssue() | |||
DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot) | |||
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo")) | |||
.type(RuleType.BUG) | |||
.forRule(SQUID_RULE_KEY) | |||
@@ -149,7 +168,7 @@ public class ModuleIssuesTest { | |||
.build()); | |||
initModuleIssues(); | |||
DefaultIssue issue = new DefaultIssue() | |||
DefaultIssue issue = new DefaultIssue(projectRoot) | |||
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo")) | |||
.forRule(SQUID_RULE_KEY); | |||
when(filters.accept(anyString(), any(ScannerReport.Issue.class))).thenReturn(true); | |||
@@ -170,7 +189,7 @@ public class ModuleIssuesTest { | |||
.build()); | |||
initModuleIssues(); | |||
DefaultIssue issue = new DefaultIssue() | |||
DefaultIssue issue = new DefaultIssue(projectRoot) | |||
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("")) | |||
.forRule(SQUID_RULE_KEY); | |||
@@ -185,10 +204,14 @@ public class ModuleIssuesTest { | |||
@Test | |||
public void should_ignore_lines_commented_with_nosonar() { | |||
ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME); | |||
activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate(); | |||
activeRulesBuilder.addRule(new NewActiveRule.Builder() | |||
.setRuleKey(SQUID_RULE_KEY) | |||
.setSeverity(Severity.INFO) | |||
.setQProfileKey("qp-1") | |||
.build()); | |||
initModuleIssues(); | |||
DefaultIssue issue = new DefaultIssue() | |||
DefaultIssue issue = new DefaultIssue(projectRoot) | |||
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("")) | |||
.forRule(SQUID_RULE_KEY); | |||
@@ -204,12 +227,16 @@ public class ModuleIssuesTest { | |||
public void should_accept_issues_on_no_sonar_rules() { | |||
// The "No Sonar" rule logs violations on the lines that are flagged with "NOSONAR" !! | |||
ruleBuilder.add(NOSONAR_RULE_KEY).setName("No Sonar"); | |||
activeRulesBuilder.create(NOSONAR_RULE_KEY).setSeverity(Severity.INFO).activate(); | |||
activeRulesBuilder.addRule(new NewActiveRule.Builder() | |||
.setRuleKey(NOSONAR_RULE_KEY) | |||
.setSeverity(Severity.INFO) | |||
.setQProfileKey("qp-1") | |||
.build()); | |||
initModuleIssues(); | |||
file.noSonarAt(new HashSet<>(Collections.singletonList(3))); | |||
DefaultIssue issue = new DefaultIssue() | |||
DefaultIssue issue = new DefaultIssue(projectRoot) | |||
.at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("")) | |||
.forRule(NOSONAR_RULE_KEY); | |||
@@ -36,6 +36,7 @@ import org.junit.rules.ExpectedException; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.fs.InputDir; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.InputModule; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.utils.MessageException; | |||
import org.sonar.api.utils.System2; | |||
@@ -432,9 +433,10 @@ public class FileSystemMediumTest { | |||
.execute(); | |||
DefaultInputFile unknownInputFile = (DefaultInputFile) result.inputFile("src/unknown/file.notanalyzed"); | |||
InputDir unknownInputDir = result.inputDir("src/unknown"); | |||
InputModule root = result.root(); | |||
assertThat(unknownInputFile.isPublished()).isFalse(); | |||
assertThat(result.getReportComponent(unknownInputDir.key())).isNotNull(); | |||
assertThat(result.getReportComponent(root.key())).isNotNull(); | |||
// no issues on empty dir | |||
InputDir emptyInputDir = result.inputDir(emptyDirRelative.toString()); |
@@ -70,7 +70,8 @@ public class IssuesOnDirMediumTest { | |||
.build()) | |||
.execute(); | |||
assertThat(result.issuesFor(result.inputDir("src"))).hasSize(2); | |||
assertThat(result.issuesFor(result.inputDir("src"))).hasSize(0); | |||
assertThat(result.issuesFor(result.root())).hasSize(2); | |||
} | |||
@Test | |||
@@ -96,7 +97,8 @@ public class IssuesOnDirMediumTest { | |||
.build()) | |||
.execute(); | |||
assertThat(result.issuesFor(result.inputDir(""))).hasSize(2); | |||
assertThat(result.issuesFor(result.inputDir(""))).hasSize(0); | |||
assertThat(result.issuesFor(result.root())).hasSize(2); | |||
} | |||
} |
@@ -27,8 +27,11 @@ import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.SonarQubeSide; | |||
import org.sonar.api.SonarRuntime; | |||
import org.sonar.api.batch.AnalysisMode; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.fs.InputModule; | |||
import org.sonar.api.batch.fs.internal.DefaultFileSystem; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.InputModuleHierarchy; | |||
import org.sonar.api.batch.measure.MetricFinder; | |||
import org.sonar.api.batch.rule.ActiveRules; | |||
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; | |||
@@ -37,6 +40,7 @@ import org.sonar.api.config.internal.MapSettings; | |||
import org.sonar.api.internal.SonarRuntimeImpl; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.api.utils.Version; | |||
import org.sonar.scanner.scan.DefaultInputModuleHierarchy; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
@@ -57,6 +61,7 @@ public class DefaultSensorContextTest { | |||
private SensorStorage sensorStorage; | |||
private AnalysisMode analysisMode; | |||
private SonarRuntime runtime; | |||
private InputModuleHierarchy hierarchy; | |||
@Before | |||
public void prepare() throws Exception { | |||
@@ -69,7 +74,10 @@ public class DefaultSensorContextTest { | |||
sensorStorage = mock(SensorStorage.class); | |||
analysisMode = mock(AnalysisMode.class); | |||
runtime = SonarRuntimeImpl.forSonarQube(Version.parse("5.5"), SonarQubeSide.SCANNER); | |||
adaptor = new DefaultSensorContext(mock(InputModule.class), settings.asConfig(), settings, fs, activeRules, analysisMode, sensorStorage, runtime); | |||
hierarchy = new DefaultInputModuleHierarchy(new DefaultInputModule(ProjectDefinition.create() | |||
.setWorkDir(temp.newFolder()) | |||
.setBaseDir(temp.newFolder()).setKey("foo"))); | |||
adaptor = new DefaultSensorContext(mock(InputModule.class), settings.asConfig(), settings, fs, activeRules, analysisMode, sensorStorage, runtime, hierarchy); | |||
} | |||
@Test |
@@ -80,6 +80,7 @@ public class DefaultSensorStorageTest { | |||
private ScannerReportWriter reportWriter; | |||
private ContextPropertiesCache contextPropertiesCache = new ContextPropertiesCache(); | |||
private BranchConfiguration branchConfiguration; | |||
private DefaultInputModule projectRoot; | |||
@Before | |||
public void prepare() throws Exception { | |||
@@ -101,6 +102,11 @@ public class DefaultSensorStorageTest { | |||
underTest = new DefaultSensorStorage(metricFinder, | |||
moduleIssues, settings.asConfig(), reportPublisher, measureCache, | |||
mock(SonarCpdBlockIndex.class), contextPropertiesCache, new ScannerMetrics(), branchConfiguration); | |||
projectRoot = new DefaultInputModule(ProjectDefinition.create() | |||
.setKey("foo") | |||
.setBaseDir(temp.newFolder()) | |||
.setWorkDir(temp.newFolder())); | |||
} | |||
@Test | |||
@@ -120,7 +126,7 @@ public class DefaultSensorStorageTest { | |||
public void should_save_issue() { | |||
InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build(); | |||
DefaultIssue issue = new DefaultIssue().at(new DefaultIssueLocation().on(file)); | |||
DefaultIssue issue = new DefaultIssue(projectRoot).at(new DefaultIssueLocation().on(file)); | |||
underTest.store(issue); | |||
ArgumentCaptor<Issue> argumentCaptor = ArgumentCaptor.forClass(Issue.class); | |||
@@ -132,7 +138,7 @@ public class DefaultSensorStorageTest { | |||
public void should_save_external_issue() { | |||
InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build(); | |||
DefaultExternalIssue externalIssue = new DefaultExternalIssue().at(new DefaultIssueLocation().on(file)); | |||
DefaultExternalIssue externalIssue = new DefaultExternalIssue(projectRoot).at(new DefaultIssueLocation().on(file)); | |||
underTest.store(externalIssue); | |||
ArgumentCaptor<ExternalIssue> argumentCaptor = ArgumentCaptor.forClass(ExternalIssue.class); | |||
@@ -145,7 +151,7 @@ public class DefaultSensorStorageTest { | |||
InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").setStatus(InputFile.Status.SAME).build(); | |||
when(branchConfiguration.isShortOrPullRequest()).thenReturn(true); | |||
DefaultIssue issue = new DefaultIssue().at(new DefaultIssueLocation().on(file)); | |||
DefaultIssue issue = new DefaultIssue(projectRoot).at(new DefaultIssueLocation().on(file)); | |||
underTest.store(issue); | |||
verifyZeroInteractions(moduleIssues); |