]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3321 fix MatchesByScore when ScoreMatric contains min required score 1017/head
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Fri, 3 Jun 2016 12:56:16 +0000 (14:56 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 6 Jun 2016 07:48:55 +0000 (09:48 +0200)
server/sonar-server/src/main/java/org/sonar/server/computation/filemove/MatchesByScore.java
server/sonar-server/src/test/java/org/sonar/server/computation/filemove/MatchesByScoreTest.java [new file with mode: 0644]

index 35852ac9ee85eba6ae427f84872c8ca2490660c0..69cde753d2a9ce03021b65f6dae53ad617865e1e 100644 (file)
@@ -21,56 +21,81 @@ package org.sonar.server.computation.filemove;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
 import static org.sonar.server.computation.filemove.FileMoveDetectionStep.MIN_REQUIRED_SCORE;
 
-class MatchesByScore implements ScoreMatrix.ScoreMatrixVisitor, Iterable<List<Match>> {
-  private final ScoreMatrix scoreMatrix;
-  private final List<Match>[] matches;
-  private int totalMatches = 0;
-
-  private MatchesByScore(ScoreMatrix scoreMatrix) {
-    this.scoreMatrix = scoreMatrix;
-    this.matches = new List[Math.max(MIN_REQUIRED_SCORE, scoreMatrix.getMaxScore()) - MIN_REQUIRED_SCORE];
-  }
+abstract class MatchesByScore implements Iterable<List<Match>> {
 
   public static MatchesByScore create(ScoreMatrix scoreMatrix) {
-    MatchesByScore res = new MatchesByScore(scoreMatrix);
+    if (scoreMatrix.getMaxScore() < MIN_REQUIRED_SCORE) {
+      return EmptyMatchesByScore.INSTANCE;
+    }
+    MatchesByScoreImpl res = new MatchesByScoreImpl(scoreMatrix);
     res.populate();
     return res;
   }
 
-  private void populate() {
-    scoreMatrix.accept(this);
-  }
+  public abstract int getSize();
+
+  private static final class MatchesByScoreImpl extends MatchesByScore implements ScoreMatrix.ScoreMatrixVisitor {
+    private final ScoreMatrix scoreMatrix;
+    private final List<Match>[] matches;
+    private int totalMatches = 0;
 
-  @Override
-  public void visit(String dbFileKey, String reportFileKey, int score) {
-    if (!isAcceptableScore(score)) {
-      return;
+    private MatchesByScoreImpl(ScoreMatrix scoreMatrix) {
+      this.scoreMatrix = scoreMatrix;
+      this.matches = new List[scoreMatrix.getMaxScore() - MIN_REQUIRED_SCORE + 1];
     }
 
-    int index = score - MIN_REQUIRED_SCORE - 1;
-    if (matches[index] == null) {
-      matches[index] = new ArrayList<>(1);
+    private void populate() {
+      scoreMatrix.accept(this);
+    }
+
+    @Override
+    public void visit(String dbFileKey, String reportFileKey, int score) {
+      if (!isAcceptableScore(score)) {
+        return;
+      }
+
+      int index = score - MIN_REQUIRED_SCORE;
+      if (matches[index] == null) {
+        matches[index] = new ArrayList<>(1);
+      }
+      Match match = new Match(dbFileKey, reportFileKey);
+      matches[index].add(match);
+      totalMatches++;
     }
-    Match match = new Match(dbFileKey, reportFileKey);
-    matches[index].add(match);
-    totalMatches++;
-  }
 
-  private static boolean isAcceptableScore(int score) {
-    return score >= MIN_REQUIRED_SCORE;
-  }
 
-  public int getSize() {
-    return totalMatches;
+    private static boolean isAcceptableScore(int score) {
+      return score >= MIN_REQUIRED_SCORE;
+    }
+
+    @Override
+    public int getSize() {
+      return totalMatches;
+    }
+
+    @Override
+    public Iterator<List<Match>> iterator() {
+      return Arrays.asList(matches).iterator();
+    }
   }
 
-  @Override
-  public Iterator<List<Match>> iterator() {
-    return Arrays.asList(matches).iterator();
+  private static class EmptyMatchesByScore extends MatchesByScore {
+    private static final EmptyMatchesByScore INSTANCE = new EmptyMatchesByScore();
+
+    @Override
+    public int getSize() {
+      return 0;
+    }
+
+    @Override
+    public Iterator<List<Match>> iterator() {
+      return Collections.<List<Match>>emptyList().iterator();
+    }
   }
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/filemove/MatchesByScoreTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/filemove/MatchesByScoreTest.java
new file mode 100644 (file)
index 0000000..415bdb9
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.filemove;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.junit.Test;
+
+import static com.google.common.collect.ImmutableSet.of;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.computation.filemove.FileMoveDetectionStep.MIN_REQUIRED_SCORE;
+
+public class MatchesByScoreTest {
+
+  private static final List<Match> NO_MATCH = null;
+
+  @Test
+  public void creates_returns_always_the_same_instance_of_maxScore_is_less_than_min_required_score() {
+    Set<String> doesNotMatterDbFileKeys = Collections.emptySet();
+    Map<String, FileSimilarity.File> doesNotMatterReportFiles = Collections.emptyMap();
+    int[][] doesNotMatterScores = new int[0][0];
+
+    ScoreMatrix scoreMatrix1 = new ScoreMatrix(doesNotMatterDbFileKeys, doesNotMatterReportFiles, doesNotMatterScores, MIN_REQUIRED_SCORE - 1);
+    MatchesByScore matchesByScore = MatchesByScore.create(scoreMatrix1);
+
+    assertThat(matchesByScore.getSize()).isEqualTo(0);
+    assertThat(matchesByScore).isEmpty();
+
+    ScoreMatrix scoreMatrix2 = new ScoreMatrix(doesNotMatterDbFileKeys, doesNotMatterReportFiles, doesNotMatterScores, MIN_REQUIRED_SCORE - 5);
+    assertThat(MatchesByScore.create(scoreMatrix2)).isSameAs(matchesByScore);
+  }
+
+  @Test
+  public void creates_supports_score_with_same_value_as_min_required_score() {
+    int maxScore = 92;
+    int[][] scores = {
+      {maxScore},
+      {8},
+      {85},
+    };
+    MatchesByScore matchesByScore = MatchesByScore.create(new ScoreMatrix(
+      of("A", "B", "C"), ImmutableMap.of("1", fileOf("1")), scores, maxScore));
+
+    assertThat(matchesByScore.getSize()).isEqualTo(2);
+    assertThat(Lists.newArrayList(matchesByScore)).isEqualTo(Arrays.asList(
+      ImmutableList.of(new Match("C", "1")), // 85
+      NO_MATCH,
+      NO_MATCH,
+      NO_MATCH,
+      NO_MATCH,
+      NO_MATCH,
+      NO_MATCH,
+      ImmutableList.of(new Match("A", "1")) // 92
+    ));
+  }
+
+  private static FileSimilarity.File fileOf(String key) {
+    return new FileSimilarity.File("path of " + key, null, null);
+  }
+}