From 2787c280f5f6c18bfcdd9ded1893f1bba0c56a2a Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 31 Jul 2023 20:43:20 +0200 Subject: [PATCH] Remove 'main command' and test empty command to improve coverage --- .../java/buttondevteam/lib/chat/Command2.kt | 27 +++++++------------ .../java/buttondevteam/lib/chat/Command2MC.kt | 9 +++---- .../lib/chat/test/Command2MCCommands.kt | 3 +++ .../lib/chat/test/Command2MCTest.kt | 1 + 4 files changed, 17 insertions(+), 23 deletions(-) diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.kt b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.kt index 62dc34b..a58727b 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.kt +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.kt @@ -154,25 +154,21 @@ abstract class Command2, TP : Command2Sender>( * @param command The command to register * @return The Brigadier command node if you need it for something (like tab completion) */ - protected fun registerCommandSuper(command: TC): CoreCommandNode { - var mainCommandNode: CoreCommandNode? = null + protected fun registerCommandSuper(command: TC): List> { + val registeredNodes = mutableListOf>() for (meth in command.javaClass.methods) { val ann = meth.getAnnotation(Subcommand::class.java) ?: continue val fullPath = command.commandPath + CommandUtils.getCommandPath(meth.name, ' ') assert(fullPath.isNotBlank()) { "No path found for command class ${command.javaClass.name} and method ${meth.name}" } - val (lastNode, mainNodeMaybe, remainingPath) = registerNodeFromPath(fullPath) + val (lastNode, remainingPath) = registerNodeFromPath(fullPath) val execNode = getExecutableNode(meth, command, ann, remainingPath, CommandArgumentHelpManager(command), fullPath) lastNode.addChild(execNode) - val mainNode = mainNodeMaybe ?: execNode - if (mainCommandNode == null) mainCommandNode = mainNode - else if (mainNode.name != mainCommandNode.name) { - MainPlugin.instance.logger.warning("Multiple commands are defined in the same class! This is not supported. Class: " + command.javaClass.simpleName) - } + registeredNodes.add(execNode) } - if (mainCommandNode == null) { - throw RuntimeException("There are no subcommands defined in the command class " + command.javaClass.simpleName + "!") + if (registeredNodes.isEmpty()) { + throw RuntimeException("There are no subcommands defined in the command class ${command.javaClass.simpleName}!") } - return mainCommandNode + return registeredNodes.toList() } /** @@ -236,19 +232,16 @@ abstract class Command2, TP : Command2Sender>( * @return The last no-op node that can be used to register the executable node, * the main command node and the last part of the command path (that isn't registered yet) */ - private fun registerNodeFromPath(path: String): Triple, CoreCommandNode?, String> { + private fun registerNodeFromPath(path: String): Pair, String> { val split = path.split(" ") var parent: CommandNode = dispatcher.root - var mainCommand: CoreCommandNode? = null - split.dropLast(1).forEachIndexed { i, part -> + split.dropLast(1).forEach { part -> val child = parent.getChild(part) if (child == null) parent.addChild(CoreCommandBuilder.literalNoOp(part) { emptyArray() } .executes(::executeHelpText).build().also { parent = it }) else parent = child - if (i == 0) mainCommand = - parent as CoreCommandNode // Has to be our own literal node, if not, well, error } - return Triple(parent, mainCommand, split.last()) + return Pair(parent, split.last()) } fun getCommandList(sender: TP): Array { diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.kt b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.kt index bbe94df..6f4791d 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.kt +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2MC.kt @@ -7,7 +7,6 @@ import buttondevteam.lib.architecture.ButtonPlugin import buttondevteam.lib.architecture.Component import buttondevteam.lib.chat.commands.CommandUtils import buttondevteam.lib.chat.commands.CommandUtils.coreArgument -import buttondevteam.lib.chat.commands.CommandUtils.coreExecutable import buttondevteam.lib.chat.commands.MCCommandSettings import buttondevteam.lib.chat.commands.SubcommandData import buttondevteam.lib.player.ChromaGamerBase @@ -37,14 +36,12 @@ class Command2MC : Command2('/', true), Listener * @param command The command to register */ override fun registerCommand(command: ICommand2MC) { - val commandNode = super.registerCommandSuper(command) - val bcmd = registerOfficially(command, commandNode) - // TODO: Support aliases + val nodes = super.registerCommandSuper(command) val permPrefix = "chroma.command." //Allow commands by default, it will check mod-only - val nodes = commandNode.coreExecutable() - ?.let { getSubcommands(commandNode) + it } ?: getSubcommands(commandNode) for (node in nodes) { + val bcmd = registerOfficially(command, node) + // TODO: Support aliases val subperm = permPrefix + node.data.fullPath.replace(' ', '.') if (Bukkit.getPluginManager().getPermission(subperm) == null) //Check needed for plugin reset Bukkit.getPluginManager().addPermission(Permission(subperm, PermissionDefault.TRUE)) diff --git a/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCCommands.kt b/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCCommands.kt index 2e150d3..eef9842 100644 --- a/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCCommands.kt +++ b/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCCommands.kt @@ -119,6 +119,9 @@ abstract class Command2MCCommands { } } + @CommandClass + object TestEmptyCommand : ICommand2MC() + interface ITestCommand2MC { var testCommandReceived: String? } diff --git a/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCTest.kt b/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCTest.kt index 9366cb9..d631e6d 100644 --- a/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCTest.kt +++ b/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCTest.kt @@ -53,6 +53,7 @@ class Command2MCTest { TestNoMainCommand1.register() TestNoMainCommand2.register() TestParamsCommand.register() + assertEquals("There are no subcommands defined in the command class TestEmptyCommand!", assertFails { TestEmptyCommand.register() }.message) } @Test