From 109f2ea7a488219e05f121f60599862efce4f3ed Mon Sep 17 00:00:00 2001 From: James Seibel Date: Wed, 20 Jul 2022 07:11:46 -0500 Subject: [PATCH] Finish OverrideInjector and add unit tests --- .../dependencyInjection/OverrideInjector.java | 61 ++++++++++------ .../interfaces/IOverrideTest.java | 15 ++++ .../objects/OverrideTestAssembly.java | 22 ++++++ .../objects/OverrideTestCore.java | 23 ++++++ .../objects/OverrideTestPrimary.java | 23 ++++++ .../objects/OverrideTestSecondary.java | 23 ++++++ .../java/tests/DependencyInjectorTest.java | 70 ++++++++++++++++++- 7 files changed, 215 insertions(+), 22 deletions(-) create mode 100644 src/test/java/testItems/overrideInjection/interfaces/IOverrideTest.java create mode 100644 src/test/java/testItems/overrideInjection/objects/OverrideTestAssembly.java create mode 100644 src/test/java/testItems/overrideInjection/objects/OverrideTestCore.java create mode 100644 src/test/java/testItems/overrideInjection/objects/OverrideTestPrimary.java create mode 100644 src/test/java/testItems/overrideInjection/objects/OverrideTestSecondary.java diff --git a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/OverrideInjector.java b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/OverrideInjector.java index ecb05344c..d307852a8 100644 --- a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/OverrideInjector.java +++ b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/OverrideInjector.java @@ -36,38 +36,59 @@ public class OverrideInjector { public static final OverrideInjector INSTANCE = new OverrideInjector(); - private static final DependencyInjector PRIMARY_INJECTOR = new DependencyInjector<>(IDhApiOverrideable.class, false); - private static final DependencyInjector SECONDARY_INJECTOR = new DependencyInjector<>(IDhApiOverrideable.class, false); - private static final DependencyInjector CORE_INJECTOR = new DependencyInjector<>(IDhApiOverrideable.class, false); + private final DependencyInjector primaryInjector = new DependencyInjector<>(IDhApiOverrideable.class, false); + private final DependencyInjector secondaryInjector = new DependencyInjector<>(IDhApiOverrideable.class, false); + private final DependencyInjector coreInjector = new DependencyInjector<>(IDhApiOverrideable.class, false); + + private static final GenericEnumConverter ENUM_CONVERTER = new GenericEnumConverter<>(EApiOverridePriority.class, EDhApiOverridePriority.class); + + /** + * This is used to determine if an override is part of Distant Horizons' + * Core or not. + * This probably isn't the best way of going about this, but it works for now. + */ + private final String corePackagePath; + + + + public OverrideInjector() + { + String thisPackageName = this.getClass().getPackage().getName(); + int secondPackageEndingIndex = StringUtil.nthIndexOf(thisPackageName, ".", 3); + + this.corePackagePath = thisPackageName.substring(0, secondPackageEndingIndex); // this should be "com.seibel.lod" + } + + /** This constructor should only be used for testing different corePackagePaths. */ + public OverrideInjector(String newCorePackagePath) + { + this.corePackagePath = newCorePackagePath; + } - private static final GenericEnumConverter enumConverter = new GenericEnumConverter<>(EApiOverridePriority.class, EDhApiOverridePriority.class); /** * See {@link DependencyInjector#bind(Class, IBindable) bind(Class, IBindable)} for full documentation. * + * @throws IllegalArgumentException if a non-Distant Horizons Override with the priority CORE is passed in * @see DependencyInjector#bind(Class, IBindable) */ public void bind(Class dependencyInterface, IDhApiOverrideable dependencyImplementation) throws IllegalStateException, IllegalArgumentException { if (getCorePriorityEnum(dependencyImplementation) == EApiOverridePriority.PRIMARY) { - PRIMARY_INJECTOR.bind(dependencyInterface, dependencyImplementation); + primaryInjector.bind(dependencyInterface, dependencyImplementation); } else if (getCorePriorityEnum(dependencyImplementation) == EApiOverridePriority.SECONDARY) { - SECONDARY_INJECTOR.bind(dependencyInterface, dependencyImplementation); + secondaryInjector.bind(dependencyInterface, dependencyImplementation); } else { - // not the best way of doing this, but it should work - String thisPackageName = this.getClass().getPackage().getName(); - int secondPackageEndingIndex = StringUtil.nthIndexOf(thisPackageName, ".", 3); - String thisPackageBeginningName = thisPackageName.substring(0, secondPackageEndingIndex); // this should be "com.seibel.lod" - - if (dependencyImplementation.getClass().getPackage().getName().startsWith(thisPackageBeginningName)) + String packageName = dependencyImplementation.getClass().getPackage().getName(); + if (packageName.startsWith(this.corePackagePath)) { - CORE_INJECTOR.bind(dependencyInterface, dependencyImplementation); + coreInjector.bind(dependencyInterface, dependencyImplementation); } else { @@ -84,14 +105,14 @@ public class OverrideInjector */ public T get(Class interfaceClass) throws ClassCastException { - T value = PRIMARY_INJECTOR.get(interfaceClass); + T value = primaryInjector.get(interfaceClass); if (value == null) { - value = SECONDARY_INJECTOR.get(interfaceClass); + value = secondaryInjector.get(interfaceClass); } if (value == null) { - value = CORE_INJECTOR.get(interfaceClass); + value = coreInjector.get(interfaceClass); } return value; @@ -110,15 +131,15 @@ public class OverrideInjector T value; if (overridePriority == EApiOverridePriority.PRIMARY) { - value = PRIMARY_INJECTOR.get(interfaceClass); + value = primaryInjector.get(interfaceClass); } else if (overridePriority == EApiOverridePriority.SECONDARY) { - value = SECONDARY_INJECTOR.get(interfaceClass); + value = secondaryInjector.get(interfaceClass); } else { - value = CORE_INJECTOR.get(interfaceClass); + value = coreInjector.get(interfaceClass); } return value; @@ -128,7 +149,7 @@ public class OverrideInjector /** Small helper method so we don't have to use DhApi enums. */ private EApiOverridePriority getCorePriorityEnum(IDhApiOverrideable override) { - return enumConverter.convertToCoreType(override.getOverrideType()); + return ENUM_CONVERTER.convertToCoreType(override.getOverrideType()); } } diff --git a/src/test/java/testItems/overrideInjection/interfaces/IOverrideTest.java b/src/test/java/testItems/overrideInjection/interfaces/IOverrideTest.java new file mode 100644 index 000000000..7d059b88f --- /dev/null +++ b/src/test/java/testItems/overrideInjection/interfaces/IOverrideTest.java @@ -0,0 +1,15 @@ +package testItems.overrideInjection.interfaces; + +import com.seibel.lod.core.api.external.items.interfaces.override.IDhApiOverrideable; + +/** + * Dummy override test interface for dependency unit tests. + * + * @author James Seibel + * @version 2022-7-19 + */ +public interface IOverrideTest extends IDhApiOverrideable +{ + public int getValue(); + +} diff --git a/src/test/java/testItems/overrideInjection/objects/OverrideTestAssembly.java b/src/test/java/testItems/overrideInjection/objects/OverrideTestAssembly.java new file mode 100644 index 000000000..93d7cf74e --- /dev/null +++ b/src/test/java/testItems/overrideInjection/objects/OverrideTestAssembly.java @@ -0,0 +1,22 @@ +package testItems.overrideInjection.objects; + +import com.seibel.lod.core.util.StringUtil; + +/** + * assembly classes are used to reference the package they are in. + * + * @author james seibel + * @version 2022-7-19 + */ +public class OverrideTestAssembly +{ + + /** Returns the first N packages in this class' path. */ + public static String getPackagePath(int numberOfPackagesToReturn) + { + String thisPackageName = OverrideTestAssembly.class.getPackage().getName(); + int secondPackageEndingIndex = StringUtil.nthIndexOf(thisPackageName, ".", numberOfPackagesToReturn); + return thisPackageName.substring(0, secondPackageEndingIndex); + } + +} diff --git a/src/test/java/testItems/overrideInjection/objects/OverrideTestCore.java b/src/test/java/testItems/overrideInjection/objects/OverrideTestCore.java new file mode 100644 index 000000000..ae0d02714 --- /dev/null +++ b/src/test/java/testItems/overrideInjection/objects/OverrideTestCore.java @@ -0,0 +1,23 @@ +package testItems.overrideInjection.objects; + +import com.seibel.lod.core.api.external.items.enums.override.EDhApiOverridePriority; +import testItems.overrideInjection.interfaces.IOverrideTest; + +/** + * Dummy test implementation object for dependency injection unit tests. + * + * @author James Seibel + * @version 2022-7-19 + */ +public class OverrideTestCore implements IOverrideTest +{ + public static int VALUE = 1; + + + @Override + public int getValue() { return VALUE; } + + @Override + public EDhApiOverridePriority getOverrideType() { return EDhApiOverridePriority.CORE; } + +} diff --git a/src/test/java/testItems/overrideInjection/objects/OverrideTestPrimary.java b/src/test/java/testItems/overrideInjection/objects/OverrideTestPrimary.java new file mode 100644 index 000000000..a96964f03 --- /dev/null +++ b/src/test/java/testItems/overrideInjection/objects/OverrideTestPrimary.java @@ -0,0 +1,23 @@ +package testItems.overrideInjection.objects; + +import com.seibel.lod.core.api.external.items.enums.override.EDhApiOverridePriority; +import testItems.overrideInjection.interfaces.IOverrideTest; + +/** + * Dummy test implementation object for dependency injection unit tests. + * + * @author James Seibel + * @version 2022-7-19 + */ +public class OverrideTestPrimary implements IOverrideTest +{ + public static int VALUE = 3; + + + @Override + public int getValue() { return VALUE; } + + @Override + public EDhApiOverridePriority getOverrideType() { return EDhApiOverridePriority.PRIMARY; } + +} diff --git a/src/test/java/testItems/overrideInjection/objects/OverrideTestSecondary.java b/src/test/java/testItems/overrideInjection/objects/OverrideTestSecondary.java new file mode 100644 index 000000000..75a89fdcb --- /dev/null +++ b/src/test/java/testItems/overrideInjection/objects/OverrideTestSecondary.java @@ -0,0 +1,23 @@ +package testItems.overrideInjection.objects; + +import com.seibel.lod.core.api.external.items.enums.override.EDhApiOverridePriority; +import testItems.overrideInjection.interfaces.IOverrideTest; + +/** + * Dummy test implementation object for dependency injection unit tests. + * + * @author James Seibel + * @version 2022-7-19 + */ +public class OverrideTestSecondary implements IOverrideTest +{ + public static int VALUE = 2; + + + @Override + public int getValue() { return VALUE; } + + @Override + public EDhApiOverridePriority getOverrideType() { return EDhApiOverridePriority.SECONDARY; } + +} diff --git a/src/test/java/tests/DependencyInjectorTest.java b/src/test/java/tests/DependencyInjectorTest.java index 26aaca62c..34d09f03a 100644 --- a/src/test/java/tests/DependencyInjectorTest.java +++ b/src/test/java/tests/DependencyInjectorTest.java @@ -158,8 +158,74 @@ public class DependencyInjectorTest } - Assert.assertNotNull(ISingletonTestTwo.class.getSimpleName() + " not bound.", testInterTwo); - Assert.assertEquals(ISingletonTestTwo.class.getSimpleName() + " incorrect value.", testInterTwo.getValue(), ConcreteSingletonTestBoth.VALUE); + @Test + public void testOverrideInjection() + { + OverrideInjector TEST_OVERRIDE_INJECTOR = new OverrideInjector(OverrideTestAssembly.getPackagePath(2)); + OverrideInjector CORE_OVERRIDE_INJECTOR = new OverrideInjector(); + + + // pre-dependency setup + Assert.assertNull("Nothing should have been bound.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class)); + Assert.assertNull("Nothing should have been bound.", CORE_OVERRIDE_INJECTOR.get(IOverrideTest.class)); + + + // variables to use later + IOverrideTest override; + OverrideTestCore coreOverride = new OverrideTestCore(); + OverrideTestSecondary secondaryOverride = new OverrideTestSecondary(); + OverrideTestPrimary primaryOverride = new OverrideTestPrimary(); + + + // core override binding + try { TEST_OVERRIDE_INJECTOR.bind(IOverrideTest.class, coreOverride); } catch (IllegalArgumentException e) { Assert.fail("Core override should be bindable for test package injector."); } + + try + { + CORE_OVERRIDE_INJECTOR.bind(IOverrideTest.class, coreOverride); + Assert.fail("Core override should not be bindable for core package injector."); + } + catch (IllegalArgumentException e) { /* this exception should be thrown */ } + + + // core override + Assert.assertNotNull("Test injector should've bound core override.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class)); + Assert.assertNull("Core injector should not have bound core override.", CORE_OVERRIDE_INJECTOR.get(IOverrideTest.class)); + // priority gets + Assert.assertNotNull("Core override should be bound.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class, EApiOverridePriority.CORE)); + Assert.assertNull("Secondary override should not be bound yet.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class, EApiOverridePriority.SECONDARY)); + Assert.assertNull("Primary override should not be bound yet.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class, EApiOverridePriority.PRIMARY)); + // standard get + override = TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class); + Assert.assertEquals("Override returned incorrect override type.", override.getOverrideType(), EDhApiOverridePriority.CORE); + Assert.assertEquals("Incorrect override object returned.", override.getValue(), OverrideTestCore.VALUE); + + + // secondary override + TEST_OVERRIDE_INJECTOR.bind(IOverrideTest.class, secondaryOverride); + // priority gets + Assert.assertNotNull("Test injector should've bound secondary override.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class)); + Assert.assertNotNull("Core override should be bound.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class, EApiOverridePriority.CORE)); + Assert.assertNotNull("Secondary override should be bound.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class, EApiOverridePriority.SECONDARY)); + Assert.assertNull("Primary override should not be bound yet.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class, EApiOverridePriority.PRIMARY)); + // standard get + override = TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class); + Assert.assertEquals("Override returned incorrect override type.", override.getOverrideType(), EDhApiOverridePriority.SECONDARY); + Assert.assertEquals("Incorrect override object returned.", override.getValue(), OverrideTestSecondary.VALUE); + + + // primary override + TEST_OVERRIDE_INJECTOR.bind(IOverrideTest.class, primaryOverride); + // priority gets + Assert.assertNotNull("Test injector should've bound primary override.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class)); + Assert.assertNotNull("Core override should be bound.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class, EApiOverridePriority.CORE)); + Assert.assertNotNull("Secondary override should be bound.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class, EApiOverridePriority.SECONDARY)); + Assert.assertNotNull("Primary override should be bound.", TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class, EApiOverridePriority.PRIMARY)); + // standard get + override = TEST_OVERRIDE_INJECTOR.get(IOverrideTest.class); + Assert.assertEquals("Override returned incorrect override type.", override.getOverrideType(), EDhApiOverridePriority.PRIMARY); + Assert.assertEquals("Incorrect override object returned.", override.getValue(), OverrideTestPrimary.VALUE); + }