mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Convert ReactPropConstantsTest to Kotlin (#39005)
Summary: Converts ReactPropConstantsTest to Kotlin, as requested in https://github.com/facebook/react-native/issues/38825 ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [INTERNAL] [CHANGED] - Convert ReactPropConstantsTest to Kotlin [INTERNAL] [CHANGED] - Add null-check to ViewManagersPropertyCache.java Pull Request resolved: https://github.com/facebook/react-native/pull/39005 Test Plan: 1. Run `./gradlew :packages:react-native:ReactAndroid:test`. 2. All tests should pass. Reviewed By: mdvacca, rshest Differential Revision: D48430460 Pulled By: cortinico fbshipit-source-id: cc425f14bf15ec6e5a334c631d52ca962d06a2a9
This commit is contained in:
committed by
Facebook GitHub Bot
parent
10feddcf03
commit
4a48fd2bb5
+5
@@ -393,6 +393,11 @@ import java.util.Map;
|
||||
*/
|
||||
/*package*/ static Map<String, PropSetter> getNativePropSettersForShadowNodeClass(
|
||||
Class<? extends ReactShadowNode> cls) {
|
||||
if (cls == null) {
|
||||
return EMPTY_PROPS_MAP;
|
||||
}
|
||||
;
|
||||
|
||||
for (Class iface : cls.getInterfaces()) {
|
||||
if (iface == ReactShadowNode.class) {
|
||||
return EMPTY_PROPS_MAP;
|
||||
|
||||
-159
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* 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.uimanager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
import android.view.View;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.facebook.react.uimanager.annotations.ReactPropGroup;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
/** Verifies that prop constants are generated properly based on {@code ReactProp} annotation. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Ignore // TODO T14964130
|
||||
public class ReactPropConstantsTest {
|
||||
|
||||
private class ViewManagerUnderTest extends ViewManager<View, ReactShadowNode> {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SomeView";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReactShadowNode createShadowNodeInstance() {
|
||||
fail("This method should not be executed as a part of this test");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View createViewInstance(ThemedReactContext reactContext) {
|
||||
fail("This method should not be executed as a part of this test");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ReactShadowNode> getShadowNodeClass() {
|
||||
return ReactShadowNode.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateExtraData(View root, Object extraData) {
|
||||
fail("This method should not be executed as a part of this test");
|
||||
}
|
||||
|
||||
@ReactProp(name = "boolProp")
|
||||
public void setBoolProp(View v, boolean value) {}
|
||||
|
||||
@ReactProp(name = "intProp")
|
||||
public void setIntProp(View v, int value) {}
|
||||
|
||||
@ReactProp(name = "floatProp")
|
||||
public void setFloatProp(View v, float value) {}
|
||||
|
||||
@ReactProp(name = "doubleProp")
|
||||
public void setDoubleProp(View v, double value) {}
|
||||
|
||||
@ReactProp(name = "stringProp")
|
||||
public void setStringProp(View v, String value) {}
|
||||
|
||||
@ReactProp(name = "boxedBoolProp")
|
||||
public void setBoxedBoolProp(View v, Boolean value) {}
|
||||
|
||||
@ReactProp(name = "boxedIntProp")
|
||||
public void setBoxedIntProp(View v, Integer value) {}
|
||||
|
||||
@ReactProp(name = "arrayProp")
|
||||
public void setArrayProp(View v, ReadableArray value) {}
|
||||
|
||||
@ReactProp(name = "mapProp")
|
||||
public void setMapProp(View v, ReadableMap value) {}
|
||||
|
||||
@ReactPropGroup(
|
||||
names = {
|
||||
"floatGroupPropFirst",
|
||||
"floatGroupPropSecond",
|
||||
})
|
||||
public void setFloatGroupProp(View v, int index, float value) {}
|
||||
|
||||
@ReactPropGroup(names = {"intGroupPropFirst", "intGroupPropSecond"})
|
||||
public void setIntGroupProp(View v, int index, int value) {}
|
||||
|
||||
@ReactPropGroup(
|
||||
names = {
|
||||
"boxedIntGroupPropFirst",
|
||||
"boxedIntGroupPropSecond",
|
||||
})
|
||||
public void setBoxedIntGroupProp(View v, int index, Integer value) {}
|
||||
|
||||
@ReactProp(name = "customIntProp", customType = "date")
|
||||
public void customIntProp(View v, int value) {}
|
||||
|
||||
@ReactPropGroup(
|
||||
names = {"customBoxedIntGroupPropFirst", "customBoxedIntGroupPropSecond"},
|
||||
customType = "color")
|
||||
public void customIntGroupProp(View v, int index, Integer value) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNativePropsIncludeCorrectTypes() {
|
||||
List<ViewManager> viewManagers = Arrays.<ViewManager>asList(new ViewManagerUnderTest());
|
||||
ReactApplicationContext reactContext =
|
||||
new ReactApplicationContext(RuntimeEnvironment.getApplication());
|
||||
UIManagerModule uiManagerModule = new UIManagerModule(reactContext, viewManagers, 0);
|
||||
Map<String, String> constants =
|
||||
(Map) valueAtPath(uiManagerModule.getConstants(), "SomeView", "NativeProps");
|
||||
assertThat(constants)
|
||||
.isEqualTo(
|
||||
MapBuilder.<String, String>builder()
|
||||
.put("boolProp", "boolean")
|
||||
.put("intProp", "number")
|
||||
.put("doubleProp", "number")
|
||||
.put("floatProp", "number")
|
||||
.put("stringProp", "String")
|
||||
.put("boxedBoolProp", "boolean")
|
||||
.put("boxedIntProp", "number")
|
||||
.put("arrayProp", "Array")
|
||||
.put("mapProp", "Map")
|
||||
.put("floatGroupPropFirst", "number")
|
||||
.put("floatGroupPropSecond", "number")
|
||||
.put("intGroupPropFirst", "number")
|
||||
.put("intGroupPropSecond", "number")
|
||||
.put("boxedIntGroupPropFirst", "number")
|
||||
.put("boxedIntGroupPropSecond", "number")
|
||||
.put("customIntProp", "date")
|
||||
.put("customBoxedIntGroupPropFirst", "color")
|
||||
.put("customBoxedIntGroupPropSecond", "color")
|
||||
.build());
|
||||
}
|
||||
|
||||
private static Object valueAtPath(Map nestedMap, String... keyPath) {
|
||||
assertThat(keyPath).isNotEmpty();
|
||||
Object value = nestedMap;
|
||||
for (String key : keyPath) {
|
||||
assertThat(value).isInstanceOf(Map.class);
|
||||
nestedMap = (Map) value;
|
||||
assertThat(nestedMap).containsKey(key);
|
||||
value = nestedMap.get(key);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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.uimanager
|
||||
|
||||
import android.view.View
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.bridge.ReadableArray
|
||||
import com.facebook.react.bridge.ReadableMap
|
||||
import com.facebook.react.common.MapBuilder
|
||||
import com.facebook.react.uimanager.annotations.ReactProp
|
||||
import com.facebook.react.uimanager.annotations.ReactPropGroup
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.RuntimeEnvironment
|
||||
|
||||
/** Verifies that prop constants are generated properly based on `ReactProp` annotation. */
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class ReactPropConstantsTest {
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private inner class ViewManagerUnderTest : ViewManager<View?, ReactShadowNode<*>?>() {
|
||||
override fun getName(): String {
|
||||
return "SomeView"
|
||||
}
|
||||
|
||||
override fun createShadowNodeInstance(): ReactShadowNode<*>? {
|
||||
Assertions.fail<Any>("This method should not be executed as a part of this test")
|
||||
return null
|
||||
}
|
||||
|
||||
override fun createViewInstance(reactContext: ThemedReactContext): View {
|
||||
Assertions.fail<Any>("This method should not be executed as a part of this test")
|
||||
return View(reactContext)
|
||||
}
|
||||
|
||||
override fun getShadowNodeClass(): Class<out ReactShadowNode<*>> {
|
||||
return ReactShadowNode::class.java
|
||||
}
|
||||
|
||||
override fun updateExtraData(root: View, extraData: Any) {
|
||||
Assertions.fail<Any>("This method should not be executed as a part of this test")
|
||||
}
|
||||
|
||||
@ReactProp(name = "boolProp") fun setBoolProp(v: View?, value: Boolean) {}
|
||||
|
||||
@ReactProp(name = "intProp") fun setIntProp(v: View?, value: Int) {}
|
||||
|
||||
@ReactProp(name = "floatProp") fun setFloatProp(v: View?, value: Float) {}
|
||||
|
||||
@ReactProp(name = "doubleProp") fun setDoubleProp(v: View?, value: Double) {}
|
||||
|
||||
@ReactProp(name = "stringProp") fun setStringProp(v: View?, value: String?) {}
|
||||
|
||||
@ReactProp(name = "boxedBoolProp") fun setBoxedBoolProp(v: View?, value: Boolean?) {}
|
||||
|
||||
@ReactProp(name = "boxedIntProp") fun setBoxedIntProp(v: View?, value: Int?) {}
|
||||
|
||||
@ReactProp(name = "arrayProp") fun setArrayProp(v: View?, value: ReadableArray?) {}
|
||||
|
||||
@ReactProp(name = "mapProp") fun setMapProp(v: View?, value: ReadableMap?) {}
|
||||
|
||||
@ReactPropGroup(names = ["floatGroupPropFirst", "floatGroupPropSecond"])
|
||||
fun setFloatGroupProp(v: View?, index: Int, value: Float) {}
|
||||
|
||||
@ReactPropGroup(names = ["intGroupPropFirst", "intGroupPropSecond"])
|
||||
fun setIntGroupProp(v: View?, index: Int, value: Int) {}
|
||||
|
||||
@ReactPropGroup(names = ["boxedIntGroupPropFirst", "boxedIntGroupPropSecond"])
|
||||
fun setBoxedIntGroupProp(v: View?, index: Int, value: Int?) {}
|
||||
|
||||
@ReactProp(name = "customIntProp", customType = "date")
|
||||
fun customIntProp(v: View?, value: Int) {}
|
||||
|
||||
@ReactPropGroup(
|
||||
names = ["customBoxedIntGroupPropFirst", "customBoxedIntGroupPropSecond"],
|
||||
customType = "color")
|
||||
fun customIntGroupProp(v: View?, index: Int, value: Int?) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNativePropsIncludeCorrectTypes() {
|
||||
val viewManagers = listOf<ViewManager<*, *>>(ViewManagerUnderTest())
|
||||
val reactContext = ReactApplicationContext(RuntimeEnvironment.getApplication())
|
||||
val uiManagerModule = UIManagerModule(reactContext, viewManagers, 0)
|
||||
val constants: Map<*, *> =
|
||||
valueAtPath(uiManagerModule.constants as Map<*, *>, "SomeView", "NativeProps")
|
||||
|
||||
Assertions.assertThat(constants)
|
||||
.isEqualTo(
|
||||
MapBuilder.builder<String, String>()
|
||||
.put("boolProp", "boolean")
|
||||
.put("intProp", "number")
|
||||
.put("doubleProp", "number")
|
||||
.put("floatProp", "number")
|
||||
.put("stringProp", "String")
|
||||
.put("boxedBoolProp", "boolean")
|
||||
.put("boxedIntProp", "number")
|
||||
.put("arrayProp", "Array")
|
||||
.put("mapProp", "Map")
|
||||
.put("floatGroupPropFirst", "number")
|
||||
.put("floatGroupPropSecond", "number")
|
||||
.put("intGroupPropFirst", "number")
|
||||
.put("intGroupPropSecond", "number")
|
||||
.put("boxedIntGroupPropFirst", "number")
|
||||
.put("boxedIntGroupPropSecond", "number")
|
||||
.put("customIntProp", "date")
|
||||
.put("customBoxedIntGroupPropFirst", "color")
|
||||
.put("customBoxedIntGroupPropSecond", "color")
|
||||
.build())
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun valueAtPath(nestedMap: Map<*, *>, vararg keyPath: String): Map<*, *> {
|
||||
require(keyPath.isNotEmpty()) { "keyPath must not be empty" }
|
||||
var value: Map<*, *> = nestedMap
|
||||
for (key in keyPath) {
|
||||
require(key in value) { "Key '$key' not found in the map" }
|
||||
require(value[key] is Map<*, *>) { "Key '$key' must be a map itself" }
|
||||
value = value[key] as Map<*, *>
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user