]> source.dussan.org Git - sonarqube.git/blob
c68e857d7dc66145a408536b3550d0a070893189
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2019 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.ce.task.projectanalysis.duplication;
21
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;
33
34 import static org.assertj.core.api.Assertions.assertThat;
35 import static org.mockito.Mockito.mock;
36
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";
45
46   @Rule
47   public ExpectedException expectedException = ExpectedException.none();
48
49   @Test
50   public void constructor_throws_NPE_if_original_is_null() {
51     expectedException.expect(NullPointerException.class);
52     expectedException.expectMessage("original TextBlock can not be null");
53
54     new Duplication(null, Collections.emptySet());
55   }
56
57   @Test
58   public void constructor_throws_NPE_if_duplicates_is_null() {
59     expectedException.expect(NullPointerException.class);
60     expectedException.expectMessage("duplicates can not be null");
61
62     new Duplication(SOME_ORIGINAL_TEXTBLOCK, null);
63   }
64
65   @Test
66   public void constructor_throws_IAE_if_duplicates_is_empty() {
67     expectedException.expect(IllegalArgumentException.class);
68     expectedException.expectMessage("duplicates can not be empty");
69
70     new Duplication(SOME_ORIGINAL_TEXTBLOCK, Collections.emptySet());
71   }
72
73   @Test
74   public void constructor_throws_NPE_if_duplicates_contains_null() {
75     expectedException.expect(NullPointerException.class);
76     expectedException.expectMessage("duplicates can not contain null");
77
78     new Duplication(SOME_ORIGINAL_TEXTBLOCK, new HashSet<>(Arrays.asList(mock(Duplicate.class), null, mock(Duplicate.class))));
79   }
80
81   @Test
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");
85
86     new Duplication(SOME_ORIGINAL_TEXTBLOCK, new HashSet<>(Arrays.asList(mock(Duplicate.class), new InnerDuplicate(SOME_ORIGINAL_TEXTBLOCK), mock(Duplicate.class))));
87   }
88
89   @Test
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());
93
94     new Duplication(SOME_ORIGINAL_TEXTBLOCK, ImmutableSet.of(new MyDuplicate(), new MyDuplicate()));
95   }
96
97   private static final class MyDuplicate implements Duplicate {
98
99     @Override
100     public TextBlock getTextBlock() {
101       throw new UnsupportedOperationException("getTextBlock not implemented");
102     }
103   }
104
105   @Test
106   public void getOriginal_returns_original() {
107     assertThat(new Duplication(SOME_ORIGINAL_TEXTBLOCK, ImmutableSet.of(mock(Duplicate.class))).getOriginal()).isSameAs(SOME_ORIGINAL_TEXTBLOCK);
108   }
109
110   @Test
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);
115
116     Duplication duplication = new Duplication(
117       SOME_ORIGINAL_TEXTBLOCK,
118       shuffledList(crossProjectDuplicate, inProjectDuplicate, innerDuplicate));
119
120     assertThat(duplication.getDuplicates()).containsExactly(innerDuplicate, inProjectDuplicate, crossProjectDuplicate);
121   }
122
123   @Test
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));
129
130     assertGetDuplicatesSorting(innerDuplicate1, innerDuplicate2, innerDuplicate3, innerDuplicate4);
131   }
132
133   @Test
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);
139
140     assertGetDuplicatesSorting(innerDuplicate1, innerDuplicate2, innerDuplicate3, innerDuplicate4);
141   }
142
143   @Test
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);
149
150     assertGetDuplicatesSorting(innerDuplicate1, innerDuplicate2, innerDuplicate3, innerDuplicate4);
151   }
152
153   @Test
154   public void equals_compares_on_original_and_duplicates() {
155     Duplication duplication = new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1)));
156
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))));
161   }
162
163   @Test
164   public void hashcode_is_based_on_original_only() {
165     Duplication duplication = new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1)));
166
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());
170   }
171
172   @Test
173   public void verify_toString() {
174     Duplication duplication = new Duplication(
175       SOME_ORIGINAL_TEXTBLOCK,
176       Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1)));
177
178     assertThat(duplication.toString())
179       .isEqualTo("Duplication{original=TextBlock{start=1, end=2}, duplicates=[InnerDuplicate{textBlock=TextBlock{start=2, end=2}}]}");
180   }
181
182   @SafeVarargs
183   private final <T extends Duplicate> void assertGetDuplicatesSorting(T... expected) {
184     Duplication duplication = new Duplication(SOME_ORIGINAL_TEXTBLOCK, shuffledList(expected));
185
186     assertThat(duplication.getDuplicates()).containsExactly(expected);
187   }
188
189   private static List<Duplicate> shuffledList(Duplicate... duplicates) {
190     List<Duplicate> res = new ArrayList<>(Arrays.asList(duplicates));
191     Collections.shuffle(res);
192     return res;
193   }
194 }