refactor(config): complete rewrite of configuration system
BREAKING CHANGE: New section-based configuration format New Features: - Type-safe BlockKey sealed interface (Vanilla, Oraxen, ItemsAdder) - Section-based config: RegionConfig, BlockConfig, ResetConfig, RewardConfig, UIConfig, TeleportConfig - Human-readable durations: 5m, 30s, 2h, 1d - YAML inheritance from defaults.yml - MiniMessage support for action bar and item names - Immutable config records with validation Removed: - Legacy MineConfig (17-field god object) - ConfigParser, ConfigValidator, ConfigSerializer split classes - Legacy FillMode enum (replaced with better version) - Old ConfigLoader with complex parsing logic New Files: - data/config/block/BlockKey.java - sealed interface for block types - data/config/block/BlockConfig.java - type-safe block weights - data/config/block/FillMode.java - fill strategies - data/config/region/RegionConfig.java - region management - data/config/reset/ResetConfig.java - reset behavior with Duration - data/config/reward/RewardConfig.java - rewards with ItemReward - data/config/teleport/TeleportConfig.java - teleport on reset - data/config/ui/UIConfig.java - action bar and messages - data/config/MineConfig.java - composed from sections - data/config/ConfigLoader.java - clean loader with defaults inheritance - defaults.yml - default configuration template Tests: - BlockKeyTest.java - serialization/deserialization - BlockConfigTest.java - weight normalization, validation - ResetConfigTest.java - duration parsing, defaults - UIConfigTest.java - timer formatting, action bar - MineConfigTest.java - builder, defaults, validation
This commit is contained in:
parent
f4e9458544
commit
f1060f34d4
22 changed files with 2012 additions and 896 deletions
191
src/test/java/dev/loki/lomines/data/config/MineConfigTest.java
Normal file
191
src/test/java/dev/loki/lomines/data/config/MineConfigTest.java
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
package dev.loki.lomines.data.config;
|
||||
|
||||
import dev.loki.lomines.data.config.block.BlockConfig;
|
||||
import dev.loki.lomines.data.config.block.BlockKey;
|
||||
import dev.loki.lomines.data.config.block.FillMode;
|
||||
import dev.loki.lomines.data.config.region.RegionConfig;
|
||||
import dev.loki.lomines.data.config.reset.ResetConfig;
|
||||
import dev.loki.lomines.data.config.reward.RewardConfig;
|
||||
import dev.loki.lomines.data.config.teleport.TeleportConfig;
|
||||
import dev.loki.lomines.data.config.ui.UIConfig;
|
||||
import dev.loki.lomines.util.location.Cuboid;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class MineConfigTest {
|
||||
|
||||
@Test
|
||||
void testBuilder() {
|
||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("world");
|
||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("world")).thenReturn(world);
|
||||
|
||||
Location loc1 = new Location(world, 0, 64, 0);
|
||||
Location loc2 = new Location(world, 10, 74, 10);
|
||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
||||
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
||||
|
||||
MineConfig config = MineConfig.builder("testmine")
|
||||
.region(region)
|
||||
.blocks(blocks)
|
||||
.reset(ResetConfig.defaults())
|
||||
.rewards(RewardConfig.empty())
|
||||
.teleport(TeleportConfig.disabled())
|
||||
.ui(UIConfig.defaults())
|
||||
.build();
|
||||
|
||||
assertEquals("testmine", config.name());
|
||||
assertEquals(1, config.region().regionCount());
|
||||
assertEquals(1, config.blocks().blockCount());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultsFactory() {
|
||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("world");
|
||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("world")).thenReturn(world);
|
||||
|
||||
Location loc1 = new Location(world, 0, 64, 0);
|
||||
Location loc2 = new Location(world, 10, 74, 10);
|
||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
||||
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
||||
|
||||
MineConfig config = MineConfig.defaults("mymine", region, blocks);
|
||||
|
||||
assertEquals("mymine", config.name());
|
||||
assertNotNull(config.reset());
|
||||
assertNotNull(config.rewards());
|
||||
assertNotNull(config.teleport());
|
||||
assertNotNull(config.ui());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNameNormalized() {
|
||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("world");
|
||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("world")).thenReturn(world);
|
||||
|
||||
Location loc1 = new Location(world, 0, 64, 0);
|
||||
Location loc2 = new Location(world, 10, 74, 10);
|
||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
||||
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
||||
|
||||
MineConfig config = MineConfig.builder("TestMine_123 ")
|
||||
.region(region)
|
||||
.blocks(blocks)
|
||||
.build();
|
||||
|
||||
assertEquals("testmine_123", config.name());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullNameThrows() {
|
||||
assertThrows(NullPointerException.class, () ->
|
||||
MineConfig.builder(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBlankNameThrows() {
|
||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("world");
|
||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("world")).thenReturn(world);
|
||||
|
||||
Location loc1 = new Location(world, 0, 64, 0);
|
||||
Location loc2 = new Location(world, 10, 74, 10);
|
||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
||||
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
MineConfig.builder(" ")
|
||||
.region(region)
|
||||
.blocks(blocks)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullRegionThrows() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
||||
|
||||
assertThrows(NullPointerException.class, () ->
|
||||
MineConfig.builder("test")
|
||||
.region(null)
|
||||
.blocks(blocks)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullBlocksThrows() {
|
||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("world");
|
||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("world")).thenReturn(world);
|
||||
|
||||
Location loc1 = new Location(world, 0, 64, 0);
|
||||
Location loc2 = new Location(world, 10, 74, 10);
|
||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
||||
|
||||
assertThrows(NullPointerException.class, () ->
|
||||
MineConfig.builder("test")
|
||||
.region(region)
|
||||
.blocks(null)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWorldNameDelegation() {
|
||||
try (MockedStatic<org.bukkit.Bukkit> bukkit = Mockito.mockStatic(org.bukkit.Bukkit.class)) {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("nether");
|
||||
bukkit.when(() -> org.bukkit.Bukkit.getWorld("nether")).thenReturn(world);
|
||||
|
||||
Location loc1 = new Location(world, 0, 64, 0);
|
||||
Location loc2 = new Location(world, 10, 74, 10);
|
||||
RegionConfig region = RegionConfig.fromSelections(List.of(loc1, loc2));
|
||||
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||
BlockConfig blocks = new BlockConfig(weights, FillMode.CUBOID, null);
|
||||
|
||||
MineConfig config = MineConfig.builder("test")
|
||||
.region(region)
|
||||
.blocks(blocks)
|
||||
.build();
|
||||
|
||||
assertEquals("nether", config.worldName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
package dev.loki.lomines.data.config.block;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class BlockConfigTest {
|
||||
|
||||
@Test
|
||||
void testValidConfig() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 50.0);
|
||||
weights.put(new BlockKey.Vanilla(Material.DIRT), 30.0);
|
||||
weights.put(new BlockKey.Vanilla(Material.COAL_ORE), 20.0);
|
||||
|
||||
BlockConfig config = new BlockConfig(weights, FillMode.CUBOID, null);
|
||||
|
||||
assertEquals(3, config.blockCount());
|
||||
assertFalse(config.hasCustomBlocks());
|
||||
assertEquals(FillMode.CUBOID, config.fillMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWeightsAreNormalized() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||
weights.put(new BlockKey.Vanilla(Material.DIRT), 100.0);
|
||||
|
||||
BlockConfig config = new BlockConfig(weights, FillMode.CUBOID, null);
|
||||
|
||||
// Should be normalized to sum to 1.0
|
||||
double stoneWeight = config.weightFor(new BlockKey.Vanilla(Material.STONE));
|
||||
double dirtWeight = config.weightFor(new BlockKey.Vanilla(Material.DIRT));
|
||||
|
||||
assertEquals(0.5, stoneWeight, 0.001);
|
||||
assertEquals(0.5, dirtWeight, 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyConfigThrows() {
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
new BlockConfig(Map.of(), FillMode.CUBOID, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNegativeWeightThrows() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), -10.0);
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
new BlockConfig(weights, FillMode.CUBOID, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testZeroWeightThrows() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 0.0);
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
new BlockConfig(weights, FillMode.CUBOID, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullWeightThrows() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), null);
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
new BlockConfig(weights, FillMode.CUBOID, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullBlockKeyThrows() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(null, 50.0);
|
||||
|
||||
assertThrows(NullPointerException.class, () ->
|
||||
new BlockConfig(weights, FillMode.CUBOID, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCustomBlocksDetected() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 50.0);
|
||||
weights.put(new BlockKey.Oraxen("ruby_ore"), 50.0);
|
||||
|
||||
BlockConfig config = new BlockConfig(weights, FillMode.CUBOID, null);
|
||||
assertTrue(config.hasCustomBlocks());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVanillaOnlyFactory() {
|
||||
Map<Material, Double> materials = new HashMap<>();
|
||||
materials.put(Material.STONE, 60.0);
|
||||
materials.put(Material.DIRT, 40.0);
|
||||
|
||||
BlockConfig config = BlockConfig.vanilla(materials);
|
||||
|
||||
assertEquals(2, config.blockCount());
|
||||
assertFalse(config.hasCustomBlocks());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testImmutableWeights() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||
|
||||
BlockConfig config = new BlockConfig(weights, FillMode.CUBOID, null);
|
||||
|
||||
// Try to modify the returned map
|
||||
Map<BlockKey, Double> returnedWeights = config.weights();
|
||||
assertThrows(UnsupportedOperationException.class, () ->
|
||||
returnedWeights.put(new BlockKey.Vanilla(Material.DIRT), 50.0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMaskConfig() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||
|
||||
BlockKey marker = new BlockKey.Vanilla(Material.PINK_CONCRETE);
|
||||
Map<String, Boolean> positions = new HashMap<>();
|
||||
positions.put("world;10;64;10;0;0", true);
|
||||
|
||||
BlockConfig.MaskConfig mask = new BlockConfig.MaskConfig(marker, positions);
|
||||
BlockConfig config = new BlockConfig(weights, FillMode.MASK, mask);
|
||||
|
||||
assertEquals(FillMode.MASK, config.fillMode());
|
||||
assertNotNull(config.mask());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFillModeNullThrows() {
|
||||
Map<BlockKey, Double> weights = new HashMap<>();
|
||||
weights.put(new BlockKey.Vanilla(Material.STONE), 100.0);
|
||||
|
||||
assertThrows(NullPointerException.class, () ->
|
||||
new BlockConfig(weights, null, null));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package dev.loki.lomines.data.config.block;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class BlockKeyTest {
|
||||
|
||||
@Test
|
||||
void testVanillaSerialization() {
|
||||
BlockKey.Vanilla stone = new BlockKey.Vanilla(Material.STONE);
|
||||
assertEquals("stone", stone.serialize());
|
||||
|
||||
BlockKey.Vanilla diamondOre = new BlockKey.Vanilla(Material.DIAMOND_ORE);
|
||||
assertEquals("diamond_ore", diamondOre.serialize());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOraxenSerialization() {
|
||||
BlockKey.Oraxen custom = new BlockKey.Oraxen("ruby_ore");
|
||||
assertEquals("oraxen:ruby_ore", custom.serialize());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testItemsAdderSerialization() {
|
||||
BlockKey.ItemsAdder custom = new BlockKey.ItemsAdder("mythic_block");
|
||||
assertEquals("itemsadder:mythic_block", custom.serialize());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeserializeVanilla() {
|
||||
BlockKey key = BlockKey.deserialize("stone");
|
||||
assertInstanceOf(BlockKey.Vanilla.class, key);
|
||||
assertEquals(Material.STONE, ((BlockKey.Vanilla) key).material());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeserializeOraxen() {
|
||||
BlockKey key = BlockKey.deserialize("oraxen:custom_block");
|
||||
assertInstanceOf(BlockKey.Oraxen.class, key);
|
||||
assertEquals("custom_block", ((BlockKey.Oraxen) key).id());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeserializeItemsAdder() {
|
||||
BlockKey key = BlockKey.deserialize("itemsadder:mythic_ore");
|
||||
assertInstanceOf(BlockKey.ItemsAdder.class, key);
|
||||
assertEquals("mythic_ore", ((BlockKey.ItemsAdder) key).id());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeserializeNullThrows() {
|
||||
assertThrows(IllegalArgumentException.class, () -> BlockKey.deserialize(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeserializeEmptyThrows() {
|
||||
assertThrows(IllegalArgumentException.class, () -> BlockKey.deserialize(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeserializeBlankThrows() {
|
||||
assertThrows(IllegalArgumentException.class, () -> BlockKey.deserialize(" "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeserializeUnknownVanillaThrows() {
|
||||
assertThrows(IllegalArgumentException.class, () -> BlockKey.deserialize("not_a_real_block"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVanillaNotBlockThrows() {
|
||||
assertThrows(IllegalArgumentException.class, () -> new BlockKey.Vanilla(Material.DIAMOND));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOraxenNullIdThrows() {
|
||||
assertThrows(NullPointerException.class, () -> new BlockKey.Oraxen(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOraxenBlankIdThrows() {
|
||||
assertThrows(IllegalArgumentException.class, () -> new BlockKey.Oraxen(" "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testItemsAdderEmptyIdThrows() {
|
||||
assertThrows(IllegalArgumentException.class, () -> new BlockKey.ItemsAdder(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCaseInsensitiveDeserialization() {
|
||||
BlockKey key1 = BlockKey.deserialize("STONE");
|
||||
BlockKey key2 = BlockKey.deserialize("stone");
|
||||
BlockKey key3 = BlockKey.deserialize("StOnE");
|
||||
|
||||
assertEquals(key1.serialize(), key2.serialize());
|
||||
assertEquals(key2.serialize(), key3.serialize());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquality() {
|
||||
BlockKey a = new BlockKey.Vanilla(Material.STONE);
|
||||
BlockKey b = new BlockKey.Vanilla(Material.STONE);
|
||||
BlockKey c = new BlockKey.Vanilla(Material.DIRT);
|
||||
|
||||
assertEquals(a, b);
|
||||
assertEquals(a.hashCode(), b.hashCode());
|
||||
assertNotEquals(a, c);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
package dev.loki.lomines.data.config.reset;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ResetConfigTest {
|
||||
|
||||
@Test
|
||||
void testDefaultConfig() {
|
||||
ResetConfig config = ResetConfig.defaults();
|
||||
|
||||
assertEquals(Duration.ofMinutes(5), config.interval());
|
||||
assertEquals(10.0, config.percentTrigger());
|
||||
assertFalse(config.percentEnabled());
|
||||
assertTrue(config.commands().isEmpty());
|
||||
assertEquals("", config.broadcastMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuilder() {
|
||||
ResetConfig config = ResetConfig.builder()
|
||||
.interval("10m")
|
||||
.percentTrigger(25.0)
|
||||
.percentEnabled(true)
|
||||
.commands(List.of("broadcast Reset!", "eco give %player% 10"))
|
||||
.broadcastMessage("Mine reset!")
|
||||
.build();
|
||||
|
||||
assertEquals(Duration.ofMinutes(10), config.interval());
|
||||
assertEquals(25.0, config.percentTrigger());
|
||||
assertTrue(config.percentEnabled());
|
||||
assertEquals(2, config.commands().size());
|
||||
assertEquals("Mine reset!", config.broadcastMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuilderWithTicks() {
|
||||
ResetConfig config = ResetConfig.builder()
|
||||
.intervalTicks(1200) // 60 seconds
|
||||
.build();
|
||||
|
||||
assertEquals(Duration.ofSeconds(60), config.interval());
|
||||
assertEquals(1200, config.intervalTicks());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIntervalParsing() {
|
||||
assertEquals(Duration.ofSeconds(30), ResetConfig.builder().interval("30s").build().interval());
|
||||
assertEquals(Duration.ofMinutes(5), ResetConfig.builder().interval("5m").build().interval());
|
||||
assertEquals(Duration.ofHours(2), ResetConfig.builder().interval("2h").build().interval());
|
||||
assertEquals(Duration.ofDays(1), ResetConfig.builder().interval("1d").build().interval());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInvalidIntervalDefaultsToFiveMinutes() {
|
||||
ResetConfig config = ResetConfig.builder()
|
||||
.interval("invalid")
|
||||
.build();
|
||||
|
||||
assertEquals(ResetConfig.DEFAULT_INTERVAL, config.interval());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNegativeIntervalDefaults() {
|
||||
ResetConfig config = new ResetConfig(
|
||||
Duration.ofSeconds(-10),
|
||||
10.0,
|
||||
false,
|
||||
List.of(),
|
||||
""
|
||||
);
|
||||
|
||||
assertEquals(ResetConfig.DEFAULT_INTERVAL, config.interval());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testZeroIntervalDefaults() {
|
||||
ResetConfig config = new ResetConfig(
|
||||
Duration.ZERO,
|
||||
10.0,
|
||||
false,
|
||||
List.of(),
|
||||
""
|
||||
);
|
||||
|
||||
assertEquals(ResetConfig.DEFAULT_INTERVAL, config.interval());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTooShortIntervalClamped() {
|
||||
ResetConfig config = ResetConfig.builder()
|
||||
.interval("0.5s")
|
||||
.build();
|
||||
|
||||
assertEquals(Duration.ofSeconds(1), config.interval());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTooLongIntervalClamped() {
|
||||
ResetConfig config = ResetConfig.builder()
|
||||
.interval("48h")
|
||||
.build();
|
||||
|
||||
assertEquals(Duration.ofHours(24), config.interval());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInvalidPercentTriggerClamped() {
|
||||
ResetConfig negative = new ResetConfig(
|
||||
Duration.ofMinutes(5),
|
||||
-10.0,
|
||||
false,
|
||||
List.of(),
|
||||
""
|
||||
);
|
||||
assertEquals(ResetConfig.DEFAULT_PERCENT_TRIGGER, negative.percentTrigger());
|
||||
|
||||
ResetConfig over100 = new ResetConfig(
|
||||
Duration.ofMinutes(5),
|
||||
150.0,
|
||||
false,
|
||||
List.of(),
|
||||
""
|
||||
);
|
||||
assertEquals(ResetConfig.DEFAULT_PERCENT_TRIGGER, over100.percentTrigger());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIntervalDisplay() {
|
||||
assertEquals("30s", new ResetConfig(Duration.ofSeconds(30), 10.0, false, List.of(), "").intervalDisplay());
|
||||
assertEquals("5m", new ResetConfig(Duration.ofMinutes(5), 10.0, false, List.of(), "").intervalDisplay());
|
||||
assertEquals("2h", new ResetConfig(Duration.ofHours(2), 10.0, false, List.of(), "").intervalDisplay());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPercentTriggerEnabled() {
|
||||
assertFalse(ResetConfig.defaults().isPercentTriggerEnabled());
|
||||
assertFalse(new ResetConfig(Duration.ofMinutes(5), 10.0, false, List.of(), "").isPercentTriggerEnabled());
|
||||
assertTrue(new ResetConfig(Duration.ofMinutes(5), 10.0, true, List.of(), "").isPercentTriggerEnabled());
|
||||
assertFalse(new ResetConfig(Duration.ofMinutes(5), 0.0, true, List.of(), "").isPercentTriggerEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testImmutableCommands() {
|
||||
ResetConfig config = ResetConfig.builder()
|
||||
.commands(List.of("cmd1"))
|
||||
.build();
|
||||
|
||||
assertThrows(UnsupportedOperationException.class, () ->
|
||||
config.commands().add("cmd2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullCommandsDefaultsToEmpty() {
|
||||
ResetConfig config = new ResetConfig(
|
||||
Duration.ofMinutes(5),
|
||||
10.0,
|
||||
false,
|
||||
null,
|
||||
"test"
|
||||
);
|
||||
|
||||
assertTrue(config.commands().isEmpty());
|
||||
}
|
||||
}
|
||||
112
src/test/java/dev/loki/lomines/data/config/ui/UIConfigTest.java
Normal file
112
src/test/java/dev/loki/lomines/data/config/ui/UIConfigTest.java
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
package dev.loki.lomines.data.config.ui;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class UIConfigTest {
|
||||
|
||||
@Test
|
||||
void testDefaults() {
|
||||
UIConfig config = UIConfig.defaults();
|
||||
|
||||
assertTrue(config.actionBarEnabled());
|
||||
assertEquals(UIConfig.DEFAULT_ACTIONBAR_FORMAT, config.actionBarFormat());
|
||||
assertEquals(50.0, config.actionBarRange());
|
||||
assertEquals(UIConfig.DEFAULT_TIMER_FORMAT, config.timerFormat());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDisabled() {
|
||||
UIConfig config = UIConfig.disabled();
|
||||
|
||||
assertFalse(config.actionBarEnabled());
|
||||
assertEquals("", config.actionBarFormat());
|
||||
assertEquals(0, config.actionBarRange());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCustomConfig() {
|
||||
UIConfig config = new UIConfig(
|
||||
true,
|
||||
"<red>{mine}</red>",
|
||||
100.0,
|
||||
"HH:mm:ss"
|
||||
);
|
||||
|
||||
assertTrue(config.actionBarEnabled());
|
||||
assertEquals("<red>{mine}</red>", config.actionBarFormat());
|
||||
assertEquals(100.0, config.actionBarRange());
|
||||
assertEquals("HH:mm:ss", config.timerFormat());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullFormatDefaults() {
|
||||
UIConfig config = new UIConfig(true, null, 50.0, null);
|
||||
|
||||
assertEquals(UIConfig.DEFAULT_ACTIONBAR_FORMAT, config.actionBarFormat());
|
||||
assertEquals(UIConfig.DEFAULT_TIMER_FORMAT, config.timerFormat());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBlankFormatDefaults() {
|
||||
UIConfig config = new UIConfig(true, " ", 50.0, " ");
|
||||
|
||||
assertEquals(UIConfig.DEFAULT_ACTIONBAR_FORMAT, config.actionBarFormat());
|
||||
assertEquals(UIConfig.DEFAULT_TIMER_FORMAT, config.timerFormat());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNegativeRangeClamped() {
|
||||
UIConfig config = new UIConfig(true, "test", -10.0, "mm:ss");
|
||||
|
||||
assertEquals(1.0, config.actionBarRange());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRangeSquared() {
|
||||
UIConfig config = new UIConfig(true, "test", 50.0, "mm:ss");
|
||||
|
||||
assertEquals(2500.0, config.actionBarRangeSquared(), 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFormatActionBar() {
|
||||
UIConfig config = UIConfig.defaults();
|
||||
Component result = config.formatActionBar("TestMine", 50.5, "02:30", 500, 1000);
|
||||
|
||||
String serialized = MiniMessage.miniMessage().serialize(result);
|
||||
assertTrue(serialized.contains("TestMine"));
|
||||
assertTrue(serialized.contains("50.5"));
|
||||
assertTrue(serialized.contains("02:30"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFormatTimerMmSs() {
|
||||
UIConfig config = new UIConfig(true, "", 0, "mm:ss");
|
||||
|
||||
assertEquals("00:30", config.formatTimer(30));
|
||||
assertEquals("05:00", config.formatTimer(300));
|
||||
assertEquals("59:59", config.formatTimer(3599));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFormatTimerHhMmSs() {
|
||||
UIConfig config = new UIConfig(true, "", 0, "HH:mm:ss");
|
||||
|
||||
assertEquals("0:00:30", config.formatTimer(30));
|
||||
assertEquals("0:05:00", config.formatTimer(300));
|
||||
assertEquals("1:00:00", config.formatTimer(3600));
|
||||
assertEquals("2:30:45", config.formatTimer(9045));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFormatTimerDefault() {
|
||||
UIConfig config = UIConfig.defaults();
|
||||
|
||||
assertEquals("02:30", config.formatTimer(150));
|
||||
assertEquals("10:00", config.formatTimer(600));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue