Browse Source

Merge pull request #794 from jplag/distribution-fix

Fix similarity distribution in JPlagResult
Timur Sağlam 4 years ago
parent
commit
ed3286d62c

+ 1 - 2
core/src/main/java/de/jplag/JPlagResult.java

@@ -141,8 +141,7 @@ public class JPlagResult {
             int index = (int) (similarity * SIMILARITY_DISTRIBUTION_SIZE); // divide similarity by bucket size to find index of correct bucket.
             index = Math.min(index, SIMILARITY_DISTRIBUTION_SIZE - 1);// index is out of bounds when similarity is 1.0. decrease by one to count
                                                                       // towards the highest value bucket
-            similarityDistribution[SIMILARITY_DISTRIBUTION_SIZE - 1 - index]++; // count comparison towards its determined bucket. bucket order is
-            // reversed, so that the highest value bucket has the lowest index
+            similarityDistribution[index]++; // count comparison towards its determined bucket.
         }
         return similarityDistribution;
     }

+ 9 - 6
core/src/main/java/de/jplag/reporting/reportobject/mapper/MetricMapper.java

@@ -1,10 +1,11 @@
 package de.jplag.reporting.reportobject.mapper;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.function.Function;
-import java.util.stream.Collectors;
 
 import de.jplag.JPlagComparison;
 import de.jplag.JPlagResult;
