mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Allow 'userInfo' for native promise.reject + add native error stack support (#20940)
Summary: As mentioned [here](https://github.com/react-native-community/react-native-releases/issues/34#issuecomment-417718601), Android is missing native Promise reject with a `userInfo` `WritableMap` support and also `nativeStack` support (which addresses `TODO(8850038)`). This PR adds Android support for both of these. React Native on iOS ([here](https://github.com/facebook/react-native/blob/master/React/Base/RCTUtils.m#L433)) and Windows ([here](https://github.com/Microsoft/react-native-windows/pull/732)) already support this so this is a relatively minor addition to bring Android in line with the other platforms. (JS support is also [here](https://github.com/facebook/react-native/blob/master/Libraries/BatchedBridge/NativeModules.js#L145-L148)) Existing methods remain unchanged other than general cleanup of variable names (`e -> throwable`) and adding code comments/docs. Additionally, the `ShareTestModule` implementation of Promise (SimplePromise) was updated to reflect these changes - other line changes in this file are from formatting in Android Studio - if this is an issue let me know. - Currently inconsistent with other platforms. - Blocking a couple of issues over at [invertase/react-native-firebase](https://github.com/invertase/react-native-firebase) - save for re-writing everything to Promise resolve only - which is no small change and isn't a great solution either. Pull Request resolved: https://github.com/facebook/react-native/pull/20940 Differential Revision: D13412527 Pulled By: cpojer fbshipit-source-id: 2ca6c5f3db9ff2c2986b02edda80bc73432f66d3
This commit is contained in:
committed by
Facebook Github Bot
parent
5194495e97
commit
794d2264f9
@@ -11,31 +11,31 @@ import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactTestHelper;
|
||||
import com.facebook.react.bridge.JavaOnlyMap;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactTestHelper;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.rule.PowerMockRule;
|
||||
import org.robolectric.internal.ShadowExtractor;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.internal.ShadowExtractor;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@@ -53,12 +53,14 @@ public class ShareModuleTest {
|
||||
@Before
|
||||
public void prepareModules() throws Exception {
|
||||
PowerMockito.mockStatic(Arguments.class);
|
||||
Mockito.when(Arguments.createMap()).thenAnswer(new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return new JavaOnlyMap();
|
||||
}
|
||||
});
|
||||
Mockito
|
||||
.when(Arguments.createMap())
|
||||
.thenAnswer(new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return new JavaOnlyMap();
|
||||
}
|
||||
});
|
||||
|
||||
mShareModule = new ShareModule(ReactTestHelper.createCatalystContextForTest());
|
||||
}
|
||||
@@ -83,17 +85,34 @@ public class ShareModuleTest {
|
||||
|
||||
mShareModule.share(content, dialogTitle, promise);
|
||||
|
||||
final Intent chooserIntent =
|
||||
((ShadowApplication)ShadowExtractor.extract(RuntimeEnvironment.application)).getNextStartedActivity();
|
||||
final Intent chooserIntent =
|
||||
((ShadowApplication) ShadowExtractor.extract(RuntimeEnvironment.application)).getNextStartedActivity();
|
||||
assertNotNull("Dialog was not displayed", chooserIntent);
|
||||
assertEquals(Intent.ACTION_CHOOSER, chooserIntent.getAction());
|
||||
assertEquals(dialogTitle, chooserIntent.getExtras().get(Intent.EXTRA_TITLE));
|
||||
assertEquals(
|
||||
dialogTitle,
|
||||
chooserIntent
|
||||
.getExtras()
|
||||
.get(Intent.EXTRA_TITLE)
|
||||
);
|
||||
|
||||
final Intent contentIntent = (Intent)chooserIntent.getExtras().get(Intent.EXTRA_INTENT);
|
||||
final Intent contentIntent = (Intent) chooserIntent
|
||||
.getExtras()
|
||||
.get(Intent.EXTRA_INTENT);
|
||||
assertNotNull("Intent was not built correctly", contentIntent);
|
||||
assertEquals(Intent.ACTION_SEND, contentIntent.getAction());
|
||||
assertEquals(title, contentIntent.getExtras().get(Intent.EXTRA_SUBJECT));
|
||||
assertEquals(message, contentIntent.getExtras().get(Intent.EXTRA_TEXT));
|
||||
assertEquals(
|
||||
title,
|
||||
contentIntent
|
||||
.getExtras()
|
||||
.get(Intent.EXTRA_SUBJECT)
|
||||
);
|
||||
assertEquals(
|
||||
message,
|
||||
contentIntent
|
||||
.getExtras()
|
||||
.get(Intent.EXTRA_TEXT)
|
||||
);
|
||||
|
||||
assertEquals(1, promise.getResolved());
|
||||
}
|
||||
@@ -111,7 +130,8 @@ public class ShareModuleTest {
|
||||
}
|
||||
|
||||
final static class SimplePromise implements Promise {
|
||||
private static final String DEFAULT_ERROR = "EUNSPECIFIED";
|
||||
private static final String ERROR_DEFAULT_CODE = "EUNSPECIFIED";
|
||||
private static final String ERROR_DEFAULT_MESSAGE = "Error not specified.";
|
||||
|
||||
private int mResolved;
|
||||
private int mRejected;
|
||||
@@ -126,7 +146,7 @@ public class ShareModuleTest {
|
||||
public int getRejected() {
|
||||
return mRejected;
|
||||
}
|
||||
|
||||
|
||||
public Object getValue() {
|
||||
return mValue;
|
||||
}
|
||||
@@ -147,31 +167,72 @@ public class ShareModuleTest {
|
||||
|
||||
@Override
|
||||
public void reject(String code, String message) {
|
||||
reject(code, message, /*Throwable*/null);
|
||||
reject(code, message, /*Throwable*/null, /*WritableMap*/null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, Throwable throwable) {
|
||||
reject(code, /*Message*/null, throwable, /*WritableMap*/null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, String message, Throwable throwable) {
|
||||
reject(code, message, throwable, /*WritableMap*/null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(Throwable throwable) {
|
||||
reject(/*Code*/null, /*Message*/null, throwable, /*WritableMap*/null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(Throwable throwable, WritableMap userInfo) {
|
||||
reject(/*Code*/null, /*Message*/null, throwable, userInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, @Nonnull WritableMap userInfo) {
|
||||
reject(code, /*Message*/null, /*Throwable*/null, userInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, Throwable throwable, WritableMap userInfo) {
|
||||
reject(code, /*Message*/null, throwable, userInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, String message, @Nonnull WritableMap userInfo) {
|
||||
reject(code, message, /*Throwable*/null, userInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(
|
||||
String code,
|
||||
String message,
|
||||
@Nullable Throwable throwable,
|
||||
@Nullable WritableMap userInfo
|
||||
) {
|
||||
mRejected++;
|
||||
|
||||
if (code == null) {
|
||||
mErrorCode = ERROR_DEFAULT_CODE;
|
||||
} else {
|
||||
mErrorCode = code;
|
||||
}
|
||||
|
||||
if (message != null) {
|
||||
mErrorMessage = message;
|
||||
} else if (throwable != null) {
|
||||
mErrorMessage = throwable.getMessage();
|
||||
} else {
|
||||
mErrorMessage = ERROR_DEFAULT_MESSAGE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void reject(String message) {
|
||||
reject(DEFAULT_ERROR, message, /*Throwable*/null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, Throwable e) {
|
||||
reject(code, e.getMessage(), e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(Throwable e) {
|
||||
reject(DEFAULT_ERROR, e.getMessage(), e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, String message, @Nullable Throwable e) {
|
||||
mRejected++;
|
||||
mErrorCode = code;
|
||||
mErrorMessage = message;
|
||||
reject(/*Code*/null, message, /*Throwable*/null, /*WritableMap*/null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user