Skip to content

Commit

Permalink
✅ Add unit tests for EventType and EventManager
Browse files Browse the repository at this point in the history
The @contract of the EventManager interface have also been revised.
  • Loading branch information
YvanMazy committed Mar 23, 2024
1 parent 958a2a9 commit dc3e7f7
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 10 deletions.
15 changes: 15 additions & 0 deletions api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,19 @@ dependencies {
api 'net.kyori:adventure-text-minimessage:4.16.0'

api 'com.google.code.gson:gson:2.10.1'
}

configurations {
testClasses {
extendsFrom(testImplementation)
}
}

tasks.register('testJar', Jar) {
archiveClassifier.set('test')
from sourceSets.test.output
}

artifacts {
testClasses testJar
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
package be.darkkraft.transferproxy.api.event;

import be.darkkraft.transferproxy.api.event.listener.EventListener;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

public interface EventManager {
Expand All @@ -33,8 +34,10 @@ public interface EventManager {

<T extends EventListener<?>> void addListener(final @NotNull EventType eventType, final @NotNull T eventListener);

<T extends EventListener<?>> boolean removeListener(final @NotNull EventType eventType, final @NotNull T eventListener);
@Contract("null, _ -> false; _, null -> false; _, _ -> _")
<T extends EventListener<?>> boolean removeListener(final EventType eventType, final T eventListener);

@NotNull <T extends EventListener<?>> T[] getListeners(final @NotNull EventType eventType);
@Contract("null -> null; !null -> _")
<T extends EventListener<?>> T[] getListeners(final EventType eventType);

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import be.darkkraft.transferproxy.api.status.listener.DefaultStatusListener;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;
import java.util.function.Supplier;

public enum EventType {
Expand All @@ -45,11 +46,11 @@ public enum EventType {
private final Supplier<@NotNull EventListener<?>> defaultListener;

EventType(final @NotNull Class<?> eventClass, final @NotNull Supplier<@NotNull EventListener<?>> defaultListener) {
this.eventClass = eventClass;
this.defaultListener = defaultListener;
this.eventClass = Objects.requireNonNull(eventClass, "eventClass must not be null");
this.defaultListener = Objects.requireNonNull(defaultListener, "defaultListener must not be null");
}

public Class<?> getEventClass() {
public @NotNull Class<?> getEventClass() {
return this.eventClass;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* MIT License
*
* Copyright (c) 2024 Darkkraft
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package be.darkkraft.transferproxy.api.event;

import be.darkkraft.transferproxy.api.util.test.MockedTransferProxy;
import be.darkkraft.transferproxy.api.util.test.TestUtil;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;

import static org.junit.jupiter.api.Assertions.assertTrue;

class EventTypeTest {

@BeforeAll
static void setUp() {
MockedTransferProxy.mock();
}

@ParameterizedTest
@EnumSource(EventType.class)
void testClassOfDefaultListener(final EventType type) throws ClassNotFoundException {
assertTrue(TestUtil.getGenericType(type.buildDefaultListener().getClass()).isAssignableFrom(type.getEventClass()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* MIT License
*
* Copyright (c) 2024 Darkkraft
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package be.darkkraft.transferproxy.api.util.test;

import be.darkkraft.transferproxy.api.TransferProxy;
import be.darkkraft.transferproxy.api.configuration.ProxyConfiguration;
import be.darkkraft.transferproxy.api.configuration.yaml.YamlProxyConfiguration;
import be.darkkraft.transferproxy.api.module.ModuleManager;
import be.darkkraft.transferproxy.api.network.NetworkServer;
import org.jetbrains.annotations.NotNull;
import org.mockito.Mockito;

public class MockedTransferProxy extends TransferProxy {

public static void mock() {
new MockedTransferProxy().start();
}

// I use the yaml configuration because it has the default values
private final ProxyConfiguration configuration = new YamlProxyConfiguration();
private final ModuleManager moduleManager = Mockito.mock(ModuleManager.class);
private final NetworkServer networkServer = Mockito.mock(NetworkServer.class);
private final long startedTime = System.currentTimeMillis();

@Override
public void start() {
this.setInstance(this);
}

@Override
public void stop() {

}

@Override
public @NotNull ProxyConfiguration getConfiguration() {
return this.configuration;
}

@Override
public @NotNull ModuleManager getModuleManager() {
return this.moduleManager;
}

@Override
public NetworkServer getNetworkServer() {
return this.networkServer;
}

@Override
public long getStartedTime() {
return this.startedTime;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* MIT License
*
* Copyright (c) 2024 Darkkraft
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package be.darkkraft.transferproxy.api.util.test;

import org.jetbrains.annotations.NotNull;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class TestUtil {

private TestUtil() throws IllegalAccessException {
throw new IllegalAccessException("You cannot instantiate a utility class");
}

public static @NotNull Class<?> getGenericType(final Class<?> clazz) throws ClassNotFoundException {
for (final Type type : clazz.getGenericInterfaces()) {
if (type instanceof final ParameterizedType paramType) {
final Type[] arguments = paramType.getActualTypeArguments();
if (arguments.length >= 1) {
return Class.forName(arguments[0].getTypeName());
}
} else {
return getGenericType(Class.forName(type.getTypeName()));
}
}
throw new IllegalArgumentException("No generic type found");
}

}
1 change: 1 addition & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {
dependencies {
// Project API
api project(":api")
testImplementation project(path: ':api', configuration: 'testClasses')

// Logging
api 'org.fusesource.jansi:jansi:2.4.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ public synchronized <T extends EventListener<?>> void addListener(final @NotNull
}

@Override
public synchronized <T extends EventListener<?>> boolean removeListener(final @NotNull EventType eventType, @NotNull final T eventListener) {
Objects.requireNonNull(eventType, "eventType cannot be null");
Objects.requireNonNull(eventListener, "eventListener cannot be null");
public synchronized <T extends EventListener<?>> boolean removeListener(final EventType eventType, final T eventListener) {
if (eventType == null || eventListener == null) {
return false;
}
final EventListener<?>[] listeners = this.listenerMap.get(eventType);
if (listeners == null) {
return false;
Expand Down Expand Up @@ -112,8 +113,8 @@ public synchronized <T extends EventListener<?>> boolean removeListener(final @N

@SuppressWarnings("unchecked")
@Override
public @NotNull <T extends EventListener<?>> T[] getListeners(final @NotNull EventType eventType) {
return (T[]) this.listenerMap.get(eventType);
public <T extends EventListener<?>> T[] getListeners(final EventType eventType) {
return eventType != null ? (T[]) this.listenerMap.get(eventType) : null;
}

}
Loading

0 comments on commit dc3e7f7

Please sign in to comment.