You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DuplicationTest.java 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 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. import java.util.ArrayList;
  22. import java.util.Arrays;
  23. import java.util.Collections;
  24. import java.util.List;
  25. import org.junit.Test;
  26. import org.sonar.ce.task.projectanalysis.component.Component;
  27. import org.sonar.ce.task.projectanalysis.component.ReportComponent;
  28. import static org.assertj.core.api.Assertions.assertThat;
  29. import static org.assertj.core.api.Assertions.assertThatThrownBy;
  30. import static org.mockito.Mockito.mock;
  31. public class DuplicationTest {
  32. private static final TextBlock SOME_ORIGINAL_TEXTBLOCK = new TextBlock(1, 2);
  33. private static final TextBlock TEXT_BLOCK_1 = new TextBlock(2, 2);
  34. private static final TextBlock TEXT_BLOCK_2 = new TextBlock(2, 3);
  35. private static final ReportComponent FILE_COMPONENT_1 = ReportComponent.builder(Component.Type.FILE, 1).build();
  36. private static final ReportComponent FILE_COMPONENT_2 = ReportComponent.builder(Component.Type.FILE, 2).build();
  37. private static final String FILE_KEY_1 = "1";
  38. private static final String FILE_KEY_2 = "2";
  39. @Test
  40. public void constructor_throws_NPE_if_original_is_null() {
  41. assertThatThrownBy(() -> new Duplication(null, Collections.emptyList()))
  42. .isInstanceOf(NullPointerException.class)
  43. .hasMessage("original TextBlock can not be null");
  44. }
  45. @Test
  46. public void constructor_throws_NPE_if_duplicates_is_null() {
  47. assertThatThrownBy(() -> new Duplication(SOME_ORIGINAL_TEXTBLOCK, null))
  48. .isInstanceOf(NullPointerException.class)
  49. .hasMessage("duplicates can not be null");
  50. }
  51. @Test
  52. public void constructor_throws_IAE_if_duplicates_is_empty() {
  53. assertThatThrownBy(() -> new Duplication(SOME_ORIGINAL_TEXTBLOCK, Collections.emptyList()))
  54. .isInstanceOf(IllegalArgumentException.class)
  55. .hasMessage("duplicates can not be empty");
  56. }
  57. @Test
  58. public void constructor_throws_NPE_if_duplicates_contains_null() {
  59. assertThatThrownBy(() -> new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(mock(Duplicate.class), null, mock(Duplicate.class))))
  60. .isInstanceOf(NullPointerException.class)
  61. .hasMessage("duplicates can not contain null");
  62. }
  63. @Test
  64. public void constructor_throws_IAE_if_duplicates_contains_InnerDuplicate_of_original() {
  65. assertThatThrownBy(() -> new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(mock(Duplicate.class), new InnerDuplicate(SOME_ORIGINAL_TEXTBLOCK), mock(Duplicate.class))))
  66. .isInstanceOf(IllegalArgumentException.class)
  67. .hasMessage("TextBlock of an InnerDuplicate can not be the original TextBlock");
  68. }
  69. @Test
  70. public void constructor_throws_IAE_when_attempting_to_sort_Duplicate_of_unkown_type() {
  71. assertThatThrownBy(() -> new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new MyDuplicate(), new MyDuplicate())))
  72. .isInstanceOf(IllegalArgumentException.class)
  73. .hasMessage("Unsupported type of Duplicate " + MyDuplicate.class.getName());
  74. }
  75. private static final class MyDuplicate implements Duplicate {
  76. @Override
  77. public TextBlock getTextBlock() {
  78. throw new UnsupportedOperationException("getTextBlock not implemented");
  79. }
  80. }
  81. @Test
  82. public void getOriginal_returns_original() {
  83. assertThat(new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1)))
  84. .getOriginal()).isSameAs(SOME_ORIGINAL_TEXTBLOCK);
  85. }
  86. @Test
  87. public void getDuplicates_sorts_duplicates_by_Inner_then_InProject_then_CrossProject() {
  88. CrossProjectDuplicate crossProjectDuplicate = new CrossProjectDuplicate("some key", TEXT_BLOCK_1);
  89. InProjectDuplicate inProjectDuplicate = new InProjectDuplicate(FILE_COMPONENT_1, TEXT_BLOCK_1);
  90. InnerDuplicate innerDuplicate = new InnerDuplicate(TEXT_BLOCK_1);
  91. Duplication duplication = new Duplication(
  92. SOME_ORIGINAL_TEXTBLOCK,
  93. shuffledList(crossProjectDuplicate, inProjectDuplicate, innerDuplicate));
  94. assertThat(duplication.getDuplicates()).containsExactly(innerDuplicate, inProjectDuplicate, crossProjectDuplicate);
  95. }
  96. @Test
  97. public void getDuplicates_sorts_duplicates_of_InnerDuplicate_by_TextBlock() {
  98. InnerDuplicate innerDuplicate1 = new InnerDuplicate(TEXT_BLOCK_2);
  99. InnerDuplicate innerDuplicate2 = new InnerDuplicate(new TextBlock(3, 3));
  100. InnerDuplicate innerDuplicate3 = new InnerDuplicate(new TextBlock(3, 4));
  101. InnerDuplicate innerDuplicate4 = new InnerDuplicate(new TextBlock(4, 4));
  102. assertGetDuplicatesSorting(innerDuplicate1, innerDuplicate2, innerDuplicate3, innerDuplicate4);
  103. }
  104. @Test
  105. public void getDuplicates_sorts_duplicates_of_InProjectDuplicate_by_component_then_TextBlock() {
  106. InProjectDuplicate innerDuplicate1 = new InProjectDuplicate(FILE_COMPONENT_1, TEXT_BLOCK_1);
  107. InProjectDuplicate innerDuplicate2 = new InProjectDuplicate(FILE_COMPONENT_1, TEXT_BLOCK_2);
  108. InProjectDuplicate innerDuplicate3 = new InProjectDuplicate(FILE_COMPONENT_2, TEXT_BLOCK_1);
  109. InProjectDuplicate innerDuplicate4 = new InProjectDuplicate(FILE_COMPONENT_2, TEXT_BLOCK_2);
  110. assertGetDuplicatesSorting(innerDuplicate1, innerDuplicate2, innerDuplicate3, innerDuplicate4);
  111. }
  112. @Test
  113. public void getDuplicates_sorts_duplicates_of_CrossProjectDuplicate_by_fileKey_then_TextBlock() {
  114. CrossProjectDuplicate innerDuplicate1 = new CrossProjectDuplicate(FILE_KEY_1, TEXT_BLOCK_1);
  115. CrossProjectDuplicate innerDuplicate2 = new CrossProjectDuplicate(FILE_KEY_1, TEXT_BLOCK_2);
  116. CrossProjectDuplicate innerDuplicate3 = new CrossProjectDuplicate(FILE_KEY_2, TEXT_BLOCK_1);
  117. CrossProjectDuplicate innerDuplicate4 = new CrossProjectDuplicate(FILE_KEY_2, TEXT_BLOCK_2);
  118. assertGetDuplicatesSorting(innerDuplicate1, innerDuplicate2, innerDuplicate3, innerDuplicate4);
  119. }
  120. @Test
  121. public void equals_compares_on_original_and_duplicates() {
  122. Duplication duplication = new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1)));
  123. assertThat(duplication).isEqualTo(duplication);
  124. assertThat(duplication).isEqualTo(new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1))));
  125. assertThat(duplication).isNotEqualTo(new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_2))));
  126. assertThat(duplication).isNotEqualTo(new Duplication(TEXT_BLOCK_1, Arrays.asList(new InnerDuplicate(SOME_ORIGINAL_TEXTBLOCK))));
  127. }
  128. @Test
  129. public void hashcode_is_based_on_original_only() {
  130. Duplication duplication = new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1)));
  131. assertThat(duplication.hashCode()).isEqualTo(new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1))).hashCode());
  132. assertThat(duplication.hashCode()).isNotEqualTo(new Duplication(SOME_ORIGINAL_TEXTBLOCK, Arrays.asList(new InnerDuplicate(TEXT_BLOCK_2))).hashCode());
  133. assertThat(duplication.hashCode()).isNotEqualTo(new Duplication(TEXT_BLOCK_1, Arrays.asList(new InnerDuplicate(SOME_ORIGINAL_TEXTBLOCK))).hashCode());
  134. }
  135. @Test
  136. public void verify_toString() {
  137. Duplication duplication = new Duplication(
  138. SOME_ORIGINAL_TEXTBLOCK,
  139. Arrays.asList(new InnerDuplicate(TEXT_BLOCK_1)));
  140. assertThat(duplication.toString())
  141. .isEqualTo("Duplication{original=TextBlock{start=1, end=2}, duplicates=[InnerDuplicate{textBlock=TextBlock{start=2, end=2}}]}");
  142. }
  143. @SafeVarargs
  144. private final <T extends Duplicate> void assertGetDuplicatesSorting(T... expected) {
  145. Duplication duplication = new Duplication(SOME_ORIGINAL_TEXTBLOCK, shuffledList(expected));
  146. assertThat(duplication.getDuplicates()).containsExactly(expected);
  147. }
  148. private static List<Duplicate> shuffledList(Duplicate... duplicates) {
  149. List<Duplicate> res = new ArrayList<>(Arrays.asList(duplicates));
  150. Collections.shuffle(res);
  151. return res;
  152. }
  153. }