package com.android21buttons.fragmenttestrule;

import android.support.test.rule.ActivityTestRule;
import android.support.v4.app.Fragment;
import android.util.Log;

/**
 * This rule provides functional testing of a single fragment.
 *
 * Idea extracted from: http://stackoverflow.com/a/38393087/842697
 *
 * @param <F> the Fragment to test
 */
public class FragmentTestRule<F extends Fragment> extends ActivityTestRule<TestActivity> {
    private static final String TAG = "FragmentTestRule";

    private final Class<F> fragmentClass;
    private F fragment;

    public FragmentTestRule(Class<F> fragmentClass) {
        this(fragmentClass, false);
    }

    public FragmentTestRule(Class<F> fragmentClass, boolean initialTouchMode) {
        this(fragmentClass, initialTouchMode, true);
    }

    public FragmentTestRule(Class<F> fragmentClass, boolean initialTouchMode, boolean launchActivity) {
        super(TestActivity.class, initialTouchMode, launchActivity);
        this.fragmentClass = fragmentClass;
    }

    @Override
    protected void afterActivityLaunched() {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                FragmentTestRule.this.fragment = createFragment();
                getActivity().getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.fragmentTestRule_fForFragment, fragment)
                    .commit();
            }
        });
    }

    @SuppressWarnings("unchecked")
    protected F createFragment() {
        try {
            return (F) fragmentClass.newInstance();
        } catch (InstantiationException e) {
            throw new AssertionError(String.format("%s: Could not insert %s into %s: %s",
                getClass().getSimpleName(),
                fragmentClass.getSimpleName(),
                TestActivity.class.getSimpleName(),
                e.getMessage()));
        } catch (IllegalAccessException e) {
            throw new AssertionError(String.format("%s: Could not insert %s into %s: %s",
                getClass().getSimpleName(),
                fragmentClass.getSimpleName(),
                TestActivity.class.getSimpleName(),
                e.getMessage()));
        }
    }


    public F getFragment() {
        if (fragment == null) {
            Log.w(TAG, "Fragment wasn't created yet");
        }
        return fragment;
    }
}

@@ -227,16 +227,20 @@
 ment.%0A *
+ %3Cp%3E
 %0A * Idea
@@ -371,16 +371,40 @@
 estRule%3C
+A extends TestActivity, 
 F extend
@@ -440,28 +440,17 @@
 estRule%3C
-TestActivity
+A
 %3E %7B%0A    
@@ -586,366 +586,1558 @@
 lic 
-FragmentTestRule(Class%3CF%3E fragmentClass) %7B%0A        this(fragmentClass, false);%0A    %7D%0A%0A    public FragmentTestRule(Class%3CF%3E fragmentClass, boolean initialTouchMode) %7B%0A        this(fragmentClass, initialTouchMode, true);%0A    %7D%0A%0A    public FragmentTestRule(Class%3CF%3E fragmentClass, boolean initialTouchMode, boolean launchActivity) %7B%0A        super(TestActivity.c
+static %3CF extends Fragment%3E FragmentTestRule%3CTestActivity, F%3E create(Class%3CF%3E fragmentClass) %7B%0A        return create(TestActivity.class, fragmentClass);%0A    %7D%0A%0A    public static %3CF extends Fragment%3E FragmentTestRule%3CTestActivity, F%3E create(Class%3CF%3E fragmentClass, boolean initialTouchMode) %7B%0A        return create(TestActivity.class, fragmentClass, initialTouchMode);%0A    %7D%0A%0A    public static %3CF extends Fragment%3E FragmentTestRule%3CTestActivity, F%3E create(Class%3CF%3E fragmentClass, boolean initialTouchMode, boolean launchActivity) %7B%0A        return create(TestActivity.class, fragmentClass, initialTouchMode, launchActivity);%0A    %7D%0A%0A    public static %3CA extends TestActivity, F extends Fragment%3E FragmentTestRule%3CA, F%3E create(Class%3CA%3E activityClass, Class%3CF%3E fragmentClass) %7B%0A        return create(activityClass, fragmentClass, false);%0A    %7D%0A%0A    public static %3CA extends TestActivity, F extends Fragment%3E FragmentTestRule%3CA, F%3E create(Class%3CA%3E activityClass, Class%3CF%3E fragmentClass, boolean initialTouchMode) %7B%0A        return create(activityClass, fragmentClass, initialTouchMode, true);%0A    %7D%0A%0A    public static %3CA extends TestActivity, F extends Fragment%3E FragmentTestRule%3CA, F%3E create(Class%3CA%3E activityClass, Class%3CF%3E fragmentClass, boolean initialTouchMode, boolean launchActivity) %7B%0A        return new FragmentTestRule%3C%3E(activityClass, fragmentClass, initialTouchMode, launchActivity);%0A    %7D%0A%0A    protected FragmentTestRule(Class%3CA%3E activityClass, Class%3CF%3E fragmentClass, boolean initialTouchMode, boolean launchActivity) %7B%0A        super(activityC
 lass
@@ -2535,16 +2535,20 @@
         
+   
+ 
 .beginTr
@@ -2559,16 +2559,20 @@
 ction()%0A
+    
         
@@ -2658,16 +2658,20 @@
         
+    
 .commit(
@@ -2710,43 +2710,8 @@
  %7D%0A%0A
-    @SuppressWarnings(%22unchecked%22)%0A
     
@@ -2777,12 +2777,8 @@
 turn
- (F)
  fra
@@ -2946,32 +2946,36 @@
                 
+    
 getClass().getSi
@@ -2978,32 +2978,36 @@
 etSimpleName(),%0A
+    
                 
@@ -3029,32 +3029,36 @@
 etSimpleName(),%0A
+    
                 
@@ -3101,32 +3101,36 @@
                 
+    
 e.getMessage()))
@@ -3274,32 +3274,36 @@
                 
+    
 getClass().getSi
@@ -3306,32 +3306,36 @@
 etSimpleName(),%0A
+    
                 
@@ -3373,32 +3373,36 @@
                 
+    
 TestActivity.cla
@@ -3413,32 +3413,36 @@
 etSimpleName(),%0A
+    
                 
@@ -3476,17 +3476,16 @@
 %0A    %7D%0A%0A
-%0A
     publ

Create any kind of Activity