package org.rocket.network.guice;

import com.google.inject.Guice;
import com.google.inject.Injector;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.rocket.network.Controller;
import org.rocket.network.ControllerFactory;
import org.rocket.network.NetworkClient;

import javax.inject.Inject;
import java.util.Iterator;
import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;

public class ControllerModuleTest {

    @Inject ControllerFactory factory;

    @Controller
    public static class TheController {
        @Inject NetworkClient client;
        @Inject Helper helper;
    }

    @Controller
    public static class AnotherController {
        @Inject NetworkClient client;
    }

    public static class Helper {
        @Inject NetworkClient client;
    }

    @Before
    public void setUp() throws Exception {
        Injector injector = Guice.createInjector(
                new ControllerFactoryModule(),
                new ControllerModule() {
                    @Override
                    protected void configure() {
                        newController().to(TheController.class);
                    }
                },
                new ControllerModule() {
                    @Override
                    protected void configure() {
                        newController().to(AnotherController.class);
                    }
                }
        );
        injector.injectMembers(this);
    }

    @After
    public void tearDown() throws Exception {
        factory = null;
    }

    @Test
    public void testCreateControllers() throws Exception {
        // given
        NetworkClient client = mock(NetworkClient.class);

        // when
        Set<Object> controllers = factory.create(client);

        // then
        assertEquals("number of controllers", 2, controllers.size());

        Iterator<Object> it = controllers.iterator();

        TheController controller = (TheController) it.next();
        assertEquals("controller's client", client, controller.client);
        assertEquals("controller's helper's client", client, controller.helper.client);

        AnotherController anotherController = (AnotherController) it.next();
        assertEquals("another controller's client", client, anotherController.client);
    }
}
@@ -197,184 +197,189 @@
 ork.
-Controller;%0Aimport org.rocket.network.ControllerFactory;%0Aimport org.rocket.network.NetworkClient;%0A%0Aimport javax.inject.Injec
+*;%0A%0Aimport javax.inject.Inject;%0Aimport java.util.Iterator;%0Aimport java.util.Se
 t;%0A
+%0A
 import 
-java.util.Iterator;%0Aimport java.util.Set;%0A
+static org.hamcrest.CoreMatchers.equalTo;%0Aimport static org.hamcrest.CoreMatchers.nullValue;
 %0Aimp
@@ -420,16 +420,59 @@
 Equals;%0A
+import static org.junit.Assert.assertThat;%0A
 import s
@@ -671,24 +671,62 @@
 ent client;%0A
+        @Inject MutProp%3CString%3E name;%0A
         @Inj
@@ -841,32 +841,67 @@
 kClient client;%0A
+        @Inject Prop%3CString%3E name;%0A
     %7D%0A%0A    publi
@@ -2464,20 +2464,439 @@
 ler.client);
+%0A%0A        assertThat(%22controller prop 'name'%22, controller.name.orNull(), nullValue());%0A        assertThat(%22another controller prop 'name'%22, anotherController.name.orEmpty(), nullValue());%0A%0A        controller.name.set(%22foobar%22);%0A%0A        assertThat(%22controller prop 'name'%22, controller.name.get(), equalTo(%22foobar%22));%0A        assertThat(%22another controller prop 'name'%22, anotherController.name.get(), equalTo(%22foobar%22));
 %0A    %7D%0A%7D

Test Prop/MutProp injection