diff --git a/di/src/main/java/org/panda_lang/utilities/inject/InjectorProcessor.java b/di/src/main/java/org/panda_lang/utilities/inject/InjectorProcessor.java index 32ff4b9..47b1717 100644 --- a/di/src/main/java/org/panda_lang/utilities/inject/InjectorProcessor.java +++ b/di/src/main/java/org/panda_lang/utilities/inject/InjectorProcessor.java @@ -35,7 +35,7 @@ final class InjectorProcessor { private final Injector injector; private final Map injectableCache = new HashMap<>(); - final Bind autoConstructBind; + private final Bind autoConstructBind; InjectorProcessor(Injector injector) { this.injector = injector; @@ -188,4 +188,8 @@ protected Bind fetchBind(@Nullable Annotation annotation, Property p return handlers; } + Bind getAutoConstructBind() { + return this.autoConstructBind; + } + } diff --git a/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionFieldsTest.java b/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionFieldsTest.java index 140704a..39ae1d6 100644 --- a/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionFieldsTest.java +++ b/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionFieldsTest.java @@ -1,19 +1,19 @@ 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) - private @interface Custom { } + private @interface Custom {} private static class Service extends AbstractService { @@ -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()); } diff --git a/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionHandlerTest.java b/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionHandlerTest.java index 93e116f..0ebadb1 100644 --- a/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionHandlerTest.java +++ b/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionHandlerTest.java @@ -14,11 +14,11 @@ public class DependencyInjectionHandlerTest { @Injectable @Retention(RetentionPolicy.RUNTIME) - private @interface Custom { } + private @interface Custom {} @Injectable @Retention(RetentionPolicy.RUNTIME) - private @interface TestAnnotation { } + private @interface TestAnnotation {} private static class Service1 { diff --git a/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionInstancesTest.java b/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionInstancesTest.java index 086c679..7945b28 100644 --- a/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionInstancesTest.java +++ b/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionInstancesTest.java @@ -32,23 +32,27 @@ void shouldNotInjectInstances() { }); }); - assertThrows(InvalidParameterException.class, () -> injector.forConstructor(InvalidClass.class).newInstance(), "Class has contain one and only one constructor"); + assertThrows(InvalidParameterException.class, () -> injector.forConstructor(InvalidClass.class).newInstance(), "Class has to contain one and only constructor"); assertThrows(DependencyInjectionException.class, () -> injector.newInstance(Service.class)); } - private static class Bean { } + private static class Bean {} - private interface Custom { } - private static class CustomImpl implements Custom { } + private interface Custom {} + + private static class CustomImpl implements Custom {} private 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); @@ -57,6 +61,7 @@ public InvalidClass(Bean bean, Custom custom) { public InvalidClass(Bean bean) { assertNotNull(bean); } + } } diff --git a/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionUtilsTest.java b/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionUtilsTest.java index 26133f9..7f82aea 100644 --- a/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionUtilsTest.java +++ b/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionUtilsTest.java @@ -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 { @@ -36,18 +36,18 @@ void testAnnotation() { assertDoesNotThrow(() -> DependencyInjectionUtils.testAnnotation(InjectableAnnotation.class)); } - private static class NotAnAnnotation { } + private static class NotAnAnnotation {} - private @interface DefaultAnnotation { } + private @interface DefaultAnnotation {} @Retention(RetentionPolicy.CLASS) - private @interface ClassAnnotation { } + private @interface ClassAnnotation {} @Retention(RetentionPolicy.RUNTIME) - private @interface RuntimeAnnotation { } + private @interface RuntimeAnnotation {} @Injectable @Retention(RetentionPolicy.RUNTIME) - private @interface InjectableAnnotation { } + private @interface InjectableAnnotation {} } \ No newline at end of file diff --git a/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionWikiTest.java b/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionWikiTest.java index 49ec0b3..9b78dd6 100644 --- a/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionWikiTest.java +++ b/di/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionWikiTest.java @@ -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 { @@ -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 - private @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 @@ -66,6 +66,7 @@ private Entity(@AwesomeRandom UUID random) { public UUID getId() { return id; } + } } diff --git a/di/src/test/java/org/panda_lang/utilities/inject/InjectorProcessorTest.java b/di/src/test/java/org/panda_lang/utilities/inject/InjectorProcessorTest.java index 184076c..6d48ba6 100644 --- a/di/src/test/java/org/panda_lang/utilities/inject/InjectorProcessorTest.java +++ b/di/src/test/java/org/panda_lang/utilities/inject/InjectorProcessorTest.java @@ -4,11 +4,10 @@ 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 org.panda_lang.utilities.inject.shared.AnnotationUtils; -import org.panda_lang.utilities.inject.shared.DummyProperty; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -28,13 +27,26 @@ final class InjectorProcessorTest { @Injectable @Retention(RetentionPolicy.RUNTIME) - private @interface TestAnnotation { } + private @interface TestAnnotation {} private static class TestClass { - public TestClass(int intProp, @TestAnnotation String stringAnnotatedProp) { } + private int intProp; + private float floatProp; + private String stringProp; + @TestAnnotation + private String stringAnnotatedProp; + @AutoConstruct + private Object autoConstructProp; - public TestClass(int intProp, float floatProp) { } + 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); + } } @@ -49,21 +61,21 @@ void shouldFetchAnnotations() { @Test void shouldFetchBinds() throws Exception { // Fetch single - Property intProperty = new DummyProperty<>("intProp", int.class); + Property intProperty = TestClass.getProperty("intProp"); assertDoesNotThrow(() -> this.processor.fetchBind(null, intProperty)); - Property stringProperty = new DummyProperty<>("stringProp", String.class); + Property stringProperty = TestClass.getProperty("stringProp"); Bind stringBind = assertDoesNotThrow(() -> this.processor.fetchBind(null, stringProperty)); assertEquals("Test", stringBind.getValue(stringProperty, null)); - Property stringAnnotatedProperty = new DummyProperty<>("stringAnnotatedProp", String.class, TestAnnotation.class); - TestAnnotation testAnnotation = AnnotationUtils.instanceAnnotation(TestAnnotation.class); + Property stringAnnotatedProperty = TestClass.getProperty("stringAnnotatedProp"); + TestAnnotation testAnnotation = stringAnnotatedProperty.getAnnotation(TestAnnotation.class); Bind annotatedStringBind = assertDoesNotThrow(() -> this.processor.fetchBind(testAnnotation, stringAnnotatedProperty)); assertEquals("TestAnnotation", annotatedStringBind.getValue(stringAnnotatedProperty, testAnnotation)); - Property autoConstructProperty = new DummyProperty<>("autoConstructProp", Object.class, AutoConstruct.class); + Property autoConstructProperty = TestClass.getProperty("autoConstructProp"); Bind autoConstructBind = assertDoesNotThrow(() -> this.processor.fetchBind(null, autoConstructProperty)); - assertEquals(this.processor.autoConstructBind, autoConstructBind); + assertEquals(this.processor.getAutoConstructBind(), autoConstructBind); // Fetch multiple Constructor testConstructor = TestClass.class.getConstructors()[0]; @@ -76,18 +88,14 @@ void shouldFetchBinds() throws Exception { } @Test - void shouldNotFetchBinds() { + void shouldNotFetchBinds() throws Exception { // Fetch single - Property floatProperty = new DummyProperty<>("floatProp", float.class); - Property doubleProperty = new DummyProperty<>("doubleProp", double.class); - + Property floatProperty = TestClass.getProperty("floatProp"); assertThrows(MissingBindException.class, () -> this.processor.fetchBind(null, floatProperty)); - assertThrows(MissingBindException.class, () -> this.processor.fetchBind(null, doubleProperty)); // Fetch multiple Constructor testConstructor = TestClass.class.getConstructors()[1]; Annotation[] annotations = this.processor.fetchAnnotations(testConstructor); - assertThrows(MissingBindException.class, () -> this.processor.fetchBinds(annotations, testConstructor)); } diff --git a/di/src/test/java/org/panda_lang/utilities/inject/MethodsInvocationTest.java b/di/src/test/java/org/panda_lang/utilities/inject/MethodsInvocationTest.java index 4b1a3a6..338b0d3 100644 --- a/di/src/test/java/org/panda_lang/utilities/inject/MethodsInvocationTest.java +++ b/di/src/test/java/org/panda_lang/utilities/inject/MethodsInvocationTest.java @@ -41,13 +41,13 @@ public void failMethod() { } @Retention(RetentionPolicy.RUNTIME) - private @interface TestAnnotation { } + private @interface TestAnnotation {} @Retention(RetentionPolicy.RUNTIME) - private @interface TestAnnotation2 { } + private @interface TestAnnotation2 {} @Test - void shouldInvokeMethods() throws NoSuchMethodException { + void shouldInvokeMethods() { Injector injector = DependencyInjection.createInjector(resources -> { resources.on(int.class).assignInstance(3); }); @@ -61,7 +61,7 @@ void shouldInvokeMethods() throws NoSuchMethodException { } @Test - void shouldNotInvokeMethods() throws NoSuchMethodException { + void shouldNotInvokeMethods() { Injector injector = DependencyInjection.createInjector(resources -> { resources.on(int.class).assignInstance(3); }); diff --git a/di/src/test/java/org/panda_lang/utilities/inject/annotations/AutoConstructTest.java b/di/src/test/java/org/panda_lang/utilities/inject/annotations/AutoConstructTest.java index 56f0fe5..0626f72 100644 --- a/di/src/test/java/org/panda_lang/utilities/inject/annotations/AutoConstructTest.java +++ b/di/src/test/java/org/panda_lang/utilities/inject/annotations/AutoConstructTest.java @@ -6,7 +6,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; final class AutoConstructTest { diff --git a/di/src/test/java/org/panda_lang/utilities/inject/shared/AnnotationUtils.java b/di/src/test/java/org/panda_lang/utilities/inject/shared/AnnotationUtils.java deleted file mode 100644 index cad68cb..0000000 --- a/di/src/test/java/org/panda_lang/utilities/inject/shared/AnnotationUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.panda_lang.utilities.inject.shared; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Proxy; - -public final class AnnotationUtils { - - private AnnotationUtils() { - } - - @SuppressWarnings("unchecked") - public static A instanceAnnotation(Class annotationClass) { - return (A) Proxy.newProxyInstance(annotationClass.getClassLoader(), new Class[] { annotationClass }, (proxy, method, args) -> { - if (method.getName().equals("annotationType")) { - return annotationClass; - } - - if (method.getName().equals("toString")) { - return "@" + annotationClass.getName() + "()"; - } - - if (method.getName().equals("hashCode")) { - return annotationClass.hashCode() * 127; - } - - if (method.getName().equals("equals")) { - return args[0] instanceof Annotation && annotationClass.equals(((Annotation) args[0]).annotationType()); - } - - throw new UnsupportedOperationException("Unsupported method: " + method); - }); - } - -} diff --git a/di/src/test/java/org/panda_lang/utilities/inject/shared/DummyProperty.java b/di/src/test/java/org/panda_lang/utilities/inject/shared/DummyProperty.java deleted file mode 100644 index bafa960..0000000 --- a/di/src/test/java/org/panda_lang/utilities/inject/shared/DummyProperty.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.panda_lang.utilities.inject.shared; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import org.panda_lang.utilities.inject.Property; -import panda.std.stream.PandaStream; - -public class DummyProperty implements Property { - - private final String name; - private final Class type; - private final Map, Annotation> annotations; - - public DummyProperty(String name, Class type, List> annotations) { - this.name = name; - this.type = type; - this.annotations = PandaStream.of(annotations).toMap( - annotation -> annotation, - annotation -> { - try { - return AnnotationUtils.instanceAnnotation(annotation); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - ); - } - - @SafeVarargs - public DummyProperty(String name, Class type, Class... annotations) { - this(name, type, Arrays.asList(annotations)); - } - - @Override - public String getName() { - return this.name; - } - - @Override - public Class getType() { - return this.type; - } - - @Override - public Type getParametrizedType() { - return this.type; - } - - @Override - @SuppressWarnings("unchecked") - public A getAnnotation(Class annotation) { - return (A) this.annotations.get(annotation); - } - - @Override - public Annotation[] getAnnotations() { - return this.annotations.values().toArray(new Annotation[0]); - } - -}