Skip to content

Commit

Permalink
New version 1.14.0 (#17)
Browse files Browse the repository at this point in the history
* Update pom.xml

* Update to Minecraft 1.18 biome changes

* Update pom.xml 1.13.0

* Update to latest Minecraft API

* Added test class

* Add distribution management section to POM

* Update to MC 1.21.4 and CodeMC changes (#16)

---------

Co-authored-by: BONNe <bonne@bonne.id.lv>
  • Loading branch information
tastybento and BONNe authored Nov 17, 2024
1 parent e4ede61 commit db9d8e3
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 10 deletions.
18 changes: 9 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,9 @@
</issueManagement>

<distributionManagement>
<snapshotRepository>
<id>codemc-snapshots</id>
<url>https://repo.codemc.org/repository/maven-snapshots</url>
</snapshotRepository>
<repository>
<id>codemc-releases</id>
<url>https://repo.codemc.org/repository/maven-releases</url>
<id>bentoboxworld</id>
<url>https://repo.codemc.org/repository/bentoboxworld</url>
</repository>
</distributionManagement>

Expand All @@ -46,8 +42,8 @@
<java.version>17</java.version>
<powermock.version>2.0.9</powermock.version>
<!-- More visible way how to change dependency versions -->
<spigot.version>1.20.4-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>2.0.0-SNAPSHOT</bentobox.version>
<spigot.version>1.21.3-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>2.7.1-SNAPSHOT</bentobox.version>
<!-- Revision variable removes warning about dynamic version -->
<revision>${build.version}-SNAPSHOT</revision>
<!-- This allows to change between versions and snapshots. -->
Expand All @@ -56,7 +52,7 @@
X.Y.Z -> BentoBox core version
.M -> Addon development iteration.
-->
<build.version>1.13</build.version>
<build.version>1.14.0</build.version>
<build.number>-LOCAL</build.number>
</properties>

Expand Down Expand Up @@ -107,6 +103,10 @@
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
</repository>
<repository>
<id>bentoboxworld</id>
<url>https://repo.codemc.org/repository/bentoboxworld/</url>
</repository>
<repository>
<id>codemc</id>
<url>https://repo.codemc.org/repository/maven-snapshots/</url>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,22 @@
import org.bukkit.entity.Fish;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.eclipse.jdt.annotation.NonNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.AddonDescription;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.extramobs.ExtraMobsAddon;
import world.bentobox.extramobs.config.Settings;
import world.bentobox.extramobs.listeners.mocks.ServerMocks;

@RunWith(PowerMockRunner.class)
public class MobsSpawnListenerTest {
Expand Down Expand Up @@ -64,6 +68,7 @@ public class MobsSpawnListenerTest {

@Before
public void setUp() {
ServerMocks.newServer();
settings = new Settings();
when(addon.getSettings()).thenReturn(settings);

Expand Down Expand Up @@ -93,6 +98,13 @@ public void setUp() {
listener = new MobsSpawnListener(addon);
}

@After
public void tearDown() {
ServerMocks.unsetBukkitServer();
User.clearUsers();
Mockito.framework().clearInlineMocks();
}

// Test case for natural spawning of Zombified Piglin in the Nether
@Test
public void testNaturalSpawnZombifiedPiglinNether() {
Expand Down Expand Up @@ -136,7 +148,6 @@ public void testFishSpawnDeepOcean() {
when(event.getSpawnReason()).thenReturn(CreatureSpawnEvent.SpawnReason.NATURAL);
when(event.getLocation()).thenReturn(location);
when(world.getEnvironment()).thenReturn(World.Environment.NORMAL);
when(world.getBiome(anyInt(), anyInt(), anyInt())).thenReturn(Biome.DEEP_OCEAN);
settings.setGuardianChance(1.1); // Set so that it will always spawn
when(block.getType()).thenReturn(Material.WATER, Material.WATER, Material.WATER, Material.PRISMARINE);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package world.bentobox.extramobs.listeners.mocks;

import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import org.bukkit.Bukkit;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.Server;
import org.bukkit.Tag;
import org.bukkit.UnsafeValues;
import org.eclipse.jdt.annotation.NonNull;

public final class ServerMocks {

public static @NonNull Server newServer() {
Server mock = mock(Server.class);

Logger noOp = mock(Logger.class);
when(mock.getLogger()).thenReturn(noOp);
when(mock.isPrimaryThread()).thenReturn(true);

// Unsafe
UnsafeValues unsafe = mock(UnsafeValues.class);
when(mock.getUnsafe()).thenReturn(unsafe);

// Server must be available before tags can be mocked.
Bukkit.setServer(mock);

// Bukkit has a lot of static constants referencing registry values. To initialize those, the
// registries must be able to be fetched before the classes are touched.
Map<Class<? extends Keyed>, Object> registers = new HashMap<>();

doAnswer(invocationGetRegistry -> registers.computeIfAbsent(invocationGetRegistry.getArgument(0), clazz -> {
Registry<?> registry = mock(Registry.class);
Map<NamespacedKey, Keyed> cache = new HashMap<>();
doAnswer(invocationGetEntry -> {
NamespacedKey key = invocationGetEntry.getArgument(0);
// Some classes (like BlockType and ItemType) have extra generics that will be
// erased during runtime calls. To ensure accurate typing, grab the constant's field.
// This approach also allows us to return null for unsupported keys.
Class<? extends Keyed> constantClazz;
try {
//noinspection unchecked
constantClazz = (Class<? extends Keyed>) clazz
.getField(key.getKey().toUpperCase(Locale.ROOT).replace('.', '_')).getType();
} catch (ClassCastException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
return null;
}

return cache.computeIfAbsent(key, key1 -> {
Keyed keyed = mock(constantClazz);
doReturn(key).when(keyed).getKey();
return keyed;
});
}).when(registry).get(notNull());
return registry;
})).when(mock).getRegistry(notNull());

// Tags are dependent on registries, but use a different method.
// This will set up blank tags for each constant; all that needs to be done to render them
// functional is to re-mock Tag#getValues.
doAnswer(invocationGetTag -> {
Tag<?> tag = mock(Tag.class);
doReturn(invocationGetTag.getArgument(1)).when(tag).getKey();
doReturn(Set.of()).when(tag).getValues();
doAnswer(invocationIsTagged -> {
Keyed keyed = invocationIsTagged.getArgument(0);
Class<?> type = invocationGetTag.getArgument(2);
if (!type.isAssignableFrom(keyed.getClass())) {
return null;
}
// Since these are mocks, the exact instance might not be equal. Consider equal keys equal.
return tag.getValues().contains(keyed)
|| tag.getValues().stream().anyMatch(value -> value.getKey().equals(keyed.getKey()));
}).when(tag).isTagged(notNull());
return tag;
}).when(mock).getTag(notNull(), notNull(), notNull());

// Once the server is all set up, touch BlockType and ItemType to initialize.
// This prevents issues when trying to access dependent methods from a Material constant.
try {
Class.forName("org.bukkit.inventory.ItemType");
Class.forName("org.bukkit.block.BlockType");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}

return mock;
}

public static void unsetBukkitServer() {
try {
Field server = Bukkit.class.getDeclaredField("server");
server.setAccessible(true);
server.set(null, null);
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}

private ServerMocks() {
}

}

0 comments on commit db9d8e3

Please sign in to comment.