/** * Copyright (c) 2015-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.uimanager; import java.util.Arrays; import java.util.List; import java.util.Map; 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.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.modules.junit4.rule.PowerMockRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import static org.fest.assertions.api.Assertions.assertThat; import static org.fest.assertions.api.Assertions.fail; /** * Verifies that prop constants are generated properly based on {@code ReactProp} annotation. */ @RunWith(RobolectricTestRunner.class) @PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"}) public class ReactPropConstantsTest { @Rule public PowerMockRule rule = new PowerMockRule(); 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.application); UIManagerModule uiManagerModule = new UIManagerModule( reactContext, viewManagers, new UIImplementationProvider()); 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; } }