#727 Instantiate ExecutableCommand objects in CommandHandler

- Change CommandDescription to contain a reference to ExecutableCommand class only
- Instantiate the actual ExecutableCommand objects in CommandHandler
This commit is contained in:
ljacqu
2016-06-04 21:13:38 +02:00
parent c6778b566d
commit 26ac466035
19 changed files with 320 additions and 331 deletions
@@ -1,13 +1,9 @@
package fr.xephi.authme.command;
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
import org.bukkit.configuration.MemorySection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Collection;
@@ -22,9 +18,6 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
/**
* Checks that the commands declared in plugin.yml correspond
@@ -59,14 +52,7 @@ public class CommandConsistencyTest {
*/
@SuppressWarnings("unchecked")
private static Collection<List<String>> initializeCommands() {
AuthMeServiceInitializer injector = mock(AuthMeServiceInitializer.class);
given(injector.newInstance(any(Class.class))).willAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return mock((Class<?>) invocation.getArguments()[0]);
}
});
CommandInitializer initializer = new CommandInitializer(injector);
CommandInitializer initializer = new CommandInitializer();
Collection<List<String>> commandLabels = new ArrayList<>();
for (CommandDescription baseCommand : initializer.getCommands()) {
commandLabels.add(baseCommand.getLabels());
@@ -1,17 +1,25 @@
package fr.xephi.authme.command;
import com.google.common.collect.Sets;
import fr.xephi.authme.command.TestCommandsUtil.TestLoginCommand;
import fr.xephi.authme.command.TestCommandsUtil.TestRegisterCommand;
import fr.xephi.authme.command.TestCommandsUtil.TestUnregisterCommand;
import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
import fr.xephi.authme.permission.PermissionsManager;
import org.bukkit.command.CommandSender;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import java.util.Collections;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import static fr.xephi.authme.command.FoundResultStatus.INCORRECT_ARGUMENTS;
import static fr.xephi.authme.command.FoundResultStatus.MISSING_BASE_COMMAND;
@@ -19,7 +27,6 @@ import static fr.xephi.authme.command.FoundResultStatus.NO_PERMISSION;
import static fr.xephi.authme.command.FoundResultStatus.SUCCESS;
import static fr.xephi.authme.command.FoundResultStatus.UNKNOWN_LABEL;
import static java.util.Arrays.asList;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
@@ -29,6 +36,7 @@ import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -43,20 +51,53 @@ import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class CommandHandlerTest {
@InjectMocks
private CommandHandler handler;
@Mock
private CommandService commandService;
private AuthMeServiceInitializer initializer;
@Mock
private CommandInitializer commandInitializer;
@Mock
private CommandMapper commandMapper;
@Mock
private PermissionsManager permissionsManager;
@Mock
private HelpProvider helpProvider;
@Captor
private ArgumentCaptor<List<String>> captor;
private Map<Class<? extends ExecutableCommand>, ExecutableCommand> mockedCommands = new HashMap<>();
@Before
@SuppressWarnings("unchecked")
public void initializeCommandMapper() {
given(commandMapper.getCommandClasses()).willReturn(Sets.newHashSet(ExecutableCommand.class,
TestLoginCommand.class, TestRegisterCommand.class, TestUnregisterCommand.class));
setInjectorToMockExecutableCommandClasses();
handler = new CommandHandler(initializer, commandMapper, permissionsManager, helpProvider);
}
/**
* Makes the initializer return a mock when {@link AuthMeServiceInitializer#newInstance(Class)} is invoked
* with (a child of) ExecutableCommand.class. The mocks the initializer creates are stored in {@link #mockedCommands}.
* <p>
* The {@link CommandMapper} is mocked in {@link #initializeCommandMapper()} to return certain test classes.
*/
private void setInjectorToMockExecutableCommandClasses() {
given(initializer.newInstance(any(Class.class))).willAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Class<?> clazz = (Class<?>) invocation.getArguments()[0];
if (ExecutableCommand.class.isAssignableFrom(clazz)) {
@SuppressWarnings("unchecked")
Class<? extends ExecutableCommand> commandClass = (Class<? extends ExecutableCommand>) clazz;
ExecutableCommand mock = mock(commandClass);
mockedCommands.put(commandClass, mock);
return mock;
}
throw new IllegalStateException("Unexpected class '" + clazz.getName()
+ "': Not a child of ExecutableCommand");
}
});
}
@Test
@@ -66,22 +107,18 @@ public class CommandHandlerTest {
String[] bukkitArgs = {"Login", "myPass"};
CommandSender sender = mock(CommandSender.class);
ExecutableCommand executableCommand = mock(ExecutableCommand.class);
CommandDescription command = mock(CommandDescription.class);
given(command.getExecutableCommand()).willReturn(executableCommand);
given(commandService.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class)))
doReturn(TestLoginCommand.class).when(command).getExecutableCommand();
given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class)))
.willReturn(new FoundCommandResult(command, asList("Authme", "Login"), asList("myPass"), 0.0, SUCCESS));
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
verify(commandService).mapPartsToCommand(eq(sender), captor.capture());
assertThat(captor.getValue(), contains("Authme", "Login", "myPass"));
verify(executableCommand).executeCommand(eq(sender), captor.capture());
assertThat(captor.getValue(), contains("myPass"));
ExecutableCommand executableCommand = mockedCommands.get(TestLoginCommand.class);
verify(commandMapper).mapPartsToCommand(sender, asList("Authme", "Login", "myPass"));
verify(executableCommand).executeCommand(sender, asList("myPass"));
// Ensure that no error message was issued to the command sender
verify(sender, never()).sendMessage(anyString());
}
@@ -93,15 +130,14 @@ public class CommandHandlerTest {
String[] bukkitArgs = {"testPlayer"};
CommandSender sender = mock(CommandSender.class);
CommandDescription command = mock(CommandDescription.class);
given(commandService.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class)))
given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class)))
.willReturn(new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 0.0, NO_PERMISSION));
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
verify(commandService).mapPartsToCommand(eq(sender), captor.capture());
assertThat(captor.getValue(), contains("unreg", "testPlayer"));
verify(commandMapper).mapPartsToCommand(sender, asList("unreg", "testPlayer"));
verify(command, never()).getExecutableCommand();
verify(sender).sendMessage(argThat(containsString("don't have permission")));
}
@@ -113,7 +149,7 @@ public class CommandHandlerTest {
String[] bukkitArgs = {"testPlayer"};
CommandSender sender = mock(CommandSender.class);
CommandDescription command = mock(CommandDescription.class);
given(commandService.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn(
given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn(
new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 0.0, INCORRECT_ARGUMENTS));
given(permissionsManager.hasPermission(sender, command.getPermission())).willReturn(true);
@@ -121,9 +157,7 @@ public class CommandHandlerTest {
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
verify(commandService).mapPartsToCommand(eq(sender), captor.capture());
assertThat(captor.getValue(), contains("unreg", "testPlayer"));
verify(commandMapper).mapPartsToCommand(sender, asList("unreg", "testPlayer"));
verify(command, never()).getExecutableCommand();
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(sender, atLeastOnce()).sendMessage(captor.capture());
@@ -137,7 +171,7 @@ public class CommandHandlerTest {
String[] bukkitArgs = {"testPlayer"};
CommandSender sender = mock(CommandSender.class);
CommandDescription command = mock(CommandDescription.class);
given(commandService.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn(
given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn(
new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 0.0, INCORRECT_ARGUMENTS));
given(permissionsManager.hasPermission(sender, command.getPermission())).willReturn(false);
@@ -145,9 +179,7 @@ public class CommandHandlerTest {
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
verify(commandService).mapPartsToCommand(eq(sender), captor.capture());
assertThat(captor.getValue(), contains("unreg", "testPlayer"));
verify(commandMapper).mapPartsToCommand(sender, asList("unreg", "testPlayer"));
verify(command, never()).getExecutableCommand();
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(sender).sendMessage(captor.capture());
@@ -161,15 +193,14 @@ public class CommandHandlerTest {
String[] bukkitArgs = {"testPlayer"};
CommandSender sender = mock(CommandSender.class);
CommandDescription command = mock(CommandDescription.class);
given(commandService.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn(
given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn(
new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 0.0, MISSING_BASE_COMMAND));
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
verify(commandService).mapPartsToCommand(eq(sender), captor.capture());
assertThat(captor.getValue(), contains("unreg", "testPlayer"));
verify(commandMapper).mapPartsToCommand(sender, asList("unreg", "testPlayer"));
verify(command, never()).getExecutableCommand();
verify(sender).sendMessage(argThat(containsString("Failed to parse")));
}
@@ -182,16 +213,14 @@ public class CommandHandlerTest {
CommandSender sender = mock(CommandSender.class);
CommandDescription command = mock(CommandDescription.class);
given(command.getLabels()).willReturn(Collections.singletonList("test_cmd"));
given(commandService.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn(
given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn(
new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 0.01, UNKNOWN_LABEL));
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
verify(commandService).mapPartsToCommand(eq(sender), captor.capture());
assertThat(captor.getValue(), contains("unreg", "testPlayer"));
verify(commandMapper).mapPartsToCommand(sender, asList("unreg", "testPlayer"));
verify(command, never()).getExecutableCommand();
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(sender, times(3)).sendMessage(captor.capture());
@@ -210,16 +239,14 @@ public class CommandHandlerTest {
CommandSender sender = mock(CommandSender.class);
CommandDescription command = mock(CommandDescription.class);
given(command.getLabels()).willReturn(Collections.singletonList("test_cmd"));
given(commandService.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn(
given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn(
new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 1.0, UNKNOWN_LABEL));
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
verify(commandService).mapPartsToCommand(eq(sender), captor.capture());
assertThat(captor.getValue(), contains("unreg", "testPlayer"));
verify(commandMapper).mapPartsToCommand(sender, asList("unreg", "testPlayer"));
verify(command, never()).getExecutableCommand();
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(sender, times(2)).sendMessage(captor.capture());
@@ -232,25 +259,21 @@ public class CommandHandlerTest {
public void shouldStripWhitespace() {
// given
String bukkitLabel = "AuthMe";
String[] bukkitArgs = {" ", "", "LOGIN", " ", "testArg", " "};
String[] bukkitArgs = {" ", "", "REGISTER", " ", "testArg", " "};
CommandSender sender = mock(CommandSender.class);
ExecutableCommand executableCommand = mock(ExecutableCommand.class);
CommandDescription command = mock(CommandDescription.class);
given(command.getExecutableCommand()).willReturn(executableCommand);
given(commandService.mapPartsToCommand(eq(sender), anyListOf(String.class)))
.willReturn(new FoundCommandResult(command, asList("AuthMe", "LOGIN"), asList("testArg"), 0.0, SUCCESS));
doReturn(TestRegisterCommand.class).when(command).getExecutableCommand();
given(commandMapper.mapPartsToCommand(eq(sender), anyListOf(String.class)))
.willReturn(new FoundCommandResult(command, asList("AuthMe", "REGISTER"), asList("testArg"), 0.0, SUCCESS));
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
verify(commandService).mapPartsToCommand(eq(sender), captor.capture());
assertThat(captor.getValue(), contains("AuthMe", "LOGIN", "testArg"));
verify(command.getExecutableCommand()).executeCommand(eq(sender), captor.capture());
assertThat(captor.getValue(), contains("testArg"));
ExecutableCommand executableCommand = mockedCommands.get(TestRegisterCommand.class);
verify(commandMapper).mapPartsToCommand(sender, asList("AuthMe", "REGISTER", "testArg"));
verify(executableCommand).executeCommand(sender, asList("testArg"));
verify(sender, never()).sendMessage(anyString());
}
@@ -1,13 +1,10 @@
package fr.xephi.authme.command;
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.util.StringUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Collection;
@@ -20,14 +17,8 @@ import java.util.regex.Pattern;
import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Test for {@link CommandInitializer} to guarantee the integrity of the defined commands.
@@ -45,15 +36,7 @@ public class CommandInitializerTest {
@SuppressWarnings("unchecked")
@BeforeClass
public static void initializeCommandCollection() {
AuthMeServiceInitializer initializer = mock(AuthMeServiceInitializer.class);
when(initializer.newInstance(any(Class.class))).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) {
Class<?> clazz = (Class<?>) invocation.getArguments()[0];
return mock(clazz);
}
});
CommandInitializer commandInitializer = new CommandInitializer(initializer);
CommandInitializer commandInitializer = new CommandInitializer();
commands = commandInitializer.getCommands();
}
@@ -174,34 +157,6 @@ public class CommandInitializerTest {
walkThroughCommands(commands, descriptionTester);
}
/**
* Check that the implementation of {@link ExecutableCommand} a command points to is the same for each type:
* it is inefficient to instantiate the same type multiple times.
*/
@Test
public void shouldNotHaveMultipleInstancesOfSameExecutableCommandSubType() {
// given
final Map<Class<? extends ExecutableCommand>, ExecutableCommand> implementations = new HashMap<>();
BiConsumer descriptionTester = new BiConsumer() {
@Override
public void accept(CommandDescription command, int depth) {
assertThat(command.getExecutableCommand(), not(nullValue()));
ExecutableCommand commandExec = command.getExecutableCommand();
ExecutableCommand storedExec = implementations.get(command.getExecutableCommand().getClass());
if (storedExec == null) {
implementations.put(commandExec.getClass(), commandExec);
} else {
assertSame("has same implementation of '" + storedExec.getClass().getName() + "' for command with "
+ "parent " + (command.getParent() == null ? "null" : command.getParent().getLabels()),
storedExec, commandExec);
}
}
};
// when/then
walkThroughCommands(commands, descriptionTester);
}
@Test
public void shouldHaveOptionalArgumentsAfterMandatoryOnes() {
// given
@@ -291,7 +246,7 @@ public class CommandInitializerTest {
}
private void testCollectionForCommand(CommandDescription command, int argCount,
Map<Class<? extends ExecutableCommand>, Integer> collection) {
final Class<? extends ExecutableCommand> clazz = command.getExecutableCommand().getClass();
final Class<? extends ExecutableCommand> clazz = command.getExecutableCommand();
Integer existingCount = collection.get(clazz);
if (existingCount == null) {
collection.put(clazz, argCount);
@@ -1,5 +1,9 @@
package fr.xephi.authme.command;
import fr.xephi.authme.command.TestCommandsUtil.TestLoginCommand;
import fr.xephi.authme.command.TestCommandsUtil.TestRegisterCommand;
import fr.xephi.authme.command.TestCommandsUtil.TestUnregisterCommand;
import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;
import org.bukkit.command.CommandSender;
@@ -14,6 +18,7 @@ import static fr.xephi.authme.command.TestCommandsUtil.getCommandWithLabel;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
@@ -275,4 +280,14 @@ public class CommandMapperTest {
assertThat(result.getArguments(), contains(parts.get(2)));
}
@Test
public void shouldReturnExecutableCommandClasses() {
// given / when
Set<Class<? extends ExecutableCommand>> commandClasses = mapper.getCommandClasses();
// then
assertThat(commandClasses, containsInAnyOrder(ExecutableCommand.class, HelpCommand.class,
TestLoginCommand.class, TestRegisterCommand.class, TestUnregisterCommand.class));
}
}
@@ -1,6 +1,5 @@
package fr.xephi.authme.command;
import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.NewSetting;
@@ -11,19 +10,14 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
@@ -35,10 +29,6 @@ public class CommandServiceTest {
@InjectMocks
private CommandService commandService;
@Mock
private CommandMapper commandMapper;
@Mock
private HelpProvider helpProvider;
@Mock
private Messages messages;
@Mock
private NewSetting settings;
@@ -69,40 +59,6 @@ public class CommandServiceTest {
verify(messages).send(sender, MessageKey.ANTIBOT_AUTO_ENABLED_MESSAGE, "10");
}
@Test
public void shouldMapPartsToCommand() {
// given
CommandSender sender = mock(Player.class);
List<String> commandParts = Arrays.asList("authme", "test", "test2");
FoundCommandResult givenResult = mock(FoundCommandResult.class);
given(commandMapper.mapPartsToCommand(sender, commandParts)).willReturn(givenResult);
// when
FoundCommandResult result = commandService.mapPartsToCommand(sender, commandParts);
// then
assertThat(result, equalTo(givenResult));
verify(commandMapper).mapPartsToCommand(sender, commandParts);
}
@Test
public void shouldOutputHelp() {
// given
CommandSender sender = mock(CommandSender.class);
FoundCommandResult result = mock(FoundCommandResult.class);
int options = HelpProvider.SHOW_LONG_DESCRIPTION;
List<String> messages = Arrays.asList("Test message 1", "Other test message", "Third message for test");
given(helpProvider.printHelp(sender, result, options)).willReturn(messages);
// when
commandService.outputHelp(sender, result, options);
// then
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(sender, times(3)).sendMessage(captor.capture());
assertThat(captor.getAllValues(), equalTo(messages));
}
@Test
public void shouldRetrieveMessage() {
// given
@@ -9,7 +9,6 @@ import java.util.List;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
/**
* Test for {@link CommandUtils}.
@@ -59,14 +58,14 @@ public class CommandUtilsTest {
.labels("authme", "auth")
.description("Base")
.detailedDescription("Test base command.")
.executableCommand(mock(ExecutableCommand.class))
.executableCommand(ExecutableCommand.class)
.build();
CommandDescription command = CommandDescription.builder()
.parent(base)
.labels("help", "h", "?")
.description("Child")
.detailedDescription("Test child command.")
.executableCommand(mock(ExecutableCommand.class))
.executableCommand(ExecutableCommand.class)
.build();
// when
@@ -131,6 +130,6 @@ public class CommandUtilsTest {
.labels("authme", "auth")
.description("Base")
.detailedDescription("Test base command.")
.executableCommand(mock(ExecutableCommand.class));
.executableCommand(ExecutableCommand.class);
}
}
@@ -4,6 +4,7 @@ import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PlayerPermission;
import org.bukkit.command.CommandSender;
import java.util.Collection;
import java.util.List;
@@ -12,7 +13,6 @@ import java.util.Set;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.mockito.Mockito.mock;
/**
* Util class for generating and retrieving test commands.
@@ -29,22 +29,24 @@ public final class TestCommandsUtil {
*/
public static Set<CommandDescription> generateCommands() {
// Register /authme
CommandDescription authMeBase = createCommand(null, null, singletonList("authme"));
CommandDescription authMeBase = createCommand(null, null, singletonList("authme"), ExecutableCommand.class);
// Register /authme login <password>
createCommand(PlayerPermission.LOGIN, authMeBase, singletonList("login"), newArgument("password", false));
createCommand(PlayerPermission.LOGIN, authMeBase, singletonList("login"),
TestLoginCommand.class, newArgument("password", false));
// Register /authme register <password> <confirmation>, aliases: /authme reg, /authme r
createCommand(PlayerPermission.LOGIN, authMeBase, asList("register", "reg", "r"),
createCommand(PlayerPermission.LOGIN, authMeBase, asList("register", "reg", "r"), TestRegisterCommand.class,
newArgument("password", false), newArgument("confirmation", false));
// Register /email [player]
CommandDescription emailBase = createCommand(null, null, singletonList("email"), newArgument("player", true));
CommandDescription emailBase = createCommand(null, null, singletonList("email"), ExecutableCommand.class,
newArgument("player", true));
// Register /email helptest -- use only to test for help command arguments special case
CommandDescription.builder().parent(emailBase).labels("helptest").executableCommand(mock(HelpCommand.class))
CommandDescription.builder().parent(emailBase).labels("helptest").executableCommand(HelpCommand.class)
.description("test").detailedDescription("Test.").withArgument("Query", "", false).build();
// Register /unregister <player>, alias: /unreg
CommandDescription unregisterBase = createCommand(AdminPermission.UNREGISTER, null,
asList("unregister", "unreg"), newArgument("player", false));
asList("unregister", "unreg"), TestUnregisterCommand.class, newArgument("player", false));
return newHashSet(authMeBase, emailBase, unregisterBase);
}
@@ -83,14 +85,15 @@ public final class TestCommandsUtil {
/** Shortcut command to initialize a new test command. */
private static CommandDescription createCommand(PermissionNode permission, CommandDescription parent,
List<String> labels, CommandArgumentDescription... arguments) {
List<String> labels, Class<? extends ExecutableCommand> commandClass,
CommandArgumentDescription... arguments) {
CommandDescription.CommandBuilder command = CommandDescription.builder()
.labels(labels)
.parent(parent)
.permission(permission)
.description(labels.get(0) + " cmd")
.detailedDescription("'" + labels.get(0) + "' test command")
.executableCommand(mock(ExecutableCommand.class));
.executableCommand(commandClass);
if (arguments != null && arguments.length > 0) {
for (CommandArgumentDescription argument : arguments) {
@@ -106,4 +109,25 @@ public final class TestCommandsUtil {
return new CommandArgumentDescription(label, "'" + label + "' argument description", isOptional);
}
public static class TestLoginCommand implements ExecutableCommand {
@Override
public void executeCommand(CommandSender sender, List<String> arguments) {
// noop
}
}
public static class TestRegisterCommand implements ExecutableCommand {
@Override
public void executeCommand(CommandSender sender, List<String> arguments) {
// noop
}
}
public static class TestUnregisterCommand implements ExecutableCommand {
@Override
public void executeCommand(CommandSender sender, List<String> arguments) {
// noop
}
}
}
@@ -1,7 +1,7 @@
package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AntiBot;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.CommandMapper;
import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.command.help.HelpProvider;
import org.bukkit.command.CommandSender;
@@ -35,7 +35,10 @@ public class SwitchAntiBotCommandTest {
private AntiBot antiBot;
@Mock
private CommandService service;
private CommandMapper commandMapper;
@Mock
private HelpProvider helpProvider;
@Test
public void shouldReturnAntiBotState() {
@@ -81,7 +84,7 @@ public class SwitchAntiBotCommandTest {
// given
CommandSender sender = mock(CommandSender.class);
FoundCommandResult foundCommandResult = mock(FoundCommandResult.class);
given(service.mapPartsToCommand(sender, asList("authme", "antibot"))).willReturn(foundCommandResult);
given(commandMapper.mapPartsToCommand(sender, asList("authme", "antibot"))).willReturn(foundCommandResult);
// when
command.executeCommand(sender, Collections.singletonList("wrong"));
@@ -89,6 +92,6 @@ public class SwitchAntiBotCommandTest {
// then
verify(antiBot, never()).overrideAntiBotStatus(anyBoolean());
verify(sender).sendMessage(argThat(containsString("Invalid")));
verify(service).outputHelp(sender, foundCommandResult, HelpProvider.SHOW_ARGUMENTS);
verify(helpProvider).outputHelp(sender, foundCommandResult, HelpProvider.SHOW_ARGUMENTS);
}
}
@@ -13,6 +13,7 @@ import org.bukkit.command.CommandSender;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import java.util.Arrays;
import java.util.Collections;
@@ -33,7 +34,9 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Test for {@link HelpProvider}.
@@ -67,9 +70,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Arrays.asList("authme", "login"));
// when
List<String> lines = helpProvider.printHelp(sender, result, SHOW_LONG_DESCRIPTION);
helpProvider.outputHelp(sender, result, SHOW_LONG_DESCRIPTION);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(5));
assertThat(lines.get(0), containsString(HELP_HEADER + " HELP"));
assertThat(removeColors(lines.get(1)), containsString("Command: /authme login <password>"));
@@ -85,9 +89,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Arrays.asList("authme", "reg"));
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_ARGUMENTS);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_ARGUMENTS);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(4));
assertThat(lines.get(0), containsString(HELP_HEADER + " HELP"));
assertThat(removeColors(lines.get(1)), equalTo("Arguments:"));
@@ -102,9 +107,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Collections.singletonList("email"));
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_ARGUMENTS);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_ARGUMENTS);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(3));
assertThat(removeColors(lines.get(2)), containsString("player: 'player' argument description (Optional)"));
}
@@ -117,9 +123,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Collections.singletonList("authme"));
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_ARGUMENTS);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_ARGUMENTS);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(1)); // only has the help banner
}
@@ -133,9 +140,10 @@ public class HelpProviderTest {
given(permissionsManager.hasPermission(sender, command.getPermission())).willReturn(true);
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_PERMISSIONS);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_PERMISSIONS);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(5));
assertThat(removeColors(lines.get(1)), containsString("Permissions:"));
assertThat(removeColors(lines.get(2)),
@@ -154,9 +162,10 @@ public class HelpProviderTest {
given(permissionsManager.hasPermission(sender, command.getPermission())).willReturn(false);
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_PERMISSIONS);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_PERMISSIONS);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(5));
assertThat(removeColors(lines.get(1)), containsString("Permissions:"));
assertThat(removeColors(lines.get(2)),
@@ -172,9 +181,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Collections.singletonList("authme"));
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_PERMISSIONS);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_PERMISSIONS);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(1));
}
@@ -187,9 +197,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Collections.singletonList("test"));
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_PERMISSIONS);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_PERMISSIONS);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(1));
}
@@ -200,9 +211,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Arrays.asList("authme", "reg"));
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_ALTERNATIVES);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_ALTERNATIVES);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(4));
assertThat(removeColors(lines.get(1)), containsString("Alternatives:"));
assertThat(removeColors(lines.get(2)), containsString("/authme register <password> <confirmation>"));
@@ -216,9 +228,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Arrays.asList("authme", "login"));
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_ALTERNATIVES);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_ALTERNATIVES);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(1));
}
@@ -229,9 +242,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Collections.singletonList("authme"));
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_CHILDREN);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_CHILDREN);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(4));
assertThat(removeColors(lines.get(1)), containsString("Commands:"));
assertThat(removeColors(lines.get(2)), containsString("/authme login: login cmd"));
@@ -245,9 +259,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Collections.singletonList("authme"));
// when
List<String> lines = helpProvider.printHelp(sender, result, HIDE_COMMAND | SHOW_CHILDREN);
helpProvider.outputHelp(sender, result, HIDE_COMMAND | SHOW_CHILDREN);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(1));
}
@@ -258,9 +273,10 @@ public class HelpProviderTest {
Collections.<String>emptyList(), 0.0, FoundResultStatus.UNKNOWN_LABEL);
// when
List<String> lines = helpProvider.printHelp(sender, result, ALL_OPTIONS);
helpProvider.outputHelp(sender, result, ALL_OPTIONS);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(1));
assertThat(lines.get(0), containsString("Failed to retrieve any help information"));
}
@@ -276,9 +292,10 @@ public class HelpProviderTest {
FoundCommandResult result = newFoundResult(command, Arrays.asList("authme", "ragister"));
// when
List<String> lines = helpProvider.printHelp(sender, result, 0);
helpProvider.outputHelp(sender, result, 0);
// then
List<String> lines = getLines(sender);
assertThat(lines, hasSize(2));
assertThat(lines.get(0), containsString(HELP_HEADER + " HELP"));
assertThat(removeColors(lines.get(1)), containsString("Command: /authme register <password> <confirmation>"));
@@ -328,5 +345,11 @@ public class HelpProviderTest {
}
return str;
}
private static List<String> getLines(CommandSender sender) {
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(sender, atLeastOnce()).sendMessage(captor.capture());
return captor.getAllValues();
}
}
@@ -4,11 +4,7 @@ import fr.xephi.authme.command.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandInitializer;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
import fr.xephi.authme.permission.PermissionNode;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import tools.utils.AutoToolTask;
import tools.utils.FileUtils;
import tools.utils.TagValue.NestedTagValue;
@@ -19,10 +15,6 @@ import java.util.Collection;
import java.util.Scanner;
import java.util.Set;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class CommandPageCreater implements AutoToolTask {
private static final String OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "commands.md";
@@ -39,7 +31,7 @@ public class CommandPageCreater implements AutoToolTask {
@Override
public void executeDefault() {
CommandInitializer commandInitializer = new CommandInitializer(getMockInitializer());
CommandInitializer commandInitializer = new CommandInitializer();
final Set<CommandDescription> baseCommands = commandInitializer.getCommands();
NestedTagValue commandTags = new NestedTagValue();
addCommandsInfo(commandTags, baseCommands);
@@ -84,25 +76,4 @@ public class CommandPageCreater implements AutoToolTask {
}
return result.toString();
}
/**
* Creates an initializer mock that returns mocks of any {@link ExecutableCommand} subclasses passed to it.
*
* @return the initializer mock
*/
@SuppressWarnings("unchecked")
private static AuthMeServiceInitializer getMockInitializer() {
AuthMeServiceInitializer initializer = mock(AuthMeServiceInitializer.class);
when(initializer.newInstance(isA(Class.class))).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Class<?> clazz = (Class<?>) invocation.getArguments()[0];
if (ExecutableCommand.class.isAssignableFrom(clazz)) {
return mock(clazz);
}
throw new IllegalStateException("Unexpected request to instantiate class of type " + clazz.getName());
}
});
return initializer;
}
}