Bug 1442243 - 6. Add BaseSessionTest; r?snorp draft
authorJim Chen <nchen@mozilla.com>
Wed, 07 Mar 2018 16:12:51 -0500
changeset 764515 6d586babf5da3eaab4fd52f2fd56908d15edc801
parent 764514 52664740ae6ad218f3bc41e80124ff4e3fe88c03
child 764516 e91c90fec686e47304761faca3b5f62ec3980af4
push id101776
push userbmo:nchen@mozilla.com
push dateWed, 07 Mar 2018 21:13:11 +0000
reviewerssnorp
bugs1442243
milestone60.0a1
Bug 1442243 - 6. Add BaseSessionTest; r?snorp Add BaseSessionTest to provide some common boilerplate code, as well as Kotlin extension functions for operating on a GeckoSession. MozReview-Commit-ID: 73KTZN6Zo0K
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationListenerTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressListenerTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
@@ -0,0 +1,87 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+package org.mozilla.geckoview.test
+
+import android.os.Parcel
+import org.mozilla.geckoview.GeckoSession
+import org.mozilla.geckoview.test.rule.GeckoSessionTestRule
+
+import org.hamcrest.Matcher
+import org.hamcrest.Matchers
+import org.junit.Rule
+import org.junit.rules.ErrorCollector
+
+import kotlin.reflect.KClass
+
+/**
+ * Common base class for tests using GeckoSessionTestRule,
+ * providing the test rule and other utilities.
+ */
+open class BaseSessionTest(noErrorCollector: Boolean = false) {
+    companion object {
+        const val INVALID_URI = "http://www.test.invalid/"
+        const val HELLO_HTML_PATH = "/assets/www/hello.html"
+        const val HELLO2_HTML_PATH = "/assets/www/hello2.html"
+        const val NEW_SESSION_HTML_PATH = "/assets/www/newSession.html";
+        const val NEW_SESSION_CHILD_HTML_PATH = "/assets/www/newSession_child.html";
+    }
+
+    @get:Rule val sessionRule = GeckoSessionTestRule()
+
+    @get:Rule val errors = ErrorCollector()
+    fun <T> assertThat(reason: String, v: T, m: Matcher<T>) = sessionRule.assertThat(reason, v, m)
+
+    init {
+        if (!noErrorCollector) {
+            sessionRule.errorCollector = errors
+        }
+    }
+
+    fun GeckoSession.loadTestPath(path: String) =
+            this.loadUri(GeckoSessionTestRule.APK_URI_PREFIX + path.removePrefix("/"))
+
+    inline fun GeckoSession.toParcel(lambda: (Parcel) -> Unit) {
+        val parcel = Parcel.obtain()
+        try {
+            this.writeToParcel(parcel, 0)
+
+            val pos = parcel.dataPosition()
+            parcel.setDataPosition(0)
+
+            lambda(parcel)
+
+            assertThat("Read parcel matches written parcel",
+                       parcel.dataPosition(), Matchers.equalTo(pos))
+        } finally {
+            parcel.recycle()
+        }
+    }
+
+    fun GeckoSession.openWindow() =
+            sessionRule.openSession(this)
+
+    fun GeckoSession.waitForPageStop() =
+            sessionRule.waitForPageStop(this)
+
+    fun GeckoSession.waitForPageStops(count: Int) =
+            sessionRule.waitForPageStops(this, count)
+
+    fun GeckoSession.waitUntilCalled(ifce: KClass<*>, vararg methods: String) =
+            sessionRule.waitUntilCalled(this, ifce, *methods)
+
+    fun GeckoSession.waitUntilCalled(callback: Any) =
+            sessionRule.waitUntilCalled(this, callback)
+
+    fun GeckoSession.forCallbacksDuringWait(callback: Any) =
+            sessionRule.forCallbacksDuringWait(this, callback)
+
+    fun GeckoSession.delegateUntilTestEnd(callback: Any) =
+            sessionRule.delegateUntilTestEnd(this, callback)
+
+    fun GeckoSession.delegateDuringNextWait(callback: Any) =
+            sessionRule.delegateDuringNextWait(this, callback)
+
+    fun GeckoSession.synthesizeTap(x: Int, y: Int) =
+            sessionRule.synthesizeTap(this, x, y)
+}
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
@@ -10,42 +10,28 @@ import org.mozilla.geckoview.test.rule.G
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.Setting
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.TimeoutMillis
 import org.mozilla.geckoview.test.util.Callbacks
 
 import android.support.test.filters.LargeTest
 import android.support.test.filters.MediumTest
 import android.support.test.runner.AndroidJUnit4
 
