Reviewed By: fkgozali

Differential Revision: D7207630

fbshipit-source-id: 69cc10d7d45031eec9f3d934b981a5e4bb62a0ef
This commit is contained in:
Andrew Chen (Eng) 2018-03-14 16:01:32 -07:00 коммит произвёл Facebook Github Bot
Родитель 304db5cb65
Коммит d678058402
4 изменённых файлов: 90 добавлений и 9 удалений

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

@ -20,6 +20,10 @@ const infoLog = require('infoLog');
const invariant = require('fbjs/lib/invariant');
const renderApplication = require('renderApplication');
// Renderer provider must be supplied by each app. If none, traditional
// renderApplication() will be used.
let fabricRendererProvider: ?() => typeof renderApplication = null;
type Task = (taskData: any) => Promise<void>;
type TaskProvider = () => Task;
export type ComponentProvider = () => React$ComponentType<any>;
@ -31,6 +35,7 @@ export type AppConfig = {
component?: ComponentProvider,
run?: Function,
section?: boolean,
fabric?: boolean,
};
export type Runnable = {
component?: ComponentProvider,
@ -80,6 +85,7 @@ const AppRegistry = {
appConfig.appKey,
appConfig.component,
appConfig.section,
appConfig.fabric,
);
}
});
@ -94,16 +100,26 @@ const AppRegistry = {
appKey: string,
componentProvider: ComponentProvider,
section?: boolean,
fabric?: boolean,
): string {
runnables[appKey] = {
componentProvider,
run: appParameters =>
renderApplication(
run: appParameters => {
let renderFunc = renderApplication;
if (fabric) {
invariant(
fabricRendererProvider != null,
'A Fabric renderer provider must be set to render Fabric components',
);
renderFunc = fabricRendererProvider();
}
renderFunc(
componentProviderInstrumentationHook(componentProvider),
appParameters.initialProps,
appParameters.rootTag,
wrapperComponentProvider && wrapperComponentProvider(appParameters),
),
);
},
};
if (section) {
sections[appKey] = runnables[appKey];
@ -236,6 +252,10 @@ const AppRegistry = {
NativeModules.HeadlessJsTaskSupport.notifyTaskFinished(taskId);
});
},
setFabricRendererProvider(provider: () => typeof renderApplication): void {
fabricRendererProvider = provider;
},
};
BatchedBridge.registerCallableModule('AppRegistry', AppRegistry);

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

@ -27,6 +27,8 @@ rn_android_library(
react_native_target("java/com/facebook/react/bridge:bridge"),
react_native_target("java/com/facebook/react/common:common"),
react_native_target("java/com/facebook/react/devsupport:interfaces"),
react_native_target("java/com/facebook/react/fabric:fabric"),
react_native_target("java/com/facebook/react/fabric/jsc:jsc"),
react_native_target("java/com/facebook/react/module/annotations:annotations"),
react_native_target("java/com/facebook/react/module/model:model"),
react_native_target("java/com/facebook/react/modules/core:core"),

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

@ -7,19 +7,17 @@
package com.facebook.react.testing;
import javax.annotation.Nullable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import android.content.Intent;
import android.graphics.Bitmap;
import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.testing.idledetection.IdleWaiter;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
/**
* Base class for instrumentation tests that runs React based react application in UI mode
@ -35,6 +33,9 @@ public abstract class ReactAppInstrumentationTestCase extends
protected void setUp() throws Exception {
super.setUp();
Intent intent = new Intent();
intent.putExtra(ReactAppTestActivity.EXTRA_IS_FABRIC_TEST, isFabricTest());
setActivityIntent(intent);
final ReactAppTestActivity activity = getActivity();
try {
runTestOnUiThread(new Runnable() {
@ -144,6 +145,10 @@ public abstract class ReactAppInstrumentationTestCase extends
return false;
}
protected boolean isFabricTest() {
return false;
}
/**
* Override this method to provide extra native modules to be loaded before the app starts
*/

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

@ -7,6 +7,7 @@
package com.facebook.react.testing;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
@ -17,8 +18,16 @@ import com.facebook.infer.annotation.Assertions;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactInstanceManagerBuilder;
import com.facebook.react.ReactRootView;
import com.facebook.react.bridge.JSIModule;
import com.facebook.react.bridge.JSIModuleHolder;
import com.facebook.react.bridge.JSIModulesProvider;
import com.facebook.react.bridge.JavaScriptContextHolder;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.UIManager;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.fabric.FabricUIManager;
import com.facebook.react.fabric.jsc.FabricJSCBinding;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.PermissionAwareActivity;
import com.facebook.react.modules.core.PermissionListener;
@ -26,6 +35,10 @@ import com.facebook.react.shell.MainReactPackage;
import com.facebook.react.testing.idledetection.ReactBridgeIdleSignaler;
import com.facebook.react.testing.idledetection.ReactIdleDetectionUtil;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.ViewManagerRegistry;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
@ -33,6 +46,8 @@ import javax.annotation.Nullable;
public class ReactAppTestActivity extends FragmentActivity
implements DefaultHardwareBackBtnHandler, PermissionAwareActivity {
public static final String EXTRA_IS_FABRIC_TEST = "is_fabric_test";
private static final String DEFAULT_BUNDLE_NAME = "AndroidTestBundle.js";
private static final int ROOT_VIEW_ID = 8675309;
// we need a bigger timeout for CI builds because they run on a slow emulator
@ -62,6 +77,11 @@ public class ReactAppTestActivity extends FragmentActivity
rootView.addView(mScreenshotingFrameLayout);
mReactRootView = new ReactRootView(this);
Intent intent = getIntent();
if (intent != null && intent.getBooleanExtra(EXTRA_IS_FABRIC_TEST, false)) {
mReactRootView.setIsFabric(true);
}
mScreenshotingFrameLayout.addView(mReactRootView);
}
@ -179,6 +199,36 @@ public class ReactAppTestActivity extends FragmentActivity
.setUseDeveloperSupport(useDevSupport)
.setBridgeIdleDebugListener(mBridgeIdleSignaler)
.setInitialLifecycleState(mLifecycleState)
.setJSIModulesProvider(
new JSIModulesProvider() {
@Override
public List<JSIModuleHolder> getJSIModules(
final ReactApplicationContext reactApplicationContext,
final JavaScriptContextHolder jsContext) {
List<JSIModuleHolder> modules = new ArrayList<>();
modules.add(
new JSIModuleHolder() {
@Override
public Class<? extends JSIModule> getJSIModuleClass() {
return UIManager.class;
}
@Override
public FabricUIManager getJSIModule() {
List<ViewManager> viewManagers =
getReactInstanceManager().getOrCreateViewManagers(reactApplicationContext);
FabricUIManager fabricUIManager =
new FabricUIManager(
reactApplicationContext, new ViewManagerRegistry(viewManagers));
new FabricJSCBinding().installFabric(jsContext, fabricUIManager);
return fabricUIManager;
}
});
return modules;
}})
.setUIImplementationProvider(uiImplementationProvider);
mReactInstanceManager = builder.build();
@ -195,6 +245,10 @@ public class ReactAppTestActivity extends FragmentActivity
.startReactApplication(mReactInstanceManager, appKey, initialProps);
}
private ReactInstanceManager getReactInstanceManager() {
return mReactInstanceManager;
}
public boolean waitForLayout(long millis) throws InterruptedException {
return mLayoutEvent.await(millis, TimeUnit.MILLISECONDS);
}