Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cover more methods with tests and slightly improve other tests #34

Merged
merged 9 commits into from
Jul 19, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ public class DependencyInjectionException extends RuntimeException {
super(message);
}

DependencyInjectionException(Throwable cause) {
super(cause);
}

DependencyInjectionException(String message, Throwable cause) {
super(message, cause);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,8 @@ protected Bind<Annotation> fetchBind(@Nullable Annotation annotation, Property p
return handlers;
}

Bind<Annotation> getAutoConstructBind() {
return this.autoConstructBind;
}

}
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package org.panda_lang.utilities.inject;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.junit.jupiter.api.Test;
import org.panda_lang.utilities.inject.annotations.Inject;
import org.panda_lang.utilities.inject.annotations.Injectable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

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

final class DependencyInjectionFieldsTest {

@Injectable
@Retention(RetentionPolicy.RUNTIME)
@interface Custom { }
private @interface Custom {}

static class Service extends AbstractService {
private static class Service extends AbstractService {

public final boolean throughConstructor;
public final String customArgument;
Expand All @@ -41,7 +41,7 @@ public String serve() {

}

static abstract class AbstractService {
private static abstract class AbstractService {

@Inject
protected float abstractFieldOne;
Expand All @@ -68,7 +68,7 @@ void shouldInjectFields() {
resources.annotatedWithTested(Custom.class).assignHandler((property, custom, objects) -> objects[0].toString());
});

Service service = injector.newInstanceWithFields(Service.class,"custom argument");
Service service = injector.newInstanceWithFields(Service.class, "custom argument");
assertEquals("Hello Field 7", service.serve());
assertEquals("1.2 254623242914889729", service.serveAbstract());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,25 @@

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.ThreadLocalRandom;
import org.junit.jupiter.api.Test;
import org.panda_lang.utilities.inject.annotations.Inject;
import org.panda_lang.utilities.inject.annotations.Injectable;
import org.panda_lang.utilities.inject.annotations.PostConstruct;

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

public class DependencyInjectionHandlerTest {

@Injectable
@Retention(RetentionPolicy.RUNTIME)
@interface Custom { }
private @interface Custom {}

@Injectable
@Retention(RetentionPolicy.RUNTIME)
@interface TestAnnotation { }
private @interface TestAnnotation {}

public static class Service1 {
private static class Service1 {

@Inject
@Custom
Expand Down Expand Up @@ -61,7 +59,7 @@ void shouldCreateInstance() {
injector.newInstanceWithFields(Service1.class);
}

public static class Service2 {
private static class Service2 {

@Inject
public String fieldOne;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.panda_lang.utilities.inject;

import java.security.InvalidParameterException;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand Down Expand Up @@ -31,19 +32,36 @@ void shouldNotInjectInstances() {
});
});

assertThrows(InvalidParameterException.class, () -> injector.forConstructor(InvalidClass.class).newInstance(), "Class has to contain one and only constructor");
assertThrows(DependencyInjectionException.class, () -> injector.newInstance(Service.class));
}

public static class Bean { }
private static class Bean {}

public interface Custom { }
static class CustomImpl implements Custom { }
private interface Custom {}

private static class CustomImpl implements Custom {}

private static class Service {

static class Service {
public Service(Bean bean, Custom custom) {
assertNotNull(bean);
assertNotNull(custom);
}

}

private static class InvalidClass { // 2 constructors (only 1 is allowed)

public InvalidClass(Bean bean, Custom custom) {
assertNotNull(bean);
assertNotNull(custom);
}

public InvalidClass(Bean bean) {
assertNotNull(bean);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@

package org.panda_lang.utilities.inject;

import org.junit.jupiter.api.Test;
import org.panda_lang.utilities.inject.annotations.Injectable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.junit.jupiter.api.Test;
import org.panda_lang.utilities.inject.annotations.Injectable;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;

class DependencyInjectionUtilsTest {

Expand All @@ -36,18 +36,18 @@ void testAnnotation() {
assertDoesNotThrow(() -> DependencyInjectionUtils.testAnnotation(InjectableAnnotation.class));
}

static class NotAnAnnotation { }
private static class NotAnAnnotation {}

@interface DefaultAnnotation { }
private @interface DefaultAnnotation {}

@Retention(RetentionPolicy.CLASS)
@interface ClassAnnotation { }
private @interface ClassAnnotation {}

@Retention(RetentionPolicy.RUNTIME)
@interface RuntimeAnnotation { }
private @interface RuntimeAnnotation {}

@Injectable
@Retention(RetentionPolicy.RUNTIME)
@interface InjectableAnnotation { }
private @interface InjectableAnnotation {}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@

package org.panda_lang.utilities.inject;

import org.junit.jupiter.api.Test;
import org.panda_lang.utilities.inject.annotations.Inject;
import org.panda_lang.utilities.inject.annotations.Injectable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.panda_lang.utilities.inject.annotations.Inject;
import org.panda_lang.utilities.inject.annotations.Injectable;

final class DependencyInjectionWikiTest {

Expand Down Expand Up @@ -53,9 +52,10 @@ void testWikiExample() {

@Injectable // mark annotation as DI ready annotation
@Retention(RetentionPolicy.RUNTIME) // make sure that the annotation is visible at runtime
@interface AwesomeRandom { }
private @interface AwesomeRandom {}

private static final class Entity {

private final UUID id;

@Inject //it's not required, but it might be useful to disable "unused method" warnings/scanning for annotations
Expand All @@ -66,6 +66,7 @@ private Entity(@AwesomeRandom UUID random) {
public UUID getId() {
return id;
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package org.panda_lang.utilities.inject;

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import org.junit.jupiter.api.Test;
import org.panda_lang.utilities.inject.annotations.AutoConstruct;
import org.panda_lang.utilities.inject.annotations.Injectable;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

final class InjectorProcessorTest {

private final Injector injector = DependencyInjection.createInjector(resources -> {
resources.on(int.class).assignInstance(2023);
resources.on(String.class).assignInstance("Test");
resources.annotatedWithTested(TestAnnotation.class).assignInstance("TestAnnotation");
});
private final InjectorProcessor processor = new InjectorProcessor(this.injector);

@Injectable
@Retention(RetentionPolicy.RUNTIME)
private @interface TestAnnotation {}

private static class TestClass {

private int intProp;
private float floatProp;
private String stringProp;
@TestAnnotation
private String stringAnnotatedProp;
@AutoConstruct
private Object autoConstructProp;

public TestClass(int intProp, @TestAnnotation String stringAnnotatedProp) {}

public TestClass(int intProp, float floatProp) {}

private static PropertyField getProperty(String fieldName) throws NoSuchFieldException {
Field field = TestClass.class.getDeclaredField(fieldName);
return new PropertyField(field);
}

}

@Test
void shouldFetchAnnotations() {
Annotation[] annotations = this.processor.fetchAnnotations(TestClass.class.getConstructors()[0]);
assertEquals(2, annotations.length);
assertNull(annotations[0]);
assertTrue(annotations[1] instanceof TestAnnotation);
}

@Test
void shouldFetchBinds() throws Exception {
// Fetch single
Property intProperty = TestClass.getProperty("intProp");
assertDoesNotThrow(() -> this.processor.fetchBind(null, intProperty));

Property stringProperty = TestClass.getProperty("stringProp");
Bind<Annotation> stringBind = assertDoesNotThrow(() -> this.processor.fetchBind(null, stringProperty));
assertEquals("Test", stringBind.getValue(stringProperty, null));

Property stringAnnotatedProperty = TestClass.getProperty("stringAnnotatedProp");
TestAnnotation testAnnotation = stringAnnotatedProperty.getAnnotation(TestAnnotation.class);
Bind<Annotation> annotatedStringBind = assertDoesNotThrow(() -> this.processor.fetchBind(testAnnotation, stringAnnotatedProperty));
assertEquals("TestAnnotation", annotatedStringBind.getValue(stringAnnotatedProperty, testAnnotation));

Property autoConstructProperty = TestClass.getProperty("autoConstructProp");
Bind<Annotation> autoConstructBind = assertDoesNotThrow(() -> this.processor.fetchBind(null, autoConstructProperty));
assertEquals(this.processor.getAutoConstructBind(), autoConstructBind);

// Fetch multiple
Constructor<?> testConstructor = TestClass.class.getConstructors()[0];
Annotation[] annotations = this.processor.fetchAnnotations(testConstructor);
Bind<Annotation>[] fetchedBinds = assertDoesNotThrow(() -> this.processor.fetchBinds(annotations, testConstructor));

assertEquals(2, fetchedBinds.length);
assertNotNull(fetchedBinds[0]);
assertNotNull(fetchedBinds[1]);
}

@Test
void shouldNotFetchBinds() throws Exception {
// Fetch single
Property floatProperty = TestClass.getProperty("floatProp");
assertThrows(MissingBindException.class, () -> this.processor.fetchBind(null, floatProperty));

// Fetch multiple
Constructor<?> testConstructor = TestClass.class.getConstructors()[1];
Annotation[] annotations = this.processor.fetchAnnotations(testConstructor);
assertThrows(MissingBindException.class, () -> this.processor.fetchBinds(annotations, testConstructor));
}

}
Loading