From 491bee409d06b7d15d71d46671cd1b595e42db11 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Tue, 15 Nov 2022 18:18:58 +0000 Subject: [PATCH] prioritise shorter contained roots --- .../mutationtest/tooling/PathComparator.java | 21 ++++++++++++------- .../tooling/PathComparatorTest.java | 19 +++++++++++++++-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/PathComparator.java b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/PathComparator.java index 3057ca87c..372b3c41e 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/PathComparator.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/PathComparator.java @@ -6,7 +6,11 @@ * Comparator to allow ordering of Objects by their closeness to a * given root, assuming their toString provides a path like hierarchy. *

- * Allows paths in same module as a file to be examined before those in other modules + * Allows paths in same module as a file to be examined before those in other modules. + * + * Expects the base path supplied to be deeper than the shared root (e.g. + * /a/b/c/target/pit-reports when shared root is a/b/c) + * */ class PathComparator implements Comparator { @@ -30,16 +34,19 @@ private int distanceFromBase(String s1) { String[] a = s1.split(separator); for (int i = 0; i != baseParts.length; i++) { - if (a.length == i) { - return i - 1; - } - - if (!a[i].equals(baseParts[i])) { + if (a.length == i || !a[i].equals(baseParts[i])) { return i; } + if (a.length - 1 == i) { + // horrible fudge. This path is shorter than our base, but matches everything in it. + // We want to prioritise it above ones that mismatch, so we use a magic 1000. So long + // as the directory structure is not bizarrely deep, short fully matching paths will appear + // before longer mismatched paths. + return i + 1000; + } } - return baseParts.length; + return a.length; } } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/PathComparatorTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/PathComparatorTest.java index de90c61ab..9d471a93b 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/PathComparatorTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/PathComparatorTest.java @@ -20,6 +20,14 @@ public void identicalPathsCompareAsZero() { assertThat(underTest.compare(base,base)).isEqualTo(0); } + @Test + public void shortSubPathsAreWeightedAboveLongPathsThatDoNotMatchBase() { + String base = "a/b/more"; + PathComparator underTest = new PathComparator(base, "/"); + + assertThat(underTest.compare("a/b", "a/b/c/d/e/f")).isLessThan(underTest.compare("a/b/c/d/e", "a/b/c/d/e/f/g/h/i")); + } + @Test public void identicalPathsCompareAsZeroWhenNotUnderBase() { PathComparator underTest = new PathComparator(new File("different/path"), File.separator); @@ -33,8 +41,7 @@ public void sameRootedPathComparesHigher() { PathComparator underTest = new PathComparator(base, File.separator); File sameRoot = new File("start/end/leaf"); File differentRoot = new File("start/different/leaf"); - assertThat(underTest.compare(differentRoot, sameRoot)).isEqualTo(1); - assertThat(underTest.compare(sameRoot, differentRoot)).isEqualTo(-1); + assertThat(underTest.compare(differentRoot, sameRoot)).isGreaterThan(underTest.compare(sameRoot, differentRoot)); } @Test @@ -88,6 +95,14 @@ public void modulesUnderRootAlwaysSortedFirst() { assertThat(paths.get(1)).isEqualTo("a/b/c/d/e"); } + @Test + public void sortsByLengthWhenAllEquallyUnderRoot() { + PathComparator underTest = new PathComparator("a/b/c/irrelevant", "/"); + List paths = asList("a/b/x", "a/b/x/x", "a/b/x/x/x", "a/b/x/x/x/x", "a/b"); + paths.sort(underTest); + assertThat(paths).containsExactly("a/b", "a/b/x", "a/b/x/x", "a/b/x/x/x", "a/b/x/x/x/x"); + } + @Test public void handlesBaseIndexLongerThanSuppliedPath() { PathComparator underTest = new PathComparator("/a/b/c/irrelevant", "/");