1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-20 11:45:51 +00:00

Added Unit Test and loop detection

This commit is contained in:
TheBusyBiscuit 2020-09-07 01:13:25 +02:00
parent 773996617d
commit 06498e3f63
9 changed files with 123 additions and 22 deletions

View File

@ -28,6 +28,7 @@ import io.github.thebusybiscuit.cscorelib2.protection.ProtectionManager;
import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.api.gps.GPSNetwork;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry;
@ -96,6 +97,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.setup.SlimefunItemSetup
import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import io.papermc.lib.PaperLib;
import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
@ -174,7 +176,6 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
}
else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) {
long timestamp = System.nanoTime();
PaperLib.suggestPaper(this);
// We wanna ensure that the Server uses a compatible version of Minecraft
@ -228,6 +229,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
getLogger().log(Level.INFO, "Loading GEO-Resources...");
GEOResourcesSetup.setup();
getLogger().log(Level.INFO, "Loading Tags...");
loadTags();
getLogger().log(Level.INFO, "Loading items...");
loadItems();
@ -492,6 +496,17 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new PlayerProfileListener(this);
}
private void loadTags() {
for (SlimefunTag tag : SlimefunTag.values()) {
try {
tag.reload();
}
catch (TagMisconfigurationException e) {
getLogger().log(Level.SEVERE, "Failed to load a Tag!", e);
}
}
}
private void loadItems() {
try {
SlimefunItemSetup.setup(this);

View File

@ -23,7 +23,6 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.AutomatedCraftingChamber;
@ -32,7 +31,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.Grind
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.MakeshiftSmeltery;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.OreCrusher;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.Smeltery;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.Item.CustomItemSerializer;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.Item.CustomItemSerializer.ItemFlag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -45,22 +43,8 @@ public final class PostSetup {
private PostSetup() {}
public static void loadTags() {
Slimefun.getLogger().log(Level.INFO, "Loading Tags...");
for (SlimefunTag tag : SlimefunTag.values()) {
try {
tag.reload();
}
catch (TagMisconfigurationException e) {
Slimefun.getLogger().log(Level.SEVERE, "Failed to load a Tag!", e);
}
}
}
public static void setupWiki() {
Slimefun.getLogger().log(Level.INFO, "Loading Wiki pages...");
JsonParser parser = new JsonParser();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(SlimefunPlugin.class.getResourceAsStream("/wiki.json"), StandardCharsets.UTF_8))) {

View File

@ -98,6 +98,11 @@ public enum SlimefunTag implements Tag<Material> {
}
}
@Nonnull
public Set<Tag<Material>> getSubTags() {
return Collections.unmodifiableSet(additionalTags);
}
/**
* This method returns an Array representation for this {@link SlimefunTag}.
*

View File

@ -88,7 +88,7 @@ class TagParser implements Keyed {
}
}
else if (PatternUtils.MINECRAFT_TAG.matcher(value).matches()) {
String keyValue = PatternUtils.COLON.split(value)[1].toUpperCase(Locale.ROOT);
String keyValue = PatternUtils.COLON.split(value)[1];
NamespacedKey namespacedKey = NamespacedKey.minecraft(keyValue);
Tag<Material> itemsTag = Bukkit.getTag(Tag.REGISTRY_ITEMS, namespacedKey, Material.class);
Tag<Material> blocksTag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, namespacedKey, Material.class);

View File

@ -15,7 +15,6 @@
"minecraft:brown_concrete_powder",
"minecraft:green_concrete_powder",
"minecraft:red_concrete_powder",
"minecraft:black_concrete_powder",
"minecraft:legacy_concrete_powder"
"minecraft:black_concrete_powder"
]
}

View File

@ -1,6 +1,10 @@
{
"values" : [
"#minecraft:gold_ores",
{
"id" : "#minecraft:gold_ores",
"required" : false
},
"minecraft:gold_ore",
"minecraft:iron_ore",
"minecraft:coal_ore",
"minecraft:lapis_ore",

View File

@ -3,7 +3,7 @@
"#minecraft:saplings",
"#minecraft:wooden_pressure_plates",
"minecraft:stone_pressure_plate",
"minecraft:light_pressure_plate",
"minecraft:light_weighted_pressure_plate",
"minecraft:heavy_weighted_pressure_plate",
"minecraft:cake"
]

View File

@ -73,7 +73,9 @@ public final class TestUtilities {
public static void registerDefaultTags(ServerMock server) {
// We really don't need these to be accurate, just fill them with some examples
// that approximate the actual content
server.createMaterialTag(NamespacedKey.minecraft("dirt_like"), Material.DIRT, Material.PODZOL, Material.MYCELIUM);
server.createMaterialTag(NamespacedKey.minecraft("logs"), Material.OAK_LOG, Material.STRIPPED_OAK_LOG, Material.OAK_WOOD, Material.STRIPPED_OAK_WOOD, Material.ACACIA_LOG, Material.STRIPPED_ACACIA_LOG, Material.ACACIA_WOOD, Material.STRIPPED_ACACIA_WOOD);
server.createMaterialTag(NamespacedKey.minecraft("wooden_pressure_plates"), Material.OAK_PRESSURE_PLATE, Material.BIRCH_PRESSURE_PLATE, Material.SPRUCE_PRESSURE_PLATE, Material.JUNGLE_PRESSURE_PLATE, Material.ACACIA_PRESSURE_PLATE, Material.DARK_OAK_PRESSURE_PLATE);
server.createMaterialTag(NamespacedKey.minecraft("wooden_trapdoors"), Material.OAK_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.ACACIA_TRAPDOOR, Material.DARK_OAK_TRAPDOOR);
server.createMaterialTag(NamespacedKey.minecraft("wooden_slabs"), Material.OAK_SLAB, Material.BIRCH_SLAB, Material.JUNGLE_SLAB, Material.SPRUCE_SLAB, Material.ACACIA_SLAB, Material.DARK_OAK_SLAB);
server.createMaterialTag(NamespacedKey.minecraft("wooden_fences"), Material.OAK_FENCE, Material.BIRCH_FENCE, Material.JUNGLE_FENCE, Material.SPRUCE_FENCE, Material.ACACIA_FENCE, Material.DARK_OAK_FENCE);
@ -83,6 +85,9 @@ public final class TestUtilities {
server.createMaterialTag(NamespacedKey.minecraft("saplings"), Material.OAK_SAPLING, Material.BIRCH_SAPLING, Material.SPRUCE_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING);
server.createMaterialTag(NamespacedKey.minecraft("coral_blocks"), Material.BRAIN_CORAL_BLOCK, Material.BUBBLE_CORAL_BLOCK, Material.FIRE_CORAL_BLOCK, Material.HORN_CORAL_BLOCK, Material.TUBE_CORAL_BLOCK);
server.createMaterialTag(NamespacedKey.minecraft("corals"), Material.BRAIN_CORAL, Material.BUBBLE_CORAL, Material.FIRE_CORAL, Material.HORN_CORAL, Material.TUBE_CORAL);
server.createMaterialTag(NamespacedKey.minecraft("gold_ores"), Material.GOLD_ORE);
server.createMaterialTag(NamespacedKey.minecraft("sand"), Material.SAND, Material.RED_SAND);
server.createMaterialTag(NamespacedKey.minecraft("crops"), Material.WHEAT, Material.CARROTS, Material.POTATOES, Material.BEETROOTS);
server.createMaterialTag(NamespacedKey.minecraft("ice"), Material.ICE, Material.PACKED_ICE, Material.FROSTED_ICE, Material.BLUE_ICE);
}

View File

@ -0,0 +1,89 @@
package io.github.thebusybiscuit.slimefun4.testing.tests.utils;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.testing.TestUtilities;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
class TestSlimefunTags {
@BeforeAll
public static void load() {
ServerMock server = MockBukkit.mock();
MockBukkit.load(SlimefunPlugin.class);
TestUtilities.registerDefaultTags(server);
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@Test
@DisplayName("Test for Exceptions with Slimefun Tags")
void testTags() {
for (SlimefunTag tag : SlimefunTag.values()) {
Assertions.assertDoesNotThrow(tag::reload);
}
}
@Test
@DisplayName("Test for infinite loops with Slimefun Tags")
void testForInfiniteLoops() throws TagMisconfigurationException {
for (SlimefunTag tag : SlimefunTag.values()) {
tag.reload();
}
for (SlimefunTag tag : SlimefunTag.values()) {
assertNotCyclic(tag);
}
}
private void assertNotCyclic(@Nonnull SlimefunTag tag) {
Set<SlimefunTag> visiting = new HashSet<>();
Set<SlimefunTag> visited = new HashSet<>();
if (isCyclic(visiting, visited, tag)) {
System.out.println("Currently visiting: " + visiting);
System.out.println("Previously visited" + visiting);
Assertions.fail("Tag '" + tag.getKey() + "' is cyclic!");
}
}
@ParametersAreNonnullByDefault
private boolean isCyclic(Set<SlimefunTag> visiting, Set<SlimefunTag> visited, SlimefunTag tag) {
visiting.add(tag);
for (Tag<Material> sub : tag.getSubTags()) {
if (sub instanceof SlimefunTag) {
if (visiting.contains(sub)) {
return true;
}
else if (!visited.contains(sub) && isCyclic(visiting, visited, (SlimefunTag) sub)) {
return true;
}
}
}
visiting.remove(tag);
visited.add(tag);
return false;
}
}