Command processor testing
This commit is contained in:
1 parent
c19287d580
commit
6fc3dc9577
6 files changed
+1142
-27
No files matched your search
@@ -70,8 +70,8 @@ public class NetNeutrality {
|
||||
throw new RuntimeException("No bot token provided, exiting.");
|
||||
}
|
||||
|
||||
DatabaseMigration.migrate();
|
||||
SessionManager.getSessionFactory();
|
||||
DatabaseMigration.migrate();
|
||||
CommandManager.init();
|
||||
MusicManager.initPlayerManager();
|
||||
TaskManager.getInstance().init();
|
||||
|
||||
@@ -58,6 +58,7 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
||||
@Override
|
||||
public List<CommandOption> parseOptions(String[] args, List<OptionData> commandOptions) {
|
||||
List<CommandOption> options = new ArrayList<>();
|
||||
int required = commandOptions.stream().filter(OptionData::isRequired).toList().size();
|
||||
Mentions mentions = message.getMentions();
|
||||
int roleMentionIndex = 0;
|
||||
int userMentionIndex = 0;
|
||||
@@ -74,13 +75,59 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
||||
try {
|
||||
switch (type) {
|
||||
case STRING -> {
|
||||
String str = args[index];
|
||||
int currentOptionIndex = commandOptions.indexOf(data);
|
||||
boolean nextOptionIsString = false;
|
||||
if (currentOptionIndex + 1 < commandOptions.size()) {
|
||||
OptionData nextOption = commandOptions.get(currentOptionIndex + 1);
|
||||
nextOptionIsString = nextOption.getType() == OptionType.STRING;
|
||||
}
|
||||
|
||||
if ((str.contains("<@") || str.contains("<#")) && str.contains(">")) {
|
||||
invalidateContext(data, "expected a string at position " + (index + 1) + " but a role/user/channel was provided");
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
if (!nextOptionIsString) {
|
||||
while (index < args.length) {
|
||||
String nextArg = args[index];
|
||||
|
||||
if ((nextArg.contains("<@") || nextArg.contains("<#") || nextArg.contains("<@&")) && nextArg.contains(">")) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (nextArg.equalsIgnoreCase("true") || nextArg.equalsIgnoreCase("false")) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
Long.parseLong(nextArg);
|
||||
break;
|
||||
} catch (NumberFormatException ignored) {}
|
||||
|
||||
try {
|
||||
Double.parseDouble(nextArg);
|
||||
break;
|
||||
} catch (NumberFormatException ignored) {}
|
||||
|
||||
if (!strBuilder.isEmpty()) {
|
||||
strBuilder.append(" ");
|
||||
}
|
||||
|
||||
strBuilder.append(nextArg);
|
||||
index++;
|
||||
}
|
||||
|
||||
// Update index to skip the concatenated strings
|
||||
index = index - 1;
|
||||
} else {
|
||||
// Next option is also a string, so just take the current argument
|
||||
if (index < args.length) {
|
||||
strBuilder.append(args[index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (strBuilder.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
String str = strBuilder.toString();
|
||||
|
||||
if (!choices.isEmpty()) {
|
||||
List<Command.Choice> matched = choices.stream().filter(choice -> choice.getAsString().equalsIgnoreCase(str)).toList();
|
||||
if (matched.isEmpty()) {
|
||||
@@ -119,8 +166,6 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
||||
} else if (max != null && num > max.longValue()) {
|
||||
value = max.longValue();
|
||||
}
|
||||
|
||||
value = num;
|
||||
}
|
||||
case BOOLEAN -> {
|
||||
String str = args[index];
|
||||
@@ -132,7 +177,7 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
||||
invalidateContext(data, "expected true or false");
|
||||
}
|
||||
case NUMBER -> {
|
||||
double num = Long.parseLong(args[index]);
|
||||
double num = Double.parseDouble(args[index]);
|
||||
if (!choices.isEmpty()) {
|
||||
List<Command.Choice> matched = choices.stream().filter(choice -> choice.getAsDouble() == num).toList();
|
||||
if (matched.isEmpty()) {
|
||||
@@ -209,7 +254,7 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
||||
if (mentions.getChannels().size() > channelMentionIndex) {
|
||||
GuildChannel channel = mentions.getChannels().get(channelMentionIndex++);
|
||||
|
||||
if (!requiredChannelTypes.contains(channel.getType())) {
|
||||
if (!requiredChannelTypes.isEmpty() && !requiredChannelTypes.contains(channel.getType())) {
|
||||
invalidateContext(data, "not a valid channel type at index " + (index + 1) +
|
||||
" , valid types are: " + validTypes(requiredChannelTypes));
|
||||
break;
|
||||
@@ -225,7 +270,11 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
||||
}
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
if (data.isRequired()) {
|
||||
if (options.size() < required) {
|
||||
invalidateContext(data, "missing required argument at index " + (index + 1));
|
||||
}
|
||||
|
||||
if (data.isRequired() && index < required) {
|
||||
// This should never happen because required options are validated before calling parseOptions()
|
||||
throw new IllegalArgumentException("Required option " + data.getName() + " was not found at index " + index);
|
||||
}
|
||||
@@ -240,6 +289,13 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
||||
index++;
|
||||
}
|
||||
|
||||
// Check if there are leftover arguments that weren't consumed
|
||||
if (index < args.length) {
|
||||
if (options.size() >= required) {
|
||||
invalidateContext(commandOptions.getLast(), "too many arguments");
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import me.bobert.netneutrality.core.tasks.TaskManager;
|
||||
import me.bobert.netneutrality.exceptions.CommandExecutionException;
|
||||
import me.bobert.netneutrality.exceptions.GracefulContextError;
|
||||
import me.bobert.netneutrality.utils.UserFunction;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
|
||||
@@ -204,22 +203,6 @@ public class CommandProcessor {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if last option is a string, if it is then combine all remaining strings into one
|
||||
// ["@user", "you", "are", "banned"] becomes ["@user", "you are banned"]
|
||||
if (!options.isEmpty() && arguments.size() > 1) {
|
||||
OptionData last = options.get(options.size() - 1);
|
||||
if (last.getType() == OptionType.STRING) {
|
||||
List<String> lastArgs = arguments.stream().skip(options.size() - 1).toList();
|
||||
arguments.removeAll(lastArgs);
|
||||
arguments.add(String.join(" ", lastArgs));
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.size() > required + optional) {
|
||||
context.reply(invalidUsage("too many arguments"));
|
||||
return false;
|
||||
}
|
||||
|
||||
context.setCurrentCommandOptions(arguments.toArray(String[]::new), options);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -120,6 +120,10 @@ public class MessageCommandOption implements CommandOption {
|
||||
|
||||
@Override
|
||||
public User getAsUser() {
|
||||
if (value instanceof Member) {
|
||||
return ((Member) value).getUser();
|
||||
}
|
||||
|
||||
if (value instanceof User) {
|
||||
return (User) value;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user