Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 48 additions & 7 deletions src/main/java/dev/coly/jdat/JDATesting.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package dev.coly.jdat;

import dev.coly.util.Annotations;
import dev.coly.util.Callback;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.EventListener;
import net.dv8tion.jda.api.hooks.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Assertions;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;

/**
* This class should be used in testing. It creates fake {@link net.dv8tion.jda.api.events.Event}s and other JDA objects
Expand All @@ -22,25 +27,61 @@
public class JDATesting {

/**
* Test a {@link EventListener} with a {@link MessageReceivedEvent}. You can test the return to see if your
* code returns the correct {@link Message} output for a given input.
* Test a {@link EventListener} with a {@link MessageReceivedEvent}.
* One can test the return to see if one's code returns the correct {@link Message} output for a given input.
*
* @param listener The {@link EventListener} that will be tested.
* @param input The input you want to test.
* @return The {@link Message} your {@link EventListener} would return given the input. Test
* this if it is correct.
* @param input The input that will be used as the message.
* @return The {@link Message} the {@link EventListener} would return given the input.
* Test this if it is correct.
* @throws InterruptedException This code uses a {@link CountDownLatch} that can the
* interrupted if the thread is interrupted.
*/
public static Message testMessageReceivedEvent(EventListener listener, String input) throws InterruptedException {
public static Message testMessageReceivedEvent(@NotNull EventListener listener, String input) throws InterruptedException {
return testMessageReceivedEvent(input, listener::onEvent);
}

/**
* Test a {@link Class} with methods annotated with {@link SubscribeEvent} using a {@link MessageReceivedEvent}.
* One can test the return to see if one's code returns the correct {@link Message} outputs for a given input.
* This method will test all methods annotated with {@link SubscribeEvent} in the provided {@link Class} and will
* return only when all methods have been tested.
* The order of the {@link Message} objects in the returned is the same order as the methods in the {@link Class}.
*
* @param clazz The {@link Class} that contains methods annotated with {@link SubscribeEvent} and
* will be tested.
* @param input The input that will be used as the message.
* @return List of {@link Message}s the methods would return given the input.
* Test if the messages are correct.
* @throws InterruptedException This code uses a {@link CountDownLatch} that can be
* interrupted if the thread is interrupted.
*/
@NotNull
public static List<Message> testMessageReceivedEvent(Class<?> clazz, String input) throws InterruptedException {
List<Method> methods = Annotations.getMethodsAnnotatedWith(clazz, SubscribeEvent.class);
List <Message> messages = new ArrayList<>();
for (Method method : methods) {
messages.add(testMessageReceivedEvent(input, (event) -> {
try {
method.invoke(clazz.getDeclaredConstructor().newInstance(), event);
} catch (Exception e) {
Assertions.fail("Could not invoke method with @SubscribeEvent annotation", e);
}
}));
}
return messages;
}

private static Message testMessageReceivedEvent(String input, @NotNull Consumer<MessageReceivedEvent> onEvent)
throws InterruptedException {
Callback<Message> messageCallback = Callback.single();

MessageChannel channel = JDAObjects.getMessageChannel("test-chanel", 0L, messageCallback);
Message message = JDAObjects.getMessage(input, new ArrayList<>(), channel);
MessageReceivedEvent event = JDAObjects.getMessageReceivedEvent(channel, message,
JDAObjects.getMember("Test User", "0000"));

listener.onEvent(event);
onEvent.accept(event);
return messageCallback.await();
}

Expand Down
26 changes: 26 additions & 0 deletions src/main/java/dev/coly/util/Annotations.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package dev.coly.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class Annotations {

private Annotations() {}

public static List<Method> getMethodsAnnotatedWith(final Class<?> type, final Class<? extends Annotation> annotation) {
final List<Method> methods = new ArrayList<>();
Class<?> klass = type;
while (klass != Object.class) {
for (final Method method : klass.getDeclaredMethods()) {
if (method.isAnnotationPresent(annotation)) {
methods.add(method);
}
}
klass = klass.getSuperclass();
}
return methods;
}

}
14 changes: 9 additions & 5 deletions src/test/java/dev/coly/jdat/TestEventListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ public class TestEventListener extends ListenerAdapter {

@Override
public void onMessageReceived(@NotNull MessageReceivedEvent e) {
if (e.getMessage().getContentDisplay().equals(".ping")) {
e.getChannel().sendMessage("Pong!").queue();
} else if (e.getMessage().getContentDisplay().equals(".embed")) {
e.getChannel().sendMessageEmbeds(getTestEmbed()).queue();
}
handleMessageReceived(e);
}

@Override
Expand All @@ -42,4 +38,12 @@ public static MessageEmbed getTestEmbed() {
return embedBuilder.build();
}

public static void handleMessageReceived(MessageReceivedEvent e) {
if (e.getMessage().getContentDisplay().equals(".ping")) {
e.getChannel().sendMessage("Pong!").queue();
} else if (e.getMessage().getContentDisplay().equals(".embed")) {
e.getChannel().sendMessageEmbeds(getTestEmbed()).queue();
}
}

}
39 changes: 32 additions & 7 deletions src/test/java/dev/coly/jdat/TestMessageReceivedEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ public void testTestMessageReceivedEvent() {
}
}

