package roboguice.view; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.lang.ref.SoftReference; import java.util.ArrayList; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.util.ActivityController; import roboguice.RoboGuice; import roboguice.activity.RoboActivity; import roboguice.inject.InjectView; import com.google.inject.Inject; import android.content.Context; import android.os.Bundle; import android.view.View; import android.widget.LinearLayout; @RunWith(RobolectricTestRunner.class) public class ViewInjectionTest { @Test public void shouldInjectViewsIntoActivitiesAndViews() { final C activity = Robolectric.buildActivity(C.class).create().get(); assertThat(activity.v, equalTo((View)activity.ref)); assertThat(activity.v.w, equalTo(activity.v.ref)); } @Test public void shouldBeAbleToInjectViewsIntoPojos() { final B activity = Robolectric.buildActivity(B.class).create().get(); assertThat(activity.a.v,equalTo(activity.ref)); } @Test public void shouldNotHoldReferencesToContext() { ActivityController<A> controller= Robolectric.buildActivity(A.class).create(); final SoftReference<A> activityRef = new SoftReference<A>(controller.get()); assertThat(activityRef.get(), not(equalTo(null))); assertThat(activityRef.get().v, not(equalTo(null))); controller.destroy(); //noinspection UnusedAssignment controller=null; // Force an OoM // http://stackoverflow.com/questions/3785713/how-to-make-the-java-system-release-soft-references/3810234 boolean oomHappened = false; try { @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) final ArrayList<Object[]> allocations = new ArrayList<Object[]>(); int size; while( (size = Math.min(Math.abs((int)Runtime.getRuntime().freeMemory()),Integer.MAX_VALUE))>0 ) allocations.add( new Object[size] ); } catch( OutOfMemoryError e ) { // great! oomHappened = true; } assertTrue(oomHappened); assertThat(activityRef.get(), equalTo(null)); } @Ignore("getWindow().getDecoreView() doesn't seem to return the root view in robolectric?") @Test public void shouldBeAbleToInjectReferencesToTaggedViews() { final D activity = Robolectric.buildActivity(D.class).create().get(); assertThat(activity.v, equalTo((View)activity.ref)); assertThat(activity.v.w, equalTo(activity.v.ref)); } public static class A extends RoboActivity { @InjectView(100) protected View v; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final View x = new View(this); x.setId(100); setContentView(x); } } public static class B extends RoboActivity { @Inject PojoA a; View ref; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ref = new View(this); ref.setId(100); setContentView(ref); } public static class PojoA { @InjectView(100) View v; } } public static class C extends RoboActivity { @InjectView(100) ViewA v; LinearLayout ref; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ref = new ViewA(this); ref.setId(100); setContentView(ref); } public static class ViewA extends LinearLayout { @InjectView(101) View w; View ref; public ViewA(Context context) { super(context); ref = new View(getContext()); ref.setId(101); addView(ref); RoboGuice.getInjector(getContext()).injectMembers(this); RoboGuice.getInjector(getContext()).injectViewMembers(this); } } } public static class D extends RoboActivity { @InjectView(tag="100") ViewA v; LinearLayout ref; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ref = new ViewA(this); ref.setTag("100"); setContentView(ref); } public static class ViewA extends LinearLayout { @InjectView(tag="101") View w; View ref; public ViewA(Context context) { super(context); ref = new View(getContext()); ref.setTag("101"); addView(ref); RoboGuice.getInjector(getContext()).injectMembers(this); } } } }