]> source.dussan.org Git - sonarqube.git/blob
fe2493acb7817069756cd3942ab424cb4ac86a40
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2016 SonarSource SA
4  * mailto:contact 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.server.computation.source;
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Random;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.sonar.api.utils.log.LogTester;
30 import org.sonar.db.protobuf.DbFileSources;
31 import org.sonar.scanner.protocol.output.ScannerReport;
32 import org.sonar.scanner.protocol.output.ScannerReport.SyntaxHighlightingRule.HighlightingType;
33 import org.sonar.scanner.protocol.output.ScannerReport.TextRange;
34 import org.sonar.server.computation.component.Component;
35 import org.sonar.server.computation.source.RangeOffsetConverter.RangeOffsetConverterException;
36
37 import static com.google.common.collect.ImmutableMap.of;
38 import static org.assertj.core.api.Assertions.assertThat;
39 import static org.mockito.Mockito.doThrow;
40 import static org.mockito.Mockito.mock;
41 import static org.mockito.Mockito.when;
42 import static org.sonar.api.utils.log.LoggerLevel.WARN;
43 import static org.sonar.db.protobuf.DbFileSources.Data.newBuilder;
44 import static org.sonar.scanner.protocol.output.ScannerReport.SyntaxHighlightingRule.HighlightingType.ANNOTATION;
45 import static org.sonar.scanner.protocol.output.ScannerReport.SyntaxHighlightingRule.HighlightingType.COMMENT;
46 import static org.sonar.scanner.protocol.output.ScannerReport.SyntaxHighlightingRule.HighlightingType.CONSTANT;
47 import static org.sonar.scanner.protocol.output.ScannerReport.SyntaxHighlightingRule.HighlightingType.HIGHLIGHTING_STRING;
48 import static org.sonar.server.computation.component.ReportComponent.builder;
49
50 public class HighlightingLineReaderTest {
51
52   @Rule
53   public LogTester logTester = new LogTester();
54
55   static final Component FILE = builder(Component.Type.FILE, 1).setUuid("FILE_UUID").setKey("FILE_KEY").build();
56
57   static final int DEFAULT_LINE_LENGTH = 5;
58
59   static final int LINE_1 = 1;
60   static final int LINE_2 = 2;
61   static final int LINE_3 = 3;
62   static final int LINE_4 = 4;
63
64   static final String RANGE_LABEL_1 = "1,2";
65   static final String RANGE_LABEL_2 = "2,3";
66   static final String RANGE_LABEL_3 = "3,4";
67   static final String RANGE_LABEL_4 = "0,2";
68   static final String RANGE_LABEL_5 = "0,3";
69
70   RangeOffsetConverter rangeOffsetConverter = mock(RangeOffsetConverter.class);
71
72   DbFileSources.Data.Builder sourceData = newBuilder();
73   DbFileSources.Line.Builder line1 = sourceData.addLinesBuilder().setSource("line1").setLine(1);
74   DbFileSources.Line.Builder line2 = sourceData.addLinesBuilder().setSource("line2").setLine(2);
75   DbFileSources.Line.Builder line3 = sourceData.addLinesBuilder().setSource("line3").setLine(3);
76   DbFileSources.Line.Builder line4 = sourceData.addLinesBuilder().setSource("line4").setLine(4);
77
78   @Test
79   public void nothing_to_read() {
80     HighlightingLineReader highlightingLineReader = newReader(Collections.<TextRange, HighlightingType>emptyMap());
81
82     DbFileSources.Line.Builder lineBuilder = newBuilder().addLinesBuilder().setLine(1);
83     highlightingLineReader.read(lineBuilder);
84
85     assertThat(lineBuilder.hasHighlighting()).isFalse();
86   }
87
88   @Test
89   public void read_one_line() {
90     HighlightingLineReader highlightingLineReader = newReader(of(
91       newSingleLineTextRangeWithExpectingLabel(LINE_1, RANGE_LABEL_1), ANNOTATION));
92
93     highlightingLineReader.read(line1);
94
95     assertThat(line1.getHighlighting()).isEqualTo(RANGE_LABEL_1 + ",a");
96   }
97
98   @Test
99   public void read_many_lines() {
100     HighlightingLineReader highlightingLineReader = newReader(of(
101       newSingleLineTextRangeWithExpectingLabel(LINE_1, RANGE_LABEL_1), ANNOTATION,
102       newSingleLineTextRangeWithExpectingLabel(LINE_2, RANGE_LABEL_2), COMMENT,
103       newSingleLineTextRangeWithExpectingLabel(LINE_4, RANGE_LABEL_3), CONSTANT));
104
105     highlightingLineReader.read(line1);
106     highlightingLineReader.read(line2);
107     highlightingLineReader.read(line3);
108     highlightingLineReader.read(line4);
109
110     assertThat(line1.getHighlighting()).isEqualTo(RANGE_LABEL_1 + ",a");
111     assertThat(line2.getHighlighting()).isEqualTo(RANGE_LABEL_2 + ",cd");
112     assertThat(line4.getHighlighting()).isEqualTo(RANGE_LABEL_3 + ",c");
113   }
114
115   @Test
116   public void read_many_syntax_highlighting_on_same_line() {
117     HighlightingLineReader highlightingLineReader = newReader(of(
118       newSingleLineTextRangeWithExpectingLabel(LINE_1, RANGE_LABEL_1), ANNOTATION,
119       newSingleLineTextRangeWithExpectingLabel(LINE_1, RANGE_LABEL_2), COMMENT));
120
121     highlightingLineReader.read(line1);
122
123     assertThat(line1.getHighlighting()).isEqualTo(RANGE_LABEL_1 + ",a;" + RANGE_LABEL_2 + ",cd");
124   }
125
126   @Test
127   public void read_one_syntax_highlighting_on_many_lines() {
128     // This highlighting begin on line 1 and finish on line 3
129     TextRange textRange = newTextRange(LINE_1, LINE_3);
130     when(rangeOffsetConverter.offsetToString(textRange, LINE_1, DEFAULT_LINE_LENGTH)).thenReturn(RANGE_LABEL_1);
131     when(rangeOffsetConverter.offsetToString(textRange, LINE_2, 6)).thenReturn(RANGE_LABEL_2);
132     when(rangeOffsetConverter.offsetToString(textRange, LINE_3, DEFAULT_LINE_LENGTH)).thenReturn(RANGE_LABEL_3);
133
134     HighlightingLineReader highlightingLineReader = newReader(of(textRange, ANNOTATION));
135
136     highlightingLineReader.read(line1);
137     DbFileSources.Line.Builder line2 = sourceData.addLinesBuilder().setSource("line 2").setLine(2);
138     highlightingLineReader.read(line2);
139     highlightingLineReader.read(line3);
140
141     assertThat(line1.getHighlighting()).isEqualTo(RANGE_LABEL_1 + ",a");
142     assertThat(line2.getHighlighting()).isEqualTo(RANGE_LABEL_2 + ",a");
143     assertThat(line3.getHighlighting()).isEqualTo(RANGE_LABEL_3 + ",a");
144   }
145
146   @Test
147   public void read_many_syntax_highlighting_on_many_lines() {
148     TextRange textRange1 = newTextRange(LINE_1, LINE_3);
149     when(rangeOffsetConverter.offsetToString(textRange1, LINE_1, DEFAULT_LINE_LENGTH)).thenReturn(RANGE_LABEL_1);
150     when(rangeOffsetConverter.offsetToString(textRange1, LINE_2, DEFAULT_LINE_LENGTH)).thenReturn(RANGE_LABEL_2);
151     when(rangeOffsetConverter.offsetToString(textRange1, LINE_3, DEFAULT_LINE_LENGTH)).thenReturn(RANGE_LABEL_3);
152
153     TextRange textRange2 = newTextRange(LINE_2, LINE_4);
154     when(rangeOffsetConverter.offsetToString(textRange2, LINE_2, DEFAULT_LINE_LENGTH)).thenReturn(RANGE_LABEL_2);
155     when(rangeOffsetConverter.offsetToString(textRange2, LINE_3, DEFAULT_LINE_LENGTH)).thenReturn(RANGE_LABEL_2);
156     when(rangeOffsetConverter.offsetToString(textRange2, LINE_4, DEFAULT_LINE_LENGTH)).thenReturn(RANGE_LABEL_4);
157
158     TextRange textRange3 = newTextRange(LINE_2, LINE_2);
159     when(rangeOffsetConverter.offsetToString(textRange3, LINE_2, DEFAULT_LINE_LENGTH)).thenReturn(RANGE_LABEL_5);
160
161     HighlightingLineReader highlightingLineReader = newReader(of(
162       textRange1, ANNOTATION,
163       textRange2, HIGHLIGHTING_STRING,
164       textRange3, COMMENT));
165
166     highlightingLineReader.read(line1);
167     highlightingLineReader.read(line2);
168     highlightingLineReader.read(line3);
169     highlightingLineReader.read(line4);
170
171     assertThat(line1.getHighlighting()).isEqualTo(RANGE_LABEL_1 + ",a");
172     assertThat(line2.getHighlighting()).isEqualTo(RANGE_LABEL_2 + ",a;" + RANGE_LABEL_2 + ",s;" + RANGE_LABEL_5 + ",cd");
173     assertThat(line3.getHighlighting()).isEqualTo(RANGE_LABEL_3 + ",a;" + RANGE_LABEL_2 + ",s");
174     assertThat(line4.getHighlighting()).isEqualTo(RANGE_LABEL_4 + ",s");
175   }
176
177   @Test
178   public void read_highlighting_declared_on_a_whole_line() {
179     TextRange textRange = newTextRange(LINE_1, LINE_2);
180     when(rangeOffsetConverter.offsetToString(textRange, LINE_1, DEFAULT_LINE_LENGTH)).thenReturn(RANGE_LABEL_1);
181     when(rangeOffsetConverter.offsetToString(textRange, LINE_2, DEFAULT_LINE_LENGTH)).thenReturn("");
182
183     HighlightingLineReader highlightingLineReader = newReader(of(textRange, ANNOTATION));
184
185     highlightingLineReader.read(line1);
186     highlightingLineReader.read(line2);
187     highlightingLineReader.read(line3);
188
189     assertThat(line1.getHighlighting()).isEqualTo(RANGE_LABEL_1 + ",a");
190     // Nothing should be set on line 2
191     assertThat(line2.getHighlighting()).isEmpty();
192     assertThat(line3.getHighlighting()).isEmpty();
193   }
194
195   @Test
196   public void not_fail_and_stop_processing_when_range_offset_converter_throw_RangeOffsetConverterException() {
197     TextRange textRange1 = newTextRange(LINE_1, LINE_1);
198     doThrow(RangeOffsetConverterException.class).when(rangeOffsetConverter).offsetToString(textRange1, LINE_1, DEFAULT_LINE_LENGTH);
199
200     HighlightingLineReader highlightingLineReader = newReader(of(
201       textRange1, HighlightingType.ANNOTATION,
202       newSingleLineTextRangeWithExpectingLabel(LINE_2, RANGE_LABEL_1), HIGHLIGHTING_STRING));
203
204     highlightingLineReader.read(line1);
205     highlightingLineReader.read(line2);
206
207     assertNoHighlighting();
208     assertThat(logTester.logs(WARN)).isNotEmpty();
209   }
210
211   @Test
212   public void keep_existing_processed_highlighting_when_range_offset_converter_throw_RangeOffsetConverterException() {
213     TextRange textRange2 = newTextRange(LINE_2, LINE_2);
214     doThrow(RangeOffsetConverterException.class).when(rangeOffsetConverter).offsetToString(textRange2, LINE_2, DEFAULT_LINE_LENGTH);
215
216     HighlightingLineReader highlightingLineReader = newReader(of(
217       newSingleLineTextRangeWithExpectingLabel(LINE_1, RANGE_LABEL_1), ANNOTATION,
218       textRange2, HIGHLIGHTING_STRING));
219
220     highlightingLineReader.read(line1);
221     highlightingLineReader.read(line2);
222
223     assertThat(line1.hasHighlighting()).isTrue();
224     assertThat(line2.hasHighlighting()).isFalse();
225     assertThat(logTester.logs(WARN)).isNotEmpty();
226   }
227
228   @Test
229   public void display_file_key_in_warning_when_range_offset_converter_throw_RangeOffsetConverterException() {
230     TextRange textRange1 = newTextRange(LINE_1, LINE_1);
231     doThrow(RangeOffsetConverterException.class).when(rangeOffsetConverter).offsetToString(textRange1, LINE_1, DEFAULT_LINE_LENGTH);
232     HighlightingLineReader highlightingLineReader = newReader(of(textRange1, ANNOTATION));
233
234     highlightingLineReader.read(line1);
235
236     assertThat(logTester.logs(WARN)).containsOnly("Inconsistency detected in Highlighting data. Highlighting will be ignored for file 'FILE_KEY'");
237   }
238
239   private HighlightingLineReader newReader(Map<TextRange, HighlightingType> textRangeByType) {
240     List<ScannerReport.SyntaxHighlightingRule> syntaxHighlightingList = new ArrayList<>();
241     for (Map.Entry<TextRange, HighlightingType> entry : textRangeByType.entrySet()) {
242       syntaxHighlightingList.add(ScannerReport.SyntaxHighlightingRule.newBuilder()
243         .setRange(entry.getKey())
244         .setType(entry.getValue())
245         .build());
246     }
247     return new HighlightingLineReader(FILE, syntaxHighlightingList.iterator(), rangeOffsetConverter);
248   }
249
250   private static TextRange newTextRange(int startLine, int enLine) {
251     Random random = new Random();
252     return TextRange.newBuilder()
253       .setStartLine(startLine).setEndLine(enLine)
254       // Offsets are not used by the reader
255       .setStartOffset(random.nextInt()).setEndOffset(random.nextInt())
256       .build();
257   }
258
259   private TextRange newSingleLineTextRangeWithExpectingLabel(int line, String rangeLabel) {
260     TextRange textRange = newTextRange(line, line);
261     when(rangeOffsetConverter.offsetToString(textRange, line, DEFAULT_LINE_LENGTH)).thenReturn(rangeLabel);
262     return textRange;
263   }
264
265   private void assertNoHighlighting() {
266     assertThat(line1.hasHighlighting()).isFalse();
267     assertThat(line2.hasHighlighting()).isFalse();
268     assertThat(line3.hasHighlighting()).isFalse();
269     assertThat(line4.hasHighlighting()).isFalse();
270   }
271
272 }