.
This commit is contained in:
parent
682cff9a8b
commit
a2d1153ae8
17 changed files with 439 additions and 326 deletions
|
|
@ -2,12 +2,14 @@ package de.kentoj.kencommandapi.api;
|
|||
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||
import de.kentoj.kencommandapi.api.parser2.InvocationCommandParser;
|
||||
import de.kentoj.kencommandapi.api.parser2.SuggestionCommandParser;
|
||||
import de.kentoj.kencommandapi.api.parser.CommandParseHelper;
|
||||
import de.kentoj.kencommandapi.api.parser.InvocationCommandParser;
|
||||
import de.kentoj.kencommandapi.api.parser.SuggestionCommandParser;
|
||||
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
||||
import de.kentoj.kencommandapi.api.platform.SendMessageMethod;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
|
|
@ -20,13 +22,14 @@ public class CommandHandler<T> {
|
|||
|
||||
public CommandHandler(SendMessageMethod<T> sendMessageMethod, HasPermissionMethod<T> hasPermissionMethod) {
|
||||
this.sendMessageMethod = sendMessageMethod;
|
||||
invocationParser = new InvocationCommandParser<>(hasPermissionMethod);
|
||||
suggestionParser = new SuggestionCommandParser<>(hasPermissionMethod);
|
||||
var parseHelper = new CommandParseHelper<>(hasPermissionMethod);
|
||||
invocationParser = new InvocationCommandParser<>(parseHelper);
|
||||
suggestionParser = new SuggestionCommandParser<>(parseHelper);
|
||||
}
|
||||
|
||||
@SuppressWarnings("CodeBlock2Expr")
|
||||
public void invoke(RootLiteral<T> rootLiteral, T sender, String[] args) {
|
||||
invocationParser.invoke(rootLiteral, sender, args)
|
||||
invocationParser.parse(rootLiteral, sender, Arrays.stream(args).iterator())
|
||||
.ifSuccessOrElse(data -> {
|
||||
var ctx = new CommandContext<>(sender, data.getArguments());
|
||||
data.getExecutor().execute(ctx).whenComplete((result, ex) -> {
|
||||
|
|
@ -40,7 +43,8 @@ public class CommandHandler<T> {
|
|||
});
|
||||
}
|
||||
|
||||
public List<String> getSuggestions(RootLiteral<T> rootNode, T sender, String[] args) {
|
||||
return suggestionParser.getSuggestions(rootNode, sender, args);
|
||||
public List<String> getSuggestions(RootLiteral<T> rootNode, T sender, String[] args, boolean trailingSpace) {
|
||||
System.out.println("youre using the latest n greatest command parsing 3");
|
||||
return suggestionParser.suggest(rootNode, sender, Arrays.stream(args).iterator(), trailingSpace);
|
||||
}
|
||||
}
|
||||
|
|
@ -33,7 +33,6 @@ public interface Literal<T> {
|
|||
/**
|
||||
* @throws IllegalArgumentException if there is already an argument with the same id
|
||||
* @throws IllegalStateException if a greedy argument was added to the literal previously
|
||||
* @throws IllegalStateException if the literal already has a child literal assigned to it
|
||||
*/
|
||||
<V> void addArgument(CommandArgument<T, V> argument);
|
||||
|
||||
|
|
@ -50,7 +49,6 @@ public interface Literal<T> {
|
|||
/**
|
||||
* @throws IllegalArgumentException if there is already a literal with the same name
|
||||
* @throws IllegalStateException if a greedy argument was added to the literal previously
|
||||
* @throws IllegalStateException if the literal already has an argument assigned to it
|
||||
*/
|
||||
void addLiteral(@NotNull Literal<T> literal);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package de.kentoj.kencommandapi.api.parser;
|
||||
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class CommandParseHelper<T> {
|
||||
private final HasPermissionMethod<T> hasPermission;
|
||||
|
||||
public boolean hasPermission(T sender, Literal<T> literal) {
|
||||
if (literal.getPermission() == null) return true;
|
||||
return hasPermission.test(sender, literal.getPermission());
|
||||
}
|
||||
|
||||
public String parseInput(Iterator<String> tokenIter, boolean isGreedy) {
|
||||
if (!isGreedy)
|
||||
return tokenIter.next();
|
||||
var builder = new StringBuilder();
|
||||
tokenIter.forEachRemaining(tok -> builder.append(" ").append(tok));
|
||||
builder.deleteCharAt(0);
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package de.kentoj.kencommandapi.api.parser;
|
||||
|
||||
import com.leakyabstractions.result.api.Result;
|
||||
import com.leakyabstractions.result.core.Results;
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
||||
import de.kentoj.kencommandapi.api.invocation.ParsedArgument;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||
import de.kentoj.kencommandapi.internal.ParsedArgumentImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class InvocationCommandParser<T> {
|
||||
private final CommandParseHelper<T> helper;
|
||||
|
||||
public Result<ExecutionData, String> parse(
|
||||
RootLiteral<T> rootLiteral,
|
||||
T sender,
|
||||
Iterator<String> tokenIter
|
||||
) {
|
||||
Literal<T> currentLiteral = rootLiteral;
|
||||
Map<String, ParsedArgument<T, ?>> parsedArguments = new HashMap<>();
|
||||
|
||||
while (true) {
|
||||
{
|
||||
var result = processArguments(currentLiteral, sender, tokenIter)
|
||||
.ifSuccess(parsedArguments::putAll);
|
||||
if (result.hasFailure())
|
||||
return result.mapSuccess(__ -> null);
|
||||
}
|
||||
|
||||
if (!tokenIter.hasNext()) {
|
||||
if (currentLiteral.getExecutor() == null)
|
||||
return Results.failure("Literal expected");
|
||||
break;
|
||||
}
|
||||
|
||||
var literalName = tokenIter.next();
|
||||
var nextLiteral = currentLiteral.getLiteral(literalName);
|
||||
var isIncompleteOrUnknown = nextLiteral == null || !helper.hasPermission(sender, nextLiteral);
|
||||
if (isIncompleteOrUnknown)
|
||||
return Results.failure("Unknown literal: " + literalName);
|
||||
currentLiteral = nextLiteral;
|
||||
}
|
||||
|
||||
return Results.success(new ExecutionData(currentLiteral.getExecutor(), parsedArguments));
|
||||
}
|
||||
|
||||
private Result<Map<String, ParsedArgument<T, ?>>, String> processArguments(
|
||||
Literal<T> literal,
|
||||
T sender,
|
||||
Iterator<String> tokenIter
|
||||
) {
|
||||
Map<String, ParsedArgument<T, ?>> parsedArguments = new HashMap<>();
|
||||
|
||||
for (var _argument : literal.getArguments()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
var argument = ((CommandArgument<T, Object>) _argument);
|
||||
|
||||
Object value;
|
||||
if (!tokenIter.hasNext()) {
|
||||
if (argument.getDefaultValueProvider() == null)
|
||||
return Results.failure("Argument expected: " + argument.getId());
|
||||
value = argument.getDefaultValueProvider().apply(sender);
|
||||
} else {
|
||||
var input = helper.parseInput(tokenIter, argument.getType().isGreedy());
|
||||
try {
|
||||
value = argument.getType().parseInput(input);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
return Results.failure("Illegal argument '" + input + "' for " + argument.getId() + ": " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
parsedArguments.put(argument.getId(), new ParsedArgumentImpl<>(value, argument));
|
||||
}
|
||||
|
||||
return Results.success(parsedArguments);
|
||||
}
|
||||
|
||||
@Value
|
||||
public class ExecutionData {
|
||||
CommandExecutor<T> executor;
|
||||
Map<String, ParsedArgument<T, ?>> arguments;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
package de.kentoj.kencommandapi.api.parser;
|
||||
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SuggestionCommandParser<T> {
|
||||
|
||||
private final CommandParseHelper<T> helper;
|
||||
|
||||
public List<String> suggest(
|
||||
RootLiteral<T> rootLiteral,
|
||||
T sender,
|
||||
Iterator<String> tokenIter,
|
||||
boolean suggestNext
|
||||
) {
|
||||
Literal<T> currentLiteral = rootLiteral;
|
||||
Literal<T> previousLiteral = null;
|
||||
|
||||
while (true) {
|
||||
var argumentSuggestions = processArguments(currentLiteral, tokenIter, sender, suggestNext);
|
||||
if (argumentSuggestions != null)
|
||||
return argumentSuggestions;
|
||||
|
||||
if (!tokenIter.hasNext()) {
|
||||
if (suggestNext || previousLiteral == null)
|
||||
return suggestions(currentLiteral, sender).toList();
|
||||
return suggestions(previousLiteral, sender).toList();
|
||||
}
|
||||
|
||||
var input = tokenIter.next();
|
||||
var nextLiteral = currentLiteral.getLiteral(input);
|
||||
var isIncompleteOrUnknown = nextLiteral == null || !helper.hasPermission(sender, nextLiteral);
|
||||
if (isIncompleteOrUnknown) {
|
||||
var finalInput = input.toLowerCase();
|
||||
return suggestions(currentLiteral, sender)
|
||||
.filter(name -> name.toLowerCase().startsWith(finalInput))
|
||||
.toList();
|
||||
}
|
||||
|
||||
previousLiteral = currentLiteral;
|
||||
currentLiteral = nextLiteral;
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable List<String> processArguments(
|
||||
Literal<T> literal,
|
||||
Iterator<String> tokenIter,
|
||||
T sender,
|
||||
boolean suggestNext
|
||||
) {
|
||||
var argsIter = literal.getArguments().iterator();
|
||||
|
||||
/*
|
||||
for each argument:
|
||||
if no next token: suggest current
|
||||
parse token
|
||||
if not last token: skip
|
||||
if nextToken:
|
||||
if has next argument: suggest next argument
|
||||
else: return null
|
||||
return current argument's suggestions filtered
|
||||
|
||||
*/
|
||||
|
||||
while (argsIter.hasNext()) {
|
||||
var argument = argsIter.next();
|
||||
if (!tokenIter.hasNext())
|
||||
return argument.getSuggestionProvider().suggest(sender);
|
||||
var input = helper.parseInput(tokenIter, argument.getType().isGreedy()).toLowerCase();
|
||||
if (tokenIter.hasNext())
|
||||
continue;
|
||||
if (suggestNext) {
|
||||
if (argsIter.hasNext())
|
||||
return argsIter.next().getSuggestionProvider().suggest(sender);
|
||||
return null;
|
||||
}
|
||||
return argument.getSuggestionProvider().suggest(sender).stream()
|
||||
.filter(suggestion -> suggestion.toLowerCase().startsWith(input))
|
||||
.toList();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Stream<String> suggestions(Literal<T> literal, T sender) {
|
||||
return literal.getLiterals().stream()
|
||||
.filter(lit -> helper.hasPermission(sender, lit))
|
||||
.map(Literal::getNames)
|
||||
.flatMap(Arrays::stream);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package de.kentoj.kencommandapi.api.parser2;
|
||||
|
||||
import com.leakyabstractions.result.api.Result;
|
||||
import com.leakyabstractions.result.core.Results;
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public abstract class AbstractCommandParser<T> {
|
||||
|
||||
private final HasPermissionMethod<T> hasPermission;
|
||||
|
||||
protected boolean hasPermission(T sender, Literal<T> literal) {
|
||||
if (literal.getPermission() == null) return true;
|
||||
return hasPermission.test(sender, literal.getPermission());
|
||||
}
|
||||
|
||||
protected String parseInput(String[] args, AtomicInteger index, boolean isGreedy) {
|
||||
if (!isGreedy)
|
||||
return args[index.getAndIncrement()];
|
||||
|
||||
var ret = String.join(" ", Arrays.copyOfRange(args, index.get(), args.length));
|
||||
index.set(args.length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected Result<Object, String> parseArgument(CommandArgument<T, Object> argument, String input) {
|
||||
try {
|
||||
return Results.success(argument.getType().parseInput(input));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
return Results.failure("Illegal argument '" + input + "' for " + argument.getId() + ": " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
package de.kentoj.kencommandapi.api.parser2;
|
||||
|
||||
import com.leakyabstractions.result.api.Result;
|
||||
import com.leakyabstractions.result.core.Results;
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
||||
import de.kentoj.kencommandapi.api.invocation.ParsedArgument;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
||||
import de.kentoj.kencommandapi.internal.ParsedArgumentImpl;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class InvocationCommandParser<T> extends AbstractCommandParser<T> {
|
||||
|
||||
public InvocationCommandParser(HasPermissionMethod<T> hasPermission) {
|
||||
super(hasPermission);
|
||||
}
|
||||
|
||||
public Result<ExecutionData, String> invoke(
|
||||
RootLiteral<T> rootLiteral,
|
||||
T sender,
|
||||
String[] args
|
||||
) {
|
||||
Map<String, ParsedArgument<T, ?>> parsedArguments = new HashMap<>();
|
||||
Literal<T> currentLiteral = rootLiteral;
|
||||
AtomicInteger index = new AtomicInteger(0);
|
||||
|
||||
while (true) {
|
||||
for (var _argument : currentLiteral.getArguments()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
var argument = ((CommandArgument<T, Object>) _argument);
|
||||
|
||||
Object value;
|
||||
if (index.get() >= args.length) {
|
||||
if (argument.getDefaultValueProvider() == null)
|
||||
return Results.failure("Argument expected: " + argument.getId());
|
||||
value = argument.getDefaultValueProvider().apply(sender);
|
||||
} else {
|
||||
var input = parseInput(args, index, argument.getType().isGreedy());
|
||||
var parseResult = parseArgument(argument, input);
|
||||
if (parseResult.hasFailure()) return parseResult.mapSuccess(__ -> null);
|
||||
value = parseResult.getSuccess().orElseThrow();
|
||||
}
|
||||
|
||||
parsedArguments.put(argument.getId(), new ParsedArgumentImpl<>(value, argument));
|
||||
}
|
||||
|
||||
if (index.get() >= args.length) {
|
||||
if (currentLiteral.getExecutor() == null)
|
||||
return Results.failure("Literal expected");
|
||||
break;
|
||||
}
|
||||
|
||||
var literalName = args[index.getAndIncrement()];
|
||||
var nextLiteral = currentLiteral.getLiteral(literalName);
|
||||
if (nextLiteral == null || !hasPermission(sender, nextLiteral))
|
||||
return Results.failure("Unknown literal: " + literalName);
|
||||
currentLiteral = nextLiteral;
|
||||
}
|
||||
|
||||
return Results.success(new ExecutionData(currentLiteral.getExecutor(), parsedArguments));
|
||||
}
|
||||
|
||||
@Value
|
||||
public class ExecutionData {
|
||||
CommandExecutor<T> executor;
|
||||
Map<String, ParsedArgument<T, ?>> arguments;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
package de.kentoj.kencommandapi.api.parser2;
|
||||
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SuggestionCommandParser<T> extends AbstractCommandParser<T> {
|
||||
|
||||
public SuggestionCommandParser(HasPermissionMethod<T> hasPermission) {
|
||||
super(hasPermission);
|
||||
}
|
||||
|
||||
public List<String> getSuggestions(
|
||||
RootLiteral<T> rootNode,
|
||||
T sender,
|
||||
String[] args
|
||||
) {
|
||||
Literal<T> currentLiteral = rootNode;
|
||||
AtomicInteger index = new AtomicInteger(0);
|
||||
|
||||
while (true) {
|
||||
for (var argument : currentLiteral.getArguments()) {
|
||||
// TODO somewhere suggest next argument at trailing space
|
||||
if (index.getAndIncrement() >= args.length)
|
||||
return argument.getSuggestionProvider().suggest(sender);
|
||||
if (argument.getType().isGreedy())
|
||||
index.set(args.length);
|
||||
}
|
||||
|
||||
if (index.get() >= args.length) {
|
||||
// TODO suggest next argument at trailing space
|
||||
if (currentLiteral.getExecutor() == null)
|
||||
return suggestions(currentLiteral, sender).toList();
|
||||
}
|
||||
|
||||
var input = args[index.getAndIncrement()];
|
||||
var nextLiteral = currentLiteral.getLiteral(input);
|
||||
if (nextLiteral == null || !hasPermission(sender, nextLiteral)) {
|
||||
var finalInput = input.toLowerCase();
|
||||
return suggestions(currentLiteral, sender)
|
||||
.filter(name -> name.toLowerCase().startsWith(finalInput))
|
||||
.toList();
|
||||
}
|
||||
|
||||
currentLiteral = nextLiteral;
|
||||
}
|
||||
}
|
||||
|
||||
private Stream<String> suggestions(Literal<T> literal, T sender) {
|
||||
return literal.getLiterals().stream()
|
||||
.filter(lit -> hasPermission(sender, lit))
|
||||
.map(Literal::getNames)
|
||||
.flatMap(Arrays::stream);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
package de.kentoj.kencommandapi.api.parser;
|
||||
|
||||
import de.kentoj.kencommandapi.api.CommandHandler;
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||
import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class CommandHandlerTest {
|
||||
|
||||
@Test
|
||||
void suggestArgument() {
|
||||
var rootNode = Literal.rootLiteral(MessageStyle.PLAIN, "someRootNode");
|
||||
var arg = CommandArgument.arg("someArg", new StringArgumentType<>());
|
||||
arg.setSuggestionProvider(__ -> List.of("a", "b", "c"));
|
||||
rootNode.addArgument(arg);
|
||||
rootNode.setExecutor(ENV.EMPTY_EXECUTOR);
|
||||
|
||||
var handler = new CommandHandler<>((__, ___) -> {}, (__, ___) -> true);
|
||||
var suggestions = handler.getSuggestions(rootNode, ENV.SENDER, new String[0]);
|
||||
assertEquals(List.of("a", "b", "c"), suggestions);
|
||||
}
|
||||
|
||||
@Test
|
||||
void suggestLiterals() {
|
||||
var rootNode = Literal.rootLiteral(MessageStyle.PLAIN, "someRootNode");
|
||||
var literal1 = Literal.literal("lit1");
|
||||
var literal2 = Literal.literal("lit2");
|
||||
rootNode.addLiteral(literal1);
|
||||
rootNode.addLiteral(literal2);
|
||||
|
||||
var handler = new CommandHandler<>((__, ___) -> {}, (__, ___) -> true);
|
||||
var suggestions = handler.getSuggestions(rootNode, ENV.SENDER, new String[0]);
|
||||
assertEquals(List.of("lit1", "lit2"), suggestions.stream().sorted().toList());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package de.kentoj.kencommandapi.api.parser;
|
||||
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||
import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
|
||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class SuggestionCommandParserTest {
|
||||
|
||||
private final SuggestionCommandParser<Object> suggestionParser;
|
||||
private final RootLiteral<Object> rootLiteral;
|
||||
|
||||
public SuggestionCommandParserTest() {
|
||||
rootLiteral = Literal.rootLiteral(MessageStyle.PLAIN, "someRootNode");
|
||||
suggestionParser = new SuggestionCommandParser<>((__, ___) -> true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void suggestNextArgument() {
|
||||
var arg = CommandArgument.arg("someArg", new StringArgumentType<>());
|
||||
arg.setSuggestionProvider(__ -> List.of("foo", "bar"));
|
||||
rootLiteral.addArgument(arg);
|
||||
|
||||
var suggestions = suggestionParser.getSuggestions(rootLiteral, ENV.SENDER, args(""));
|
||||
assertEquals(Stream.of("foo", "bar").sorted().toList(), suggestions.stream().sorted().toList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void suggestNextArgumentAtSpace() {
|
||||
var uselessArg = CommandArgument.arg("someUselessArg", new StringArgumentType<>());
|
||||
var arg = CommandArgument.arg("someArg", new StringArgumentType<>());
|
||||
arg.setSuggestionProvider(__ -> List.of("foo", "bar"));
|
||||
rootLiteral.addArgument(uselessArg);
|
||||
rootLiteral.addArgument(arg);
|
||||
|
||||
var suggestions = suggestionParser.getSuggestions(rootLiteral, ENV.SENDER, args("hi "));
|
||||
assertEquals(Stream.of("foo", "bar").sorted().toList(), suggestions.stream().sorted().toList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void suggestCurrentArgument() {
|
||||
var arg = CommandArgument.arg("someArg", new StringArgumentType<>());
|
||||
arg.setSuggestionProvider(__ -> List.of("foo", "bar"));
|
||||
rootLiteral.addArgument(arg);
|
||||
|
||||
var suggestions = suggestionParser.getSuggestions(rootLiteral, ENV.SENDER, args("f"));
|
||||
assertEquals(List.of("foo"), suggestions);
|
||||
}
|
||||
|
||||
@Test
|
||||
void suggestNextLiteral() {
|
||||
var literalFoo = Literal.literal("foo");
|
||||
var literalBar = Literal.literal("bar");
|
||||
rootLiteral.addLiteral(literalFoo);
|
||||
rootLiteral.addLiteral(literalBar);
|
||||
|
||||
var suggestions = suggestionParser.getSuggestions(rootLiteral, ENV.SENDER, args(""));
|
||||
assertEquals(Stream.of("foo", "bar").sorted().toList(), suggestions.stream().sorted().toList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void suggestCurrentLiteral() {
|
||||
var literalFoo = Literal.literal("foo");
|
||||
var literalBar = Literal.literal("bar");
|
||||
rootLiteral.addLiteral(literalFoo);
|
||||
rootLiteral.addLiteral(literalBar);
|
||||
|
||||
var suggestions = suggestionParser.getSuggestions(rootLiteral, ENV.SENDER, args("f"));
|
||||
assertEquals(List.of("foo"), suggestions);
|
||||
}
|
||||
|
||||
private String[] args(String input) {
|
||||
List<String> args = new ArrayList<>(Arrays.asList(input.split(" ")));
|
||||
if (input.endsWith(" "))
|
||||
args.add("");
|
||||
return args.toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue