diff --git a/ButtonProcessor/pom.xml b/ButtonProcessor/pom.xml
index dfbfe2b..ed36791 100644
--- a/ButtonProcessor/pom.xml
+++ b/ButtonProcessor/pom.xml
@@ -37,7 +37,7 @@
maven-compiler-plugin
3.8.1
- -proc:none
+ none
17
diff --git a/Chroma-Core/pom.xml b/Chroma-Core/pom.xml
index baa48ce..a5ea55a 100755
--- a/Chroma-Core/pom.xml
+++ b/Chroma-Core/pom.xml
@@ -249,6 +249,12 @@
mccoroutine-bukkit-core
2.11.0
+
+ com.github.seeseemelk
+ MockBukkit-v1.19
+ 2.29.0
+ test
+
TBMCPlugins
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 e8da066..e62b3ce 100644
--- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.kt
+++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.kt
@@ -90,8 +90,14 @@ abstract class Command2, TP : Command2Sender>(
paramConverters[cl] = ParamConverter(converter, errormsg, allSupplier)
}
+ /**
+ * Handle the given command line as sent by the sender.
+ *
+ * @param sender The sender who sent the command
+ * @param commandline The command line, including the leading command char
+ */
open fun handleCommand(sender: TP, commandline: String): Boolean {
- val results = dispatcher.parse(commandline, sender)
+ val results = dispatcher.parse(commandline.removePrefix("/"), sender)
if (results.reader.canRead()) {
return false // Unknown command
}
@@ -138,6 +144,7 @@ abstract class Command2, TP : Command2Sender>(
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, mainNode, remainingPath) = registerNodeFromPath(fullPath)
lastNode.addChild(getExecutableNode(meth, command, ann, remainingPath, CommandArgumentHelpManager(command), fullPath))
if (mainCommandNode == null) mainCommandNode = mainNode
diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.kt b/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.kt
index 6a122c3..b8d724a 100644
--- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.kt
+++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/ICommand2.kt
@@ -74,32 +74,31 @@ abstract class ICommand2(val manager: Command2<*, TP>) {
get() = EMPTY_PATHS // TODO: Deal with this (used for channel IDs)
private fun getcmdpath(): String {
- if (!javaClass.isAnnotationPresent(CommandClass::class.java)) throw RuntimeException(
- "No @CommandClass annotation on command class " + javaClass.simpleName + "!"
- )
+ if (!javaClass.isAnnotationPresent(CommandClass::class.java))
+ throw RuntimeException("No @CommandClass annotation on command class ${javaClass.simpleName}!")
val getFromClass = Function { cl: Class<*> ->
cl.simpleName.lowercase(Locale.getDefault()).replace("commandbase", "") // <-- ...
.replace("command", "")
}
- var path = javaClass.getAnnotation(CommandClass::class.java).path
- var prevpath = if (path.isEmpty()) getFromClass.apply(javaClass) else path.also { path = it }
- var cl: Class<*>? = javaClass.superclass
- while (cl != null && cl.getPackage().name != ICommand2MC::class.java.getPackage().name) {
- //
- var newpath: String
- val ccann: CommandClass? = cl.getAnnotation(CommandClass::class.java)
- if (ccann?.path.isNullOrEmpty() || ccann?.path == prevpath) {
- if (ccann?.excludeFromPath ?: Modifier.isAbstract(cl.modifiers)) {
- cl = cl.superclass
- continue
- }
- newpath = getFromClass.apply(cl)
- } else newpath = ccann!!.path
- path = "$newpath $path"
- prevpath = newpath
- cl = cl.superclass
+ val classList = mutableListOf>(javaClass)
+ while (true) {
+ val superClass = classList.last().superclass
+ if (superClass != null && superClass.getPackage().name != ICommand2MC::class.java.getPackage().name) {
+ classList.add(superClass)
+ } else {
+ break
+ }
}
- return path
+ return classList.reversed().associateWith { it.getAnnotation(CommandClass::class.java) }
+ .mapNotNull {
+ if (it.value?.path.isNullOrEmpty())
+ if (it.value?.excludeFromPath ?: Modifier.isAbstract(it.key.modifiers))
+ null
+ else
+ it.key.simpleName.lowercase().removeSuffix("commandbase").removeSuffix("command")
+ else
+ it.value.path
+ }.joinToString(" ")
}
companion object {
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
new file mode 100644
index 0000000..b4c3db6
--- /dev/null
+++ b/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCTest.kt
@@ -0,0 +1,73 @@
+package buttondevteam.lib.chat.test
+
+import be.seeseemelk.mockbukkit.MockBukkit
+import buttondevteam.core.MainPlugin
+import buttondevteam.core.component.channel.Channel
+import buttondevteam.lib.architecture.ButtonPlugin
+import buttondevteam.lib.chat.Command2
+import buttondevteam.lib.chat.Command2MCSender
+import buttondevteam.lib.chat.CommandClass
+import buttondevteam.lib.chat.ICommand2MC
+import buttondevteam.lib.player.ChromaGamerBase
+import buttondevteam.lib.player.TBMCPlayer
+import org.junit.jupiter.api.MethodOrderer
+import org.junit.jupiter.api.Order
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestMethodOrder
+import java.util.*
+
+@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
+class Command2MCTest {
+
+ init {
+ if (!initialized) {
+ try {
+ MockBukkit.mock()
+ } catch (e: IllegalStateException) {
+ throw RuntimeException("Failed to init tests! Something in here fails to initialize. Check the first test case.", e)
+ }
+ MockBukkit.load(MainPlugin::class.java, true)
+ ButtonPlugin.command2MC.unregisterCommands(MainPlugin.instance) // FIXME should have the init code separate of the plugin init code
+ initialized = true
+ }
+ }
+
+ @Test
+ @Order(1)
+ fun testRegisterCommand() {
+ MainPlugin.instance.registerCommand(TestCommand)
+ assert(ButtonPlugin.command2MC.commandNodes.size == 1)
+ assert(ButtonPlugin.command2MC.commandNodes.first().literal == "test")
+ }
+
+ @Test
+ fun testHasPermission() {
+ }
+
+ @Test
+ fun testAddParamConverter() {
+ }
+
+ @Test
+ fun testUnregisterCommands() {
+ }
+
+ @Test
+ @Order(2)
+ fun testHandleCommand() {
+ val user = ChromaGamerBase.getUser(UUID.randomUUID().toString(), TBMCPlayer::class.java)
+ assert(ButtonPlugin.command2MC.handleCommand(Command2MCSender(user, Channel.globalChat, user), "/test hmm"))
+ }
+
+ @CommandClass
+ object TestCommand : ICommand2MC() {
+ @Command2.Subcommand
+ fun def(sender: Command2MCSender, test: String) {
+ println(test)
+ }
+ }
+
+ companion object {
+ private var initialized = false
+ }
+}
\ No newline at end of file
diff --git a/Chroma-Core/src/test/resources/commands.yml b/Chroma-Core/src/test/resources/commands.yml
new file mode 100644
index 0000000..4d3ff60
--- /dev/null
+++ b/Chroma-Core/src/test/resources/commands.yml
@@ -0,0 +1,18 @@
+buttondevteam:
+ lib:
+ chat:
+ test:
+ Command2MCTest:
+ TestCommand:
+ def:
+ method: def()
+ params: ''
+ core:
+ ComponentCommand:
+ def:
+ method: def()
+ params: ''
+ ChromaCommand:
+ def:
+ method: def()
+ params: ''
diff --git a/pom.xml b/pom.xml
index af71e1c..ecae72f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,18 +41,19 @@
-
- junit
- junit
- 4.13.1
- test
-
-
-
- org.projectlombok
- lombok
- ${lombok.version}
- provided
-
-
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.9.3
+ test
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
+
\ No newline at end of file