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.
 * <p>
 * Idea extracted from: http://stackoverflow.com/a/38393087/842697
 *
 * @param <A> The activity where the fragment will be added
 * @param <F> The fragment to test
 */
public class FragmentTestRule<A extends TestActivity, F extends Fragment> extends ActivityTestRule<A> {
    private static final String TAG = "FragmentTestRule";

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

    public static <F extends Fragment> FragmentTestRule<TestActivity, F> create(Class<F> fragmentClass) {
        return create(TestActivity.class, fragmentClass);
    }

    public static <F extends Fragment> FragmentTestRule<TestActivity, F> create(Class<F> fragmentClass, boolean initialTouchMode) {
        return create(TestActivity.class, fragmentClass, initialTouchMode);
    }

    public static <F extends Fragment> FragmentTestRule<TestActivity, F> create(Class<F> fragmentClass, boolean initialTouchMode, boolean launchActivity) {
        return create(TestActivity.class, fragmentClass, initialTouchMode, launchActivity);
    }

    public static <A extends TestActivity, F extends Fragment> FragmentTestRule<A, F> create(Class<A> activityClass, Class<F> fragmentClass) {
        return create(activityClass, fragmentClass, false);
    }

    public static <A extends TestActivity, F extends Fragment> FragmentTestRule<A, F> create(Class<A> activityClass, Class<F> fragmentClass, boolean initialTouchMode) {
        return create(activityClass, fragmentClass, initialTouchMode, true);
    }

    public static <A extends TestActivity, F extends Fragment> FragmentTestRule<A, F> create(Class<A> activityClass, Class<F> fragmentClass, boolean initialTouchMode, boolean launchActivity) {
        return new FragmentTestRule<>(activityClass, fragmentClass, initialTouchMode, launchActivity);
    }

    protected FragmentTestRule(Class<A> activityClass, Class<F> fragmentClass, boolean initialTouchMode, boolean launchActivity) {
        super(activityClass, 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();
            }
        });
    }

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

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

@@ -640,81 +640,32 @@
    p
-ublic static %3CF extends Fragment%3E FragmentTestRule%3CTestActivity, F%3E creat
+rotected FragmentTestRul
 e(Cl
@@ -692,38 +692,40 @@
 ) %7B%0A        
-return create(
+this((Class%3CA%3E) 
 TestActivity
@@ -764,81 +764,32 @@
    p
-ublic static %3CF extends Fragment%3E FragmentTestRule%3CTestActivity, F%3E creat
+rotected FragmentTestRul
 e(Cl
@@ -842,38 +842,40 @@
 ) %7B%0A        
-return create(
+this((Class%3CA%3E) 
 TestActivity
@@ -932,81 +932,32 @@
    p
-ublic static %3CF extends Fragment%3E FragmentTestRule%3CTestActivity, F%3E creat
+rotected FragmentTestRul
 e(Cl
@@ -1038,30 +1038,32 @@
         
-return create(
+this((Class%3CA%3E) 
 TestActi
@@ -1140,65 +1140,16 @@
    p
-ublic static %3CA extends TestActivity, F extends Fragment%3E
+rotected
  Fra
@@ -1157,37 +1157,24 @@
 mentTestRule
-%3CA, F%3E create
 (Class%3CA%3E ac
@@ -1216,37 +1216,28 @@
 ) %7B%0A        
-return create
+this
 (activityCla
@@ -1279,65 +1279,16 @@
    p
-ublic static %3CA extends TestActivity, F extends Fragment%3E
+rotected
  Fra
@@ -1296,37 +1296,24 @@
 mentTestRule
-%3CA, F%3E create
 (Class%3CA%3E ac
@@ -1389,186 +1389,13 @@
     
-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 
+this(
 acti
@@ -1400,33 +1400,24 @@
 tivityClass,
- Class%3CF%3E
  fragmentCla
@@ -1415,32 +1415,24 @@
 agmentClass,
- boolean
  initialTouc
@@ -1442,134 +1442,12 @@
 de, 
-boolean launchActivity) %7B%0A        return new FragmentTestRule%3C%3E(activityClass, fragmentClass, initialTouchMode, launchActivity
+true
 );%0A 

Use constructor instead of creators