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

Added Unit Tests for NetworkManager and Network class

This commit is contained in:
TheBusyBiscuit 2020-05-11 23:02:24 +02:00
parent 3597fc0388
commit d01a7d2186
9 changed files with 306 additions and 45 deletions

View File

@ -12,7 +12,6 @@ import org.bukkit.Particle.DustOptions;
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
@ -63,34 +62,54 @@ public abstract class Network {
protected Location regulator;
private Queue<Location> nodeQueue = new ArrayDeque<>();
protected Set<Location> connectedLocations = new HashSet<>();
protected Set<Location> regulatorNodes = new HashSet<>();
protected Set<Location> connectorNodes = new HashSet<>();
protected Set<Location> terminusNodes = new HashSet<>();
private final NetworkManager manager;
protected final Set<Location> connectedLocations = new HashSet<>();
protected final Set<Location> regulatorNodes = new HashSet<>();
protected final Set<Location> connectorNodes = new HashSet<>();
protected final Set<Location> terminusNodes = new HashSet<>();
protected Network(Location regulator) {
protected Network(NetworkManager manager, Location regulator) {
this.manager = manager;
this.regulator = regulator;
connectedLocations.add(regulator);
nodeQueue.add(regulator.clone());
}
/**
* This returns the size of this {@link Network}. It is equivalent to the amount
* of {@link Location Locations} connected to this {@link Network}.
*
* @return The size of this {@link Network}
*/
public int getSize() {
return regulatorNodes.size() + connectorNodes.size() + terminusNodes.size();
}
protected void addLocationToNetwork(Location l) {
if (connectedLocations.contains(l)) {
return;
}
connectedLocations.add(l.clone());
handleLocationUpdate(l);
markDirty(l);
}
public void handleLocationUpdate(Location l) {
/**
* This method marks the given {@link Location} as dirty and adds it to a {@link Queue}
* to handle this update.
*
* @param l
* The {@link Location} to update
*/
public void markDirty(Location l) {
if (regulator.equals(l)) {
SlimefunPlugin.getNetworkManager().unregisterNetwork(this);
return;
manager.unregisterNetwork(this);
}
else {
nodeQueue.add(l.clone());
}
}
/**
* This method checks whether the given {@link Location} is part of this {@link Network}.
@ -118,7 +137,7 @@ public abstract class Network {
}
private void discoverStep() {
int maxSteps = SlimefunPlugin.getNetworkManager().getMaxSize();
int maxSteps = manager.getMaxSize();
int steps = 0;
while (nodeQueue.peek() != null) {
@ -129,7 +148,7 @@ public abstract class Network {
if (classification != currentAssignment) {
if (currentAssignment == NetworkComponent.REGULATOR || currentAssignment == NetworkComponent.CONNECTOR) {
// Requires a complete rebuild of the network, so we just throw the current one away.
SlimefunPlugin.getNetworkManager().unregisterNetwork(this);
manager.unregisterNetwork(this);
return;
}
else if (currentAssignment == NetworkComponent.TERMINUS) {

View File

@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.core.networks;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import org.bukkit.Location;
import org.bukkit.Server;
@ -21,7 +22,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListen
* @see NetworkListener
*
*/
public final class NetworkManager {
public class NetworkManager {
private final int maxNodes;
private final List<Network> networks = new LinkedList<>();
@ -29,11 +30,11 @@ public final class NetworkManager {
/**
* This creates a new {@link NetworkManager} with the given capacity.
*
* @param capacity
* @param maxStepSize
* The maximum amount of nodes a {@link Network} can have
*/
public NetworkManager(int capacity) {
maxNodes = capacity;
public NetworkManager(int maxStepSize) {
maxNodes = maxStepSize;
}
/**
@ -55,14 +56,14 @@ public final class NetworkManager {
return networks;
}
public <T extends Network> T getNetworkFromLocation(Location l, Class<T> type) {
public <T extends Network> Optional<T> getNetworkFromLocation(Location l, Class<T> type) {
for (Network network : networks) {
if (type.isInstance(network) && network.connectsTo(l)) {
return type.cast(network);
return Optional.of(type.cast(network));
}
}
return null;
return Optional.empty();
}
public <T extends Network> List<T> getNetworksFromLocation(Location l, Class<T> type) {
@ -87,7 +88,7 @@ public final class NetworkManager {
public void handleAllNetworkLocationUpdate(Location l) {
for (Network n : getNetworksFromLocation(l, Network.class)) {
n.handleLocationUpdate(l);
n.markDirty(l);
}
}

View File

@ -36,18 +36,20 @@ public class CargoNet extends ChestTerminalNetwork {
private int tickDelayThreshold = 0;
public static CargoNet getNetworkFromLocation(Location l) {
return SlimefunPlugin.getNetworkManager().getNetworkFromLocation(l, CargoNet.class);
return SlimefunPlugin.getNetworkManager().getNetworkFromLocation(l, CargoNet.class).orElse(null);
}
public static CargoNet getNetworkFromLocationOrCreate(Location l) {
CargoNet cargoNetwork = getNetworkFromLocation(l);
Optional<CargoNet> cargoNetwork = SlimefunPlugin.getNetworkManager().getNetworkFromLocation(l, CargoNet.class);
if (cargoNetwork == null) {
cargoNetwork = new CargoNet(l);
SlimefunPlugin.getNetworkManager().registerNetwork(cargoNetwork);
if (cargoNetwork.isPresent()) {
return cargoNetwork.get();
}
else {
CargoNet network = new CargoNet(l);
SlimefunPlugin.getNetworkManager().registerNetwork(network);
return network;
}
return cargoNetwork;
}
protected CargoNet(Location l) {

View File

@ -27,6 +27,7 @@ import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
@ -54,7 +55,7 @@ abstract class ChestTerminalNetwork extends Network {
private final Set<ItemRequest> itemRequests = new HashSet<>();
protected ChestTerminalNetwork(Location regulator) {
super(regulator);
super(SlimefunPlugin.getNetworkManager(), regulator);
}
protected static Optional<Block> getAttachedBlock(Block block) {

View File

@ -1,6 +1,7 @@
package io.github.thebusybiscuit.slimefun4.core.networks.energy;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import org.bukkit.Location;
@ -59,19 +60,17 @@ public class EnergyNet extends Network {
return EnergyNetComponentType.NONE;
}
public static EnergyNet getNetworkFromLocation(Location l) {
return SlimefunPlugin.getNetworkManager().getNetworkFromLocation(l, EnergyNet.class);
}
public static EnergyNet getNetworkFromLocationOrCreate(Location l) {
EnergyNet energyNetwork = getNetworkFromLocation(l);
Optional<EnergyNet> cargoNetwork = SlimefunPlugin.getNetworkManager().getNetworkFromLocation(l, EnergyNet.class);
if (energyNetwork == null) {
energyNetwork = new EnergyNet(l);
SlimefunPlugin.getNetworkManager().registerNetwork(energyNetwork);
if (cargoNetwork.isPresent()) {
return cargoNetwork.get();
}
else {
EnergyNet network = new EnergyNet(l);
SlimefunPlugin.getNetworkManager().registerNetwork(network);
return network;
}
return energyNetwork;
}
private final Set<Location> generators = new HashSet<>();
@ -79,7 +78,7 @@ public class EnergyNet extends Network {
private final Set<Location> consumers = new HashSet<>();
protected EnergyNet(Location l) {
super(l);
super(SlimefunPlugin.getNetworkManager(), l);
}
@Override

View File

@ -23,8 +23,8 @@ public class NetworkListener implements Listener {
private final NetworkManager manager;
public NetworkListener(SlimefunPlugin plugin) {
manager = SlimefunPlugin.getNetworkManager();
public NetworkListener(SlimefunPlugin plugin, NetworkManager manager) {
this.manager = manager;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@ -34,7 +34,7 @@ public class NetworkListener implements Listener {
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlaceBreak(BlockPlaceEvent e) {
public void onBlockPlace(BlockPlaceEvent e) {
manager.handleAllNetworkLocationUpdate(e.getBlock().getLocation());
}
}

View File

@ -62,7 +62,7 @@ public class SlimefunStartupTask implements Runnable {
}
if (isEnabled("ENERGY_REGULATOR", "CARGO_MANAGER")) {
new NetworkListener(plugin);
new NetworkListener(plugin, SlimefunPlugin.getNetworkManager());
}
}

View File

@ -0,0 +1,70 @@
package io.github.thebusybiscuit.slimefun4.tests.listeners;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.BlockState;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
public class TestNetworkListener {
private static SlimefunPlugin plugin;
private static NetworkListener listener;
private static NetworkManager manager = new NetworkManager(80);
private static ServerMock server;
@BeforeAll
public static void load() {
server = MockBukkit.mock();
plugin = MockBukkit.load(SlimefunPlugin.class);
listener = new NetworkListener(plugin, manager);
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@Test
public void testBlockBreak() {
World world = server.addSimpleWorld("Simple Network Listener World");
Location l = new Location(world, 3000, 120, -500);
Network network = Mockito.mock(Network.class);
Mockito.when(network.connectsTo(l)).thenReturn(true);
manager.registerNetwork(network);
listener.onBlockBreak(new BlockBreakEvent(l.getBlock(), server.addPlayer()));
Mockito.verify(network).markDirty(l);
}
@Test
public void testBlockPlace() {
World world = server.addSimpleWorld("Simple Network Listener World");
Location l = new Location(world, 3000, 120, -500);
Location l2 = new Location(world, 3000, 121, -500);
Network network = Mockito.mock(Network.class);
Mockito.when(network.connectsTo(l)).thenReturn(true);
manager.registerNetwork(network);
BlockState state = Mockito.mock(BlockState.class);
listener.onBlockPlace(new BlockPlaceEvent(l.getBlock(), state, l2.getBlock(), new ItemStack(Material.AIR), server.addPlayer(), true, EquipmentSlot.HAND));
Mockito.verify(network).markDirty(l);
}
}

View File

@ -0,0 +1,169 @@
package io.github.thebusybiscuit.slimefun4.tests.networks;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.bukkit.Location;
import org.bukkit.World;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent;
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
public class TestNetworkManager {
private static ServerMock server;
@BeforeAll
public static void load() {
server = MockBukkit.mock();
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@Test
public void testGetMaxNetworkSize() {
int size = 50;
NetworkManager manager = new NetworkManager(size);
Assertions.assertEquals(size, manager.getMaxSize());
}
@Test
public void testGetNetworkList() {
NetworkManager manager = new NetworkManager(10);
World world = server.addSimpleWorld("Simple Network World");
Location loc = new Location(world, 0, 100, 0);
Network network = new DummyNetwork(manager, loc, 10, new HashMap<>());
Assertions.assertFalse(manager.getNetworkList().contains(network));
manager.registerNetwork(network);
Assertions.assertTrue(manager.getNetworkList().contains(network));
manager.unregisterNetwork(network);
Assertions.assertFalse(manager.getNetworkList().contains(network));
}
@Test
public void testDirtyRegulatorUnregistersNetwork() {
World world = server.addSimpleWorld("Simple Network World");
Location loc = new Location(world, 0, 100, 0);
NetworkManager manager = Mockito.mock(NetworkManager.class);
Network network = new DummyNetwork(manager, loc, 10, new HashMap<>());
network.markDirty(loc);
Mockito.verify(manager).unregisterNetwork(network);
}
@Test
public void testGetNetworkAtLocation() {
NetworkManager manager = new NetworkManager(10);
World world = server.addSimpleWorld("Simple Network World");
Location loc = new Location(world, 0, 100, 0);
Location loc2 = new Location(world, 0, 200, 0);
Network network = new DummyNetwork(manager, loc, 10, new HashMap<>());
Assertions.assertFalse(manager.getNetworkFromLocation(loc, DummyNetwork.class).isPresent());
manager.registerNetwork(network);
Optional<DummyNetwork> optional = manager.getNetworkFromLocation(loc, DummyNetwork.class);
Assertions.assertTrue(optional.isPresent());
Assertions.assertEquals(network, optional.get());
Assertions.assertFalse(manager.getNetworkFromLocation(loc2, DummyNetwork.class).isPresent());
Assertions.assertFalse(manager.getNetworkFromLocation(loc, CargoNet.class).isPresent());
}
@Test
public void testGetNetworksAtLocation() {
NetworkManager manager = new NetworkManager(10);
World world = server.addSimpleWorld("Simple Network World");
Location loc = new Location(world, 0, 100, 0);
Location loc2 = new Location(world, 0, 200, 0);
Network network = new DummyNetwork(manager, loc, 10, new HashMap<>());
manager.registerNetwork(network);
Assertions.assertFalse(manager.getNetworksFromLocation(loc2, DummyNetwork.class).contains(network));
Assertions.assertFalse(manager.getNetworksFromLocation(loc, CargoNet.class).contains(network));
Assertions.assertTrue(manager.getNetworksFromLocation(loc, DummyNetwork.class).contains(network));
}
@Test
public void testSingleNodeNetwork() {
NetworkManager manager = new NetworkManager(1);
World world = server.addSimpleWorld("Simple Network World");
Location loc = new Location(world, 0, 100, 0);
Network network = new DummyNetwork(manager, loc, 1, new HashMap<>());
network.tick();
Assertions.assertEquals(1, network.getSize());
Assertions.assertEquals(NetworkComponent.REGULATOR, network.classifyLocation(loc));
}
@Test
public void testCornerConnection() {
NetworkManager manager = new NetworkManager(100);
World world = server.addSimpleWorld("Simple Network World");
Map<Location, NetworkComponent> map = new HashMap<>();
Location loc = new Location(world, 0, 100, 0);
Location loc2 = new Location(world, 0, 100, 2);
map.put(loc2, NetworkComponent.CONNECTOR);
Location loc3 = new Location(world, 2, 100, 2);
map.put(loc3, NetworkComponent.CONNECTOR);
Network network = new DummyNetwork(manager, loc, 3, map);
network.tick();
Assertions.assertEquals(3, network.getSize());
}
private class DummyNetwork extends Network {
private final int range;
private final Map<Location, NetworkComponent> locations;
protected DummyNetwork(NetworkManager manager, Location regulator, int range, Map<Location, NetworkComponent> locations) {
super(manager, regulator);
this.range = range;
this.locations = locations;
}
@Override
public int getRange() {
return range;
}
@Override
public NetworkComponent classifyLocation(Location l) {
if (l.equals(regulator)) return NetworkComponent.REGULATOR;
return locations.get(l);
}
@Override
public void onClassificationChange(Location l, NetworkComponent from, NetworkComponent to) {
// Do nothing
}
}
}