package com.mobilesolutionworks.android.app.test;

import android.app.Activity;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.action.ViewActions;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import android.support.test.runner.lifecycle.Stage;
import android.support.v4.app.Fragment;
import android.view.Surface;
import android.view.View;

import com.linkedin.android.testbutler.TestButler;

import junit.framework.Assert;

import org.hamcrest.Matcher;
import org.junit.Rule;
import org.junit.Test;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
import static android.support.test.espresso.matcher.ViewMatchers.withId;

/**
 * Created by yunarta on 9/3/17.
 */

public class RetainChildFragmentTest {

    @Rule
    public ActivityTestRule<RetainChildFragmentActivity> mActivityTestRule = new ActivityTestRule<>(RetainChildFragmentActivity.class);

    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        final AtomicReference<Integer> rootFragmentHash = new AtomicReference<>();
        final AtomicReference<Integer> childFragmentHash = new AtomicReference<>();

        onView(isRoot()).perform(new ViewAction() {
            @Override
            public Matcher<View> getConstraints() {
                return isRoot();
            }

            @Override
            public String getDescription() {
                return null;
            }

            @Override
            public void perform(UiController uiController, View view) {
                ArrayList<Activity> resumedActivities = new ArrayList<>(ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED));
                if (resumedActivities.isEmpty()) {
                    throw new RuntimeException("Could not change orientation");
                }

                RetainChildFragmentActivity activity = (RetainChildFragmentActivity) resumedActivities.get(0);
                Fragment rootFragment = activity.getSupportFragmentManager().findFragmentById(R.id.fragment_container);
                Assert.assertNotNull(rootFragment);
                rootFragmentHash.set(System.identityHashCode(rootFragment));

                Fragment child = rootFragment.getChildFragmentManager().findFragmentByTag("child");
                Assert.assertNotNull(child);
                childFragmentHash.set(System.identityHashCode(child));
            }
        });

        onView(withId(R.id.button)).perform(ViewActions.click());
        Thread.sleep(1);

        TestButler.setRotation(Surface.ROTATION_90);
        Thread.sleep(1);

        TestButler.setRotation(Surface.ROTATION_0);
        Thread.sleep(1);

        pressBack();
        Thread.sleep(1);

        onView(isRoot()).perform(new ViewAction() {
            @Override
            public Matcher<View> getConstraints() {
                return isRoot();
            }

            @Override
            public String getDescription() {
                return null;
            }

            @Override
            public void perform(UiController uiController, View view) {
                ArrayList<Activity> resumedActivities = new ArrayList<>(ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED));
                if (resumedActivities.isEmpty()) {
                    throw new RuntimeException("Could not change orientation");
                }

                RetainChildFragmentActivity activity = (RetainChildFragmentActivity) resumedActivities.get(0);
                Fragment rootFragment = activity.getSupportFragmentManager().findFragmentById(R.id.fragment_container);
                Assert.assertNotNull(rootFragment);
                Assert.assertEquals(rootFragmentHash.get(), Integer.valueOf(System.identityHashCode(rootFragment)));

                Fragment child = rootFragment.getChildFragmentManager().findFragmentByTag("child");
                Assert.assertNotNull(child);
                Assert.assertNotSame("If this is equals, then Android Support solved this problem", childFragmentHash.get(), Integer.valueOf(System.identityHashCode(child)));
            }
        });
    }

}

@@ -1353,16 +1353,95 @@
 r test.%0A
+        final AtomicReference%3CInteger%3E activityHash = new AtomicReference%3C%3E();%0A
         
@@ -2139,157 +2139,8 @@
 D));
-%0A                if (resumedActivities.isEmpty()) %7B%0A                    throw new RuntimeException(%22Could not change orientation%22);%0A                %7D
 %0A%0A  
@@ -2240,32 +2240,102 @@
 ivities.get(0);%0A
+                activityHash.set(System.identityHashCode(activity));%0A%0A
                 
@@ -3639,24 +3639,25 @@
 .RESUMED));%0A
+%0A
             
@@ -3664,12 +3664,77 @@
     
-if (
+RetainChildFragmentActivity activity = (RetainChildFragmentActivity) 
 resu
@@ -3751,20 +3751,15 @@
 ies.
-isEmpty()) %7B
+get(0);
 %0A   
@@ -3775,38 +3775,28 @@
     
-    throw new RuntimeException
+Assert.assertNotSame
 (%22Co
@@ -3826,141 +3826,84 @@
 ion%22
-);%0A                %7D%0A%0A                RetainChildFragmentActivity activity = (RetainChildFragmentActivity) resumedActivities.get(0
+, activityHash.get(), Integer.valueOf(System.identityHashCode(activity))
 );%0A
+%0A
     

Add proof of rotation as part of this test as well