package com.episode6.hackit.mockspresso.internal;

import com.episode6.hackit.mockspresso.DefaultTestRunner;
import com.episode6.hackit.mockspresso.api.DependencyProvider;
import com.episode6.hackit.mockspresso.reflect.DependencyKey;
import com.episode6.hackit.mockspresso.reflect.TypeToken;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import javax.inject.Provider;

import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

/**
 * Tests {@link MockspressoImpl}
 */
@RunWith(DefaultTestRunner.class)
public class MockspressoImplTest {

  @Mock MockspressoConfigContainer mConfig;
  @Mock DependencyProviderFactory mDependencyProviderFactory;
  @Mock RealObjectMaker mRealObjectMaker;
  @Mock DependencyProvider mDependencyProvider;

  @Mock Provider<MockspressoBuilderImpl> mBuilderProvider;
  @Mock MockspressoBuilderImpl mBuilder;

  MockspressoImpl mMockspresso;

  @Before
  public void setup() {
    MockitoAnnotations.initMocks(this);

    when(mDependencyProviderFactory.getDependencyProviderFor(any(DependencyKey.class))).thenReturn(mDependencyProvider);
    when(mBuilderProvider.get()).thenReturn(mBuilder);

    mMockspresso = new MockspressoImpl(mConfig, mDependencyProviderFactory, mRealObjectMaker, mBuilderProvider);
  }

  @Test
  public void testBasicUsage() {
    mMockspresso.create(String.class);
    mMockspresso.create(TypeToken.of(Integer.class));
    mMockspresso.buildUpon();
    MockspressoConfigContainer configContainer = mMockspresso.getConfig();

    InOrder inOrder = Mockito.inOrder(mDependencyProviderFactory, mRealObjectMaker, mBuilderProvider, mBuilder);
    inOrder.verify(mDependencyProviderFactory).getDependencyProviderFor(DependencyKey.of(String.class));
    inOrder.verify(mRealObjectMaker).createObject(mDependencyProvider, TypeToken.of(String.class));
    inOrder.verify(mDependencyProviderFactory).getDependencyProviderFor(DependencyKey.of(Integer.class));
    inOrder.verify(mRealObjectMaker).createObject(mDependencyProvider, TypeToken.of(Integer.class));
    inOrder.verify(mBuilderProvider).get();
    inOrder.verify(mBuilder).setParent(mConfig);
    inOrder.verifyNoMoreInteractions();

    assertThat(configContainer).isEqualTo(mConfig);
  }
}

@@ -1077,16 +1077,48 @@
 ilder;%0A%0A
+  Object thing = new Object();%0A%0A
   Mocksp
@@ -1141,16 +1141,16 @@
 presso;%0A
-
 %0A  @Befo
@@ -1334,24 +1334,123 @@
 yProvider);%0A
+    when(mDependencyProviderFactory.getBlankDependencyProvider()).thenReturn(mDependencyProvider);%0A
     when(mBu
@@ -1741,24 +1741,120 @@
 er.class));%0A
+    mMockspresso.inject(thing);%0A    mMockspresso.getDependency(DependencyKey.of(String.class));%0A
     mMockspr
@@ -2057,19 +2057,41 @@
 mBuilder
+, mDependencyProvider
 );%0A
+%0A
     inOr
@@ -2279,32 +2279,33 @@
 String.class));%0A
+%0A
     inOrder.veri
@@ -2386,32 +2386,32 @@
 nteger.class));%0A
-
     inOrder.veri
@@ -2487,32 +2487,373 @@
 nteger.class));%0A
+%0A    inOrder.verify(mDependencyProviderFactory).getDependencyProviderFor(DependencyKey.of(Object.class));%0A    inOrder.verify(mRealObjectMaker).injectObject(mDependencyProvider, thing);%0A%0A    inOrder.verify(mDependencyProviderFactory).getBlankDependencyProvider();%0A    inOrder.verify(mDependencyProvider).get(DependencyKey.of(String.class));%0A%0A
     inOrder.veri

test `inject()` and `getDependenccy()` in unit test