Skip to content

Commit

Permalink
Revert D52033328: Convert the last Unit Tests to Kotlin
Browse files Browse the repository at this point in the history
Differential Revision:
D52033328

Original commit changeset: fabe19f88129

Original Phabricator Diff: D52033328

fbshipit-source-id: 3186196dd6df1bd720164894828f8fd1c9215710
  • Loading branch information
Qian Wu authored and facebook-github-bot committed Dec 11, 2023
1 parent 9f28616 commit 6b532c7
Show file tree
Hide file tree
Showing 9 changed files with 538 additions and 505 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public class ReactHostImpl implements ReactHost {

private final Context mContext;
private final ReactHostDelegate mReactHostDelegate;
@Nullable private final ComponentFactory mComponentFactory;
private final ComponentFactory mComponentFactory;
private final ReactJsExceptionHandler mReactJsExceptionHandler;
private final DevSupportManager mDevSupportManager;
private final Executor mBGExecutor;
Expand Down Expand Up @@ -137,7 +137,7 @@ public class ReactHostImpl implements ReactHost {
public ReactHostImpl(
Context context,
ReactHostDelegate delegate,
@Nullable ComponentFactory componentFactory,
ComponentFactory componentFactory,
boolean allowPackagerServerAccess,
ReactJsExceptionHandler reactJsExceptionHandler,
boolean useDevSupport) {
Expand All @@ -155,7 +155,7 @@ public ReactHostImpl(
public ReactHostImpl(
Context context,
ReactHostDelegate delegate,
@Nullable ComponentFactory componentFactory,
ComponentFactory componentFactory,
Executor bgExecutor,
Executor uiExecutor,
ReactJsExceptionHandler reactJsExceptionHandler,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* 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.runtime;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.doReturn;

import android.app.Activity;
import android.content.Context;
import com.facebook.react.bridge.JSIModuleType;
import com.facebook.react.uimanager.UIManagerModule;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;

/** Tests {@link BridgelessReactContext} */
@RunWith(RobolectricTestRunner.class)
public class BridgelessReactContextTest {

private Context mContext;
private ReactHostImpl mReactHost;
private BridgelessReactContext mBridgelessReactContext;

@Before
public void setUp() {
mContext = Robolectric.buildActivity(Activity.class).create().get();
mReactHost = Mockito.mock(ReactHostImpl.class);
mBridgelessReactContext = new BridgelessReactContext(mContext, mReactHost);
}

@Test
public void getNativeModuleTest() {
UIManagerModule mUiManagerModule = Mockito.mock(UIManagerModule.class);
doReturn(mUiManagerModule)
.when(mReactHost)
.getNativeModule(ArgumentMatchers.<Class<UIManagerModule>>any());

UIManagerModule uiManagerModule =
mBridgelessReactContext.getNativeModule(UIManagerModule.class);

assertThat(uiManagerModule).isEqualTo(mUiManagerModule);
}

@Test(expected = UnsupportedOperationException.class)
public void getJSIModule_throwsException() {
mBridgelessReactContext.getJSIModule(JSIModuleType.TurboModuleManager);
}

// Disable this test for now due to mocking FabricUIManager fails
// @Test
// public void getJSIModuleTest() {
// FabricUIManager fabricUiManager = Mockito.mock(FabricUIManager.class);
// doReturn(fabricUiManager).when(mReactHost).getUIManager();
// assertThat(mBridgelessReactContext.getJSIModule(JSIModuleType.UIManager))
// .isEqualTo(fabricUiManager);
// }

@Test(expected = UnsupportedOperationException.class)
public void getCatalystInstance_throwsException() {
mBridgelessReactContext.getCatalystInstance();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/*
* 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.runtime;

import static android.os.Looper.getMainLooper;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.robolectric.Shadows.shadowOf;

import android.app.Activity;
import com.facebook.react.MemoryPressureRouter;
import com.facebook.react.bridge.JSBundleLoader;
import com.facebook.react.bridge.MemoryPressureListener;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.UIManager;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.devsupport.interfaces.PackagerStatusCallback;
import com.facebook.react.fabric.ComponentFactory;
import com.facebook.react.interfaces.TaskInterface;
import com.facebook.react.runtime.internal.bolts.TaskCompletionSource;
import com.facebook.react.uimanager.events.BlackHoleEventDispatcher;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.testutils.shadows.ShadowSoLoader;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.LooperMode;

/** Tests {@linkcom.facebook.react.runtime.ReactHostImpl} */
@Ignore("Ignore for now as these tests fail in OSS only")
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowSoLoader.class)
@LooperMode(LooperMode.Mode.PAUSED)
public class ReactHostTest {

private ReactHostDelegate mReactHostDelegate;
private ReactInstance mReactInstance;
private MemoryPressureRouter mMemoryPressureRouter;
private BridgelessDevSupportManager mDevSupportManager;
private JSBundleLoader mJSBundleLoader;
private ReactHostImpl mReactHost;
private ActivityController<Activity> mActivityController;
private ComponentFactory mComponentFactory;
private BridgelessReactContext mBridgelessReactContext;

@Before
public void setUp() throws Exception {
initMocks(this);

mActivityController = Robolectric.buildActivity(Activity.class).create().start().resume();

mReactHostDelegate = mock(ReactHostDelegate.class);
mReactInstance = mock(ReactInstance.class);
mMemoryPressureRouter = mock(MemoryPressureRouter.class);
mDevSupportManager = mock(BridgelessDevSupportManager.class);
mJSBundleLoader = mock(JSBundleLoader.class);
mComponentFactory = mock(ComponentFactory.class);
mBridgelessReactContext = mock(BridgelessReactContext.class);

// TODO This should be replaced with proper mocking once this test is un-ignored
// whenNew(ReactInstance.class).withAnyArguments().thenReturn(mReactInstance);
//
// whenNew(BridgelessReactContext.class).withAnyArguments().thenReturn(mBridgelessReactContext);
// whenNew(MemoryPressureRouter.class).withAnyArguments().thenReturn(mMemoryPressureRouter);
//
// whenNew(BridgelessDevSupportManager.class).withAnyArguments().thenReturn(mDevSupportManager);

doReturn(mJSBundleLoader).when(mReactHostDelegate).getJsBundleLoader();

mReactHost =
new ReactHostImpl(
mActivityController.get().getApplication(),
mReactHostDelegate,
mComponentFactory,
false,
null,
false);

TaskCompletionSource<Boolean> taskCompletionSource = new TaskCompletionSource<>();
taskCompletionSource.setResult(true);
// TODO This should be replaced with proper mocking once this test is un-ignored
// whenNew(TaskCompletionSource.class).withAnyArguments().thenReturn(taskCompletionSource);
}

@Test
public void getEventDispatcher_returnsBlackHoleEventDispatcher() {
EventDispatcher eventDispatcher = mReactHost.getEventDispatcher();
assertThat(eventDispatcher).isInstanceOf(BlackHoleEventDispatcher.class);
}

@Test
public void getUIManager_returnsNullIfNoInstance() {
UIManager uiManager = mReactHost.getUIManager();
assertThat(uiManager).isNull();
}

@Test
public void testGetDevSupportManager() {
assertThat(mReactHost.getDevSupportManager()).isEqualTo(mDevSupportManager);
}

@Test
public void testStart() throws Exception {
doNothing().when(mDevSupportManager).isPackagerRunning(any(PackagerStatusCallback.class));
assertThat(mReactHost.isInstanceInitialized()).isFalse();

waitForTaskUIThread(mReactHost.start());

assertThat(mReactHost.isInstanceInitialized()).isTrue();
assertThat(mReactHost.getCurrentReactContext()).isNotNull();
verify(mMemoryPressureRouter).addMemoryPressureListener((MemoryPressureListener) any());
}

private void startReactHost() throws Exception {
waitForTaskUIThread(mReactHost.start());
}

@Test
public void testDestroy() throws Exception {
startReactHost();

waitForTaskUIThread(mReactHost.destroy("Destroying from testing infra", null));
assertThat(mReactHost.isInstanceInitialized()).isFalse();
assertThat(mReactHost.getCurrentReactContext()).isNull();
}

@Test
public void testReload() throws Exception {
startReactHost();

ReactContext oldReactContext = mReactHost.getCurrentReactContext();
BridgelessReactContext newReactContext = mock(BridgelessReactContext.class);
assertThat(newReactContext).isNotEqualTo(oldReactContext);
// TODO This should be replaced with proper mocking once this test is un-ignored
// whenNew(BridgelessReactContext.class).withAnyArguments().thenReturn(newReactContext);

waitForTaskUIThread(mReactHost.reload("Reload from testing infra"));

assertThat(mReactHost.isInstanceInitialized()).isTrue();
assertThat(mReactHost.getCurrentReactContext()).isNotNull();
assertThat(mReactHost.getCurrentReactContext()).isEqualTo(newReactContext);
assertThat(mReactHost.getCurrentReactContext()).isNotEqualTo(oldReactContext);
}

@Test
public void testLifecycleStateChanges() throws Exception {
startReactHost();

assertThat(mReactHost.getLifecycleState()).isEqualTo(LifecycleState.BEFORE_CREATE);
mReactHost.onHostResume(mActivityController.get());
assertThat(mReactHost.getLifecycleState()).isEqualTo(LifecycleState.RESUMED);
mReactHost.onHostPause(mActivityController.get());
assertThat(mReactHost.getLifecycleState()).isEqualTo(LifecycleState.BEFORE_RESUME);
mReactHost.onHostDestroy(mActivityController.get());
assertThat(mReactHost.getLifecycleState()).isEqualTo(LifecycleState.BEFORE_CREATE);
}

private static <T> void waitForTaskUIThread(TaskInterface<T> task) throws InterruptedException {
boolean isTaskCompleted = false;
while (!isTaskCompleted) {
if (!task.waitForCompletion(4, TimeUnit.MILLISECONDS)) {
shadowOf(getMainLooper()).idle();
} else {
if (task.isCancelled() || task.isFaulted()) {
throw new RuntimeException("Task was cancelled or faulted. Error: " + task.getError());
}
isTaskCompleted = true;
}
}
}
}
Loading

0 comments on commit 6b532c7

Please sign in to comment.