Command processor testing
This commit is contained in:
1 parent
c19287d580
commit
6fc3dc9577
6 files changed
+1142
-27
No files matched your search
@@ -277,7 +277,12 @@
|
|||||||
<version>${mockito.version}</version>
|
<version>${mockito.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-junit-jupiter</artifactId>
|
||||||
|
<version>${mockito.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -70,8 +70,8 @@ public class NetNeutrality {
|
|||||||
throw new RuntimeException("No bot token provided, exiting.");
|
throw new RuntimeException("No bot token provided, exiting.");
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseMigration.migrate();
|
|
||||||
SessionManager.getSessionFactory();
|
SessionManager.getSessionFactory();
|
||||||
|
DatabaseMigration.migrate();
|
||||||
CommandManager.init();
|
CommandManager.init();
|
||||||
MusicManager.initPlayerManager();
|
MusicManager.initPlayerManager();
|
||||||
TaskManager.getInstance().init();
|
TaskManager.getInstance().init();
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
|||||||
@Override
|
@Override
|
||||||
public List<CommandOption> parseOptions(String[] args, List<OptionData> commandOptions) {
|
public List<CommandOption> parseOptions(String[] args, List<OptionData> commandOptions) {
|
||||||
List<CommandOption> options = new ArrayList<>();
|
List<CommandOption> options = new ArrayList<>();
|
||||||
|
int required = commandOptions.stream().filter(OptionData::isRequired).toList().size();
|
||||||
Mentions mentions = message.getMentions();
|
Mentions mentions = message.getMentions();
|
||||||
int roleMentionIndex = 0;
|
int roleMentionIndex = 0;
|
||||||
int userMentionIndex = 0;
|
int userMentionIndex = 0;
|
||||||
@@ -74,13 +75,59 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
|||||||
try {
|
try {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case STRING -> {
|
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(">")) {
|
StringBuilder strBuilder = new StringBuilder();
|
||||||
invalidateContext(data, "expected a string at position " + (index + 1) + " but a role/user/channel was provided");
|
if (!nextOptionIsString) {
|
||||||
|
while (index < args.length) {
|
||||||
|
String nextArg = args[index];
|
||||||
|
|
||||||
|
if ((nextArg.contains("<@") || nextArg.contains("<#") || nextArg.contains("<@&")) && nextArg.contains(">")) {
|
||||||
break;
|
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()) {
|
if (!choices.isEmpty()) {
|
||||||
List<Command.Choice> matched = choices.stream().filter(choice -> choice.getAsString().equalsIgnoreCase(str)).toList();
|
List<Command.Choice> matched = choices.stream().filter(choice -> choice.getAsString().equalsIgnoreCase(str)).toList();
|
||||||
if (matched.isEmpty()) {
|
if (matched.isEmpty()) {
|
||||||
@@ -119,8 +166,6 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
|||||||
} else if (max != null && num > max.longValue()) {
|
} else if (max != null && num > max.longValue()) {
|
||||||
value = max.longValue();
|
value = max.longValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
value = num;
|
|
||||||
}
|
}
|
||||||
case BOOLEAN -> {
|
case BOOLEAN -> {
|
||||||
String str = args[index];
|
String str = args[index];
|
||||||
@@ -132,7 +177,7 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
|||||||
invalidateContext(data, "expected true or false");
|
invalidateContext(data, "expected true or false");
|
||||||
}
|
}
|
||||||
case NUMBER -> {
|
case NUMBER -> {
|
||||||
double num = Long.parseLong(args[index]);
|
double num = Double.parseDouble(args[index]);
|
||||||
if (!choices.isEmpty()) {
|
if (!choices.isEmpty()) {
|
||||||
List<Command.Choice> matched = choices.stream().filter(choice -> choice.getAsDouble() == num).toList();
|
List<Command.Choice> matched = choices.stream().filter(choice -> choice.getAsDouble() == num).toList();
|
||||||
if (matched.isEmpty()) {
|
if (matched.isEmpty()) {
|
||||||
@@ -209,7 +254,7 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
|||||||
if (mentions.getChannels().size() > channelMentionIndex) {
|
if (mentions.getChannels().size() > channelMentionIndex) {
|
||||||
GuildChannel channel = mentions.getChannels().get(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) +
|
invalidateContext(data, "not a valid channel type at index " + (index + 1) +
|
||||||
" , valid types are: " + validTypes(requiredChannelTypes));
|
" , valid types are: " + validTypes(requiredChannelTypes));
|
||||||
break;
|
break;
|
||||||
@@ -225,7 +270,11 @@ public class MessageCommandContext extends CommandContext implements MessageCont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IndexOutOfBoundsException e) {
|
} 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()
|
// 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);
|
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++;
|
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;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import me.bobert.netneutrality.core.tasks.TaskManager;
|
|||||||
import me.bobert.netneutrality.exceptions.CommandExecutionException;
|
import me.bobert.netneutrality.exceptions.CommandExecutionException;
|
||||||
import me.bobert.netneutrality.exceptions.GracefulContextError;
|
import me.bobert.netneutrality.exceptions.GracefulContextError;
|
||||||
import me.bobert.netneutrality.utils.UserFunction;
|
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.OptionData;
|
||||||
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
|
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
|
||||||
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
|
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
|
||||||
@@ -204,22 +203,6 @@ public class CommandProcessor {
|
|||||||
return false;
|
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);
|
context.setCurrentCommandOptions(arguments.toArray(String[]::new), options);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,10 @@ public class MessageCommandOption implements CommandOption {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User getAsUser() {
|
public User getAsUser() {
|
||||||
|
if (value instanceof Member) {
|
||||||
|
return ((Member) value).getUser();
|
||||||
|
}
|
||||||
|
|
||||||
if (value instanceof User) {
|
if (value instanceof User) {
|
||||||
return (User) value;
|
return (User) value;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user