import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
-import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Iterables.isEmpty;
import static java.util.Objects.requireNonNull;
import static org.sonar.api.measures.CoreMetrics.DUPLICATED_BLOCKS_KEY;
protected int dupLineCount = 0;
protected int lineCount = 0;
- protected DuplicationCounter() {
- this(null);
- }
-
private DuplicationCounter(@Nullable DuplicationRepository duplicationRepository) {
this.duplicationRepository = duplicationRepository;
}
@Override
public void initialize(CounterInitializationContext context) {
Component leaf = context.getLeaf();
- if (leaf.getType() == Component.Type.FILE) {
+ if (leaf.getType() == Component.Type.FILE && !leaf.getFileAttributes().isUnitTest()) {
initializeForFile(leaf);
} else if (leaf.getType() == Component.Type.PROJECT_VIEW) {
initializeForProjectView(context);
for (Duplication duplication : duplications) {
blocks++;
addLines(duplication.getOriginal(), duplicatedLineNumbers);
- for (InnerDuplicate innerDuplicate : from(duplication.getDuplicates()).filter(InnerDuplicate.class)) {
+ InnerDuplicate[] innerDuplicates = duplication.getDuplicates().stream()
+ .filter(x -> x instanceof InnerDuplicate)
+ .map(d -> (InnerDuplicate) d)
+ .toArray(InnerDuplicate[]::new);
+
+ for (InnerDuplicate innerDuplicate : innerDuplicates) {
blocks++;
addLines(innerDuplicate.getTextBlock(), duplicatedLineNumbers);
}
*/
package org.sonar.ce.task.projectanalysis.duplication;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.ce.task.projectanalysis.component.FileAttributes;
private static final int FILE_2_REF = 12342;
private static final int FILE_3_REF = 1261;
private static final int FILE_4_REF = 1262;
+ private static final int FILE_5_REF = 1263;
+
private static final FileAttributes FILE_1_ATTRS = mock(FileAttributes.class);
private static final FileAttributes FILE_2_ATTRS = mock(FileAttributes.class);
private static final FileAttributes FILE_3_ATTRS = mock(FileAttributes.class);
private static final FileAttributes FILE_4_ATTRS = mock(FileAttributes.class);
+ private static final FileAttributes FILE_5_ATTRS = mock(FileAttributes.class);
private static final String SOME_FILE_KEY = "some file key";
builder(FILE, FILE_2_REF).setFileAttributes(FILE_2_ATTRS).build())
.build(),
builder(FILE, FILE_3_REF).setFileAttributes(FILE_3_ATTRS).build(),
- builder(FILE, FILE_4_REF).setFileAttributes(FILE_4_ATTRS).build())
+ builder(FILE, FILE_4_REF).setFileAttributes(FILE_4_ATTRS).build(),
+ builder(FILE, FILE_5_REF).setFileAttributes(FILE_5_ATTRS).build())
.build());
@Rule
public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
private DuplicationMeasures underTest = new DuplicationMeasures(treeRootHolder, metricRepository, measureRepository, duplicationRepository);
+ @Before
+ public void before() {
+ when(FILE_5_ATTRS.isUnitTest()).thenReturn(true);
+ }
+
@Test
public void compute_duplicated_blocks_one_for_original_one_for_each_InnerDuplicate() {
TextBlock original = new TextBlock(1, 1);
assertRawMeasureValue(FILE_1_REF, DUPLICATED_BLOCKS_KEY, 4);
}
+ @Test
+ public void dont_compute_duplicated_blocks_for_test_files() {
+ duplicationRepository.addDuplication(FILE_5_REF, new TextBlock(1, 1), new TextBlock(3, 3));
+ duplicationRepository.addDuplication(FILE_5_REF, new TextBlock(2, 2), new TextBlock(3, 3));
+
+ underTest.execute();
+
+ assertRawMeasureValue(FILE_5_REF, DUPLICATED_BLOCKS_KEY, 0);
+ assertRawMeasureValue(FILE_5_REF, DUPLICATED_FILES_KEY, 0);
+
+ }
+
@Test
public void compute_duplicated_blocks_does_not_count_blocks_only_once_it_assumes_consistency_from_duplication_data() {
duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 1), new TextBlock(3, 3));
when(FILE_1_ATTRS.getLines()).thenReturn(10);
when(FILE_2_ATTRS.getLines()).thenReturn(40);
+ // this should have no effect as it's a test file
+ when(FILE_5_ATTRS.getLines()).thenReturn(1_000_000);
+
underTest.execute();
assertRawMeasureValue(FILE_1_REF, DUPLICATED_LINES_DENSITY_KEY, 20d);
}
@Test
- public void not_compute_duplicated_lines_density_when_lines_is_zero() {
+ public void dont_compute_duplicated_lines_density_when_lines_is_zero() {
when(FILE_1_ATTRS.getLines()).thenReturn(0);
when(FILE_2_ATTRS.getLines()).thenReturn(0);
underTest.execute();
import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
import org.sonar.api.batch.sensor.internal.DefaultStorable;
import org.sonar.api.batch.sensor.internal.SensorStorage;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Collections.unmodifiableList;
import static java.util.Objects.requireNonNull;
public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens {
-
+ private static final Logger LOG = Loggers.get(DefaultCpdTokens.class);
private final List<TokensLine> result = new ArrayList<>();
- private InputFile inputFile;
+ private DefaultInputFile inputFile;
private int startLine = Integer.MIN_VALUE;
private int startIndex = 0;
private int currentIndex = 0;
private StringBuilder sb = new StringBuilder();
private TextRange lastRange;
+ private boolean loggedTestCpdWarning = false;
public DefaultCpdTokens(SensorStorage storage) {
super(storage);
@Override
public DefaultCpdTokens onFile(InputFile inputFile) {
- this.inputFile = requireNonNull(inputFile, "file can't be null");
+ this.inputFile = (DefaultInputFile) requireNonNull(inputFile, "file can't be null");
return this;
}
checkState(lastRange == null || lastRange.end().compareTo(range.start()) <= 0,
"Tokens of file %s should be provided in order.\nPrevious token: %s\nLast token: %s", inputFile, lastRange, range);
- String value = image;
-
int line = range.start().line();
if (line != startLine) {
addNewTokensLine(result, startIndex, currentIndex, startLine, sb);
startLine = line;
}
currentIndex++;
- sb.append(value);
+ sb.append(image);
lastRange = range;
return this;
}
private boolean isExcludedForDuplication() {
- return ((DefaultInputFile) inputFile).isExcludedForDuplication();
+ if (inputFile.isExcludedForDuplication()) {
+ return true;
+ }
+ if (inputFile.type() == InputFile.Type.TEST) {
+ if (!loggedTestCpdWarning) {
+ LOG.warn("Duplication reported for '{}' will be ignored because it's a test file.", inputFile);
+ loggedTestCpdWarning = true;
+ }
+ return true;
+ }
+ return false;
}
public List<TokensLine> getTokenLines() {
package org.sonar.api.batch.sensor.cpd.internal;
import org.junit.Test;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import static org.mockito.Mockito.verifyZeroInteractions;
public class DefaultCpdTokensTest {
+ private final SensorStorage sensorStorage = mock(SensorStorage.class);
private final DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java")
.setLines(2)
@Test
public void save_no_tokens() {
- SensorStorage sensorStorage = mock(SensorStorage.class);
DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage)
.onFile(inputFile);
@Test
public void save_one_token() {
- SensorStorage sensorStorage = mock(SensorStorage.class);
DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage)
.onFile(inputFile)
.addToken(inputFile.newRange(1, 2, 1, 5), "foo");
@Test
public void handle_exclusions() {
- SensorStorage sensorStorage = mock(SensorStorage.class);
inputFile.setExcludedForDuplication(true);
DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage)
.onFile(inputFile)
assertThat(tokens.getTokenLines()).isEmpty();
}
+ @Test
+ public void dont_save_for_test_files() {
+ DefaultInputFile testInputFile = new TestInputFileBuilder("foo", "src/Foo.java")
+ .setLines(2)
+ .setOriginalLineStartOffsets(new int[] {0, 50})
+ .setOriginalLineEndOffsets(new int[] {49, 100})
+ .setLastValidOffset(101)
+ .setType(InputFile.Type.TEST)
+ .build();
+
+ DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage)
+ .onFile(testInputFile)
+ .addToken(testInputFile.newRange(1, 2, 1, 5), "foo");
+
+ tokens.save();
+ verifyZeroInteractions(sensorStorage);
+ assertThat(tokens.getTokenLines()).isEmpty();
+ }
+
@Test
public void save_many_tokens() {
- SensorStorage sensorStorage = mock(SensorStorage.class);
DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage)
.onFile(inputFile)
.addToken(inputFile.newRange(1, 2, 1, 5), "foo")