diff --git a/src/main/java/net/tfminecraft/research/util/YamlFolder.java b/src/main/java/net/tfminecraft/research/util/YamlFolder.java index 87bfb62..283229d 100644 --- a/src/main/java/net/tfminecraft/research/util/YamlFolder.java +++ b/src/main/java/net/tfminecraft/research/util/YamlFolder.java @@ -3,10 +3,15 @@ import java.io.File; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; public final class YamlFolder { + // Sorted so that duplicate ids resolve the same way on every filesystem: the first file by name wins. + private static final Comparator BY_NAME = Comparator.comparing(File::getName, String.CASE_INSENSITIVE_ORDER) + .thenComparing(File::getName); + private YamlFolder() {} public static List listYamlFiles(File folder) { @@ -23,6 +28,7 @@ public static List listYamlFiles(File folder) { yamlFiles.add(file); } } + yamlFiles.sort(BY_NAME); return yamlFiles; } } diff --git a/src/test/java/net/tfminecraft/research/util/ResearchUtilitiesTest.java b/src/test/java/net/tfminecraft/research/util/ResearchUtilitiesTest.java index 63ce3f1..597d65c 100644 --- a/src/test/java/net/tfminecraft/research/util/ResearchUtilitiesTest.java +++ b/src/test/java/net/tfminecraft/research/util/ResearchUtilitiesTest.java @@ -422,7 +422,7 @@ void yamlFilesAreSelectedOnlyFromReadableDirectories() throws Exception { Files.writeString(directory.resolve("other.txt"), "text"); Files.createDirectory(directory.resolve("folder.yml")); assertEquals(List.of(), YamlFolder.listYamlFiles(lower.toFile())); - assertEquals(Set.of(lower.toFile(), upper.toFile()), new HashSet<>(YamlFolder.listYamlFiles(directory.toFile()))); + assertEquals(List.of(lower.toFile(), upper.toFile()), YamlFolder.listYamlFiles(directory.toFile())); File unreadable = mock(File.class); when(unreadable.exists()).thenReturn(true); when(unreadable.isDirectory()).thenReturn(true); @@ -430,6 +430,26 @@ void yamlFilesAreSelectedOnlyFromReadableDirectories() throws Exception { assertEquals(List.of(), YamlFolder.listYamlFiles(unreadable)); } + @Test + void yamlFilesAreSortedByNameWhateverOrderTheFilesystemLists() { + File folder = mock(File.class); + when(folder.exists()).thenReturn(true); + when(folder.isDirectory()).thenReturn(true); + File b = yamlFile("b.yml"); + File upperA = yamlFile("A.yml"); + File lowerA = yamlFile("a.yml"); + File c = yamlFile("C.yml"); + when(folder.listFiles()).thenReturn(new File[] {c, lowerA, b, upperA}); + assertEquals(List.of(upperA, lowerA, b, c), YamlFolder.listYamlFiles(folder)); + } + + private static File yamlFile(String name) { + File file = mock(File.class); + when(file.isFile()).thenReturn(true); + when(file.getName()).thenReturn(name); + return file; + } + @Test void utilityClassesExposeNoPublicConstructors() throws Exception { for (Class type : List.of(GridLayout.class, AspectProgressLayout.class, AspectSlotOrder.class,