Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 094f7ddf authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Try to add some more documentation to testables"

parents 8a3e865c 0c408008
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@ public class TileServicesTest extends SysuiTestCase {

    @Before
    public void setUp() throws Exception {
        TestableLooper.get(this).setAsMainLooper();
        mManagers = new ArrayList<>();
        QSTileHost host = new QSTileHost(mContext, null,
                mock(StatusBarIconController.class));
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ import java.util.List;

/**
 * A runner with support for extra annotations provided by the Testables library.
 * @see UiThreadTest
 * @see TestableLooper.RunWithLooper
 */
public class AndroidTestingRunner extends BlockJUnit4ClassRunner {

+4 −0
Original line number Diff line number Diff line
@@ -80,6 +80,10 @@ public abstract class BaseFragmentTest {
        });
    }

    /**
     * Allows tests to sub-class TestableContext if they want to provide any extended functionality
     * or provide a {@link LeakCheck} to the TestableContext upon instantiation.
     */
    protected TestableContext getContext() {
        return new TestableContext(InstrumentationRegistry.getContext());
    }
+57 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@

package android.testing;

import android.content.Context;
import android.util.ArrayMap;
import android.util.Log;

@@ -28,6 +29,35 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Utility for dealing with the facts of Lifecycle. Creates trackers to check that for every
 * call to registerX, addX, bindX, a corresponding call to unregisterX, removeX, and unbindX
 * is performed. This should be applied to a test as a {@link org.junit.rules.TestRule}
 * and will only check for leaks on successful tests.
 * <p>
 * Example that will catch an allocation and fail:
 * <pre class="prettyprint">
 * public class LeakCheckTest {
 *    &#064;Rule public LeakCheck mLeakChecker = new LeakCheck();
 *
 *    &#064;Test
 *    public void testLeak() {
 *        Context context = new ContextWrapper(...) {
 *            public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
 *                mLeakChecker.getTracker("receivers").addAllocation(new Throwable());
 *            }
 *            public void unregisterReceiver(BroadcastReceiver receiver) {
 *                mLeakChecker.getTracker("receivers").clearAllocations();
 *            }
 *        };
 *        context.registerReceiver(...);
 *    }
 *  }
 * </pre>
 *
 * Note: {@link TestableContext} supports leak tracking when using
 * {@link TestableContext#TestableContext(Context, LeakCheck)}.
 */
public class LeakCheck extends TestWatcher {

    private final Map<String, Tracker> mTrackers = new HashMap<>();
@@ -40,6 +70,13 @@ public class LeakCheck extends TestWatcher {
        verify();
    }

    /**
     * Acquire a {@link Tracker}. Gets a tracker for the specified tag, creating one if necessary.
     * There should be one tracker for each pair of add/remove callbacks (e.g. one tracker for
     * registerReceiver/unregisterReceiver).
     *
     * @param tag Unique tag to use for this set of allocation tracking.
     */
    public Tracker getTracker(String tag) {
        Tracker t = mTrackers.get(tag);
        if (t == null) {
@@ -49,10 +86,13 @@ public class LeakCheck extends TestWatcher {
        return t;
    }

    public void verify() {
    private void verify() {
        mTrackers.values().forEach(Tracker::verify);
    }

    /**
     * Holds allocations associated with a specific callback (such as a BroadcastReceiver).
     */
    public static class LeakInfo {
        private static final String TAG = "LeakInfo";
        private List<Throwable> mThrowables = new ArrayList<>();
@@ -60,11 +100,20 @@ public class LeakCheck extends TestWatcher {
        LeakInfo() {
        }

        /**
         * Should be called once for each callback/listener added. addAllocation may be
         * called several times, but it only takes one clearAllocations call to remove all
         * of them.
         */
        public void addAllocation(Throwable t) {
            // TODO: Drop off the first element in the stack trace here to have a cleaner stack.
            mThrowables.add(t);
        }

        /**
         * Should be called when the callback/listener has been removed. One call to
         * clearAllocations will counteract any number of calls to addAllocation.
         */
        public void clearAllocations() {
            mThrowables.clear();
        }
@@ -82,9 +131,16 @@ public class LeakCheck extends TestWatcher {
        }
    }

    /**
     * Tracks allocations related to a specific tag or method(s).
     * @see #getTracker(String)
     */
    public static class Tracker {
        private Map<Object, LeakInfo> mObjects = new ArrayMap<>();

        private Tracker() {
        }

        public LeakInfo getLeakInfo(Object object) {
            LeakInfo leakInfo = mObjects.get(object);
            if (leakInfo == null) {
+5 −1
Original line number Diff line number Diff line
@@ -27,7 +27,11 @@ import com.google.android.collect.Maps;
import java.util.Map;

/**
 * Alternative to a MockContentResolver that falls back to real providers.
 * A version of ContentResolver that allows easy mocking of providers.
 * By default it acts as a normal ContentResolver and returns all the
 * same providers.
 * @see #addProvider(String, ContentProvider)
 * @see #setFallbackToExisting(boolean)
 */
public class TestableContentResolver extends ContentResolver {

Loading