package info.ebenoit.ebul.cmp; import org.junit.Test; import info.ebenoit.ebul.func.ThrowingBiConsumer; import info.ebenoit.ebul.func.ThrowingConsumer; import test.inherited.CBase; import test.inherited.CChild; import test.inherited.CChildOfAbstract; import test.interfaces.CImplementation; import test.simple.CSimple; import static org.junit.Assert.*; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; /** * Tests for the {@link NewComponentInfo} class * <p> * Note: since most methods in this class are just accessors, they are not tested. */ public class TestNewComponentInfo { /** Class that has no default constructor */ private static class TestFail1 { private TestFail1( int arg ) { // EMPTY } } /** Test component with no information */ private static class TestCmp1 { // EMPTY } /** Test component with a name, autostart and dependency information */ @Component( "Test component" ) @Autostart @Dependencies( { "TestCmp1" , "TestCmp3" } ) private static class TestCmp2 { // EMPTY } /** Test component acting as a driver for another */ @DriverFor( "TestCmp1" ) private static class TestCmp3 { // EMPTY } /** Test component that should inherit dependencies */ @Dependencies( "TestCmp5" ) private static class TestCmp4 extends TestCmp2 { // EMPTY } /** Test anonymous component */ @Anonymous private static class TestCmpAnon { // EMPTY } /** Test anonymous component with empty {@link Component} annotation */ @Anonymous @Component private static class TestCmpAnonComponent { // EMPTY } /** Test anonymous component that has a name provider (invalid!) */ @Anonymous private static class TestCmpAnonPN { @NameProvider public String getComponentName( ) { return null; } } /** Test anonymous component that has a specified name (invalid!) */ @Component( "Fail!" ) @Anonymous private static class TestCmpAnonNamed { // EMPTY } /** Test component with a name provider */ private static class TestCmpPN { @NameProvider public String getComponentName( ) { return "TestCmpPN"; } } /** Test component with a name provider and an annotation-specified name (invalid!) */ @Component( "Fail" ) private static class TestCmpPNFail1 { @NameProvider public String getComponentName( ) { return "TestCmpPNFail"; } } /** Test component with a static name provider (invalid) */ private static class TestCmpPNFail2 { @NameProvider static public String getComponentName( ) { return "TestCmpPNFail"; } } /** Test component with a name provider that doesn't return a string (invalid) */ private static class TestCmpPNFail3 { @NameProvider static public Object getComponentName( ) { return "TestCmpPNFail"; } } /** Test component with a name provider that has arguments (invalid) */ private static class TestCmpPNFail4 { @NameProvider static public String getComponentName( String fail ) { return "TestCmpPNFail"; } } /** Test component with multiple name providers (invalid) */ private static class TestCmpPNFail5 { @NameProvider static public String getComponentName( ) { return "TestCmpPNFail"; } @NameProvider static public String getComponentNameToo( String fail ) { return "TestCmpPNFail"; } } /** Test component that has lifecycle methods */ private static class TestCmp5 { protected final boolean hadLifecycleAction[] = new boolean[ 4 ]; @LifecycleMethod( LifecycleStage.INITIALISE ) private void init( ) { hadLifecycleAction[ LifecycleStage.INITIALISE.ordinal( ) ] = true; } @LifecycleMethod( LifecycleStage.START ) private void start( ) { hadLifecycleAction[ LifecycleStage.START.ordinal( ) ] = true; } @LifecycleMethod( LifecycleStage.STOP ) private void stop( ) { hadLifecycleAction[ LifecycleStage.STOP.ordinal( ) ] = true; } @LifecycleMethod( LifecycleStage.DESTROY ) private void destroy( ) { hadLifecycleAction[ LifecycleStage.DESTROY.ordinal( ) ] = true; } } /** Test component that has inherited and overridden lifecycle methods */ private static class TestCmp6 extends TestCmp5 { private boolean hadLocalInitialise; @LifecycleMethod( LifecycleStage.INITIALISE ) private void init( ) { hadLocalInitialise = true; } } /** Test interface that defines a lifecycle method */ private static interface ITest7 { @LifecycleMethod( LifecycleStage.INITIALISE ) public void init( ); } /** Test component that has an interface-defined lifecycle method */ private static class TestCmp7 implements ITest7 { private boolean initialised; @Override public void init( ) { this.initialised = true; } } /** Test component with duplicate lifecycle methods */ private static class TestFail2 { @LifecycleMethod( LifecycleStage.INITIALISE ) private void init1( ) { // EMPTY } @LifecycleMethod( LifecycleStage.INITIALISE ) private void init2( ) { // EMPTY } } /** Test component with a dependency injection field using a name */ private static class TestCmp8 { @UseComponent( "TestCmp1" ) protected TestCmp1 dependency; } /** Test component with a dependency injection field using the field's type */ private static class TestCmp9 { @UseComponent private TestCmp1 dependency; } /** Test component with a static dependency injection field */ private static class TestFail3 { @UseComponent private static TestCmp1 dependency; } /** Test component with a final dependency injection field */ private static class TestFail4 { @UseComponent private final TestCmp1 dependency; private TestFail4( ) { super( ); this.dependency = null; } } /** Test component with a primitive dependency injection field */ private static class TestFail5 { @UseComponent( "x" ) private int dependency; } /** Test component with an array dependency injection field */ private static class TestFail6 { @UseComponent( "x" ) private Object[] dependency; } /** Test component with a dependency injection method using a name */ private static class TestCmp10 { protected TestCmp1 dependency; @UseComponent( "TestCmp1" ) private void inject( TestCmp1 dependency ) { this.dependency = dependency; } } /** Test component with a dependency injection method with no name */ private static class TestCmp11 { private TestCmp1 dependency; @UseComponent private void inject( TestCmp1 dependency ) { this.dependency = dependency; } } /** Test component with a static dependency injection method */ private static class TestFail7 { @UseComponent private static void inject( TestCmp1 dependency ) { // EMPTY } } /** Test component with a dependency injection method that has no parameters */ private static class TestFail8 { @UseComponent( "x" ) private void inject( ) { // EMPTY } } /** Test component with a dependency injection method that has two parameters */ private static class TestFail9 { @UseComponent private void inject( TestCmp1 dependency , int x ) { // EMPTY } } /** Test component with a primitive dependency injection method */ private static class TestFail10 { @UseComponent( "x" ) private void inject( int x ) { // EMPTY } } /** Test component with an array dependency injection field */ private static class TestFail11 { @UseComponent( "x" ) private void inject( Object[] x ) { // EMPTY } } /** Test component that inherits a dependency injection method */ private static class TestCmp12 extends TestCmp10 { // EMPTY } /** Test component that inherits a dependency injection */ private static class TestCmp13 extends TestCmp8 { // EMPTY } /** Interface that defines a dependency injection method */ private static interface ITest14 { @UseComponent( "TestCmp1" ) public void inject( TestCmp1 dependency ); } /** Test component with a dependency injection method defined in an interface */ private static class TestCmp14 implements ITest14 { private TestCmp1 dependency; @Override public void inject( TestCmp1 dependency ) { this.dependency = dependency; } } /** Test: {@link NewComponentInfo#addDependencyInjector(DependencyInfo, ThrowingBiConsumer)} adds a dependency */ @Test public void testAddDependencyInjector( ) { NewComponentInfo< Object > nci = new NewComponentInfo< Object >( new Object( ) ); nci.addDependencyInjector( new DependencyInfo( "test" ) , ( cmp , dep ) -> { } ); assertTrue( nci.getDependencies( ).contains( new DependencyInfo( "test" ) ) ); } /** Test: {@link NewComponentInfo#fromClass(Class)} on a component class with no default constructor */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail1( ) { NewComponentInfo.fromClass( TestFail1.class ); } /** Test: {@link NewComponentInfo#fromClass(Class)} on a component class with no information */ @Test public void testFromClass1( ) { NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmp1.class ); assertEquals( "" , nci.getName( ) ); assertFalse( nci.getAutostart( ) ); assertTrue( nci.getDependencies( ).isEmpty( ) ); assertNull( nci.getDriverFor( ) ); assertTrue( nci.getInjectors( ).isEmpty( ) ); assertTrue( nci.getSupplier( ).get( ) instanceof TestCmp1 ); } /** Test: {@link NewComponentInfo#fromClass(Class)} on a component class with a name, dependencies and autostart */ @Test public void testFromClass2( ) { NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmp2.class ); assertEquals( "Test component" , nci.getName( ) ); assertTrue( nci.getAutostart( ) ); HashSet< DependencyInfo > deps = nci.getDependencies( ); assertEquals( 2 , deps.size( ) ); assertTrue( deps.contains( new DependencyInfo( "TestCmp1" ) ) ); assertTrue( deps.contains( new DependencyInfo( "TestCmp3" ) ) ); } /** Test: {@link NewComponentInfo#fromClass(Class)} on a component class set to be a driver for another component */ @Test public void testFromClass3( ) { NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmp3.class ); HashSet< DependencyInfo > deps = nci.getDependencies( ); assertEquals( 1 , deps.size( ) ); assertTrue( deps.contains( new DependencyInfo( "TestCmp1" ) ) ); assertEquals( "TestCmp1" , nci.getDriverFor( ) ); } /** Test: {@link NewComponentInfo#fromClass(Class)} on a component class with inherited + local dependencies */ @Test public void testFromClass4( ) { NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmp4.class ); assertNotEquals( "component name was inherited!" , "Test component" , nci.getName( ) ); assertFalse( "autostart state was inherited!" , nci.getAutostart( ) ); HashSet< DependencyInfo > deps = nci.getDependencies( ); assertEquals( 3 , deps.size( ) ); assertTrue( deps.contains( new DependencyInfo( "TestCmp1" ) ) ); assertTrue( deps.contains( new DependencyInfo( "TestCmp3" ) ) ); assertTrue( deps.contains( new DependencyInfo( "TestCmp5" ) ) ); } /** Test: {@link NewComponentInfo#fromClass(Class)} on a component class with the {@link Anonymous} annotation */ @Test public void testFromClassAnon( ) { NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmpAnon.class ); assertNull( nci.getName( ) ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with the {@link Anonymous} annotation and an * empty {@link Component} annotation */ @Test public void testFromClassAnonComponent( ) { NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmpAnonComponent.class ); assertNull( nci.getName( ) ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with the {@link Anonymous} annotation that * includes a {@link NameProvider} */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassAnonPN( ) { NewComponentInfo.fromClass( TestCmpAnonPN.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with the {@link Anonymous} annotation and a * {@link Component} annotation carrying a value */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassAnonNamed( ) { NewComponentInfo.fromClass( TestCmpAnonNamed.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that uses a {@link NameProvider} */ @Test public void testFromClassPN1( ) { NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmpPN.class ); assertEquals( "" , nci.getName( ) ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that uses a {@link NameProvider} but also * has an annotation-specified name */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassPNFail1( ) { NewComponentInfo.fromClass( TestCmpPNFail1.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that uses {@link NameProvider} on a static * method */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassPNFail2( ) { NewComponentInfo.fromClass( TestCmpPNFail2.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that uses {@link NameProvider} on a method * that doesn't return a string */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassPNFail3( ) { NewComponentInfo.fromClass( TestCmpPNFail3.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that uses {@link NameProvider} on a method * that has arguments */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassPNFail4( ) { NewComponentInfo.fromClass( TestCmpPNFail4.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that uses {@link NameProvider} on more than * one method */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassPNFail5( ) { NewComponentInfo.fromClass( TestCmpPNFail5.class ); } /** Test: {@link NewComponentInfo#fromClass(Class)} on a component class with lifecycle methods */ @Test public void testFromClass5( ) { NewComponentInfo< TestCmp5 > nci = NewComponentInfo.fromClass( TestCmp5.class ); TestCmp5 cmp = nci.getSupplier( ).get( ); for ( LifecycleStage stage : LifecycleStage.values( ) ) { ThrowingConsumer< ? super TestCmp5 > f = nci.getLifecycleAction( stage ); assertNotNull( f ); assertFalse( cmp.hadLifecycleAction[ stage.ordinal( ) ] ); f.accept( cmp ); assertTrue( cmp.hadLifecycleAction[ stage.ordinal( ) ] ); } } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with inherited and overridden lifecycle * methods */ @Test public void testFromClass6( ) { NewComponentInfo< TestCmp6 > nci = NewComponentInfo.fromClass( TestCmp6.class ); TestCmp6 cmp = nci.getSupplier( ).get( ); for ( LifecycleStage stage : LifecycleStage.values( ) ) { ThrowingConsumer< ? super TestCmp6 > f = nci.getLifecycleAction( stage ); assertNotNull( f ); assertFalse( cmp.hadLifecycleAction[ stage.ordinal( ) ] ); f.accept( cmp ); if ( stage == LifecycleStage.INITIALISE ) { assertFalse( cmp.hadLifecycleAction[ stage.ordinal( ) ] ); assertTrue( cmp.hadLocalInitialise ); } else { assertTrue( cmp.hadLifecycleAction[ stage.ordinal( ) ] ); } } } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with interface-defined lifecycle methods */ @Test public void testFromClass7( ) { NewComponentInfo< TestCmp7 > nci = NewComponentInfo.fromClass( TestCmp7.class ); TestCmp7 cmp = nci.getSupplier( ).get( ); ThrowingConsumer< ? super TestCmp7 > f = nci.getLifecycleAction( LifecycleStage.INITIALISE ); assertNotNull( f ); f.accept( cmp ); assertTrue( cmp.initialised ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that defines more than one method for a * single lifecycle stage */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail2( ) { NewComponentInfo.fromClass( TestFail2.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with a dependency injection field that names * its target */ @Test public void testFromClass8( ) { NewComponentInfo< TestCmp8 > nci = NewComponentInfo.fromClass( TestCmp8.class ); DependencyInfo expectedDep = new DependencyInfo( "TestCmp1" ); HashSet< DependencyInfo > deps = nci.getDependencies( ); assertEquals( 1 , deps.size( ) ); assertTrue( deps.contains( expectedDep ) ); HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( ); assertEquals( 1 , injectors.size( ) ); ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep ); assertEquals( 1 , diList.size( ) ); ThrowingBiConsumer< ? super TestCmp8 , Object > injector = diList.get( 0 ); assertNotNull( injector ); TestCmp8 cmp = nci.getSupplier( ).get( ); TestCmp1 inject = new TestCmp1( ); injector.accept( cmp , inject ); assertSame( inject , cmp.dependency ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with a dependency injection field that * doesn't name its target */ @Test public void testFromClass9( ) { NewComponentInfo< TestCmp9 > nci = NewComponentInfo.fromClass( TestCmp9.class ); DependencyInfo expectedDep = new DependencyInfo( TestCmp1.class ); HashSet< DependencyInfo > deps = nci.getDependencies( ); assertEquals( 1 , deps.size( ) ); assertTrue( deps.contains( expectedDep ) ); HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( ); assertEquals( 1 , injectors.size( ) ); ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep ); assertEquals( 1 , diList.size( ) ); ThrowingBiConsumer< ? super TestCmp9 , Object > injector = diList.get( 0 ); assertNotNull( injector ); TestCmp9 cmp = nci.getSupplier( ).get( ); TestCmp1 inject = new TestCmp1( ); injector.accept( cmp , inject ); assertSame( inject , cmp.dependency ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that has a static dependency injection field */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail3( ) { NewComponentInfo.fromClass( TestFail3.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that has a final dependency injection field */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail4( ) { NewComponentInfo.fromClass( TestFail4.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that has a primitive dependency injection * field */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail5( ) { NewComponentInfo.fromClass( TestFail5.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that has an array dependency injection field */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail6( ) { NewComponentInfo.fromClass( TestFail6.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with a dependency injection method that * names its target */ @Test public void testFromClass10( ) { NewComponentInfo< TestCmp10 > nci = NewComponentInfo.fromClass( TestCmp10.class ); DependencyInfo expectedDep = new DependencyInfo( "TestCmp1" ); HashSet< DependencyInfo > deps = nci.getDependencies( ); assertEquals( 1 , deps.size( ) ); assertTrue( deps.contains( expectedDep ) ); HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( ); assertEquals( 1 , injectors.size( ) ); ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep ); assertEquals( 1 , diList.size( ) ); ThrowingBiConsumer< ? super TestCmp10 , Object > injector = diList.get( 0 ); assertNotNull( injector ); TestCmp10 cmp = nci.getSupplier( ).get( ); TestCmp1 inject = new TestCmp1( ); injector.accept( cmp , inject ); assertSame( inject , cmp.dependency ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with a dependency injection method that * doesn't name its target */ @Test public void testFromClass11( ) { NewComponentInfo< TestCmp11 > nci = NewComponentInfo.fromClass( TestCmp11.class ); DependencyInfo expectedDep = new DependencyInfo( TestCmp1.class ); HashSet< DependencyInfo > deps = nci.getDependencies( ); assertEquals( 1 , deps.size( ) ); assertTrue( deps.contains( expectedDep ) ); HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( ); assertEquals( 1 , injectors.size( ) ); ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep ); assertEquals( 1 , diList.size( ) ); ThrowingBiConsumer< ? super TestCmp11 , Object > injector = diList.get( 0 ); assertNotNull( injector ); TestCmp11 cmp = nci.getSupplier( ).get( ); TestCmp1 inject = new TestCmp1( ); injector.accept( cmp , inject ); assertSame( inject , cmp.dependency ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that has a static dependency injection * method */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail7( ) { NewComponentInfo.fromClass( TestFail7.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that has a dependency injection method with * no arguments */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail8( ) { NewComponentInfo.fromClass( TestFail8.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that has a dependency injection method with * more than one argument field */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail9( ) { NewComponentInfo.fromClass( TestFail9.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that has a dependency injection method with * a primitive argument */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail10( ) { NewComponentInfo.fromClass( TestFail10.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that has a dependency injection method with * an array argument */ @Test( expected = ComponentDefinitionException.class ) public void testFromClassFail11( ) { NewComponentInfo.fromClass( TestFail11.class ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with an inherited dependency injection * method */ @Test public void testFromClass12( ) { NewComponentInfo< TestCmp12 > nci = NewComponentInfo.fromClass( TestCmp12.class ); DependencyInfo expectedDep = new DependencyInfo( "TestCmp1" ); HashSet< DependencyInfo > deps = nci.getDependencies( ); assertEquals( 1 , deps.size( ) ); assertTrue( deps.contains( expectedDep ) ); HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( ); assertEquals( 1 , injectors.size( ) ); ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep ); assertEquals( 1 , diList.size( ) ); ThrowingBiConsumer< ? super TestCmp12 , Object > injector = diList.get( 0 ); assertNotNull( injector ); TestCmp12 cmp = nci.getSupplier( ).get( ); TestCmp1 inject = new TestCmp1( ); injector.accept( cmp , inject ); assertSame( inject , cmp.dependency ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with an inherited dependency injection field */ @Test public void testFromClass13( ) { NewComponentInfo< TestCmp13 > nci = NewComponentInfo.fromClass( TestCmp13.class ); DependencyInfo expectedDep = new DependencyInfo( "TestCmp1" ); HashSet< DependencyInfo > deps = nci.getDependencies( ); assertEquals( 1 , deps.size( ) ); assertTrue( deps.contains( expectedDep ) ); HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( ); assertEquals( 1 , injectors.size( ) ); ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep ); assertEquals( 1 , diList.size( ) ); ThrowingBiConsumer< ? super TestCmp13 , Object > injector = diList.get( 0 ); assertNotNull( injector ); TestCmp13 cmp = nci.getSupplier( ).get( ); TestCmp1 inject = new TestCmp1( ); injector.accept( cmp , inject ); assertSame( inject , cmp.dependency ); } /** * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with an interface-defined dependency * injection method */ @Test public void testFromClass14( ) { NewComponentInfo< TestCmp14 > nci = NewComponentInfo.fromClass( TestCmp14.class ); DependencyInfo expectedDep = new DependencyInfo( "TestCmp1" ); HashSet< DependencyInfo > deps = nci.getDependencies( ); assertEquals( 1 , deps.size( ) ); assertTrue( deps.contains( expectedDep ) ); HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( ); assertEquals( 1 , injectors.size( ) ); ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep ); assertEquals( 1 , diList.size( ) ); ThrowingBiConsumer< ? super TestCmp14 , Object > injector = diList.get( 0 ); assertNotNull( injector ); TestCmp14 cmp = nci.getSupplier( ).get( ); TestCmp1 inject = new TestCmp1( ); injector.accept( cmp , inject ); assertSame( inject , cmp.dependency ); } /** * Test: {@link NewComponentInfo#scanPackage(String, boolean)} finds a simple {@link Component}-annotated class */ @Test public void testScanPackageSimple( ) throws ComponentDefinitionException , ClassNotFoundException , IOException { ArrayList< NewComponentInfo< ? > > result = NewComponentInfo.scanPackage( "test.simple" , false ); assertEquals( 1 , result.size( ) ); assertSame( CSimple.class , result.get( 0 ).getSupplier( ).get( ).getClass( ) ); } /** * Test: {@link NewComponentInfo#scanPackage(String, boolean)} finds components that inherit each other, ignoring * abstract classes */ @Test public void testScanPackageInheritance( ) throws ComponentDefinitionException , ClassNotFoundException , IOException { ArrayList< NewComponentInfo< ? > > result = NewComponentInfo.scanPackage( "test.inherited" , false ); assertEquals( 3 , result.size( ) ); Set< ? > classes = result.stream( ).map( x -> x.getSupplier( ).get( ).getClass( ) ) .collect( Collectors.toSet( ) ); assertTrue( classes.contains( CBase.class ) ); assertTrue( classes.contains( CChild.class ) ); assertTrue( classes.contains( CChildOfAbstract.class ) ); } /** * Test: {@link NewComponentInfo#scanPackage(String, boolean)} finds components defined by implementing a * {@link Component}-annotated interface */ @Test public void testScanPackageInterfaces( ) throws ComponentDefinitionException , ClassNotFoundException , IOException { ArrayList< NewComponentInfo< ? > > result = NewComponentInfo.scanPackage( "test.interfaces" , false ); assertEquals( 1 , result.size( ) ); assertSame( CImplementation.class , result.get( 0 ).getSupplier( ).get( ).getClass( ) ); } }