diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index f496ae8..9653356 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -18,10 +18,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 - uses: actions/setup-java@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v4 with: - java-version: '11' + java-version: '17' distribution: 'temurin' cache: maven diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/maven-deploy.yml new file mode 100644 index 0000000..44ddb92 --- /dev/null +++ b/.github/workflows/maven-deploy.yml @@ -0,0 +1,20 @@ +name: Publish package to GitHub Packages +on: + release: + types: [created] +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + - name: Publish package + run: mvn --batch-mode deploy + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3138f0e..64311b5 100644 --- a/pom.xml +++ b/pom.xml @@ -4,13 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - me.hgsoft.minecraft.devcommand - DevCommand - 0.0.2-SNAPSHOT + dev.hugog.minecraft + dev-command + 0.0.3 11 11 + UTF-8 @@ -25,7 +26,7 @@ org.spigotmc spigot-api - 1.19.2-R0.1-SNAPSHOT + 1.20.6-R0.1-SNAPSHOT provided @@ -53,6 +54,12 @@ 2.18.0 + + com.google.inject + guice + 5.1.0 + + org.junit.jupiter junit-jupiter @@ -63,14 +70,14 @@ org.mockito mockito-core - 4.7.0 + 4.8.0 test org.mockito mockito-junit-jupiter - 4.7.0 + 4.8.0 test @@ -89,15 +96,16 @@ maven-clean-plugin - 3.1.0 + 3.3.1 maven-resources-plugin - 3.0.2 + 3.3.1 org.apache.maven.plugins maven-compiler-plugin + 3.11.0 11 11 @@ -105,19 +113,40 @@ maven-surefire-plugin - 2.22.1 + 3.1.2 + + + maven-failsafe-plugin + 3.1.2 + + + + integration-test + verify + + + maven-jar-plugin - 3.0.2 + 3.3.0 maven-install-plugin - 2.5.2 + 3.1.1 + + + dev-command-depository + GitHub Packages DevCommand Repository + https://maven.pkg.github.com/Hugo1307/DevCommand + + + + \ No newline at end of file diff --git a/src/main/java/dev/hugog/minecraft/dev_command/DevCommand.java b/src/main/java/dev/hugog/minecraft/dev_command/DevCommand.java new file mode 100644 index 0000000..f9b9776 --- /dev/null +++ b/src/main/java/dev/hugog/minecraft/dev_command/DevCommand.java @@ -0,0 +1,37 @@ +package dev.hugog.minecraft.dev_command; + +import com.google.inject.Inject; +import com.google.inject.Injector; +import lombok.Getter; +import dev.hugog.minecraft.dev_command.commands.handler.CommandHandler; +import dev.hugog.minecraft.dev_command.dependencies.DependencyHandler; +import dev.hugog.minecraft.dev_command.injection.GuiceBinderModule; + +@Getter +public final class DevCommand { + + private static DevCommand instance; + + @Inject + private CommandHandler commandHandler; + @Inject + private DependencyHandler dependencyHandler; + + private DevCommand() { + initDependencyInjectionModules(); + } + + public static DevCommand getOrCreateInstance() { + if (instance == null) { + instance = new DevCommand(); + } + return instance; + } + + private void initDependencyInjectionModules() { + GuiceBinderModule guiceBinderModule = new GuiceBinderModule(); + Injector injector = guiceBinderModule.createInjector(); + injector.injectMembers(this); + } + +} diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/annotations/ArgsValidation.java b/src/main/java/dev/hugog/minecraft/dev_command/annotations/ArgsValidation.java similarity index 50% rename from src/main/java/me/hgsoft/minecraft/devcommand/annotations/ArgsValidation.java rename to src/main/java/dev/hugog/minecraft/dev_command/annotations/ArgsValidation.java index 117d689..c176449 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/annotations/ArgsValidation.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/annotations/ArgsValidation.java @@ -1,6 +1,6 @@ -package me.hgsoft.minecraft.devcommand.annotations; +package dev.hugog.minecraft.dev_command.annotations; -import me.hgsoft.minecraft.devcommand.validators.CommandArgument; +import dev.hugog.minecraft.dev_command.validators.CommandArgument; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -10,7 +10,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ArgsValidation { - Class>[] argsTypes(); - int mandatory() default 0; + Class>[] mandatoryArgs() default {}; + Class>[] optionalArgs() default {}; } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/annotations/Command.java b/src/main/java/dev/hugog/minecraft/dev_command/annotations/Command.java similarity index 78% rename from src/main/java/me/hgsoft/minecraft/devcommand/annotations/Command.java rename to src/main/java/dev/hugog/minecraft/dev_command/annotations/Command.java index 1964fb8..0e25cdc 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/annotations/Command.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/annotations/Command.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.annotations; +package dev.hugog.minecraft.dev_command.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -12,5 +12,6 @@ String alias(); String description() default ""; String permission() default ""; + boolean isPlayerOnly() default false; } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/annotations/Dependencies.java b/src/main/java/dev/hugog/minecraft/dev_command/annotations/Dependencies.java similarity index 84% rename from src/main/java/me/hgsoft/minecraft/devcommand/annotations/Dependencies.java rename to src/main/java/dev/hugog/minecraft/dev_command/annotations/Dependencies.java index 24f1a34..ec40292 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/annotations/Dependencies.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/annotations/Dependencies.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.annotations; +package dev.hugog.minecraft.dev_command.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/commands/BukkitDevCommand.java b/src/main/java/dev/hugog/minecraft/dev_command/commands/BukkitDevCommand.java similarity index 72% rename from src/main/java/me/hgsoft/minecraft/devcommand/commands/BukkitDevCommand.java rename to src/main/java/dev/hugog/minecraft/dev_command/commands/BukkitDevCommand.java index cf40c18..c963515 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/commands/BukkitDevCommand.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/commands/BukkitDevCommand.java @@ -1,16 +1,18 @@ -package me.hgsoft.minecraft.devcommand.commands; +package dev.hugog.minecraft.dev_command.commands; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; import lombok.Generated; import lombok.Getter; -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.dependencies.DependencyHandler; -import me.hgsoft.minecraft.devcommand.exceptions.ArgumentsConfigException; -import me.hgsoft.minecraft.devcommand.exceptions.PermissionConfigException; -import me.hgsoft.minecraft.devcommand.factories.ArgumentFactory; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.validators.CommandArgument; -import me.hgsoft.minecraft.devcommand.validators.ICommandArgument; +import dev.hugog.minecraft.dev_command.DevCommand; +import dev.hugog.minecraft.dev_command.dependencies.DependencyHandler; +import dev.hugog.minecraft.dev_command.exceptions.ArgumentsConfigException; +import dev.hugog.minecraft.dev_command.exceptions.PermissionConfigException; +import dev.hugog.minecraft.dev_command.factories.ArgumentFactory; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.validators.CommandArgument; +import dev.hugog.minecraft.dev_command.validators.ICommandArgument; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import java.util.Arrays; import java.util.List; @@ -32,10 +34,20 @@ public BukkitDevCommand(BukkitCommandData commandData, CommandSender commandSend @Override public boolean hasPermissionToExecuteCommand() { + if (commandData.getPermission() == null) { throw new PermissionConfigException(String.format("Unable to find the permission for the command %s. Have you configured any permission at all?", commandData.getName())); } + return commandSender.hasPermission(commandData.getPermission()); + + } + + @Override + public boolean canSenderExecuteCommand() { + if (commandData.isPlayerOnly()) + return commandSender instanceof Player; + return true; } @Override @@ -57,6 +69,11 @@ public boolean hasValidArgs() { for (int mandatoryArgumentIdx = 0; mandatoryArgumentIdx < mandatoryArguments.length; mandatoryArgumentIdx++) { String currentArgument = mandatoryArguments[mandatoryArgumentIdx]; + + if (commandData.getMandatoryArguments() == null) { + continue; + } + Class> expectedCommandArgumentClass = commandData.getMandatoryArguments()[mandatoryArgumentIdx]; ICommandArgument expectedCommandArgument = new ArgumentFactory(currentArgument).generate(expectedCommandArgumentClass); @@ -91,7 +108,7 @@ public boolean hasValidArgs() { @Override public List getDependencies() { - DependencyHandler dependencyHandler = DependencyHandler.createOrGetInstance(); + DependencyHandler dependencyHandler = DevCommand.getOrCreateInstance().getDependencyHandler(); Integration commandIntegration = commandData.getIntegration(); return Arrays.stream(getCommandData().getDependencies()) @@ -100,4 +117,10 @@ public List getDependencies() { } + @Override + public Object getDependency(Class dependencyClass) { + DependencyHandler dependencyHandler = DevCommand.getOrCreateInstance().getDependencyHandler(); + return dependencyHandler.getDependencyInstance(commandData.getIntegration(), dependencyClass); + } + } \ No newline at end of file diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/commands/IDevCommand.java b/src/main/java/dev/hugog/minecraft/dev_command/commands/IDevCommand.java similarity index 57% rename from src/main/java/me/hgsoft/minecraft/devcommand/commands/IDevCommand.java rename to src/main/java/dev/hugog/minecraft/dev_command/commands/IDevCommand.java index fabea92..22c4e4d 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/commands/IDevCommand.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/commands/IDevCommand.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.commands; +package dev.hugog.minecraft.dev_command.commands; import java.util.List; @@ -7,6 +7,8 @@ public interface IDevCommand { void execute(); boolean hasPermissionToExecuteCommand(); boolean hasValidArgs(); + boolean canSenderExecuteCommand(); List getDependencies(); + Object getDependency(Class dependencyClass); } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/commands/builder/BukkitCommandDataBuilder.java b/src/main/java/dev/hugog/minecraft/dev_command/commands/builder/BukkitCommandDataBuilder.java similarity index 78% rename from src/main/java/me/hgsoft/minecraft/devcommand/commands/builder/BukkitCommandDataBuilder.java rename to src/main/java/dev/hugog/minecraft/dev_command/commands/builder/BukkitCommandDataBuilder.java index f2b7555..e2dae25 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/commands/builder/BukkitCommandDataBuilder.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/commands/builder/BukkitCommandDataBuilder.java @@ -1,9 +1,9 @@ -package me.hgsoft.minecraft.devcommand.commands.builder; +package dev.hugog.minecraft.dev_command.commands.builder; -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.commands.IDevCommand; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.validators.CommandArgument; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; +import dev.hugog.minecraft.dev_command.commands.IDevCommand; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.validators.CommandArgument; public class BukkitCommandDataBuilder implements ICommandBuilder { @@ -14,6 +14,7 @@ public class BukkitCommandDataBuilder implements ICommandBuilder executor; private Class[] dependencies; private String permission; + private boolean isPlayerOnly; private Class>[] mandatoryArguments; private Class>[] optionalArguments; @@ -74,8 +75,13 @@ public final BukkitCommandDataBuilder withIntegration(Integration integration) { return this; } + public final BukkitCommandDataBuilder withPlayerOnly(boolean isPlayerOnly) { + this.isPlayerOnly = isPlayerOnly; + return this; + } + public BukkitCommandData build() { - return new BukkitCommandData(name, alias, description, integration, dependencies, executor, permission, mandatoryArguments, optionalArguments); + return new BukkitCommandData(name, alias, description, integration, dependencies, executor, permission, isPlayerOnly, mandatoryArguments, optionalArguments); } } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/commands/builder/ICommandBuilder.java b/src/main/java/dev/hugog/minecraft/dev_command/commands/builder/ICommandBuilder.java similarity index 68% rename from src/main/java/me/hgsoft/minecraft/devcommand/commands/builder/ICommandBuilder.java rename to src/main/java/dev/hugog/minecraft/dev_command/commands/builder/ICommandBuilder.java index 103c354..6c8f51d 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/commands/builder/ICommandBuilder.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/commands/builder/ICommandBuilder.java @@ -1,6 +1,6 @@ -package me.hgsoft.minecraft.devcommand.commands.builder; +package dev.hugog.minecraft.dev_command.commands.builder; -import me.hgsoft.minecraft.devcommand.commands.IDevCommand; +import dev.hugog.minecraft.dev_command.commands.IDevCommand; public interface ICommandBuilder, C> { diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/commands/data/AbstractCommandData.java b/src/main/java/dev/hugog/minecraft/dev_command/commands/data/AbstractCommandData.java similarity index 72% rename from src/main/java/me/hgsoft/minecraft/devcommand/commands/data/AbstractCommandData.java rename to src/main/java/dev/hugog/minecraft/dev_command/commands/data/AbstractCommandData.java index a2d71ca..541766c 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/commands/data/AbstractCommandData.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/commands/data/AbstractCommandData.java @@ -1,11 +1,11 @@ -package me.hgsoft.minecraft.devcommand.commands.data; +package dev.hugog.minecraft.dev_command.commands.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.ToString; -import me.hgsoft.minecraft.devcommand.commands.IDevCommand; -import me.hgsoft.minecraft.devcommand.integration.Integration; +import dev.hugog.minecraft.dev_command.commands.IDevCommand; +import dev.hugog.minecraft.dev_command.integration.Integration; @Getter @RequiredArgsConstructor diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/commands/data/BukkitCommandData.java b/src/main/java/dev/hugog/minecraft/dev_command/commands/data/BukkitCommandData.java similarity index 59% rename from src/main/java/me/hgsoft/minecraft/devcommand/commands/data/BukkitCommandData.java rename to src/main/java/dev/hugog/minecraft/dev_command/commands/data/BukkitCommandData.java index 7d49096..70bf626 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/commands/data/BukkitCommandData.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/commands/data/BukkitCommandData.java @@ -1,11 +1,11 @@ -package me.hgsoft.minecraft.devcommand.commands.data; +package dev.hugog.minecraft.dev_command.commands.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; -import me.hgsoft.minecraft.devcommand.commands.IDevCommand; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.validators.CommandArgument; +import dev.hugog.minecraft.dev_command.commands.IDevCommand; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.validators.CommandArgument; @Getter @ToString(callSuper = true) @@ -13,12 +13,14 @@ public class BukkitCommandData extends AbstractCommandData { private final String permission; + private final boolean isPlayerOnly; private final Class>[] mandatoryArguments; private final Class>[] optionalArguments; - public BukkitCommandData(String name, String alias, String description, Integration integration, Class[] dependencies, Class executor, String permission, Class>[] mandatoryArguments, Class>[] optionalArguments) { + public BukkitCommandData(String name, String alias, String description, Integration integration, Class[] dependencies, Class executor, String permission, boolean isPlayerOnly, Class>[] mandatoryArguments, Class>[] optionalArguments) { super(name, alias, description, integration, executor, dependencies); this.permission = permission; + this.isPlayerOnly = isPlayerOnly; this.mandatoryArguments = mandatoryArguments; this.optionalArguments = optionalArguments; } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/commands/executors/DevCommandExecutor.java b/src/main/java/dev/hugog/minecraft/dev_command/commands/executors/DevCommandExecutor.java similarity index 74% rename from src/main/java/me/hgsoft/minecraft/devcommand/commands/executors/DevCommandExecutor.java rename to src/main/java/dev/hugog/minecraft/dev_command/commands/executors/DevCommandExecutor.java index 41c990a..59435a8 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/commands/executors/DevCommandExecutor.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/commands/executors/DevCommandExecutor.java @@ -1,8 +1,9 @@ -package me.hgsoft.minecraft.devcommand.commands.executors; +package dev.hugog.minecraft.dev_command.commands.executors; +import dev.hugog.minecraft.dev_command.DevCommand; +import dev.hugog.minecraft.dev_command.commands.handler.CommandHandler; +import dev.hugog.minecraft.dev_command.integration.Integration; import lombok.NonNull; -import me.hgsoft.minecraft.devcommand.CommandHandler; -import me.hgsoft.minecraft.devcommand.integration.Integration; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -29,7 +30,8 @@ public boolean onCommand(@NonNull CommandSender commandSender, @NonNull Command return false; } - CommandHandler commandHandler = CommandHandler.createOrGetInstance(); + DevCommand devCommand = DevCommand.getOrCreateInstance(); + CommandHandler commandHandler = devCommand.getCommandHandler(); // No arguments for the command. if (args.length == 0) { @@ -39,7 +41,7 @@ public boolean onCommand(@NonNull CommandSender commandSender, @NonNull Command commandHandler.executeCommandByAlias(integration, args[0], commandSender); return true; } else { - commandHandler.executeCommandByAlias(integration, args[0], commandSender, Arrays.copyOfRange(args, 1, args.length)); + commandHandler.executeCommandByAlias(integration, args[0], commandSender, Arrays.copyOfRange(args, 1, args.length, String[].class)); return true; } diff --git a/src/main/java/dev/hugog/minecraft/dev_command/commands/handler/CommandHandler.java b/src/main/java/dev/hugog/minecraft/dev_command/commands/handler/CommandHandler.java new file mode 100644 index 0000000..b80a810 --- /dev/null +++ b/src/main/java/dev/hugog/minecraft/dev_command/commands/handler/CommandHandler.java @@ -0,0 +1,91 @@ +package dev.hugog.minecraft.dev_command.commands.handler; + +import com.google.inject.Inject; +import dev.hugog.minecraft.dev_command.commands.IDevCommand; +import dev.hugog.minecraft.dev_command.commands.data.AbstractCommandData; +import dev.hugog.minecraft.dev_command.discovery.CommandDiscoveryService; +import dev.hugog.minecraft.dev_command.exceptions.AutoConfigurationException; +import dev.hugog.minecraft.dev_command.exceptions.InvalidIntegrationException; +import dev.hugog.minecraft.dev_command.factories.CommandFactory; +import dev.hugog.minecraft.dev_command.factories.IObjectFactory; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.registry.commands.CommandRegistry; +import lombok.NonNull; +import lombok.extern.log4j.Log4j2; + +import java.util.List; + +@Log4j2 +public class CommandHandler { + + private final CommandRegistry commandRegistry; + + @Inject + public CommandHandler(CommandRegistry commandRegistry) { + this.commandRegistry = commandRegistry; + } + + public void registerCommand(Integration integration, AbstractCommandData command) { + commandRegistry.add(integration, command); + } + + public boolean executeCommandByAlias(Integration integration, String alias, Object... commandArgs) { + + IObjectFactory commandFactory = new CommandFactory(commandArgs); + List registeredCommandsForIntegration = commandRegistry.getValues(integration); + + if (registeredCommandsForIntegration == null) { + return false; + } + + for (AbstractCommandData registeredCommand : registeredCommandsForIntegration) { + + if (registeredCommand.getAlias().equalsIgnoreCase(alias)) { + commandFactory.generate(registeredCommand).execute(); + return true; + } + + } + + return false; + + } + + public void initCommandsAutoConfiguration(@NonNull Integration integration) { + + validateIntegration(integration); + + initCommandsAutoConfiguration(integration, new CommandDiscoveryService(integration)); + + } + + public void initCommandsAutoConfiguration(@NonNull Integration integration, CommandDiscoveryService commandDiscoveryService) { + + validateIntegration(integration); + + if (commandDiscoveryService.containsCommandsWithRepeatedAliases()) { + throw new AutoConfigurationException("Unable to autoconfigure commands as there are commands with repeated aliases."); + } + + commandDiscoveryService.getDiscoveredCommandsData().forEach(abstractCommand -> { + if (abstractCommand != null) { + registerCommand(integration, abstractCommand); + log.info(String.format("Loaded command '%s' from '%s'.", abstractCommand.getAlias(), integration.getName())); + } else { + log.info("Failed to load at least one of the commands..."); + } + }); + + } + + public List getRegisteredCommands(Integration integration) { + return commandRegistry.getValues(integration); + } + + private void validateIntegration(Integration integration) { + if (!integration.isValid()) { + throw new InvalidIntegrationException(String.format("The integration %s contained an invalid base package.", integration.getName())); + } + } + +} diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/dependencies/DependencyHandler.java b/src/main/java/dev/hugog/minecraft/dev_command/dependencies/DependencyHandler.java similarity index 56% rename from src/main/java/me/hgsoft/minecraft/devcommand/dependencies/DependencyHandler.java rename to src/main/java/dev/hugog/minecraft/dev_command/dependencies/DependencyHandler.java index 51cee05..c1ef99c 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/dependencies/DependencyHandler.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/dependencies/DependencyHandler.java @@ -1,19 +1,25 @@ -package me.hgsoft.minecraft.devcommand.dependencies; +package dev.hugog.minecraft.dev_command.dependencies; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.registry.dependencies.DependencyRegistry; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.registry.dependencies.DependencyRegistry; import java.util.Arrays; import java.util.List; +@Singleton public class DependencyHandler { - private static DependencyHandler instance; + private final DependencyRegistry dependencyRegistry; - private DependencyHandler() { } + @Inject + public DependencyHandler(DependencyRegistry dependencyRegistry) { + this.dependencyRegistry = dependencyRegistry; + } public void registerDependency(Integration integration, Object dependency) { - DependencyRegistry.getInstance().add(integration, dependency); + dependencyRegistry.add(integration, dependency); } public void registerDependencies(Integration integration, Object... dependencies) { Arrays.stream(dependencies).forEach(dependency -> registerDependency(integration, dependency)); @@ -21,7 +27,6 @@ public void registerDependencies(Integration integration, Object... dependencies public Object getDependencyInstance(Integration integration, Class dependencyClass) { - DependencyRegistry dependencyRegistry = DependencyRegistry.getInstance(); List registeredDependencies = dependencyRegistry.getValues(integration); for (Object registeredDependency : registeredDependencies) { @@ -34,11 +39,4 @@ public Object getDependencyInstance(Integration integration, Class dependency } - public static DependencyHandler createOrGetInstance() { - if (instance == null) { - instance = new DependencyHandler(); - } - return instance; - } - } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/discovery/CommandDiscoveryService.java b/src/main/java/dev/hugog/minecraft/dev_command/discovery/CommandDiscoveryService.java similarity index 53% rename from src/main/java/me/hgsoft/minecraft/devcommand/discovery/CommandDiscoveryService.java rename to src/main/java/dev/hugog/minecraft/dev_command/discovery/CommandDiscoveryService.java index e8a0a76..adfe98b 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/discovery/CommandDiscoveryService.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/discovery/CommandDiscoveryService.java @@ -1,16 +1,17 @@ -package me.hgsoft.minecraft.devcommand.discovery; - +package dev.hugog.minecraft.dev_command.discovery; + +import dev.hugog.minecraft.dev_command.annotations.ArgsValidation; +import dev.hugog.minecraft.dev_command.annotations.Command; +import dev.hugog.minecraft.dev_command.annotations.Dependencies; +import dev.hugog.minecraft.dev_command.commands.IDevCommand; +import dev.hugog.minecraft.dev_command.commands.builder.BukkitCommandDataBuilder; +import dev.hugog.minecraft.dev_command.commands.data.AbstractCommandData; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.validators.CommandArgument; import lombok.Getter; -import me.hgsoft.minecraft.devcommand.annotations.ArgsValidation; -import me.hgsoft.minecraft.devcommand.annotations.Command; -import me.hgsoft.minecraft.devcommand.annotations.Dependencies; -import me.hgsoft.minecraft.devcommand.commands.data.AbstractCommandData; -import me.hgsoft.minecraft.devcommand.commands.builder.BukkitCommandDataBuilder; -import me.hgsoft.minecraft.devcommand.commands.IDevCommand; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.validators.CommandArgument; import org.reflections.Reflections; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -21,27 +22,40 @@ public class CommandDiscoveryService { private final Reflections reflectionUtils; public CommandDiscoveryService(Integration integration) { + this(integration, new Reflections(integration.getBasePackage())); + } + + public CommandDiscoveryService(Integration integration, Reflections reflectionUtils) { this.integration = integration; - this.reflectionUtils = new Reflections(integration.getBasePackage()); + this.reflectionUtils = reflectionUtils; } - public Set> getCommandExecutorClasses() { + public Set> getCommandClasses() { return reflectionUtils.getTypesAnnotatedWith(Command.class) .stream() .filter(this::containsCommandAnnotation) .filter(this::isValidCommandClass) - .map(this::getCommandExecutor) + .map(this::getCommandClass) .collect(Collectors.toSet()); } - public AbstractCommandData executorClassToCommand(Class commandExecutorClass) { + public List getDiscoveredCommandsData() { + return getCommandClasses() + .stream() + .map(this::commandClassToCommandData) + .collect(Collectors.toList()); + } + + public AbstractCommandData commandClassToCommandData(Class commandExecutorClass) { - Class>[] argsValidationTypes = null; + Class>[] mandatoryArgsValidationTypes = null; + Class>[] optionalArgsValidationTypes = null; Class[] commandDependencies = null; if (containsArgsValidator(commandExecutorClass)) { ArgsValidation executorArgsValidationAnnotation = getArgsValidationAnnotation(commandExecutorClass); - argsValidationTypes = executorArgsValidationAnnotation.argsTypes(); + mandatoryArgsValidationTypes = executorArgsValidationAnnotation.mandatoryArgs(); + optionalArgsValidationTypes = executorArgsValidationAnnotation.optionalArgs(); } if (containsDependenciesAnnotation(commandExecutorClass)) { @@ -52,18 +66,32 @@ public AbstractCommandData executorClassToCommand(Class c Command executorCommandAnnotation = getCommandAnnotation(commandExecutorClass); String commandAlias = executorCommandAnnotation.alias(); - String commandDescription = executorCommandAnnotation.description().equals("") ? null : executorCommandAnnotation.description(); - String commandPermission = executorCommandAnnotation.permission().equals("") ? null : executorCommandAnnotation.permission(); + String commandDescription = executorCommandAnnotation.description().isEmpty() ? null : executorCommandAnnotation.description(); + String commandPermission = executorCommandAnnotation.permission().isEmpty() ? null : executorCommandAnnotation.permission(); + boolean isPlayerOnly = executorCommandAnnotation.isPlayerOnly(); return new BukkitCommandDataBuilder(commandAlias, integration, commandExecutorClass) .withDescription(commandDescription) .withPermission(commandPermission) - .withMandatoryArguments(argsValidationTypes) + .withPlayerOnly(isPlayerOnly) + .withMandatoryArguments(mandatoryArgsValidationTypes) + .withOptionalArguments(optionalArgsValidationTypes) .withDependencies(commandDependencies) .build(); } + public boolean containsCommandsWithRepeatedAliases() { + + List commandDataObjectsGenerated = getDiscoveredCommandsData(); + + return getDiscoveredCommandsData().stream() + .map(AbstractCommandData::getAlias) + .distinct() + .count() != commandDataObjectsGenerated.size(); + + } + private Command getCommandAnnotation(Class classToGetAnnotationFrom) { return classToGetAnnotationFrom.getAnnotation(Command.class); } @@ -89,7 +117,7 @@ private boolean containsDependenciesAnnotation(Class classToCheck) { } @SuppressWarnings("unchecked") - private Class getCommandExecutor(Class classToCheck) { + private Class getCommandClass(Class classToCheck) { return isValidCommandClass(classToCheck) ? (Class) classToCheck : null; } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/exceptions/ArgumentsConfigException.java b/src/main/java/dev/hugog/minecraft/dev_command/exceptions/ArgumentsConfigException.java similarity index 75% rename from src/main/java/me/hgsoft/minecraft/devcommand/exceptions/ArgumentsConfigException.java rename to src/main/java/dev/hugog/minecraft/dev_command/exceptions/ArgumentsConfigException.java index d353cc1..aa47227 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/exceptions/ArgumentsConfigException.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/exceptions/ArgumentsConfigException.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.exceptions; +package dev.hugog.minecraft.dev_command.exceptions; public class ArgumentsConfigException extends RuntimeException { diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/exceptions/AutoConfigurationException.java b/src/main/java/dev/hugog/minecraft/dev_command/exceptions/AutoConfigurationException.java similarity index 75% rename from src/main/java/me/hgsoft/minecraft/devcommand/exceptions/AutoConfigurationException.java rename to src/main/java/dev/hugog/minecraft/dev_command/exceptions/AutoConfigurationException.java index 88cdc52..3b8a3e4 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/exceptions/AutoConfigurationException.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/exceptions/AutoConfigurationException.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.exceptions; +package dev.hugog.minecraft.dev_command.exceptions; public class AutoConfigurationException extends RuntimeException { diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/exceptions/InvalidIntegrationException.java b/src/main/java/dev/hugog/minecraft/dev_command/exceptions/InvalidIntegrationException.java similarity index 75% rename from src/main/java/me/hgsoft/minecraft/devcommand/exceptions/InvalidIntegrationException.java rename to src/main/java/dev/hugog/minecraft/dev_command/exceptions/InvalidIntegrationException.java index 789cd44..f98aeee 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/exceptions/InvalidIntegrationException.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/exceptions/InvalidIntegrationException.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.exceptions; +package dev.hugog.minecraft.dev_command.exceptions; public class InvalidIntegrationException extends RuntimeException { public InvalidIntegrationException(String message) { diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/exceptions/PermissionConfigException.java b/src/main/java/dev/hugog/minecraft/dev_command/exceptions/PermissionConfigException.java similarity index 75% rename from src/main/java/me/hgsoft/minecraft/devcommand/exceptions/PermissionConfigException.java rename to src/main/java/dev/hugog/minecraft/dev_command/exceptions/PermissionConfigException.java index 262aab0..636e38a 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/exceptions/PermissionConfigException.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/exceptions/PermissionConfigException.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.exceptions; +package dev.hugog.minecraft.dev_command.exceptions; public class PermissionConfigException extends RuntimeException { diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/factories/ArgumentFactory.java b/src/main/java/dev/hugog/minecraft/dev_command/factories/ArgumentFactory.java similarity index 86% rename from src/main/java/me/hgsoft/minecraft/devcommand/factories/ArgumentFactory.java rename to src/main/java/dev/hugog/minecraft/dev_command/factories/ArgumentFactory.java index 2319975..1e3eae2 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/factories/ArgumentFactory.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/factories/ArgumentFactory.java @@ -1,6 +1,6 @@ -package me.hgsoft.minecraft.devcommand.factories; +package dev.hugog.minecraft.dev_command.factories; -import me.hgsoft.minecraft.devcommand.validators.ICommandArgument; +import dev.hugog.minecraft.dev_command.validators.ICommandArgument; import java.lang.reflect.Constructor; diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/factories/CommandFactory.java b/src/main/java/dev/hugog/minecraft/dev_command/factories/CommandFactory.java similarity index 53% rename from src/main/java/me/hgsoft/minecraft/devcommand/factories/CommandFactory.java rename to src/main/java/dev/hugog/minecraft/dev_command/factories/CommandFactory.java index a9a459f..2e8b460 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/factories/CommandFactory.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/factories/CommandFactory.java @@ -1,12 +1,11 @@ -package me.hgsoft.minecraft.devcommand.factories; +package dev.hugog.minecraft.dev_command.factories; -import me.hgsoft.minecraft.devcommand.commands.data.AbstractCommandData; -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.commands.IDevCommand; +import dev.hugog.minecraft.dev_command.commands.IDevCommand; +import dev.hugog.minecraft.dev_command.commands.data.AbstractCommandData; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; import org.bukkit.command.CommandSender; import java.lang.reflect.Constructor; -import java.util.Arrays; public class CommandFactory implements IObjectFactory { @@ -29,7 +28,23 @@ public IDevCommand generate(AbstractCommandData abstractCommandData) { if (abstractCommandData instanceof BukkitCommandData) { executorConstructor = executor.getConstructor(BukkitCommandData.class, CommandSender.class, String[].class); - executorInstance = executorConstructor.newInstance(abstractCommandData, executorArgs[0], Arrays.copyOfRange(executorArgs, 1, executorArgs.length, String[].class)); + + if (executorArgs.length == 0) { + throw new IllegalArgumentException("You must provide a CommandSender and a String[] as arguments for the BukkitCommandData executor."); + } + + if (executorArgs[0] != null && !(executorArgs[0] instanceof CommandSender)) { + throw new IllegalArgumentException("The first argument for the BukkitCommandData executor must be a CommandSender."); + } + + String[] remainingArgs = new String[0]; + + if (executorArgs.length > 1) { + remainingArgs = (String[]) executorArgs[1]; + } + + executorInstance = executorConstructor.newInstance(abstractCommandData, executorArgs[0], remainingArgs); + } else { executorInstance = null; } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/factories/IObjectFactory.java b/src/main/java/dev/hugog/minecraft/dev_command/factories/IObjectFactory.java similarity index 57% rename from src/main/java/me/hgsoft/minecraft/devcommand/factories/IObjectFactory.java rename to src/main/java/dev/hugog/minecraft/dev_command/factories/IObjectFactory.java index 5bfbcf7..803d4d8 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/factories/IObjectFactory.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/factories/IObjectFactory.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.factories; +package dev.hugog.minecraft.dev_command.factories; public interface IObjectFactory { T generate(C command); diff --git a/src/main/java/dev/hugog/minecraft/dev_command/injection/GuiceBinderModule.java b/src/main/java/dev/hugog/minecraft/dev_command/injection/GuiceBinderModule.java new file mode 100644 index 0000000..daee060 --- /dev/null +++ b/src/main/java/dev/hugog/minecraft/dev_command/injection/GuiceBinderModule.java @@ -0,0 +1,20 @@ +package dev.hugog.minecraft.dev_command.injection; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; + +public class GuiceBinderModule extends AbstractModule { + + public GuiceBinderModule() {} + + public Injector createInjector() { + return Guice.createInjector(this); + } + + @Override + protected void configure() { + + } + +} diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/integration/Integration.java b/src/main/java/dev/hugog/minecraft/dev_command/integration/Integration.java similarity index 93% rename from src/main/java/me/hgsoft/minecraft/devcommand/integration/Integration.java rename to src/main/java/dev/hugog/minecraft/dev_command/integration/Integration.java index e9e517e..7c28bd6 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/integration/Integration.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/integration/Integration.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.integration; +package dev.hugog.minecraft.dev_command.integration; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -32,6 +32,10 @@ public static Integration createFromPlugin(JavaPlugin plugin) { return new Integration(getNameFromPlugin(plugin), plugin, getBasePackageFromPlugin(plugin)); } + public boolean isValid() { + return basePackage != null; + } + private static String getNameFromPlugin(JavaPlugin plugin) { return plugin.getName(); } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/registry/IRegistry.java b/src/main/java/dev/hugog/minecraft/dev_command/registry/IRegistry.java similarity index 79% rename from src/main/java/me/hgsoft/minecraft/devcommand/registry/IRegistry.java rename to src/main/java/dev/hugog/minecraft/dev_command/registry/IRegistry.java index c300c28..2416f2c 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/registry/IRegistry.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/registry/IRegistry.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.registry; +package dev.hugog.minecraft.dev_command.registry; import java.util.List; diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/registry/commands/CommandRegistry.java b/src/main/java/dev/hugog/minecraft/dev_command/registry/commands/CommandRegistry.java similarity index 66% rename from src/main/java/me/hgsoft/minecraft/devcommand/registry/commands/CommandRegistry.java rename to src/main/java/dev/hugog/minecraft/dev_command/registry/commands/CommandRegistry.java index e10d820..67cbc69 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/registry/commands/CommandRegistry.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/registry/commands/CommandRegistry.java @@ -1,18 +1,18 @@ -package me.hgsoft.minecraft.devcommand.registry.commands; +package dev.hugog.minecraft.dev_command.registry.commands; -import me.hgsoft.minecraft.devcommand.commands.data.AbstractCommandData; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.registry.IRegistry; +import com.google.inject.Singleton; +import dev.hugog.minecraft.dev_command.commands.data.AbstractCommandData; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.registry.IRegistry; import java.util.*; +@Singleton public class CommandRegistry implements IRegistry { - private static CommandRegistry instance; - private final Map> registeredCommands; - private CommandRegistry() { + public CommandRegistry() { this.registeredCommands = new HashMap<>(); } @@ -40,10 +40,4 @@ public void setValues(Integration key, List value) { registeredCommands.put(key, value); } - public static CommandRegistry getInstance() { - if (instance == null) - instance = new CommandRegistry(); - return instance; - } - } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/registry/dependencies/DependencyRegistry.java b/src/main/java/dev/hugog/minecraft/dev_command/registry/dependencies/DependencyRegistry.java similarity index 66% rename from src/main/java/me/hgsoft/minecraft/devcommand/registry/dependencies/DependencyRegistry.java rename to src/main/java/dev/hugog/minecraft/dev_command/registry/dependencies/DependencyRegistry.java index f287246..eb7e91d 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/registry/dependencies/DependencyRegistry.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/registry/dependencies/DependencyRegistry.java @@ -1,18 +1,17 @@ -package me.hgsoft.minecraft.devcommand.registry.dependencies; +package dev.hugog.minecraft.dev_command.registry.dependencies; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.registry.IRegistry; +import com.google.inject.Singleton; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.registry.IRegistry; -import javax.annotation.Nullable; import java.util.*; +@Singleton public class DependencyRegistry implements IRegistry { - private static DependencyRegistry instance; - private final Map> registeredDependencies; - private DependencyRegistry() { + public DependencyRegistry() { this.registeredDependencies = new HashMap<>(); } @@ -40,11 +39,4 @@ public void setValues(Integration key, List value) { registeredDependencies.put(key, value); } - public static DependencyRegistry getInstance() { - if (instance == null) { - instance = new DependencyRegistry(); - } - return instance; - } - } diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/validators/BooleanArgument.java b/src/main/java/dev/hugog/minecraft/dev_command/validators/BooleanArgument.java similarity index 95% rename from src/main/java/me/hgsoft/minecraft/devcommand/validators/BooleanArgument.java rename to src/main/java/dev/hugog/minecraft/dev_command/validators/BooleanArgument.java index e622a7e..9539fdd 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/validators/BooleanArgument.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/validators/BooleanArgument.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.validators; +package dev.hugog.minecraft.dev_command.validators; import lombok.EqualsAndHashCode; import lombok.ToString; diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/validators/CommandArgument.java b/src/main/java/dev/hugog/minecraft/dev_command/validators/CommandArgument.java similarity index 85% rename from src/main/java/me/hgsoft/minecraft/devcommand/validators/CommandArgument.java rename to src/main/java/dev/hugog/minecraft/dev_command/validators/CommandArgument.java index 3dd69ad..aa4ba2c 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/validators/CommandArgument.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/validators/CommandArgument.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.validators; +package dev.hugog.minecraft.dev_command.validators; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/validators/DoubleArgument.java b/src/main/java/dev/hugog/minecraft/dev_command/validators/DoubleArgument.java similarity index 79% rename from src/main/java/me/hgsoft/minecraft/devcommand/validators/DoubleArgument.java rename to src/main/java/dev/hugog/minecraft/dev_command/validators/DoubleArgument.java index b3a9268..8dfe09c 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/validators/DoubleArgument.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/validators/DoubleArgument.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.validators; +package dev.hugog.minecraft.dev_command.validators; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -13,7 +13,7 @@ public DoubleArgument(String argument) { @Override public boolean isValid() { - return getArgument().matches("\\d*\\.\\d+"); + return getArgument().matches("[-+]?\\d*\\.\\d+"); } @Override diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/validators/ICommandArgument.java b/src/main/java/dev/hugog/minecraft/dev_command/validators/ICommandArgument.java similarity index 61% rename from src/main/java/me/hgsoft/minecraft/devcommand/validators/ICommandArgument.java rename to src/main/java/dev/hugog/minecraft/dev_command/validators/ICommandArgument.java index 3b86390..88d221c 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/validators/ICommandArgument.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/validators/ICommandArgument.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.validators; +package dev.hugog.minecraft.dev_command.validators; public interface ICommandArgument { diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/validators/IntegerArgument.java b/src/main/java/dev/hugog/minecraft/dev_command/validators/IntegerArgument.java similarity index 90% rename from src/main/java/me/hgsoft/minecraft/devcommand/validators/IntegerArgument.java rename to src/main/java/dev/hugog/minecraft/dev_command/validators/IntegerArgument.java index fe3b0c4..51d627e 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/validators/IntegerArgument.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/validators/IntegerArgument.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.validators; +package dev.hugog.minecraft.dev_command.validators; import lombok.EqualsAndHashCode; import lombok.ToString; diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/validators/StringArgument.java b/src/main/java/dev/hugog/minecraft/dev_command/validators/StringArgument.java similarity index 88% rename from src/main/java/me/hgsoft/minecraft/devcommand/validators/StringArgument.java rename to src/main/java/dev/hugog/minecraft/dev_command/validators/StringArgument.java index dd12236..3b2c525 100644 --- a/src/main/java/me/hgsoft/minecraft/devcommand/validators/StringArgument.java +++ b/src/main/java/dev/hugog/minecraft/dev_command/validators/StringArgument.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.validators; +package dev.hugog.minecraft.dev_command.validators; import lombok.EqualsAndHashCode; import lombok.ToString; diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/CommandHandler.java b/src/main/java/me/hgsoft/minecraft/devcommand/CommandHandler.java deleted file mode 100644 index dea1b4d..0000000 --- a/src/main/java/me/hgsoft/minecraft/devcommand/CommandHandler.java +++ /dev/null @@ -1,98 +0,0 @@ -package me.hgsoft.minecraft.devcommand; - -import lombok.extern.log4j.Log4j2; -import me.hgsoft.minecraft.devcommand.commands.data.AbstractCommandData; -import me.hgsoft.minecraft.devcommand.discovery.CommandDiscoveryService; -import me.hgsoft.minecraft.devcommand.exceptions.AutoConfigurationException; -import me.hgsoft.minecraft.devcommand.exceptions.InvalidIntegrationException; -import me.hgsoft.minecraft.devcommand.commands.IDevCommand; -import me.hgsoft.minecraft.devcommand.factories.IObjectFactory; -import me.hgsoft.minecraft.devcommand.factories.CommandFactory; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.registry.commands.CommandRegistry; - -import java.util.*; -import java.util.stream.Collectors; - -@Log4j2 -public class CommandHandler { - - private static CommandHandler currentInstance; - - private CommandHandler() { } - - public void registerCommand(Integration integration, AbstractCommandData command) { - CommandRegistry.getInstance().add(integration, command); - } - - public boolean executeCommandByAlias(Integration integration, String alias, Object... commandArgs) { - - IObjectFactory commandFactory = new CommandFactory(commandArgs); - CommandRegistry commandRegistry = CommandRegistry.getInstance(); - List registeredCommandsForIntegration = commandRegistry.getValues(integration); - - if (registeredCommandsForIntegration == null) { - System.out.println("No Commands registered"); - return false; - } - - for (AbstractCommandData registeredCommand : registeredCommandsForIntegration) { - - if (registeredCommand.getAlias().equalsIgnoreCase(alias)) { - commandFactory.generate(registeredCommand).execute(); - return true; - } - - } - - return false; - - } - - public void initCommandsAutoConfiguration(Integration integration) { - - System.out.println("INTEGRATION VALID: " + integration.toString()); - - if (!checkIntegrationValidity(integration)) { - throw new InvalidIntegrationException(String.format("The integration %s contained an invalid base package.", integration.getName())); - } - - CommandDiscoveryService commandDiscoveryService = new CommandDiscoveryService(integration); - - List discoveredAbstractCommandDataList = commandDiscoveryService.getCommandExecutorClasses() - .stream() - .map(commandDiscoveryService::executorClassToCommand) - .collect(Collectors.toList()); - - boolean hasRepeatedAliases = discoveredAbstractCommandDataList.stream() - .map(AbstractCommandData::getAlias) - .distinct() - .count() != discoveredAbstractCommandDataList.size(); - - if (hasRepeatedAliases) { - throw new AutoConfigurationException("Unable to autoconfigure commands as there are commands with repeated aliases."); - } - - discoveredAbstractCommandDataList.forEach(abstractCommand -> { - registerCommand(integration, abstractCommand); - log.info(String.format("Loaded command '%s' from '%s'.", abstractCommand.getAlias(), integration.getName())); - }); - - } - - private boolean checkIntegrationValidity(Integration integration) { - if (integration == null || integration.getBasePackage() == null) { - log.warn("Unable to find base package for Integration - Commands Auto-Configuration stopped."); - return false; - } - return true; - } - - public static CommandHandler createOrGetInstance() { - if (currentInstance == null) { - currentInstance = new CommandHandler(); - } - return currentInstance; - } - -} diff --git a/src/main/java/me/hgsoft/minecraft/devcommand/DevCommand.java b/src/main/java/me/hgsoft/minecraft/devcommand/DevCommand.java deleted file mode 100644 index 95c2627..0000000 --- a/src/main/java/me/hgsoft/minecraft/devcommand/DevCommand.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.hgsoft.minecraft.devcommand; - -import lombok.Getter; -import me.hgsoft.minecraft.devcommand.dependencies.DependencyHandler; - -@Getter -public final class DevCommand { - - private static DevCommand instance; - - private final CommandHandler commandHandler; - private final DependencyHandler dependencyHandler; - - private DevCommand() { - this.commandHandler = CommandHandler.createOrGetInstance(); - this.dependencyHandler = DependencyHandler.createOrGetInstance(); - } - - public static DevCommand getInstance() { - if (instance == null) { - instance = new DevCommand(); - } - return instance; - } - -} diff --git a/src/test/java/dev/hugog/minecraft/dev_command/IntegrationTestIT.java b/src/test/java/dev/hugog/minecraft/dev_command/IntegrationTestIT.java new file mode 100644 index 0000000..4686d4d --- /dev/null +++ b/src/test/java/dev/hugog/minecraft/dev_command/IntegrationTestIT.java @@ -0,0 +1,82 @@ +package dev.hugog.minecraft.dev_command; + +import dev.hugog.minecraft.dev_command.commands.builder.BukkitCommandDataBuilder; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; +import dev.hugog.minecraft.dev_command.utils.test_classes.valid.TestCommand; +import dev.hugog.minecraft.dev_command.commands.handler.CommandHandler; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.registry.commands.CommandRegistry; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class IntegrationTestIT { + + private CommandRegistry commandRegistry; + private CommandHandler commandHandler; + private Integration pluginIntegration; + + @BeforeEach + void setUp() { + commandRegistry = new CommandRegistry(); + commandHandler = new CommandHandler(commandRegistry); + pluginIntegration = new Integration("myPlugin", "dev.hugog.minecraft.dev_command.utils.test_classes.valid"); + TestCommand.called = false; + } + + @AfterEach + void tearDown() { + TestCommand.called = false; + TestCommand.args = null; + TestCommand.command = null; + TestCommand.sender = null; + commandRegistry.setValues(pluginIntegration, null); + } + + @Test + void registerAndExecuteBukkitCommand() { + + BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", pluginIntegration, TestCommand.class) + .withDescription("Help Command") + .withPermission("dev_commands.commands.help") + .build(); + + commandHandler.registerCommand(pluginIntegration, bukkitCommand); + commandHandler.executeCommandByAlias(pluginIntegration, "test", null, new String[] {"1"}); + + // The command was successfully called + assertTrue(TestCommand.called); + + // The sender is the same + assertNull(TestCommand.sender); + // The args are also correct + assertArrayEquals(new String[] {"1"}, TestCommand.args); + + Assertions.assertEquals(bukkitCommand, TestCommand.command); + + } + + @Test + void autoCommandDiscoveryAndExecuteBukkitCommand() { + + commandHandler.initCommandsAutoConfiguration(pluginIntegration); + commandHandler.executeCommandByAlias(pluginIntegration, "test", null, new String[]{"good", "afternoon"}); + + // The command was successfully called + assertTrue(TestCommand.called); + + // The sender is the same + assertNull(TestCommand.sender); + // The args are also correct + assertArrayEquals(new String[] {"good", "afternoon"}, TestCommand.args); + + // The command alias is also correct + assertNotNull(TestCommand.command); + Assertions.assertEquals(TestCommand.command.getAlias(), "test"); + + } + +} diff --git a/src/test/java/dev/hugog/minecraft/dev_command/commands/CommandHandlerTest.java b/src/test/java/dev/hugog/minecraft/dev_command/commands/CommandHandlerTest.java new file mode 100644 index 0000000..5832a93 --- /dev/null +++ b/src/test/java/dev/hugog/minecraft/dev_command/commands/CommandHandlerTest.java @@ -0,0 +1,163 @@ +package dev.hugog.minecraft.dev_command.commands; + +import dev.hugog.minecraft.dev_command.commands.builder.BukkitCommandDataBuilder; +import dev.hugog.minecraft.dev_command.commands.data.AbstractCommandData; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; +import dev.hugog.minecraft.dev_command.utils.test_classes.valid.TestCommand; +import dev.hugog.minecraft.dev_command.commands.handler.CommandHandler; +import dev.hugog.minecraft.dev_command.discovery.CommandDiscoveryService; +import dev.hugog.minecraft.dev_command.exceptions.AutoConfigurationException; +import dev.hugog.minecraft.dev_command.exceptions.InvalidIntegrationException; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.registry.commands.CommandRegistry; +import dev.hugog.minecraft.dev_command.validators.IntegerArgument; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class CommandHandlerTest { + + @Mock + private CommandRegistry commandRegistryMock; + @Mock + private Integration integrationMock; + @InjectMocks + private CommandHandler commandHandler; + + private BukkitCommandData bukkitCommandStub; + + @BeforeEach + void setUp() { + + bukkitCommandStub = new BukkitCommandDataBuilder("test", integrationMock, TestCommand.class) + .withDescription("Bukkit Test Command!") + .withPermission("command.bukkit_test") + .withMandatoryArguments(IntegerArgument.class) + .build(); + + } + + @AfterEach + void tearDown() { + commandRegistryMock.setValues(integrationMock, null); + TestCommand.called = false; + } + + @Test + @DisplayName("Test CommandHandler registerCommand()") + void registerCommand() { + + commandHandler.registerCommand(integrationMock, bukkitCommandStub); + verify(commandRegistryMock, times(1)).add(integrationMock, bukkitCommandStub); + + } + + @Test + @DisplayName("Test if command is executed when there are no commands registered.") + void executeCommandByAlias_NoCommandsRegistered() { + + when(commandRegistryMock.getValues(integrationMock)).thenReturn(null); + + boolean commandExecuted = commandHandler.executeCommandByAlias(integrationMock, bukkitCommandStub.getAlias(), null, null); + + assertFalse(commandExecuted); + + verify(commandRegistryMock, times(1)).getValues(integrationMock); + + } + + @Test + @DisplayName("Test if the command is executed when it is not registered.") + void executeCommandByAlias_CommandNotRegistered() { + + AbstractCommandData abstractCommandDataMock = mock(AbstractCommandData.class); + + when(commandRegistryMock.getValues(integrationMock)).thenReturn(List.of(abstractCommandDataMock)); + when(abstractCommandDataMock.getAlias()).thenReturn("not_registered_alias"); + + assertFalse(commandHandler.executeCommandByAlias(integrationMock, bukkitCommandStub.getAlias(), null, null)); + + verify(commandRegistryMock, times(1)).getValues(integrationMock); + + } + + @Test + @DisplayName("Test if command is executed successfully by its alias.") + void executeCommandByAlias() { + + commandHandler.registerCommand(integrationMock, bukkitCommandStub); + + when(commandRegistryMock.getValues(integrationMock)).thenReturn(List.of(bukkitCommandStub)); + + assertTrue(commandHandler.executeCommandByAlias(integrationMock, bukkitCommandStub.getAlias(), null, new String[] {"good", "afternoon" } )); + + verify(commandRegistryMock, times(1)).getValues(integrationMock); + + } + + @Test + @DisplayName("Test autoconfiguration method.") + void initCommandsAutoConfiguration() { + + CommandDiscoveryService commandDiscoveryServiceMock = mock(CommandDiscoveryService.class); + + when(commandDiscoveryServiceMock.containsCommandsWithRepeatedAliases()).thenReturn(false); + when(commandDiscoveryServiceMock.getDiscoveredCommandsData()).thenReturn(List.of(mock(AbstractCommandData.class))); + when(integrationMock.isValid()).thenReturn(true); + + assertDoesNotThrow(() -> commandHandler.initCommandsAutoConfiguration(integrationMock, commandDiscoveryServiceMock)); + + verify(commandRegistryMock, times(1)).add(any(), any()); + + } + + @Test + @DisplayName("Test autoconfiguration with duplicated command aliases.") + void initCommandsAutoConfiguration_withDuplicatedAliases() { + + CommandDiscoveryService commandDiscoveryServiceMock = mock(CommandDiscoveryService.class); + + when(commandDiscoveryServiceMock.containsCommandsWithRepeatedAliases()).thenReturn(true); + when(integrationMock.isValid()).thenReturn(true); + + assertThrows(AutoConfigurationException.class, () -> commandHandler.initCommandsAutoConfiguration(integrationMock, commandDiscoveryServiceMock)); + + verify(commandDiscoveryServiceMock, times(1)).containsCommandsWithRepeatedAliases(); + + } + + @Test + @DisplayName("Test method to initiate commands autoconfiguration with Invalid integration.") + void initCommandsAutoConfigurationWithInvalidIntegration() { + + Integration invalidIntegration = new Integration("MyPlugin", null); + assertThrows(InvalidIntegrationException.class, () -> commandHandler.initCommandsAutoConfiguration(invalidIntegration)); + + } + + @Test + @DisplayName("Test method to get registered commands.") + void getRegisteredCommands() { + + when(commandRegistryMock.getValues(integrationMock)).thenReturn(List.of(bukkitCommandStub)); + + commandHandler.registerCommand(integrationMock, bukkitCommandStub); + + assertEquals(commandHandler.getRegisteredCommands(integrationMock), List.of(bukkitCommandStub)); + + verify(commandRegistryMock, times(1)).getValues(integrationMock); + + } + +} \ No newline at end of file diff --git a/src/test/java/me/hgsoft/minecraft/devcommand/dependencies/DependencyHandlerTest.java b/src/test/java/dev/hugog/minecraft/dev_command/dependencies/DependencyHandlerTest.java similarity index 80% rename from src/test/java/me/hgsoft/minecraft/devcommand/dependencies/DependencyHandlerTest.java rename to src/test/java/dev/hugog/minecraft/dev_command/dependencies/DependencyHandlerTest.java index c84e348..fbd13db 100644 --- a/src/test/java/me/hgsoft/minecraft/devcommand/dependencies/DependencyHandlerTest.java +++ b/src/test/java/dev/hugog/minecraft/dev_command/dependencies/DependencyHandlerTest.java @@ -1,4 +1,4 @@ -package me.hgsoft.minecraft.devcommand.dependencies; +package dev.hugog.minecraft.dev_command.dependencies; import org.junit.jupiter.api.Test; diff --git a/src/test/java/dev/hugog/minecraft/dev_command/discovery/CommandDiscoveryServiceTest.java b/src/test/java/dev/hugog/minecraft/dev_command/discovery/CommandDiscoveryServiceTest.java new file mode 100644 index 0000000..b619ddb --- /dev/null +++ b/src/test/java/dev/hugog/minecraft/dev_command/discovery/CommandDiscoveryServiceTest.java @@ -0,0 +1,171 @@ +package dev.hugog.minecraft.dev_command.discovery; + +import dev.hugog.minecraft.dev_command.annotations.Command; +import dev.hugog.minecraft.dev_command.commands.data.AbstractCommandData; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; +import dev.hugog.minecraft.dev_command.utils.test_classes.invalid.TestCommandCopy; +import dev.hugog.minecraft.dev_command.utils.test_classes.valid.ArgumentTestCommand; +import dev.hugog.minecraft.dev_command.utils.test_classes.valid.NoAnnotationTestCommand; +import dev.hugog.minecraft.dev_command.utils.test_classes.valid.TestCommand; +import dev.hugog.minecraft.dev_command.validators.IntegerArgument; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.reflections.Reflections; + +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class CommandDiscoveryServiceTest { + + @Mock + private Reflections reflectionsUtilsMock; + + @InjectMocks + private CommandDiscoveryService commandDiscoveryService; + + @Test + @DisplayName("Test method to get classes annotated with @Command") + void getCommandClasses() { + + when(reflectionsUtilsMock.getTypesAnnotatedWith(Command.class)).thenReturn(Set.of(TestCommand.class, NoAnnotationTestCommand.class)); + + // Contains Only TestCommand cause the other one does not contain the @Command annotation. + assertThat(commandDiscoveryService.getCommandClasses()) + .isNotNull() + .isNotEmpty() + .hasSize(1) + .containsOnly(TestCommand.class); + + } + + @Test + @DisplayName("Test method to generate command data for all the detected commands.") + void getDiscoveredCommandsData() { + + when(reflectionsUtilsMock.getTypesAnnotatedWith(Command.class)).thenReturn(Set.of(TestCommand.class)); + + assertThat(commandDiscoveryService.getDiscoveredCommandsData()) + .isNotNull() + .isNotEmpty() + .hasSize(1); + + // Below: + // Check if the values from @Command annotation in TestCommand class were successfully introduced + // in the command data class generated. + + assertThat(commandDiscoveryService.getDiscoveredCommandsData()) + .extracting(AbstractCommandData::getName) + .containsOnlyNulls(); + + assertThat(commandDiscoveryService.getDiscoveredCommandsData()) + .extracting(AbstractCommandData::getAlias) + .containsExactly("test"); + + assertThat(commandDiscoveryService.getDiscoveredCommandsData()) + .extracting(AbstractCommandData::getDescription) + .containsExactly("Bukkit Test Command!"); + + assertThat(commandDiscoveryService.getDiscoveredCommandsData()) + .extracting(AbstractCommandData::getExecutor) + .first() + .isEqualTo(TestCommand.class); + + assertThat(commandDiscoveryService.getDiscoveredCommandsData()) + .first() + .isInstanceOf(BukkitCommandData.class); + + assertThat(commandDiscoveryService.getDiscoveredCommandsData()) + .first() + .isInstanceOfSatisfying(BukkitCommandData.class, bukkitCommandData -> + assertThat(bukkitCommandData).extracting(BukkitCommandData::getPermission).isEqualTo("command.bukkit_test") + ); + + assertThat(commandDiscoveryService.getDiscoveredCommandsData()) + .first() + .isInstanceOfSatisfying(BukkitCommandData.class, bukkitCommandData -> + assertThat(bukkitCommandData) + .extracting(BukkitCommandData::getMandatoryArguments) + .extracting(classes -> + assertThat(classes).containsExactlyInAnyOrder(IntegerArgument.class) + ).isNotNull() + ); + + assertThat(commandDiscoveryService.getDiscoveredCommandsData()) + .first() + .isInstanceOfSatisfying(BukkitCommandData.class, bukkitCommandData -> + assertThat(bukkitCommandData.getOptionalArguments()).isEmpty() + ); + + } + + @Test + @DisplayName("Test method to convert from command class to command data object.") + void commandClassToCommandData() { + + assertThat(commandDiscoveryService.commandClassToCommandData(TestCommand.class)) + .isNotNull() + .isInstanceOf(BukkitCommandData.class); + + assertThat(commandDiscoveryService.commandClassToCommandData(TestCommand.class)) + .extracting(AbstractCommandData::getName) + .isNull(); + + assertThat(commandDiscoveryService.commandClassToCommandData(TestCommand.class)) + .extracting(AbstractCommandData::getAlias) + .isEqualTo("test"); + + assertThat(commandDiscoveryService.commandClassToCommandData(TestCommand.class)) + .extracting(AbstractCommandData::getDescription) + .isEqualTo("Bukkit Test Command!"); + + assertThat(commandDiscoveryService.commandClassToCommandData(TestCommand.class)) + .extracting(AbstractCommandData::getExecutor) + .isEqualTo(TestCommand.class); + + assertThat(commandDiscoveryService.commandClassToCommandData(TestCommand.class)) + .isInstanceOfSatisfying(BukkitCommandData.class, bukkitCommandData -> + assertThat(bukkitCommandData).extracting(BukkitCommandData::getPermission).isEqualTo("command.bukkit_test") + ); + + assertThat(commandDiscoveryService.commandClassToCommandData(TestCommand.class)) + .isInstanceOfSatisfying(BukkitCommandData.class, bukkitCommandData -> + assertThat(bukkitCommandData) + .extracting(BukkitCommandData::getMandatoryArguments) + .extracting(classes -> + assertThat(classes).containsExactlyInAnyOrder(IntegerArgument.class) + ).isNotNull() + ); + + assertThat(commandDiscoveryService.commandClassToCommandData(TestCommand.class)) + .isInstanceOfSatisfying(BukkitCommandData.class, bukkitCommandData -> + assertThat(bukkitCommandData.getOptionalArguments()).isEmpty() + ); + + } + + @Test + @DisplayName("Test if commands with repeated aliases are detected successfully.") + void containsCommandsWithRepeatedAliases() { + + // Both TestCommand and TestCommandCopy have the same alias + when(reflectionsUtilsMock.getTypesAnnotatedWith(Command.class)) + .thenReturn(Set.of(TestCommand.class, TestCommandCopy.class)); + + assertThat(commandDiscoveryService.containsCommandsWithRepeatedAliases()).isTrue(); + + // TestCommand and ArgumentTestCommand have different aliases + when(reflectionsUtilsMock.getTypesAnnotatedWith(Command.class)) + .thenReturn(Set.of(TestCommand.class, ArgumentTestCommand.class)); + + assertThat(commandDiscoveryService.containsCommandsWithRepeatedAliases()).isFalse(); + + } + +} \ No newline at end of file diff --git a/src/test/java/dev/hugog/minecraft/dev_command/executors/BukkitDevCommandTest.java b/src/test/java/dev/hugog/minecraft/dev_command/executors/BukkitDevCommandTest.java new file mode 100644 index 0000000..6948536 --- /dev/null +++ b/src/test/java/dev/hugog/minecraft/dev_command/executors/BukkitDevCommandTest.java @@ -0,0 +1,320 @@ +package dev.hugog.minecraft.dev_command.executors; + +import dev.hugog.minecraft.dev_command.commands.BukkitDevCommand; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; +import dev.hugog.minecraft.dev_command.exceptions.ArgumentsConfigException; +import dev.hugog.minecraft.dev_command.exceptions.PermissionConfigException; +import dev.hugog.minecraft.dev_command.validators.BooleanArgument; +import dev.hugog.minecraft.dev_command.validators.DoubleArgument; +import dev.hugog.minecraft.dev_command.validators.IntegerArgument; +import dev.hugog.minecraft.dev_command.validators.StringArgument; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class BukkitDevCommandTest { + + @Mock + private CommandSender commandSenderMock; + @Mock + private BukkitCommandData bukkitCommandDataMock; + + private BukkitDevCommand bukkitDevCommandStub; + + @BeforeEach + void setUp() { + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, commandSenderMock, null) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + } + + @Test + @DisplayName("Test the hasPermissionToExecuteCommand method when player HAS permission.") + void hasPermissionToExecuteCommand() { + + String commandPermission = "commands.no_annotation_test"; + + when(bukkitCommandDataMock.getPermission()).thenReturn(commandPermission); + when(commandSenderMock.hasPermission(commandPermission)).thenReturn(Boolean.TRUE); + + assertThat(bukkitDevCommandStub.hasPermissionToExecuteCommand()).isTrue(); + + verify(bukkitCommandDataMock, times(2)).getPermission(); + verify(commandSenderMock, times(1)).hasPermission(commandPermission); + + } + + @Test + @DisplayName("Test the hasPermissionToExecuteCommand method when player DOES NOT HAVE permission.") + void hasPermissionToExecuteCommand_noPermission() { + + String commandPermission = "commands.no_annotation_test"; + + when(bukkitCommandDataMock.getPermission()).thenReturn(commandPermission); + when(commandSenderMock.hasPermission(commandPermission)).thenReturn(Boolean.FALSE); + + assertThat(bukkitDevCommandStub.hasPermissionToExecuteCommand()).isFalse(); + + verify(bukkitCommandDataMock, times(2)).getPermission(); + verify(commandSenderMock, times(1)).hasPermission(commandPermission); + + } + + @Test + @DisplayName("Test the behaviour when the method is called when the permission is null a.k.a. not defined.") + void hasPermissionToExecuteCommand_withUndefinedPermission() { + + when(bukkitCommandDataMock.getPermission()).thenReturn(null); + + assertThrows(PermissionConfigException.class, () -> bukkitDevCommandStub.hasPermissionToExecuteCommand(), + String.format("Unable to find the permission for the command %s. Have you configured any permission at all?", bukkitCommandDataMock.getName())); + + verify(bukkitCommandDataMock, times(1)).getPermission(); + verify(commandSenderMock, never()).hasPermission(anyString()); + + } + + @Test + @DisplayName("Test the canExecuteCommand method when the command is player only and the sender is a player.") + void canExecuteCommand() { + + Player playerMock = mock(Player.class); + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, playerMock, null) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + + when(bukkitCommandDataMock.isPlayerOnly()).thenReturn(true); + assertThat(bukkitDevCommandStub.canSenderExecuteCommand()).isTrue(); + + } + + @Test + @DisplayName("Test the canExecuteCommand method when the command is not player only and the sender is not a player.") + void canExecuteCommand_withoutPlayerOnlyFlag() { + + when(bukkitCommandDataMock.isPlayerOnly()).thenReturn(false); + assertThat(bukkitDevCommandStub.canSenderExecuteCommand()).isTrue(); + + } + + @Test + @DisplayName("Test the canExecuteCommand method when the command player only and the sender is not a player.") + void canExecuteCommand__withPlayerOnlyFlag() { + + when(bukkitCommandDataMock.isPlayerOnly()).thenReturn(true); + assertThat(bukkitDevCommandStub.canSenderExecuteCommand()).isFalse(); + + } + + @Test + @DisplayName("Test command mandatory arguments validation.") + @SuppressWarnings("unchecked") + void hasValidArgs_Mandatory() { + + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, commandSenderMock, new String[] {"1", "hey"}) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[]{IntegerArgument.class, StringArgument.class}); + + assertThat(bukkitDevCommandStub.hasValidArgs()).isTrue(); + + } + + @Test + @DisplayName("Test invalid mandatory arguments validation.") + @SuppressWarnings("unchecked") + void hasValidArgs_Mandatory_InvalidArguments() { + + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, commandSenderMock, new String[] {"1", "notADouble"}) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[]{IntegerArgument.class, DoubleArgument.class}); + + // Fails cause second argument is not a double. + assertThat(bukkitDevCommandStub.hasValidArgs()).isFalse(); + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[]{DoubleArgument.class, StringArgument.class}); + + // Fails cause the first argument is an Integer, not a Double. + assertThat(bukkitDevCommandStub.hasValidArgs()).isFalse(); + + } + + @Test + @DisplayName("Test validation for optional arguments.") + @SuppressWarnings("unchecked") + void hasValidArgs_Optional() { + + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, commandSenderMock, new String[] {"Some String"}) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[0]); + when(bukkitCommandDataMock.getOptionalArguments()).thenReturn(new Class[]{StringArgument.class}); + + assertThat(bukkitDevCommandStub.hasValidArgs()).isTrue(); + + } + + @Test + @DisplayName("Test invalid optional arguments validation.") + @SuppressWarnings("unchecked") + void hasValidArgs_Optional_InvalidArguments() { + + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, commandSenderMock, new String[] {"notAInteger"}) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[0]); + when(bukkitCommandDataMock.getOptionalArguments()).thenReturn(new Class[] {IntegerArgument.class}); + + // Fails cause the optional argument (first argument) is not an Integer - is a String + assertThat(bukkitDevCommandStub.hasValidArgs()).isFalse(); + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[0]); + when(bukkitCommandDataMock.getOptionalArguments()).thenReturn(new Class[] {BooleanArgument.class}); + + // Fails cause the optional argument (first argument) is not a Boolean - is a String + assertThat(bukkitDevCommandStub.hasValidArgs()).isFalse(); + + } + + @Test + @DisplayName("Test mandatory AND optional arguments validation.") + @SuppressWarnings("unchecked") + void hasValidArgs_Mandatory_And_Optional() { + + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, commandSenderMock, new String[] {"1","mandatoryArgument","1.2"}) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[] {IntegerArgument.class, StringArgument.class}); + when(bukkitCommandDataMock.getOptionalArguments()).thenReturn(new Class[] {DoubleArgument.class}); + + assertThat(bukkitDevCommandStub.hasValidArgs()).isTrue(); + + } + + @Test + @DisplayName("Test invalid mandatory AND optional arguments validation.") + @SuppressWarnings("unchecked") + void hasValidArgs_Mandatory_And_Optional_Invalid() { + + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, commandSenderMock, new String[] {"1","true","1.2"}) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[] {IntegerArgument.class, BooleanArgument.class}); + when(bukkitCommandDataMock.getOptionalArguments()).thenReturn(new Class[] {BooleanArgument.class}); + + // Fails cause although the mandatory arguments are valid the optional arguments are not valid. + assertThat(bukkitDevCommandStub.hasValidArgs()).isFalse(); + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[] {DoubleArgument.class, IntegerArgument.class}); + when(bukkitCommandDataMock.getOptionalArguments()).thenReturn(new Class[] {BooleanArgument.class}); + + // Fails cause although the optional arguments are valid the mandatory arguments are not valid + assertThat(bukkitDevCommandStub.hasValidArgs()).isFalse(); + + } + + @Test + @DisplayName("Test argument validation for unconventional arguments.") + @SuppressWarnings("unchecked") + void hasValidArgs_WeirdArguments() { + + String[] arguments = new String[] {"-78","yes",".22", "-0.44"}; + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, commandSenderMock, arguments) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[] {IntegerArgument.class, BooleanArgument.class, DoubleArgument.class, DoubleArgument.class}); + + assertThat(bukkitDevCommandStub.hasValidArgs()).isTrue(); + + } + + @Test + @DisplayName("Test argument validation without optional args.") + @SuppressWarnings("unchecked") + void hasValidArgs_OptionalArgs() { + + String[] arguments = new String[] {"-78","yes"}; + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, commandSenderMock, arguments) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(new Class[] {IntegerArgument.class, BooleanArgument.class}); + // Request validation for optional argument - not present in this case + when(bukkitCommandDataMock.getOptionalArguments()).thenReturn(new Class[] {StringArgument.class}); + + // The argument validation passes cause the argument missing is optional + assertThat(bukkitDevCommandStub.hasValidArgs()).isTrue(); + + } + + + @Test + @DisplayName("Test for call of argument validation without configuration.") + void argumentsConfigExceptionTest() { + + String[] arguments = new String[] {"-78","yes",".22", "-0.44"}; + bukkitDevCommandStub = new BukkitDevCommand(bukkitCommandDataMock, commandSenderMock, arguments) { + @Override + public void execute() { + System.out.println("Command Executed"); + } + }; + + when(bukkitCommandDataMock.getMandatoryArguments()).thenReturn(null); + when(bukkitCommandDataMock.getOptionalArguments()).thenReturn(null); + + assertThrows(ArgumentsConfigException.class, + () -> bukkitDevCommandStub.hasValidArgs(), + String.format("Unable to find arguments configuration for the command %s. Have you added configured any arguments for the command?", bukkitCommandDataMock.getName())); + + } + +} \ No newline at end of file diff --git a/src/test/java/me/hgsoft/minecraft/devcommand/factory/CommandFactoryTest.java b/src/test/java/dev/hugog/minecraft/dev_command/factory/CommandFactoryTest.java similarity index 55% rename from src/test/java/me/hgsoft/minecraft/devcommand/factory/CommandFactoryTest.java rename to src/test/java/dev/hugog/minecraft/dev_command/factory/CommandFactoryTest.java index 6a42395..ce7dccc 100644 --- a/src/test/java/me/hgsoft/minecraft/devcommand/factory/CommandFactoryTest.java +++ b/src/test/java/dev/hugog/minecraft/dev_command/factory/CommandFactoryTest.java @@ -1,13 +1,13 @@ -package me.hgsoft.minecraft.devcommand.factory; +package dev.hugog.minecraft.dev_command.factory; -import me.hgsoft.minecraft.devcommand.commands.data.AbstractCommandData; -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.commands.builder.BukkitCommandDataBuilder; -import me.hgsoft.minecraft.devcommand.commands.IDevCommand; -import me.hgsoft.minecraft.devcommand.factories.CommandFactory; -import me.hgsoft.minecraft.devcommand.factories.IObjectFactory; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.utils.TestCommandDevCommand; +import dev.hugog.minecraft.dev_command.commands.IDevCommand; +import dev.hugog.minecraft.dev_command.commands.builder.BukkitCommandDataBuilder; +import dev.hugog.minecraft.dev_command.commands.data.AbstractCommandData; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; +import dev.hugog.minecraft.dev_command.factories.CommandFactory; +import dev.hugog.minecraft.dev_command.factories.IObjectFactory; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.utils.test_classes.valid.TestCommand; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,8 +26,8 @@ class CommandFactoryTest { @BeforeEach void setUp() { - bukkitCommandFactory = new CommandFactory(null, "good", "afternoon"); - bukkitCommand = new BukkitCommandDataBuilder("test", integrationMock, TestCommandDevCommand.class) + bukkitCommandFactory = new CommandFactory(null, new String[] {"good", "afternoon"}); + bukkitCommand = new BukkitCommandDataBuilder("test", integrationMock, TestCommand.class) .withName("Test Command") .withDescription("Bukkit Test Command") .build(); @@ -36,7 +36,7 @@ void setUp() { @Test void generateExecutorForBukkitCommand() { IDevCommand generatedBukkitCommandExecutor = bukkitCommandFactory.generate(bukkitCommand); - Assertions.assertTrue(generatedBukkitCommandExecutor instanceof TestCommandDevCommand); + Assertions.assertTrue(generatedBukkitCommandExecutor instanceof TestCommand); } } \ No newline at end of file diff --git a/src/test/java/dev/hugog/minecraft/dev_command/registry/CommandRegistryTest.java b/src/test/java/dev/hugog/minecraft/dev_command/registry/CommandRegistryTest.java new file mode 100644 index 0000000..61636c8 --- /dev/null +++ b/src/test/java/dev/hugog/minecraft/dev_command/registry/CommandRegistryTest.java @@ -0,0 +1,52 @@ +package dev.hugog.minecraft.dev_command.registry; + +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; +import dev.hugog.minecraft.dev_command.integration.Integration; +import dev.hugog.minecraft.dev_command.registry.commands.CommandRegistry; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.spy; + +@ExtendWith(MockitoExtension.class) +class CommandRegistryTest { + + @Mock + private Integration integrationStub; + @Mock + private BukkitCommandData bukkitCommand; + + @Test + void add() { + + CommandRegistry commandRegistry = spy(CommandRegistry.class); + + assertNull(commandRegistry.getValues(integrationStub)); + + commandRegistry.add(integrationStub, bukkitCommand); + + assertNotNull(commandRegistry.getValues(integrationStub)); + assertEquals(1, commandRegistry.getValues(integrationStub).size()); + assertEquals(bukkitCommand, commandRegistry.getValues(integrationStub).get(0)); + + } + + @Test + void remove() { + + CommandRegistry commandRegistry = spy(CommandRegistry.class); + + commandRegistry.setValues(integrationStub, List.of(bukkitCommand)); + + assertNotNull(commandRegistry.getValues(integrationStub)); + assertEquals(1, commandRegistry.getValues(integrationStub).size()); + assertEquals(bukkitCommand, commandRegistry.getValues(integrationStub).get(0)); + + } + +} \ No newline at end of file diff --git a/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/invalid/TestCommandCopy.java b/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/invalid/TestCommandCopy.java new file mode 100644 index 0000000..3732000 --- /dev/null +++ b/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/invalid/TestCommandCopy.java @@ -0,0 +1,32 @@ +package dev.hugog.minecraft.dev_command.utils.test_classes.invalid; + +import dev.hugog.minecraft.dev_command.commands.BukkitDevCommand; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; +import dev.hugog.minecraft.dev_command.annotations.ArgsValidation; +import dev.hugog.minecraft.dev_command.annotations.Command; +import dev.hugog.minecraft.dev_command.validators.IntegerArgument; +import org.bukkit.command.CommandSender; + +@Command(alias = "test", description = "Bukkit Test Command!", permission = "command.bukkit_test") +@ArgsValidation(mandatoryArgs = {IntegerArgument.class}) +public class TestCommandCopy extends BukkitDevCommand { + + public static boolean called; + public static BukkitCommandData command; + public static CommandSender sender; + public static String[] args; + + public TestCommandCopy(BukkitCommandData command, CommandSender commandSender, String[] args) { + super(command, commandSender, args); + } + + @Override + public void execute() { + System.out.println("Bukkit Test Command executed!"); + called = true; + command = this.getCommandData(); + sender = getCommandSender(); + args = getArgs(); + } + +} diff --git a/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/ArgumentTestCommand.java b/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/ArgumentTestCommand.java new file mode 100644 index 0000000..7bb7cc2 --- /dev/null +++ b/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/ArgumentTestCommand.java @@ -0,0 +1,30 @@ +package dev.hugog.minecraft.dev_command.utils.test_classes.valid; + +import dev.hugog.minecraft.dev_command.commands.BukkitDevCommand; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; +import dev.hugog.minecraft.dev_command.annotations.ArgsValidation; +import dev.hugog.minecraft.dev_command.annotations.Command; +import dev.hugog.minecraft.dev_command.validators.IntegerArgument; +import org.bukkit.command.CommandSender; + +@Command(alias = "test_arg", description = "Argument Test Command!", permission = "command.bukkit_test") +@ArgsValidation(mandatoryArgs = {IntegerArgument.class}) +public class ArgumentTestCommand extends BukkitDevCommand { + + public static boolean called; + public static boolean hasPermission; + public static boolean hasValidArgs; + + public ArgumentTestCommand(BukkitCommandData command, CommandSender commandSender, String[] args) { + super(command, commandSender, args); + } + + @Override + public void execute() { + System.out.println("Argument Test Command Executed!"); + called = true; + hasPermission = hasPermissionToExecuteCommand(); + hasValidArgs = hasValidArgs(); + } + +} diff --git a/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/InvalidTestCommand.java b/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/InvalidTestCommand.java new file mode 100644 index 0000000..b5e6fad --- /dev/null +++ b/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/InvalidTestCommand.java @@ -0,0 +1,7 @@ +package dev.hugog.minecraft.dev_command.utils.test_classes.valid; + +import dev.hugog.minecraft.dev_command.annotations.Command; + +@Command(alias = "invalid_cmd") +public class InvalidTestCommand { +} diff --git a/src/test/java/me/hgsoft/minecraft/devcommand/utils/arguments/NoAnnotationArgumentTestCommandDevCommand.java b/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/NoAnnotationTestCommand.java similarity index 53% rename from src/test/java/me/hgsoft/minecraft/devcommand/utils/arguments/NoAnnotationArgumentTestCommandDevCommand.java rename to src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/NoAnnotationTestCommand.java index f3e5108..76cbf0d 100644 --- a/src/test/java/me/hgsoft/minecraft/devcommand/utils/arguments/NoAnnotationArgumentTestCommandDevCommand.java +++ b/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/NoAnnotationTestCommand.java @@ -1,16 +1,16 @@ -package me.hgsoft.minecraft.devcommand.utils.arguments; +package dev.hugog.minecraft.dev_command.utils.test_classes.valid; -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.commands.BukkitDevCommand; +import dev.hugog.minecraft.dev_command.commands.BukkitDevCommand; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; import org.bukkit.command.CommandSender; -public class NoAnnotationArgumentTestCommandDevCommand extends BukkitDevCommand { +public class NoAnnotationTestCommand extends BukkitDevCommand { public static boolean called; public static boolean hasPermission; public static boolean hasValidArgs; - public NoAnnotationArgumentTestCommandDevCommand(BukkitCommandData command, CommandSender commandSender, String[] args) { + public NoAnnotationTestCommand(BukkitCommandData command, CommandSender commandSender, String[] args) { super(command, commandSender, args); } diff --git a/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/TestCommand.java b/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/TestCommand.java new file mode 100644 index 0000000..4bd037c --- /dev/null +++ b/src/test/java/dev/hugog/minecraft/dev_command/utils/test_classes/valid/TestCommand.java @@ -0,0 +1,32 @@ +package dev.hugog.minecraft.dev_command.utils.test_classes.valid; + +import dev.hugog.minecraft.dev_command.commands.BukkitDevCommand; +import dev.hugog.minecraft.dev_command.commands.data.BukkitCommandData; +import dev.hugog.minecraft.dev_command.annotations.ArgsValidation; +import dev.hugog.minecraft.dev_command.annotations.Command; +import dev.hugog.minecraft.dev_command.validators.IntegerArgument; +import org.bukkit.command.CommandSender; + +@Command(alias = "test", description = "Bukkit Test Command!", permission = "command.bukkit_test") +@ArgsValidation(mandatoryArgs = {IntegerArgument.class}) +public class TestCommand extends BukkitDevCommand { + + public static boolean called; + public static BukkitCommandData command; + public static CommandSender sender; + public static String[] args; + + public TestCommand(BukkitCommandData command, CommandSender commandSender, String[] args) { + super(command, commandSender, args); + } + + @Override + public void execute() { + System.out.println("Bukkit Test Command executed!"); + called = true; + command = this.getCommandData(); + sender = getCommandSender(); + args = getArgs(); + } + +} diff --git a/src/test/java/me/hgsoft/minecraft/devcommand/CommandHandlerTest.java b/src/test/java/me/hgsoft/minecraft/devcommand/CommandHandlerTest.java deleted file mode 100644 index d79b199..0000000 --- a/src/test/java/me/hgsoft/minecraft/devcommand/CommandHandlerTest.java +++ /dev/null @@ -1,96 +0,0 @@ -package me.hgsoft.minecraft.devcommand; - -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.commands.builder.BukkitCommandDataBuilder; -import me.hgsoft.minecraft.devcommand.exceptions.InvalidIntegrationException; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.registry.commands.CommandRegistry; -import me.hgsoft.minecraft.devcommand.utils.TestCommandDevCommand; -import me.hgsoft.minecraft.devcommand.validators.IntegerArgument; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; - -class CommandHandlerTest { - - private CommandHandler commandHandler; - private CommandRegistry commandRegistry; - private BukkitCommandData bukkitCommandStub; - private Integration integrationStub; - - @BeforeEach - void setUp() { - commandHandler = CommandHandler.createOrGetInstance(); - commandRegistry = CommandRegistry.getInstance(); - integrationStub = new Integration("myIntegration", "me.hgsoft."); - bukkitCommandStub = new BukkitCommandDataBuilder("test", integrationStub, TestCommandDevCommand.class) - .withDescription("Bukkit Test Command!") - .withPermission("command.bukkit_test") - .withMandatoryArguments(IntegerArgument.class) - .build(); - } - - @AfterEach - void tearDown() { - commandRegistry.setValues(integrationStub, null); - TestCommandDevCommand.called = false; - } - - @Test - void registerCommand() { - - Assertions.assertNull(commandRegistry.getValues(integrationStub)); - - commandHandler.registerCommand(integrationStub, bukkitCommandStub); - - Assertions.assertEquals(1, commandRegistry.getValues(integrationStub).size()); - Assertions.assertEquals(bukkitCommandStub, commandRegistry.getValues(integrationStub).get(0)); - - } - - @Test - void executeCommandByAlias_CommandNotRegistered() { - - boolean commandSuccessfullyExecuted = commandHandler.executeCommandByAlias(integrationStub, bukkitCommandStub.getAlias(), null, "1"); - - assertFalse(commandSuccessfullyExecuted); - assertFalse(TestCommandDevCommand.called); - - } - - @Test - void executeCommandByAliasForBukkitCommand() { - - commandHandler.registerCommand(integrationStub, bukkitCommandStub); - boolean commandSuccessfullyExecuted = commandHandler.executeCommandByAlias(integrationStub, bukkitCommandStub.getAlias(), null, "good", "afternoon"); - - assertTrue(commandSuccessfullyExecuted); - assertTrue(TestCommandDevCommand.called); - - } - - @Test - void initCommandsAutoConfiguration() { - - commandHandler.initCommandsAutoConfiguration(integrationStub); - - assertThat(commandRegistry.getValues(integrationStub)) - .isNotNull() - .hasSize(2) - .contains(bukkitCommandStub); - - } - - @Test - void initCommandsAutoConfigurationWithInvalidIntegration() { - - Integration invalidIntegration = new Integration("MyPlugin", null); - assertThrows(InvalidIntegrationException.class, () -> commandHandler.initCommandsAutoConfiguration(invalidIntegration)); - - } - -} \ No newline at end of file diff --git a/src/test/java/me/hgsoft/minecraft/devcommand/IntegrationTest.java b/src/test/java/me/hgsoft/minecraft/devcommand/IntegrationTest.java deleted file mode 100644 index 70f8303..0000000 --- a/src/test/java/me/hgsoft/minecraft/devcommand/IntegrationTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package me.hgsoft.minecraft.devcommand; - -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.commands.builder.BukkitCommandDataBuilder; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.registry.commands.CommandRegistry; -import me.hgsoft.minecraft.devcommand.utils.TestCommandDevCommand; -import org.junit.jupiter.api.*; - -import static org.junit.jupiter.api.Assertions.*; - -class IntegrationTest { - - private static CommandHandler commandHandler; - private static CommandRegistry commandRegistry; - private static Integration pluginIntegration; - - @BeforeAll - static void initialSetUp() { - commandHandler = CommandHandler.createOrGetInstance(); - commandRegistry = CommandRegistry.getInstance(); - pluginIntegration = new Integration("myPlugin", "me.hgsoft.minecraft.devcommand"); - } - - @BeforeEach - void setUp() { - TestCommandDevCommand.called = false; - } - - @AfterEach - void tearDown() { - TestCommandDevCommand.called = false; - TestCommandDevCommand.args = null; - TestCommandDevCommand.command = null; - TestCommandDevCommand.sender = null; - commandRegistry.setValues(pluginIntegration, null); - } - - @Test - void registerAndExecuteBukkitCommand() { - - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("help bukkit", pluginIntegration, TestCommandDevCommand.class) - .withDescription("Help Command") - .withPermission("dev_commands.commands.help") - .build(); - - commandHandler.registerCommand(pluginIntegration, bukkitCommand); - commandHandler.executeCommandByAlias(pluginIntegration, "help bukkit", null, "1"); - - // The command was successfully called - assertTrue(TestCommandDevCommand.called); - - // The sender is the same - assertNull(TestCommandDevCommand.sender); - // The args are also correct - assertArrayEquals(new String[] {"1"}, TestCommandDevCommand.args); - - assertEquals(bukkitCommand, TestCommandDevCommand.command); - - } - - @Test - void autoCommandDiscoveryAndExecuteBukkitCommand() { - - commandHandler.initCommandsAutoConfiguration(pluginIntegration); - commandHandler.executeCommandByAlias(pluginIntegration, "test", null, "good", "afternoon"); - - // The command was successfully called - assertTrue(TestCommandDevCommand.called); - - // The sender is the same - assertNull(TestCommandDevCommand.sender); - // The args are also correct - assertArrayEquals(new String[] {"good", "afternoon"}, TestCommandDevCommand.args); - - // The command alias is also correct - assertNotNull(TestCommandDevCommand.command); - assertEquals(TestCommandDevCommand.command.getAlias(), "test"); - - } - -} diff --git a/src/test/java/me/hgsoft/minecraft/devcommand/executors/BukkitDevCommandTest.java b/src/test/java/me/hgsoft/minecraft/devcommand/executors/BukkitDevCommandTest.java deleted file mode 100644 index d923069..0000000 --- a/src/test/java/me/hgsoft/minecraft/devcommand/executors/BukkitDevCommandTest.java +++ /dev/null @@ -1,248 +0,0 @@ -package me.hgsoft.minecraft.devcommand.executors; - -import me.hgsoft.minecraft.devcommand.CommandHandler; -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.commands.builder.BukkitCommandDataBuilder; -import me.hgsoft.minecraft.devcommand.exceptions.ArgumentsConfigException; -import me.hgsoft.minecraft.devcommand.exceptions.PermissionConfigException; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.registry.commands.CommandRegistry; -import me.hgsoft.minecraft.devcommand.utils.arguments.ArgumentDevCommandTestCommand; -import me.hgsoft.minecraft.devcommand.utils.arguments.NoAnnotationArgumentTestCommandDevCommand; -import me.hgsoft.minecraft.devcommand.validators.BooleanArgument; -import me.hgsoft.minecraft.devcommand.validators.DoubleArgument; -import me.hgsoft.minecraft.devcommand.validators.IntegerArgument; -import me.hgsoft.minecraft.devcommand.validators.StringArgument; -import org.bukkit.command.CommandSender; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -class BukkitDevCommandTest { - - @Mock - private CommandSender commandSender; - - private Integration integration; - private CommandHandler commandHandler; - private CommandRegistry commandRegistry; - - @BeforeEach - void setUp() { - integration = new Integration("MyPlugin", "me"); - commandHandler = CommandHandler.createOrGetInstance(); - commandRegistry = CommandRegistry.getInstance(); - } - - @AfterEach - void tearDown() { - NoAnnotationArgumentTestCommandDevCommand.called = false; - NoAnnotationArgumentTestCommandDevCommand.hasPermission = false; - NoAnnotationArgumentTestCommandDevCommand.hasValidArgs = false; - commandRegistry.setValues(integration, null); - } - - @Test - void hasPermissionToExecuteCommand() { - - String commandPermission = "commands.no_annotation_test"; - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", integration, NoAnnotationArgumentTestCommandDevCommand.class) - .withPermission(commandPermission) - .build(); - - when(commandSender.hasPermission(bukkitCommand.getPermission())).thenReturn(true); - - commandHandler.registerCommand(integration, bukkitCommand); - - try { - commandHandler.executeCommandByAlias(integration, "test", commandSender); - } catch (ArgumentsConfigException e) { - // Ignored exception - } - - assertTrue(NoAnnotationArgumentTestCommandDevCommand.called); - assertTrue(NoAnnotationArgumentTestCommandDevCommand.hasPermission); - - } - - @Test - void hasPermissionToExecuteCommand_NotConfiguredException() { - - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", integration, NoAnnotationArgumentTestCommandDevCommand.class) - .build(); - - commandHandler.registerCommand(integration, bukkitCommand); - - assertThrows(PermissionConfigException.class, - () -> commandHandler.executeCommandByAlias(integration, "test", commandSender), - String.format("Unable to find the permission for the command %s. Have you configured any permission at all?", bukkitCommand.getName())); - - } - - @Test - void hasValidArgs_Mandatory() { - - String commandPermission = "commands.no_annotation_test"; - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", integration, NoAnnotationArgumentTestCommandDevCommand.class) - .withPermission(commandPermission) - .withMandatoryArguments(IntegerArgument.class, DoubleArgument.class, StringArgument.class, BooleanArgument.class) - .build(); - - commandHandler.registerCommand(integration, bukkitCommand); - commandHandler.executeCommandByAlias(integration, "test", commandSender, "1", "22.222", "hey", "true"); - - assertTrue(NoAnnotationArgumentTestCommandDevCommand.called); - assertTrue(NoAnnotationArgumentTestCommandDevCommand.hasValidArgs); - - } - - @Test - void hasValidArgs_Mandatory_InvalidArguments() { - - String commandPermission = "commands.no_annotation_test"; - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", integration, NoAnnotationArgumentTestCommandDevCommand.class) - .withPermission(commandPermission) - .withMandatoryArguments(IntegerArgument.class, DoubleArgument.class, StringArgument.class, BooleanArgument.class) - .build(); - - commandHandler.registerCommand(integration, bukkitCommand); - commandHandler.executeCommandByAlias(integration, "test", commandSender, "Hello!", ".22aa", "Valid!", "ash"); - - assertTrue(NoAnnotationArgumentTestCommandDevCommand.called); - assertFalse(NoAnnotationArgumentTestCommandDevCommand.hasValidArgs); - - } - - @Test - void hasValidArgs_Optional() { - - String commandPermission = "commands.no_annotation_test"; - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", integration, NoAnnotationArgumentTestCommandDevCommand.class) - .withPermission(commandPermission) - .withOptionalArguments(IntegerArgument.class, DoubleArgument.class) - .build(); - - commandHandler.registerCommand(integration, bukkitCommand); - commandHandler.executeCommandByAlias(integration, "test", commandSender, "1"); - - assertTrue(NoAnnotationArgumentTestCommandDevCommand.called); - assertTrue(NoAnnotationArgumentTestCommandDevCommand.hasValidArgs); - - } - - @Test - void hasValidArgs_Optional_InvalidArguments() { - - String commandPermission = "commands.no_annotation_test"; - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", integration, NoAnnotationArgumentTestCommandDevCommand.class) - .withPermission(commandPermission) - .withOptionalArguments(IntegerArgument.class, DoubleArgument.class) - .build(); - - commandHandler.registerCommand(integration, bukkitCommand); - commandHandler.executeCommandByAlias(integration, "test", commandSender, "Hey", ".22"); - - assertTrue(NoAnnotationArgumentTestCommandDevCommand.called); - assertFalse(NoAnnotationArgumentTestCommandDevCommand.hasValidArgs); - - } - - @Test - void hasValidArgs_Mandatory_And_Optional() { - - String commandPermission = "commands.no_annotation_test"; - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", integration, NoAnnotationArgumentTestCommandDevCommand.class) - .withPermission(commandPermission) - .withMandatoryArguments(BooleanArgument.class) - .withOptionalArguments(IntegerArgument.class, DoubleArgument.class) - .build(); - - commandHandler.registerCommand(integration, bukkitCommand); - commandHandler.executeCommandByAlias(integration, "test", commandSender, "True", "22"); - - assertTrue(NoAnnotationArgumentTestCommandDevCommand.called); - assertTrue(NoAnnotationArgumentTestCommandDevCommand.hasValidArgs); - - } - - @Test - void hasValidArgs_Mandatory_And_Optional_Invalid() { - - String commandPermission = "commands.no_annotation_test"; - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", integration, NoAnnotationArgumentTestCommandDevCommand.class) - .withPermission(commandPermission) - .withMandatoryArguments(BooleanArgument.class) - .withOptionalArguments(IntegerArgument.class, DoubleArgument.class) - .build(); - - commandHandler.registerCommand(integration, bukkitCommand); - commandHandler.executeCommandByAlias(integration, "test", commandSender, "true", "Boa tarde", ".22"); - - assertTrue(NoAnnotationArgumentTestCommandDevCommand.called); - assertFalse(NoAnnotationArgumentTestCommandDevCommand.hasValidArgs); - - } - - @Test - void hasValidArgs_WeirdArguments() { - - String commandPermission = "commands.no_annotation_test"; - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", integration, NoAnnotationArgumentTestCommandDevCommand.class) - .withPermission(commandPermission) - .withMandatoryArguments(IntegerArgument.class, DoubleArgument.class, StringArgument.class, BooleanArgument.class) - .build(); - - commandHandler.registerCommand(integration, bukkitCommand); - commandHandler.executeCommandByAlias(integration, "test", commandSender, "-78", ".222", "20", "yes"); - - assertTrue(NoAnnotationArgumentTestCommandDevCommand.called); - assertTrue(NoAnnotationArgumentTestCommandDevCommand.hasValidArgs); - - } - - @Test - void hasValidArgs_Mandatory_And_Optional_Annotation() { - - commandHandler.initCommandsAutoConfiguration(integration); - commandHandler.executeCommandByAlias(integration, "test_arg", commandSender, "22"); - - assertTrue(ArgumentDevCommandTestCommand.called); - assertTrue(ArgumentDevCommandTestCommand.hasValidArgs); - - } - - @Test - void hasValidArgs_Mandatory_And_Optional_Annotation_Invalid() { - - commandHandler.initCommandsAutoConfiguration(integration); - commandHandler.executeCommandByAlias(integration, "test_arg", commandSender, "true"); - - assertTrue(ArgumentDevCommandTestCommand.called); - assertFalse(ArgumentDevCommandTestCommand.hasValidArgs); - - } - - @Test - void argumentsConfigExceptionTest() { - - String commandPermission = "commands.no_annotation_test"; - BukkitCommandData bukkitCommand = new BukkitCommandDataBuilder("test", integration, NoAnnotationArgumentTestCommandDevCommand.class) - .withPermission(commandPermission) - .build(); - - commandHandler.registerCommand(integration, bukkitCommand); - - assertThrows(ArgumentsConfigException.class, - () -> commandHandler.executeCommandByAlias(integration, "test", commandSender), - String.format("Unable to find arguments configuration for the command %s. Have you added configured any arguments for the command?", bukkitCommand.getName())); - - } - -} \ No newline at end of file diff --git a/src/test/java/me/hgsoft/minecraft/devcommand/registry/CommandRegistryTest.java b/src/test/java/me/hgsoft/minecraft/devcommand/registry/CommandRegistryTest.java deleted file mode 100644 index f991629..0000000 --- a/src/test/java/me/hgsoft/minecraft/devcommand/registry/CommandRegistryTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package me.hgsoft.minecraft.devcommand.registry; - -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.commands.builder.BukkitCommandDataBuilder; -import me.hgsoft.minecraft.devcommand.integration.Integration; -import me.hgsoft.minecraft.devcommand.registry.commands.CommandRegistry; -import me.hgsoft.minecraft.devcommand.utils.TestCommandDevCommand; -import org.junit.jupiter.api.*; - -import java.util.List; - -class CommandRegistryTest { - - private BukkitCommandData bukkitCommand; - private CommandRegistry commandRegistry; - private Integration integrationStub; - - @BeforeEach - void setUp() { - integrationStub = new Integration("myIntegration", null); - commandRegistry = CommandRegistry.getInstance(); - bukkitCommand = new BukkitCommandDataBuilder("test", integrationStub, TestCommandDevCommand.class).build(); - } - - @AfterEach - void tearDown() { - commandRegistry.setValues(integrationStub, null); - } - - @Test - void add() { - - Assertions.assertNull(commandRegistry.getValues(integrationStub)); - - commandRegistry.add(integrationStub, bukkitCommand); - - Assertions.assertNotNull(commandRegistry.getValues(integrationStub)); - Assertions.assertEquals(1, commandRegistry.getValues(integrationStub).size()); - Assertions.assertEquals(bukkitCommand, commandRegistry.getValues(integrationStub).get(0)); - - } - - @Test - void remove() { - - commandRegistry.setValues(integrationStub, List.of(bukkitCommand)); - - Assertions.assertNotNull(commandRegistry.getValues(integrationStub)); - Assertions.assertEquals(1, commandRegistry.getValues(integrationStub).size()); - Assertions.assertEquals(bukkitCommand, commandRegistry.getValues(integrationStub).get(0)); - - } - -} \ No newline at end of file diff --git a/src/test/java/me/hgsoft/minecraft/devcommand/utils/InvalidTestCommand.java b/src/test/java/me/hgsoft/minecraft/devcommand/utils/InvalidTestCommand.java deleted file mode 100644 index c39e05e..0000000 --- a/src/test/java/me/hgsoft/minecraft/devcommand/utils/InvalidTestCommand.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.hgsoft.minecraft.devcommand.utils; - -import me.hgsoft.minecraft.devcommand.annotations.Command; - -@Command(alias = "invalid_cmd") -public class InvalidTestCommand { -} diff --git a/src/test/java/me/hgsoft/minecraft/devcommand/utils/TestCommandDevCommand.java b/src/test/java/me/hgsoft/minecraft/devcommand/utils/TestCommandDevCommand.java deleted file mode 100644 index f76f668..0000000 --- a/src/test/java/me/hgsoft/minecraft/devcommand/utils/TestCommandDevCommand.java +++ /dev/null @@ -1,32 +0,0 @@ -package me.hgsoft.minecraft.devcommand.utils; - -import me.hgsoft.minecraft.devcommand.annotations.ArgsValidation; -import me.hgsoft.minecraft.devcommand.annotations.Command; -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.commands.BukkitDevCommand; -import me.hgsoft.minecraft.devcommand.validators.IntegerArgument; -import org.bukkit.command.CommandSender; - -@Command(alias = "test", description = "Bukkit Test Command!", permission = "command.bukkit_test") -@ArgsValidation(argsTypes = {IntegerArgument.class}) -public class TestCommandDevCommand extends BukkitDevCommand { - - public static boolean called; - public static BukkitCommandData command; - public static CommandSender sender; - public static String[] args; - - public TestCommandDevCommand(BukkitCommandData command, CommandSender commandSender, String[] args) { - super(command, commandSender, args); - } - - @Override - public void execute() { - System.out.println("Bukkit Test Command executed!"); - called = true; - command = this.getCommandData(); - sender = getCommandSender(); - args = getArgs(); - } - -} diff --git a/src/test/java/me/hgsoft/minecraft/devcommand/utils/arguments/ArgumentDevCommandTestCommand.java b/src/test/java/me/hgsoft/minecraft/devcommand/utils/arguments/ArgumentDevCommandTestCommand.java deleted file mode 100644 index bf4c205..0000000 --- a/src/test/java/me/hgsoft/minecraft/devcommand/utils/arguments/ArgumentDevCommandTestCommand.java +++ /dev/null @@ -1,30 +0,0 @@ -package me.hgsoft.minecraft.devcommand.utils.arguments; - -import me.hgsoft.minecraft.devcommand.annotations.ArgsValidation; -import me.hgsoft.minecraft.devcommand.annotations.Command; -import me.hgsoft.minecraft.devcommand.commands.data.BukkitCommandData; -import me.hgsoft.minecraft.devcommand.commands.BukkitDevCommand; -import me.hgsoft.minecraft.devcommand.validators.IntegerArgument; -import org.bukkit.command.CommandSender; - -@Command(alias = "test_arg", description = "Argument Test Command!", permission = "command.bukkit_test") -@ArgsValidation(argsTypes = {IntegerArgument.class}) -public class ArgumentDevCommandTestCommand extends BukkitDevCommand { - - public static boolean called; - public static boolean hasPermission; - public static boolean hasValidArgs; - - public ArgumentDevCommandTestCommand(BukkitCommandData command, CommandSender commandSender, String[] args) { - super(command, commandSender, args); - } - - @Override - public void execute() { - System.out.println("Argument Test Command Executed!"); - called = true; - hasPermission = hasPermissionToExecuteCommand(); - hasValidArgs = hasValidArgs(); - } - -}