|
30 | 30 | import org.antlr.v4.runtime.Token; |
31 | 31 | import org.antlr.v4.runtime.Vocabulary; |
32 | 32 | import org.junit.jupiter.api.Test; |
| 33 | +import org.junit.jupiter.params.ParameterizedTest; |
| 34 | +import org.junit.jupiter.params.provider.ValueSource; |
33 | 35 | import org.sonar.api.batch.fs.InputFile; |
34 | 36 | import org.sonar.api.batch.sensor.highlighting.TypeOfText; |
35 | 37 | import org.sonar.api.batch.sensor.internal.SensorContextTester; |
|
45 | 47 | import java.util.stream.IntStream; |
46 | 48 |
|
47 | 49 | import static org.assertj.core.api.Assertions.assertThat; |
| 50 | +import static org.assertj.core.api.Assertions.assertThatNoException; |
48 | 51 | import static org.mockito.Mockito.mock; |
49 | 52 | import static org.mockito.Mockito.when; |
50 | 53 |
|
@@ -130,6 +133,56 @@ void testMergeHighlightingTokens() { |
130 | 133 |
|
131 | 134 | } |
132 | 135 |
|
| 136 | + @ParameterizedTest(name = "{0}") |
| 137 | + @ValueSource(strings = { |
| 138 | + // Tab-indented query: ensures tabs producing position differences do not crash highlighting. |
| 139 | + "highlightLongQuery.bsl", |
| 140 | + // СГРУППИРОВАТЬ ПО on separate BSL continuation lines -> single multiline SDBL token. |
| 141 | + "highlightCrmQuery.bsl", |
| 142 | + // ИНДЕКСИРОВАТЬ ПО on separate lines (reproduces PR #424 comment from ERP 2.5 module). |
| 143 | + "highlightErpIndexByQuery.bsl", |
| 144 | + // Real-world reproducer from issue #318 (CRM_КлиентыСервер.bsl attachment). |
| 145 | + "CRM_КлиентыСервер.bsl" |
| 146 | + }) |
| 147 | + void testHighlightingDoesNotThrowOnFile(String fileName) { |
| 148 | + // given |
| 149 | + context = SensorContextTester.create(Path.of(".")); |
| 150 | + highlighter = new BSLHighlighter(context); |
| 151 | + var baseDirName = "src/test/resources/examples"; |
| 152 | + var path = Path.of(baseDirName, fileName); |
| 153 | + documentContext = BSLLSBinding.getServerContext().addDocument(path.toUri()); |
| 154 | + BSLLSBinding.getServerContext().rebuildDocument(documentContext); |
| 155 | + inputFile = Tools.inputFileBSL(fileName, Path.of(baseDirName).toFile()); |
| 156 | + |
| 157 | + // when/then - should not throw, even for multiline SDBL tokens or tab-indented queries |
| 158 | + assertThatNoException().isThrownBy(() -> |
| 159 | + highlighter.saveHighlighting(inputFile, documentContext) |
| 160 | + ); |
| 161 | + } |
| 162 | + |
| 163 | + @Test |
| 164 | + void testSaveHighlightingWithInvalidTokenPosition() { |
| 165 | + // given |
| 166 | + context = SensorContextTester.create(Path.of(".")); |
| 167 | + highlighter = new BSLHighlighter(context); |
| 168 | + documentContext = mock(DocumentContext.class); |
| 169 | + |
| 170 | + // Create a token with position exceeding line length |
| 171 | + var token = new CommonToken(BSLLexer.IF_KEYWORD, "Если"); |
| 172 | + token.setLine(1); |
| 173 | + token.setCharPositionInLine(20); |
| 174 | + |
| 175 | + when(documentContext.getTokens()).thenReturn(List.of(token)); |
| 176 | + |
| 177 | + // Create InputFile with short content (line has less than 20 characters) |
| 178 | + inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR, "А = 1;"); |
| 179 | + |
| 180 | + // when/then - should not throw |
| 181 | + assertThatNoException().isThrownBy(() -> |
| 182 | + highlighter.saveHighlighting(inputFile, documentContext) |
| 183 | + ); |
| 184 | + } |
| 185 | + |
133 | 186 | private void testHighlighting(Vocabulary vocabulary, Map<String, TypeOfText> highlightingMap) { |
134 | 187 | // given |
135 | 188 | initContext(vocabulary); |
|
0 commit comments