diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/testsupport/ProjectPaths.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/testsupport/ProjectPaths.java new file mode 100644 index 000000000..c63903367 --- /dev/null +++ b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/testsupport/ProjectPaths.java @@ -0,0 +1,81 @@ +package art.arcane.iris.testsupport; + +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.CodeSource; +import java.security.ProtectionDomain; + +public final class ProjectPaths { + private static final Path MODULE_ROOT = resolveModuleRoot(); + private static final Path REPOSITORY_ROOT = resolveRepositoryRoot(MODULE_ROOT); + + private ProjectPaths() { + } + + public static Path moduleRoot() { + return MODULE_ROOT; + } + + public static Path repositoryRoot() { + return REPOSITORY_ROOT; + } + + public static Path moduleFile(String relative) { + return MODULE_ROOT.resolve(relative).normalize(); + } + + public static Path repositoryFile(String relative) { + return REPOSITORY_ROOT.resolve(relative).normalize(); + } + + public static File moduleFileAt(String relative) { + return moduleFile(relative).toFile(); + } + + public static File repositoryFileAt(String relative) { + return repositoryFile(relative).toFile(); + } + + private static Path resolveModuleRoot() { + ProtectionDomain domain = ProjectPaths.class.getProtectionDomain(); + CodeSource source = domain == null ? null : domain.getCodeSource(); + URL location = source == null ? null : source.getLocation(); + + if (location != null) { + try { + Path current = Path.of(location.toURI()).toAbsolutePath().normalize(); + + while (current != null) { + Path name = current.getFileName(); + + if (name != null && "build".equals(name.toString()) && current.getParent() != null) { + return current.getParent(); + } + + current = current.getParent(); + } + } catch (URISyntaxException | IllegalArgumentException ignored) { + return Path.of("").toAbsolutePath().normalize(); + } + } + + return Path.of("").toAbsolutePath().normalize(); + } + + private static Path resolveRepositoryRoot(Path moduleRoot) { + Path current = moduleRoot; + + while (current != null) { + if (Files.isRegularFile(current.resolve("settings.gradle"))) { + return current; + } + + current = current.getParent(); + } + + return moduleRoot; + } +} diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/localization/ModdedMessageContributorTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/localization/ModdedMessageContributorTest.java index 634ca6702..55a0038a5 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/localization/ModdedMessageContributorTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/localization/ModdedMessageContributorTest.java @@ -2,6 +2,7 @@ package art.arcane.iris.modded.localization; import art.arcane.iris.core.localization.IrisLanguage; import art.arcane.iris.core.localization.IrisMessages; +import art.arcane.iris.modded.testsupport.ProjectPaths; import art.arcane.volmlib.util.localization.MessageKey; import art.arcane.volmlib.util.localization.VolmitLocales; import com.google.gson.JsonObject; @@ -27,7 +28,7 @@ public class ModdedMessageContributorTest { @Test public void completeLoaderCatalogStillMatchesEveryDownloadableLocale() throws Exception { - Path sourceRoot = Path.of("../../core/src/main/resources/languages"); + Path sourceRoot = ProjectPaths.repositoryFile("core/src/main/resources/languages"); for (String locale : VolmitLocales.nonEnglish()) { JsonObject document = JsonParser.parseString(Files.readString(sourceRoot.resolve(locale + ".json"))) .getAsJsonObject(); diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/testsupport/ProjectPaths.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/testsupport/ProjectPaths.java new file mode 100644 index 000000000..8fb746e94 --- /dev/null +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/testsupport/ProjectPaths.java @@ -0,0 +1,81 @@ +package art.arcane.iris.modded.testsupport; + +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.CodeSource; +import java.security.ProtectionDomain; + +public final class ProjectPaths { + private static final Path MODULE_ROOT = resolveModuleRoot(); + private static final Path REPOSITORY_ROOT = resolveRepositoryRoot(MODULE_ROOT); + + private ProjectPaths() { + } + + public static Path moduleRoot() { + return MODULE_ROOT; + } + + public static Path repositoryRoot() { + return REPOSITORY_ROOT; + } + + public static Path moduleFile(String relative) { + return MODULE_ROOT.resolve(relative).normalize(); + } + + public static Path repositoryFile(String relative) { + return REPOSITORY_ROOT.resolve(relative).normalize(); + } + + public static File moduleFileAt(String relative) { + return moduleFile(relative).toFile(); + } + + public static File repositoryFileAt(String relative) { + return repositoryFile(relative).toFile(); + } + + private static Path resolveModuleRoot() { + ProtectionDomain domain = ProjectPaths.class.getProtectionDomain(); + CodeSource source = domain == null ? null : domain.getCodeSource(); + URL location = source == null ? null : source.getLocation(); + + if (location != null) { + try { + Path current = Path.of(location.toURI()).toAbsolutePath().normalize(); + + while (current != null) { + Path name = current.getFileName(); + + if (name != null && "build".equals(name.toString()) && current.getParent() != null) { + return current.getParent(); + } + + current = current.getParent(); + } + } catch (URISyntaxException | IllegalArgumentException ignored) { + return Path.of("").toAbsolutePath().normalize(); + } + } + + return Path.of("").toAbsolutePath().normalize(); + } + + private static Path resolveRepositoryRoot(Path moduleRoot) { + Path current = moduleRoot; + + while (current != null) { + if (Files.isRegularFile(current.resolve("settings.gradle"))) { + return current; + } + + current = current.getParent(); + } + + return moduleRoot; + } +} diff --git a/core/src/test/java/art/arcane/iris/core/localization/IrisDownloadValidationTest.java b/core/src/test/java/art/arcane/iris/core/localization/IrisDownloadValidationTest.java index 84251d6a7..d6b6d71e7 100644 --- a/core/src/test/java/art/arcane/iris/core/localization/IrisDownloadValidationTest.java +++ b/core/src/test/java/art/arcane/iris/core/localization/IrisDownloadValidationTest.java @@ -1,5 +1,6 @@ package art.arcane.iris.core.localization; +import art.arcane.iris.testsupport.ProjectPaths; import art.arcane.volmlib.util.localization.LocaleOverlay; import art.arcane.volmlib.util.localization.LocalizationValidator; import art.arcane.volmlib.util.localization.RemoteLanguageCatalog; @@ -111,7 +112,7 @@ public class IrisDownloadValidationTest { } private String completeCatalog() throws IOException { - return Files.readString(Path.of("src/main/resources/languages", LOCALE + ".json")); + return Files.readString(ProjectPaths.moduleFile("src/main/resources/languages").resolve(LOCALE + ".json")); } private String incompleteCatalog(String complete) { diff --git a/core/src/test/java/art/arcane/iris/core/localization/IrisLanguageEditorTest.java b/core/src/test/java/art/arcane/iris/core/localization/IrisLanguageEditorTest.java index ba2314ac6..94d8222b4 100644 --- a/core/src/test/java/art/arcane/iris/core/localization/IrisLanguageEditorTest.java +++ b/core/src/test/java/art/arcane/iris/core/localization/IrisLanguageEditorTest.java @@ -1,5 +1,6 @@ package art.arcane.iris.core.localization; +import art.arcane.iris.testsupport.ProjectPaths; import art.arcane.volmlib.util.localization.LocalizationCandidate; import art.arcane.volmlib.util.localization.LocalizationSnapshot; import art.arcane.volmlib.util.localization.PluginLanguageEditor; @@ -49,7 +50,7 @@ public class IrisLanguageEditorTest { assertTrue(IrisLanguage.reload(directory, "en_US")); Path cache = IrisLanguage.remote(directory).cacheFile("fr_FR"); Files.createDirectories(cache.getParent()); - Files.copy(Path.of("src/main/resources/languages/fr_FR.json"), cache); + Files.copy(ProjectPaths.moduleFile("src/main/resources/languages/fr_FR.json"), cache); PluginLanguageEditor.Options options = IrisLanguage.editorOptions(); LocalizationSnapshot english = LocalizationSnapshot.create( LocalizationCandidate.english(IrisLanguage.catalog(), PluralSelector.oneOther())); @@ -106,7 +107,7 @@ public class IrisLanguageEditorTest { @Test public void incompleteDownloadedLocaleCanBeEditedWithoutBeingSelected() throws Exception { - byte[] complete = Files.readAllBytes(Path.of("src/main/resources/languages/fr_FR.json")); + byte[] complete = Files.readAllBytes(ProjectPaths.moduleFile("src/main/resources/languages/fr_FR.json")); AtomicInteger requests = new AtomicInteger(); Field remoteField = IrisLanguage.class.getDeclaredField("remote"); remoteField.setAccessible(true); diff --git a/core/src/test/java/art/arcane/iris/core/localization/IrisLanguageTest.java b/core/src/test/java/art/arcane/iris/core/localization/IrisLanguageTest.java index 79425b4c2..8b43f25cc 100644 --- a/core/src/test/java/art/arcane/iris/core/localization/IrisLanguageTest.java +++ b/core/src/test/java/art/arcane/iris/core/localization/IrisLanguageTest.java @@ -1,6 +1,7 @@ package art.arcane.iris.core.localization; import art.arcane.iris.core.IrisSettings; +import art.arcane.iris.testsupport.ProjectPaths; import art.arcane.volmlib.util.localization.MessageArgument; import art.arcane.volmlib.util.localization.LocaleOverlay; import art.arcane.volmlib.util.localization.LocalizationValidationResult; @@ -117,7 +118,7 @@ public class IrisLanguageTest { for (String locale : VolmitLocales.nonEnglish()) { Path target = IrisLanguage.remote(dataFolder).cacheFile(locale); Files.createDirectories(target.getParent()); - Files.copy(Path.of("src/main/resources/languages", locale + ".json"), target, StandardCopyOption.REPLACE_EXISTING); + Files.copy(ProjectPaths.moduleFile("src/main/resources/languages").resolve(locale + ".json"), target, StandardCopyOption.REPLACE_EXISTING); } } @@ -127,7 +128,7 @@ public class IrisLanguageTest { } private LocaleOverlay loadSourceOverlay(String locale) throws Exception { - Path source = Path.of("src/main/resources/languages", locale + ".json"); + Path source = ProjectPaths.moduleFile("src/main/resources/languages").resolve(locale + ".json"); return IrisLanguage.parseDownloadedOverlay(source.toString(), locale, Files.readString(source)); } diff --git a/core/src/test/java/art/arcane/iris/testsupport/ProjectPaths.java b/core/src/test/java/art/arcane/iris/testsupport/ProjectPaths.java new file mode 100644 index 000000000..c63903367 --- /dev/null +++ b/core/src/test/java/art/arcane/iris/testsupport/ProjectPaths.java @@ -0,0 +1,81 @@ +package art.arcane.iris.testsupport; + +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.CodeSource; +import java.security.ProtectionDomain; + +public final class ProjectPaths { + private static final Path MODULE_ROOT = resolveModuleRoot(); + private static final Path REPOSITORY_ROOT = resolveRepositoryRoot(MODULE_ROOT); + + private ProjectPaths() { + } + + public static Path moduleRoot() { + return MODULE_ROOT; + } + + public static Path repositoryRoot() { + return REPOSITORY_ROOT; + } + + public static Path moduleFile(String relative) { + return MODULE_ROOT.resolve(relative).normalize(); + } + + public static Path repositoryFile(String relative) { + return REPOSITORY_ROOT.resolve(relative).normalize(); + } + + public static File moduleFileAt(String relative) { + return moduleFile(relative).toFile(); + } + + public static File repositoryFileAt(String relative) { + return repositoryFile(relative).toFile(); + } + + private static Path resolveModuleRoot() { + ProtectionDomain domain = ProjectPaths.class.getProtectionDomain(); + CodeSource source = domain == null ? null : domain.getCodeSource(); + URL location = source == null ? null : source.getLocation(); + + if (location != null) { + try { + Path current = Path.of(location.toURI()).toAbsolutePath().normalize(); + + while (current != null) { + Path name = current.getFileName(); + + if (name != null && "build".equals(name.toString()) && current.getParent() != null) { + return current.getParent(); + } + + current = current.getParent(); + } + } catch (URISyntaxException | IllegalArgumentException ignored) { + return Path.of("").toAbsolutePath().normalize(); + } + } + + return Path.of("").toAbsolutePath().normalize(); + } + + private static Path resolveRepositoryRoot(Path moduleRoot) { + Path current = moduleRoot; + + while (current != null) { + if (Files.isRegularFile(current.resolve("settings.gradle"))) { + return current; + } + + current = current.getParent(); + } + + return moduleRoot; + } +}