Move ReactNativeTestRule to OSS

Summary: And migrated ReactRootViewTestCase to use ReactNativeTestRule.

Reviewed By: mdvacca

Differential Revision: D9557362

fbshipit-source-id: 1469d0ad8c125b5ea729371d81956e61780c56cf
This commit is contained in:
Andrew Chen (Eng)
2018-08-29 12:54:13 -07:00
committed by Facebook Github Bot
parent bf8e1b4ffa
commit afe0843bee
7 changed files with 369 additions and 107 deletions
@@ -2,7 +2,7 @@ load("//ReactNative:DEFS.bzl", "react_native_dep", "react_native_integration_tes
rn_android_library(
name = "tests",
srcs = glob(["**/*.java"]),
srcs = glob(["*.java"]),
visibility = [
"PUBLIC",
],
@@ -1,105 +0,0 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* 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.tests;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.facebook.react.testing.ReactInstanceSpecForTest;
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
import com.facebook.react.testing.StringRecordingModule;
import com.facebook.react.ReactRootView;
import org.junit.Ignore;
/**
* Integration test for {@link ReactRootView}.
*/
public class ReactRootViewTestCase extends ReactAppInstrumentationTestCase {
private StringRecordingModule mRecordingModule;
@Override
protected String getReactApplicationKeyUnderTest() {
return "CatalystRootViewTestApp";
}
@Ignore("t6596940: fix intermittently failing test")
public void testResizeRootView() throws Throwable {
final ReactRootView rootView = (ReactRootView) getRootView();
final View childView = rootView.getChildAt(0);
assertEquals(rootView.getWidth(), childView.getWidth());
final int newWidth = rootView.getWidth() / 2;
runTestOnUiThread(
new Runnable() {
@Override
public void run() {
rootView.setLayoutParams(new FrameLayout.LayoutParams(
newWidth,
ViewGroup.LayoutParams.MATCH_PARENT));
}
});
getInstrumentation().waitForIdleSync();
waitForBridgeAndUIIdle();
assertEquals(newWidth, childView.getWidth());
}
/**
* Verify that removing the root view from hierarchy will trigger subviews removal both on JS and
* native side
*/
public void testRemoveRootView() throws Throwable {
final ReactRootView rootView = (ReactRootView) getRootView();
assertEquals(1, rootView.getChildCount());
runTestOnUiThread(
new Runnable() {
@Override
public void run() {
ViewGroup parent = (ViewGroup) rootView.getParent();
parent.removeView(rootView);
// removing from parent should not remove child views, child views should be removed as
// an effect of native call to UIManager.removeRootView
assertEquals(1, rootView.getChildCount());
}
});
getInstrumentation().waitForIdleSync();
waitForBridgeAndUIIdle();
assertEquals("root component should not be automatically unmounted", 0, mRecordingModule.getCalls().size());
assertEquals(1, rootView.getChildCount());
runTestOnUiThread(
new Runnable() {
@Override
public void run() {
rootView.unmountReactApplication();
}
});
waitForBridgeAndUIIdle();
assertEquals(1, mRecordingModule.getCalls().size());
assertEquals("RootComponentWillUnmount", mRecordingModule.getCalls().get(0));
assertEquals(0, rootView.getChildCount());
}
@Override
protected ReactInstanceSpecForTest createReactInstanceSpecForTest() {
mRecordingModule = new StringRecordingModule();
return new ReactInstanceSpecForTest()
.addNativeModule(mRecordingModule);
}
}
@@ -0,0 +1,26 @@
# BUILD FILE SYNTAX: SKYLARK
load(
"@xplat//ReactNative:DEFS.bzl",
"react_native_dep",
"react_native_integration_tests_target",
"react_native_target",
"rn_android_library",
)
rn_android_library(
name = "core",
srcs = glob(["*.java"]),
deps = [
react_native_dep("java/com/facebook/fbreact/testing:testing"),
react_native_dep("third-party/java/espresso:espresso"),
react_native_dep("third-party/java/fest:fest"),
react_native_dep("third-party/java/junit:junit"),
react_native_dep("third-party/java/testing-support-lib:testing-support-lib"),
react_native_integration_tests_target("java/com/facebook/react/testing:testing"),
react_native_integration_tests_target("java/com/facebook/react/testing/rule:rule"),
react_native_target("java/com/facebook/react:react"),
react_native_target("java/com/facebook/react/bridge:bridge"),
react_native_target("java/com/facebook/react/shell:shell"),
react_native_target("java/com/facebook/react/uimanager:uimanager"),
],
)
@@ -0,0 +1,129 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.react.tests.core;
import static org.fest.assertions.api.Assertions.assertThat;
import android.app.Instrumentation;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactRootView;
import com.facebook.react.bridge.ModuleSpec;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.react.testing.StringRecordingModule;
import com.facebook.react.testing.rule.ReactNativeTestRule;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Provider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class ReactRootViewTest {
final StringRecordingModule mRecordingModule = new StringRecordingModule();
final ReactPackage mReactPackage = new MainReactPackage() {
@Override
public List<ModuleSpec> getNativeModules(ReactApplicationContext context) {
List<ModuleSpec> modules = new ArrayList<>(super.getNativeModules(context));
modules.add(
ModuleSpec.nativeModuleSpec(
StringRecordingModule.class,
new Provider<NativeModule>() {
@Override
public NativeModule get() {
return mRecordingModule;
}
}));
return modules;
}
};
@Rule
public ReactNativeTestRule mReactNativeRule =
new ReactNativeTestRule("AndroidTestBundle.js", mReactPackage);
@Before
public void setup() {
mReactNativeRule.render("CatalystRootViewTestApp");
}
@Test
public void testResizeRootView() {
final ReactRootView rootView = mReactNativeRule.getView();
final View childView = rootView.getChildAt(0);
assertThat(rootView.getWidth()).isEqualTo(childView.getWidth());
final int newWidth = rootView.getWidth() / 2;
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
instrumentation.runOnMainSync(
new Runnable() {
@Override
public void run() {
rootView.setLayoutParams(new FrameLayout.LayoutParams(
newWidth,
ViewGroup.LayoutParams.MATCH_PARENT));
}
});
instrumentation.waitForIdleSync();
mReactNativeRule.waitForIdleSync();
assertThat(newWidth).isEqualTo(childView.getWidth());
}
/**
* Verify that removing the root view from hierarchy will trigger subviews removal both on JS and
* native side
*/
@Test
public void testRemoveRootView() {
final ReactRootView rootView = mReactNativeRule.getView();
assertThat(rootView.getChildCount()).isEqualTo(1);
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
instrumentation.runOnMainSync(
new Runnable() {
@Override
public void run() {
ViewGroup parent = (ViewGroup) rootView.getParent();
parent.removeView(rootView);
// removing from parent should not remove child views, child views should be removed as
// an effect of native call to UIManager.removeRootView
assertThat(rootView.getChildCount()).isEqualTo(1);
}
});
instrumentation.waitForIdleSync();
mReactNativeRule.waitForIdleSync();
assertThat(mRecordingModule.getCalls().size())
.isEqualTo(0)
.overridingErrorMessage("root component should not be automatically unmounted");
assertThat(rootView.getChildCount()).isEqualTo(1);
instrumentation.runOnMainSync(
new Runnable() {
@Override
public void run() {
rootView.unmountReactApplication();
}
});
mReactNativeRule.waitForIdleSync();
assertThat(mRecordingModule.getCalls().size()).isEqualTo(1);
assertThat(mRecordingModule.getCalls().get(0)).isEqualTo("RootComponentWillUnmount");
assertThat(rootView.getChildCount()).isEqualTo(0);
}
}