@Test
public void testTestMessageReceivedEventUsingSubscribeEvent() {
try {
List<Message> messages = JDATesting.testMessageReceivedEvent(TestSubscribeEvent.class, ".ping");
Assertions.assertEquals(1, messages.size());
Assertions.assertEquals("Pong!", messages.get(0).getContentRaw());
} catch (InterruptedException e) {
Assertions.fail(e);
}
}

@Test
public void testAssertMessageReceivedEvent() {
JDATesting.assertGuildMessageReceivedEvent(new TestEventListener(), ".ping", "Pong!");
Expand All @@ -27,18 +38,32 @@ public void testAssertMessageReceivedEvent() {
@Test
public void testTestMessageReceivedEventWithEmbeds() {
try {
Message message = JDATesting.testMessageReceivedEvent(new TestEventListener(), ".embed");
MessageEmbed embed = message.getEmbeds().get(0);
Assertions.assertEquals("Test Embed", embed.getTitle());
Assertions.assertEquals("Coly Team", Objects.requireNonNull(embed.getAuthor()).getName());
Assertions.assertEquals("Test Name", embed.getFields().get(0).getName());
Assertions.assertEquals("Test Value", embed.getFields().get(0).getValue());
Assertions.assertTrue(embed.getFields().get(0).isInline());
assertEmbedMessage(JDATesting.testMessageReceivedEvent(new TestEventListener(), ".embed"));
} catch (InterruptedException e) {
Assertions.fail(e);
}
}

@Test
public void testTestMessageReceivedUsingSubscribeEventEventWithEmbeds() {
try {
List<Message> messages = JDATesting.testMessageReceivedEvent(TestSubscribeEvent.class, ".embed");
Assertions.assertEquals(1, messages.size());
assertEmbedMessage(messages.get(0));
} catch (InterruptedException e) {
Assertions.fail(e);
}
}

private void assertEmbedMessage(Message message) {
MessageEmbed embed = message.getEmbeds().get(0);
Assertions.assertEquals("Test Embed", embed.getTitle());
Assertions.assertEquals("Coly Team", Objects.requireNonNull(embed.getAuthor()).getName());
Assertions.assertEquals("Test Name", embed.getFields().get(0).getName());
Assertions.assertEquals("Test Value", embed.getFields().get(0).getValue());
Assertions.assertTrue(embed.getFields().get(0).isInline());
}

@Test
public void testAssertMessageReceivedEventWithEmbeds() {
JDATesting.assertGuildMessageReceivedEvent(new TestEventListener(), ".embed",
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/dev/coly/jdat/TestSubscribeEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package dev.coly.jdat;

import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.SubscribeEvent;

public class TestSubscribeEvent {

@SubscribeEvent
public void subscribeMessage(MessageReceivedEvent e) {
TestEventListener.handleMessageReceived(e);
}

}