Remove 'main command' and test empty command to improve coverage
This commit is contained in:
parent
7e511c169b
commit
2787c280f5
4 changed files with 17 additions and 23 deletions
|
@ -154,25 +154,21 @@ abstract class Command2<TC : ICommand2<TP>, TP : Command2Sender>(
|
||||||
* @param command The command to register
|
* @param command The command to register
|
||||||
* @return The Brigadier command node if you need it for something (like tab completion)
|
* @return The Brigadier command node if you need it for something (like tab completion)
|
||||||
*/
|
*/
|
||||||
protected fun registerCommandSuper(command: TC): CoreCommandNode<TP, *> {
|
protected fun registerCommandSuper(command: TC): List<CoreExecutableNode<TP, TC>> {
|
||||||
var mainCommandNode: CoreCommandNode<TP, *>? = null
|
val registeredNodes = mutableListOf<CoreExecutableNode<TP, TC>>()
|
||||||
for (meth in command.javaClass.methods) {
|
for (meth in command.javaClass.methods) {
|
||||||
val ann = meth.getAnnotation(Subcommand::class.java) ?: continue
|
val ann = meth.getAnnotation(Subcommand::class.java) ?: continue
|
||||||
val fullPath = command.commandPath + CommandUtils.getCommandPath(meth.name, ' ')
|
val fullPath = command.commandPath + CommandUtils.getCommandPath(meth.name, ' ')
|
||||||
assert(fullPath.isNotBlank()) { "No path found for command class ${command.javaClass.name} and method ${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)
|
val execNode = getExecutableNode(meth, command, ann, remainingPath, CommandArgumentHelpManager(command), fullPath)
|
||||||
lastNode.addChild(execNode)
|
lastNode.addChild(execNode)
|
||||||
val mainNode = mainNodeMaybe ?: execNode
|
registeredNodes.add(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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (mainCommandNode == null) {
|
if (registeredNodes.isEmpty()) {
|
||||||
throw RuntimeException("There are no subcommands defined in the command class " + command.javaClass.simpleName + "!")
|
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<TC : ICommand2<TP>, TP : Command2Sender>(
|
||||||
* @return The last no-op node that can be used to register the executable node,
|
* @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)
|
* the main command node and the last part of the command path (that isn't registered yet)
|
||||||
*/
|
*/
|
||||||
private fun registerNodeFromPath(path: String): Triple<CommandNode<TP>, CoreCommandNode<TP, *>?, String> {
|
private fun registerNodeFromPath(path: String): Pair<CommandNode<TP>, String> {
|
||||||
val split = path.split(" ")
|
val split = path.split(" ")
|
||||||
var parent: CommandNode<TP> = dispatcher.root
|
var parent: CommandNode<TP> = dispatcher.root
|
||||||
var mainCommand: CoreCommandNode<TP, *>? = null
|
split.dropLast(1).forEach { part ->
|
||||||
split.dropLast(1).forEachIndexed { i, part ->
|
|
||||||
val child = parent.getChild(part)
|
val child = parent.getChild(part)
|
||||||
if (child == null) parent.addChild(CoreCommandBuilder.literalNoOp<TP, TC>(part) { emptyArray() }
|
if (child == null) parent.addChild(CoreCommandBuilder.literalNoOp<TP, TC>(part) { emptyArray() }
|
||||||
.executes(::executeHelpText).build().also { parent = it })
|
.executes(::executeHelpText).build().also { parent = it })
|
||||||
else parent = child
|
else parent = child
|
||||||
if (i == 0) mainCommand =
|
|
||||||
parent as CoreCommandNode<TP, *> // 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<String> {
|
fun getCommandList(sender: TP): Array<String> {
|
||||||
|
|
|
@ -7,7 +7,6 @@ import buttondevteam.lib.architecture.ButtonPlugin
|
||||||
import buttondevteam.lib.architecture.Component
|
import buttondevteam.lib.architecture.Component
|
||||||
import buttondevteam.lib.chat.commands.CommandUtils
|
import buttondevteam.lib.chat.commands.CommandUtils
|
||||||
import buttondevteam.lib.chat.commands.CommandUtils.coreArgument
|
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.MCCommandSettings
|
||||||
import buttondevteam.lib.chat.commands.SubcommandData
|
import buttondevteam.lib.chat.commands.SubcommandData
|
||||||
import buttondevteam.lib.player.ChromaGamerBase
|
import buttondevteam.lib.player.ChromaGamerBase
|
||||||
|
@ -37,14 +36,12 @@ class Command2MC : Command2<ICommand2MC, Command2MCSender>('/', true), Listener
|
||||||
* @param command The command to register
|
* @param command The command to register
|
||||||
*/
|
*/
|
||||||
override fun registerCommand(command: ICommand2MC) {
|
override fun registerCommand(command: ICommand2MC) {
|
||||||
val commandNode = super.registerCommandSuper(command)
|
val nodes = super.registerCommandSuper(command)
|
||||||
val bcmd = registerOfficially(command, commandNode)
|
|
||||||
// TODO: Support aliases
|
|
||||||
val permPrefix = "chroma.command."
|
val permPrefix = "chroma.command."
|
||||||
//Allow commands by default, it will check mod-only
|
//Allow commands by default, it will check mod-only
|
||||||
val nodes = commandNode.coreExecutable<Command2MCSender, ICommand2MC>()
|
|
||||||
?.let { getSubcommands(commandNode) + it } ?: getSubcommands(commandNode)
|
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
|
val bcmd = registerOfficially(command, node)
|
||||||
|
// TODO: Support aliases
|
||||||
val subperm = permPrefix + node.data.fullPath.replace(' ', '.')
|
val subperm = permPrefix + node.data.fullPath.replace(' ', '.')
|
||||||
if (Bukkit.getPluginManager().getPermission(subperm) == null) //Check needed for plugin reset
|
if (Bukkit.getPluginManager().getPermission(subperm) == null) //Check needed for plugin reset
|
||||||
Bukkit.getPluginManager().addPermission(Permission(subperm, PermissionDefault.TRUE))
|
Bukkit.getPluginManager().addPermission(Permission(subperm, PermissionDefault.TRUE))
|
||||||
|
|
|
@ -119,6 +119,9 @@ abstract class Command2MCCommands {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CommandClass
|
||||||
|
object TestEmptyCommand : ICommand2MC()
|
||||||
|
|
||||||
interface ITestCommand2MC {
|
interface ITestCommand2MC {
|
||||||
var testCommandReceived: String?
|
var testCommandReceived: String?
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ class Command2MCTest {
|
||||||
TestNoMainCommand1.register()
|
TestNoMainCommand1.register()
|
||||||
TestNoMainCommand2.register()
|
TestNoMainCommand2.register()
|
||||||
TestParamsCommand.register()
|
TestParamsCommand.register()
|
||||||
|
assertEquals("There are no subcommands defined in the command class TestEmptyCommand!", assertFails { TestEmptyCommand.register() }.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in a new issue