From 248eb365a8320f9b82071b10984ccf8bc473e2a7 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 27 Jul 2022 02:43:49 -0600 Subject: [PATCH 01/33] Add a proper JUnit testing system --- .github/workflows/JUnit-tests.yml | 30 ++++ build.gradle | 33 ++++- src/main/java/ch/njol/skript/Skript.java | 35 ++++- .../java/ch/njol/skript/SkriptCommand.java | 6 +- .../skript/SkriptCommandTabCompleter.java | 2 +- .../{tests => test}/platform/Environment.java | 16 ++- .../platform/PlatformMain.java | 4 +- .../platform}/package-info.java | 2 +- .../runner/CondMinecraftVersion.java | 2 +- .../{tests => test}/runner/EffAssert.java | 2 +- .../{tests => test}/runner/EvtTestCase.java | 2 +- .../runner/SkriptTestEvent.java | 2 +- .../{tests => test}/runner/TestFunctions.java | 2 +- .../{tests => test}/runner/TestMode.java | 4 +- .../{tests => test}/runner/TestTracker.java | 4 +- .../{tests => test/runner}/package-info.java | 2 +- .../njol/skript/test/tests/AliasesTest.java | 55 ++++++++ .../njol/skript/test/tests/ClassesTest.java | 75 ++++++++++ .../njol/skript/test/tests/package-info.java | 27 ++++ .../{tests => test/utils}/TestResults.java | 2 +- .../platform => test/utils}/package-info.java | 4 +- src/main/java/ch/njol/skript/util/Utils.java | 75 +++++++++- .../skript/variables/FlatFileStorageTest.java | 65 +++++++++ .../skriptlang/skript/config/NodeTest.java | 58 ++++++++ .../skript/localization/NounTest.java | 65 +++++++++ .../skriptlang/skript/utils/UtilsTest.java | 128 ++++++++++++++++++ 26 files changed, 669 insertions(+), 33 deletions(-) create mode 100644 .github/workflows/JUnit-tests.yml rename src/main/java/ch/njol/skript/{tests => test}/platform/Environment.java (96%) rename src/main/java/ch/njol/skript/{tests => test}/platform/PlatformMain.java (98%) rename src/main/java/ch/njol/skript/{tests/runner => test/platform}/package-info.java (96%) rename src/main/java/ch/njol/skript/{tests => test}/runner/CondMinecraftVersion.java (98%) rename src/main/java/ch/njol/skript/{tests => test}/runner/EffAssert.java (98%) rename src/main/java/ch/njol/skript/{tests => test}/runner/EvtTestCase.java (98%) rename src/main/java/ch/njol/skript/{tests => test}/runner/SkriptTestEvent.java (96%) rename src/main/java/ch/njol/skript/{tests => test}/runner/TestFunctions.java (98%) rename src/main/java/ch/njol/skript/{tests => test}/runner/TestMode.java (96%) rename src/main/java/ch/njol/skript/{tests => test}/runner/TestTracker.java (95%) rename src/main/java/ch/njol/skript/{tests => test/runner}/package-info.java (96%) create mode 100644 src/main/java/ch/njol/skript/test/tests/AliasesTest.java create mode 100644 src/main/java/ch/njol/skript/test/tests/ClassesTest.java create mode 100644 src/main/java/ch/njol/skript/test/tests/package-info.java rename src/main/java/ch/njol/skript/{tests => test/utils}/TestResults.java (98%) rename src/main/java/ch/njol/skript/{tests/platform => test/utils}/package-info.java (92%) create mode 100644 src/test/java/ch/njol/skript/variables/FlatFileStorageTest.java create mode 100644 src/test/java/org/skriptlang/skript/config/NodeTest.java create mode 100644 src/test/java/org/skriptlang/skript/localization/NounTest.java create mode 100644 src/test/java/org/skriptlang/skript/utils/UtilsTest.java diff --git a/.github/workflows/JUnit-tests.yml b/.github/workflows/JUnit-tests.yml new file mode 100644 index 00000000000..fa70aa2a0aa --- /dev/null +++ b/.github/workflows/JUnit-tests.yml @@ -0,0 +1,30 @@ +name: JUnit Tests + +on: + push: + branches: + - main + - 'dev/**' + pull_request: + +jobs: + build: + if: "! contains(toJSON(github.event.commits.*.message), '[ci skip]')" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'adopt' + cache: gradle + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build Skript + run: ./gradlew nightlyRelease + - name: Run non-runtime JUnit tests + run: ./gradlew clean test + diff --git a/build.gradle b/build.gradle index 39506d9defb..6b7b7033182 100644 --- a/build.gradle +++ b/build.gradle @@ -19,11 +19,17 @@ allprojects { maven { url 'https://repo.papermc.io/repository/maven-public/' } maven { url 'https://ci.emc.gs/nexus/content/groups/aikar/' } } + configurations.all { + resolutionStrategy { + force('org.junit.jupiter:junit-jupiter-engine:5.8.1') + } + } } dependencies { shadow group: 'io.papermc', name: 'paperlib', version: '1.0.7' shadow group: 'org.bstats', name: 'bstats-bukkit', version: '3.0.0' + implementation group: 'io.papermc.paper', name: 'paper-api', version: '1.19-R0.1-SNAPSHOT' implementation group: 'org.eclipse.jdt', name: 'org.eclipse.jdt.annotation', version: '2.2.600' implementation group: 'com.google.code.findbugs', name: 'findbugs', version: '3.0.1' @@ -31,7 +37,16 @@ dependencies { implementation group: 'net.milkbowl.vault', name: 'Vault', version: '1.7.1', { exclude group: 'org.bstats', module: 'bstats-bukkit' } + implementation fileTree(dir: 'lib', include: '*.jar') + + // JUnit 4 Runner for Runtime tests. + shadow fileTree(dir: 'lib', include: 'junit-4.13.2.jar') + shadow fileTree(dir: 'lib', include: 'hamcrest-2.2.jar') + + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.1' + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.8.1' + testImplementation group: 'org.easymock', name: 'easymock', version: '4.2' } compileJava.options.encoding = 'UTF-8' @@ -51,11 +66,21 @@ task jar(overwrite: true, type: ShadowJar) { dependsOn checkAliases archiveName jarName ? 'Skript.jar' : jarName from sourceSets.main.output + dependencies { + exclude(dependency('org.hamcrest:.*')) + exclude(dependency('org.junit:.*')) + exclude(dependency('junit:.*')) + } } task build(overwrite: true, type: ShadowJar) { archiveName jarName ? 'Skript.jar' : jarName from sourceSets.main.output + dependencies { + exclude(dependency('org.hamcrest:.*')) + exclude(dependency('org.junit:.*')) + exclude(dependency('junit:.*')) + } } task relocateShadowJar(type: ConfigureShadowRelocation) { @@ -174,7 +199,7 @@ void createTestTask(String name, String environments, boolean devMode, int javaV project.configurations.runtimeClasspath.find { it.name.startsWith('gson') }, sourceSets.main.runtimeClasspath ]) - main = 'ch.njol.skript.tests.platform.PlatformMain' + main = 'ch.njol.skript.test.platform.PlatformMain' args = [ 'test_runners', 'src/test/skript/tests', @@ -307,3 +332,9 @@ task nightlyRelease(type: ShadowJar) { ) } } + + +test { + useJUnitPlatform() + dependsOn jar +} diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 7d6b0d9827c..4cbc60463eb 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -72,6 +72,8 @@ import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; import org.eclipse.jdt.annotation.Nullable; +import org.junit.runner.JUnitCore; +import org.junit.runner.Result; import com.google.gson.Gson; @@ -119,9 +121,9 @@ import ch.njol.skript.registrations.Comparators; import ch.njol.skript.registrations.Converters; import ch.njol.skript.registrations.EventValues; -import ch.njol.skript.tests.runner.SkriptTestEvent; -import ch.njol.skript.tests.runner.TestMode; -import ch.njol.skript.tests.runner.TestTracker; +import ch.njol.skript.test.runner.SkriptTestEvent; +import ch.njol.skript.test.runner.TestMode; +import ch.njol.skript.test.runner.TestTracker; import ch.njol.skript.timings.SkriptTimings; import ch.njol.skript.update.ReleaseManifest; import ch.njol.skript.update.ReleaseStatus; @@ -555,7 +557,7 @@ public void run() { info("Preparing Skript for testing..."); tainted = true; try { - getAddonInstance().loadClasses("ch.njol.skript", "tests"); + getAddonInstance().loadClasses("ch.njol.skript.test", "runner"); } catch (IOException e) { Skript.exception("Failed to load testing environment."); Bukkit.getServer().shutdown(); @@ -628,6 +630,30 @@ protected void afterErrors() { if (TestMode.DEV_MODE) { // Run tests NOW! info("Test development mode enabled. Test scripts are at " + TestMode.TEST_DIR); } else { + info("Running all JUnit tests..."); + long milliseconds = 0, tests = 0, fails = 0, ignored = 0; + try { + for (Class test : Utils.getClasses("ch.njol.skript.test", "tests")) { + Result junit = JUnitCore.runClasses(test); + TestTracker.testStarted("JUnit: '" + test.getName() + "'"); + tests += junit.getRunCount(); + milliseconds += junit.getRunTime(); + ignored += junit.getIgnoreCount(); + if (junit.getFailureCount() > 0) { + fails += junit.getFailureCount(); + junit.getFailures().forEach(failure -> { + String message = failure.getMessage() == null ? "" : " " + failure.getMessage(); + TestTracker.testFailed("JUnit: '" + test.getName() + "'" + message); + Skript.exception(failure.getException(), "JUnit test '" + failure.getTestHeader() + " failed."); + }); + } + } + } catch (IOException e) { + Skript.exception(e, "Failed to execute JUnit runtime tests."); + } + if (ignored > 0) + Skript.warning("There were " + ignored + " ignored test cases! This can mean they are not properly setup in order for that class!"); + info("Completed " + tests + " JUnit tests with " + fails + " failures in " + milliseconds + " milliseconds."); info("Running all tests from " + TestMode.TEST_DIR); // Treat parse errors as fatal testing failure @@ -660,6 +686,7 @@ protected void afterErrors() { Skript.exception(e, "Failed to write test results."); } info("Testing done, shutting down the server."); + // Delay server shutdown to stop the server from crashing because the current tick takes a long time due to all the tests Bukkit.getScheduler().runTaskLater(Skript.this, () -> { Bukkit.getServer().shutdown(); diff --git a/src/main/java/ch/njol/skript/SkriptCommand.java b/src/main/java/ch/njol/skript/SkriptCommand.java index 66c90b38a73..6fc7f4d0fd5 100644 --- a/src/main/java/ch/njol/skript/SkriptCommand.java +++ b/src/main/java/ch/njol/skript/SkriptCommand.java @@ -43,9 +43,9 @@ import ch.njol.skript.localization.PluralizingArgsMessage; import ch.njol.skript.log.RedirectingLogHandler; import ch.njol.skript.log.TimingLogHandler; -import ch.njol.skript.tests.runner.SkriptTestEvent; -import ch.njol.skript.tests.runner.TestMode; -import ch.njol.skript.tests.runner.TestTracker; +import ch.njol.skript.test.runner.SkriptTestEvent; +import ch.njol.skript.test.runner.TestMode; +import ch.njol.skript.test.runner.TestTracker; import ch.njol.skript.util.ExceptionUtils; import ch.njol.skript.util.FileUtils; import ch.njol.skript.util.SkriptColor; diff --git a/src/main/java/ch/njol/skript/SkriptCommandTabCompleter.java b/src/main/java/ch/njol/skript/SkriptCommandTabCompleter.java index 10cc7649a6f..7eebe42e551 100644 --- a/src/main/java/ch/njol/skript/SkriptCommandTabCompleter.java +++ b/src/main/java/ch/njol/skript/SkriptCommandTabCompleter.java @@ -18,7 +18,7 @@ */ package ch.njol.skript; -import ch.njol.skript.tests.runner.TestMode; +import ch.njol.skript.test.runner.TestMode; import ch.njol.util.StringUtils; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; diff --git a/src/main/java/ch/njol/skript/tests/platform/Environment.java b/src/main/java/ch/njol/skript/test/platform/Environment.java similarity index 96% rename from src/main/java/ch/njol/skript/tests/platform/Environment.java rename to src/main/java/ch/njol/skript/test/platform/Environment.java index 763a9d94f90..cea3e99e533 100644 --- a/src/main/java/ch/njol/skript/tests/platform/Environment.java +++ b/src/main/java/ch/njol/skript/test/platform/Environment.java @@ -16,13 +16,15 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests.platform; +package ch.njol.skript.test.platform; -import ch.njol.skript.tests.TestResults; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; + +import ch.njol.skript.test.utils.TestResults; + import org.eclipse.jdt.annotation.Nullable; import java.io.File; @@ -239,11 +241,11 @@ public TestResults runTests(Path runnerRoot, Path testsRoot, boolean devMode, bo args.addAll(Arrays.asList(commandLine)); Process process = new ProcessBuilder(args) - .directory(env.toFile()) - .redirectOutput(Redirect.INHERIT) - .redirectError(Redirect.INHERIT) - .redirectInput(Redirect.INHERIT) - .start(); + .directory(env.toFile()) + .redirectOutput(Redirect.INHERIT) + .redirectError(Redirect.INHERIT) + .redirectInput(Redirect.INHERIT) + .start(); // When we exit, try to make them exit too Runtime.getRuntime().addShutdownHook(new Thread(() -> { diff --git a/src/main/java/ch/njol/skript/tests/platform/PlatformMain.java b/src/main/java/ch/njol/skript/test/platform/PlatformMain.java similarity index 98% rename from src/main/java/ch/njol/skript/tests/platform/PlatformMain.java rename to src/main/java/ch/njol/skript/test/platform/PlatformMain.java index 0098f97200e..22975df5b6a 100644 --- a/src/main/java/ch/njol/skript/tests/platform/PlatformMain.java +++ b/src/main/java/ch/njol/skript/test/platform/PlatformMain.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests.platform; +package ch.njol.skript.test.platform; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -39,7 +39,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonSyntaxException; -import ch.njol.skript.tests.TestResults; +import ch.njol.skript.test.utils.TestResults; import ch.njol.util.NonNullPair; /** diff --git a/src/main/java/ch/njol/skript/tests/runner/package-info.java b/src/main/java/ch/njol/skript/test/platform/package-info.java similarity index 96% rename from src/main/java/ch/njol/skript/tests/runner/package-info.java rename to src/main/java/ch/njol/skript/test/platform/package-info.java index 8d276f66853..6ea91784b5f 100644 --- a/src/main/java/ch/njol/skript/tests/runner/package-info.java +++ b/src/main/java/ch/njol/skript/test/platform/package-info.java @@ -20,7 +20,7 @@ * Support for script-based testing. */ @NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) -package ch.njol.skript.tests.runner; +package ch.njol.skript.test.platform; import org.eclipse.jdt.annotation.DefaultLocation; import org.eclipse.jdt.annotation.NonNullByDefault; diff --git a/src/main/java/ch/njol/skript/tests/runner/CondMinecraftVersion.java b/src/main/java/ch/njol/skript/test/runner/CondMinecraftVersion.java similarity index 98% rename from src/main/java/ch/njol/skript/tests/runner/CondMinecraftVersion.java rename to src/main/java/ch/njol/skript/test/runner/CondMinecraftVersion.java index 4aaafa405f7..bc5f1436349 100644 --- a/src/main/java/ch/njol/skript/tests/runner/CondMinecraftVersion.java +++ b/src/main/java/ch/njol/skript/test/runner/CondMinecraftVersion.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests.runner; +package ch.njol.skript.test.runner; import org.bukkit.event.Event; import org.eclipse.jdt.annotation.Nullable; diff --git a/src/main/java/ch/njol/skript/tests/runner/EffAssert.java b/src/main/java/ch/njol/skript/test/runner/EffAssert.java similarity index 98% rename from src/main/java/ch/njol/skript/tests/runner/EffAssert.java rename to src/main/java/ch/njol/skript/test/runner/EffAssert.java index e86fe7127cb..16af12d11c3 100644 --- a/src/main/java/ch/njol/skript/tests/runner/EffAssert.java +++ b/src/main/java/ch/njol/skript/test/runner/EffAssert.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests.runner; +package ch.njol.skript.test.runner; import org.bukkit.event.Event; import org.eclipse.jdt.annotation.Nullable; diff --git a/src/main/java/ch/njol/skript/tests/runner/EvtTestCase.java b/src/main/java/ch/njol/skript/test/runner/EvtTestCase.java similarity index 98% rename from src/main/java/ch/njol/skript/tests/runner/EvtTestCase.java rename to src/main/java/ch/njol/skript/test/runner/EvtTestCase.java index 82809604a19..eb6bbd93b4f 100644 --- a/src/main/java/ch/njol/skript/tests/runner/EvtTestCase.java +++ b/src/main/java/ch/njol/skript/test/runner/EvtTestCase.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests.runner; +package ch.njol.skript.test.runner; import org.bukkit.event.Event; import org.eclipse.jdt.annotation.Nullable; diff --git a/src/main/java/ch/njol/skript/tests/runner/SkriptTestEvent.java b/src/main/java/ch/njol/skript/test/runner/SkriptTestEvent.java similarity index 96% rename from src/main/java/ch/njol/skript/tests/runner/SkriptTestEvent.java rename to src/main/java/ch/njol/skript/test/runner/SkriptTestEvent.java index be7bf978857..558a7ae458e 100644 --- a/src/main/java/ch/njol/skript/tests/runner/SkriptTestEvent.java +++ b/src/main/java/ch/njol/skript/test/runner/SkriptTestEvent.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests.runner; +package ch.njol.skript.test.runner; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; diff --git a/src/main/java/ch/njol/skript/tests/runner/TestFunctions.java b/src/main/java/ch/njol/skript/test/runner/TestFunctions.java similarity index 98% rename from src/main/java/ch/njol/skript/tests/runner/TestFunctions.java rename to src/main/java/ch/njol/skript/test/runner/TestFunctions.java index 21f31a52b80..fe9a434cebe 100644 --- a/src/main/java/ch/njol/skript/tests/runner/TestFunctions.java +++ b/src/main/java/ch/njol/skript/test/runner/TestFunctions.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests.runner; +package ch.njol.skript.test.runner; import ch.njol.skript.classes.ClassInfo; import ch.njol.skript.lang.function.Functions; diff --git a/src/main/java/ch/njol/skript/tests/runner/TestMode.java b/src/main/java/ch/njol/skript/test/runner/TestMode.java similarity index 96% rename from src/main/java/ch/njol/skript/tests/runner/TestMode.java rename to src/main/java/ch/njol/skript/test/runner/TestMode.java index d4612da0b4a..a68f0217fa5 100644 --- a/src/main/java/ch/njol/skript/tests/runner/TestMode.java +++ b/src/main/java/ch/njol/skript/test/runner/TestMode.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests.runner; +package ch.njol.skript.test.runner; import java.io.File; import java.nio.file.Path; @@ -24,7 +24,7 @@ import org.eclipse.jdt.annotation.Nullable; -import ch.njol.skript.tests.TestResults; +import ch.njol.skript.test.utils.TestResults; /** * Static utilities for Skript's 'test mode'. diff --git a/src/main/java/ch/njol/skript/tests/runner/TestTracker.java b/src/main/java/ch/njol/skript/test/runner/TestTracker.java similarity index 95% rename from src/main/java/ch/njol/skript/tests/runner/TestTracker.java rename to src/main/java/ch/njol/skript/test/runner/TestTracker.java index a80ca913814..8d1bf2facd3 100644 --- a/src/main/java/ch/njol/skript/tests/runner/TestTracker.java +++ b/src/main/java/ch/njol/skript/test/runner/TestTracker.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests.runner; +package ch.njol.skript.test.runner; import java.util.HashMap; import java.util.HashSet; @@ -25,7 +25,7 @@ import org.eclipse.jdt.annotation.Nullable; -import ch.njol.skript.tests.TestResults; +import ch.njol.skript.test.utils.TestResults; /** * Tracks failed and succeeded tests. diff --git a/src/main/java/ch/njol/skript/tests/package-info.java b/src/main/java/ch/njol/skript/test/runner/package-info.java similarity index 96% rename from src/main/java/ch/njol/skript/tests/package-info.java rename to src/main/java/ch/njol/skript/test/runner/package-info.java index bee5911b214..0111f884a88 100644 --- a/src/main/java/ch/njol/skript/tests/package-info.java +++ b/src/main/java/ch/njol/skript/test/runner/package-info.java @@ -20,7 +20,7 @@ * Support for script-based testing. */ @NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) -package ch.njol.skript.tests; +package ch.njol.skript.test.runner; import org.eclipse.jdt.annotation.DefaultLocation; import org.eclipse.jdt.annotation.NonNullByDefault; diff --git a/src/main/java/ch/njol/skript/test/tests/AliasesTest.java b/src/main/java/ch/njol/skript/test/tests/AliasesTest.java new file mode 100644 index 00000000000..c1de1292d4b --- /dev/null +++ b/src/main/java/ch/njol/skript/test/tests/AliasesTest.java @@ -0,0 +1,55 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +package ch.njol.skript.test.tests; + +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.junit.Test; +import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.registrations.Classes; + +public class AliasesTest { + + @Test + public void test() { + ItemStack itemstack = new ItemStack(Material.LEATHER_CHESTPLATE, 6); + ItemMeta meta = itemstack.getItemMeta(); + assert meta instanceof LeatherArmorMeta; + LeatherArmorMeta leather = (LeatherArmorMeta) meta; + leather.setColor(Color.LIME); + itemstack.setItemMeta(leather); + ItemType itemType = new ItemType(itemstack); + assert itemType.equals(new ItemType(itemstack)); + + itemstack = new ItemStack(Material.LEATHER_CHESTPLATE, 2); + meta = itemstack.getItemMeta(); + assert meta instanceof LeatherArmorMeta; + leather = (LeatherArmorMeta) meta; + leather.setColor(Color.RED); + itemstack.setItemMeta(leather); + assert !itemType.equals(new ItemType(itemstack)); + + assert Classes.serialize(itemType).equals(Classes.serialize(itemType)); + assert !Classes.serialize(itemType).equals(Classes.serialize(new ItemType(itemstack))); + } + +} diff --git a/src/main/java/ch/njol/skript/test/tests/ClassesTest.java b/src/main/java/ch/njol/skript/test/tests/ClassesTest.java new file mode 100644 index 00000000000..b77a9f8c970 --- /dev/null +++ b/src/main/java/ch/njol/skript/test/tests/ClassesTest.java @@ -0,0 +1,75 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +package ch.njol.skript.test.tests; + +import org.bukkit.GameMode; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Snowball; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.inventory.InventoryType; +import org.junit.Test; + +import ch.njol.skript.entity.CreeperData; +import ch.njol.skript.entity.EntityType; +import ch.njol.skript.entity.SimpleEntityData; +import ch.njol.skript.entity.ThrownPotionData; +import ch.njol.skript.entity.WolfData; +import ch.njol.skript.entity.XpOrbData; +import ch.njol.skript.registrations.Classes; +import ch.njol.skript.util.Date; +import ch.njol.skript.util.Direction; +import ch.njol.skript.util.Experience; +import ch.njol.skript.util.SkriptColor; +import ch.njol.skript.util.StructureType; +import ch.njol.skript.util.Time; +import ch.njol.skript.util.Timeperiod; +import ch.njol.skript.util.Timespan; +import ch.njol.skript.util.WeatherType; + +public class ClassesTest { + + @Test + public void test() { + Object[] random = { + // Java + (byte) 127, (short) 2000, -1600000, 1L << 40, -1.5f, 13.37, + "String", + + // Skript + SkriptColor.BLACK, StructureType.RED_MUSHROOM, WeatherType.THUNDER, + new Date(System.currentTimeMillis()), new Timespan(1337), new Time(12000), new Timeperiod(1000, 23000), + new Experience(15), new Direction(0, Math.PI, 10), new Direction(new double[] {0, 1, 0}), + new EntityType(new SimpleEntityData(HumanEntity.class), 300), + new CreeperData(), + new SimpleEntityData(Snowball.class), + new ThrownPotionData(), + new WolfData(), + new XpOrbData(50), + + // Bukkit - simple classes only + GameMode.ADVENTURE, InventoryType.CHEST, DamageCause.FALL, + + // there is also at least one variable for each class on my test server which are tested whenever the server shuts down. + }; + for (Object o : random) { + Classes.serialize(o); // includes a deserialisation test + } + } + +} diff --git a/src/main/java/ch/njol/skript/test/tests/package-info.java b/src/main/java/ch/njol/skript/test/tests/package-info.java new file mode 100644 index 00000000000..22b410830c5 --- /dev/null +++ b/src/main/java/ch/njol/skript/test/tests/package-info.java @@ -0,0 +1,27 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +/** + * Runs JUnit tests runtime after server started. + */ +@NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) +package ch.njol.skript.test.tests; + +import org.eclipse.jdt.annotation.DefaultLocation; +import org.eclipse.jdt.annotation.NonNullByDefault; + diff --git a/src/main/java/ch/njol/skript/tests/TestResults.java b/src/main/java/ch/njol/skript/test/utils/TestResults.java similarity index 98% rename from src/main/java/ch/njol/skript/tests/TestResults.java rename to src/main/java/ch/njol/skript/test/utils/TestResults.java index ecc9045f0b2..53586491992 100644 --- a/src/main/java/ch/njol/skript/tests/TestResults.java +++ b/src/main/java/ch/njol/skript/test/utils/TestResults.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests; +package ch.njol.skript.test.utils; import java.util.Map; import java.util.Set; diff --git a/src/main/java/ch/njol/skript/tests/platform/package-info.java b/src/main/java/ch/njol/skript/test/utils/package-info.java similarity index 92% rename from src/main/java/ch/njol/skript/tests/platform/package-info.java rename to src/main/java/ch/njol/skript/test/utils/package-info.java index eef7a9713b0..846a1258239 100644 --- a/src/main/java/ch/njol/skript/tests/platform/package-info.java +++ b/src/main/java/ch/njol/skript/test/utils/package-info.java @@ -17,10 +17,10 @@ * Copyright Peter Güttinger, SkriptLang team and contributors */ /** - * Support for script-based testing. + * Utils for script-based testing. */ @NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) -package ch.njol.skript.tests.platform; +package ch.njol.skript.test.utils; import org.eclipse.jdt.annotation.DefaultLocation; import org.eclipse.jdt.annotation.NonNullByDefault; diff --git a/src/main/java/ch/njol/skript/util/Utils.java b/src/main/java/ch/njol/skript/util/Utils.java index 7598fb83b74..0094d47593c 100644 --- a/src/main/java/ch/njol/skript/util/Utils.java +++ b/src/main/java/ch/njol/skript/util/Utils.java @@ -18,6 +18,11 @@ */ package ch.njol.skript.util; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -25,12 +30,15 @@ import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.messaging.Messenger; import org.bukkit.plugin.messaging.PluginMessageListener; import org.eclipse.jdt.annotation.Nullable; @@ -51,6 +59,7 @@ import ch.njol.util.Pair; import ch.njol.util.StringUtils; import ch.njol.util.coll.CollectionUtils; +import ch.njol.util.coll.iterator.EnumerationIterable; import net.md_5.bungee.api.ChatColor; /** @@ -149,7 +158,71 @@ public static Pair getAmount(String s) { // } // return new AmountResponse(s); // } - + + public static Class[] getClasses(String basePackage, String... subPackages) throws IOException { + assert subPackages != null; + JarFile jar = new JarFile(getFile()); + for (int i = 0; i < subPackages.length; i++) + subPackages[i] = subPackages[i].replace('.', '/') + "/"; + basePackage = basePackage.replace('.', '/') + "/"; + List> classes = new ArrayList<>(); + try { + List classNames = new ArrayList<>(); + + for (JarEntry e : new EnumerationIterable<>(jar.entries())) { + if (e.getName().startsWith(basePackage) && e.getName().endsWith(".class") && !e.getName().endsWith("package-info.class")) { + boolean load = subPackages.length == 0; + for (String sub : subPackages) { + if (e.getName().startsWith(sub, basePackage.length())) { + load = true; + break; + } + } + + if (load) + classNames.add(e.getName().replace('/', '.').substring(0, e.getName().length() - ".class".length())); + } + } + + classNames.sort(String::compareToIgnoreCase); + + for (String c : classNames) { + try { + classes.add(Class.forName(c, true, Skript.getInstance().getClass().getClassLoader())); + } catch (ClassNotFoundException ex) { + Skript.exception(ex, "Cannot load class " + c); + } catch (ExceptionInInitializerError err) { + Skript.exception(err.getCause(), "class " + c + " generated an exception while loading"); + } + } + } finally { + try { + jar.close(); + } catch (IOException e) {} + } + return classes.toArray(Class[]::new); + } + + @Nullable + private static File getFile() { + try { + final Method getFile = JavaPlugin.class.getDeclaredMethod("getFile"); + getFile.setAccessible(true); + return (File) getFile.invoke(Skript.getInstance()); + } catch (final NoSuchMethodException e) { + Skript.outdatedError(e); + } catch (final IllegalArgumentException e) { + Skript.outdatedError(e); + } catch (final IllegalAccessException e) { + assert false; + } catch (final SecurityException e) { + throw new RuntimeException(e); + } catch (final InvocationTargetException e) { + throw new RuntimeException(e.getCause()); + } + return null; + } + private final static String[][] plurals = { {"fe", "ves"},// most -f words' plurals can end in -fs as well as -ves diff --git a/src/test/java/ch/njol/skript/variables/FlatFileStorageTest.java b/src/test/java/ch/njol/skript/variables/FlatFileStorageTest.java new file mode 100644 index 00000000000..596c549ccd3 --- /dev/null +++ b/src/test/java/ch/njol/skript/variables/FlatFileStorageTest.java @@ -0,0 +1,65 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +package ch.njol.skript.variables; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.junit.Test; + +public class FlatFileStorageTest { + + @Test + public void testHexCoding() { + byte[] bytes = {-0x80, -0x50, -0x01, 0x00, 0x01, 0x44, 0x7F}; + String string = "80B0FF0001447F"; + assertEquals(string, FlatFileStorage.encode(bytes)); + assert Arrays.equals(bytes, FlatFileStorage.decode(string)) : Arrays.toString(bytes) + " != " + Arrays.toString(FlatFileStorage.decode(string)); + } + + @Test + public void testCSV() { + String[][] vs = { + {"", ""}, + {",", "", ""}, + {",,", "", "", ""}, + {"a", "a"}, + {"a,", "a", ""}, + {",a", "", "a"}, + {",a,", "", "a", ""}, + {" , a , ", "", "a", ""}, + {"a,b,c", "a", "b", "c"}, + {" a , b , c ", "a", "b", "c"}, + + {"\"\"", ""}, + {"\",\"", ","}, + {"\"\"\"\"", "\""}, + {"\" \"", " "}, + {"a, \"\"\"\", b, \", c\", d", "a", "\"", "b", ", c", "d"}, + {"a, \"\"\", b, \", c", "a", "\", b, ", "c"}, + + {"\"\t\0\"", "\t\0"}, + }; + for (String[] v : vs) { + assert Arrays.equals(Arrays.copyOfRange(v, 1, v.length), FlatFileStorage.splitCSV(v[0])) : v[0] + ": " + Arrays.toString(Arrays.copyOfRange(v, 1, v.length)) + " != " + Arrays.toString(FlatFileStorage.splitCSV(v[0])); + } + } + +} diff --git a/src/test/java/org/skriptlang/skript/config/NodeTest.java b/src/test/java/org/skriptlang/skript/config/NodeTest.java new file mode 100644 index 00000000000..ef4235cc9d2 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/config/NodeTest.java @@ -0,0 +1,58 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +package org.skriptlang.skript.config; + +import static org.junit.Assert.assertArrayEquals; + +import org.junit.Test; + +import ch.njol.skript.config.Node; +import ch.njol.util.NonNullPair; + +public class NodeTest { + + @Test + public void splitLineTest() { + String[][] data = { + {"", "", ""}, + {"ab", "ab", ""}, + {"ab#", "ab", "#"}, + {"ab##", "ab#", ""}, + {"ab###", "ab#", "#"}, + {"#ab", "", "#ab"}, + {"ab#cd", "ab", "#cd"}, + {"ab##cd", "ab#cd", ""}, + {"ab###cd", "ab#", "#cd"}, + {"######", "###", ""}, + {"#######", "###", "#"}, + {"#### # ####", "## ", "# ####"}, + {"##### ####", "##", "# ####"}, + {"#### #####", "## ##", "#"}, + {"#########", "####", "#"}, + {"a##b#c##d#e", "a#b", "#c##d#e"}, + {" a ## b # c ## d # e ", " a # b ", "# c ## d # e "}, + }; + for (String[] d : data) { + NonNullPair p = Node.splitLine(d[0]); + assertArrayEquals(d[0], new String[] {d[1], d[2]}, new String[] {p.getFirst(), p.getSecond()}); + } + + } + +} diff --git a/src/test/java/org/skriptlang/skript/localization/NounTest.java b/src/test/java/org/skriptlang/skript/localization/NounTest.java new file mode 100644 index 00000000000..d2cfe553b45 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/localization/NounTest.java @@ -0,0 +1,65 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +package org.skriptlang.skript.localization; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import ch.njol.skript.localization.Noun; +import ch.njol.util.NonNullPair; + +public class NounTest { + + @Test + public void testGetPlural() { + String[][] tests = { + {"a", "a", "a"}, + {"a¦b", "a", "ab"}, + {"a¦b¦c", "ab", "ac"}, + {"a¦b¦c¦d", "abd", "acd"}, + {"a¦b¦c¦d¦e", "abd", "acde"}, + {"a¦b¦c¦d¦e¦f", "abde", "acdf"}, + {"a¦b¦c¦d¦e¦f¦g", "abdeg", "acdfg"}, + }; + for (String[] test : tests) { + NonNullPair p = Noun.getPlural(test[0]); + assertEquals(test[1], p.getFirst()); + assertEquals(test[2], p.getSecond()); + } + } + + @Test + public void testNormalizePluralMarkers() { + String[][] tests = { + {"a", "a"}, + {"a¦b", "a¦¦b¦"}, + {"a¦b¦c", "a¦b¦c¦"}, + {"a¦b¦c¦d", "a¦b¦c¦d"}, + {"a¦b¦c¦d¦e", "a¦b¦c¦d¦¦e¦"}, + {"a¦b¦c¦d¦e¦f", "a¦b¦c¦d¦e¦f¦"}, + {"a¦b¦c¦d¦e¦f¦g", "a¦b¦c¦d¦e¦f¦g"}, + }; + for (String[] test : tests) { + assertEquals(test[1], Noun.normalizePluralMarkers(test[0])); + assertEquals(test[1] + "@x", Noun.normalizePluralMarkers(test[0] + "@x")); + } + } + +} diff --git a/src/test/java/org/skriptlang/skript/utils/UtilsTest.java b/src/test/java/org/skriptlang/skript/utils/UtilsTest.java new file mode 100644 index 00000000000..abe58831f55 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/utils/UtilsTest.java @@ -0,0 +1,128 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +package org.skriptlang.skript.utils; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.replay; +import static org.junit.Assert.assertEquals; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.UnknownHostException; +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.junit.Before; +import org.junit.Test; + +import ch.njol.skript.log.SkriptLogger; +import ch.njol.skript.util.Utils; + +public class UtilsTest { + + @Before + public void fakeServer() throws Exception { + if (Bukkit.getServer() == null) { + Logger logger = Logger.getLogger(getClass().getCanonicalName()); + logger.setParent(SkriptLogger.LOGGER); + logger.setLevel(Level.WARNING); + + Server server = createMock(Server.class); + server.getLogger(); + expectLastCall().andReturn(logger).anyTimes(); + server.isPrimaryThread(); + expectLastCall().andReturn(true).anyTimes(); + server.getName(); + expectLastCall().andReturn("Whatever").anyTimes(); + server.getVersion(); + expectLastCall().andReturn("2.0").anyTimes(); + server.getBukkitVersion(); + expectLastCall().andReturn("2.0").anyTimes(); + replay(server); + + Bukkit.setServer(server); + } + } + + @Test + public void testPlural() { + String[][] strings = { + {"house", "houses"}, + {"cookie", "cookies"}, + {"creeper", "creepers"}, + {"cactus", "cacti"}, + {"rose", "roses"}, + {"dye", "dyes"}, + {"name", "names"}, + {"ingot", "ingots"}, + {"derp", "derps"}, + {"sheep", "sheep"}, + {"choir", "choirs"}, + {"man", "men"}, + {"child", "children"}, + {"hoe", "hoes"}, + {"toe", "toes"}, + {"hero", "heroes"}, + {"kidney", "kidneys"}, + {"anatomy", "anatomies"}, + {"axe", "axes"}, + {"elf", "elfs"}, + {"knife", "knives"}, + {"shelf", "shelfs"}, + }; + for (String[] s : strings) { + assertEquals(s[1], Utils.toEnglishPlural(s[0])); + assertEquals(s[0], Utils.getEnglishPlural(s[1]).getFirst()); + } + } + + @Test + public void testSuperClass() { + Class[][] classes = { + {Object.class, Object.class}, + {String.class, String.class}, + {String.class, Object.class, Object.class}, + {Object.class, String.class, Object.class}, + {String.class, String.class, String.class}, + {Object.class, String.class, Object.class, String.class, Object.class}, + {Double.class, Integer.class, Number.class}, + {UnknownHostException.class, FileNotFoundException.class, IOException.class}, + {SortedMap.class, TreeMap.class, SortedMap.class}, + {LinkedList.class, ArrayList.class, AbstractList.class}, + {List.class, Set.class, Collection.class}, + {ArrayList.class, Set.class, Collection.class}, + }; + for (Class[] cs : classes) { + assertEquals(cs[cs.length - 1], Utils.getSuperType(Arrays.copyOf(cs, cs.length - 1))); + } + } + +} From 17160468eb8b271713dbe31ba983590b9ba471d0 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Tue, 16 Aug 2022 20:06:51 -0600 Subject: [PATCH 02/33] Fix Java 8 --- src/main/java/ch/njol/skript/util/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/util/Utils.java b/src/main/java/ch/njol/skript/util/Utils.java index 0094d47593c..02805f7e17e 100644 --- a/src/main/java/ch/njol/skript/util/Utils.java +++ b/src/main/java/ch/njol/skript/util/Utils.java @@ -200,7 +200,7 @@ public static Class[] getClasses(String basePackage, String... subPackages) t jar.close(); } catch (IOException e) {} } - return classes.toArray(Class[]::new); + return classes.toArray(new Class[classes.size()]); } @Nullable From 9c362c6e3795bbfa11a4219b3572ca259a14b9f4 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 17 Aug 2022 01:34:08 -0600 Subject: [PATCH 03/33] Make test jar compile with different dependencies --- .github/workflows/JUnit-tests.yml | 30 ---------------- build.gradle | 34 ++++++++----------- src/main/java/ch/njol/skript/Skript.java | 16 +++++++-- .../njol/skript/test/tests/package-info.java | 27 --------------- .../test/tests/aliases}/AliasesTest.java | 6 ++-- .../test/tests/classes}/ClassesTest.java | 2 +- .../{ => test/tests}/config/NodeTest.java | 2 +- .../tests}/localization/NounTest.java | 2 +- .../{ => test/tests}/utils/UtilsTest.java | 2 +- 9 files changed, 35 insertions(+), 86 deletions(-) delete mode 100644 .github/workflows/JUnit-tests.yml delete mode 100644 src/main/java/ch/njol/skript/test/tests/package-info.java rename src/{main/java/ch/njol/skript/test/tests => test/java/org/skriptlang/skript/test/tests/aliases}/AliasesTest.java (88%) rename src/{main/java/ch/njol/skript/test/tests => test/java/org/skriptlang/skript/test/tests/classes}/ClassesTest.java (98%) rename src/test/java/org/skriptlang/skript/{ => test/tests}/config/NodeTest.java (97%) rename src/test/java/org/skriptlang/skript/{ => test/tests}/localization/NounTest.java (97%) rename src/test/java/org/skriptlang/skript/{ => test/tests}/utils/UtilsTest.java (98%) diff --git a/.github/workflows/JUnit-tests.yml b/.github/workflows/JUnit-tests.yml deleted file mode 100644 index fa70aa2a0aa..00000000000 --- a/.github/workflows/JUnit-tests.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: JUnit Tests - -on: - push: - branches: - - main - - 'dev/**' - pull_request: - -jobs: - build: - if: "! contains(toJSON(github.event.commits.*.message), '[ci skip]')" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'adopt' - cache: gradle - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - name: Build Skript - run: ./gradlew nightlyRelease - - name: Run non-runtime JUnit tests - run: ./gradlew clean test - diff --git a/build.gradle b/build.gradle index 82f0713c3e5..23f93488417 100644 --- a/build.gradle +++ b/build.gradle @@ -11,6 +11,10 @@ plugins { id 'java' } +configurations { + testImplementation.extendsFrom testShadow +} + allprojects { repositories { mavenCentral() @@ -39,13 +43,8 @@ dependencies { implementation fileTree(dir: 'lib', include: '*.jar') - // JUnit 4 Runner for Runtime tests. - shadow fileTree(dir: 'lib', include: 'junit-4.13.2.jar') - shadow fileTree(dir: 'lib', include: 'hamcrest-2.2.jar') - - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.1' - testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.8.1' - testImplementation group: 'org.easymock', name: 'easymock', version: '4.2' + testShadow group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.1' + testShadow group: 'org.easymock', name: 'easymock', version: '4.2' } compileJava.options.encoding = 'UTF-8' @@ -61,25 +60,21 @@ task checkAliases { } } +task testJar(type: ShadowJar) { + dependsOn(compileTestJava) + archiveName 'Skript.jar' + from sourceSets.test.output, sourceSets.main.output, project.configurations.testShadow +} + task jar(overwrite: true, type: ShadowJar) { dependsOn checkAliases archiveName jarName ? 'Skript.jar' : jarName from sourceSets.main.output - dependencies { - exclude(dependency('org.hamcrest:.*')) - exclude(dependency('org.junit:.*')) - exclude(dependency('junit:.*')) - } } task build(overwrite: true, type: ShadowJar) { archiveName jarName ? 'Skript.jar' : jarName from sourceSets.main.output - dependencies { - exclude(dependency('org.hamcrest:.*')) - exclude(dependency('org.junit:.*')) - exclude(dependency('junit:.*')) - } } task relocateShadowJar(type: ConfigureShadowRelocation) { @@ -185,7 +180,7 @@ tasks.register('testNaming') { // Create a test task with given name, environments dir/file, dev mode and java version. void createTestTask(String name, String environments, boolean devMode, int javaVersion, boolean genDocs) { tasks.register(name, JavaExec) { - dependsOn jar, testNaming + dependsOn testJar, testNaming javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(javaVersion) } @@ -332,8 +327,7 @@ task nightlyRelease(type: ShadowJar) { } } - test { useJUnitPlatform() - dependsOn jar + dependsOn testJar } diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 4cbc60463eb..d2e106751a6 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -75,6 +75,7 @@ import org.junit.runner.JUnitCore; import org.junit.runner.Result; +import com.google.common.collect.Lists; import com.google.gson.Gson; import ch.njol.skript.aliases.Aliases; @@ -631,9 +632,15 @@ protected void afterErrors() { info("Test development mode enabled. Test scripts are at " + TestMode.TEST_DIR); } else { info("Running all JUnit tests..."); - long milliseconds = 0, tests = 0, fails = 0, ignored = 0; + long milliseconds = 0, tests = 0, fails = 0, ignored = 0, size = 0; try { - for (Class test : Utils.getClasses("ch.njol.skript.test", "tests")) { + List> classes = Lists.newArrayList(Utils.getClasses("ch.njol.skript.test", "tests")); + classes.addAll(Lists.newArrayList(Utils.getClasses("org.skriptlang.skript.test", "tests"))); + // Test that requires package access. + classes.add(Class.forName("ch.njol.skript.variables.FlatFileStorageTest")); + size = classes.size(); + for (Class test : classes) { + info("Running JUnit test '" + test.getName() + "'"); Result junit = JUnitCore.runClasses(test); TestTracker.testStarted("JUnit: '" + test.getName() + "'"); tests += junit.getRunCount(); @@ -650,10 +657,13 @@ protected void afterErrors() { } } catch (IOException e) { Skript.exception(e, "Failed to execute JUnit runtime tests."); + } catch (ClassNotFoundException e) { + // Should be the Skript test jar gradle task. + assert false; } if (ignored > 0) Skript.warning("There were " + ignored + " ignored test cases! This can mean they are not properly setup in order for that class!"); - info("Completed " + tests + " JUnit tests with " + fails + " failures in " + milliseconds + " milliseconds."); + info("Completed " + tests + " JUnit tests in " + size + " classes with " + fails + " failures in " + milliseconds + " milliseconds."); info("Running all tests from " + TestMode.TEST_DIR); // Treat parse errors as fatal testing failure diff --git a/src/main/java/ch/njol/skript/test/tests/package-info.java b/src/main/java/ch/njol/skript/test/tests/package-info.java deleted file mode 100644 index 22b410830c5..00000000000 --- a/src/main/java/ch/njol/skript/test/tests/package-info.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This file is part of Skript. - * - * Skript is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Skript 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Skript. If not, see . - * - * Copyright Peter Güttinger, SkriptLang team and contributors - */ -/** - * Runs JUnit tests runtime after server started. - */ -@NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) -package ch.njol.skript.test.tests; - -import org.eclipse.jdt.annotation.DefaultLocation; -import org.eclipse.jdt.annotation.NonNullByDefault; - diff --git a/src/main/java/ch/njol/skript/test/tests/AliasesTest.java b/src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java similarity index 88% rename from src/main/java/ch/njol/skript/test/tests/AliasesTest.java rename to src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java index c1de1292d4b..a23a3ac0dd2 100644 --- a/src/main/java/ch/njol/skript/test/tests/AliasesTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.test.tests; +package org.skriptlang.skript.test.tests.aliases; import org.bukkit.Color; import org.bukkit.Material; @@ -48,7 +48,9 @@ public void test() { itemstack.setItemMeta(leather); assert !itemType.equals(new ItemType(itemstack)); - assert Classes.serialize(itemType).equals(Classes.serialize(itemType)); + // Contains assert inside serialize method too, Njol mentioned this. + assert Classes.serialize(itemType) != null; + //assert Classes.serialize(itemType).equals(Classes.serialize(itemType)); assert !Classes.serialize(itemType).equals(Classes.serialize(new ItemType(itemstack))); } diff --git a/src/main/java/ch/njol/skript/test/tests/ClassesTest.java b/src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java similarity index 98% rename from src/main/java/ch/njol/skript/test/tests/ClassesTest.java rename to src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java index b77a9f8c970..e26ba244aec 100644 --- a/src/main/java/ch/njol/skript/test/tests/ClassesTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.test.tests; +package org.skriptlang.skript.test.tests.classes; import org.bukkit.GameMode; import org.bukkit.entity.HumanEntity; diff --git a/src/test/java/org/skriptlang/skript/config/NodeTest.java b/src/test/java/org/skriptlang/skript/test/tests/config/NodeTest.java similarity index 97% rename from src/test/java/org/skriptlang/skript/config/NodeTest.java rename to src/test/java/org/skriptlang/skript/test/tests/config/NodeTest.java index ef4235cc9d2..e24d28405f2 100644 --- a/src/test/java/org/skriptlang/skript/config/NodeTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/config/NodeTest.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package org.skriptlang.skript.config; +package org.skriptlang.skript.test.tests.config; import static org.junit.Assert.assertArrayEquals; diff --git a/src/test/java/org/skriptlang/skript/localization/NounTest.java b/src/test/java/org/skriptlang/skript/test/tests/localization/NounTest.java similarity index 97% rename from src/test/java/org/skriptlang/skript/localization/NounTest.java rename to src/test/java/org/skriptlang/skript/test/tests/localization/NounTest.java index d2cfe553b45..0c9cd31de11 100644 --- a/src/test/java/org/skriptlang/skript/localization/NounTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/localization/NounTest.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package org.skriptlang.skript.localization; +package org.skriptlang.skript.test.tests.localization; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/org/skriptlang/skript/utils/UtilsTest.java b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java similarity index 98% rename from src/test/java/org/skriptlang/skript/utils/UtilsTest.java rename to src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java index abe58831f55..3664973ee47 100644 --- a/src/test/java/org/skriptlang/skript/utils/UtilsTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package org.skriptlang.skript.utils; +package org.skriptlang.skript.test.tests.utils; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expectLastCall; From f240e78d347ce44f01bdc9d4c10cdf7a7a59ad7e Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 17 Aug 2022 01:38:05 -0600 Subject: [PATCH 04/33] Remove un-needed force dependency --- build.gradle | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 23f93488417..4e9e10c1d1b 100644 --- a/build.gradle +++ b/build.gradle @@ -23,11 +23,6 @@ allprojects { maven { url 'https://repo.papermc.io/repository/maven-public/' } maven { url 'https://ci.emc.gs/nexus/content/groups/aikar/' } } - configurations.all { - resolutionStrategy { - force('org.junit.jupiter:junit-jupiter-engine:5.8.1') - } - } } dependencies { @@ -63,7 +58,7 @@ task checkAliases { task testJar(type: ShadowJar) { dependsOn(compileTestJava) archiveName 'Skript.jar' - from sourceSets.test.output, sourceSets.main.output, project.configurations.testShadow + from sourceSets.test.output, sourceSets.main.output, project.configurations.testShadow } task jar(overwrite: true, type: ShadowJar) { From d09f31696088c26cabdb23580998188b57a85e1a Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 17 Aug 2022 02:11:33 -0600 Subject: [PATCH 05/33] Use JUnit 4 --- build.gradle | 3 ++- .../org/skriptlang/skript/test/tests/aliases/AliasesTest.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4e9e10c1d1b..2e9f320e81a 100644 --- a/build.gradle +++ b/build.gradle @@ -38,7 +38,8 @@ dependencies { implementation fileTree(dir: 'lib', include: '*.jar') - testShadow group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.1' + //testShadow group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.1' + testShadow group: 'junit', name: 'junit', version: '4.12' testShadow group: 'org.easymock', name: 'easymock', version: '4.2' } diff --git a/src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java b/src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java index a23a3ac0dd2..84f01df3c88 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java @@ -50,6 +50,7 @@ public void test() { // Contains assert inside serialize method too, Njol mentioned this. assert Classes.serialize(itemType) != null; + // This doesn't work anymore since Njol added this. //assert Classes.serialize(itemType).equals(Classes.serialize(itemType)); assert !Classes.serialize(itemType).equals(Classes.serialize(new ItemType(itemstack))); } From f0339069e31f68a0804879e43a3648b2467c3b0e Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 28 Dec 2022 05:01:52 -0700 Subject: [PATCH 06/33] Finish JUnit --- .github/workflows/junit.yml | 27 ++++ build.gradle | 35 +++-- src/main/java/ch/njol/skript/Skript.java | 120 ++++++++---------- .../skript/test/platform/Environment.java | 59 ++++++++- .../skript/test/platform/PlatformMain.java | 28 ++-- .../ch/njol/skript/test/runner/TestMode.java | 5 + .../test/tests/aliases/AliasesTest.java | 1 + src/test/skript/tests/junit/README.md | 8 ++ 8 files changed, 195 insertions(+), 88 deletions(-) create mode 100644 .github/workflows/junit.yml create mode 100644 src/test/skript/tests/junit/README.md diff --git a/.github/workflows/junit.yml b/.github/workflows/junit.yml new file mode 100644 index 00000000000..00fb8d999f3 --- /dev/null +++ b/.github/workflows/junit.yml @@ -0,0 +1,27 @@ +name: JUnit + +on: + push: + branches: + - master + - 'dev/**' + pull_request: + +jobs: + build: + if: "! contains(toJSON(github.event.commits.*.message), '[ci skip]')" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'adopt' + cache: gradle + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build Skript and run JUnit + run: ./gradlew clean junit diff --git a/build.gradle b/build.gradle index 1bbd916433f..6f02b47bdff 100644 --- a/build.gradle +++ b/build.gradle @@ -41,6 +41,7 @@ dependencies { //testShadow group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.1' testShadow group: 'junit', name: 'junit', version: '4.12' testShadow group: 'org.easymock', name: 'easymock', version: '4.2' + testShadow group: 'org.junit.vintage', name: 'junit-vintage-engine', version: '5.8.2' } compileJava.options.encoding = 'UTF-8' @@ -58,7 +59,7 @@ task checkAliases { task testJar(type: ShadowJar) { dependsOn(compileTestJava) - archiveName 'Skript.jar' + archiveName 'Skript-JUnit.jar' from sourceSets.test.output, sourceSets.main.output, project.configurations.testShadow } @@ -174,9 +175,13 @@ tasks.register('testNaming') { } // Create a test task with given name, environments dir/file, dev mode and java version. -void createTestTask(String name, String environments, boolean devMode, int javaVersion, boolean genDocs) { +void createTestTask(String name, String environment, boolean devMode, int javaVersion, boolean genDocs, boolean junit) { tasks.register(name, JavaExec) { - dependsOn nightlyRelease, testNaming + if (junit) { + dependsOn testJar + } else { + dependsOn nightlyRelease, testNaming + } javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(javaVersion) } @@ -185,18 +190,19 @@ void createTestTask(String name, String environments, boolean devMode, int javaV } group = 'execution' classpath = files([ - 'build' + File.separator + 'libs' + File.separator + 'Skript-nightly.jar', + 'build' + File.separator + 'libs' + File.separator + (junit ? 'Skript-JUnit.jar' : 'Skript-nightly.jar'), project.configurations.runtimeClasspath.find { it.name.startsWith('gson') }, sourceSets.main.runtimeClasspath ]) main = 'ch.njol.skript.test.platform.PlatformMain' args = [ 'test_runners', - 'src/test/skript/tests', + junit ? 'src/test/skript/tests/junit' : 'src/test/skript/tests', 'src/test/resources/runner_data', - environments, + environment, devMode, - genDocs + genDocs, + junit ] } } @@ -209,17 +215,22 @@ tasks.withType(JavaCompile).configureEach { options.compilerArgs += ["-source", "" + oldestJava, "-target", "" + oldestJava] } +createTestTask('JUnitQuick','src/test/skript/environments/' + latestEnv, false, latestJava, false, true) +createTestTask('JUnitJava17', 'src/test/skript/environments/java17', false, latestJava, false, true) +createTestTask('JUnitJava8','src/test/skript/environments/java8', false, oldestJava, false, true) +tasks.register('JUnit') {dependsOn JUnitJava8, JUnitJava17} + // Register different Skript testing tasks -createTestTask('quickTest', 'src/test/skript/environments/' + latestEnv, false, latestJava, false) -createTestTask('skriptTestJava17', 'src/test/skript/environments/java17', false, latestJava, false) -createTestTask('skriptTestJava8', 'src/test/skript/environments/java8', false, oldestJava, false) +createTestTask('quickTest', 'src/test/skript/environments/' + latestEnv, false, latestJava, false, false) +createTestTask('skriptTestJava17', 'src/test/skript/environments/java17', false, latestJava, false, false) +createTestTask('skriptTestJava8', 'src/test/skript/environments/java8', false, oldestJava, false, false) createTestTask('skriptTestDev', 'src/test/skript/environments/' + (project.property('testEnv') == null ? latestEnv : project.property('testEnv') + '.json'), true, Integer.parseInt(project.property('testEnvJavaVersion') == null - ? latestJava : project.property('testEnvJavaVersion')), false) + ? latestJava : project.property('testEnvJavaVersion')), false, false) tasks.register('skriptTest') {dependsOn skriptTestJava8, skriptTestJava17} createTestTask('genDocs', 'src/test/skript/environments/' + (project.property('testEnv') == null ? latestEnv : project.property('testEnv') + '.json'), false, Integer.parseInt(project.property('testEnvJavaVersion') == null - ? latestJava : project.property('testEnvJavaVersion')), true) + ? latestJava : project.property('testEnvJavaVersion')), true, false) // Build flavor configurations task githubResources(type: ProcessResources) { diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 353c10dd424..98ac36954b0 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -696,59 +696,16 @@ protected void afterErrors() { // Skript initialization done debug("Early init done"); - Bukkit.getScheduler().runTaskLater(Skript.this, () -> { - if (TestMode.ENABLED) { // Ignore late init (scripts, etc.) in test mode + if (TestMode.ENABLED) { + Bukkit.getScheduler().runTaskLater(Skript.this, () -> info("Skript testing environment enabled, starting soon..."), 1); + // Ignore late init (scripts, etc.) in test mode + Bukkit.getScheduler().runTaskLater(Skript.this, () -> { if (TestMode.GEN_DOCS) { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "skript gen-docs"); - String results = new Gson().toJson(TestTracker.collectResults()); - try { - Files.write(TestMode.RESULTS_FILE, results.getBytes(StandardCharsets.UTF_8)); - } catch (IOException e) { - Skript.exception(e, "Failed to write test results."); - } - // Delay server shutdown to stop the server from crashing because the current tick takes a long time due to all the tests - Bukkit.getScheduler().runTaskLater(Skript.this, () -> { - Bukkit.getServer().shutdown(); - }, 5); - return; - } - if (TestMode.DEV_MODE) { // Run tests NOW! + } else if (TestMode.DEV_MODE) { // Developer controlled environment. info("Test development mode enabled. Test scripts are at " + TestMode.TEST_DIR); } else { - info("Running all JUnit tests..."); - long milliseconds = 0, tests = 0, fails = 0, ignored = 0, size = 0; - try { - List> classes = Lists.newArrayList(Utils.getClasses("ch.njol.skript.test", "tests")); - classes.addAll(Lists.newArrayList(Utils.getClasses("org.skriptlang.skript.test", "tests"))); - // Test that requires package access. - classes.add(Class.forName("ch.njol.skript.variables.FlatFileStorageTest")); - size = classes.size(); - for (Class test : classes) { - info("Running JUnit test '" + test.getName() + "'"); - Result junit = JUnitCore.runClasses(test); - TestTracker.testStarted("JUnit: '" + test.getName() + "'"); - tests += junit.getRunCount(); - milliseconds += junit.getRunTime(); - ignored += junit.getIgnoreCount(); - if (junit.getFailureCount() > 0) { - fails += junit.getFailureCount(); - junit.getFailures().forEach(failure -> { - String message = failure.getMessage() == null ? "" : " " + failure.getMessage(); - TestTracker.testFailed("JUnit: '" + test.getName() + "'" + message); - Skript.exception(failure.getException(), "JUnit test '" + failure.getTestHeader() + " failed."); - }); - } - } - } catch (IOException e) { - Skript.exception(e, "Failed to execute JUnit runtime tests."); - } catch (ClassNotFoundException e) { - // Should be the Skript test jar gradle task. - assert false; - } - if (ignored > 0) - Skript.warning("There were " + ignored + " ignored test cases! This can mean they are not properly setup in order for that class!"); - info("Completed " + tests + " JUnit tests in " + size + " classes with " + fails + " failures in " + milliseconds + " milliseconds."); - info("Running all tests from " + TestMode.TEST_DIR); + info("Loading all tests from " + TestMode.TEST_DIR); // Treat parse errors as fatal testing failure CountingLogHandler errorCounter = new CountingLogHandler(Level.SEVERE); @@ -762,8 +719,6 @@ protected void afterErrors() { } Bukkit.getPluginManager().callEvent(new SkriptTestEvent()); - - info("Collecting results to " + TestMode.RESULTS_FILE); if (errorCounter.getCount() > 0) { TestTracker.testStarted("parse scripts"); TestTracker.testFailed(errorCounter.getCount() + " error(s) found"); @@ -772,23 +727,56 @@ protected void afterErrors() { TestTracker.testStarted("run scripts"); TestTracker.testFailed("exception was thrown during execution"); } - String results = new Gson().toJson(TestTracker.collectResults()); - try { - Files.write(TestMode.RESULTS_FILE, results.getBytes(StandardCharsets.UTF_8)); - } catch (IOException e) { - Skript.exception(e, "Failed to write test results."); + if (TestMode.JUNIT) { + info("Running all JUnit tests..."); + long milliseconds = 0, tests = 0, fails = 0, ignored = 0, size = 0; + try { + List> classes = Lists.newArrayList(Utils.getClasses("org.skriptlang.skript.test", "tests")); + // Test that requires package access. + classes.add(Class.forName("ch.njol.skript.variables.FlatFileStorageTest")); + size = classes.size(); + for (Class test : classes) { + info("Running JUnit test '" + test.getName() + "'"); + Result junit = JUnitCore.runClasses(test); + TestTracker.testStarted("JUnit: '" + test.getName() + "'"); + tests += junit.getRunCount(); + milliseconds += junit.getRunTime(); + ignored += junit.getIgnoreCount(); + if (junit.getFailureCount() > 0) { + fails += junit.getFailureCount(); + junit.getFailures().forEach(failure -> { + String message = failure.getMessage() == null ? "" : " " + failure.getMessage(); + TestTracker.testFailed("'" + test.getName() + "': " + message); + Skript.exception(failure.getException(), "JUnit test '" + failure.getTestHeader() + " failed."); + }); + } + } + } catch (IOException e) { + Skript.exception(e, "Failed to execute JUnit runtime tests."); + } catch (ClassNotFoundException e) { + // Should be the Skript test jar gradle task. + assert false; + } + if (ignored > 0) + Skript.warning("There were " + ignored + " ignored test cases! This can mean they are not properly setup in order in that class!"); + + info("Completed " + tests + " JUnit tests in " + size + " classes with " + fails + " failures in " + milliseconds + " milliseconds."); } - info("Testing done, shutting down the server."); - - // Delay server shutdown to stop the server from crashing because the current tick takes a long time due to all the tests - Bukkit.getScheduler().runTaskLater(Skript.this, () -> { - Bukkit.getServer().shutdown(); - }, 5); - } - return; - } - }, 100); + info("Collecting results to " + TestMode.RESULTS_FILE); + String results = new Gson().toJson(TestTracker.collectResults()); + try { + Files.write(TestMode.RESULTS_FILE, results.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + Skript.exception(e, "Failed to write test results."); + } + info("Testing done, shutting down the server..."); + // Delay server shutdown to stop the server from crashing because the current tick takes a long time due to all the tests + Bukkit.getScheduler().runTaskLater(Skript.this, () -> { + Bukkit.getServer().shutdown(); + }, 5); + }, 100); + } final long vld = System.currentTimeMillis() - vls; if (logNormal()) diff --git a/src/main/java/ch/njol/skript/test/platform/Environment.java b/src/main/java/ch/njol/skript/test/platform/Environment.java index cea3e99e533..cd7fb24d3f3 100644 --- a/src/main/java/ch/njol/skript/test/platform/Environment.java +++ b/src/main/java/ch/njol/skript/test/platform/Environment.java @@ -45,6 +45,11 @@ */ public class Environment { + /** + * Time before the process is killed if there was a stack stace etc. + */ + private static final int TIMEOUT = 5 * 60_000; // 5 minutes. + private static final Gson gson = new Gson(); /** @@ -265,7 +270,7 @@ public void run() { System.exit(1); } } - }, 8 * 60_000); // 8 minutes. + }, TIMEOUT); } int code = process.waitFor(); @@ -280,4 +285,56 @@ public void run() { return results; } + @Nullable + public TestResults runJUnit(Path runnerRoot, Path testsRoot, String... jvmArgs) throws IOException, InterruptedException { + Path env = runnerRoot.resolve(name); + Path resultsPath = env.resolve("test_results.json"); + Files.deleteIfExists(resultsPath); + List args = new ArrayList<>(); + args.add(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"); + args.add("-ea"); + args.add("-Dskript.testing.enabled=true"); + args.add("-Dskript.testing.dir=" + testsRoot); + args.add("-Dskript.testing.junit=true"); + args.add("-Dskript.testing.results=test_results.json"); + args.add("-Ddisable.watchdog=true"); + args.addAll(Arrays.asList(jvmArgs)); + args.addAll(Arrays.asList(commandLine)); + + Process process = new ProcessBuilder(args) + .directory(env.toFile()) + .redirectOutput(Redirect.INHERIT) + .redirectError(Redirect.INHERIT) + .redirectInput(Redirect.INHERIT) + .start(); + + // When we exit, try to make them exit too + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + if (process.isAlive()) { + process.destroy(); + } + })); + + new Timer("runner watchdog", true).schedule(new TimerTask() { + + @Override + public void run() { + if (process.isAlive()) { + System.err.println("Test environment is taking too long, failing..."); + System.exit(1); + } + } + }, TIMEOUT); + int code = process.waitFor(); + if (code != 0) + throw new IOException("environment returned with code " + code); + + // Read test results + if (!Files.exists(resultsPath)) + return null; + TestResults results = new Gson().fromJson(new String(Files.readAllBytes(resultsPath)), TestResults.class); + assert results != null; + return results; + } + } diff --git a/src/main/java/ch/njol/skript/test/platform/PlatformMain.java b/src/main/java/ch/njol/skript/test/platform/PlatformMain.java index 22975df5b6a..d21c6551a1b 100644 --- a/src/main/java/ch/njol/skript/test/platform/PlatformMain.java +++ b/src/main/java/ch/njol/skript/test/platform/PlatformMain.java @@ -62,6 +62,7 @@ public static void main(String... args) throws IOException, InterruptedException assert envsRoot != null; boolean devMode = "true".equals(args[4]); boolean genDocs = "true".equals(args[5]); + boolean junit = "true".equals(args[6]); // Load environments List envs; @@ -80,17 +81,22 @@ public static void main(String... args) throws IOException, InterruptedException } System.out.println("Test environments: " + String.join(", ", envs.stream().map(Environment::getName).collect(Collectors.toList()))); - - Set allTests = new HashSet<>(); + Map>> failures = new HashMap<>(); - + Set allTests = new HashSet<>(); + boolean docsFailed = false; // Run tests and collect the results envs.sort(Comparator.comparing(Environment::getName)); for (Environment env : envs) { System.out.println("Starting testing on " + env.getName()); env.initialize(dataRoot, runnerRoot, false); - TestResults results = env.runTests(runnerRoot, testsRoot, devMode, genDocs, "-Xmx5G"); + TestResults results = null; + if (junit) { + results = env.runJUnit(runnerRoot, testsRoot, "-Xmx5G"); + } else { + results = env.runTests(runnerRoot, testsRoot, devMode, genDocs, "-Xmx5G"); + } if (results == null) { if (devMode) { // Nothing to report, it's the dev mode environment. @@ -134,19 +140,23 @@ public static void main(String... args) throws IOException, InterruptedException // All succeeded tests in a single line System.out.printf("%s Results %s%n", StringUtils.repeat("-", 25), StringUtils.repeat("-", 25)); - System.out.println("Tested environments: " + String.join(", ", + System.out.println("\nTested environments: " + String.join(", ", envs.stream().map(Environment::getName).collect(Collectors.toList()))); - System.out.println("\nSucceeded: " + String.join(", ", succeeded)); + System.out.println("\nSucceeded:\n " + String.join((junit ? "\n " : ", "), succeeded)); + if (!failNames.isEmpty()) { // More space for failed tests, they're important - System.err.println("Failed:"); + Thread.sleep(1); // speed at which system prints fails without this, and can look like successful tests failed. + System.err.println("\nFailed:"); for (String failed : failNames) { List> errors = failures.get(failed); - System.err.println(" " + failed + " (on " + errors.size() + " environments)"); + System.err.println(" " + failed + " (on " + errors.size() + " environment" + (errors.size() == 1 ? "" : "s") + ")"); for (NonNullPair error : errors) { System.err.println(" " + error.getSecond() + " (on " + error.getFirst().getName() + ")"); } } - System.exit(failNames.size()); // Error code to indicate how many tests failed + System.out.printf("%n%s", StringUtils.repeat("-", 60)); + System.exit(failNames.size()); // Error code to indicate how many tests failed. + return; } System.out.printf("%n%s", StringUtils.repeat("-", 60)); } diff --git a/src/main/java/ch/njol/skript/test/runner/TestMode.java b/src/main/java/ch/njol/skript/test/runner/TestMode.java index a68f0217fa5..9374269f710 100644 --- a/src/main/java/ch/njol/skript/test/runner/TestMode.java +++ b/src/main/java/ch/njol/skript/test/runner/TestMode.java @@ -63,6 +63,11 @@ public class TestMode { */ public static final Path RESULTS_FILE = ENABLED ? Paths.get(System.getProperty(ROOT + "results")) : null; + /** + * If this test is for JUnits on the server. + */ + public static final boolean JUNIT = "true".equals(System.getProperty(ROOT + "junit")); + /** * In development mode, file that was last run. */ diff --git a/src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java b/src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java index 84f01df3c88..c2ad1a61918 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/aliases/AliasesTest.java @@ -24,6 +24,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.LeatherArmorMeta; import org.junit.Test; + import ch.njol.skript.aliases.ItemType; import ch.njol.skript.registrations.Classes; diff --git a/src/test/skript/tests/junit/README.md b/src/test/skript/tests/junit/README.md new file mode 100644 index 00000000000..029b1a5c184 --- /dev/null +++ b/src/test/skript/tests/junit/README.md @@ -0,0 +1,8 @@ +# JUnit testing system +This folder is for scripts that will load and be present for the Skript JUnit tests. +This allows a test to listen for events or persist during JUnit tests. + +An example would be checking the damage of an entity. You would write a test script +and have the on damage event inside that script with assertion checking. +Then in the JUnit Java class, you would perform some action that would damage the entity. +That test script then catches that event and any errors will be included in the final results. From 35297dbda49ab2e46827dc4fc28a02fd2e5a446d Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 28 Dec 2022 08:08:10 -0700 Subject: [PATCH 07/33] Add JUnit to Skript script support --- .../{junit.yml => junit-17-builds.yml} | 4 +- .github/workflows/junit-8-builds.yml | 27 ++++++ build.gradle | 8 +- src/main/java/ch/njol/skript/Skript.java | 91 +++++-------------- .../skript/test/platform/PlatformMain.java | 1 + .../ch/njol/skript/test/runner/EffAssert.java | 56 ++++++------ .../skript/test/runner/ExprJUnitTest.java | 71 +++++++++++++++ .../skript/test/runner/SkriptJUnitTest.java | 81 +++++++++++++++++ .../njol/skript/test/runner/TestTracker.java | 24 +++-- .../tests/regression/SimpleJUnitTest.java | 40 ++++++++ .../skript/tests/junit/SimpleJUnitTest.sk | 7 ++ 11 files changed, 298 insertions(+), 112 deletions(-) rename .github/workflows/{junit.yml => junit-17-builds.yml} (90%) create mode 100644 .github/workflows/junit-8-builds.yml create mode 100644 src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java create mode 100644 src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java create mode 100644 src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java create mode 100644 src/test/skript/tests/junit/SimpleJUnitTest.sk diff --git a/.github/workflows/junit.yml b/.github/workflows/junit-17-builds.yml similarity index 90% rename from .github/workflows/junit.yml rename to .github/workflows/junit-17-builds.yml index 00fb8d999f3..eca1ebb9706 100644 --- a/.github/workflows/junit.yml +++ b/.github/workflows/junit-17-builds.yml @@ -1,4 +1,4 @@ -name: JUnit +name: JUnit (MC 1.17+) on: push: @@ -24,4 +24,4 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build Skript and run JUnit - run: ./gradlew clean junit + run: ./gradlew clean JUnitJava17 diff --git a/.github/workflows/junit-8-builds.yml b/.github/workflows/junit-8-builds.yml new file mode 100644 index 00000000000..93971c79624 --- /dev/null +++ b/.github/workflows/junit-8-builds.yml @@ -0,0 +1,27 @@ +name: JUnit (MC 1.13-1.16) + +on: + push: + branches: + - master + - 'dev/**' + pull_request: + +jobs: + build: + if: "! contains(toJSON(github.event.commits.*.message), '[ci skip]')" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'adopt' + cache: gradle + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build Skript and run JUnit + run: ./gradlew clean JUnitJava8 diff --git a/build.gradle b/build.gradle index 6f02b47bdff..d0b3c77dede 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,7 @@ allprojects { dependencies { shadow group: 'io.papermc', name: 'paperlib', version: '1.0.7' shadow group: 'org.bstats', name: 'bstats-bukkit', version: '3.0.0' + implementation group: 'io.papermc.paper', name: 'paper-api', version: '1.19.3-R0.1-SNAPSHOT' implementation group: 'org.eclipse.jdt', name: 'org.eclipse.jdt.annotation', version: '2.2.700' implementation group: 'com.google.code.findbugs', name: 'findbugs', version: '3.0.1' @@ -38,10 +39,8 @@ dependencies { implementation fileTree(dir: 'lib', include: '*.jar') - //testShadow group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.1' testShadow group: 'junit', name: 'junit', version: '4.12' testShadow group: 'org.easymock', name: 'easymock', version: '4.2' - testShadow group: 'org.junit.vintage', name: 'junit-vintage-engine', version: '5.8.2' } compileJava.options.encoding = 'UTF-8' @@ -333,8 +332,3 @@ task nightlyRelease(type: ShadowJar) { ) } } - -test { - useJUnitPlatform() - dependsOn testJar -} diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 98ac36954b0..6eda0f49522 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -42,12 +42,14 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Filter; import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; @@ -74,6 +76,10 @@ import org.eclipse.jdt.annotation.Nullable; import org.junit.runner.JUnitCore; import org.junit.runner.Result; +import org.skriptlang.skript.lang.entry.EntryValidator; +import org.skriptlang.skript.lang.script.Script; +import org.skriptlang.skript.lang.structure.Structure; +import org.skriptlang.skript.lang.structure.StructureInfo; import com.google.common.collect.Lists; import com.google.gson.Gson; @@ -122,6 +128,7 @@ import ch.njol.skript.registrations.Comparators; import ch.njol.skript.registrations.Converters; import ch.njol.skript.registrations.EventValues; +import ch.njol.skript.test.runner.SkriptJUnitTest; import ch.njol.skript.test.runner.SkriptTestEvent; import ch.njol.skript.test.runner.TestMode; import ch.njol.skript.test.runner.TestTracker; @@ -147,66 +154,6 @@ import ch.njol.util.StringUtils; import ch.njol.util.coll.iterator.CheckedIterator; import ch.njol.util.coll.iterator.EnumerationIterable; -import com.google.gson.Gson; -import org.bstats.bukkit.Metrics; -import org.bstats.charts.SimplePie; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.Server; -import org.bukkit.command.CommandSender; -import org.bukkit.command.PluginCommand; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.server.PluginDisableEvent; -import org.bukkit.event.server.ServerCommandEvent; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.plugin.java.JavaPlugin; -import org.eclipse.jdt.annotation.Nullable; -import org.skriptlang.skript.lang.entry.EntryValidator; -import org.skriptlang.skript.lang.script.Script; -import org.skriptlang.skript.lang.structure.Structure; -import org.skriptlang.skript.lang.structure.StructureInfo; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.lang.Thread.UncaughtExceptionHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.logging.Filter; -import java.util.logging.Level; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; // TODO meaningful error if someone uses an %expression with percent signs% outside of text or a variable @@ -414,7 +361,6 @@ public static void disableHookRegistration(Class>... hooks) { * The folder containing all Scripts. * Never reference this field directly. Use {@link #getScriptsFolder()}. */ - @SuppressWarnings("NotNullFieldNotInitialized") private File scriptsFolder; /** @@ -700,9 +646,11 @@ protected void afterErrors() { Bukkit.getScheduler().runTaskLater(Skript.this, () -> info("Skript testing environment enabled, starting soon..."), 1); // Ignore late init (scripts, etc.) in test mode Bukkit.getScheduler().runTaskLater(Skript.this, () -> { + long shutdown = 0; if (TestMode.GEN_DOCS) { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "skript gen-docs"); } else if (TestMode.DEV_MODE) { // Developer controlled environment. + SkriptLogger.setVerbosity(Verbosity.DEBUG); info("Test development mode enabled. Test scripts are at " + TestMode.TEST_DIR); } else { info("Loading all tests from " + TestMode.TEST_DIR); @@ -728,6 +676,7 @@ protected void afterErrors() { TestTracker.testFailed("exception was thrown during execution"); } if (TestMode.JUNIT) { + SkriptLogger.setVerbosity(Verbosity.DEBUG); info("Running all JUnit tests..."); long milliseconds = 0, tests = 0, fails = 0, ignored = 0, size = 0; try { @@ -735,10 +684,14 @@ protected void afterErrors() { // Test that requires package access. classes.add(Class.forName("ch.njol.skript.variables.FlatFileStorageTest")); size = classes.size(); - for (Class test : classes) { - info("Running JUnit test '" + test.getName() + "'"); - Result junit = JUnitCore.runClasses(test); - TestTracker.testStarted("JUnit: '" + test.getName() + "'"); + for (Class clazz : classes) { + String test = clazz.getName(); + SkriptJUnitTest.lastJUnitTest = test; + info("Running JUnit test '" + test + "'"); + Result junit = JUnitCore.runClasses(clazz); + TestTracker.testStarted("JUnit: '" + test + "'"); + shutdown += SkriptJUnitTest.getDelay(); + SkriptJUnitTest.setDelay(0); tests += junit.getRunCount(); milliseconds += junit.getRunTime(); ignored += junit.getIgnoreCount(); @@ -746,10 +699,11 @@ protected void afterErrors() { fails += junit.getFailureCount(); junit.getFailures().forEach(failure -> { String message = failure.getMessage() == null ? "" : " " + failure.getMessage(); - TestTracker.testFailed("'" + test.getName() + "': " + message); + TestTracker.testFailed("'" + test + "': " + message); Skript.exception(failure.getException(), "JUnit test '" + failure.getTestHeader() + " failed."); }); } + SkriptJUnitTest.lastJUnitTest = null; } } catch (IOException e) { Skript.exception(e, "Failed to execute JUnit runtime tests."); @@ -770,11 +724,12 @@ protected void afterErrors() { } catch (IOException e) { Skript.exception(e, "Failed to write test results."); } - info("Testing done, shutting down the server..."); + long seconds = TimeUnit.MILLISECONDS.toSeconds(shutdown); + info("Testing done, shutting down the server in " + seconds + " second " + (seconds == 1 ? "" : "s") + "..."); // Delay server shutdown to stop the server from crashing because the current tick takes a long time due to all the tests Bukkit.getScheduler().runTaskLater(Skript.this, () -> { Bukkit.getServer().shutdown(); - }, 5); + }, seconds * 20); }, 100); } diff --git a/src/main/java/ch/njol/skript/test/platform/PlatformMain.java b/src/main/java/ch/njol/skript/test/platform/PlatformMain.java index d21c6551a1b..422c83e1548 100644 --- a/src/main/java/ch/njol/skript/test/platform/PlatformMain.java +++ b/src/main/java/ch/njol/skript/test/platform/PlatformMain.java @@ -154,6 +154,7 @@ public static void main(String... args) throws IOException, InterruptedException System.err.println(" " + error.getSecond() + " (on " + error.getFirst().getName() + ")"); } } + Thread.sleep(1); System.out.printf("%n%s", StringUtils.repeat("-", 60)); System.exit(failNames.size()); // Error code to indicate how many tests failed. return; diff --git a/src/main/java/ch/njol/skript/test/runner/EffAssert.java b/src/main/java/ch/njol/skript/test/runner/EffAssert.java index 16af12d11c3..e339bf3e9a3 100644 --- a/src/main/java/ch/njol/skript/test/runner/EffAssert.java +++ b/src/main/java/ch/njol/skript/test/runner/EffAssert.java @@ -23,13 +23,12 @@ import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.NoDoc; import ch.njol.skript.lang.Condition; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.SkriptParser; +import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.TriggerItem; import ch.njol.skript.log.ParseLogHandler; import ch.njol.skript.log.SkriptLogger; @@ -37,37 +36,35 @@ @Name("Assert") @Description("Assert that condition is true. Test fails when it is not.") -@Examples("") -@Since("2.5") +@NoDoc public class EffAssert extends Effect { static { if (TestMode.ENABLED) - Skript.registerEffect(EffAssert.class, "assert <.+> [(1¦to fail)] with %string%"); + Skript.registerEffect(EffAssert.class, "assert <.+> [(1¦to fail)] with %string% [on [test] %string%]"); } - @SuppressWarnings("null") - private Condition condition; - - @SuppressWarnings("null") + @Nullable + private Expression junit; + private Expression errorMsg; - + private Condition condition; private boolean shouldFail; - @SuppressWarnings({"null", "unchecked"}) @Override - public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { String conditionString = parseResult.regexes.get(0).group(); errorMsg = (Expression) exprs[0]; + junit = (Expression) exprs[1]; shouldFail = parseResult.mark != 0; ParseLogHandler logHandler = SkriptLogger.startParseLogHandler(); try { condition = Condition.parse(conditionString, "Can't understand this condition: " + conditionString); - if (shouldFail) { + if (shouldFail) return true; - } if (condition == null) { logHandler.printError(); @@ -82,25 +79,32 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - protected void execute(Event e) {} - + protected void execute(Event event) {} + @Nullable @Override - public TriggerItem walk(Event e) { - if (shouldFail && condition == null) { + public TriggerItem walk(Event event) { + if (shouldFail && condition == null) return getNext(); - } - - if (condition.check(e) == shouldFail) { - String msg = errorMsg.getSingle(e); - TestTracker.testFailed(msg != null ? msg : "assertation failed"); + + if (condition.check(event) == shouldFail) { + String message = errorMsg.getSingle(event); + assert message != null; // Should not happen, developer needs to fix test. + if (junit != null) { + String test = junit.getSingle(event); + assert test != null; + TestTracker.junitTestFailed(test, message); + } else { + TestTracker.testFailed(message); + } return null; } return getNext(); } @Override - public String toString(@Nullable Event e, boolean debug) { - return "assert " + condition.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return "assert " + condition.toString(event, debug); } + } diff --git a/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java b/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java new file mode 100644 index 00000000000..6749e1428b1 --- /dev/null +++ b/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java @@ -0,0 +1,71 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +package ch.njol.skript.test.runner; + +import org.bukkit.event.Event; +import org.eclipse.jdt.annotation.Nullable; + +import ch.njol.skript.Skript; +import ch.njol.skript.doc.Description; +import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.NoDoc; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.ExpressionType; +import ch.njol.skript.lang.SkriptParser; +import ch.njol.skript.lang.util.SimpleExpression; +import ch.njol.util.Kleenean; +import ch.njol.util.coll.CollectionUtils; + +@Name("JUnit Test Name") +@Description("Returns the currently running JUnit test name otherwise nothing.") +@NoDoc +public class ExprJUnitTest extends SimpleExpression { + + static { + if (TestMode.ENABLED) + Skript.registerExpression(ExprJUnitTest.class, String.class, ExpressionType.SIMPLE, "[the] [current[ly [running]]] junit test [name]"); + } + + @Override + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + return true; + } + + @Override + @Nullable + protected String[] get(Event event) { + return CollectionUtils.array(SkriptJUnitTest.lastJUnitTest); + } + + @Override + public boolean isSingle() { + return true; + } + + @Override + public Class getReturnType() { + return String.class; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "current junit test"; + } + +} diff --git a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java new file mode 100644 index 00000000000..a46a07fc045 --- /dev/null +++ b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java @@ -0,0 +1,81 @@ +package ch.njol.skript.test.runner; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Pig; +import org.junit.After; + +/** + * Class that helps the JUnit test communicate with Skript. + */ +public abstract class SkriptJUnitTest { + + /** + * Used for getting the last ran JUnit test name. + */ + public static String lastJUnitTest; + + private static long d; + + /** + * The delay this JUnit test is requiring to run. + * + * @return the delay in milliseconds this junit test is requiring to run for. + */ + public static long getDelay() { + return d; + } + + /** + * @param delay Add a delay in milliseconds for this test to run. + */ + public static void setDelay(long delay) { + d = delay; + } + + @After + public final void cleanup() { + getTestWorld().getEntities().forEach(entity -> entity.remove()); + setBlock(Material.AIR); + } + + /** + * @return the test world. + */ + protected World getTestWorld() { + return Bukkit.getWorlds().get(0); + } + + /** + * @return the testing location at the spawn of the testing world. + */ + protected Location getTestLocation() { + return getTestWorld().getSpawnLocation().add(0, 1, 0); + } + + /** + * Spawns a testing pig at the spawn location of the testing world. + * + * @return Pig that has been spawned. + */ + protected Pig spawnTestPig() { + return (Pig) getTestWorld().spawnEntity(getTestLocation(), EntityType.PIG); + } + + /** + * Set the type of the block at the testing location. + * + * @param material The material to set the block to. + * @return the Block after it has been updated. + */ + protected Block setBlock(Material material) { + Block block = getTestWorld().getBlockAt(getTestLocation()); + block.setType(material); + return block; + } + +} diff --git a/src/main/java/ch/njol/skript/test/runner/TestTracker.java b/src/main/java/ch/njol/skript/test/runner/TestTracker.java index 8d1bf2facd3..01b1a1fc024 100644 --- a/src/main/java/ch/njol/skript/test/runner/TestTracker.java +++ b/src/main/java/ch/njol/skript/test/runner/TestTracker.java @@ -25,50 +25,56 @@ import org.eclipse.jdt.annotation.Nullable; +import ch.njol.skript.Skript; import ch.njol.skript.test.utils.TestResults; /** * Tracks failed and succeeded tests. */ public class TestTracker { - + /** * Started tests. */ private static final Set startedTests = new HashSet<>(); - + /** * Failed tests to failure assert messages. */ private static final Map failedTests = new HashMap<>(); - + @Nullable private static String currentTest; - + public static void testStarted(String name) { startedTests.add(name); currentTest = name; } - + public static void testFailed(String msg) { failedTests.put(currentTest, msg); } - + + public static void junitTestFailed(String junit, String msg) { + Skript.debug("Added JUnit fail " + junit + " with message " + msg); + failedTests.put(junit, msg); + } + public static Map getFailedTests() { return new HashMap<>(failedTests); } - + public static Set getSucceededTests() { Set tests = new HashSet<>(startedTests); tests.removeAll(failedTests.keySet()); return tests; } - + public static TestResults collectResults() { TestResults results = new TestResults(getSucceededTests(), getFailedTests(), TestMode.docsFailed); startedTests.clear(); failedTests.clear(); return results; } - + } diff --git a/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java b/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java new file mode 100644 index 00000000000..bc64435d50c --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java @@ -0,0 +1,40 @@ +package org.skriptlang.skript.test.tests.regression; + +import java.util.concurrent.TimeUnit; + +import org.bukkit.entity.Pig; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import ch.njol.skript.test.runner.SkriptJUnitTest; +import net.kyori.adventure.text.Component; + +public class SimpleJUnitTest extends SkriptJUnitTest { + + private static Pig piggy; + + static { + setDelay(TimeUnit.SECONDS.toMillis(1)); + } + + @Before + public void setup() { + piggy = spawnTestPig(); + piggy.customName(Component.text("Simple JUnit Test")); + } + + @Test + public void test() { + piggy.damage(100); + } + + @After + public void clearPiggy() { + // Remember to cleanup your test. This is an example method. + // Skript does clean up your JUnit test if it extends SkriptJUnitTest for; + // - Entities + // - Block (using getTestBlock) + } + +} diff --git a/src/test/skript/tests/junit/SimpleJUnitTest.sk b/src/test/skript/tests/junit/SimpleJUnitTest.sk new file mode 100644 index 00000000000..92584678c1b --- /dev/null +++ b/src/test/skript/tests/junit/SimpleJUnitTest.sk @@ -0,0 +1,7 @@ + +on damage of pig: + junit test is "org.skriptlang.skript.test.tests.regression.SimpleJUnitTest" + assert custom name of victim is "Simple JUnit Test" with "piggy was not the same" on junit test + + # Remember the damage was 100 but Skript represents it by hearts so it's 50. + assert damage is 50 with "damage was not 50" on the currently running junit test From fe5af2b015d92e3d1d247d016dd626b025a3f521 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 28 Dec 2022 08:11:30 -0700 Subject: [PATCH 08/33] licenseFormat --- .../skript/test/runner/SkriptJUnitTest.java | 18 ++++++++++++++++++ .../test/tests/regression/SimpleJUnitTest.java | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java index a46a07fc045..22339564314 100644 --- a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java +++ b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java @@ -1,3 +1,21 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ package ch.njol.skript.test.runner; import org.bukkit.Bukkit; diff --git a/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java b/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java index bc64435d50c..7d866eef167 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java @@ -1,3 +1,21 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ package org.skriptlang.skript.test.tests.regression; import java.util.concurrent.TimeUnit; From 109c1133a0b21de702028f7dcf2d33c702c0ade6 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 28 Dec 2022 08:16:50 -0700 Subject: [PATCH 09/33] Nullify expression in EffAssert --- src/main/java/ch/njol/skript/test/runner/EffAssert.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/test/runner/EffAssert.java b/src/main/java/ch/njol/skript/test/runner/EffAssert.java index e339bf3e9a3..800b2a040a3 100644 --- a/src/main/java/ch/njol/skript/test/runner/EffAssert.java +++ b/src/main/java/ch/njol/skript/test/runner/EffAssert.java @@ -41,7 +41,7 @@ public class EffAssert extends Effect { static { if (TestMode.ENABLED) - Skript.registerEffect(EffAssert.class, "assert <.+> [(1¦to fail)] with %string% [on [test] %string%]"); + Skript.registerEffect(EffAssert.class, "assert <.+> [(1¦to fail)] with %string% [on [test] %-string%]"); } @Nullable From 4beacb18346bd8f939632aef8757b710afae0bf4 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 28 Dec 2022 08:23:51 -0700 Subject: [PATCH 10/33] Remove debug message --- src/main/java/ch/njol/skript/test/runner/TestTracker.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/test/runner/TestTracker.java b/src/main/java/ch/njol/skript/test/runner/TestTracker.java index 01b1a1fc024..fb6b2a0df40 100644 --- a/src/main/java/ch/njol/skript/test/runner/TestTracker.java +++ b/src/main/java/ch/njol/skript/test/runner/TestTracker.java @@ -25,7 +25,6 @@ import org.eclipse.jdt.annotation.Nullable; -import ch.njol.skript.Skript; import ch.njol.skript.test.utils.TestResults; /** @@ -56,7 +55,6 @@ public static void testFailed(String msg) { } public static void junitTestFailed(String junit, String msg) { - Skript.debug("Added JUnit fail " + junit + " with message " + msg); failedTests.put(junit, msg); } From 4a22767a56c3345431ab9d9e3a972a27df25ad15 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 28 Dec 2022 08:25:20 -0700 Subject: [PATCH 11/33] Not all versions have adventure api --- .../skript/test/tests/regression/SimpleJUnitTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java b/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java index 7d866eef167..59d4ac9cc00 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java @@ -26,7 +26,6 @@ import org.junit.Test; import ch.njol.skript.test.runner.SkriptJUnitTest; -import net.kyori.adventure.text.Component; public class SimpleJUnitTest extends SkriptJUnitTest { @@ -37,9 +36,10 @@ public class SimpleJUnitTest extends SkriptJUnitTest { } @Before + @SuppressWarnings("deprecation") public void setup() { piggy = spawnTestPig(); - piggy.customName(Component.text("Simple JUnit Test")); + piggy.setCustomName("Simple JUnit Test"); } @Test From 9bd2fe4d5b9783af67a391dd17677834d6e3437c Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 28 Dec 2022 08:32:55 -0700 Subject: [PATCH 12/33] Move test_runners into gradle build cache --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d0b3c77dede..c61cf6f30c9 100644 --- a/build.gradle +++ b/build.gradle @@ -195,7 +195,7 @@ void createTestTask(String name, String environment, boolean devMode, int javaVe ]) main = 'ch.njol.skript.test.platform.PlatformMain' args = [ - 'test_runners', + 'build/test_runners', junit ? 'src/test/skript/tests/junit' : 'src/test/skript/tests', 'src/test/resources/runner_data', environment, From fbd6b290f768e7286399e549e456b8252281057b Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 28 Dec 2022 08:37:00 -0700 Subject: [PATCH 13/33] Add directory location info --- src/test/skript/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/skript/README.md b/src/test/skript/README.md index 3955abe012a..85cfd584b7b 100644 --- a/src/test/skript/README.md +++ b/src/test/skript/README.md @@ -78,9 +78,14 @@ Use Gradle to launch a test development server: gradlew clean skriptTestDev --console=plain ``` +Note: adding the tag `clean` will clear the build directory, making Skript generate a new server each time. +Don't include the `clean` tag if you want to keep the same server folder around each test. + The server launched will be running at localhost:25565. You can use console as normal, though there is some lag due to Gradle. If you're having trouble, try without --console=plain. +Server files are located at build/test_runners + To run individual test files, use /sk test \. To run last used file again, just use /sk test. From 85cd30f928ab7635f814252df658f31bbd0e4c0c Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Fri, 30 Dec 2022 11:37:45 -0700 Subject: [PATCH 14/33] Update the new test_runner directory in gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 477d2c72451..96268b378c3 100755 --- a/.gitignore +++ b/.gitignore @@ -221,4 +221,4 @@ gradle-app.setting # End of https://www.toptal.com/developers/gitignore/api/intellij+all,gradle,java,eclipse,git # Skript test runners -test_runners/ +build/test_runners/ From ee07a59b8cab26ce25f6f4ef9abc46350a0cc811 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Fri, 30 Dec 2022 12:21:28 -0700 Subject: [PATCH 15/33] Reduce the time of the simple junit test and add block utility method --- .../ch/njol/skript/test/runner/SkriptJUnitTest.java | 11 ++++++++++- .../skript/test/tests/regression/SimpleJUnitTest.java | 4 +--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java index 22339564314..ecb7c2e6d57 100644 --- a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java +++ b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java @@ -91,9 +91,18 @@ protected Pig spawnTestPig() { * @return the Block after it has been updated. */ protected Block setBlock(Material material) { - Block block = getTestWorld().getBlockAt(getTestLocation()); + Block block = getBlock(); block.setType(material); return block; } + /** + * Return the main block for testing in the getTestLocation(); + * + * @return the Block after it has been updated. + */ + protected Block getBlock() { + return getTestWorld().getBlockAt(getTestLocation()); + } + } diff --git a/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java b/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java index 59d4ac9cc00..024055aac74 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java @@ -18,8 +18,6 @@ */ package org.skriptlang.skript.test.tests.regression; -import java.util.concurrent.TimeUnit; - import org.bukkit.entity.Pig; import org.junit.After; import org.junit.Before; @@ -32,7 +30,7 @@ public class SimpleJUnitTest extends SkriptJUnitTest { private static Pig piggy; static { - setDelay(TimeUnit.SECONDS.toMillis(1)); + setDelay(10); } @Before From 0416315545a9f3bf046772483e421c259c2236c1 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 11 Jan 2023 01:17:15 -0700 Subject: [PATCH 16/33] Apply changes --- .gitignore | 5 +- src/main/java/ch/njol/skript/Skript.java | 63 +++++---- src/main/java/ch/njol/skript/SkriptAddon.java | 109 ++++------------ .../ch/njol/skript/test/runner/EffAssert.java | 12 +- .../skript/test/runner/EffObjectives.java | 122 ++++++++++++++++++ .../skript/test/runner/ExprJUnitTest.java | 2 +- .../skript/test/runner/SkriptJUnitTest.java | 59 +++++++-- src/main/java/ch/njol/skript/util/Utils.java | 37 ++++-- .../skript/variables/FlatFileStorageTest.java | 2 +- .../test/tests/classes/ClassesTest.java | 5 +- .../tests/regression/SimpleJUnitTest.java | 20 ++- .../skript/test/tests/utils/UtilsTest.java | 67 +++++----- src/test/skript/README.md | 2 +- .../skript/tests/junit/SimpleJUnitTest.sk | 13 +- 14 files changed, 330 insertions(+), 188 deletions(-) create mode 100644 src/main/java/ch/njol/skript/test/runner/EffObjectives.java diff --git a/.gitignore b/.gitignore index 96268b378c3..07a7e50f084 100755 --- a/.gitignore +++ b/.gitignore @@ -220,5 +220,6 @@ gradle-app.setting # End of https://www.toptal.com/developers/gitignore/api/intellij+all,gradle,java,eclipse,git -# Skript test runners -build/test_runners/ +# TODO remove this in the future after some time since https://github.com/SkriptLang/Skript/pull/4979 +# This ensures developers don't upload their old existing test_runners/ folder. +test_runners/ \ No newline at end of file diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 6eda0f49522..71b22453395 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -128,6 +128,7 @@ import ch.njol.skript.registrations.Comparators; import ch.njol.skript.registrations.Converters; import ch.njol.skript.registrations.EventValues; +import ch.njol.skript.test.runner.EffObjectives; import ch.njol.skript.test.runner.SkriptJUnitTest; import ch.njol.skript.test.runner.SkriptTestEvent; import ch.njol.skript.test.runner.TestMode; @@ -646,11 +647,11 @@ protected void afterErrors() { Bukkit.getScheduler().runTaskLater(Skript.this, () -> info("Skript testing environment enabled, starting soon..."), 1); // Ignore late init (scripts, etc.) in test mode Bukkit.getScheduler().runTaskLater(Skript.this, () -> { - long shutdown = 0; + // Delay is in Minecraft ticks. + long shutdownDelay = 0; if (TestMode.GEN_DOCS) { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "skript gen-docs"); } else if (TestMode.DEV_MODE) { // Developer controlled environment. - SkriptLogger.setVerbosity(Verbosity.DEBUG); info("Test development mode enabled. Test scripts are at " + TestMode.TEST_DIR); } else { info("Loading all tests from " + TestMode.TEST_DIR); @@ -680,36 +681,40 @@ protected void afterErrors() { info("Running all JUnit tests..."); long milliseconds = 0, tests = 0, fails = 0, ignored = 0, size = 0; try { - List> classes = Lists.newArrayList(Utils.getClasses("org.skriptlang.skript.test", "tests")); - // Test that requires package access. + List> classes = Lists.newArrayList(Utils.getClasses(Skript.getInstance(), "org.skriptlang.skript.test", "tests")); + // Test that requires package access. This is only present when compiling with src/test. classes.add(Class.forName("ch.njol.skript.variables.FlatFileStorageTest")); size = classes.size(); for (Class clazz : classes) { + // Reset class SkriptJUnitTest which stores test requirements. String test = clazz.getName(); - SkriptJUnitTest.lastJUnitTest = test; + SkriptJUnitTest.setCurrentJUnitTest(test); + SkriptJUnitTest.setShutdownDelay(0); + info("Running JUnit test '" + test + "'"); Result junit = JUnitCore.runClasses(clazz); TestTracker.testStarted("JUnit: '" + test + "'"); - shutdown += SkriptJUnitTest.getDelay(); - SkriptJUnitTest.setDelay(0); + + // Collect all data from the current JUnit test. + shutdownDelay = Math.max(shutdownDelay, SkriptJUnitTest.getShutdownDelay()); tests += junit.getRunCount(); milliseconds += junit.getRunTime(); ignored += junit.getIgnoreCount(); - if (junit.getFailureCount() > 0) { - fails += junit.getFailureCount(); - junit.getFailures().forEach(failure -> { - String message = failure.getMessage() == null ? "" : " " + failure.getMessage(); - TestTracker.testFailed("'" + test + "': " + message); - Skript.exception(failure.getException(), "JUnit test '" + failure.getTestHeader() + " failed."); - }); - } - SkriptJUnitTest.lastJUnitTest = null; + fails += junit.getFailureCount(); + + // If JUnit failures are present, add them to the TestTracker. + junit.getFailures().forEach(failure -> { + String message = failure.getMessage() == null ? "" : " " + failure.getMessage(); + TestTracker.testFailed("'" + test + "': " + message); + Skript.exception(failure.getException(), "JUnit test '" + failure.getTestHeader() + " failed."); + }); + SkriptJUnitTest.clearJUnitTest(); } } catch (IOException e) { Skript.exception(e, "Failed to execute JUnit runtime tests."); } catch (ClassNotFoundException e) { // Should be the Skript test jar gradle task. - assert false; + assert false : "Class 'ch.njol.skript.variables.FlatFileStorageTest' was not found."; } if (ignored > 0) Skript.warning("There were " + ignored + " ignored test cases! This can mean they are not properly setup in order in that class!"); @@ -717,19 +722,23 @@ protected void afterErrors() { info("Completed " + tests + " JUnit tests in " + size + " classes with " + fails + " failures in " + milliseconds + " milliseconds."); } } - info("Collecting results to " + TestMode.RESULTS_FILE); - String results = new Gson().toJson(TestTracker.collectResults()); - try { - Files.write(TestMode.RESULTS_FILE, results.getBytes(StandardCharsets.UTF_8)); - } catch (IOException e) { - Skript.exception(e, "Failed to write test results."); - } - long seconds = TimeUnit.MILLISECONDS.toSeconds(shutdown); - info("Testing done, shutting down the server in " + seconds + " second " + (seconds == 1 ? "" : "s") + "..."); + double display = shutdownDelay / 20; + info("Testing done, shutting down the server in " + display + " second" + (display <= 1D ? "" : "s") + "..."); // Delay server shutdown to stop the server from crashing because the current tick takes a long time due to all the tests Bukkit.getScheduler().runTaskLater(Skript.this, () -> { + if (TestMode.JUNIT && !EffObjectives.isJUnitComplete()) + TestTracker.testFailed(EffObjectives.getFailedObjectivesString()); + + info("Collecting results to " + TestMode.RESULTS_FILE); + String results = new Gson().toJson(TestTracker.collectResults()); + try { + Files.write(TestMode.RESULTS_FILE, results.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + Skript.exception(e, "Failed to write test results."); + } + Bukkit.getServer().shutdown(); - }, seconds * 20); + }, shutdownDelay); }, 100); } diff --git a/src/main/java/ch/njol/skript/SkriptAddon.java b/src/main/java/ch/njol/skript/SkriptAddon.java index d32f90d1a5c..a66fdfe7c5f 100644 --- a/src/main/java/ch/njol/skript/SkriptAddon.java +++ b/src/main/java/ch/njol/skript/SkriptAddon.java @@ -18,35 +18,27 @@ */ package ch.njol.skript; -import ch.njol.skript.localization.Language; -import ch.njol.skript.util.Utils; -import ch.njol.skript.util.Version; -import ch.njol.util.coll.iterator.EnumerationIterable; -import org.bukkit.plugin.java.JavaPlugin; -import org.eclipse.jdt.annotation.Nullable; - import java.io.File; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.bukkit.plugin.java.JavaPlugin; +import org.eclipse.jdt.annotation.Nullable; + +import ch.njol.skript.localization.Language; +import ch.njol.skript.util.Utils; +import ch.njol.skript.util.Version; + /** * Utility class for Skript addons. Use {@link Skript#registerAddon(JavaPlugin)} to create a SkriptAddon instance for your plugin. - * - * @author Peter Güttinger */ public final class SkriptAddon { - + public final JavaPlugin plugin; public final Version version; private final String name; - + /** * Package-private constructor. Use {@link Skript#registerAddon(JavaPlugin)} to get a SkriptAddon for your plugin. * @@ -67,16 +59,16 @@ public final class SkriptAddon { } version = v; } - + @Override public final String toString() { return name; } - + public String getName() { return name; } - + /** * Loads classes of the plugin by package. Useful for registering many syntax elements like Skript does it. * @@ -87,51 +79,13 @@ public String getName() { * @return This SkriptAddon */ public SkriptAddon loadClasses(String basePackage, String... subPackages) throws IOException { - assert subPackages != null; - JarFile jar = new JarFile(getFile()); - for (int i = 0; i < subPackages.length; i++) - subPackages[i] = subPackages[i].replace('.', '/') + "/"; - basePackage = basePackage.replace('.', '/') + "/"; - try { - List classNames = new ArrayList<>(); - - for (JarEntry e : new EnumerationIterable<>(jar.entries())) { - if (e.getName().startsWith(basePackage) && e.getName().endsWith(".class")) { - boolean load = subPackages.length == 0; - for (String sub : subPackages) { - if (e.getName().startsWith(sub, basePackage.length())) { - load = true; - break; - } - } - - if (load) - classNames.add(e.getName().replace('/', '.').substring(0, e.getName().length() - ".class".length())); - } - } - - classNames.sort(String::compareToIgnoreCase); - - for (String c : classNames) { - try { - Class.forName(c, true, plugin.getClass().getClassLoader()); - } catch (ClassNotFoundException ex) { - Skript.exception(ex, "Cannot load class " + c + " from " + this); - } catch (ExceptionInInitializerError err) { - Skript.exception(err.getCause(), this + "'s class " + c + " generated an exception while loading"); - } - } - } finally { - try { - jar.close(); - } catch (IOException e) {} - } + Utils.getClasses(plugin, basePackage, subPackages); return this; } - + @Nullable private String languageFileDirectory = null; - + /** * Makes Skript load language files from the specified directory, e.g. "lang" or "skript lang" if you have a lang folder yourself. Localised files will be read from the * plugin's jar and the plugin's data folder, but the default English file is only taken from the jar and must exist! @@ -149,40 +103,23 @@ public SkriptAddon setLanguageFileDirectory(String directory) { Language.loadDefault(this); return this; } - + @Nullable public String getLanguageFileDirectory() { return languageFileDirectory; } - + @Nullable private File file = null; - + /** - * @return The jar file of the plugin. The first invocation of this method uses reflection to invoke the protected method {@link JavaPlugin#getFile()} to get the plugin's jar - * file. The file is then cached and returned upon subsequent calls to this method to reduce usage of reflection. + * @return The jar file of the plugin. + * The first invocation of this method uses reflection to invoke the protected method {@link JavaPlugin#getFile()} to get the plugin's jar file. + * The file is then cached and returned upon subsequent calls to this method to reduce usage of reflection. */ @Nullable public File getFile() { - if (file != null) - return file; - try { - final Method getFile = JavaPlugin.class.getDeclaredMethod("getFile"); - getFile.setAccessible(true); - file = (File) getFile.invoke(plugin); - return file; - } catch (final NoSuchMethodException e) { - Skript.outdatedError(e); - } catch (final IllegalArgumentException e) { - Skript.outdatedError(e); - } catch (final IllegalAccessException e) { - assert false; - } catch (final SecurityException e) { - throw new RuntimeException(e); - } catch (final InvocationTargetException e) { - throw new RuntimeException(e.getCause()); - } - return null; + return Utils.getFile(plugin); } - + } diff --git a/src/main/java/ch/njol/skript/test/runner/EffAssert.java b/src/main/java/ch/njol/skript/test/runner/EffAssert.java index 800b2a040a3..2aeafa355d9 100644 --- a/src/main/java/ch/njol/skript/test/runner/EffAssert.java +++ b/src/main/java/ch/njol/skript/test/runner/EffAssert.java @@ -41,12 +41,9 @@ public class EffAssert extends Effect { static { if (TestMode.ENABLED) - Skript.registerEffect(EffAssert.class, "assert <.+> [(1¦to fail)] with %string% [on [test] %-string%]"); + Skript.registerEffect(EffAssert.class, "assert <.+> [(1¦to fail)] with %string%"); } - @Nullable - private Expression junit; - private Expression errorMsg; private Condition condition; private boolean shouldFail; @@ -56,7 +53,6 @@ public class EffAssert extends Effect { public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { String conditionString = parseResult.regexes.get(0).group(); errorMsg = (Expression) exprs[0]; - junit = (Expression) exprs[1]; shouldFail = parseResult.mark != 0; ParseLogHandler logHandler = SkriptLogger.startParseLogHandler(); @@ -90,10 +86,8 @@ public TriggerItem walk(Event event) { if (condition.check(event) == shouldFail) { String message = errorMsg.getSingle(event); assert message != null; // Should not happen, developer needs to fix test. - if (junit != null) { - String test = junit.getSingle(event); - assert test != null; - TestTracker.junitTestFailed(test, message); + if (SkriptJUnitTest.getCurrentJUnitTest() != null) { + TestTracker.junitTestFailed(SkriptJUnitTest.getCurrentJUnitTest(), message); } else { TestTracker.testFailed(message); } diff --git a/src/main/java/ch/njol/skript/test/runner/EffObjectives.java b/src/main/java/ch/njol/skript/test/runner/EffObjectives.java new file mode 100644 index 00000000000..7d0aab3d2de --- /dev/null +++ b/src/main/java/ch/njol/skript/test/runner/EffObjectives.java @@ -0,0 +1,122 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +package ch.njol.skript.test.runner; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.event.Event; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; + +import ch.njol.skript.Skript; +import ch.njol.skript.doc.Description; +import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.NoDoc; +import ch.njol.skript.lang.Effect; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; + +@Name("Objectives") +@Description("An effect to setup required objectives for JUnit tests to complete.") +@NoDoc +public class EffObjectives extends Effect { + + static { + if (TestMode.ENABLED) + Skript.registerEffect(EffObjectives.class, + "ensure [[junit] test] %string% completes [(objective|trigger)[s]] %strings%", + "complete [(objective|trigger)[s]] %strings% (for|on) [[junit] test] %string%" + ); + } + + private final static Multimap requirements = HashMultimap.create(); + private final static Multimap completness = HashMultimap.create(); + + private Expression junit, objectives; + private boolean setup; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + objectives = (Expression) exprs[matchedPattern ^ 1]; + junit = (Expression) exprs[matchedPattern]; + setup = matchedPattern == 0; + return true; + } + + @Override + protected void execute(Event event) { + String junit = this.junit.getSingle(event); + assert junit != null; + String[] objectives = this.objectives.getArray(event); + assert objectives.length > 0; + if (setup) { + Skript.info("Loaded " + toString(event, true)); + requirements.putAll(junit, Lists.newArrayList(objectives)); + } else { + Skript.info("Completed " + toString(event, true)); + completness.putAll(junit, Lists.newArrayList(objectives)); + } + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "ensure junit test " + junit.toString(event, debug) + " completes objectives " + objectives.toString(event, debug); + } + + /** + * Check if the currently running JUnit test has passed all + * it's required objectives that the script test setup. + * + * @return boolean true if the test passed. + */ + public static boolean isJUnitComplete() { + if (requirements.isEmpty()) + return true; + if (completness.isEmpty() && !requirements.isEmpty()) + return false; + return completness.equals(requirements); + } + + /** + * Returns an array string containing all the objectives that the current + * JUnit test failed to accomplish in the given time. + * + * @return + */ + public static String getFailedObjectivesString() { + StringBuilder builder = new StringBuilder(); + for (String test : requirements.keySet()) { + if (!completness.containsKey(test)) { + builder.append("JUnit test '" + test + "' didn't complete any objectives."); + continue; + } + List failures = Lists.newArrayList(requirements.get(test)); + failures.removeAll(completness.get(test)); + builder.append("JUnit test '" + test + "' failed objectives: " + Arrays.toString(failures.toArray(new String[0]))); + } + return builder.toString(); + } + +} diff --git a/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java b/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java index 6749e1428b1..d6905bc30c4 100644 --- a/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java +++ b/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java @@ -50,7 +50,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override @Nullable protected String[] get(Event event) { - return CollectionUtils.array(SkriptJUnitTest.lastJUnitTest); + return CollectionUtils.array(SkriptJUnitTest.getCurrentJUnitTest()); } @Override diff --git a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java index ecb7c2e6d57..0d9ef44f8ea 100644 --- a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java +++ b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java @@ -19,45 +19,62 @@ package ch.njol.skript.test.runner; import org.bukkit.Bukkit; +import org.bukkit.GameRule; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Pig; import org.junit.After; +import org.junit.Before; /** * Class that helps the JUnit test communicate with Skript. */ public abstract class SkriptJUnitTest { + static { + World world = Bukkit.getWorlds().get(0); + world.setGameRule(GameRule.MAX_ENTITY_CRAMMING, 1000); + world.setGameRule(GameRule.DO_PATROL_SPAWNING, false); + world.setGameRule(GameRule.DO_TRADER_SPAWNING, false); + world.setGameRule(GameRule.DO_WEATHER_CYCLE, false); + // Natural entity spawning + world.setGameRule(GameRule.DO_MOB_SPAWNING, false); + world.setGameRule(GameRule.DISABLE_RAIDS, false); + world.setGameRule(GameRule.MOB_GRIEFING, false); + } + /** - * Used for getting the last ran JUnit test name. + * Used for getting the currently running JUnit test name. */ - public static String lastJUnitTest; + private static String currentJUnitTest; - private static long d; + private static long d = 0; /** * The delay this JUnit test is requiring to run. + * Do note this is global to all other tests. The most delay is the final waiting time. * - * @return the delay in milliseconds this junit test is requiring to run for. + * @return the delay in Minecraft ticks this junit test is requiring to run for. */ - public static long getDelay() { + public static long getShutdownDelay() { return d; } /** - * @param delay Add a delay in milliseconds for this test to run. + * @param delay Set the delay in Minecraft ticks for this test to run. */ - public static void setDelay(long delay) { + public static void setShutdownDelay(long delay) { d = delay; } + @Before @After public final void cleanup() { - getTestWorld().getEntities().forEach(entity -> entity.remove()); + getTestWorld().getEntities().forEach(Entity::remove); setBlock(Material.AIR); } @@ -81,6 +98,8 @@ protected Location getTestLocation() { * @return Pig that has been spawned. */ protected Pig spawnTestPig() { + if (d <= 0D) + d = 1; // A single tick allows the piggy to spawn before server shutdown. return (Pig) getTestWorld().spawnEntity(getTestLocation(), EntityType.PIG); } @@ -102,7 +121,29 @@ protected Block setBlock(Material material) { * @return the Block after it has been updated. */ protected Block getBlock() { - return getTestWorld().getBlockAt(getTestLocation()); + return getTestWorld().getSpawnLocation().add(10, 1, 0).getBlock(); + } + + /** + * Get the currently running JUnit test name. + */ + public static String getCurrentJUnitTest() { + return currentJUnitTest; + } + + /** + * Used internally. + */ + public static void setCurrentJUnitTest(String currentJUnitTest) { + SkriptJUnitTest.currentJUnitTest = currentJUnitTest; + } + + /** + * Used internally. + */ + public static void clearJUnitTest() { + SkriptJUnitTest.currentJUnitTest = null; + setShutdownDelay(0); } } diff --git a/src/main/java/ch/njol/skript/util/Utils.java b/src/main/java/ch/njol/skript/util/Utils.java index 02805f7e17e..910705d909a 100644 --- a/src/main/java/ch/njol/skript/util/Utils.java +++ b/src/main/java/ch/njol/skript/util/Utils.java @@ -38,6 +38,7 @@ import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.messaging.Messenger; import org.bukkit.plugin.messaging.PluginMessageListener; @@ -159,9 +160,18 @@ public static Pair getAmount(String s) { // return new AmountResponse(s); // } - public static Class[] getClasses(String basePackage, String... subPackages) throws IOException { + /** + * Loads classes of the plugin by package. Useful for registering many syntax elements like Skript does it. + * + * @param basePackage The base package to add to all sub packages, e.g. "ch.njol.skript". + * @param subPackages Which subpackages of the base package should be loaded, e.g. "expressions", "conditions", "effects". Subpackages of these packages will be loaded + * as well. Use an empty array to load all subpackages of the base package. + * @throws IOException If some error occurred attempting to read the plugin's jar file. + * @return This SkriptAddon + */ + public static Class[] getClasses(Plugin plugin, String basePackage, String... subPackages) throws IOException { assert subPackages != null; - JarFile jar = new JarFile(getFile()); + JarFile jar = new JarFile(getFile(plugin)); for (int i = 0; i < subPackages.length; i++) subPackages[i] = subPackages[i].replace('.', '/') + "/"; basePackage = basePackage.replace('.', '/') + "/"; @@ -188,7 +198,7 @@ public static Class[] getClasses(String basePackage, String... subPackages) t for (String c : classNames) { try { - classes.add(Class.forName(c, true, Skript.getInstance().getClass().getClassLoader())); + classes.add(Class.forName(c, true, plugin.getClass().getClassLoader())); } catch (ClassNotFoundException ex) { Skript.exception(ex, "Cannot load class " + c); } catch (ExceptionInInitializerError err) { @@ -203,21 +213,26 @@ public static Class[] getClasses(String basePackage, String... subPackages) t return classes.toArray(new Class[classes.size()]); } + /** + * @return The jar file of the plugin. + * The first invocation of this method uses reflection to invoke the protected method {@link JavaPlugin#getFile()} to get the plugin's jar file. + * The file is then cached and returned upon subsequent calls to this method to reduce usage of reflection. + */ @Nullable - private static File getFile() { + public static File getFile(Plugin plugin) { try { - final Method getFile = JavaPlugin.class.getDeclaredMethod("getFile"); + Method getFile = JavaPlugin.class.getDeclaredMethod("getFile"); getFile.setAccessible(true); - return (File) getFile.invoke(Skript.getInstance()); - } catch (final NoSuchMethodException e) { + return (File) getFile.invoke(plugin); + } catch (NoSuchMethodException e) { Skript.outdatedError(e); - } catch (final IllegalArgumentException e) { + } catch (IllegalArgumentException e) { Skript.outdatedError(e); - } catch (final IllegalAccessException e) { + } catch (IllegalAccessException e) { assert false; - } catch (final SecurityException e) { + } catch (SecurityException e) { throw new RuntimeException(e); - } catch (final InvocationTargetException e) { + } catch (InvocationTargetException e) { throw new RuntimeException(e.getCause()); } return null; diff --git a/src/test/java/ch/njol/skript/variables/FlatFileStorageTest.java b/src/test/java/ch/njol/skript/variables/FlatFileStorageTest.java index 596c549ccd3..3868358459c 100644 --- a/src/test/java/ch/njol/skript/variables/FlatFileStorageTest.java +++ b/src/test/java/ch/njol/skript/variables/FlatFileStorageTest.java @@ -35,7 +35,7 @@ public void testHexCoding() { } @Test - public void testCSV() { + public void testSplitCSV() { String[][] vs = { {"", ""}, {",", "", ""}, diff --git a/src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java b/src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java index e26ba244aec..df8b11c869a 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java @@ -45,7 +45,7 @@ public class ClassesTest { @Test - public void test() { + public void classesTest() { Object[] random = { // Java (byte) 127, (short) 2000, -1600000, 1L << 40, -1.5f, 13.37, @@ -67,9 +67,8 @@ public void test() { // there is also at least one variable for each class on my test server which are tested whenever the server shuts down. }; - for (Object o : random) { + for (Object o : random) Classes.serialize(o); // includes a deserialisation test - } } } diff --git a/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java b/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java index 024055aac74..0f8f78b33b7 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/regression/SimpleJUnitTest.java @@ -25,23 +25,35 @@ import ch.njol.skript.test.runner.SkriptJUnitTest; +/** + * This class is a simple example JUnit. + * A piggy will spawn and get damaged by 100. + * The script under skript/tests/SimpleJUnitTest.sk will do all the assertion using the damage event. + * + * Methods exist in {@link ch.njol.skript.test.runner.SkriptJUnitTest} to simplify repetitive tasks. + */ public class SimpleJUnitTest extends SkriptJUnitTest { - private static Pig piggy; + private Pig piggy; + /** + * In the static method of the class, you can utilize methods in SkriptJUnitTest that allow you + * to control how this JUnit test will interact with the server. + */ static { - setDelay(10); + // Set the delay to 1 tick. This allows the piggy to be spawned into the world. + setShutdownDelay(1); } @Before @SuppressWarnings("deprecation") - public void setup() { + public void spawnPig() { piggy = spawnTestPig(); piggy.setCustomName("Simple JUnit Test"); } @Test - public void test() { + public void testDamage() { // Try to have more descriptive method names other than 'test()' piggy.damage(100); } diff --git a/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java index 3664973ee47..bf8ccd54d4f 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java @@ -18,9 +18,6 @@ */ package org.skriptlang.skript.test.tests.utils; -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.expectLastCall; -import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertEquals; import java.io.FileNotFoundException; @@ -35,43 +32,46 @@ import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Server; -import org.junit.Before; import org.junit.Test; -import ch.njol.skript.log.SkriptLogger; import ch.njol.skript.util.Utils; +/** + * Test methods from the Utils class. + */ public class UtilsTest { - @Before - public void fakeServer() throws Exception { - if (Bukkit.getServer() == null) { - Logger logger = Logger.getLogger(getClass().getCanonicalName()); - logger.setParent(SkriptLogger.LOGGER); - logger.setLevel(Level.WARNING); - - Server server = createMock(Server.class); - server.getLogger(); - expectLastCall().andReturn(logger).anyTimes(); - server.isPrimaryThread(); - expectLastCall().andReturn(true).anyTimes(); - server.getName(); - expectLastCall().andReturn("Whatever").anyTimes(); - server.getVersion(); - expectLastCall().andReturn("2.0").anyTimes(); - server.getBukkitVersion(); - expectLastCall().andReturn("2.0").anyTimes(); - replay(server); - - Bukkit.setServer(server); - } - } + /** + * Example of how to fake a Bukkit server using EasyMock + */ +// @Before +// public void fakeServer() throws Exception { +// if (Bukkit.getServer() == null) { +// Logger logger = Logger.getLogger(getClass().getCanonicalName()); +// logger.setParent(SkriptLogger.LOGGER); +// logger.setLevel(Level.WARNING); +// +// Server server = createMock(Server.class); +// server.getLogger(); +// expectLastCall().andReturn(logger).anyTimes(); +// server.isPrimaryThread(); +// expectLastCall().andReturn(true).anyTimes(); +// server.getName(); +// expectLastCall().andReturn("Whatever").anyTimes(); +// server.getVersion(); +// expectLastCall().andReturn("2.0").anyTimes(); +// server.getBukkitVersion(); +// expectLastCall().andReturn("2.0").anyTimes(); +// replay(server); +// +// Bukkit.setServer(server); +// } +// } + /** + * Testing method Utils.getEnglishPlural + */ @Test public void testPlural() { String[][] strings = { @@ -104,6 +104,9 @@ public void testPlural() { } } + /** + * Testing method Utils.getSuperType + */ @Test public void testSuperClass() { Class[][] classes = { diff --git a/src/test/skript/README.md b/src/test/skript/README.md index 85cfd584b7b..77f80457f3e 100644 --- a/src/test/skript/README.md +++ b/src/test/skript/README.md @@ -85,7 +85,7 @@ The server launched will be running at localhost:25565. You can use console as normal, though there is some lag due to Gradle. If you're having trouble, try without --console=plain. -Server files are located at build/test_runners +Server files are located at build/test_runners. To run individual test files, use /sk test \. To run last used file again, just use /sk test. diff --git a/src/test/skript/tests/junit/SimpleJUnitTest.sk b/src/test/skript/tests/junit/SimpleJUnitTest.sk index 92584678c1b..25a048ae372 100644 --- a/src/test/skript/tests/junit/SimpleJUnitTest.sk +++ b/src/test/skript/tests/junit/SimpleJUnitTest.sk @@ -1,7 +1,16 @@ +on script load: + # Setup our objective for this script test to complete with the JUnit test. + ensure junit test "org.skriptlang.skript.test.tests.regression.SimpleJUnitTest" completes "piggy died" on damage of pig: + # Check that this is indeed our correct test to match with the JUnit test we want. junit test is "org.skriptlang.skript.test.tests.regression.SimpleJUnitTest" - assert custom name of victim is "Simple JUnit Test" with "piggy was not the same" on junit test + + # Using the JUnit name is not required, just another example. + assert custom name of victim is "Simple JUnit Test" with "piggy was not the same" # Remember the damage was 100 but Skript represents it by hearts so it's 50. - assert damage is 50 with "damage was not 50" on the currently running junit test + assert damage is 50 with "damage was not 50" + + # Tell our objective that our runtime objective has been completed which was an entity damage event. + complete objective "piggy died" for junit test "org.skriptlang.skript.test.tests.regression.SimpleJUnitTest" From 02d94289e4eccc04670d213ddacc678bc0ef012a Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 11 Jan 2023 01:37:32 -0700 Subject: [PATCH 17/33] Version checking gamerules --- .../ch/njol/skript/test/runner/EffObjectives.java | 2 -- .../ch/njol/skript/test/runner/SkriptJUnitTest.java | 11 ++++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/ch/njol/skript/test/runner/EffObjectives.java b/src/main/java/ch/njol/skript/test/runner/EffObjectives.java index 7d0aab3d2de..f5bfc6af5ce 100644 --- a/src/main/java/ch/njol/skript/test/runner/EffObjectives.java +++ b/src/main/java/ch/njol/skript/test/runner/EffObjectives.java @@ -72,10 +72,8 @@ protected void execute(Event event) { String[] objectives = this.objectives.getArray(event); assert objectives.length > 0; if (setup) { - Skript.info("Loaded " + toString(event, true)); requirements.putAll(junit, Lists.newArrayList(objectives)); } else { - Skript.info("Completed " + toString(event, true)); completness.putAll(junit, Lists.newArrayList(objectives)); } } diff --git a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java index 0d9ef44f8ea..f25a32355b7 100644 --- a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java +++ b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java @@ -30,6 +30,8 @@ import org.junit.After; import org.junit.Before; +import ch.njol.skript.Skript; + /** * Class that helps the JUnit test communicate with Skript. */ @@ -38,13 +40,16 @@ public abstract class SkriptJUnitTest { static { World world = Bukkit.getWorlds().get(0); world.setGameRule(GameRule.MAX_ENTITY_CRAMMING, 1000); - world.setGameRule(GameRule.DO_PATROL_SPAWNING, false); - world.setGameRule(GameRule.DO_TRADER_SPAWNING, false); world.setGameRule(GameRule.DO_WEATHER_CYCLE, false); // Natural entity spawning world.setGameRule(GameRule.DO_MOB_SPAWNING, false); - world.setGameRule(GameRule.DISABLE_RAIDS, false); world.setGameRule(GameRule.MOB_GRIEFING, false); + + if (Skript.isRunningMinecraft(1, 15)) { + world.setGameRule(GameRule.DO_PATROL_SPAWNING, false); + world.setGameRule(GameRule.DO_TRADER_SPAWNING, false); + world.setGameRule(GameRule.DISABLE_RAIDS, false); + } } /** From ba24b4e61bc313091514c394d924d18af3d44ad9 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 11 Jan 2023 01:39:53 -0700 Subject: [PATCH 18/33] proper toString --- src/main/java/ch/njol/skript/test/runner/EffObjectives.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/test/runner/EffObjectives.java b/src/main/java/ch/njol/skript/test/runner/EffObjectives.java index f5bfc6af5ce..55ce5aa0352 100644 --- a/src/main/java/ch/njol/skript/test/runner/EffObjectives.java +++ b/src/main/java/ch/njol/skript/test/runner/EffObjectives.java @@ -80,7 +80,9 @@ protected void execute(Event event) { @Override public String toString(@Nullable Event event, boolean debug) { - return "ensure junit test " + junit.toString(event, debug) + " completes objectives " + objectives.toString(event, debug); + if (setup) + return "ensure junit test " + junit.toString(event, debug) + " completes objectives " + objectives.toString(event, debug); + return "complete objectives " + objectives.toString(event, debug) + " on junit test " + junit.toString(event, debug); } /** From c37e7f30d4c9dd74bdcd6950b6fc334eb57a4091 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 11 Jan 2023 01:40:50 -0700 Subject: [PATCH 19/33] Remove un-used imports --- src/main/java/ch/njol/skript/Skript.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 71b22453395..f6320ef81f4 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -42,7 +42,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.concurrent.TimeUnit; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Filter; From 4351d2d56137ef07237fa16d2ceafe1891da0227 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 11 Jan 2023 14:43:37 -0700 Subject: [PATCH 20/33] Changes --- .../test/tests/classes/ClassesTest.java | 2 +- .../test/tests/localization/UtilsPlurals.java | 46 ++++++++++++++ .../skript/test/tests/utils/UtilsTest.java | 62 ------------------- 3 files changed, 47 insertions(+), 63 deletions(-) create mode 100644 src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java diff --git a/src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java b/src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java index df8b11c869a..385078a5701 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/classes/ClassesTest.java @@ -45,7 +45,7 @@ public class ClassesTest { @Test - public void classesTest() { + public void serializationTest() { Object[] random = { // Java (byte) 127, (short) 2000, -1600000, 1L << 40, -1.5f, 13.37, diff --git a/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java b/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java new file mode 100644 index 00000000000..aad9286fb09 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java @@ -0,0 +1,46 @@ +package org.skriptlang.skript.test.tests.localization; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import ch.njol.skript.util.Utils; + +public class UtilsPlurals { + + /** + * Testing method Utils.getEnglishPlural + */ + @Test + public void testPlural() { + String[][] strings = { + {"house", "houses"}, + {"cookie", "cookies"}, + {"creeper", "creepers"}, + {"cactus", "cacti"}, + {"rose", "roses"}, + {"dye", "dyes"}, + {"name", "names"}, + {"ingot", "ingots"}, + {"derp", "derps"}, + {"sheep", "sheep"}, + {"choir", "choirs"}, + {"man", "men"}, + {"child", "children"}, + {"hoe", "hoes"}, + {"toe", "toes"}, + {"hero", "heroes"}, + {"kidney", "kidneys"}, + {"anatomy", "anatomies"}, + {"axe", "axes"}, + {"elf", "elfs"}, + {"knife", "knives"}, + {"shelf", "shelfs"}, + }; + for (String[] s : strings) { + assertEquals(s[1], Utils.toEnglishPlural(s[0])); + assertEquals(s[0], Utils.getEnglishPlural(s[1]).getFirst()); + } + } + +} diff --git a/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java index bf8ccd54d4f..02263a00b7b 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java @@ -42,68 +42,6 @@ */ public class UtilsTest { - /** - * Example of how to fake a Bukkit server using EasyMock - */ -// @Before -// public void fakeServer() throws Exception { -// if (Bukkit.getServer() == null) { -// Logger logger = Logger.getLogger(getClass().getCanonicalName()); -// logger.setParent(SkriptLogger.LOGGER); -// logger.setLevel(Level.WARNING); -// -// Server server = createMock(Server.class); -// server.getLogger(); -// expectLastCall().andReturn(logger).anyTimes(); -// server.isPrimaryThread(); -// expectLastCall().andReturn(true).anyTimes(); -// server.getName(); -// expectLastCall().andReturn("Whatever").anyTimes(); -// server.getVersion(); -// expectLastCall().andReturn("2.0").anyTimes(); -// server.getBukkitVersion(); -// expectLastCall().andReturn("2.0").anyTimes(); -// replay(server); -// -// Bukkit.setServer(server); -// } -// } - - /** - * Testing method Utils.getEnglishPlural - */ - @Test - public void testPlural() { - String[][] strings = { - {"house", "houses"}, - {"cookie", "cookies"}, - {"creeper", "creepers"}, - {"cactus", "cacti"}, - {"rose", "roses"}, - {"dye", "dyes"}, - {"name", "names"}, - {"ingot", "ingots"}, - {"derp", "derps"}, - {"sheep", "sheep"}, - {"choir", "choirs"}, - {"man", "men"}, - {"child", "children"}, - {"hoe", "hoes"}, - {"toe", "toes"}, - {"hero", "heroes"}, - {"kidney", "kidneys"}, - {"anatomy", "anatomies"}, - {"axe", "axes"}, - {"elf", "elfs"}, - {"knife", "knives"}, - {"shelf", "shelfs"}, - }; - for (String[] s : strings) { - assertEquals(s[1], Utils.toEnglishPlural(s[0])); - assertEquals(s[0], Utils.getEnglishPlural(s[1]).getFirst()); - } - } - /** * Testing method Utils.getSuperType */ From 1bb806c6d429e1395ad0e573a3f91cea75d25693 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Wed, 25 Jan 2023 23:15:33 -0700 Subject: [PATCH 21/33] Update .gitignore Co-authored-by: Patrick Miller --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 07a7e50f084..fbddca8fd46 100755 --- a/.gitignore +++ b/.gitignore @@ -222,4 +222,4 @@ gradle-app.setting # TODO remove this in the future after some time since https://github.com/SkriptLang/Skript/pull/4979 # This ensures developers don't upload their old existing test_runners/ folder. -test_runners/ \ No newline at end of file +test_runners/ From b10a00567fb1547712d1382e0764ed5268a975c4 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Wed, 25 Jan 2023 23:25:04 -0700 Subject: [PATCH 22/33] Update src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java Co-authored-by: Patrick Miller --- src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java b/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java index d6905bc30c4..14276a09f16 100644 --- a/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java +++ b/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java @@ -39,7 +39,7 @@ public class ExprJUnitTest extends SimpleExpression { static { if (TestMode.ENABLED) - Skript.registerExpression(ExprJUnitTest.class, String.class, ExpressionType.SIMPLE, "[the] [current[ly [running]]] junit test [name]"); + Skript.registerExpression(ExprJUnitTest.class, String.class, ExpressionType.SIMPLE, "[the] [current[[ly] running]] junit test [name]"); } @Override From db954be7a39508a7ccf970d149f9ffee7169a6ac Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 25 Jan 2023 23:26:47 -0700 Subject: [PATCH 23/33] Address changes --- .../ch/njol/skript/test/runner/EffObjectives.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/ch/njol/skript/test/runner/EffObjectives.java b/src/main/java/ch/njol/skript/test/runner/EffObjectives.java index 55ce5aa0352..9a2d9a0e4ae 100644 --- a/src/main/java/ch/njol/skript/test/runner/EffObjectives.java +++ b/src/main/java/ch/njol/skript/test/runner/EffObjectives.java @@ -50,8 +50,8 @@ public class EffObjectives extends Effect { ); } - private final static Multimap requirements = HashMultimap.create(); - private final static Multimap completness = HashMultimap.create(); + private static final Multimap requirements = HashMultimap.create(); + private static final Multimap completeness = HashMultimap.create(); private Expression junit, objectives; private boolean setup; @@ -74,7 +74,7 @@ protected void execute(Event event) { if (setup) { requirements.putAll(junit, Lists.newArrayList(objectives)); } else { - completness.putAll(junit, Lists.newArrayList(objectives)); + completeness.putAll(junit, Lists.newArrayList(objectives)); } } @@ -94,9 +94,9 @@ public String toString(@Nullable Event event, boolean debug) { public static boolean isJUnitComplete() { if (requirements.isEmpty()) return true; - if (completness.isEmpty() && !requirements.isEmpty()) + if (completeness.isEmpty() && !requirements.isEmpty()) return false; - return completness.equals(requirements); + return completeness.equals(requirements); } /** @@ -108,12 +108,12 @@ public static boolean isJUnitComplete() { public static String getFailedObjectivesString() { StringBuilder builder = new StringBuilder(); for (String test : requirements.keySet()) { - if (!completness.containsKey(test)) { + if (!completeness.containsKey(test)) { builder.append("JUnit test '" + test + "' didn't complete any objectives."); continue; } List failures = Lists.newArrayList(requirements.get(test)); - failures.removeAll(completness.get(test)); + failures.removeAll(completeness.get(test)); builder.append("JUnit test '" + test + "' failed objectives: " + Arrays.toString(failures.toArray(new String[0]))); } return builder.toString(); From 49c694c97875d54ca2afac0478ef462c3ed3648a Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Thu, 26 Jan 2023 00:15:46 -0700 Subject: [PATCH 24/33] Add gradle task descriptions --- build.gradle | 45 ++++++++++++++---------- src/main/java/ch/njol/skript/Skript.java | 2 +- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/build.gradle b/build.gradle index 4363ed4adcd..85212be64d3 100644 --- a/build.gradle +++ b/build.gradle @@ -79,7 +79,7 @@ task relocateShadowJar(type: ConfigureShadowRelocation) { task sourceJar(type: Jar) { from sourceSets.main.allJava - archiveClassifier = "sources" + archiveClassifier = 'sources' } tasks.withType(ShadowJar) { @@ -121,8 +121,8 @@ processResources { publishing { publications { maven(MavenPublication) { - groupId "com.github.SkriptLang" - artifactId "Skript" + groupId 'com.github.SkriptLang' + artifactId 'Skript' version project.version artifact sourceJar artifact tasks.jar @@ -131,11 +131,11 @@ publishing { repositories { maven { - name = "repo" - url = "https://repo.skriptlang.org/releases" + name = 'repo' + url = 'https://repo.skriptlang.org/releases' credentials { - username = System.getenv("MAVEN_USERNAME") - password = System.getenv("MAVEN_PASSWORD") + username = System.getenv('MAVEN_USERNAME') + password = System.getenv('MAVEN_PASSWORD') } } } @@ -174,8 +174,9 @@ tasks.register('testNaming') { } // Create a test task with given name, environments dir/file, dev mode and java version. -void createTestTask(String name, String environment, boolean devMode, int javaVersion, boolean genDocs, boolean junit) { +void createTestTask(String name, String desc, String environment, boolean devMode, int javaVersion, boolean genDocs, boolean junit) { tasks.register(name, JavaExec) { + description = desc; if (junit) { dependsOn testJar } else { @@ -211,23 +212,29 @@ def latestJava = 17 def oldestJava = 8 tasks.withType(JavaCompile).configureEach { - options.compilerArgs += ["-source", "" + oldestJava, "-target", "" + oldestJava] + options.compilerArgs += ['-source', '' + oldestJava, '-target', '' + oldestJava] } -createTestTask('JUnitQuick','src/test/skript/environments/' + latestEnv, false, latestJava, false, true) -createTestTask('JUnitJava17', 'src/test/skript/environments/java17', false, latestJava, false, true) -createTestTask('JUnitJava8','src/test/skript/environments/java8', false, oldestJava, false, true) -tasks.register('JUnit') {dependsOn JUnitJava8, JUnitJava17} +createTestTask('JUnitQuick', 'Runs JUnit tests on one environment being the latest supported Java and Minecraft.', 'src/test/skript/environments/' + latestEnv, false, latestJava, false, true) +createTestTask('JUnitJava17', 'Runs JUnit tests on all Java 17 environments.', 'src/test/skript/environments/java17', false, latestJava, false, true) +createTestTask('JUnitJava8', 'Runs JUnit tests on all Java 8 environments.', 'src/test/skript/environments/java8', false, oldestJava, false, true) +tasks.register('JUnit') { + description = 'Runs JUnit tests on all environments.' + dependsOn JUnitJava8, JUnitJava17 +} // Register different Skript testing tasks -createTestTask('quickTest', 'src/test/skript/environments/' + latestEnv, false, latestJava, false, false) -createTestTask('skriptTestJava17', 'src/test/skript/environments/java17', false, latestJava, false, false) -createTestTask('skriptTestJava8', 'src/test/skript/environments/java8', false, oldestJava, false, false) -createTestTask('skriptTestDev', 'src/test/skript/environments/' + (project.property('testEnv') == null +createTestTask('quickTest', 'Runs tests on one environment being the latest supported Java and Minecraft.', 'src/test/skript/environments/' + latestEnv, false, latestJava, false, false) +createTestTask('skriptTestJava17', 'Runs tests on all Java 17 environments.', 'src/test/skript/environments/java17', false, latestJava, false, false) +createTestTask('skriptTestJava8', 'Runs tests on all Java 8 environments.', 'src/test/skript/environments/java8', false, oldestJava, false, false) +createTestTask('skriptTestDev', 'Runs testing server and uses \'system.in\' for command input, stop server to finish.', 'src/test/skript/environments/' + (project.property('testEnv') == null ? latestEnv : project.property('testEnv') + '.json'), true, Integer.parseInt(project.property('testEnvJavaVersion') == null ? latestJava : project.property('testEnvJavaVersion')), false, false) -tasks.register('skriptTest') {dependsOn skriptTestJava8, skriptTestJava17} -createTestTask('genDocs', 'src/test/skript/environments/' + (project.property('testEnv') == null +tasks.register('skriptTest') { + description = 'Runs tests on all environments.' + dependsOn skriptTestJava8, skriptTestJava17 +} +createTestTask('genDocs', 'Generates the Skript documentation website html files.', 'src/test/skript/environments/' + (project.property('testEnv') == null ? latestEnv : project.property('testEnv') + '.json'), false, Integer.parseInt(project.property('testEnvJavaVersion') == null ? latestJava : project.property('testEnvJavaVersion')), true, false) diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 80058ff0798..008e25cad62 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -590,7 +590,7 @@ public void run() { info("Preparing Skript for testing..."); tainted = true; try { - getAddonInstance().loadClasses("ch.njol.skript.test", "runner"); + getAddonInstance().loadClasses("ch.njol.skript.test.runner"); } catch (IOException e) { Skript.exception("Failed to load testing environment."); Bukkit.getServer().shutdown(); From 7669875ee97aa19e669a5b6c54be2248613d34d2 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Fri, 27 Jan 2023 00:05:57 -0700 Subject: [PATCH 25/33] Apply changes --- src/main/java/ch/njol/skript/SkriptAddon.java | 10 ++++++--- .../skript/test/platform/PlatformMain.java | 22 +++++++++---------- .../skript/test/runner/SkriptJUnitTest.java | 10 ++++----- src/main/java/ch/njol/skript/util/Utils.java | 4 ++-- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/main/java/ch/njol/skript/SkriptAddon.java b/src/main/java/ch/njol/skript/SkriptAddon.java index a66fdfe7c5f..c117f51cb9a 100644 --- a/src/main/java/ch/njol/skript/SkriptAddon.java +++ b/src/main/java/ch/njol/skript/SkriptAddon.java @@ -110,16 +110,20 @@ public String getLanguageFileDirectory() { } @Nullable - private File file = null; + private File file; /** - * @return The jar file of the plugin. * The first invocation of this method uses reflection to invoke the protected method {@link JavaPlugin#getFile()} to get the plugin's jar file. * The file is then cached and returned upon subsequent calls to this method to reduce usage of reflection. + * Only nullable if there was an exception thrown. + * + * @return The jar file of the plugin. */ @Nullable public File getFile() { - return Utils.getFile(plugin); + if (file == null) + file = Utils.getFile(plugin); + return file; } } diff --git a/src/main/java/ch/njol/skript/test/platform/PlatformMain.java b/src/main/java/ch/njol/skript/test/platform/PlatformMain.java index 422c83e1548..29f09c30a15 100644 --- a/src/main/java/ch/njol/skript/test/platform/PlatformMain.java +++ b/src/main/java/ch/njol/skript/test/platform/PlatformMain.java @@ -137,29 +137,29 @@ public static void main(String... args) throws IOException, InterruptedException Collections.sort(succeeded); List failNames = new ArrayList<>(failures.keySet()); Collections.sort(failNames); - + // All succeeded tests in a single line - System.out.printf("%s Results %s%n", StringUtils.repeat("-", 25), StringUtils.repeat("-", 25)); - System.out.println("\nTested environments: " + String.join(", ", + StringBuilder output = new StringBuilder(String.format("%s Results %s%n", StringUtils.repeat("-", 25), StringUtils.repeat("-", 25))); + output.append("\nTested environments: " + String.join(", ", envs.stream().map(Environment::getName).collect(Collectors.toList()))); - System.out.println("\nSucceeded:\n " + String.join((junit ? "\n " : ", "), succeeded)); + output.append("\nSucceeded:\n " + String.join((junit ? "\n " : ", "), succeeded)); if (!failNames.isEmpty()) { // More space for failed tests, they're important - Thread.sleep(1); // speed at which system prints fails without this, and can look like successful tests failed. - System.err.println("\nFailed:"); + output.append("\nFailed:"); for (String failed : failNames) { List> errors = failures.get(failed); - System.err.println(" " + failed + " (on " + errors.size() + " environment" + (errors.size() == 1 ? "" : "s") + ")"); + output.append(" " + failed + " (on " + errors.size() + " environment" + (errors.size() == 1 ? "" : "s") + ")"); for (NonNullPair error : errors) { - System.err.println(" " + error.getSecond() + " (on " + error.getFirst().getName() + ")"); + output.append(" " + error.getSecond() + " (on " + error.getFirst().getName() + ")"); } } - Thread.sleep(1); - System.out.printf("%n%s", StringUtils.repeat("-", 60)); + output.append(String.format("%n%n%s", StringUtils.repeat("-", 60))); + System.err.print(output.toString()); System.exit(failNames.size()); // Error code to indicate how many tests failed. return; } - System.out.printf("%n%s", StringUtils.repeat("-", 60)); + output.append(String.format("%n%n%s", StringUtils.repeat("-", 60))); + System.out.print(output.toString()); } } diff --git a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java index f25a32355b7..ed9fb6d026e 100644 --- a/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java +++ b/src/main/java/ch/njol/skript/test/runner/SkriptJUnitTest.java @@ -57,7 +57,7 @@ public abstract class SkriptJUnitTest { */ private static String currentJUnitTest; - private static long d = 0; + private static long delay = 0; /** * The delay this JUnit test is requiring to run. @@ -66,14 +66,14 @@ public abstract class SkriptJUnitTest { * @return the delay in Minecraft ticks this junit test is requiring to run for. */ public static long getShutdownDelay() { - return d; + return delay; } /** * @param delay Set the delay in Minecraft ticks for this test to run. */ public static void setShutdownDelay(long delay) { - d = delay; + SkriptJUnitTest.delay = delay; } @Before @@ -103,8 +103,8 @@ protected Location getTestLocation() { * @return Pig that has been spawned. */ protected Pig spawnTestPig() { - if (d <= 0D) - d = 1; // A single tick allows the piggy to spawn before server shutdown. + if (delay <= 0D) + delay = 1; // A single tick allows the piggy to spawn before server shutdown. return (Pig) getTestWorld().spawnEntity(getTestLocation(), EntityType.PIG); } diff --git a/src/main/java/ch/njol/skript/util/Utils.java b/src/main/java/ch/njol/skript/util/Utils.java index 910705d909a..71650e35d46 100644 --- a/src/main/java/ch/njol/skript/util/Utils.java +++ b/src/main/java/ch/njol/skript/util/Utils.java @@ -214,9 +214,9 @@ public static Class[] getClasses(Plugin plugin, String basePackage, String... } /** - * @return The jar file of the plugin. * The first invocation of this method uses reflection to invoke the protected method {@link JavaPlugin#getFile()} to get the plugin's jar file. - * The file is then cached and returned upon subsequent calls to this method to reduce usage of reflection. + * + * @return The jar file of the plugin. */ @Nullable public static File getFile(Plugin plugin) { From 1367a0d5b2a2538c0c751ca387fb7d53da4afb65 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Mon, 13 Feb 2023 23:10:52 -0700 Subject: [PATCH 26/33] Apply changes --- src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java | 4 ++-- .../org/skriptlang/skript/test/tests/utils/UtilsTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java b/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java index 14276a09f16..0f85a98e8aa 100644 --- a/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java +++ b/src/main/java/ch/njol/skript/test/runner/ExprJUnitTest.java @@ -27,7 +27,7 @@ import ch.njol.skript.doc.NoDoc; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionType; -import ch.njol.skript.lang.SkriptParser; +import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; @@ -43,7 +43,7 @@ public class ExprJUnitTest extends SimpleExpression { } @Override - public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { return true; } diff --git a/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java index 02263a00b7b..0b0c8d0553d 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java @@ -43,7 +43,7 @@ public class UtilsTest { /** - * Testing method Utils.getSuperType + * Testing method {@link Utils#getEnglishPlural(String)} */ @Test public void testSuperClass() { From 70787c6b11e1220e5ee14ba0469428abd289ce48 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Mon, 13 Feb 2023 23:11:45 -0700 Subject: [PATCH 27/33] Apply changes --- .../java/org/skriptlang/skript/test/tests/utils/UtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java index 0b0c8d0553d..fa718e04e94 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java @@ -43,7 +43,7 @@ public class UtilsTest { /** - * Testing method {@link Utils#getEnglishPlural(String)} + * Testing method {@link Utils#getSuperType(String)} */ @Test public void testSuperClass() { From 024e3b7ee1fe0ce82407518e3f63c3ceb0c2b624 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Mon, 13 Feb 2023 23:11:57 -0700 Subject: [PATCH 28/33] Apply changes --- .../java/org/skriptlang/skript/test/tests/utils/UtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java index fa718e04e94..592ea5c9fa8 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java +++ b/src/test/java/org/skriptlang/skript/test/tests/utils/UtilsTest.java @@ -43,7 +43,7 @@ public class UtilsTest { /** - * Testing method {@link Utils#getSuperType(String)} + * Testing method {@link Utils#getSuperType(Class...)} */ @Test public void testSuperClass() { From eb9d68b5a347cfb95087baf9291167a771c91148 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Mon, 13 Feb 2023 23:12:36 -0700 Subject: [PATCH 29/33] Apply changes --- .../skriptlang/skript/test/tests/localization/UtilsPlurals.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java b/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java index aad9286fb09..fb14d1212ea 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java +++ b/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java @@ -9,7 +9,7 @@ public class UtilsPlurals { /** - * Testing method Utils.getEnglishPlural + * Testing method {@link Utils#getEnglishPlural(String)} */ @Test public void testPlural() { From 9bcb42d7b9834d5f8c627435212d705d4f17565c Mon Sep 17 00:00:00 2001 From: Pikachu920 <28607612+Pikachu920@users.noreply.github.com> Date: Fri, 3 Feb 2023 21:58:05 -0600 Subject: [PATCH 30/33] Fix Pikachu's method exists --- .../njol/skript/{tests => test}/runner/CondMethodExists.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename src/main/java/ch/njol/skript/{tests => test}/runner/CondMethodExists.java (97%) diff --git a/src/main/java/ch/njol/skript/tests/runner/CondMethodExists.java b/src/main/java/ch/njol/skript/test/runner/CondMethodExists.java similarity index 97% rename from src/main/java/ch/njol/skript/tests/runner/CondMethodExists.java rename to src/main/java/ch/njol/skript/test/runner/CondMethodExists.java index 8a3b5e04061..17d821ad6aa 100644 --- a/src/main/java/ch/njol/skript/tests/runner/CondMethodExists.java +++ b/src/main/java/ch/njol/skript/test/runner/CondMethodExists.java @@ -16,7 +16,7 @@ * * Copyright Peter Güttinger, SkriptLang team and contributors */ -package ch.njol.skript.tests.runner; +package ch.njol.skript.test.runner; import ch.njol.skript.conditions.base.PropertyCondition; import org.apache.commons.lang.StringUtils; @@ -50,7 +50,6 @@ public class CondMethodExists extends PropertyCondition { Skript.registerCondition(CondMethodExists.class, "method[s] %strings% [dont:do(esn't|n't)] exist[s]"); } - @SuppressWarnings("NotNullFieldNotInitialized") private Expression signatures; @Override From f603a73ec4e9961d5e0ad0ea3f884c933500be02 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 22 Feb 2023 18:36:24 -0700 Subject: [PATCH 31/33] Add package infos --- .../test/tests/aliases/package-info.java | 24 +++++++++++++++++++ .../test/tests/classes/package-info.java | 24 +++++++++++++++++++ .../test/tests/config/package-info.java | 24 +++++++++++++++++++ .../test/tests/localization/package-info.java | 24 +++++++++++++++++++ .../test/tests/regression/package-info.java | 24 +++++++++++++++++++ .../test/tests/syntaxes/package-info.java | 24 +++++++++++++++++++ .../skript/test/tests/utils/package-info.java | 24 +++++++++++++++++++ 7 files changed, 168 insertions(+) create mode 100644 src/test/java/org/skriptlang/skript/test/tests/aliases/package-info.java create mode 100644 src/test/java/org/skriptlang/skript/test/tests/classes/package-info.java create mode 100644 src/test/java/org/skriptlang/skript/test/tests/config/package-info.java create mode 100644 src/test/java/org/skriptlang/skript/test/tests/localization/package-info.java create mode 100644 src/test/java/org/skriptlang/skript/test/tests/regression/package-info.java create mode 100644 src/test/java/org/skriptlang/skript/test/tests/syntaxes/package-info.java create mode 100644 src/test/java/org/skriptlang/skript/test/tests/utils/package-info.java diff --git a/src/test/java/org/skriptlang/skript/test/tests/aliases/package-info.java b/src/test/java/org/skriptlang/skript/test/tests/aliases/package-info.java new file mode 100644 index 00000000000..9abed714d99 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/aliases/package-info.java @@ -0,0 +1,24 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +@NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) +package org.skriptlang.skript.test.tests.aliases; + +import org.eclipse.jdt.annotation.DefaultLocation; +import org.eclipse.jdt.annotation.NonNullByDefault; + diff --git a/src/test/java/org/skriptlang/skript/test/tests/classes/package-info.java b/src/test/java/org/skriptlang/skript/test/tests/classes/package-info.java new file mode 100644 index 00000000000..27c021a95b0 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/classes/package-info.java @@ -0,0 +1,24 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +@NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) +package org.skriptlang.skript.test.tests.classes; + +import org.eclipse.jdt.annotation.DefaultLocation; +import org.eclipse.jdt.annotation.NonNullByDefault; + diff --git a/src/test/java/org/skriptlang/skript/test/tests/config/package-info.java b/src/test/java/org/skriptlang/skript/test/tests/config/package-info.java new file mode 100644 index 00000000000..f32c2844ba2 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/config/package-info.java @@ -0,0 +1,24 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +@NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) +package org.skriptlang.skript.test.tests.config; + +import org.eclipse.jdt.annotation.DefaultLocation; +import org.eclipse.jdt.annotation.NonNullByDefault; + diff --git a/src/test/java/org/skriptlang/skript/test/tests/localization/package-info.java b/src/test/java/org/skriptlang/skript/test/tests/localization/package-info.java new file mode 100644 index 00000000000..bfc35002b56 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/localization/package-info.java @@ -0,0 +1,24 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +@NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) +package org.skriptlang.skript.test.tests.localization; + +import org.eclipse.jdt.annotation.DefaultLocation; +import org.eclipse.jdt.annotation.NonNullByDefault; + diff --git a/src/test/java/org/skriptlang/skript/test/tests/regression/package-info.java b/src/test/java/org/skriptlang/skript/test/tests/regression/package-info.java new file mode 100644 index 00000000000..8225d91b19e --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/regression/package-info.java @@ -0,0 +1,24 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +@NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) +package org.skriptlang.skript.test.tests.regression; + +import org.eclipse.jdt.annotation.DefaultLocation; +import org.eclipse.jdt.annotation.NonNullByDefault; + diff --git a/src/test/java/org/skriptlang/skript/test/tests/syntaxes/package-info.java b/src/test/java/org/skriptlang/skript/test/tests/syntaxes/package-info.java new file mode 100644 index 00000000000..1a7edcf6847 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/syntaxes/package-info.java @@ -0,0 +1,24 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +@NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) +package org.skriptlang.skript.test.tests.syntaxes; + +import org.eclipse.jdt.annotation.DefaultLocation; +import org.eclipse.jdt.annotation.NonNullByDefault; + diff --git a/src/test/java/org/skriptlang/skript/test/tests/utils/package-info.java b/src/test/java/org/skriptlang/skript/test/tests/utils/package-info.java new file mode 100644 index 00000000000..a02dc136ec8 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/utils/package-info.java @@ -0,0 +1,24 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +@NonNullByDefault({DefaultLocation.PARAMETER, DefaultLocation.RETURN_TYPE, DefaultLocation.FIELD}) +package org.skriptlang.skript.test.tests.utils; + +import org.eclipse.jdt.annotation.DefaultLocation; +import org.eclipse.jdt.annotation.NonNullByDefault; + From f906ab67042e7d5abf28b6f0918d1183edb92fc7 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 22 Feb 2023 19:30:12 -0700 Subject: [PATCH 32/33] Fix skript dev mode not working --- src/main/java/ch/njol/skript/Skript.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 9099e87d280..251c4d9afe3 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -653,6 +653,7 @@ protected void afterErrors() { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "skript gen-docs"); } else if (TestMode.DEV_MODE) { // Developer controlled environment. info("Test development mode enabled. Test scripts are at " + TestMode.TEST_DIR); + return; } else { info("Loading all tests from " + TestMode.TEST_DIR); From 93e336eb3388c087733343ebe82b8e413a5f8df7 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Thu, 23 Feb 2023 04:04:22 -0700 Subject: [PATCH 33/33] license --- build.gradle | 3 ++- .../test/tests/localization/UtilsPlurals.java | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 47813aed9c8..fff7d4c2e69 100644 --- a/build.gradle +++ b/build.gradle @@ -56,7 +56,7 @@ task checkAliases { } task testJar(type: ShadowJar) { - dependsOn(compileTestJava) + dependsOn(compileTestJava, licenseTest) archiveName 'Skript-JUnit.jar' from sourceSets.test.output, sourceSets.main.output, project.configurations.testShadow } @@ -184,6 +184,7 @@ tasks.register('testNaming') { void createTestTask(String name, String desc, String environment, boolean devMode, int javaVersion, boolean genDocs, boolean junit) { tasks.register(name, JavaExec) { description = desc; + dependsOn licenseTest if (junit) { dependsOn testJar } else { diff --git a/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java b/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java index fb14d1212ea..716f11e2d26 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java +++ b/src/test/java/org/skriptlang/skript/test/tests/localization/UtilsPlurals.java @@ -1,3 +1,21 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ package org.skriptlang.skript.test.tests.localization; import static org.junit.Assert.assertEquals;