package de.akquinet.jbosscc.needle.postconstruct;

import static org.junit.Assert.assertNotNull;

import java.util.HashSet;

import javax.annotation.PostConstruct;

import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;

import de.akquinet.jbosscc.needle.annotation.ObjectUnderTest;
import de.akquinet.jbosscc.needle.reflection.ReflectionUtil;

/**
 * 
 * @author Jan Galinski, Holisticon AG (jan.galinski@holisticon.de)
 * 
 */
public class PostConstructProcessorTest {

    Runnable runnableMock = EasyMock.createStrictMock(Runnable.class);

    /**
     * a dummy class without init()
     */
    public class A {
    }

    /**
     * a dummy class with init()
     */
    public class B extends A {

        @PostConstruct
        public void init() {
            runnableMock.run();
        }

    }

    private static final HashSet<Class<?>> ANNOTATIONS = new HashSet<Class<?>>();

    static {
        ANNOTATIONS.add(PostConstruct.class);
    }

    private final PostConstructProcessor postConstructProcessor = new PostConstructProcessor(ANNOTATIONS);

    // This Processor test does not use the NeeldeRule!
    @ObjectUnderTest(postConstruct = true)
    private A isConfiguredForPostConstructionButDoesNotContainMethod = new A();

    // This Processor test does not use the NeeldeRule!
    @ObjectUnderTest(postConstruct = true)
    private B isConfiguredForPostConstruction = new B();

    // This Processor test does not use the NeeldeRule!
    @ObjectUnderTest
    private B isNotConfiguredForPostConstruction = new B();

    @Before
    public void setUp() {
        assertNotNull(postConstructProcessor);
    }

    @Test
    public void testWithoutPostConstructMethod() throws Exception {
        EasyMock.replay(runnableMock);
        postConstructProcessor.process(
                getObjectUnderTestAnnotation("isConfiguredForPostConstructionButDoesNotContainMethod"),
                isConfiguredForPostConstructionButDoesNotContainMethod);
        EasyMock.verify(runnableMock);
    }

    @Test
    public void testWithPostConstructMethod() throws Exception {
        runnableMock.run();
        EasyMock.replay(runnableMock);
        postConstructProcessor.process(getObjectUnderTestAnnotation("isConfiguredForPostConstruction"),
                isConfiguredForPostConstruction);
        EasyMock.verify(runnableMock);

    }
    
    @Test
    public void testWithPostConstructMethod_NotConfigured() throws Exception {
        EasyMock.replay(runnableMock);
        postConstructProcessor.process(
                getObjectUnderTestAnnotation("isNotConfiguredForPostConstruction"),
                isNotConfiguredForPostConstruction);
        EasyMock.verify(runnableMock);
    }

    private ObjectUnderTest getObjectUnderTestAnnotation(final String fieldname) {
        return ReflectionUtil.getField(getClass(), fieldname).getAnnotation(ObjectUnderTest.class);
    }

}
@@ -365,20 +365,16 @@
 l;%0A%0A/**%0A
- * %0A
  * @auth
@@ -437,12 +437,8 @@
 de)%0A
- * %0A
  */%0A
@@ -484,16 +484,24 @@
  %7B%0A%0A    
+private 
 Runnable
@@ -558,16 +558,101 @@
 .class);
+%0A    private Runnable secondRunnableMock = EasyMock.createStrictMock(Runnable.class);
 %0A%0A    /*
@@ -717,21 +717,16 @@
 lass A %7B
-%0A    
 %7D%0A%0A    /
@@ -895,32 +895,222 @@
       %7D%0A%0A    %7D%0A%0A
+    /**%0A     * a dummy class with init()%0A     */%0A    public class C extends B %7B%0A%0A        @PostConstruct%0A        public void initC() %7B%0A            secondRunnableMock.run();%0A        %7D%0A%0A    %7D%0A%0A
     private stat
@@ -1821,24 +1821,196 @@
 = new B();%0A%0A
+    // This Processor test does not use the NeeldeRule!%0A    @ObjectUnderTest(postConstruct = true)%0A    private C instanceAndParentClassHavePostconstructMethods = new C();%0A%0A
     @Before%0A
@@ -2811,20 +2811,16 @@
 %0A%0A    %7D%0A
-    
 %0A    @Te
@@ -3155,32 +3155,494 @@
 leMock);%0A    %7D%0A%0A
+    @Test%0A    public void shouldCallPostConstructOnInstanceAndParent() throws Exception %7B%0A        runnableMock.run();%0A        secondRunnableMock.run();%0A        EasyMock.replay(runnableMock, secondRunnableMock);%0A%0A        postConstructProcessor.process(getObjectUnderTestAnnotation(%22instanceAndParentClassHavePostconstructMethods%22),%0A                instanceAndParentClassHavePostconstructMethods);%0A        EasyMock.verify(runnableMock, secondRunnableMock);%0A    %7D%0A%0A
     private Obje
@@ -3816,8 +3816,9 @@
     %7D%0A%0A%7D
+%0A

Test that verifies that multiple @PostConstruct methods are called.