Bug 1468048 - Add GeckoSessionTestRule.waitForResult() r=esawin,jchen

MozReview-Commit-ID: HEcBXmwOaD7
This commit is contained in:
James Willcox 2018-06-15 11:43:28 -07:00
Родитель 776cb4bacf
Коммит 68a96de0af
2 изменённых файлов: 86 добавлений и 12 удалений

Просмотреть файл

@ -4,20 +4,12 @@
package org.mozilla.geckoview.test
import android.os.Handler
import android.os.Looper
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.GeckoSessionSettings
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ChildCrashedException
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ClosedSessionAtStart
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.IgnoreCrash
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.NullDelegate
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.RejectedPromiseException
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ReuseSession
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.Setting
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.TimeoutException
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.TimeoutMillis
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDevToolsAPI
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDisplay
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.*
import org.mozilla.geckoview.test.util.Callbacks
import org.mozilla.geckoview.test.util.UiThreadUtils
@ -1679,4 +1671,32 @@ class GeckoSessionTestRuleTest : BaseSessionTest(noErrorCollector = true) {
sessionRule.session.loadUri(CONTENT_CRASH_URL)
sessionRule.waitForPageStop()
}
@Test fun waitForResult() {
val handler = Handler(Looper.getMainLooper())
val result = object : GeckoResult<Int>() {
init {
handler.postDelayed({
complete(42)
}, 100)
}
}
val value = sessionRule.waitForResult(result)
assertThat("Value should match", value, equalTo(42))
}
@Test(expected = IllegalStateException::class)
fun waitForResultExceptionally() {
val handler = Handler(Looper.getMainLooper())
val result = object : GeckoResult<Int>() {
init {
handler.postDelayed({
completeExceptionally(IllegalStateException("boom"))
}, 100)
}
}
sessionRule.waitForResult(result)
}
}

Просмотреть файл

@ -8,6 +8,9 @@ package org.mozilla.geckoview.test.rule;
import org.mozilla.gecko.gfx.GeckoDisplay;
import org.mozilla.geckoview.BuildConfig;
import org.mozilla.geckoview.GeckoResponse;
import org.mozilla.geckoview.GeckoResult;
import org.mozilla.geckoview.GeckoResult.OnExceptionListener;
import org.mozilla.geckoview.GeckoResult.OnValueListener;
import org.mozilla.geckoview.GeckoRuntime;
import org.mozilla.geckoview.GeckoRuntimeSettings;
import org.mozilla.geckoview.GeckoSession;
@ -2280,4 +2283,55 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
addExternalDelegateDuringNextWait(JvmClassMappingKt.getJavaClass(delegate),
register, unregister, impl);
}
/**
* This waits for the given result and returns it's value. If
* the result failed with an exception, it is rethrown.
*
* @param result A {@link GeckoResult} instance.
* @param <T> The type of the value held by the {@link GeckoResult}
* @return The value of the completed {@link GeckoResult}.
*/
public <T> T waitForResult(@NonNull GeckoResult<T> result) {
final ResultHolder<T> holder = new ResultHolder<>(result);
try {
beforeWait();
while (!holder.isComplete) {
UiThreadUtils.loopUntilIdle(mTimeoutMillis);
}
} finally {
afterWait(mCallRecords.size());
}
if (holder.error != null) {
throw unwrapRuntimeException(holder.error);
}
return holder.value;
}
private static class ResultHolder<T> {
public T value;
public Throwable error;
public boolean isComplete;
public ResultHolder(GeckoResult<T> result) {
result.then(new OnValueListener<T, Void>() {
@Override
public GeckoResult<Void> onValue(T value) {
ResultHolder.this.value = value;
isComplete = true;
return null;
}
}, new OnExceptionListener<Void>() {
@Override
public GeckoResult<Void> onException(Throwable error) {
ResultHolder.this.error = error;
isComplete = true;
return null;
}
});
}
}
}