@@ -25,12 +26,12 @@ public class MetricMapper {
     }
 
     public Metric getAverageMetric(JPlagResult result) {
-        return new Metric(SimilarityMetric.AVG.name(), intArrayToList(result.getSimilarityDistribution()), getTopComparisons(getComparisons(result)),
-                Messages.getString("SimilarityMetric.Avg.Description"));
+        return new Metric(SimilarityMetric.AVG.name(), convertDistribution(result.getSimilarityDistribution()),
+                getTopComparisons(getComparisons(result)), Messages.getString("SimilarityMetric.Avg.Description"));
     }
 
     public Metric getMaxMetric(JPlagResult result) {
-        return new Metric(SimilarityMetric.MAX.name(), intArrayToList(result.getMaxSimilarityDistribution()),
+        return new Metric(SimilarityMetric.MAX.name(), convertDistribution(result.getMaxSimilarityDistribution()),
                 getMaxSimilarityTopComparisons(getComparisons(result)), Messages.getString("SimilarityMetric.Max.Description"));
     }
 
@@ -39,8 +40,10 @@ public class MetricMapper {
         return result.getComparisons(maxNumberOfComparisons);
     }
 
-    private List<Integer> intArrayToList(int[] array) {
-        return Arrays.stream(array).boxed().collect(Collectors.toList());
+    private List<Integer> convertDistribution(int[] array) {
+        List<Integer> list = new ArrayList<>(Arrays.stream(array).boxed().toList());
+        Collections.reverse(list);
+        return list;
     }
 
     private List<TopComparison> getTopComparisons(List<JPlagComparison> comparisons, Function<JPlagComparison, Double> similarityExtractor) {

+ 2 - 2
core/src/test/java/de/jplag/BaseCodeTest.java

@@ -38,7 +38,7 @@ public class BaseCodeTest extends TestBase {
         assertEquals(2, result.getNumberOfSubmissions());
         assertEquals(1, result.getAllComparisons().size());
         assertEquals(1, result.getAllComparisons().get(0).matches().size());
-        assertEquals(1, result.getSimilarityDistribution()[1]);
+        assertEquals(1, result.getSimilarityDistribution()[8]);
         assertEquals(0.85, result.getAllComparisons().get(0).similarity(), DELTA);
     }
 
@@ -87,7 +87,7 @@ public class BaseCodeTest extends TestBase {
         assertEquals(submissions, result.getNumberOfSubmissions());
         assertEquals(comparisons, result.getAllComparisons().size());
         assertEquals(1, result.getAllComparisons().get(0).matches().size());
-        assertEquals(1, result.getSimilarityDistribution()[3]);
+        assertEquals(1, result.getSimilarityDistribution()[6]);
         assertEquals(0.6207, result.getAllComparisons().get(0).similarity(), DELTA);
     }
 

+ 2 - 2
core/src/test/java/de/jplag/ParallelComparisonTest.java

@@ -23,7 +23,7 @@ class ParallelComparisonTest extends TestBase {
         assertEquals(2, result.getNumberOfSubmissions());
         assertEquals(1, result.getAllComparisons().size());
         assertEquals(1, result.getAllComparisons().get(0).matches().size());
-        assertEquals(1, result.getSimilarityDistribution()[3]);
+        assertEquals(1, result.getSimilarityDistribution()[6]);
         assertEquals(0.6207, result.getAllComparisons().get(0).similarity(), DELTA);
     }
 
@@ -32,7 +32,7 @@ class ParallelComparisonTest extends TestBase {
      */
     @Test
     void testWithMinTokenMatch() throws ExitException {
-        var expectedDistribution = new int[] {1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+        var expectedDistribution = new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
         JPlagResult result = runJPlag("SimpleDuplicate", it -> it.withMinimumTokenMatch(5));
 
         assertEquals(2, result.getNumberOfSubmissions());

+ 10 - 6
core/src/test/java/de/jplag/reporting/reportobject/mapper/MetricMapperTest.java

@@ -5,6 +5,7 @@ import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.junit.jupiter.api.Assertions;
@@ -17,19 +18,20 @@ import de.jplag.options.JPlagOptions;
 import de.jplag.reporting.reportobject.model.TopComparison;
 
 public class MetricMapperTest {
+    private static final List<Integer> EXPECTED_DISTRIBUTION = List.of(29, 23, 19, 17, 13, 11, 7, 5, 3, 2);
     private final MetricMapper metricMapper = new MetricMapper(Submission::getName);
 
     @Test
     public void test_getAverageMetric() {
         // given
-        JPlagResult jPlagResult = createJPlagResult(MockMetric.AVG, distribution(2, 3, 5, 7, 11, 13, 17, 19, 23, 29),
+        JPlagResult jPlagResult = createJPlagResult(MockMetric.AVG, distribution(EXPECTED_DISTRIBUTION),
                 comparison(submission("1"), submission("2"), .7), comparison(submission("3"), submission("4"), .3));
         // when
         var result = metricMapper.getAverageMetric(jPlagResult);
 
         // then
         Assertions.assertEquals("AVG", result.name());
-        Assertions.assertIterableEquals(List.of(2, 3, 5, 7, 11, 13, 17, 19, 23, 29), result.distribution());
+        Assertions.assertIterableEquals(EXPECTED_DISTRIBUTION, result.distribution());
         Assertions.assertEquals(List.of(new TopComparison("1", "2", .7), new TopComparison("3", "4", .3)), result.topComparisons());
         Assertions.assertEquals(
                 "Average of both program coverages. This is the default similarity which"
@@ -40,14 +42,14 @@ public class MetricMapperTest {
     @Test
     public void test_getMaxMetric() {
         // given
-        JPlagResult jPlagResult = createJPlagResult(MockMetric.MAX, distribution(2, 3, 5, 7, 11, 13, 17, 19, 23, 29),
+        JPlagResult jPlagResult = createJPlagResult(MockMetric.MAX, distribution(EXPECTED_DISTRIBUTION),
                 comparison(submission("00"), submission("01"), .7), comparison(submission("10"), submission("11"), .3));
         // when
         var result = metricMapper.getMaxMetric(jPlagResult);
 
         // then
         Assertions.assertEquals("MAX", result.name());
-        Assertions.assertIterableEquals(List.of(2, 3, 5, 7, 11, 13, 17, 19, 23, 29), result.distribution());
+        Assertions.assertIterableEquals(EXPECTED_DISTRIBUTION, result.distribution());
         Assertions.assertEquals(List.of(new TopComparison("00", "01", .7), new TopComparison("10", "11", .3)), result.topComparisons());
         Assertions.assertEquals(
                 "Maximum of both program coverages. This ranking is especially useful if the programs are very "
@@ -55,8 +57,10 @@ public class MetricMapperTest {
                 result.description());
     }
 
-    private int[] distribution(int... numbers) {
-        return numbers;
+    private int[] distribution(List<Integer> expectedDistribution) {
+        var reversedDistribution = new ArrayList<>(expectedDistribution);
+        Collections.reverse(reversedDistribution);
+        return reversedDistribution.stream().mapToInt(Integer::intValue).toArray();
     }
 
     private CreateSubmission submission(String name) {