3 * Copyright (C) 2009-2019 SonarSource SA
4 * mailto:info AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.ce.task.projectanalysis.duplication;
22 import com.google.common.collect.ImmutableSet;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.HashSet;
27 import java.util.List;
28 import org.junit.Rule;
29 import org.junit.Test;
30 import org.junit.rules.ExpectedException;
31 import org.sonar.ce.task.projectanalysis.component.Component;
32 import org.sonar.ce.task.projectanalysis.component.ReportComponent;
34 import static org.assertj.core.api.Assertions.assertThat;
35 import static org.mockito.Mockito.mock;
37 public class DuplicationTest {
38 private static final TextBlock SOME_ORIGINAL_TEXTBLOCK = new TextBlock(1, 2);
39 private static final TextBlock TEXT_BLOCK_1 = new TextBlock(2, 2);
40 private static final TextBlock TEXT_BLOCK_2 = new TextBlock(2, 3);
41 private static final ReportComponent FILE_COMPONENT_1 = ReportComponent.builder(Component.Type.FILE, 1).build();
42 private static final ReportComponent FILE_COMPONENT_2 = ReportComponent.builder(Component.Type.FILE, 2).build();
43 private static final String FILE_KEY_1 = "1";
44 private static final String FILE_KEY_2 = "2";
47 public ExpectedException expectedException = ExpectedException.none();
50 public void constructor_throws_NPE_if_original_is_null() {
51 expectedException.expect(NullPointerException.class);
52 expectedException.expectMessage("original TextBlock can not be null");
54 new Duplication(null, Collections.emptySet());
58 public void constructor_throws_NPE_if_duplicates_is_null() {
59 expectedException.expect(NullPointerException.class);
60 expectedException.expectMessage("duplicates can not be null");
62 new Duplication(SOME_ORIGINAL_TEXTBLOCK, null);
66 public void constructor_throws_IAE_if_duplicates_is_empty() {
67 expectedException.expect(IllegalArgumentException.class);
68 expectedException.expectMessage("duplicates can not be empty");
70 new Duplication(SOME_ORIGINAL_TEXTBLOCK, Collections.emptySet());
74 public void constructor_throws_NPE_if_duplicates_contains_null() {
75 expectedException.expect(NullPointerException.class);
76 expectedException.expectMessage("duplicates can not contain null");
78 new Duplication(SOME_ORIGINAL_TEXTBLOCK, new HashSet<>(Arrays.asList(mock(Duplicate.class), null, mock(Duplicate.class))));
82 public void constructor_throws_IAE_if_duplicates_contains_InnerDuplicate_of_original() {
83 expectedException.expect(IllegalArgumentException.class);
84 expectedException.expectMessage("TextBlock of an InnerDuplicate can not be the original TextBlock");
86 new Duplication(SOME_ORIGINAL_TEXTBLOCK, new HashSet<>(Arrays.asList(mock(Duplicate.class), new InnerDuplicate(SOME_ORIGINAL_TEXTBLOCK), mock(Duplicate.class))));
90 public void constructor_throws_IAE_when_attempting_to_sort_Duplicate_of_unkown_type() {
91 expectedException.expect(IllegalArgumentException.class);
92 expectedException.expectMessage("Unsupported type of Duplicate " + MyDuplicate.class.getName());
94 new Duplication(SOME_ORIGINAL_TEXTBLOCK, ImmutableSet.of(new MyDuplicate(), new MyDuplicate()));
97 private static final class MyDuplicate implements Duplicate {
100 public TextBlock getTextBlock() {
101 throw new UnsupportedOperationException("getTextBlock not implemented");
106 public void getOriginal_returns_original() {
107 assertThat(new Duplication(SOME_ORIGINAL_TEXTBLOCK, ImmutableSet.of(mock(Duplicate.class))).getOriginal()).isSameAs(SOME_ORIGINAL_TEXTBLOCK);
111 public void getDuplicates_sorts_duplicates_by_Inner_then_InProject_then_CrossProject() {
112 CrossProjectDuplicate crossProjectDuplicate = new CrossProjectDuplicate("some key", TEXT_BLOCK_1);
113 InProjectDuplicate inProjectDuplicate = new InProjectDuplicate(FILE_COMPONENT_1, TEXT_BLOCK_1);
114 InnerDuplicate innerDuplicate = new InnerDuplicate(TEXT_BLOCK_1);
116 Duplication duplication = new Duplication(
117 SOME_ORIGINAL_TEXTBLOCK,
118 shuffledList(crossProjectDuplicate, inProjectDuplicate, innerDuplicate));
120 assertThat(duplication.getDuplicates()).containsExactly(innerDuplicate, inProjectDuplicate, crossProjectDuplicate);
124 public void getDuplicates_sorts_duplicates_of_InnerDuplicate_by_TextBlock() {
125 InnerDuplicate innerDuplicate1 = new InnerDuplicate(TEXT_BLOCK_2);
126 InnerDuplicate innerDuplicate2 = new InnerDuplicate(new TextBlock(3, 3));
127 InnerDuplicate innerDuplicate3 = new InnerDuplicate(new TextBlock(3, 4));
128 InnerDuplicate innerDuplicate4 = new InnerDuplicate(new TextBlock(4, 4));
130 assertGetDuplicatesSorting(innerDuplicate1, innerDuplicate2, innerDuplicate3, innerDuplicate4);
134 public void getDuplicates_sorts_duplicates_of_InProjectDuplicate_by_component_then_TextBlock() {
135 InProjectDuplicate innerDuplicate1 = new InProjectDuplicate(FILE_COMPONENT_1, TEXT_BLOCK_1);
136 InProjectDuplicate innerDuplicate2 = new InProjectDuplicate(FILE_COMPONENT_1, TEXT_BLOCK_2);
137 InProjectDuplicate innerDuplicate3 = new InProjectDuplicate(FILE_COMPONENT_2, TEXT_BLOCK_1);
138 InProjectDuplicate innerDuplicate4 = new InProjectDuplicate(FILE_COMPONENT_2, TEXT_BLOCK_2);
140 assertGetDuplicatesSorting(innerDuplicate1, innerDuplicate2, innerDuplicate3, innerDuplicate4);
144 public void getDuplicates_sorts_duplicates_of_CrossProjectDuplicate_by_fileKey_then_TextBlock() {
145 CrossProjectDuplicate innerDuplicate1 = new CrossProjectDuplicate(FILE_KEY_1, TEXT_BLOCK_1);
146 CrossProjectDuplicate innerDuplicate2 = new CrossProjectDuplicate(FILE_KEY_1, TEXT_BLOCK_2);
147 CrossProjectDuplicate innerDuplicate3 = new CrossProjectDuplicate(FILE_KEY_2, TEXT_BLOCK_1);
148 CrossProjectDuplicate innerDuplicate4 = new CrossProjectDuplicate(FILE_KEY_2, TEXT_BLOCK_2);
150 assertGetDuplicatesSorting(innerDuplicate1, innerDuplicate2, innerDuplicate3, innerDuplicate4);
154 public void equals_compares_on_original_and_duplicates() {
155 Duplication duplication = new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1)));
157 assertThat(duplication).isEqualTo(duplication);
158 assertThat(duplication).isEqualTo(new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1))));
159 assertThat(duplication).isNotEqualTo(new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_2))));
160 assertThat(duplication).isNotEqualTo(new Duplication(TEXT_BLOCK_1, Arrays.asList(new InnerDuplicate(SOME_ORIGINAL_TEXTBLOCK))));
164 public void hashcode_is_based_on_original_only() {
165 Duplication duplication = new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1)));
167 assertThat(duplication.hashCode()).isEqualTo(new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1))).hashCode());
168 assertThat(duplication.hashCode()).isNotEqualTo(new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_2))).hashCode());
169 assertThat(duplication.hashCode()).isNotEqualTo(new Duplication(TEXT_BLOCK_1, Arrays.asList(new InnerDuplicate(SOME_ORIGINAL_TEXTBLOCK))).hashCode());
173 public void verify_toString() {
174 Duplication duplication = new Duplication(
175 SOME_ORIGINAL_TEXTBLOCK,
176 Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1)));
178 assertThat(duplication.toString())
179 .isEqualTo("Duplication{original=TextBlock{start=1, end=2}, duplicates=[InnerDuplicate{textBlock=TextBlock{start=2, end=2}}]}");
183 private final <T extends Duplicate> void assertGetDuplicatesSorting(T... expected) {
184 Duplication duplication = new Duplication(SOME_ORIGINAL_TEXTBLOCK, shuffledList(expected));
186 assertThat(duplication.getDuplicates()).containsExactly(expected);
189 private static List<Duplicate> shuffledList(Duplicate... duplicates) {
190 List<Duplicate> res = new ArrayList<>(Arrays.asList(duplicates));
191 Collections.shuffle(res);