You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SensorContextTesterTest.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.api.batch.sensor.internal;
  21. import java.io.File;
  22. import java.io.IOException;
  23. import org.junit.Before;
  24. import org.junit.Rule;
  25. import org.junit.Test;
  26. import org.junit.rules.ExpectedException;
  27. import org.junit.rules.TemporaryFolder;
  28. import org.sonar.api.batch.bootstrap.ProjectDefinition;
  29. import org.sonar.api.batch.fs.InputFile;
  30. import org.sonar.api.batch.fs.internal.DefaultFileSystem;
  31. import org.sonar.api.batch.fs.internal.DefaultInputFile;
  32. import org.sonar.api.batch.fs.internal.DefaultInputModule;
  33. import org.sonar.api.batch.fs.internal.DefaultTextPointer;
  34. import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
  35. import org.sonar.api.batch.rule.ActiveRules;
  36. import org.sonar.api.batch.rule.Severity;
  37. import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
  38. import org.sonar.api.batch.rule.internal.NewActiveRule;
  39. import org.sonar.api.batch.sensor.error.AnalysisError;
  40. import org.sonar.api.batch.sensor.error.NewAnalysisError;
  41. import org.sonar.api.batch.sensor.highlighting.TypeOfText;
  42. import org.sonar.api.batch.sensor.issue.NewExternalIssue;
  43. import org.sonar.api.batch.sensor.issue.NewIssue;
  44. import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
  45. import org.sonar.api.config.internal.MapSettings;
  46. import org.sonar.api.measures.CoreMetrics;
  47. import org.sonar.api.rule.RuleKey;
  48. import org.sonar.api.rules.RuleType;
  49. import static org.assertj.core.api.Assertions.assertThat;
  50. import static org.assertj.core.api.Assertions.tuple;
  51. import static org.assertj.core.data.MapEntry.entry;
  52. public class SensorContextTesterTest {
  53. @Rule
  54. public TemporaryFolder temp = new TemporaryFolder();
  55. @Rule
  56. public ExpectedException exception = ExpectedException.none();
  57. private SensorContextTester tester;
  58. private File baseDir;
  59. @Before
  60. public void prepare() throws Exception {
  61. baseDir = temp.newFolder();
  62. tester = SensorContextTester.create(baseDir);
  63. }
  64. @Test
  65. public void testSettings() {
  66. MapSettings settings = new MapSettings();
  67. settings.setProperty("foo", "bar");
  68. tester.setSettings(settings);
  69. assertThat(tester.config().get("foo")).contains("bar");
  70. }
  71. @Test
  72. public void testActiveRules() {
  73. NewActiveRule activeRule = new NewActiveRule.Builder()
  74. .setRuleKey(RuleKey.of("foo", "bar"))
  75. .build();
  76. ActiveRules activeRules = new ActiveRulesBuilder().addRule(activeRule).build();
  77. tester.setActiveRules(activeRules);
  78. assertThat(tester.activeRules().findAll()).hasSize(1);
  79. }
  80. @Test
  81. public void testFs() throws Exception {
  82. DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder());
  83. tester.setFileSystem(fs);
  84. assertThat(tester.fileSystem().baseDir()).isNotEqualTo(baseDir);
  85. }
  86. @Test
  87. public void testIssues() {
  88. assertThat(tester.allIssues()).isEmpty();
  89. NewIssue newIssue = tester.newIssue();
  90. newIssue
  91. .at(newIssue.newLocation().on(new TestInputFileBuilder("foo", "src/Foo.java").build()))
  92. .forRule(RuleKey.of("repo", "rule"))
  93. .save();
  94. newIssue = tester.newIssue();
  95. newIssue
  96. .at(newIssue.newLocation().on(new TestInputFileBuilder("foo", "src/Foo.java").build()))
  97. .forRule(RuleKey.of("repo", "rule"))
  98. .save();
  99. assertThat(tester.allIssues()).hasSize(2);
  100. }
  101. @Test
  102. public void testExternalIssues() {
  103. assertThat(tester.allExternalIssues()).isEmpty();
  104. NewExternalIssue newExternalIssue = tester.newExternalIssue();
  105. newExternalIssue
  106. .at(newExternalIssue.newLocation().message("message").on(new TestInputFileBuilder("foo", "src/Foo.java").build()))
  107. .forRule(RuleKey.of("repo", "rule"))
  108. .type(RuleType.BUG)
  109. .severity(Severity.BLOCKER)
  110. .save();
  111. newExternalIssue = tester.newExternalIssue();
  112. newExternalIssue
  113. .at(newExternalIssue.newLocation().message("message").on(new TestInputFileBuilder("foo", "src/Foo.java").build()))
  114. .type(RuleType.BUG)
  115. .severity(Severity.BLOCKER)
  116. .forRule(RuleKey.of("repo", "rule"))
  117. .save();
  118. assertThat(tester.allExternalIssues()).hasSize(2);
  119. }
  120. @Test
  121. public void testAnalysisErrors() {
  122. assertThat(tester.allAnalysisErrors()).isEmpty();
  123. NewAnalysisError newAnalysisError = tester.newAnalysisError();
  124. InputFile file = new TestInputFileBuilder("foo", "src/Foo.java").build();
  125. newAnalysisError.onFile(file)
  126. .message("error")
  127. .at(new DefaultTextPointer(5, 2))
  128. .save();
  129. assertThat(tester.allAnalysisErrors()).hasSize(1);
  130. AnalysisError analysisError = tester.allAnalysisErrors().iterator().next();
  131. assertThat(analysisError.inputFile()).isEqualTo(file);
  132. assertThat(analysisError.message()).isEqualTo("error");
  133. assertThat(analysisError.location()).isEqualTo(new DefaultTextPointer(5, 2));
  134. }
  135. @Test
  136. public void testMeasures() throws IOException {
  137. assertThat(tester.measures("foo:src/Foo.java")).isEmpty();
  138. assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNull();
  139. tester.<Integer>newMeasure()
  140. .on(new TestInputFileBuilder("foo", "src/Foo.java").build())
  141. .forMetric(CoreMetrics.NCLOC)
  142. .withValue(2)
  143. .save();
  144. assertThat(tester.measures("foo:src/Foo.java")).hasSize(1);
  145. assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull();
  146. tester.<Integer>newMeasure()
  147. .on(new TestInputFileBuilder("foo", "src/Foo.java").build())
  148. .forMetric(CoreMetrics.LINES)
  149. .withValue(4)
  150. .save();
  151. assertThat(tester.measures("foo:src/Foo.java")).hasSize(2);
  152. assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull();
  153. assertThat(tester.measure("foo:src/Foo.java", "lines")).isNotNull();
  154. tester.<Integer>newMeasure()
  155. .on(new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder())))
  156. .forMetric(CoreMetrics.DIRECTORIES)
  157. .withValue(4)
  158. .save();
  159. assertThat(tester.measures("foo")).hasSize(1);
  160. assertThat(tester.measure("foo", "directories")).isNotNull();
  161. }
  162. @Test(expected = IllegalStateException.class)
  163. public void duplicateMeasures() {
  164. tester.<Integer>newMeasure()
  165. .on(new TestInputFileBuilder("foo", "src/Foo.java").build())
  166. .forMetric(CoreMetrics.NCLOC)
  167. .withValue(2)
  168. .save();
  169. tester.<Integer>newMeasure()
  170. .on(new TestInputFileBuilder("foo", "src/Foo.java").build())
  171. .forMetric(CoreMetrics.NCLOC)
  172. .withValue(2)
  173. .save();
  174. }
  175. @Test
  176. public void testHighlighting() {
  177. assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 3)).isEmpty();
  178. tester.newHighlighting()
  179. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build())
  180. .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION)
  181. .highlight(1, 8, 1, 10, TypeOfText.CONSTANT)
  182. .highlight(1, 9, 1, 10, TypeOfText.COMMENT)
  183. .save();
  184. assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 3)).containsExactly(TypeOfText.ANNOTATION);
  185. assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 9)).containsExactly(TypeOfText.CONSTANT, TypeOfText.COMMENT);
  186. }
  187. @Test(expected = UnsupportedOperationException.class)
  188. public void duplicateHighlighting() {
  189. tester.newHighlighting()
  190. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build())
  191. .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION)
  192. .save();
  193. tester.newHighlighting()
  194. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build())
  195. .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION)
  196. .save();
  197. }
  198. @Test
  199. public void testSymbolReferences() {
  200. assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 0)).isNull();
  201. NewSymbolTable symbolTable = tester.newSymbolTable()
  202. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build());
  203. symbolTable
  204. .newSymbol(1, 8, 1, 10);
  205. symbolTable
  206. .newSymbol(1, 1, 1, 5)
  207. .newReference(1, 10, 1, 13);
  208. symbolTable.save();
  209. assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 0)).isNull();
  210. assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 8)).isEmpty();
  211. assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 3))
  212. .extracting("start.line", "start.lineOffset", "end.line", "end.lineOffset")
  213. .containsExactly(tuple(1, 10, 1, 13));
  214. }
  215. @Test(expected = UnsupportedOperationException.class)
  216. public void duplicateSymbolReferences() {
  217. NewSymbolTable symbolTable = tester.newSymbolTable()
  218. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build());
  219. symbolTable
  220. .newSymbol(1, 8, 1, 10);
  221. symbolTable.save();
  222. symbolTable = tester.newSymbolTable()
  223. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build());
  224. symbolTable
  225. .newSymbol(1, 8, 1, 10);
  226. symbolTable.save();
  227. }
  228. @Test
  229. public void testCoverageAtLineZero() {
  230. assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull();
  231. assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull();
  232. exception.expect(IllegalStateException.class);
  233. tester.newCoverage()
  234. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build())
  235. .lineHits(0, 3);
  236. }
  237. @Test
  238. public void testCoverageAtLineOutOfRange() {
  239. assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull();
  240. assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull();
  241. exception.expect(IllegalStateException.class);
  242. tester.newCoverage()
  243. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build())
  244. .lineHits(4, 3);
  245. }
  246. @Test
  247. public void testLineHits() {
  248. assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull();
  249. assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull();
  250. tester.newCoverage()
  251. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build())
  252. .lineHits(1, 2)
  253. .lineHits(2, 3)
  254. .save();
  255. assertThat(tester.lineHits("foo:src/Foo.java", 1)).isEqualTo(2);
  256. assertThat(tester.lineHits("foo:src/Foo.java", 2)).isEqualTo(3);
  257. }
  258. public void multipleCoverage() {
  259. tester.newCoverage()
  260. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build())
  261. .lineHits(1, 2)
  262. .conditions(3, 4, 2)
  263. .save();
  264. tester.newCoverage()
  265. .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build())
  266. .lineHits(1, 2)
  267. .conditions(3, 4, 3)
  268. .save();
  269. assertThat(tester.lineHits("foo:src/Foo.java", 1)).isEqualTo(4);
  270. assertThat(tester.conditions("foo:src/Foo.java", 3)).isEqualTo(4);
  271. assertThat(tester.coveredConditions("foo:src/Foo.java", 3)).isEqualTo(3);
  272. }
  273. @Test
  274. public void testConditions() {
  275. assertThat(tester.conditions("foo:src/Foo.java", 1)).isNull();
  276. assertThat(tester.coveredConditions("foo:src/Foo.java", 1)).isNull();
  277. tester.newCoverage()
  278. .onFile(new TestInputFileBuilder("foo", "src/Foo.java")
  279. .initMetadata("annot dsf fds foo bar\nasd\nasdas\nasdfas")
  280. .build())
  281. .conditions(1, 4, 2)
  282. .save();
  283. assertThat(tester.conditions("foo:src/Foo.java", 1)).isEqualTo(4);
  284. assertThat(tester.coveredConditions("foo:src/Foo.java", 1)).isEqualTo(2);
  285. }
  286. @Test
  287. public void testCpdTokens() {
  288. assertThat(tester.cpdTokens("foo:src/Foo.java")).isNull();
  289. DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java")
  290. .initMetadata("public class Foo {\n\n}")
  291. .build();
  292. tester.newCpdTokens()
  293. .onFile(inputFile)
  294. .addToken(inputFile.newRange(0, 6), "public")
  295. .addToken(inputFile.newRange(7, 12), "class")
  296. .addToken(inputFile.newRange(13, 16), "$IDENTIFIER")
  297. .addToken(inputFile.newRange(17, 18), "{")
  298. .addToken(inputFile.newRange(3, 0, 3, 1), "}")
  299. .save();
  300. assertThat(tester.cpdTokens("foo:src/Foo.java")).extracting("value", "startLine", "startUnit", "endUnit")
  301. .containsExactly(
  302. tuple("publicclass$IDENTIFIER{", 1, 1, 4),
  303. tuple("}", 3, 5, 5));
  304. }
  305. @Test(expected = UnsupportedOperationException.class)
  306. public void duplicateCpdTokens() {
  307. DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java")
  308. .initMetadata("public class Foo {\n\n}")
  309. .build();
  310. tester.newCpdTokens()
  311. .onFile(inputFile)
  312. .addToken(inputFile.newRange(0, 6), "public")
  313. .save();
  314. tester.newCpdTokens()
  315. .onFile(inputFile)
  316. .addToken(inputFile.newRange(0, 6), "public")
  317. .save();
  318. }
  319. @Test
  320. public void testCancellation() {
  321. assertThat(tester.isCancelled()).isFalse();
  322. tester.setCancelled(true);
  323. assertThat(tester.isCancelled()).isTrue();
  324. }
  325. @Test
  326. public void testContextProperties() {
  327. assertThat(tester.getContextProperties()).isEmpty();
  328. tester.addContextProperty("foo", "bar");
  329. assertThat(tester.getContextProperties()).containsOnly(entry("foo", "bar"));
  330. }
  331. }