/* * SonarQube Java * Copyright (C) 2012-2016 SonarSource SA * mailto:contact AT sonarsource DOT com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.sonar.java; import com.google.common.collect.Lists; import org.junit.Test; import org.mockito.Mockito; import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextPointer; import org.sonar.api.batch.fs.TextRange; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.issue.IssueLocation; import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; import org.sonar.api.rule.RuleKey; import java.util.ArrayList; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; public class JavaIssueTest { @Test public void testIssueCreation() { DefaultInputFile file = new DefaultInputFile("module", "relPath"); file.setLines(3); file.setOriginalLineOffsets(new int[]{0, 10, 15}); file.setLastValidOffset(25); RuleKey ruleKey = RuleKey.of("squid", "ruleKey"); SensorContext sensorContext = mock(SensorContext.class); SensorStorage storage = mock(SensorStorage.class); DefaultIssue newIssue = new DefaultIssue(storage); DefaultIssue newIssueOnFile = new DefaultIssue(storage); DefaultIssue newIssueOnLine = new DefaultIssue(storage); Mockito.when(sensorContext.newIssue()).thenReturn(newIssue, newIssueOnFile, newIssueOnLine); // issue with secondary locations JavaIssue javaIssue = JavaIssue.create(sensorContext, ruleKey, null); javaIssue.setPrimaryLocation(file, "main message", 1, 2, 1, 6); javaIssue.addSecondaryLocation(file, 2, 2, 2, 4, "secondary message 1"); javaIssue.addSecondaryLocation(file, 3, 1, 3, 5, "secondary message 2"); javaIssue.save(); Mockito.verify(storage, Mockito.times(1)).store(newIssue); assertThat(newIssue.ruleKey()).isEqualTo(ruleKey); assertLocation(newIssue.primaryLocation(), file, "main message", 1, 2, 1, 6); assertThat(newIssue.flows()).hasSize(2); assertLocation(newIssue.flows().get(0).locations().get(0), file, "secondary message 1", 2, 2, 2, 4); assertLocation(newIssue.flows().get(1).locations().get(0), file, "secondary message 2", 3, 1, 3, 5); // issue on file javaIssue = JavaIssue.create(sensorContext, ruleKey, null); javaIssue.setPrimaryLocationOnFile(file, "file message"); javaIssue.save(); Mockito.verify(storage, Mockito.times(1)).store(newIssueOnFile); assertThat(newIssueOnFile.ruleKey()).isEqualTo(ruleKey); IssueLocation location = newIssueOnFile.primaryLocation(); assertThat(location.inputComponent()).isEqualTo(file); assertThat(location.textRange()).isNull(); assertThat(location.message()).isEqualTo("file message"); // issue on entire line javaIssue = JavaIssue.create(sensorContext, ruleKey, null); javaIssue.setPrimaryLocation(file, "line message", 2, -1, 2, -1); javaIssue.save(); Mockito.verify(storage, Mockito.times(1)).store(newIssueOnLine); assertLocation(newIssueOnLine.primaryLocation(), file, "line message", 2, 0, 2, 4); } @Test public void test_addFlow() throws Exception { DefaultInputFile file = new DefaultInputFile("module", "relPath"); file.setModuleBaseDir(new java.io.File("").toPath()); file.setLines(3); file.setOriginalLineOffsets(new int[]{0, 10, 15}); file.setLastValidOffset(25); RuleKey ruleKey = RuleKey.of("squid", "ruleKey"); SensorContext sensorContext = mock(SensorContext.class); SensorStorage storage = mock(SensorStorage.class); DefaultIssue newIssueEmptyFlow = new DefaultIssue(storage); DefaultIssue newIssueWithFlow = new DefaultIssue(storage); Mockito.when(sensorContext.newIssue()).thenReturn(newIssueEmptyFlow, newIssueWithFlow); JavaIssue javaIssue = JavaIssue.create(sensorContext, ruleKey, null); javaIssue.setPrimaryLocation(file, "main message", 1, 2, 1, 6); javaIssue.addFlow(file, new ArrayList<>()); javaIssue.save(); Mockito.verify(storage, Mockito.times(1)).store(newIssueEmptyFlow); assertThat(newIssueEmptyFlow.flows()).isEmpty(); javaIssue = JavaIssue.create(sensorContext, ruleKey, null); javaIssue.setPrimaryLocation(file, "main message", 1, 2, 1, 6); List<List<AnalyzerMessage>> flows = new ArrayList<>(); flows.add( Lists.newArrayList( new AnalyzerMessage(null, file.file(), new AnalyzerMessage.TextSpan(2,2,2,4), "flow message 1", 0))); flows.add( Lists.newArrayList( new AnalyzerMessage(null, file.file(), new AnalyzerMessage.TextSpan(3,1,3,5), "flow message 2", 0))); javaIssue.addFlow(file, flows); javaIssue.save(); Mockito.verify(storage, Mockito.times(1)).store(newIssueWithFlow); assertThat(newIssueWithFlow.flows()).hasSize(2); } private static void assertLocation(IssueLocation location, InputFile file, String message, int startLine, int startOffset, int endLine, int endOffset) { assertThat(location.inputComponent()).isEqualTo(file); assertThat(location.message()).isEqualTo(message); TextRange textRange = location.textRange(); TextPointer start = textRange.start(); assertThat(start.line()).isEqualTo(startLine); assertThat(start.lineOffset()).isEqualTo(startOffset); TextPointer end = textRange.end(); assertThat(end.line()).isEqualTo(endLine); assertThat(end.lineOffset()).isEqualTo(endOffset); } }