-import org.hamcrest.Matcher
 import org.hamcrest.Matchers.*
-import org.junit.Rule
 import org.junit.Test
-import org.junit.rules.ErrorCollector
 import org.junit.runner.RunWith
 
-fun GeckoSession.loadTestPath(path: String) =
-        this.loadUri(GeckoSessionTestRule.APK_URI_PREFIX + path.removePrefix("/"))
-
 /**
  * Test for the GeckoSessionTestRule class, to ensure it properly sets up a session for
  * each test, and to ensure it can properly wait for and assert delegate
  * callbacks.
  */
 @RunWith(AndroidJUnit4::class)
 @MediumTest
-class GeckoSessionTestRuleTest {
-    companion object {
-        const val HELLO_HTML_PATH = "assets/www/hello.html"
-    }
-
-    @get:Rule val sessionRule = GeckoSessionTestRule()
-
-    @get:Rule val errors = ErrorCollector()
-    fun <T> assertThat(reason: String, v: T, m: Matcher<T>) = errors.checkThat(reason, v, m)
+class GeckoSessionTestRuleTest : BaseSessionTest(noErrorCollector = true) {
 
     @Test fun getSession() {
         assertThat("Can get session", sessionRule.session, notNullValue())
         assertThat("Session is open",
                    sessionRule.session.isOpen, equalTo(true))
     }
 
     @GeckoSessionTestRule.ClosedSessionAtStart
rename from mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationListenerTest.kt
rename to mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationListenerTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
@@ -1,46 +1,26 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 package org.mozilla.geckoview.test
 
 import org.mozilla.geckoview.GeckoSession
-import org.mozilla.geckoview.test.rule.GeckoSessionTestRule
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
 import org.mozilla.geckoview.test.util.Callbacks
 
 import android.support.test.filters.MediumTest
 import android.support.test.runner.AndroidJUnit4
-import org.hamcrest.Matcher
 import org.hamcrest.Matchers.*
-import org.junit.Before
-import org.junit.Rule
 import org.junit.Test
-import org.junit.rules.ErrorCollector
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
 @MediumTest
-class NavigationDelegateTest {
-    companion object {
-        const val HELLO_HTML_PATH = "/assets/www/hello.html";
-        const val HELLO2_HTML_PATH = "/assets/www/hello2.html";
-        const val NEW_SESSION_HTML_PATH = "/assets/www/newSession.html";
-        const val NEW_SESSION_CHILD_HTML_PATH = "/assets/www/newSession_child.html";
-    }
-
-    @get:Rule val sessionRule = GeckoSessionTestRule()
-
-    @get:Rule val errors = ErrorCollector()
-    fun <T> assertThat(reason: String, v: T, m: Matcher<T>) = errors.checkThat(reason, v, m)
-
-    @Before fun setUp() {
-        sessionRule.errorCollector = errors
-    }
+class NavigationDelegateTest : BaseSessionTest() {
 
     @Test fun load() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
 
         sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate {
             @AssertCalled(count = 1, order = intArrayOf(1))
             override fun onLoadUri(session: GeckoSession, uri: String,
@@ -223,44 +203,43 @@ class NavigationDelegateTest {
 
             @AssertCalled(count = 1, order = intArrayOf(2))
             override fun onPageStop(session: GeckoSession, success: Boolean) {
                 assertThat("Load should succeed", success, equalTo(true))
             }
         })
     }
 
-    @Test
     @GeckoSessionTestRule.WithDisplay(width = 128, height = 128)
-    fun onNewSession_calledForNewWindow() {
+    @Test fun onNewSession_calledForNewWindow() {
         sessionRule.session.loadTestPath(NEW_SESSION_HTML_PATH)
         sessionRule.waitForPageStop()
 
         sessionRule.delegateDuringNextWait(object : Callbacks.NavigationDelegate {
             @AssertCalled(count = 1)
             override fun onNewSession(session: GeckoSession, uri: String, response: GeckoSession.Response<GeckoSession>) {
                 response.respond(null)
             }
         })
 
         sessionRule.synthesizeTap(5, 5)
         sessionRule.waitUntilCalled(GeckoSession.NavigationDelegate::class, "onNewSession")
     }
 
+    @GeckoSessionTestRule.WithDisplay(width = 128, height = 128)
     @Test(expected = IllegalArgumentException::class)
-    @GeckoSessionTestRule.WithDisplay(width = 128, height = 128)
     fun onNewSession_doesNotAllowOpened() {
         sessionRule.session.loadTestPath(NEW_SESSION_HTML_PATH)
         sessionRule.waitForPageStop()
 
         sessionRule.delegateDuringNextWait(object : Callbacks.NavigationDelegate {
             @AssertCalled(count = 1)
             override fun onNewSession(session: GeckoSession, uri: String, response: GeckoSession.Response<GeckoSession>) {
                 var session = GeckoSession(session.settings)
                 session.openWindow(null)
                 response.respond(session)
             }
         })
 
         sessionRule.synthesizeTap(5, 5)
         sessionRule.waitUntilCalled(GeckoSession.NavigationDelegate::class, "onNewSession")
     }
-}
\ No newline at end of file
+}
rename from mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressListenerTest.kt
rename to mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressListenerTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt
@@ -1,47 +1,28 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 package org.mozilla.geckoview.test
 
 import org.mozilla.geckoview.GeckoSession
-import org.mozilla.geckoview.test.rule.GeckoSessionTestRule
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
 import org.mozilla.geckoview.test.util.Callbacks
 
 import android.support.test.filters.MediumTest
 import android.support.test.filters.LargeTest
 import android.support.test.runner.AndroidJUnit4
 
-import org.hamcrest.Matcher
 import org.hamcrest.Matchers.*
-import org.junit.Before
-import org.junit.Rule
 import org.junit.Test
-import org.junit.rules.ErrorCollector
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
 @MediumTest
-class ProgressDelegateTest {
-    companion object {
-        const val INVALID_URI = "http://www.test.invalid/"
-        const val HELLO_HTML_PATH = "/assets/www/hello.html";
-        const val HELLO2_HTML_PATH = "/assets/www/hello2.html";
-    }
-
-    @get:Rule val sessionRule = GeckoSessionTestRule()
-
-    @get:Rule val errors = ErrorCollector()
-    fun <T> assertThat(reason: String, v: T, m: Matcher<T>) = errors.checkThat(reason, v, m)
-
-    @Before fun setUp() {
-        sessionRule.errorCollector = errors
-    }
+class ProgressDelegateTest : BaseSessionTest() {
 
     @Test fun load() {
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStop()
 
         sessionRule.forCallbacksDuringWait(object : Callbacks.ProgressDelegate {
             @AssertCalled(count = 1, order = intArrayOf(1))
             override fun onPageStart(session: GeckoSession, url: String) {
@@ -224,9 +205,9 @@ class ProgressDelegateTest {
             }
 
             @AssertCalled(false)
             override fun onSecurityChange(session: GeckoSession,
                                           securityInfo: GeckoSession.ProgressDelegate.SecurityInformation) {
             }
         })
     }
-}
\ No newline at end of file
+}
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
@@ -547,29 +547,36 @@ public class GeckoSessionTestRule extend
      * Get the current ErrorCollector, or null if not using one.
      *
      * @return ErrorCollector or null.
      */
     public @Nullable ErrorCollector getErrorCollector() {
         return mErrorCollector;
     }
 
-    private <T> void assertThat(final String reason, final T value, final Matcher<T> matcher) {
+    /**
+     * Assert a condition with junit.Assert or an error collector.
+     *
+     * @param reason Reason string
+     * @param value Value to check
+     * @param matcher Matcher for checking the value
+     */
+    public <T> void assertThat(final String reason, final T value, final Matcher<T> matcher) {
         if (mErrorCollector != null) {
             mErrorCollector.checkThat(reason, value, matcher);
         } else {
             org.junit.Assert.assertThat(reason, value, matcher);
         }
     }
 
     private void assertAllowMoreCalls(final MethodCall call) {
         final int count = call.getCount();
         if (count != 0) {
             assertThat(call.method.getName() + " call count should be within limit",
-                       call.getCurrentCount(), lessThan(Math.max(0, count)));
+                       call.getCurrentCount() + 1, lessThanOrEqualTo(Math.max(0, count)));
         }
     }
 
     private void assertOrder(final MethodCall call, final int order) {
         final int newOrder = call.getOrder();
         if (newOrder != 0) {
             assertThat(call.method.getName() + " should be in order",
                        newOrder, greaterThanOrEqualTo(order));