Bug 1474450 - 1. Add some tests for more GeckoResult behavior; r=snorp a=lizzard
authorJim Chen <nchen@mozilla.com>
Tue, 10 Jul 2018 13:12:55 -0400
changeset 477955 6055650e6d31
parent 477954 54ec00f46350
child 477956 94e6d8bb45e5
push id9475
push userarchaeopteryx@coole-files.de
push date2018-07-13 21:33 +0000
treeherdermozilla-beta@d7ab2f3df084 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp, lizzard
bugs1474450
milestone62.0
Bug 1474450 - 1. Add some tests for more GeckoResult behavior; r=snorp a=lizzard Add some tests for handling of uncaught exceptions, and tests for value and exception propagation. MozReview-Commit-ID: 4sEakRr1lLo
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoResultTest.java
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoResultTest.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoResultTest.java
@@ -1,33 +1,39 @@
 package org.mozilla.geckoview.test;
 
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
 import org.mozilla.geckoview.GeckoResult;
 import org.mozilla.geckoview.GeckoResult.OnExceptionListener;
 import org.mozilla.geckoview.GeckoResult.OnValueListener;
 import org.mozilla.geckoview.test.util.UiThreadUtils;
 
 import android.os.Looper;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.MediumTest;
 import android.support.test.rule.UiThreadTestRule;
 import android.support.test.runner.AndroidJUnit4;
 
-import static org.hamcrest.Matchers.equalTo;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.hamcrest.Matchers.*;
 import static org.junit.Assert.assertThat;
 
 @RunWith(AndroidJUnit4.class)
 @MediumTest
 public class GeckoResultTest {
     private static final long DEFAULT_TIMEOUT = 5000;
 
+    private static class MockException extends RuntimeException {
+    }
+
     @Rule
     public UiThreadTestRule mUiThreadTestRule = new UiThreadTestRule();
 
     private boolean mDone;
 
     private void waitUntilDone() {
         assertThat("We should not be done", mDone, equalTo(false));
 
@@ -207,20 +213,96 @@ public class GeckoResultTest {
             @Override
             public GeckoResult<Void> onException(Throwable error) {
                 assertThat("Error message should match", error.getMessage(), equalTo("boom"));
                 throw new MockException();
             }
         }).then(new OnExceptionListener<Void>() {
             @Override
             public GeckoResult<Void> onException(Throwable exception) {
-                assertThat("Exception should be MockException", exception instanceof MockException, equalTo(true));
+                assertThat("Exception should be MockException", exception, instanceOf(MockException.class));
+                done();
+                return null;
+            }
+        });
+
+        waitUntilDone();
+    }
+
+    @UiThreadTest
+    @Test
+    public void then_propagatedValue() {
+        // The first GeckoResult only has an exception listener, so when the value 42 is
+        // propagated to subsequent GeckoResult instances, the propagated value is coerced to null.
+        GeckoResult.fromValue(42).then(new OnExceptionListener<String>() {
+            @Override
+            public GeckoResult<String> onException(Throwable exception) throws Throwable {
+                return null;
+            }
+        }).then(new OnValueListener<String, Void>() {
+            @Override
+            public GeckoResult<Void> onValue(String value) throws Throwable {
+                assertThat("Propagated value is null", value, nullValue());
                 done();
                 return null;
             }
         });
 
         waitUntilDone();
     }
 
-    private static class MockException extends RuntimeException {
+    @UiThreadTest
+    @Test(expected = GeckoResult.UncaughtException.class)
+    public void then_uncaughtException() {
+        GeckoResult.fromValue(42).then(new OnValueListener<Integer, String>() {
+            @Override
+            public GeckoResult<String> onValue(Integer value) {
+                throw new MockException();
+            }
+        });
+
+        waitUntilDone();
+    }
+
+    @UiThreadTest
+    @Test(expected = GeckoResult.UncaughtException.class)
+    public void then_propagatedUncaughtException() {
+        GeckoResult.fromValue(42).then(new OnValueListener<Integer, String>() {
+            @Override
+            public GeckoResult<String> onValue(Integer value) {
+                throw new MockException();
+            }
+        }).then(new OnValueListener<String, Void>() {
+            @Override
+            public GeckoResult<Void> onValue(String value) throws Throwable {
+                return null;
+            }
+        });
+
+        waitUntilDone();
+    }
+
+    @UiThreadTest
+    @Test
+    public void then_caughtException() {
+        GeckoResult.fromValue(42).then(new OnValueListener<Integer, String>() {
+            @Override
+            public GeckoResult<String> onValue(Integer value) throws Exception {
+                throw new MockException();
+            }
+        }).then(new OnValueListener<String, Void>() {
+            @Override
+            public GeckoResult<Void> onValue(String value) throws Throwable {
+                return null;
+            }
+        }).then(new OnExceptionListener<Void>() {
+            @Override
+            public GeckoResult<Void> onException(Throwable exception) throws Throwable {
+                assertThat("Exception should be expected",
+                           exception, instanceOf(MockException.class));
+                done();
+                return null;
+            }
+        });
+
+        waitUntilDone();
     }
 }