mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-02 22:41:18 +08:00
Summary:
The way React DevTools integration was set up in RN was not entirely supported by the React team, and we had to disable it in c3b25c9059 so that we can move forward with enabling Fiber support in React Native.
Here, I am moving the DevTools client setup from RN repo to [React DevTools repo](https://github.com/facebook/react-devtools/blob/master/packages/react-devtools-core/README.md#requirereact-devtools-coreconnecttodevtoolsoptions) so that we can keep it in sync with the rest of React DevTools. This is also a part of a larger effort to consolidate DevTools code (https://github.com/facebook/react-devtools/issues/489). It allows us to remove the double injection of the hook, an lets us replace the `eval` hack with a regular dependency. The implementation [lives here now](https://github.com/facebook/react-devtools/blob/master/packages/react-devtools-core/src/backend.js).
This change re-enables Nuclide Inspector with React Native Stack reconciler and prepares it for compatibi
Closes https://github.com/facebook/react-native/pull/12316
Reviewed By: zertosh
Differential Revision: D4545322
Pulled By: gaearon
fbshipit-source-id: ab949916c1a92c6b41cd41e7e1edf9697a71de2e
763 lines
26 KiB
Java
763 lines
26 KiB
Java
/**
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
package com.facebook.react.tests;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
|
|
import com.facebook.react.bridge.BaseJavaModule;
|
|
import com.facebook.react.bridge.CatalystInstance;
|
|
import com.facebook.react.bridge.Dynamic;
|
|
import com.facebook.react.bridge.InvalidIteratorException;
|
|
import com.facebook.react.bridge.JavaScriptModule;
|
|
import com.facebook.react.bridge.NoSuchKeyException;
|
|
import com.facebook.react.bridge.ReactMethod;
|
|
import com.facebook.react.bridge.ReadableArray;
|
|
import com.facebook.react.bridge.ReadableMap;
|
|
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
import com.facebook.react.bridge.ReadableNativeMap;
|
|
import com.facebook.react.bridge.ReadableType;
|
|
import com.facebook.react.bridge.UiThreadUtil;
|
|
import com.facebook.react.bridge.UnexpectedNativeTypeException;
|
|
import com.facebook.react.bridge.WritableMap;
|
|
import com.facebook.react.bridge.WritableNativeMap;
|
|
import com.facebook.react.modules.appstate.AppStateModule;
|
|
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
|
|
import com.facebook.react.testing.FakeWebSocketModule;
|
|
import com.facebook.react.testing.ReactIntegrationTestCase;
|
|
import com.facebook.react.testing.ReactTestHelper;
|
|
import com.facebook.react.uimanager.UIImplementationProvider;
|
|
import com.facebook.react.uimanager.UIManagerModule;
|
|
import com.facebook.react.uimanager.ViewManager;
|
|
import com.facebook.react.views.view.ReactViewManager;
|
|
|
|
/**
|
|
* Integration test to verify passing various types of parameters from JS to Java works
|
|
*
|
|
* TODO: we should run these tests with isBlockingSynchronousMethod = true as well,
|
|
* since they currrently use a completely different codepath
|
|
*/
|
|
public class CatalystNativeJSToJavaParametersTestCase extends ReactIntegrationTestCase {
|
|
|
|
private interface TestJSToJavaParametersModule extends JavaScriptModule {
|
|
void returnBasicTypes();
|
|
void returnBoxedTypes();
|
|
void returnDynamicTypes();
|
|
|
|
void returnArrayWithBasicTypes();
|
|
void returnNestedArray();
|
|
void returnArrayWithMaps();
|
|
|
|
void returnMapWithBasicTypes();
|
|
void returnNestedMap();
|
|
void returnMapWithArrays();
|
|
|
|
void returnArrayWithStringDoubleIntMapArrayBooleanNull();
|
|
void returnMapWithStringDoubleIntMapArrayBooleanNull();
|
|
|
|
void returnMapForMerge1();
|
|
void returnMapForMerge2();
|
|
|
|
void returnMapWithMultibyteUTF8CharacterString();
|
|
void returnArrayWithMultibyteUTF8CharacterString();
|
|
|
|
void returnArrayWithLargeInts();
|
|
void returnMapWithLargeInts();
|
|
}
|
|
|
|
private RecordingTestModule mRecordingTestModule;
|
|
private CatalystInstance mCatalystInstance;
|
|
|
|
@Override
|
|
protected void setUp() throws Exception {
|
|
super.setUp();
|
|
|
|
List<ViewManager> viewManagers = Arrays.<ViewManager>asList(
|
|
new ReactViewManager());
|
|
final UIManagerModule mUIManager = new UIManagerModule(
|
|
getContext(),
|
|
viewManagers,
|
|
new UIImplementationProvider(),
|
|
false);
|
|
UiThreadUtil.runOnUiThread(
|
|
new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
mUIManager.onHostResume();
|
|
}
|
|
});
|
|
waitForIdleSync();
|
|
|
|
mRecordingTestModule = new RecordingTestModule();
|
|
mCatalystInstance = ReactTestHelper.catalystInstanceBuilder(this)
|
|
.addNativeModule(mRecordingTestModule)
|
|
.addNativeModule(new AndroidInfoModule())
|
|
.addNativeModule(new AppStateModule(getContext()))
|
|
.addNativeModule(new FakeWebSocketModule())
|
|
.addNativeModule(mUIManager)
|
|
.addJSModule(TestJSToJavaParametersModule.class)
|
|
.build();
|
|
}
|
|
|
|
public void testBasicTypes() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnBasicTypes();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<Object[]> basicTypesCalls = mRecordingTestModule.getBasicTypesCalls();
|
|
assertEquals(1, basicTypesCalls.size());
|
|
|
|
Object[] args = basicTypesCalls.get(0);
|
|
assertEquals("foo", args[0]);
|
|
assertEquals(3.14, args[1]);
|
|
assertEquals(true, args[2]);
|
|
assertNull(args[3]);
|
|
}
|
|
|
|
public void testBoxedTypes() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnBoxedTypes();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<Object[]> boxedTypesCalls = mRecordingTestModule.getBoxedTypesCalls();
|
|
assertEquals(1, boxedTypesCalls.size());
|
|
|
|
Object[] args = boxedTypesCalls.get(0);
|
|
assertEquals(Integer.valueOf(42), args[0]);
|
|
assertEquals(Double.valueOf(3.14), args[1]);
|
|
assertEquals(Boolean.valueOf(true), args[2]);
|
|
}
|
|
|
|
public void testDynamicType() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnDynamicTypes();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<Dynamic> dynamicCalls = mRecordingTestModule.getDynamicCalls();
|
|
assertEquals(2, dynamicCalls.size());
|
|
|
|
assertEquals("foo", dynamicCalls.get(0).asString());
|
|
assertEquals(3.14, dynamicCalls.get(1).asDouble());
|
|
}
|
|
|
|
public void testArrayWithBasicTypes() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnArrayWithBasicTypes();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableArray> calls = mRecordingTestModule.getArrayCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableArray array = calls.get(0);
|
|
assertNotNull(array);
|
|
assertEquals(5, array.size());
|
|
assertFalse(array.isNull(0));
|
|
assertEquals("foo", array.getString(0));
|
|
assertFalse(array.isNull(1));
|
|
assertEquals(3.14, array.getDouble(1));
|
|
assertFalse(array.isNull(2));
|
|
assertEquals(-111, array.getInt(2));
|
|
assertFalse(array.isNull(3));
|
|
assertTrue(array.getBoolean(3));
|
|
assertTrue(array.isNull(4));
|
|
assertEquals(null, array.getString(4));
|
|
assertEquals(null, array.getMap(4));
|
|
assertEquals(null, array.getArray(4));
|
|
}
|
|
|
|
public void testNestedArray() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnNestedArray();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableArray> calls = mRecordingTestModule.getArrayCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableArray array = calls.get(0);
|
|
assertNotNull(array);
|
|
assertEquals(2, array.size());
|
|
assertEquals("we", array.getString(0));
|
|
|
|
assertFalse(array.isNull(1));
|
|
ReadableArray subArray = array.getArray(1);
|
|
assertEquals(2, subArray.size());
|
|
assertEquals("have", subArray.getString(0));
|
|
|
|
subArray = subArray.getArray(1);
|
|
assertEquals(2, subArray.size());
|
|
assertEquals("to", subArray.getString(0));
|
|
|
|
subArray = subArray.getArray(1);
|
|
assertEquals(2, subArray.size());
|
|
assertEquals("go", subArray.getString(0));
|
|
|
|
subArray = subArray.getArray(1);
|
|
assertEquals(1, subArray.size());
|
|
assertEquals("deeper", subArray.getString(0));
|
|
}
|
|
|
|
public void testArrayWithMaps() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnArrayWithMaps();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableArray> calls = mRecordingTestModule.getArrayCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableArray array = calls.get(0);
|
|
assertEquals(2, array.size());
|
|
|
|
assertFalse(array.isNull(0));
|
|
ReadableMap m1 = array.getMap(0);
|
|
ReadableMap m2 = array.getMap(1);
|
|
|
|
assertEquals("m1v1", m1.getString("m1k1"));
|
|
assertEquals("m1v2", m1.getString("m1k2"));
|
|
assertEquals("m2v1", m2.getString("m2k1"));
|
|
}
|
|
|
|
public void testMapWithBasicTypes() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapWithBasicTypes();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> calls = mRecordingTestModule.getMapCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableMap map = calls.get(0);
|
|
assertNotNull(map);
|
|
|
|
assertTrue(map.hasKey("stringKey"));
|
|
assertFalse(map.isNull("stringKey"));
|
|
assertEquals("stringValue", map.getString("stringKey"));
|
|
|
|
assertTrue(map.hasKey("doubleKey"));
|
|
assertFalse(map.isNull("doubleKey"));
|
|
assertTrue(Math.abs(3.14 - map.getDouble("doubleKey")) < .0001);
|
|
|
|
assertTrue(map.hasKey("intKey"));
|
|
assertFalse(map.isNull("intKey"));
|
|
assertEquals(-11, map.getInt("intKey"));
|
|
|
|
assertTrue(map.hasKey("booleanKey"));
|
|
assertFalse(map.isNull("booleanKey"));
|
|
assertTrue(map.getBoolean("booleanKey"));
|
|
|
|
assertTrue(map.hasKey("nullKey"));
|
|
assertTrue(map.isNull("nullKey"));
|
|
assertNull(map.getString("nullKey"));
|
|
assertNull(map.getMap("nullKey"));
|
|
assertNull(map.getArray("nullKey"));
|
|
|
|
assertFalse(map.hasKey("nonExistentKey"));
|
|
}
|
|
|
|
public void testNestedMap() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnNestedMap();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> calls = mRecordingTestModule.getMapCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableMap map = calls.get(0);
|
|
assertNotNull(map);
|
|
|
|
assertTrue(map.hasKey("weHaveToGoDeeper"));
|
|
assertFalse(map.isNull("weHaveToGoDeeper"));
|
|
ReadableMap nestedMap = map.getMap("weHaveToGoDeeper");
|
|
assertTrue(nestedMap.hasKey("inception"));
|
|
assertTrue(nestedMap.getBoolean("inception"));
|
|
}
|
|
|
|
public void testMapParameterWithArrays() throws InterruptedException {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapWithArrays();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> calls = mRecordingTestModule.getMapCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableMap map = calls.get(0);
|
|
assertNotNull(map);
|
|
|
|
ReadableArray arrayParameter;
|
|
assertTrue(map.hasKey("empty"));
|
|
arrayParameter = map.getArray("empty");
|
|
assertNotNull(arrayParameter);
|
|
assertEquals(0, arrayParameter.size());
|
|
|
|
assertTrue(map.hasKey("ints"));
|
|
assertFalse(map.isNull("ints"));
|
|
arrayParameter = map.getArray("ints");
|
|
assertNotNull(arrayParameter);
|
|
assertEquals(2, arrayParameter.size());
|
|
assertEquals(43, arrayParameter.getInt(0));
|
|
assertEquals(44, arrayParameter.getInt(1));
|
|
|
|
assertTrue(map.hasKey("mixed"));
|
|
arrayParameter = map.getArray("mixed");
|
|
assertNotNull(arrayParameter);
|
|
assertEquals(3, arrayParameter.size());
|
|
assertEquals(77, arrayParameter.getInt(0));
|
|
assertEquals("string", arrayParameter.getString(1));
|
|
ReadableArray nestedArray = arrayParameter.getArray(2);
|
|
assertEquals(2, nestedArray.size());
|
|
}
|
|
|
|
public void testMapParameterDump() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapWithBasicTypes();
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnNestedMap();
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapWithArrays();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> calls = mRecordingTestModule.getMapCalls();
|
|
assertEquals(3, calls.size());
|
|
|
|
// App should not crash while generating debug string representation of arguments
|
|
assertNotNull(calls.get(0).toString());
|
|
assertNotNull(calls.get(1).toString());
|
|
assertNotNull(calls.get(2).toString());
|
|
}
|
|
|
|
public void testGetTypeFromArray() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class)
|
|
.returnArrayWithStringDoubleIntMapArrayBooleanNull();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableArray> calls = mRecordingTestModule.getArrayCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableArray array = calls.get(0);
|
|
|
|
assertEquals(ReadableType.String, array.getType(0));
|
|
assertEquals(ReadableType.Number, array.getType(1));
|
|
assertEquals(ReadableType.Number, array.getType(2));
|
|
assertEquals(ReadableType.Map, array.getType(3));
|
|
assertEquals(ReadableType.Array, array.getType(4));
|
|
assertEquals(ReadableType.Boolean, array.getType(5));
|
|
assertEquals(ReadableType.Null, array.getType(6));
|
|
}
|
|
|
|
public void testGetTypeFromMap() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class)
|
|
.returnMapWithStringDoubleIntMapArrayBooleanNull();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> calls = mRecordingTestModule.getMapCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableMap map = calls.get(0);
|
|
|
|
assertEquals(ReadableType.String, map.getType("string"));
|
|
assertEquals(ReadableType.Number, map.getType("double"));
|
|
assertEquals(ReadableType.Number, map.getType("int"));
|
|
assertEquals(ReadableType.Map, map.getType("map"));
|
|
assertEquals(ReadableType.Array, map.getType("array"));
|
|
assertEquals(ReadableType.Boolean, map.getType("boolean"));
|
|
assertEquals(ReadableType.Null, map.getType("null"));
|
|
}
|
|
|
|
public void testGetWrongTypeFromArray() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class)
|
|
.returnArrayWithStringDoubleIntMapArrayBooleanNull();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableArray> calls = mRecordingTestModule.getArrayCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableArray array = calls.get(0);
|
|
|
|
assertUnexpectedTypeExceptionThrown(array, 0, "boolean");
|
|
assertUnexpectedTypeExceptionThrown(array, 1, "string");
|
|
assertUnexpectedTypeExceptionThrown(array, 2, "array");
|
|
assertUnexpectedTypeExceptionThrown(array, 3, "double");
|
|
assertUnexpectedTypeExceptionThrown(array, 4, "map");
|
|
assertUnexpectedTypeExceptionThrown(array, 5, "array");
|
|
}
|
|
|
|
public void testGetWrongTypeFromMap() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class)
|
|
.returnMapWithStringDoubleIntMapArrayBooleanNull();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> calls = mRecordingTestModule.getMapCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableMap map = calls.get(0);
|
|
|
|
assertUnexpectedTypeExceptionThrown(map, "string", "double");
|
|
assertUnexpectedTypeExceptionThrown(map, "double", "map");
|
|
assertUnexpectedTypeExceptionThrown(map, "int", "boolean");
|
|
assertUnexpectedTypeExceptionThrown(map, "map", "array");
|
|
assertUnexpectedTypeExceptionThrown(map, "array", "boolean");
|
|
assertUnexpectedTypeExceptionThrown(map, "boolean", "string");
|
|
}
|
|
|
|
public void testArrayOutOfBoundsExceptionThrown() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnArrayWithBasicTypes();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableArray> calls = mRecordingTestModule.getArrayCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableArray array = calls.get(0);
|
|
assertNotNull(array);
|
|
|
|
assertArrayOutOfBoundsExceptionThrown(array, -1, "boolean");
|
|
assertArrayOutOfBoundsExceptionThrown(array, -1, "string");
|
|
assertArrayOutOfBoundsExceptionThrown(array, -1, "double");
|
|
assertArrayOutOfBoundsExceptionThrown(array, -1, "int");
|
|
assertArrayOutOfBoundsExceptionThrown(array, -1, "map");
|
|
assertArrayOutOfBoundsExceptionThrown(array, -1, "array");
|
|
|
|
assertArrayOutOfBoundsExceptionThrown(array, 10, "boolean");
|
|
assertArrayOutOfBoundsExceptionThrown(array, 10, "string");
|
|
assertArrayOutOfBoundsExceptionThrown(array, 10, "double");
|
|
assertArrayOutOfBoundsExceptionThrown(array, 10, "int");
|
|
assertArrayOutOfBoundsExceptionThrown(array, 10, "map");
|
|
assertArrayOutOfBoundsExceptionThrown(array, 10, "array");
|
|
}
|
|
|
|
public void testNoSuchKeyExceptionThrown() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapWithBasicTypes();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> calls = mRecordingTestModule.getMapCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableMap map = calls.get(0);
|
|
assertNotNull(map);
|
|
|
|
assertNoSuchKeyExceptionThrown(map, "noSuchKey", "double");
|
|
assertNoSuchKeyExceptionThrown(map, "noSuchKey", "int");
|
|
assertNoSuchKeyExceptionThrown(map, "noSuchKey", "map");
|
|
assertNoSuchKeyExceptionThrown(map, "noSuchKey", "array");
|
|
assertNoSuchKeyExceptionThrown(map, "noSuchKey", "boolean");
|
|
assertNoSuchKeyExceptionThrown(map, "noSuchKey", "string");
|
|
}
|
|
|
|
public void testIntOutOfRangeThrown() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnArrayWithLargeInts();
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapWithLargeInts();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
assertEquals(1, mRecordingTestModule.getArrayCalls().size());
|
|
assertEquals(1, mRecordingTestModule.getMapCalls().size());
|
|
|
|
ReadableArray array = mRecordingTestModule.getArrayCalls().get(0);
|
|
assertNotNull(array);
|
|
|
|
ReadableMap map = mRecordingTestModule.getMapCalls().get(0);
|
|
assertNotNull(map);
|
|
|
|
assertEquals(ReadableType.Number, array.getType(0));
|
|
assertUnexpectedTypeExceptionThrown(array, 0, "int");
|
|
assertEquals(ReadableType.Number, array.getType(1));
|
|
assertUnexpectedTypeExceptionThrown(array, 1, "int");
|
|
|
|
assertEquals(ReadableType.Number, map.getType("first"));
|
|
assertUnexpectedTypeExceptionThrown(map, "first", "int");
|
|
assertEquals(ReadableType.Number, map.getType("second"));
|
|
assertUnexpectedTypeExceptionThrown(map, "second", "int");
|
|
}
|
|
|
|
public void testMapMerging() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapForMerge1();
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapForMerge2();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> maps = mRecordingTestModule.getMapCalls();
|
|
assertEquals(2, maps.size());
|
|
|
|
WritableMap dest = new WritableNativeMap();
|
|
dest.merge(maps.get(0));
|
|
dest.merge(maps.get(1));
|
|
|
|
assertTrue(dest.hasKey("a"));
|
|
assertTrue(dest.hasKey("b"));
|
|
assertTrue(dest.hasKey("c"));
|
|
assertTrue(dest.hasKey("d"));
|
|
assertTrue(dest.hasKey("e"));
|
|
assertTrue(dest.hasKey("f"));
|
|
assertTrue(dest.hasKey("newkey"));
|
|
|
|
assertEquals("overwrite", dest.getString("a"));
|
|
assertEquals(41, dest.getInt("b"));
|
|
assertEquals("string", dest.getString("c"));
|
|
assertEquals(77, dest.getInt("d"));
|
|
assertTrue(dest.isNull("e"));
|
|
assertEquals(3, dest.getArray("f").size());
|
|
assertEquals("newvalue", dest.getString("newkey"));
|
|
}
|
|
|
|
public void testMapAccessibleAfterMerge() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapForMerge1();
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapForMerge2();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> maps = mRecordingTestModule.getMapCalls();
|
|
assertEquals(2, maps.size());
|
|
|
|
WritableMap dest = new WritableNativeMap();
|
|
dest.merge(maps.get(0));
|
|
dest.merge(maps.get(1));
|
|
|
|
ReadableMap source = maps.get(1);
|
|
|
|
assertTrue(source.hasKey("a"));
|
|
assertTrue(source.hasKey("d"));
|
|
assertTrue(source.hasKey("e"));
|
|
assertTrue(source.hasKey("f"));
|
|
assertTrue(source.hasKey("newkey"));
|
|
|
|
assertFalse(source.hasKey("b"));
|
|
assertFalse(source.hasKey("c"));
|
|
|
|
assertEquals("overwrite", source.getString("a"));
|
|
assertEquals(77, source.getInt("d"));
|
|
assertTrue(source.isNull("e"));
|
|
assertEquals(3, source.getArray("f").size());
|
|
assertEquals("newvalue", source.getString("newkey"));
|
|
}
|
|
|
|
public void testMapIterateOverMapWithBasicTypes() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapWithBasicTypes();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> calls = mRecordingTestModule.getMapCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableNativeMap map = (ReadableNativeMap) calls.get(0);
|
|
assertNotNull(map);
|
|
|
|
ReadableMapKeySetIterator mapIterator = map.keySetIterator();
|
|
Set<String> keys = new HashSet<String>();
|
|
while (mapIterator.hasNextKey()) {
|
|
keys.add(mapIterator.nextKey());
|
|
}
|
|
|
|
Set<String> expectedKeys = new HashSet<String>(
|
|
Arrays.asList("stringKey", "doubleKey", "intKey", "booleanKey", "nullKey"));
|
|
assertEquals(keys, expectedKeys);
|
|
}
|
|
|
|
public void testMapIterateOverNestedMaps() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnNestedMap();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> calls = mRecordingTestModule.getMapCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableNativeMap map = (ReadableNativeMap) calls.get(0);
|
|
assertNotNull(map);
|
|
|
|
ReadableMapKeySetIterator firstLevelIterator = map.keySetIterator();
|
|
String firstLevelKey = firstLevelIterator.nextKey();
|
|
assertEquals(firstLevelKey, "weHaveToGoDeeper");
|
|
|
|
ReadableNativeMap secondMap = map.getMap("weHaveToGoDeeper");
|
|
ReadableMapKeySetIterator secondLevelIterator = secondMap.keySetIterator();
|
|
String secondLevelKey = secondLevelIterator.nextKey();
|
|
assertEquals(secondLevelKey, "inception");
|
|
assertTrue(secondMap.getBoolean(secondLevelKey));
|
|
}
|
|
|
|
public void testInvalidIteratorExceptionThrown() {
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class).returnMapWithBasicTypes();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> calls = mRecordingTestModule.getMapCalls();
|
|
assertEquals(1, calls.size());
|
|
ReadableNativeMap map = (ReadableNativeMap) calls.get(0);
|
|
assertNotNull(map);
|
|
|
|
ReadableMapKeySetIterator mapIterator = map.keySetIterator();
|
|
while (mapIterator.hasNextKey()) {
|
|
mapIterator.nextKey();
|
|
}
|
|
assertInvalidIteratorExceptionThrown(mapIterator);
|
|
}
|
|
|
|
public void testStringWithMultibyteUTF8Characters() {
|
|
TestJSToJavaParametersModule jsModule =
|
|
mCatalystInstance.getJSModule(TestJSToJavaParametersModule.class);
|
|
jsModule.returnMapWithMultibyteUTF8CharacterString();
|
|
jsModule.returnArrayWithMultibyteUTF8CharacterString();
|
|
waitForBridgeAndUIIdle();
|
|
|
|
List<ReadableMap> maps = mRecordingTestModule.getMapCalls();
|
|
assertEquals(1, maps.size());
|
|
|
|
ReadableMap map = maps.get(0);
|
|
assertEquals("a", map.getString("one-byte"));
|
|
assertEquals("\u00A2", map.getString("two-bytes"));
|
|
assertEquals("\u20AC", map.getString("three-bytes"));
|
|
assertEquals("\uD83D\uDE1C", map.getString("four-bytes"));
|
|
assertEquals(
|
|
"\u017C\u00F3\u0142\u0107 g\u0119\u015Bl\u0105 \u6211 \uD83D\uDE0E ja\u017A\u0107",
|
|
map.getString("mixed"));
|
|
|
|
List<ReadableArray> arrays = mRecordingTestModule.getArrayCalls();
|
|
assertEquals(1, arrays.size());
|
|
|
|
ReadableArray array = arrays.get(0);
|
|
assertEquals("a", array.getString(0));
|
|
assertEquals("\u00A2", array.getString(1));
|
|
assertEquals("\u20AC", array.getString(2));
|
|
assertEquals("\uD83D\uDE1C", array.getString(3));
|
|
assertEquals(
|
|
"\u017C\u00F3\u0142\u0107 g\u0119\u015Bl\u0105 \u6211 \uD83D\uDE0E ja\u017A\u0107",
|
|
array.getString(4));
|
|
}
|
|
|
|
private void assertUnexpectedTypeExceptionThrown(
|
|
ReadableArray array,
|
|
int index,
|
|
String typeToAskFor) {
|
|
boolean gotException = false;
|
|
try {
|
|
arrayGetByType(array, index, typeToAskFor);
|
|
} catch (UnexpectedNativeTypeException expected) {
|
|
gotException = true;
|
|
}
|
|
|
|
assertTrue(gotException);
|
|
}
|
|
|
|
private void assertUnexpectedTypeExceptionThrown(
|
|
ReadableMap map,
|
|
String key,
|
|
String typeToAskFor) {
|
|
boolean gotException = false;
|
|
try {
|
|
mapGetByType(map, key, typeToAskFor);
|
|
} catch (UnexpectedNativeTypeException expected) {
|
|
gotException = true;
|
|
}
|
|
|
|
assertTrue(gotException);
|
|
}
|
|
|
|
private void assertArrayOutOfBoundsExceptionThrown(
|
|
ReadableArray array,
|
|
int index,
|
|
String typeToAskFor) {
|
|
boolean gotException = false;
|
|
try {
|
|
arrayGetByType(array, index, typeToAskFor);
|
|
} catch (ArrayIndexOutOfBoundsException expected) {
|
|
gotException = true;
|
|
}
|
|
|
|
assertTrue(gotException);
|
|
}
|
|
|
|
private void assertNoSuchKeyExceptionThrown(
|
|
ReadableMap map,
|
|
String key,
|
|
String typeToAskFor) {
|
|
boolean gotException = false;
|
|
try {
|
|
mapGetByType(map, key, typeToAskFor);
|
|
} catch (NoSuchKeyException expected) {
|
|
gotException = true;
|
|
}
|
|
|
|
assertTrue(gotException);
|
|
}
|
|
|
|
private static void assertInvalidIteratorExceptionThrown(
|
|
ReadableMapKeySetIterator iterator) {
|
|
boolean gotException = false;
|
|
try {
|
|
iterator.nextKey();
|
|
} catch (InvalidIteratorException expected) {
|
|
gotException = true;
|
|
}
|
|
|
|
assertTrue(gotException);
|
|
}
|
|
|
|
private void arrayGetByType(ReadableArray array, int index, String typeToAskFor) {
|
|
if (typeToAskFor.equals("double")) {
|
|
array.getDouble(index);
|
|
} else if (typeToAskFor.equals("int")) {
|
|
array.getInt(index);
|
|
} else if (typeToAskFor.equals("string")) {
|
|
array.getString(index);
|
|
} else if (typeToAskFor.equals("array")) {
|
|
array.getArray(index);
|
|
} else if (typeToAskFor.equals("map")) {
|
|
array.getMap(index);
|
|
} else if (typeToAskFor.equals("boolean")) {
|
|
array.getBoolean(index);
|
|
} else {
|
|
throw new RuntimeException("Unknown type: " + typeToAskFor);
|
|
}
|
|
}
|
|
|
|
private void mapGetByType(ReadableMap map, String key, String typeToAskFor) {
|
|
if (typeToAskFor.equals("double")) {
|
|
map.getDouble(key);
|
|
} else if (typeToAskFor.equals("int")) {
|
|
map.getInt(key);
|
|
} else if (typeToAskFor.equals("string")) {
|
|
map.getString(key);
|
|
} else if (typeToAskFor.equals("array")) {
|
|
map.getArray(key);
|
|
} else if (typeToAskFor.equals("map")) {
|
|
map.getMap(key);
|
|
} else if (typeToAskFor.equals("boolean")) {
|
|
map.getBoolean(key);
|
|
} else {
|
|
throw new RuntimeException("Unknown type: " + typeToAskFor);
|
|
}
|
|
}
|
|
|
|
private static class RecordingTestModule extends BaseJavaModule {
|
|
|
|
private final List<Object[]> mBasicTypesCalls = new ArrayList<Object[]>();
|
|
private final List<Object[]> mBoxedTypesCalls = new ArrayList<Object[]>();
|
|
private final List<ReadableArray> mArrayCalls = new ArrayList<ReadableArray>();
|
|
private final List<ReadableMap> mMapCalls = new ArrayList<ReadableMap>();
|
|
private final List<Dynamic> mDynamicCalls = new ArrayList<Dynamic>();
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "Recording";
|
|
}
|
|
|
|
@ReactMethod
|
|
public void receiveBasicTypes(String s, double d, boolean b, String nullableString) {
|
|
mBasicTypesCalls.add(new Object[]{s, d, b, nullableString});
|
|
}
|
|
|
|
@ReactMethod
|
|
public void receiveBoxedTypes(Integer i, Double d, Boolean b) {
|
|
mBoxedTypesCalls.add(new Object[]{i, d, b});
|
|
}
|
|
|
|
@ReactMethod
|
|
public void receiveArray(ReadableArray array) {
|
|
mArrayCalls.add(array);
|
|
}
|
|
|
|
@ReactMethod
|
|
public void receiveMap(ReadableMap map) {
|
|
mMapCalls.add(map);
|
|
}
|
|
|
|
@ReactMethod
|
|
public void receiveDynamic(Dynamic dynamic) {
|
|
mDynamicCalls.add(dynamic);
|
|
}
|
|
|
|
public List<Object[]> getBasicTypesCalls() {
|
|
return mBasicTypesCalls;
|
|
}
|
|
|
|
public List<Object[]> getBoxedTypesCalls() {
|
|
return mBoxedTypesCalls;
|
|
}
|
|
|
|
public List<ReadableArray> getArrayCalls() {
|
|
return mArrayCalls;
|
|
}
|
|
|
|
public List<ReadableMap> getMapCalls() {
|
|
return mMapCalls;
|
|
}
|
|
|
|
public List<Dynamic> getDynamicCalls() {
|
|
return mDynamicCalls;
|
|
}
|
|
}
|
|
}
|