Add command test and fix command path handling

- It feels so good to be able to debug this code
This commit is contained in:
Norbi Peti 2023-07-21 01:01:32 +02:00
parent 29f7883f9b
commit f05305cb0a
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
7 changed files with 141 additions and 37 deletions

View file

@ -37,7 +37,7 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<compilerArgument>-proc:none</compilerArgument>
<proc>none</proc>
<source>17</source>
<target>17</target>
</configuration>

View file

@ -249,6 +249,12 @@
<artifactId>mccoroutine-bukkit-core</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit-v1.19</artifactId>
<version>2.29.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<organization>
<name>TBMCPlugins</name>

View file

@ -90,8 +90,14 @@ abstract class Command2<TC : ICommand2<TP>, 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<TC : ICommand2<TP>, 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

View file

@ -74,32 +74,31 @@ abstract class ICommand2<TP : Command2Sender>(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<Class<*>>(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 {

View file

@ -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
}
}

View file

@ -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: ''

29
pom.xml
View file

@ -41,18 +41,19 @@
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>