mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-08-03 20:16:16 -04:00
test command exection, fix execution bugs
This commit is contained in:
parent
deed2949a3
commit
574c71f359
8
doc/CLI.md
Normal file
8
doc/CLI.md
Normal file
@ -0,0 +1,8 @@
|
||||
# CLI ToDo
|
||||
|
||||
- [ ] set default root node to `null`
|
||||
- [ ] all parsers
|
||||
- [ ] better suggestions
|
||||
- [ ] gui suggestions
|
||||
- [ ] improved entity parser
|
||||
- [ ] some cli commands
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.commands.errors
|
||||
|
||||
import de.bixilon.minosoft.commands.util.CommandReader
|
||||
|
||||
class DeadEndError(
|
||||
reader: CommandReader,
|
||||
) : ReaderError(reader, reader.pointer, reader.pointer)
|
@ -35,9 +35,13 @@ abstract class CommandNode(
|
||||
open fun execute(reader: CommandReader, stack: CommandStack) {
|
||||
val pointer = reader.pointer
|
||||
val stackSize = stack.size
|
||||
var lastError: Throwable? = null
|
||||
var highestStack = 0
|
||||
|
||||
var childError: Throwable? = null
|
||||
var errorStack = -1
|
||||
|
||||
for (child in children) {
|
||||
reader.pointer = pointer
|
||||
stack.reset(stackSize)
|
||||
try {
|
||||
executeChild(child, reader, stack)
|
||||
if (reader.canPeek()) {
|
||||
@ -45,18 +49,13 @@ abstract class CommandNode(
|
||||
}
|
||||
return
|
||||
} catch (error: Throwable) {
|
||||
val size = stack.size
|
||||
if (size >= highestStack) {
|
||||
highestStack = size
|
||||
lastError = error
|
||||
if (stack.size > errorStack) {
|
||||
errorStack = stack.size
|
||||
childError = error
|
||||
}
|
||||
}
|
||||
reader.pointer = pointer
|
||||
|
||||
stack.reset(stackSize)
|
||||
}
|
||||
|
||||
throw lastError ?: if (reader.canPeek()) throw TrailingTextArgument(reader) else return
|
||||
throw childError ?: return
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.commands.nodes
|
||||
|
||||
import de.bixilon.minosoft.commands.errors.DeadEndError
|
||||
import de.bixilon.minosoft.commands.errors.ExpectedArgumentError
|
||||
import de.bixilon.minosoft.commands.stack.CommandExecutor
|
||||
import de.bixilon.minosoft.commands.stack.CommandStack
|
||||
@ -38,11 +39,12 @@ abstract class ExecutableNode(
|
||||
}
|
||||
|
||||
override fun execute(reader: CommandReader, stack: CommandStack) {
|
||||
reader.skipWhitespaces()
|
||||
if (!reader.canPeekNext()) {
|
||||
// empty string
|
||||
if (executable) {
|
||||
return execute(stack)
|
||||
} else if (children.isEmpty()) {
|
||||
throw DeadEndError(reader)
|
||||
} else {
|
||||
throw ExpectedArgumentError(reader)
|
||||
}
|
||||
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.commands.nodes
|
||||
|
||||
import de.bixilon.minosoft.commands.errors.DeadEndError
|
||||
import de.bixilon.minosoft.commands.errors.ExpectedArgumentError
|
||||
import de.bixilon.minosoft.commands.errors.literal.ExpectedLiteralArgument
|
||||
import de.bixilon.minosoft.commands.errors.literal.InvalidLiteralArgumentError
|
||||
import de.bixilon.minosoft.commands.errors.literal.TrailingTextArgument
|
||||
import de.bixilon.minosoft.commands.parser.brigadier.string.StringParseError
|
||||
import de.bixilon.minosoft.commands.parser.brigadier.string.StringParser
|
||||
import de.bixilon.minosoft.commands.stack.CommandStack
|
||||
import de.bixilon.minosoft.commands.util.CommandReader
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
||||
internal class ExecutionChildReadingTest {
|
||||
|
||||
private fun createCommand(): CommandNode {
|
||||
return RootNode()
|
||||
.addChild(LiteralNode("0_literal"))
|
||||
.addChild(
|
||||
LiteralNode("1_literal")
|
||||
.addChild(LiteralNode("1_literal_2"))
|
||||
.addChild(LiteralNode("2_literal_2", executable = true))
|
||||
)
|
||||
.addChild(LiteralNode("2_literal", executable = true))
|
||||
.addChild(
|
||||
LiteralNode("1_execute")
|
||||
.addChild(ArgumentNode("args", StringParser(StringParser.StringModes.GREEDY), executable = true))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCreation() {
|
||||
assertTrue(createCommand() is RootNode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testValid() {
|
||||
val stack = CommandStack()
|
||||
assertDoesNotThrow { (createCommand().execute(CommandReader("1_execute test"), stack)) }
|
||||
assertNotNull(stack["1_execute"])
|
||||
assertEquals(stack["args"], "test")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testValid2() {
|
||||
val stack = CommandStack()
|
||||
assertDoesNotThrow { (createCommand().execute(CommandReader("1_execute this is a really long valid greedy read string..."), stack)) }
|
||||
assertNotNull(stack["1_execute"])
|
||||
assertEquals(stack["args"], "this is a really long valid greedy read string...")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInvalidLiteralValid() {
|
||||
assertThrows<InvalidLiteralArgumentError> { (createCommand().execute(CommandReader("3_404_not_found"), CommandStack())) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBlankStringArgument() {
|
||||
assertThrows<StringParseError> { (createCommand().execute(CommandReader("1_execute "), CommandStack())) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNoStringArgument() {
|
||||
assertThrows<ExpectedArgumentError> { (createCommand().execute(CommandReader("1_execute"), CommandStack())) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDeadEnd() {
|
||||
assertThrows<DeadEndError> { (createCommand().execute(CommandReader("0_literal"), CommandStack())) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTrailingData() {
|
||||
assertThrows<TrailingTextArgument> { (createCommand().execute(CommandReader("0_literal test"), CommandStack())) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testEmpty() {
|
||||
assertThrows<ExpectedLiteralArgument> { (createCommand().execute(CommandReader(""), CommandStack())) }
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun testTrailingWhitespace() {
|
||||
assertDoesNotThrow { createCommand().execute(CommandReader("2_literal "), CommandStack()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test2TrailingWhitespace() {
|
||||
assertDoesNotThrow { createCommand().execute(CommandReader("1_literal 2_literal_2 "), CommandStack()) }
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@
|
||||
package de.bixilon.minosoft.commands.nodes
|
||||
|
||||
import de.bixilon.minosoft.commands.errors.literal.InvalidLiteralArgumentError
|
||||
import de.bixilon.minosoft.commands.errors.literal.TrailingTextArgument
|
||||
import de.bixilon.minosoft.commands.errors.reader.ExpectedWhitespaceError
|
||||
import de.bixilon.minosoft.commands.parser.brigadier.string.StringParseError
|
||||
import de.bixilon.minosoft.commands.parser.brigadier.string.StringParser
|
||||
@ -29,7 +30,11 @@ internal class SuggestionChildReadingTest {
|
||||
|
||||
private fun createCommand(): CommandNode {
|
||||
return RootNode()
|
||||
.addChild(LiteralNode("1_literal"))
|
||||
.addChild(
|
||||
LiteralNode("1_literal")
|
||||
.addChild(LiteralNode("1_literal_2"))
|
||||
.addChild(LiteralNode("2_literal_2"))
|
||||
)
|
||||
.addChild(LiteralNode("2_literal"))
|
||||
.addChild(
|
||||
LiteralNode("1_execute")
|
||||
@ -76,4 +81,34 @@ internal class SuggestionChildReadingTest {
|
||||
fun testEmptySuggestions() {
|
||||
assertEquals(createCommand().getSuggestions(CommandReader(""), CommandStack()), listOf("1_literal", "2_literal", "1_execute"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTrailingData() {
|
||||
assertThrows<TrailingTextArgument> { (createCommand().getSuggestions(CommandReader("2_literal test"), CommandStack())) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test2InvalidLiteral() {
|
||||
assertThrows<InvalidLiteralArgumentError> { (createCommand().getSuggestions(CommandReader("1_literal test"), CommandStack())) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test2EmptyLevelSuggestions() {
|
||||
assertEquals(createCommand().getSuggestions(CommandReader("1_literal"), CommandStack()), listOf("1_literal_2", "2_literal_2"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test2TrailingData() {
|
||||
assertThrows<TrailingTextArgument> { (createCommand().getSuggestions(CommandReader("2_literal 1_literal_2 test"), CommandStack())) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTrailingWhitespace() {
|
||||
assertEquals(createCommand().getSuggestions(CommandReader("2_literal "), CommandStack()), emptyList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test2TrailingWhitespace() {
|
||||
assertEquals(createCommand().getSuggestions(CommandReader("1_literal 1_literal_2 "), CommandStack()), emptyList())
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user