Skip to content

Commit

Permalink
Convert ReactPropConstantsTest to Kotlin (#39005)
Browse files Browse the repository at this point in the history
Summary:
Converts ReactPropConstantsTest to Kotlin, as requested in #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: #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
  • Loading branch information
thiagobrez authored and facebook-github-bot committed Aug 17, 2023
1 parent 10feddc commit 4a48fd2
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ public BoxedColorPropSetter(ReactProp prop, Method setter) {
*/
/*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;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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
}
}
}

0 comments on commit 4a48fd2

Please sign in to comment.