Rework arena sign data store.
This commit constitutes a major rewrite of how arena signs are stored and loaded. It fixes an issue where an unloaded or missing world would cause MobArena to throw errors if there were any arena signs recorded in said world. The solution is to load signs of a given world when it is available, rather than loading all signs at once indiscriminately. At startup, signs for all _currently available_ worlds are loaded. This fixes the errors. When a world loads and a WorldLoadEvent is fired, signs in that world are loaded. This ensures that all valid signs in existing worlds will _eventually_ load. To keep things tidy, a WorldUnloadEvent will unload all signs for the unloaded world. Bukkit's own YAML deserialization implementation doesn't re-throw all deserialization errors, which means we can't actually catch the problem of missing worlds without doing an awkward "scan" of the deserialized objects. This prompted a rewrite of the serialization and data storage into a custom CSV-like format which is both simpler and also provides a lot more control over the process. Instead of relying on world _names_, the new format uses world _UUIDs_. While the rest of the plugin won't necessarily adapt well to a world being renamed, the signs data store should be resilient enough to handle it. Most of the actual sign rendering code and almost all of the template code is intact, but quite a lot of other classes have been rewritten or replaced. Some of the rewrites weren't strictly necessary, but because the components were already fairly small, rewrites were much faster and a lot less awkward than attempting to adapt existing code. Fixes #645
This commit is contained in:
@@ -1,57 +0,0 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class ArenaSignTest {
|
||||
|
||||
@Test
|
||||
public void serialize() {
|
||||
World world = mock(World.class);
|
||||
Location location = new Location(world, 1, 2, 3);
|
||||
String templateId = "a good template";
|
||||
String arenaId = "cool arena";
|
||||
String type = "join";
|
||||
ArenaSign sign = new ArenaSign(location, templateId, arenaId, type);
|
||||
|
||||
Map<String, Object> result = sign.serialize();
|
||||
|
||||
assertThat(result.get("location"), equalTo(location));
|
||||
assertThat(result.get("templateId"), equalTo(templateId));
|
||||
assertThat(result.get("arenaId"), equalTo(arenaId));
|
||||
assertThat(result.get("type"), equalTo(type));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserialize() {
|
||||
World world = mock(World.class);
|
||||
Location location = new Location(world, 1, 2, 3);
|
||||
String templateId = "a good template";
|
||||
String arenaId = "cool arena";
|
||||
String type = "join";
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("location", location);
|
||||
map.put("templateId", templateId);
|
||||
map.put("arenaId", arenaId);
|
||||
map.put("type", type);
|
||||
|
||||
ArenaSign result = ArenaSign.deserialize(map);
|
||||
|
||||
assertThat(result.location, is(equalTo(location)));
|
||||
assertThat(result.templateId, is(equalTo(templateId)));
|
||||
assertThat(result.arenaId, is(equalTo(arenaId)));
|
||||
assertThat(result.type, is(equalTo(type)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Chest;
|
||||
@@ -13,7 +11,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Optional;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
@@ -27,8 +25,6 @@ public class HandlesSignClicksTest {
|
||||
@Before
|
||||
public void setup() {
|
||||
signStore = mock(SignStore.class);
|
||||
when(signStore.findByLocation(any()))
|
||||
.thenReturn(Optional.empty());
|
||||
invokesSignAction = mock(InvokesSignAction.class);
|
||||
|
||||
subject = new HandlesSignClicks(signStore, invokesSignAction);
|
||||
@@ -40,7 +36,7 @@ public class HandlesSignClicksTest {
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyZeroInteractions(signStore);
|
||||
verifyNoInteractions(signStore, invokesSignAction);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -51,18 +47,19 @@ public class HandlesSignClicksTest {
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyZeroInteractions(signStore);
|
||||
verifyNoInteractions(signStore, invokesSignAction);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonArenaSignNoFun() {
|
||||
Block block = mock(Block.class);
|
||||
when(block.getState()).thenReturn(mock(Sign.class));
|
||||
when(signStore.findByLocation(any())).thenReturn(null);
|
||||
PlayerInteractEvent event = event(null, block);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyZeroInteractions(signStore);
|
||||
verifyNoInteractions(invokesSignAction);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -72,8 +69,7 @@ public class HandlesSignClicksTest {
|
||||
when(block.getLocation()).thenReturn(location);
|
||||
when(block.getState()).thenReturn(mock(Sign.class));
|
||||
ArenaSign sign = new ArenaSign(location, "", "", "");
|
||||
when(signStore.findByLocation(location))
|
||||
.thenReturn(Optional.of(sign));
|
||||
when(signStore.findByLocation(location)).thenReturn(sign);
|
||||
Player player = mock(Player.class);
|
||||
PlayerInteractEvent event = event(player, block);
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.garbagemule.MobArena.Messenger;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.junit.Before;
|
||||
@@ -12,135 +10,139 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class HandlesSignCreationTest {
|
||||
|
||||
StoresNewSign storesNewSign;
|
||||
RendersTemplateById rendersTemplate;
|
||||
SignCreator creator;
|
||||
SignWriter writer;
|
||||
SignStore store;
|
||||
SignRenderer renderer;
|
||||
Messenger messenger;
|
||||
Logger log;
|
||||
|
||||
HandlesSignCreation subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
storesNewSign = mock(StoresNewSign.class);
|
||||
|
||||
rendersTemplate = mock(RendersTemplateById.class);
|
||||
when(rendersTemplate.render(any(), any()))
|
||||
.thenReturn(new String[]{"", "", "", ""});
|
||||
|
||||
creator = mock(SignCreator.class);
|
||||
writer = mock(SignWriter.class);
|
||||
store = mock(SignStore.class);
|
||||
renderer = mock(SignRenderer.class);
|
||||
messenger = mock(Messenger.class);
|
||||
log = mock(Logger.class);
|
||||
|
||||
subject = new HandlesSignCreation(
|
||||
storesNewSign,
|
||||
rendersTemplate,
|
||||
messenger
|
||||
creator,
|
||||
writer,
|
||||
store,
|
||||
renderer,
|
||||
messenger,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noHeaderNoAction() {
|
||||
String[] lines = {"why", "so", "serious", "?"};
|
||||
SignChangeEvent event = event(lines, null);
|
||||
public void noSignCreationNoAction() {
|
||||
SignChangeEvent event = new SignChangeEvent(null, null, null);
|
||||
when(creator.create(event)).thenReturn(null);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyZeroInteractions(storesNewSign, rendersTemplate, messenger);
|
||||
verifyNoInteractions(writer, store, messenger, log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullLinesHandledGracefully() {
|
||||
String[] lines = {"[MA]", null, null, null};
|
||||
SignChangeEvent event = event(lines, null);
|
||||
|
||||
subject.on(event);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useSignTypeIfTemplateNotAvailable() {
|
||||
String arenaId = "castle";
|
||||
String type = "join";
|
||||
String[] lines = {"[MA]", arenaId, type, null};
|
||||
Location location = mock(Location.class);
|
||||
SignChangeEvent event = event(lines, location);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(storesNewSign).store(location, arenaId, type, type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useTemplateIfAvailable() {
|
||||
String arenaId = "castle";
|
||||
String type = "join";
|
||||
String templateId = "potato";
|
||||
String[] lines = {"[MA]", arenaId, type, templateId};
|
||||
Location location = mock(Location.class);
|
||||
SignChangeEvent event = event(lines, location);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(storesNewSign).store(location, arenaId, templateId, type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeIsLowercased() {
|
||||
String type = "JOIN";
|
||||
String[] lines = {"[MA]", "", type, ""};
|
||||
SignChangeEvent event = event(lines, null);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
String lower = type.toLowerCase();
|
||||
verify(storesNewSign).store(any(), any(), any(), eq(lower));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void templateIdIsLowercased() {
|
||||
String templateId = "BEST-TEMPLATE";
|
||||
String[] lines = {"[MA]", "", "", templateId};
|
||||
SignChangeEvent event = event(lines, null);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
String lower = templateId.toLowerCase();
|
||||
verify(storesNewSign).store(any(), any(), eq(lower), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersTemplateAfterStoring() {
|
||||
String arenaId = "castle";
|
||||
String type = "join";
|
||||
String templateId = "potato";
|
||||
String[] lines = {"[MA]", arenaId, type, templateId};
|
||||
Location location = mock(Location.class);
|
||||
SignChangeEvent event = event(lines, location);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(rendersTemplate).render(templateId, arenaId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorPassedToMessenger() {
|
||||
String msg = "you messed up";
|
||||
doThrow(new IllegalArgumentException(msg))
|
||||
.when(storesNewSign).store(any(), any(), any(), any());
|
||||
String[] lines = {"[MA]", "", "", ""};
|
||||
SignChangeEvent event = event(lines, null);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyZeroInteractions(rendersTemplate);
|
||||
verify(messenger).tell(event.getPlayer(), msg);
|
||||
}
|
||||
|
||||
private SignChangeEvent event(String[] lines, Location location) {
|
||||
Block block = mock(Block.class);
|
||||
when(block.getLocation()).thenReturn(location);
|
||||
public void passesSignFromCreator() throws Exception {
|
||||
Player player = mock(Player.class);
|
||||
return new SignChangeEvent(block, player, lines);
|
||||
SignChangeEvent event = new SignChangeEvent(null, player, null);
|
||||
ArenaSign sign = new ArenaSign(location(), null, null, null);
|
||||
when(creator.create(event)).thenReturn(sign);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(writer).write(sign);
|
||||
verify(store).add(sign);
|
||||
verify(renderer).render(sign, event);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successMessageOnCreation() {
|
||||
Player player = mock(Player.class);
|
||||
SignChangeEvent event = new SignChangeEvent(null, player, null);
|
||||
ArenaSign sign = new ArenaSign(location(), null, "castle", "join");
|
||||
when(creator.create(event)).thenReturn(sign);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(messenger).tell(eq(player), anyString());
|
||||
verify(log).info(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noWriteIfCreatorThrows() {
|
||||
SignChangeEvent event = new SignChangeEvent(null, null, null);
|
||||
doThrow(IllegalArgumentException.class).when(creator).create(event);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyNoInteractions(writer, store, renderer, log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorMessageIfCreatorThrows() {
|
||||
Player player = mock(Player.class);
|
||||
SignChangeEvent event = new SignChangeEvent(null, player, null);
|
||||
String message = "it's bad";
|
||||
doThrow(new IllegalArgumentException(message)).when(creator).create(event);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(messenger).tell(player, message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noStorageIfWriterThrows() throws Exception {
|
||||
SignChangeEvent event = new SignChangeEvent(null, null, null);
|
||||
ArenaSign sign = new ArenaSign(null, null, null, null);
|
||||
when(creator.create(event)).thenReturn(sign);
|
||||
doThrow(IOException.class).when(writer).write(sign);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyNoInteractions(store, renderer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorMessageIfWriterThrows() throws Exception {
|
||||
Player player = mock(Player.class);
|
||||
SignChangeEvent event = new SignChangeEvent(null, player, null);
|
||||
ArenaSign sign = new ArenaSign(null, null, null, null);
|
||||
when(creator.create(event)).thenReturn(sign);
|
||||
IOException exception = new IOException("it's bad");
|
||||
doThrow(exception).when(writer).write(sign);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(messenger).tell(eq(player), anyString());
|
||||
verify(log).log(eq(Level.SEVERE), anyString(), eq(exception));
|
||||
}
|
||||
|
||||
private Location location() {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("world");
|
||||
Location location = mock(Location.class);
|
||||
when(location.getBlockX()).thenReturn(1);
|
||||
when(location.getBlockY()).thenReturn(2);
|
||||
when(location.getBlockZ()).thenReturn(3);
|
||||
when(location.getWorld()).thenReturn(world);
|
||||
return location;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.garbagemule.MobArena.Messenger;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
@@ -11,53 +11,109 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class HandlesSignDestructionTest {
|
||||
|
||||
RemovesSignAtLocation removesSignAtLocation;
|
||||
SignStore store;
|
||||
SignWriter writer;
|
||||
Messenger messenger;
|
||||
Logger log;
|
||||
|
||||
HandlesSignDestruction subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
removesSignAtLocation = mock(RemovesSignAtLocation.class);
|
||||
store = mock(SignStore.class);
|
||||
writer = mock(SignWriter.class);
|
||||
messenger = mock(Messenger.class);
|
||||
log = mock(Logger.class);
|
||||
|
||||
subject = new HandlesSignDestruction(
|
||||
removesSignAtLocation,
|
||||
messenger
|
||||
store,
|
||||
writer,
|
||||
messenger,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNothingWithNonArenaSign() {
|
||||
public void noSignNoAction() {
|
||||
Location location = mock(Location.class);
|
||||
Block block = mock(Block.class);
|
||||
BlockBreakEvent event = new BlockBreakEvent(block, null);
|
||||
when(block.getLocation()).thenReturn(location);
|
||||
when(store.removeByLocation(location)).thenReturn(null);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyNoInteractions(writer, messenger, log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void erasesFoundSign() throws IOException {
|
||||
Location location = location();
|
||||
Block block = mock(Block.class);
|
||||
Player player = mock(Player.class);
|
||||
when(removesSignAtLocation.remove(any()))
|
||||
.thenReturn(Optional.empty());
|
||||
ArenaSign sign = new ArenaSign(location, "cool-sign", "castle", "join");
|
||||
when(block.getLocation()).thenReturn(location);
|
||||
when(store.removeByLocation(location)).thenReturn(sign);
|
||||
BlockBreakEvent event = new BlockBreakEvent(block, player);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyZeroInteractions(messenger);
|
||||
verify(writer).erase(sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reportsBreakageWithArenaSign() {
|
||||
public void successMessageOnDestruction() {
|
||||
Location location = location();
|
||||
Block block = mock(Block.class);
|
||||
Player player = mock(Player.class);
|
||||
ArenaSign sign = new ArenaSign(null, "", "", "");
|
||||
when(removesSignAtLocation.remove(any()))
|
||||
.thenReturn(Optional.of(sign));
|
||||
ArenaSign sign = new ArenaSign(location, "cool-sign", "castle", "join");
|
||||
when(block.getLocation()).thenReturn(location);
|
||||
when(store.removeByLocation(location)).thenReturn(sign);
|
||||
BlockBreakEvent event = new BlockBreakEvent(block, player);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(messenger).tell(eq(player), anyString());
|
||||
verify(log).info(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorMessageIfWriterThrows() throws Exception {
|
||||
Location location = mock(Location.class);
|
||||
Block block = mock(Block.class);
|
||||
Player player = mock(Player.class);
|
||||
ArenaSign sign = new ArenaSign(location, "cool-sign", "castle", "join");
|
||||
IOException exception = new IOException("it's bad");
|
||||
when(block.getLocation()).thenReturn(location);
|
||||
when(store.removeByLocation(location)).thenReturn(sign);
|
||||
doThrow(exception).when(writer).erase(sign);
|
||||
BlockBreakEvent event = new BlockBreakEvent(block, player);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(messenger).tell(eq(player), anyString());
|
||||
verify(log).log(eq(Level.SEVERE), anyString(), eq(exception));
|
||||
}
|
||||
|
||||
private Location location() {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("world");
|
||||
Location location = mock(Location.class);
|
||||
when(location.getBlockX()).thenReturn(1);
|
||||
when(location.getBlockY()).thenReturn(2);
|
||||
when(location.getBlockZ()).thenReturn(3);
|
||||
when(location.getWorld()).thenReturn(world);
|
||||
return location;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class HandlesWorldLoadTest {
|
||||
|
||||
SignDataMigrator migrator;
|
||||
SignReader reader;
|
||||
SignStore store;
|
||||
Logger log;
|
||||
|
||||
HandlesWorldLoad subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
migrator = mock(SignDataMigrator.class);
|
||||
reader = mock(SignReader.class);
|
||||
store = mock(SignStore.class);
|
||||
log = mock(Logger.class);
|
||||
|
||||
subject = new HandlesWorldLoad(
|
||||
migrator,
|
||||
reader,
|
||||
store,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorMessageIfDataMigrationThrows() throws IOException {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("world");
|
||||
IOException exception = new IOException("it's bad");
|
||||
doThrow(exception).when(migrator).migrate(world);
|
||||
WorldLoadEvent event = new WorldLoadEvent(world);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(log).log(eq(Level.SEVERE), anyString(), eq(exception));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsLoadedSignsToStore() throws IOException {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("world");
|
||||
when(world.getUID()).thenReturn(UUID.fromString("cafebabe-ea75-dead-beef-deadcafebabe"));
|
||||
Location location = mock(Location.class);
|
||||
ArenaSign sign = new ArenaSign(location, "cool-sign", "castle", "join");
|
||||
when(reader.read(world)).thenReturn(Collections.singletonList(sign));
|
||||
WorldLoadEvent event = new WorldLoadEvent(world);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(store).add(sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logsMessageOnSignAddition() throws IOException {
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn("world");
|
||||
when(world.getUID()).thenReturn(UUID.fromString("cafebabe-ea75-dead-beef-deadcafebabe"));
|
||||
Location location = mock(Location.class);
|
||||
ArenaSign sign = new ArenaSign(location, "cool-sign", "castle", "join");
|
||||
when(reader.read(world)).thenReturn(Collections.singletonList(sign));
|
||||
WorldLoadEvent event = new WorldLoadEvent(world);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(log).info(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsNothingIfNoSignsLoaded() throws IOException {
|
||||
World world = mock(World.class);
|
||||
when(reader.read(world)).thenReturn(Collections.emptyList());
|
||||
WorldLoadEvent event = new WorldLoadEvent(world);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyNoInteractions(store);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logsNothingIfNoSignsLoaded() throws IOException {
|
||||
World world = mock(World.class);
|
||||
when(reader.read(world)).thenReturn(Collections.emptyList());
|
||||
WorldLoadEvent event = new WorldLoadEvent(world);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyNoInteractions(log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorMessageIfReaderThrows() throws IOException {
|
||||
World world = mock(World.class);
|
||||
IOException exception = new IOException("it's bad");
|
||||
when(reader.read(world)).thenThrow(exception);
|
||||
WorldLoadEvent event = new WorldLoadEvent(world);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(log).log(eq(Level.SEVERE), anyString(), eq(exception));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class HandlesWorldUnloadTest {
|
||||
|
||||
SignStore store;
|
||||
Logger log;
|
||||
|
||||
HandlesWorldUnload subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
store = mock(SignStore.class);
|
||||
log = mock(Logger.class);
|
||||
|
||||
subject = new HandlesWorldUnload(
|
||||
store,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logsMessagesOnSignRemoval() {
|
||||
UUID id = UUID.fromString("cafebabe-ea75-dead-beef-deadcafebabe");
|
||||
String name = "world";
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(id);
|
||||
when(world.getName()).thenReturn(name);
|
||||
List<ArenaSign> signs = Arrays.asList(null, null);
|
||||
when(store.removeByWorld(world)).thenReturn(signs);
|
||||
WorldUnloadEvent event = new WorldUnloadEvent(world);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verify(log).info(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logsNothingIfNoSignsRemoved() {
|
||||
World world = mock(World.class);
|
||||
when(store.removeByWorld(world)).thenReturn(Collections.emptyList());
|
||||
WorldUnloadEvent event = new WorldUnloadEvent(world);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyNoInteractions(log);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.garbagemule.MobArena.Messenger;
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||
@@ -11,6 +9,8 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class InvokesSignActionTest {
|
||||
@@ -36,7 +36,7 @@ public class InvokesSignActionTest {
|
||||
|
||||
subject.invoke(sign, player);
|
||||
|
||||
verifyZeroInteractions(arenaMaster);
|
||||
verifyNoInteractions(arenaMaster);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import org.bukkit.Location;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class RedrawsArenaSignsTest {
|
||||
|
||||
SignStore signStore;
|
||||
TemplateStore templateStore;
|
||||
RendersTemplate rendersTemplate;
|
||||
SetsLines setsSignLines;
|
||||
|
||||
RedrawsArenaSigns subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
signStore = mock(SignStore.class);
|
||||
when(signStore.findByArenaId(any()))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
templateStore = mock(TemplateStore.class);
|
||||
when(templateStore.findById(any()))
|
||||
.thenReturn(Optional.empty());
|
||||
|
||||
rendersTemplate = mock(RendersTemplate.class);
|
||||
when(rendersTemplate.render(any(), any()))
|
||||
.thenReturn(new String[]{"a", "b", "c", "d"});
|
||||
|
||||
setsSignLines = mock(SetsLines.class);
|
||||
|
||||
subject = new RedrawsArenaSigns(
|
||||
signStore,
|
||||
templateStore,
|
||||
rendersTemplate,
|
||||
setsSignLines
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noSignsMeansNoRenderingOrLineSetting() {
|
||||
Arena arena = arena("castle");
|
||||
|
||||
subject.redraw(arena);
|
||||
|
||||
verifyZeroInteractions(rendersTemplate);
|
||||
verifyZeroInteractions(setsSignLines);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderFoundTemplate() {
|
||||
String arenaId = "castle";
|
||||
Arena arena = arena(arenaId);
|
||||
ArenaSign sign = sign("join", arenaId);
|
||||
when(signStore.findByArenaId(arenaId))
|
||||
.thenReturn(Collections.singletonList(sign));
|
||||
Template template = template("template", "some", "info", "about", "arena");
|
||||
when(templateStore.findById(sign.templateId))
|
||||
.thenReturn(Optional.of(template));
|
||||
|
||||
subject.redraw(arena);
|
||||
|
||||
verify(rendersTemplate).render(template, arena);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setRenderedTemplateOnSign() {
|
||||
String arenaId = "castle";
|
||||
Arena arena = arena(arenaId);
|
||||
ArenaSign sign = sign("join", arenaId);
|
||||
when(signStore.findByArenaId(sign.arenaId))
|
||||
.thenReturn(Collections.singletonList(sign));
|
||||
Template template = template("template", "try", "with", "more", "fireballs");
|
||||
when(templateStore.findById(sign.templateId))
|
||||
.thenReturn(Optional.of(template));
|
||||
String[] lines = new String[]{"this", "is", "a", "sign"};
|
||||
when(rendersTemplate.render(template, arena))
|
||||
.thenReturn(lines);
|
||||
|
||||
subject.redraw(arena);
|
||||
|
||||
verify(setsSignLines).set(sign.location, lines);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderEachTemplateOnlyOnce() {
|
||||
String arenaId = "castle";
|
||||
Arena arena = arena(arenaId);
|
||||
String templateId1 = "join";
|
||||
String templateId2 = "info";
|
||||
List<ArenaSign> signs = new ArrayList<>();
|
||||
signs.add(sign(templateId1, arenaId));
|
||||
signs.add(sign(templateId1, arenaId));
|
||||
signs.add(sign(templateId1, arenaId));
|
||||
signs.add(sign(templateId2, arenaId));
|
||||
when(signStore.findByArenaId(arenaId))
|
||||
.thenReturn(signs);
|
||||
Template template1 = template(templateId1, "join", "a", "MobArena", "today!");
|
||||
Template template2 = template(templateId2, "join", "another", "MobArena", "tomorrow!");
|
||||
when(templateStore.findById(templateId1))
|
||||
.thenReturn(Optional.of(template1));
|
||||
when(templateStore.findById(templateId2))
|
||||
.thenReturn(Optional.of(template2));
|
||||
|
||||
subject.redraw(arena);
|
||||
|
||||
verify(rendersTemplate, times(1)).render(template1, arena);
|
||||
verify(rendersTemplate, times(1)).render(template2, arena);
|
||||
verify(setsSignLines, times(signs.size())).set(any(), any());
|
||||
}
|
||||
|
||||
private Arena arena(String arenaId) {
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.configName()).thenReturn(arenaId);
|
||||
return arena;
|
||||
}
|
||||
|
||||
private ArenaSign sign(String templateId, String arenaId) {
|
||||
Location location = mock(Location.class);
|
||||
return new ArenaSign(location, templateId, arenaId, "join");
|
||||
}
|
||||
|
||||
private Template template(String id, String l1, String l2, String l3, String l4) {
|
||||
return new Template.Builder(id)
|
||||
.withBase(new String[]{l1, l2, l3, l4})
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class RemovesSignAtLocationTest {
|
||||
|
||||
SignStore signStore;
|
||||
SavesSignStore savesSignStore;
|
||||
|
||||
RemovesSignAtLocation subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
signStore = mock(SignStore.class);
|
||||
savesSignStore = mock(SavesSignStore.class);
|
||||
|
||||
subject = new RemovesSignAtLocation(
|
||||
signStore,
|
||||
savesSignStore
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noSignMeansNoWrite() {
|
||||
Location location = mock(Location.class);
|
||||
when(signStore.remove(location))
|
||||
.thenReturn(Optional.empty());
|
||||
|
||||
subject.remove(location);
|
||||
|
||||
verifyZeroInteractions(savesSignStore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void signRemovedWritesStore() {
|
||||
Location location = mock(Location.class);
|
||||
ArenaSign sign = new ArenaSign(location, "", "", "");
|
||||
when(signStore.remove(location))
|
||||
.thenReturn(Optional.of(sign));
|
||||
|
||||
subject.remove(location);
|
||||
|
||||
verify(savesSignStore).save(signStore);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.WaveManager;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -14,6 +10,10 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class RendersTemplateTest {
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class SignCreatorTest {
|
||||
|
||||
ArenaMaster arenaMaster;
|
||||
TemplateStore templateStore;
|
||||
|
||||
SignCreator subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
arenaMaster = mock(ArenaMaster.class);
|
||||
templateStore = mock(TemplateStore.class);
|
||||
|
||||
subject = new SignCreator(
|
||||
arenaMaster,
|
||||
templateStore
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noHeaderNoAction() {
|
||||
String[] lines = {"ma", "castle", "join", "cool-sign"};
|
||||
SignChangeEvent event = new SignChangeEvent(null, null, lines);
|
||||
|
||||
ArenaSign result = subject.create(event);
|
||||
|
||||
assertThat(result, nullValue());
|
||||
verifyNoInteractions(arenaMaster, templateStore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void throwsOnMissingArena() {
|
||||
String[] lines = {"[MA]", null, "join", "cool-sign"};
|
||||
SignChangeEvent event = event(lines, null);
|
||||
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> subject.create(event)
|
||||
);
|
||||
verifyNoInteractions(arenaMaster);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void throwsIfArenaNotFound() {
|
||||
String arenaId = "castle";
|
||||
String[] lines = {"[MA]", arenaId, "join", "cool-sign"};
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(null);
|
||||
SignChangeEvent event = event(lines, null);
|
||||
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> subject.create(event)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void throwsOnMissingType() {
|
||||
String arenaId = "castle";
|
||||
String[] lines = {"[MA]", arenaId, null, "cool-sign"};
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.getSlug()).thenReturn(arenaId);
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(arena);
|
||||
SignChangeEvent event = event(lines, null);
|
||||
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> subject.create(event)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void throwsOnInvalidType() {
|
||||
String arenaId = "castle";
|
||||
String[] lines = {"[MA]", arenaId, "bob", "cool-sign"};
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.getSlug()).thenReturn(arenaId);
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(arena);
|
||||
SignChangeEvent event = event(lines, null);
|
||||
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> subject.create(event)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void throwsIfTemplateNotFound() {
|
||||
String arenaId = "castle";
|
||||
String templateId = "cool-sign";
|
||||
String[] lines = {"[MA]", arenaId, "join", templateId};
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.getSlug()).thenReturn(arenaId);
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(arena);
|
||||
when(templateStore.findById(templateId)).thenReturn(Optional.empty());
|
||||
SignChangeEvent event = event(lines, null);
|
||||
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> subject.create(event)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void completeSignDefinition() {
|
||||
String arenaId = "castle";
|
||||
String signType = "join";
|
||||
String templateId = "cool-sign";
|
||||
String[] lines = {"[MA]", arenaId, signType, templateId};
|
||||
Location location = mock(Location.class);
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.getSlug()).thenReturn(arenaId);
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(arena);
|
||||
when(templateStore.findById(templateId)).thenReturn(Optional.of(mock(Template.class)));
|
||||
SignChangeEvent event = event(lines, location);
|
||||
|
||||
ArenaSign result = subject.create(event);
|
||||
|
||||
assertThat(result.location, equalTo(location));
|
||||
assertThat(result.arenaId, equalTo(arenaId));
|
||||
assertThat(result.type, equalTo(signType));
|
||||
assertThat(result.templateId, equalTo(templateId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void slugifiedArenaId() {
|
||||
String arenaId = "Area 52";
|
||||
String arenaSlug = "area-52";
|
||||
String signType = "join";
|
||||
String templateId = "cool-sign";
|
||||
String[] lines = {"[MA]", arenaId, signType, templateId};
|
||||
Location location = mock(Location.class);
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.getSlug()).thenReturn(arenaSlug);
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(arena);
|
||||
when(templateStore.findById(templateId)).thenReturn(Optional.of(mock(Template.class)));
|
||||
SignChangeEvent event = event(lines, location);
|
||||
|
||||
ArenaSign result = subject.create(event);
|
||||
|
||||
assertThat(result.location, equalTo(location));
|
||||
assertThat(result.arenaId, equalTo(arenaSlug));
|
||||
assertThat(result.type, equalTo(signType.toLowerCase()));
|
||||
assertThat(result.templateId, equalTo(templateId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void caseInsensitiveSignType() {
|
||||
String arenaId = "castle";
|
||||
String signType = "jOiN";
|
||||
String templateId = "cool-sign";
|
||||
String[] lines = {"[MA]", arenaId, signType, templateId};
|
||||
Location location = mock(Location.class);
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.getSlug()).thenReturn(arenaId);
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(arena);
|
||||
when(templateStore.findById(templateId)).thenReturn(Optional.of(mock(Template.class)));
|
||||
SignChangeEvent event = event(lines, location);
|
||||
|
||||
ArenaSign result = subject.create(event);
|
||||
|
||||
assertThat(result.location, equalTo(location));
|
||||
assertThat(result.arenaId, equalTo(arenaId));
|
||||
assertThat(result.type, equalTo(signType.toLowerCase()));
|
||||
assertThat(result.templateId, equalTo(templateId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void signWithoutTemplateUsesType() {
|
||||
String arenaId = "castle";
|
||||
String signType = "join";
|
||||
String[] lines = {"[MA]", arenaId, signType, null};
|
||||
Location location = mock(Location.class);
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.getSlug()).thenReturn(arenaId);
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(arena);
|
||||
when(templateStore.findById(signType)).thenReturn(Optional.of(mock(Template.class)));
|
||||
SignChangeEvent event = event(lines, location);
|
||||
|
||||
ArenaSign result = subject.create(event);
|
||||
|
||||
assertThat(result.templateId, equalTo(signType));
|
||||
}
|
||||
|
||||
private SignChangeEvent event(String[] lines, Location location) {
|
||||
Block block = mock(Block.class);
|
||||
when(block.getLocation()).thenReturn(location);
|
||||
Player player = mock(Player.class);
|
||||
return new SignChangeEvent(block, player, lines);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class SignDataMigratorTest {
|
||||
|
||||
Path legacyFile;
|
||||
Path pendingFile;
|
||||
Yaml yaml;
|
||||
SignFile signFile;
|
||||
Logger log;
|
||||
|
||||
SignDataMigrator subject;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
legacyFile = Files.createTempFile("SignDataMigratorTest-", ".data.tmp");
|
||||
pendingFile = Files.createTempFile("SignDataMigratorTest-", ".tmp.tmp");
|
||||
yaml = mock(Yaml.class);
|
||||
signFile = mock(SignFile.class);
|
||||
log = mock(Logger.class);
|
||||
|
||||
subject = new SignDataMigrator(
|
||||
legacyFile,
|
||||
pendingFile,
|
||||
yaml,
|
||||
signFile,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardown() throws IOException {
|
||||
Files.deleteIfExists(legacyFile);
|
||||
Files.deleteIfExists(pendingFile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initDoesNothingIfNoLegacyFile() throws IOException {
|
||||
Files.delete(pendingFile);
|
||||
Files.delete(legacyFile);
|
||||
|
||||
subject.init();
|
||||
|
||||
verifyNoInteractions(yaml, log);
|
||||
assertThat(Files.exists(legacyFile), equalTo(false));
|
||||
assertThat(Files.exists(pendingFile), equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initCreatesPendingFileAndDeletesLegacyFile() throws IOException {
|
||||
Files.delete(pendingFile);
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
when(yaml.load(anyString())).thenReturn(map);
|
||||
|
||||
subject.init();
|
||||
|
||||
assertThat(Files.exists(legacyFile), equalTo(false));
|
||||
assertThat(Files.exists(pendingFile), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLogsInfoMessagesOnConversion() throws IOException {
|
||||
Files.delete(pendingFile);
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
when(yaml.load(anyString())).thenReturn(map);
|
||||
|
||||
subject.init();
|
||||
|
||||
verify(log, times(2)).info(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initMigratesToPartialFormat() throws IOException {
|
||||
Files.delete(pendingFile);
|
||||
List<Map<String, Object>> signs = new ArrayList<>();
|
||||
signs.add(sign("world", 46.0, 101.0, -191.0, "Area 52", "join", "cool-sign"));
|
||||
signs.add(sign("lazy", 47.0, 102.0, -192.0, "Mr. Bob's Bus", "info", "status"));
|
||||
signs.add(sign("eager", 48.0, 103.0, -194.0, "Mission: Impossible", "leave", "coward"));
|
||||
signs.add(sign("world", 49.0, 104.0, -198.0, "castle", "leave", "bye-bye"));
|
||||
Map<String, Object> root = new LinkedHashMap<>();
|
||||
root.put("signs", signs);
|
||||
when(yaml.load(anyString())).thenReturn(root);
|
||||
|
||||
subject.init();
|
||||
|
||||
List<String> lines = Files.readAllLines(pendingFile);
|
||||
assertThat(lines.size(), equalTo(signs.size()));
|
||||
assertThat(lines, hasItems(
|
||||
"world;46;101;-191;area-52;join;cool-sign",
|
||||
"lazy;47;102;-192;mr-bobs-bus;info;status",
|
||||
"eager;48;103;-194;mission-impossible;leave;coward",
|
||||
"world;49;104;-198;castle;leave;bye-bye"
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migrateDoesNothingIfNoPendingFile() throws IOException {
|
||||
Files.delete(pendingFile);
|
||||
World world = mock(World.class);
|
||||
|
||||
subject.migrate(world);
|
||||
|
||||
verifyNoInteractions(signFile, log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migrateDoesNothingIfNoMatchingLines() throws IOException {
|
||||
List<String> lines = Arrays.asList(
|
||||
"world;46;101;-191;castle;join;cool-sign",
|
||||
"lazy;47;102;-192;jungle;info;status",
|
||||
"world;48;103;-194;island;leave;coward"
|
||||
);
|
||||
Files.write(pendingFile, lines);
|
||||
String name = "not-world";
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn(name);
|
||||
|
||||
subject.migrate(world);
|
||||
|
||||
verifyNoInteractions(signFile, log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migratePassesMatchingLinesToSignFile() throws IOException {
|
||||
List<String> lines = Arrays.asList(
|
||||
"world;46;101;-191;castle;join;cool-sign",
|
||||
"lazy;47;102;-192;jungle;info;status",
|
||||
"world;48;103;-194;island;leave;coward"
|
||||
);
|
||||
Files.write(pendingFile, lines);
|
||||
String name = "world";
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn(name);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
|
||||
subject.migrate(world);
|
||||
|
||||
verify(signFile).append(id + ";" + lines.get(0));
|
||||
verify(signFile).append(id + ";" + lines.get(2));
|
||||
verify(signFile).save();
|
||||
verifyNoMoreInteractions(signFile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migrateDeletesMatchingLinesFromPendingFile() throws IOException {
|
||||
List<String> lines = Arrays.asList(
|
||||
"world;46;101;-191;castle;join;cool-sign",
|
||||
"lazy;47;102;-192;jungle;info;status",
|
||||
"world;48;103;-194;island;leave;coward"
|
||||
);
|
||||
Files.write(pendingFile, lines);
|
||||
String name = "world";
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn(name);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
|
||||
subject.migrate(world);
|
||||
|
||||
List<String> remaining = Files.readAllLines(pendingFile);
|
||||
assertThat(remaining, equalTo(lines.subList(1, 2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migrateLogsInfoMessageOnMigration() throws IOException {
|
||||
List<String> lines = Arrays.asList(
|
||||
"world;46;101;-191;castle;join;cool-sign",
|
||||
"lazy;47;102;-192;jungle;info;status",
|
||||
"world;48;103;-194;island;leave;coward"
|
||||
);
|
||||
Files.write(pendingFile, lines);
|
||||
String name = "world";
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn(name);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
|
||||
subject.migrate(world);
|
||||
|
||||
verify(log, times(2)).info(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migrateDeletesPendingFileOnCompletion() throws IOException {
|
||||
List<String> lines = Arrays.asList(
|
||||
"world;46;101;-191;castle;join;cool-sign",
|
||||
"world;48;103;-194;island;leave;coward"
|
||||
);
|
||||
Files.write(pendingFile, lines);
|
||||
String name = "world";
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn(name);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
|
||||
subject.migrate(world);
|
||||
|
||||
assertThat(Files.exists(pendingFile), equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migrateLogsAdditionallyOnCompletion() throws IOException {
|
||||
List<String> lines = Arrays.asList(
|
||||
"world;46;101;-191;castle;join;cool-sign",
|
||||
"world;48;103;-194;island;leave;coward"
|
||||
);
|
||||
Files.write(pendingFile, lines);
|
||||
String name = "world";
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn(name);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
|
||||
subject.migrate(world);
|
||||
|
||||
verify(log, times(3)).info(anyString());
|
||||
}
|
||||
|
||||
private Map<String, Object> sign(
|
||||
String world,
|
||||
double x,
|
||||
double y,
|
||||
double z,
|
||||
String arenaId,
|
||||
String type,
|
||||
String templateId
|
||||
) {
|
||||
Map<String, Object> location = new LinkedHashMap<>();
|
||||
location.put("==", "org.bukkit.Location");
|
||||
location.put("world", world);
|
||||
location.put("x", x);
|
||||
location.put("y", y);
|
||||
location.put("z", z);
|
||||
location.put("pitch", 0.0);
|
||||
location.put("yaw", 0.0);
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("==", "com.garbagemule.MobArena.signs.ArenaSign");
|
||||
result.put("arenaId", arenaId);
|
||||
result.put("location", location);
|
||||
result.put("templateId", templateId);
|
||||
result.put("type", type);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class SignFileTest {
|
||||
|
||||
Path file;
|
||||
|
||||
SignFile subject;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
file = Files.createTempFile("SignFileTest-", ".tmp");
|
||||
subject = new SignFile(file);
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardown() throws IOException {
|
||||
Files.delete(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyFileEmptyLines() throws IOException {
|
||||
List<String> result = subject.lines();
|
||||
|
||||
assertThat(result.isEmpty(), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyLinesIfAppendWithoutSave() throws IOException {
|
||||
String line1 = "We will";
|
||||
String line2 = "not be saved!";
|
||||
|
||||
subject.append(line1);
|
||||
subject.append(line2);
|
||||
List<String> result = subject.lines();
|
||||
|
||||
assertThat(result.isEmpty(), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void linePersistedOnSave() throws IOException {
|
||||
String line1 = "We will";
|
||||
String line2 = "be saved!";
|
||||
|
||||
subject.append(line1);
|
||||
subject.append(line2);
|
||||
subject.save();
|
||||
List<String> result = subject.lines();
|
||||
|
||||
assertThat(result, equalTo(Arrays.asList(line1, line2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lineLingersWithoutSave() throws IOException {
|
||||
String line1 = "We will";
|
||||
String line2 = "be saved!";
|
||||
|
||||
subject.append(line1);
|
||||
subject.append(line2);
|
||||
subject.save();
|
||||
subject.erase(line1);
|
||||
List<String> result = subject.lines();
|
||||
|
||||
assertThat(result, equalTo(Arrays.asList(line1, line2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lineRemovedOnSave() throws IOException {
|
||||
String line1 = "We will";
|
||||
String line2 = "be saved!";
|
||||
|
||||
subject.append(line1);
|
||||
subject.append(line2);
|
||||
subject.save();
|
||||
subject.erase(line1);
|
||||
subject.save();
|
||||
List<String> result = subject.lines();
|
||||
|
||||
assertThat(result, equalTo(Collections.singletonList(line2)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class SignReaderTest {
|
||||
|
||||
SignFile file;
|
||||
SignSerializer serializer;
|
||||
Logger log;
|
||||
|
||||
SignReader subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
file = mock(SignFile.class);
|
||||
serializer = mock(SignSerializer.class);
|
||||
log = mock(Logger.class);
|
||||
|
||||
subject = new SignReader(
|
||||
file,
|
||||
serializer,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializesNothingIfEmptyFile() throws IOException {
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
when(file.lines()).thenReturn(Collections.emptyList());
|
||||
|
||||
subject.read(world);
|
||||
|
||||
verifyNoInteractions(serializer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logsNothingIfEmptyFile() throws IOException {
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
when(file.lines()).thenReturn(Collections.emptyList());
|
||||
|
||||
subject.read(world);
|
||||
|
||||
verifyNoInteractions(log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializesLinesWithMatchingWorldId() throws IOException {
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
String line1 = "cafebeef-ea75-dead-babe-deadcafebeef;world;1;2;3;jungle;info;status";
|
||||
String line2 = id + ";world;1;2;3;castle;join;cool-sign";
|
||||
when(file.lines()).thenReturn(Arrays.asList(line1, line2));
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
when(serializer.deserialize(line2, world)).thenReturn(sign);
|
||||
|
||||
List<ArenaSign> result = subject.read(world);
|
||||
|
||||
assertThat(result.size(), equalTo(1));
|
||||
assertThat(result, hasItem(sign));
|
||||
verifyNoMoreInteractions(serializer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logsNothingOnSuccess() throws IOException {
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
String line = id + ";world;1;2;3;castle;join;cool-sign";
|
||||
when(file.lines()).thenReturn(Collections.singletonList(line));
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
when(serializer.deserialize(line, world)).thenReturn(sign);
|
||||
|
||||
subject.read(world);
|
||||
|
||||
verifyNoInteractions(log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skipLineIfSerializerThrows() throws IOException {
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
String line1 = id + ";world;1;2;3;jungle;info;status";
|
||||
String line2 = id + ";world;4;5;6;castle;join;cool-sign";
|
||||
when(file.lines()).thenReturn(Arrays.asList(line1, line2));
|
||||
IllegalArgumentException exception = new IllegalArgumentException("it's bad");
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
when(serializer.deserialize(line1, world)).thenThrow(exception);
|
||||
when(serializer.deserialize(line2, world)).thenReturn(sign);
|
||||
|
||||
List<ArenaSign> result = subject.read(world);
|
||||
|
||||
assertThat(result.size(), equalTo(1));
|
||||
assertThat(result, hasItem(sign));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorMessageIfSerializerThrows() throws IOException {
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
String line1 = id + ";world;1;2;3;jungle;info;status";
|
||||
String line2 = id + ";world;4;5;6;castle;join;cool-sign";
|
||||
when(file.lines()).thenReturn(Arrays.asList(line1, line2));
|
||||
IllegalArgumentException exception = new IllegalArgumentException("it's bad");
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
when(serializer.deserialize(line1, world)).thenThrow(exception);
|
||||
when(serializer.deserialize(line2, world)).thenReturn(sign);
|
||||
|
||||
subject.read(world);
|
||||
|
||||
verify(log).log(eq(Level.SEVERE), anyString(), eq(exception));
|
||||
verifyNoMoreInteractions(log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propagatesExceptionsFromFile() throws IOException {
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
IOException exception = new IOException("it's bad");
|
||||
when(file.lines()).thenThrow(exception);
|
||||
|
||||
Assert.assertThrows(
|
||||
IOException.class,
|
||||
() -> subject.read(world)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class SignRendererTest {
|
||||
|
||||
TemplateStore templateStore;
|
||||
ArenaMaster arenaMaster;
|
||||
RendersTemplate rendersTemplate;
|
||||
|
||||
SignRenderer subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
templateStore = mock(TemplateStore.class);
|
||||
arenaMaster = mock(ArenaMaster.class);
|
||||
rendersTemplate = mock(RendersTemplate.class);
|
||||
|
||||
subject = new SignRenderer(
|
||||
templateStore,
|
||||
arenaMaster,
|
||||
rendersTemplate
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersErrorMessageOnSignIfTemplateNotFound() {
|
||||
Location location = mock(Location.class);
|
||||
Block block = mock(Block.class);
|
||||
Sign target = mock(Sign.class);
|
||||
when(location.getBlock()).thenReturn(block);
|
||||
when(block.getState()).thenReturn(target);
|
||||
String templateId = "cool-sign";
|
||||
when(templateStore.findById(templateId)).thenReturn(Optional.empty());
|
||||
ArenaSign sign = new ArenaSign(location, templateId, "castle", "join");
|
||||
|
||||
subject.render(sign);
|
||||
|
||||
verify(target).setLine(0, ChatColor.RED + "[ERROR]");
|
||||
verify(target).setLine(1, "Template");
|
||||
verify(target).setLine(2, ChatColor.YELLOW + "cool-sign");
|
||||
verify(target).setLine(3, "not found :(");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersErrorMessageOnSignIfArenaNotFound() {
|
||||
Location location = mock(Location.class);
|
||||
Block block = mock(Block.class);
|
||||
Sign target = mock(Sign.class);
|
||||
when(location.getBlock()).thenReturn(block);
|
||||
when(block.getState()).thenReturn(target);
|
||||
String templateId = "cool-sign";
|
||||
Template template = mock(Template.class);
|
||||
String arenaId = "castle";
|
||||
when(templateStore.findById(templateId)).thenReturn(Optional.of(template));
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(null);
|
||||
ArenaSign sign = new ArenaSign(location, templateId, arenaId, "join");
|
||||
|
||||
subject.render(sign);
|
||||
|
||||
verify(target).setLine(0, ChatColor.RED + "[ERROR]");
|
||||
verify(target).setLine(1, "Arena");
|
||||
verify(target).setLine(2, ChatColor.YELLOW + arenaId);
|
||||
verify(target).setLine(3, "not found :(");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersResultsFromDelegateOnSign() {
|
||||
Location location = mock(Location.class);
|
||||
Block block = mock(Block.class);
|
||||
Sign target = mock(Sign.class);
|
||||
when(location.getBlock()).thenReturn(block);
|
||||
when(block.getState()).thenReturn(target);
|
||||
String templateId = "cool-sign";
|
||||
Template template = mock(Template.class);
|
||||
String arenaId = "castle";
|
||||
Arena arena = mock(Arena.class);
|
||||
String[] lines = new String[]{"this", "is", "a", "sign"};
|
||||
when(templateStore.findById(templateId)).thenReturn(Optional.of(template));
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(arena);
|
||||
when(rendersTemplate.render(template, arena)).thenReturn(lines);
|
||||
ArenaSign sign = new ArenaSign(location, templateId, arenaId, "join");
|
||||
|
||||
subject.render(sign);
|
||||
|
||||
verify(target).setLine(0, lines[0]);
|
||||
verify(target).setLine(1, lines[1]);
|
||||
verify(target).setLine(2, lines[2]);
|
||||
verify(target).setLine(3, lines[3]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersErrorMessageInEventIfTemplateNotFound() {
|
||||
String templateId = "cool-sign";
|
||||
when(templateStore.findById(templateId)).thenReturn(Optional.empty());
|
||||
ArenaSign sign = new ArenaSign(null, templateId, "castle", "join");
|
||||
SignChangeEvent event = mock(SignChangeEvent.class);
|
||||
|
||||
subject.render(sign, event);
|
||||
|
||||
verify(event).setLine(0, ChatColor.RED + "[ERROR]");
|
||||
verify(event).setLine(1, "Template");
|
||||
verify(event).setLine(2, ChatColor.YELLOW + "cool-sign");
|
||||
verify(event).setLine(3, "not found :(");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersErrorMessageInEventIfArenaNotFound() {
|
||||
String templateId = "cool-sign";
|
||||
Template template = mock(Template.class);
|
||||
String arenaId = "castle";
|
||||
when(templateStore.findById(templateId)).thenReturn(Optional.of(template));
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(null);
|
||||
ArenaSign sign = new ArenaSign(null, templateId, arenaId, "join");
|
||||
SignChangeEvent event = mock(SignChangeEvent.class);
|
||||
|
||||
subject.render(sign, event);
|
||||
|
||||
verify(event).setLine(0, ChatColor.RED + "[ERROR]");
|
||||
verify(event).setLine(1, "Arena");
|
||||
verify(event).setLine(2, ChatColor.YELLOW + arenaId);
|
||||
verify(event).setLine(3, "not found :(");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersResultsFromDelegateInEvent() {
|
||||
String templateId = "cool-sign";
|
||||
Template template = mock(Template.class);
|
||||
String arenaId = "castle";
|
||||
Arena arena = mock(Arena.class);
|
||||
String[] lines = new String[]{"this", "is", "a", "sign"};
|
||||
when(templateStore.findById(templateId)).thenReturn(Optional.of(template));
|
||||
when(arenaMaster.getArenaWithName(arenaId)).thenReturn(arena);
|
||||
when(rendersTemplate.render(template, arena)).thenReturn(lines);
|
||||
ArenaSign sign = new ArenaSign(null, templateId, arenaId, "join");
|
||||
SignChangeEvent event = mock(SignChangeEvent.class);
|
||||
|
||||
subject.render(sign, event);
|
||||
|
||||
verify(event).setLine(0, lines[0]);
|
||||
verify(event).setLine(1, lines[1]);
|
||||
verify(event).setLine(2, lines[2]);
|
||||
verify(event).setLine(3, lines[3]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class SignSerializerTest {
|
||||
|
||||
SignSerializer subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
subject = new SignSerializer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializeReturnsSemicolonSeparatedRepresentation() {
|
||||
World world = mock(World.class);
|
||||
Location location = new Location(world, 1, 2, 3);
|
||||
String arenaId = "castle";
|
||||
String type = "join";
|
||||
String templateId = "status";
|
||||
when(world.getUID()).thenReturn(UUID.fromString("cafebabe-ea75-dead-beef-deadcafebabe"));
|
||||
when(world.getName()).thenReturn("world");
|
||||
ArenaSign sign = new ArenaSign(location, templateId, arenaId, type);
|
||||
|
||||
String result = subject.serialize(sign);
|
||||
|
||||
String expected = "cafebabe-ea75-dead-beef-deadcafebabe;world;1;2;3;castle;join;status";
|
||||
assertThat(result, equalTo(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeThrowsIfLengthLessThan8() {
|
||||
World world = mock(World.class);
|
||||
String input = "1;2;3;4;5;6;7";
|
||||
|
||||
Assert.assertThrows(
|
||||
"Invalid input; expected 8 parts, got 7",
|
||||
IllegalArgumentException.class,
|
||||
() -> subject.deserialize(input, world)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeThrowsIfLengthGreaterThan8() {
|
||||
World world = mock(World.class);
|
||||
String input = "1;2;3;4;5;6;7;8;9";
|
||||
|
||||
Assert.assertThrows(
|
||||
"Invalid input; expected 8 parts, got 9",
|
||||
IllegalArgumentException.class,
|
||||
() -> subject.deserialize(input, world)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeThrowsIfWorldDoesNotMatchId() {
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(UUID.fromString("deadbeef-ea75-cafe-babe-deadcafebeef"));
|
||||
String input = "wrong-id;world;1;2;3;castle;join;status";
|
||||
|
||||
Assert.assertThrows(
|
||||
"World mismatch",
|
||||
IllegalArgumentException.class,
|
||||
() -> subject.deserialize(input, world)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeReturnsIfWorldMatchesId() {
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(UUID.fromString("cafebabe-ea75-dead-beef-deadcafebabe"));
|
||||
String input = "cafebabe-ea75-dead-beef-deadcafebabe;wrong-world;1;2;3;castle;join;status";
|
||||
|
||||
ArenaSign result = subject.deserialize(input, world);
|
||||
|
||||
Location location = new Location(world, 1, 2, 3);
|
||||
assertThat(result.location, equalTo(location));
|
||||
assertThat(result.arenaId, equalTo("castle"));
|
||||
assertThat(result.type, equalTo("join"));
|
||||
assertThat(result.templateId, equalTo("status"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeSerializeReflexivity() {
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
String name = "world";
|
||||
World world = mock(World.class);
|
||||
when(world.getName()).thenReturn(name);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
String line = id + ";" + name + ";1;2;3;castle;join;cool-sign";
|
||||
|
||||
String result = subject.serialize(subject.deserialize(line, world));
|
||||
|
||||
assertThat(result, equalTo(line));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializeDeserializeReflexivity() {
|
||||
String id = "cafebabe-ea75-dead-beef-deadcafebabe";
|
||||
World world = mock(World.class);
|
||||
when(world.getUID()).thenReturn(UUID.fromString(id));
|
||||
Location location = new Location(world, 1, 2, 3);
|
||||
ArenaSign sign = new ArenaSign(location, "cool-sign", "castle", "join");
|
||||
|
||||
ArenaSign result = subject.deserialize(subject.serialize(sign), world);
|
||||
|
||||
assertThat(result.location, equalTo(location));
|
||||
assertThat(result.arenaId, equalTo("castle"));
|
||||
assertThat(result.type, equalTo("join"));
|
||||
assertThat(result.templateId, equalTo("cool-sign"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalReturnsTrueIfStringsAreEqual() {
|
||||
String line = "cafebabe-ea75-dead-beef-deadcafebabe;world;1;2;3;castle;join;status";
|
||||
|
||||
boolean result = subject.equal(line, line);
|
||||
|
||||
assertThat(result, equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalReturnsTrueIfWorldIdAndLocationMatch() {
|
||||
String line1 = "cafebabe-ea75-dead-beef-deadcafebabe;right-world;1;2;3;jungle;leave;out";
|
||||
String line2 = "cafebabe-ea75-dead-beef-deadcafebabe;wrong-world;1;2;3;castle;join;status";
|
||||
|
||||
boolean result = subject.equal(line1, line2);
|
||||
|
||||
assertThat(result, equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalReturnsFalseIfOnlyWorldIdIsDifferent() {
|
||||
String line1 = "cafebabe-ea75-dead-beef-deadcafebabe;right-world;1;2;3;castle;join;status";
|
||||
String line2 = "deadbeef-feed-cafe-babe-a70ff1cecafe;right-world;1;2;3;castle;join;status";
|
||||
|
||||
boolean result = subject.equal(line1, line2);
|
||||
|
||||
assertThat(result, equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalReturnsFalseIfOnlyCoordsAreDifferent() {
|
||||
String line1 = "cafebabe-ea75-dead-beef-deadcafebabe;right-world;1;2;3;castle;join;status";
|
||||
String line2 = "cafebabe-ea75-dead-beef-deadcafebabe;right-world;4;5;6;castle;join;status";
|
||||
|
||||
boolean result = subject.equal(line1, line2);
|
||||
|
||||
assertThat(result, equalTo(false));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class SignStoreTest {
|
||||
|
||||
SignStore subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
subject = new SignStore();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByLocationReturnsNullIfSignDoesNotExist() {
|
||||
Location location = mock(Location.class);
|
||||
|
||||
ArenaSign result = subject.findByLocation(location);
|
||||
|
||||
assertThat(result, nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByLocationReturnsSignIfItExists() {
|
||||
Location location = mock(Location.class);
|
||||
ArenaSign sign = new ArenaSign(location, "cool-sign", "castle", "join");
|
||||
|
||||
subject.add(sign);
|
||||
ArenaSign result = subject.findByLocation(location);
|
||||
|
||||
assertThat(result, equalTo(sign));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByArenaIdReturnsEmptyListIfNoSignsMatch() {
|
||||
Location location1 = mock(Location.class);
|
||||
Location location2 = mock(Location.class);
|
||||
ArenaSign sign1 = new ArenaSign(location1, "cool-sign", "castle", "join");
|
||||
ArenaSign sign2 = new ArenaSign(location2, "lame-sign", "island", "leave");
|
||||
|
||||
subject.add(sign1);
|
||||
subject.add(sign2);
|
||||
List<ArenaSign> result = subject.findByArenaId("jungle");
|
||||
|
||||
assertThat(result.isEmpty(), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByArenaIdReturnsOnlyMatchingSigns() {
|
||||
Location location1 = mock(Location.class);
|
||||
Location location2 = mock(Location.class);
|
||||
Location location3 = mock(Location.class);
|
||||
ArenaSign sign1 = new ArenaSign(location1, "cool-sign", "castle", "join");
|
||||
ArenaSign sign2 = new ArenaSign(location2, "lame-sign", "island", "leave");
|
||||
ArenaSign sign3 = new ArenaSign(location3, "very-sign", "jungle", "info");
|
||||
|
||||
subject.add(sign1);
|
||||
subject.add(sign2);
|
||||
subject.add(sign3);
|
||||
List<ArenaSign> result = subject.findByArenaId("island");
|
||||
|
||||
assertThat(result.size(), equalTo(1));
|
||||
assertThat(result, hasItem(sign2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeReturnsNullIfSignDoesNotExist() {
|
||||
Location location = mock(Location.class);
|
||||
ArenaSign sign = new ArenaSign(location, "cool-sign", "castle", "join");
|
||||
|
||||
ArenaSign result = subject.removeByLocation(location);
|
||||
|
||||
assertThat(result, nullValue());
|
||||
|
||||
subject.add(sign);
|
||||
assertThat(subject.removeByLocation(location), equalTo(sign));
|
||||
|
||||
assertThat(subject.removeByLocation(location), nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeReturnsSignIfItExists() {
|
||||
Location location = mock(Location.class);
|
||||
ArenaSign sign = new ArenaSign(location, "cool-sign", "castle", "join");
|
||||
|
||||
subject.add(sign);
|
||||
ArenaSign result = subject.removeByLocation(location);
|
||||
|
||||
assertThat(result, equalTo(sign));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeReturnsNullIfSignWasRemoved() {
|
||||
Location location = mock(Location.class);
|
||||
ArenaSign sign = new ArenaSign(location, "cool-sign", "castle", "join");
|
||||
|
||||
subject.add(sign);
|
||||
subject.removeByLocation(location);
|
||||
ArenaSign result = subject.removeByLocation(location);
|
||||
|
||||
assertThat(result, nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeByWorldReturnsOnlyMatchingSigns() {
|
||||
World world1 = mock(World.class);
|
||||
World world2 = mock(World.class);
|
||||
Location location1 = mock(Location.class);
|
||||
Location location2 = mock(Location.class);
|
||||
when(location1.getWorld()).thenReturn(world1);
|
||||
when(location2.getWorld()).thenReturn(world2);
|
||||
ArenaSign sign1 = new ArenaSign(location1, "lame-sign", "jungle", "info");
|
||||
ArenaSign sign2 = new ArenaSign(location2, "cool-sign", "castle", "join");
|
||||
|
||||
subject.add(sign1);
|
||||
subject.add(sign2);
|
||||
List<ArenaSign> result = subject.removeByWorld(world2);
|
||||
|
||||
assertThat(result, not(hasItem(sign1)));
|
||||
assertThat(result, hasItem(sign2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeByWorldReturnsEmptyListIfSignsWereRemoved() {
|
||||
World world1 = mock(World.class);
|
||||
World world2 = mock(World.class);
|
||||
Location location1 = mock(Location.class);
|
||||
Location location2 = mock(Location.class);
|
||||
when(location1.getWorld()).thenReturn(world1);
|
||||
when(location2.getWorld()).thenReturn(world2);
|
||||
ArenaSign sign1 = new ArenaSign(location1, "lame-sign", "jungle", "info");
|
||||
ArenaSign sign2 = new ArenaSign(location2, "cool-sign", "castle", "join");
|
||||
|
||||
subject.add(sign1);
|
||||
subject.add(sign2);
|
||||
subject.removeByWorld(world2);
|
||||
List<ArenaSign> result = subject.removeByWorld(world2);
|
||||
|
||||
assertThat(result.isEmpty(), equalTo(true));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class SignWriterTest {
|
||||
|
||||
SignFile file;
|
||||
SignSerializer serializer;
|
||||
Logger log;
|
||||
|
||||
SignWriter subject;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
file = mock(SignFile.class);
|
||||
serializer = mock(SignSerializer.class);
|
||||
log = mock(Logger.class);
|
||||
|
||||
subject = new SignWriter(
|
||||
file,
|
||||
serializer,
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCallsAppendWithSerializedSign() throws IOException {
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
String line = "some arbitrary serialization";
|
||||
when(serializer.serialize(sign)).thenReturn(line);
|
||||
|
||||
subject.write(sign);
|
||||
|
||||
verify(file).append(line);
|
||||
verify(file).save();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCallsEraseOnConflicts() throws IOException {
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
String line = "some arbitrary serialization";
|
||||
String c1 = "some conflicting line";
|
||||
String c2 = "some non-conflicting line";
|
||||
String c3 = "some other conflicting line";
|
||||
when(serializer.serialize(sign)).thenReturn(line);
|
||||
when(serializer.equal(c1, line)).thenReturn(true);
|
||||
when(serializer.equal(c2, line)).thenReturn(false);
|
||||
when(serializer.equal(c3, line)).thenReturn(true);
|
||||
when(file.lines()).thenReturn(Arrays.asList(c1, c2, c3));
|
||||
|
||||
subject.write(sign);
|
||||
|
||||
verify(file).erase(c1);
|
||||
verify(file).erase(c3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeLogsWarningOnConflicts() throws IOException {
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
String line = "some arbitrary serialization";
|
||||
String c1 = "some conflicting line";
|
||||
String c2 = "some non-conflicting line";
|
||||
String c3 = "some other conflicting line";
|
||||
when(serializer.serialize(sign)).thenReturn(line);
|
||||
when(serializer.equal(c1, line)).thenReturn(true);
|
||||
when(serializer.equal(c2, line)).thenReturn(false);
|
||||
when(serializer.equal(c3, line)).thenReturn(true);
|
||||
when(file.lines()).thenReturn(Arrays.asList(c1, c2, c3));
|
||||
|
||||
subject.write(sign);
|
||||
|
||||
verify(log, times(2)).warning(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successfulWriteLogsNothing() throws IOException {
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
String line = "some arbitrary serialization";
|
||||
when(serializer.serialize(sign)).thenReturn(line);
|
||||
|
||||
subject.write(sign);
|
||||
|
||||
verifyNoInteractions(log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eraseCallsEraseWithIdentifiedLineOnly() throws IOException {
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
String line = "right-id;wrong-name;some other stuff";
|
||||
String c1 = "wrong-id;wrong-name;some stuff";
|
||||
String c2 = "right-id;right-name;some other stuff";
|
||||
String c3 = "wrong-id;wrong-name;some more stuff";
|
||||
when(serializer.serialize(sign)).thenReturn(line);
|
||||
when(serializer.equal(anyString(), anyString())).thenReturn(false);
|
||||
when(serializer.equal(c2, line)).thenReturn(true);
|
||||
when(file.lines()).thenReturn(Arrays.asList(c1, c2, c3));
|
||||
|
||||
subject.erase(sign);
|
||||
|
||||
verify(file).erase(c2);
|
||||
verify(file).save();
|
||||
verifyNoMoreInteractions(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successfulEraseLogsNothing() throws IOException {
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
String line = "right-id;wrong-name;some other stuff";
|
||||
String candiate1 = "wrong-id;wrong-name;some stuff";
|
||||
String candiate2 = "right-id;right-name;some other stuff";
|
||||
String candiate3 = "wrong-id;wrong-name;some more stuff";
|
||||
when(serializer.serialize(sign)).thenReturn(line);
|
||||
when(serializer.equal(anyString(), anyString())).thenReturn(false);
|
||||
when(serializer.equal(candiate2, line)).thenReturn(true);
|
||||
when(file.lines()).thenReturn(Arrays.asList(candiate1, candiate2, candiate3));
|
||||
|
||||
subject.erase(sign);
|
||||
|
||||
verifyNoInteractions(log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eraseBailsOnNoMatch() throws IOException {
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
String line = "right-id;right-name;some right stuff";
|
||||
List<String> candidates = Arrays.asList("a", "b", "c");
|
||||
when(serializer.serialize(sign)).thenReturn(line);
|
||||
when(serializer.equal(anyString(), anyString())).thenReturn(false);
|
||||
when(file.lines()).thenReturn(candidates);
|
||||
|
||||
subject.erase(sign);
|
||||
|
||||
verify(file, never()).erase(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eraseLogsWarningOnNoMatch() throws IOException {
|
||||
ArenaSign sign = new ArenaSign(null, "cool-sign", "castle", "join");
|
||||
String line = "right-id;right-name;some right stuff";
|
||||
List<String> candidates = Arrays.asList("a", "b", "c");
|
||||
when(serializer.serialize(sign)).thenReturn(line);
|
||||
when(serializer.equal(anyString(), anyString())).thenReturn(false);
|
||||
when(file.lines()).thenReturn(candidates);
|
||||
|
||||
subject.erase(sign);
|
||||
|
||||
verify(log).warning(anyString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
package com.garbagemule.MobArena.signs;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||
import org.bukkit.Location;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@RunWith(MockitoJUnitRunner.StrictStubs.class)
|
||||
public class StoresNewSignTest {
|
||||
|
||||
ArenaMaster arenaMaster;
|
||||
TemplateStore templateStore;
|
||||
SignStore signStore;
|
||||
SavesSignStore savesSignStore;
|
||||
|
||||
StoresNewSign subject;
|
||||
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
arenaMaster = mock(ArenaMaster.class);
|
||||
when(arenaMaster.getArenaWithName(any()))
|
||||
.thenReturn(null);
|
||||
|
||||
templateStore = mock(TemplateStore.class);
|
||||
when(templateStore.findById(any()))
|
||||
.thenReturn(Optional.empty());
|
||||
|
||||
signStore = mock(SignStore.class);
|
||||
|
||||
savesSignStore = mock(SavesSignStore.class);
|
||||
|
||||
subject = new StoresNewSign(
|
||||
arenaMaster,
|
||||
templateStore,
|
||||
signStore,
|
||||
savesSignStore
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void throwOnNonExistentArena() {
|
||||
Location location = mock(Location.class);
|
||||
String arenaId = "castle";
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
|
||||
subject.store(location, arenaId, "", "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void throwOnNonExistentTemplate() {
|
||||
Location location = mock(Location.class);
|
||||
String arenaId = "castle";
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arenaMaster.getArenaWithName(arenaId))
|
||||
.thenReturn(arena);
|
||||
String templateId = "template";
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
|
||||
subject.store(location, arenaId, templateId, "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void throwOnNonInvalidSignType() {
|
||||
Location location = mock(Location.class);
|
||||
String arenaId = "castle";
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arenaMaster.getArenaWithName(arenaId))
|
||||
.thenReturn(arena);
|
||||
String templateId = "a very nice template";
|
||||
Template template = template(templateId);
|
||||
when(templateStore.findById(templateId))
|
||||
.thenReturn(Optional.of(template));
|
||||
String signType = "not a real sign type";
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
|
||||
subject.store(location, arenaId, templateId, signType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void storesSignAndWritesToDisk() {
|
||||
Location location = mock(Location.class);
|
||||
String arenaId = "castle";
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arenaMaster.getArenaWithName(arenaId))
|
||||
.thenReturn(arena);
|
||||
String templateId = "a very nice template";
|
||||
Template template = template(templateId);
|
||||
when(templateStore.findById(templateId))
|
||||
.thenReturn(Optional.of(template));
|
||||
String signType = "join";
|
||||
|
||||
subject.store(location, arenaId, templateId, signType);
|
||||
|
||||
ArgumentCaptor<ArenaSign> captor = ArgumentCaptor.forClass(ArenaSign.class);
|
||||
verify(signStore).store(captor.capture());
|
||||
verify(savesSignStore).save(signStore);
|
||||
ArenaSign sign = captor.getValue();
|
||||
assertThat(sign.location, equalTo(location));
|
||||
assertThat(sign.arenaId, equalTo(arenaId));
|
||||
assertThat(sign.templateId, equalTo(templateId));
|
||||
assertThat(sign.type, equalTo(signType));
|
||||
}
|
||||
|
||||
private Template template(String id) {
|
||||
return new Template.Builder(id)
|
||||
.withBase(new String[]{"", "", "", ""})
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user