mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Convert and re-enable TimingModuleTest (#37763)
Summary: As part of the effort to Kotlin-fy React Native tests, I've converted [TimingModuleTest](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.java) to Kotlin. I noticed the test suite was ignored and it was failing locally but managed to get all the tests to pass except one which I kept ignored. ## Changelog: [Internal] [Changed] - Convert TimingModuleTest to Kotlin Pull Request resolved: https://github.com/facebook/react-native/pull/37763 Test Plan: Tests pass: ./gradlew :packages:react-native:ReactAndroid:test Formatted with [KtFmt](https://facebook.github.io/ktfmt/) Reviewed By: cortinico Differential Revision: D46543718 Pulled By: rshest fbshipit-source-id: 761b778a6d07417c9c83457c2777ee87f198f158
This commit is contained in:
committed by
Facebook GitHub Bot
parent
5662faa708
commit
108309e407
-307
@@ -1,307 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.modules.timing;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.CatalystInstance;
|
||||
import com.facebook.react.bridge.JavaOnlyArray;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.common.SystemClock;
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
||||
import com.facebook.react.modules.core.ChoreographerCompat;
|
||||
import com.facebook.react.modules.core.JSTimers;
|
||||
import com.facebook.react.modules.core.ReactChoreographer;
|
||||
import com.facebook.react.modules.core.TimingModule;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.rule.PowerMockRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link TimingModule}. */
|
||||
// DISABLED, BROKEN https://circleci.com/gh/facebook/react-native/12068
|
||||
@PrepareForTest({Arguments.class, SystemClock.class, ReactChoreographer.class})
|
||||
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "androidx.*", "android.*"})
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Ignore // TODO T13905097
|
||||
public class TimingModuleTest {
|
||||
|
||||
private static final long FRAME_TIME_NS = 17 * 1000 * 1000; // 17 ms
|
||||
|
||||
private TimingModule mTimingModule;
|
||||
private ReactChoreographer mReactChoreographerMock;
|
||||
private PostFrameCallbackHandler mPostFrameCallbackHandler;
|
||||
private PostFrameIdleCallbackHandler mIdlePostFrameCallbackHandler;
|
||||
private long mCurrentTimeNs;
|
||||
private JSTimers mJSTimersMock;
|
||||
|
||||
@Rule public PowerMockRule rule = new PowerMockRule();
|
||||
|
||||
@Before
|
||||
public void prepareModules() {
|
||||
PowerMockito.mockStatic(Arguments.class);
|
||||
when(Arguments.createArray())
|
||||
.thenAnswer(
|
||||
new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return new JavaOnlyArray();
|
||||
}
|
||||
});
|
||||
|
||||
PowerMockito.mockStatic(SystemClock.class);
|
||||
when(SystemClock.uptimeMillis()).thenReturn(mCurrentTimeNs / 1000000);
|
||||
when(SystemClock.currentTimeMillis()).thenReturn(mCurrentTimeNs / 1000000);
|
||||
when(SystemClock.nanoTime()).thenReturn(mCurrentTimeNs);
|
||||
|
||||
mReactChoreographerMock = mock(ReactChoreographer.class);
|
||||
PowerMockito.mockStatic(ReactChoreographer.class);
|
||||
when(ReactChoreographer.getInstance()).thenReturn(mReactChoreographerMock);
|
||||
|
||||
CatalystInstance reactInstance = mock(CatalystInstance.class);
|
||||
ReactApplicationContext reactContext = mock(ReactApplicationContext.class);
|
||||
when(reactContext.getCatalystInstance()).thenReturn(reactInstance);
|
||||
when(reactContext.hasActiveReactInstance()).thenReturn(true);
|
||||
|
||||
mCurrentTimeNs = 0;
|
||||
mPostFrameCallbackHandler = new PostFrameCallbackHandler();
|
||||
mIdlePostFrameCallbackHandler = new PostFrameIdleCallbackHandler();
|
||||
|
||||
doAnswer(mPostFrameCallbackHandler)
|
||||
.when(mReactChoreographerMock)
|
||||
.postFrameCallback(
|
||||
eq(ReactChoreographer.CallbackType.TIMERS_EVENTS),
|
||||
any(ChoreographerCompat.FrameCallback.class));
|
||||
|
||||
doAnswer(mIdlePostFrameCallbackHandler)
|
||||
.when(mReactChoreographerMock)
|
||||
.postFrameCallback(
|
||||
eq(ReactChoreographer.CallbackType.IDLE_EVENT),
|
||||
any(ChoreographerCompat.FrameCallback.class));
|
||||
|
||||
mTimingModule = new TimingModule(reactContext, mock(DevSupportManager.class));
|
||||
mJSTimersMock = mock(JSTimers.class);
|
||||
when(reactContext.getJSModule(JSTimers.class)).thenReturn(mJSTimersMock);
|
||||
|
||||
doAnswer(
|
||||
new Answer() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
((Runnable) invocation.getArguments()[0]).run();
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.when(reactContext)
|
||||
.runOnJSQueueThread(any(Runnable.class));
|
||||
|
||||
mTimingModule.initialize();
|
||||
}
|
||||
|
||||
private void stepChoreographerFrame() {
|
||||
ChoreographerCompat.FrameCallback callback =
|
||||
mPostFrameCallbackHandler.getAndResetFrameCallback();
|
||||
ChoreographerCompat.FrameCallback idleCallback =
|
||||
mIdlePostFrameCallbackHandler.getAndResetFrameCallback();
|
||||
|
||||
mCurrentTimeNs += FRAME_TIME_NS;
|
||||
when(SystemClock.uptimeMillis()).thenReturn(mCurrentTimeNs / 1000000);
|
||||
if (callback != null) {
|
||||
callback.doFrame(mCurrentTimeNs);
|
||||
}
|
||||
|
||||
if (idleCallback != null) {
|
||||
idleCallback.doFrame(mCurrentTimeNs);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleTimer() {
|
||||
mTimingModule.onHostResume();
|
||||
mTimingModule.createTimer(1, 1, 0, false);
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(1.0));
|
||||
reset(mJSTimersMock);
|
||||
stepChoreographerFrame();
|
||||
verifyNoMoreInteractions(mJSTimersMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleRecurringTimer() {
|
||||
mTimingModule.createTimer(100, 1, 0, true);
|
||||
mTimingModule.onHostResume();
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(100.0));
|
||||
|
||||
reset(mJSTimersMock);
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(100.0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelRecurringTimer() {
|
||||
mTimingModule.onHostResume();
|
||||
mTimingModule.createTimer(105, 1, 0, true);
|
||||
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(105.0));
|
||||
|
||||
reset(mJSTimersMock);
|
||||
mTimingModule.deleteTimer(105);
|
||||
stepChoreographerFrame();
|
||||
verifyNoMoreInteractions(mJSTimersMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPausingAndResuming() {
|
||||
mTimingModule.onHostResume();
|
||||
mTimingModule.createTimer(41, 1, 0, true);
|
||||
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41.0));
|
||||
|
||||
reset(mJSTimersMock);
|
||||
mTimingModule.onHostPause();
|
||||
stepChoreographerFrame();
|
||||
verifyNoMoreInteractions(mJSTimersMock);
|
||||
|
||||
reset(mJSTimersMock);
|
||||
mTimingModule.onHostResume();
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41.0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeadlessJsTaskInBackground() {
|
||||
mTimingModule.onHostPause();
|
||||
mTimingModule.onHeadlessJsTaskStart(42);
|
||||
mTimingModule.createTimer(41, 1, 0, true);
|
||||
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41.0));
|
||||
|
||||
reset(mJSTimersMock);
|
||||
mTimingModule.onHeadlessJsTaskFinish(42);
|
||||
stepChoreographerFrame();
|
||||
verifyNoMoreInteractions(mJSTimersMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeadlessJsTaskInForeground() {
|
||||
mTimingModule.onHostResume();
|
||||
mTimingModule.onHeadlessJsTaskStart(42);
|
||||
mTimingModule.createTimer(41, 1, 0, true);
|
||||
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41.0));
|
||||
|
||||
reset(mJSTimersMock);
|
||||
mTimingModule.onHeadlessJsTaskFinish(42);
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41.0));
|
||||
|
||||
reset(mJSTimersMock);
|
||||
mTimingModule.onHostPause();
|
||||
verifyNoMoreInteractions(mJSTimersMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeadlessJsTaskIntertwine() {
|
||||
mTimingModule.onHostResume();
|
||||
mTimingModule.onHeadlessJsTaskStart(42);
|
||||
mTimingModule.createTimer(41, 1, 0, true);
|
||||
mTimingModule.onHostPause();
|
||||
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41.0));
|
||||
|
||||
reset(mJSTimersMock);
|
||||
mTimingModule.onHostResume();
|
||||
mTimingModule.onHeadlessJsTaskFinish(42);
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41.0));
|
||||
|
||||
reset(mJSTimersMock);
|
||||
mTimingModule.onHostPause();
|
||||
stepChoreographerFrame();
|
||||
verifyNoMoreInteractions(mJSTimersMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetTimeoutZero() {
|
||||
mTimingModule.createTimer(100, 0, 0, false);
|
||||
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(100.0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdleCallback() {
|
||||
mTimingModule.onHostResume();
|
||||
mTimingModule.setSendIdleEvents(true);
|
||||
|
||||
stepChoreographerFrame();
|
||||
verify(mJSTimersMock).callIdleCallbacks(SystemClock.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActiveTimersInRange() {
|
||||
mTimingModule.onHostResume();
|
||||
assertThat(mTimingModule.hasActiveTimersInRange(100)).isFalse();
|
||||
|
||||
mTimingModule.createTimer(41, 1, 0, true);
|
||||
assertThat(mTimingModule.hasActiveTimersInRange(100)).isFalse(); // Repeating
|
||||
|
||||
mTimingModule.createTimer(42, 150, 0, false);
|
||||
assertThat(mTimingModule.hasActiveTimersInRange(100)).isFalse(); // Out of range
|
||||
assertThat(mTimingModule.hasActiveTimersInRange(200)).isTrue(); // In range
|
||||
}
|
||||
|
||||
private static class PostFrameIdleCallbackHandler implements Answer<Void> {
|
||||
|
||||
private ChoreographerCompat.FrameCallback mFrameCallback;
|
||||
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
Object[] args = invocation.getArguments();
|
||||
mFrameCallback = (ChoreographerCompat.FrameCallback) args[1];
|
||||
return null;
|
||||
}
|
||||
|
||||
public ChoreographerCompat.FrameCallback getAndResetFrameCallback() {
|
||||
ChoreographerCompat.FrameCallback callback = mFrameCallback;
|
||||
mFrameCallback = null;
|
||||
return callback;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PostFrameCallbackHandler implements Answer<Void> {
|
||||
|
||||
private ChoreographerCompat.FrameCallback mFrameCallback;
|
||||
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
Object[] args = invocation.getArguments();
|
||||
mFrameCallback = (ChoreographerCompat.FrameCallback) args[1];
|
||||
return null;
|
||||
}
|
||||
|
||||
public ChoreographerCompat.FrameCallback getAndResetFrameCallback() {
|
||||
ChoreographerCompat.FrameCallback callback = mFrameCallback;
|
||||
mFrameCallback = null;
|
||||
return callback;
|
||||
}
|
||||
}
|
||||
}
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.modules.timing
|
||||
|
||||
import com.facebook.react.bridge.Arguments
|
||||
import com.facebook.react.bridge.CatalystInstance
|
||||
import com.facebook.react.bridge.JavaOnlyArray
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.common.SystemClock
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager
|
||||
import com.facebook.react.modules.core.ChoreographerCompat.FrameCallback
|
||||
import com.facebook.react.modules.core.JSTimers
|
||||
import com.facebook.react.modules.core.ReactChoreographer
|
||||
import com.facebook.react.modules.core.ReactChoreographer.CallbackType
|
||||
import com.facebook.react.modules.core.TimingModule
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.eq
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.reset
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.verifyNoMoreInteractions
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.invocation.InvocationOnMock
|
||||
import org.mockito.stubbing.Answer
|
||||
import org.powermock.api.mockito.PowerMockito
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
||||
import org.powermock.modules.junit4.rule.PowerMockRule
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@PrepareForTest(Arguments::class, SystemClock::class, ReactChoreographer::class)
|
||||
@PowerMockIgnore("org.mockito.*", "org.robolectric.*", "androidx.*", "android.*")
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class TimingModuleTest {
|
||||
companion object {
|
||||
const val FRAME_TIME_NS = 17 * 1000 * 1000
|
||||
}
|
||||
|
||||
private lateinit var timingModule: TimingModule
|
||||
private lateinit var reactChoreographerMock: ReactChoreographer
|
||||
private lateinit var postFrameCallbackHandler: PostFrameCallbackHandler
|
||||
private lateinit var idlePostFrameCallbackHandler: PostFrameCallbackHandler
|
||||
private var currentTimeNs = 0L
|
||||
private lateinit var jSTimersMock: JSTimers
|
||||
|
||||
@get:Rule val powerMockRule = PowerMockRule()
|
||||
|
||||
@Before
|
||||
fun prepareModules() {
|
||||
PowerMockito.mockStatic(Arguments::class.java)
|
||||
whenever(Arguments.createArray()).thenAnswer {
|
||||
return@thenAnswer JavaOnlyArray()
|
||||
}
|
||||
|
||||
PowerMockito.mockStatic(SystemClock::class.java)
|
||||
whenever(SystemClock.uptimeMillis()).thenAnswer {
|
||||
return@thenAnswer currentTimeNs / 1000000
|
||||
}
|
||||
whenever(SystemClock.currentTimeMillis()).thenAnswer {
|
||||
return@thenAnswer currentTimeNs / 1000000
|
||||
}
|
||||
whenever(SystemClock.nanoTime()).thenAnswer {
|
||||
return@thenAnswer currentTimeNs
|
||||
}
|
||||
|
||||
reactChoreographerMock = mock(ReactChoreographer::class.java)
|
||||
PowerMockito.mockStatic(ReactChoreographer::class.java)
|
||||
whenever(ReactChoreographer.getInstance()).thenAnswer { reactChoreographerMock }
|
||||
|
||||
val reactInstance = mock(CatalystInstance::class.java)
|
||||
val reactContext = mock(ReactApplicationContext::class.java)
|
||||
whenever(reactContext.catalystInstance).thenReturn(reactInstance)
|
||||
whenever(reactContext.hasActiveReactInstance()).thenReturn(true)
|
||||
|
||||
postFrameCallbackHandler = PostFrameCallbackHandler()
|
||||
idlePostFrameCallbackHandler = PostFrameCallbackHandler()
|
||||
|
||||
whenever(
|
||||
reactChoreographerMock.postFrameCallback(
|
||||
eq(CallbackType.TIMERS_EVENTS), any(FrameCallback::class.java)))
|
||||
.thenAnswer {
|
||||
return@thenAnswer postFrameCallbackHandler.answer(it)
|
||||
}
|
||||
|
||||
whenever(
|
||||
reactChoreographerMock.postFrameCallback(
|
||||
eq(CallbackType.IDLE_EVENT), any(FrameCallback::class.java)))
|
||||
.thenAnswer {
|
||||
return@thenAnswer idlePostFrameCallbackHandler.answer(it)
|
||||
}
|
||||
|
||||
timingModule = TimingModule(reactContext, mock(DevSupportManager::class.java))
|
||||
jSTimersMock = mock(JSTimers::class.java)
|
||||
whenever(reactContext.getJSModule(JSTimers::class.java)).thenReturn(jSTimersMock)
|
||||
whenever(reactContext.runOnJSQueueThread(any(Runnable::class.java))).thenAnswer { invocation ->
|
||||
(invocation.arguments[0] as Runnable).run()
|
||||
return@thenAnswer true
|
||||
}
|
||||
|
||||
timingModule.initialize()
|
||||
}
|
||||
|
||||
private fun stepChoreographerFrame() {
|
||||
val callback = postFrameCallbackHandler.getAndResetFrameCallback()
|
||||
val idleCallback = idlePostFrameCallbackHandler.getAndResetFrameCallback()
|
||||
currentTimeNs += FRAME_TIME_NS
|
||||
whenever(SystemClock.uptimeMillis()).thenAnswer {
|
||||
return@thenAnswer currentTimeNs / 1000000
|
||||
}
|
||||
callback?.doFrame(currentTimeNs)
|
||||
idleCallback?.doFrame(currentTimeNs)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSimpleTimer() {
|
||||
timingModule.onHostResume()
|
||||
timingModule.createTimer(1.0, 1.0, 0.0, false)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(1.0))
|
||||
reset(jSTimersMock)
|
||||
stepChoreographerFrame()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSimpleRecurringTimer() {
|
||||
timingModule.createTimer(100.0, 1.0, 0.0, true)
|
||||
timingModule.onHostResume()
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(100.0))
|
||||
reset(jSTimersMock)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(100.0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCancelRecurringTimer() {
|
||||
timingModule.onHostResume()
|
||||
timingModule.createTimer(105.0, 1.0, 0.0, true)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(105.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.deleteTimer(105.0)
|
||||
stepChoreographerFrame()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPausingAndResuming() {
|
||||
timingModule.onHostResume()
|
||||
timingModule.createTimer(41.0, 1.0, 0.0, true)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHostPause()
|
||||
stepChoreographerFrame()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHostResume()
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHeadlessJsTaskInBackground() {
|
||||
timingModule.onHostPause()
|
||||
timingModule.onHeadlessJsTaskStart(42)
|
||||
timingModule.createTimer(41.0, 1.0, 0.0, true)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHeadlessJsTaskFinish(42)
|
||||
stepChoreographerFrame()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHeadlessJsTaskInForeground() {
|
||||
timingModule.onHostResume()
|
||||
timingModule.onHeadlessJsTaskStart(42)
|
||||
timingModule.createTimer(41.0, 1.0, 0.0, true)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHeadlessJsTaskFinish(42)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHostPause()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHeadlessJsTaskIntertwine() {
|
||||
timingModule.onHostResume()
|
||||
timingModule.onHeadlessJsTaskStart(42)
|
||||
timingModule.createTimer(41.0, 1.0, 0.0, true)
|
||||
timingModule.onHostPause()
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHostResume()
|
||||
timingModule.onHeadlessJsTaskFinish(42)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHostPause()
|
||||
stepChoreographerFrame()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetTimeoutZero() {
|
||||
timingModule.createTimer(100.0, 0.0, 0.0, false)
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(100.0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testActiveTimersInRange() {
|
||||
timingModule.onHostResume()
|
||||
assertThat(timingModule.hasActiveTimersInRange(100)).isFalse
|
||||
timingModule.createTimer(41.0, 1.0, 0.0, true)
|
||||
assertThat(timingModule.hasActiveTimersInRange(100)).isFalse // Repeating
|
||||
timingModule.createTimer(42.0, 150.0, 0.0, false)
|
||||
assertThat(timingModule.hasActiveTimersInRange(100)).isFalse // Out of range
|
||||
assertThat(timingModule.hasActiveTimersInRange(200)).isTrue // In range
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIdleCallback() {
|
||||
timingModule.setSendIdleEvents(true)
|
||||
timingModule.onHostResume()
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callIdleCallbacks(SystemClock.currentTimeMillis().toDouble())
|
||||
}
|
||||
|
||||
private class PostFrameCallbackHandler : Answer<Unit> {
|
||||
|
||||
private var frameCallback: FrameCallback? = null
|
||||
|
||||
override fun answer(invocation: InvocationOnMock) {
|
||||
invocation.arguments[1]?.let { frameCallback = it as FrameCallback }
|
||||
}
|
||||
|
||||
fun getAndResetFrameCallback(): FrameCallback? {
|
||||
val callback = frameCallback
|
||||
frameCallback = null
|
||||
return callback
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user