Skip to content

Commit

Permalink
Update dependencies, require 1.20.6
Browse files Browse the repository at this point in the history
  • Loading branch information
Jikoo committed Jun 14, 2024
1 parent 58ccdaa commit bb95465
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 22 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.20.6-R0.1-SNAPSHOT</version>
<version>1.21-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand All @@ -99,7 +99,7 @@
<dependency>
<groupId>com.github.jikoo</groupId>
<artifactId>planarwrappers</artifactId>
<version>3.2.2</version>
<version>3.2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: EnchantableBlocks
main: com.github.jikoo.enchantableblocks.EnchantableBlocksPlugin
version: ${project.version}
author: Jikoo
api-version: "1.18"
api-version: "1.20.6"
libraries:
- it.unimi.dsi:fastutil:${versions.fastutil}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;

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;
Expand All @@ -17,7 +19,6 @@
import org.bukkit.Server;
import org.bukkit.Tag;
import org.jetbrains.annotations.NotNull;
import org.mockito.Answers;

public final class ServerMocks {

Expand All @@ -26,28 +27,44 @@ public final class ServerMocks {

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

// 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.
// The mock registry can later be more specifically modified as necessary.
doAnswer(invocationGetRegistry -> {
// This must be mocked here or else Registry will be initialized when mocking it.
Registry<?> registry = mock();
doAnswer(invocationGetEntry -> {
NamespacedKey key = invocationGetEntry.getArgument(0);
// Set registries to always return a new value so that any constants are initialized.
Class<? extends Keyed> arg = invocationGetRegistry.getArgument(0);
// Deep stubs aren't great, but Bukkit has a lot of nullity checks on new constants.
Keyed keyed = mock(arg, withSettings().defaultAnswer(Answers.RETURNS_DEEP_STUBS));
doReturn(key).when(keyed).getKey();
// It may eventually be necessary to stub BlockType#typed() here, but deep stubs work for now.
return keyed;
}).when(registry).get(notNull());
return registry;
}).when(mock).getRegistry(notNull());
Map<Class<? extends Keyed>, Object> registers = new HashMap<>();

doAnswer(invocationGetRegistry ->
registers.computeIfAbsent(invocationGetRegistry.getArgument(0), clazz -> {
Registry<?> registry = mock();
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
Expand All @@ -68,6 +85,15 @@ public final class ServerMocks {
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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ public final class ItemFactoryMocks {
when(factory.isApplicable(any(ItemMeta.class), any(Material.class))).thenReturn(true);
when(factory.isApplicable(any(ItemMeta.class), any(ItemStack.class)))
.thenAnswer(invocation -> factory.isApplicable(invocation.getArgument(0), invocation.getArgument(1, ItemStack.class).getType()));
when(factory.updateMaterial(any(ItemMeta.class), any(Material.class))).thenAnswer(invocation -> invocation.getArgument(1));

return factory;
}
Expand Down

0 comments on commit bb95465

Please sign in to comment.