text: /*
   * Copyright (c) Facebook, Inc. and its affiliates.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   */
  
  #include <exception>
  
  #include <glog/logging.h>
  #include <gtest/gtest.h>
  #include <react/uimanager/ComponentDescriptorFactory.h>
  #include <react/uimanager/UITemplateProcessor.h>
  
  using namespace facebook::react;
  
  #include <react/components/rncore/ComponentDescriptors.h>
  #include <react/components/scrollview/ScrollViewComponentDescriptor.h>
  #include <react/components/view/ViewComponentDescriptor.h>
  #include <react/config/ReactNativeConfig.h>
  #include <react/uimanager/ComponentDescriptorFactory.h>
  #include <react/uimanager/ComponentDescriptorRegistry.h>
  #include <react/utils/ContextContainer.h>
  
  namespace facebook {
  namespace react {
  
  static ComponentRegistryFactory getComponentRegistryFactory() {
    return [](const EventDispatcher::Weak &eventDispatcher,
              const ContextContainer::Shared &contextContainer) {
      auto registry = std::make_shared<ComponentDescriptorRegistry>();
      registry->registerComponentDescriptor(
          std::make_shared<ViewComponentDescriptor>(eventDispatcher));
      registry->registerComponentDescriptor(
          std::make_shared<ScrollViewComponentDescriptor>(eventDispatcher));
      registry->registerComponentDescriptor(
          std::make_shared<ActivityIndicatorViewComponentDescriptor>(
              eventDispatcher));
      return registry;
    };
  }
  
  bool mockSimpleTestValue_;
  
  NativeModuleRegistry buildNativeModuleRegistry();
  
  NativeModuleRegistry buildNativeModuleRegistry() {
    NativeModuleRegistry nMR;
    nMR.registerModule(
        "MobileConfig",
        [&](const std::string &methodName, const folly::dynamic &args) {
          return mockSimpleTestValue_;
        });
    return nMR;
  }
  
  class MockReactNativeConfig : public ReactNativeConfig {
   public:
    MockReactNativeConfig() {}
    bool getBool(const std::string &param) const override {
      return mockSimpleTestValue_;
    }
  
    std::string getString(const std::string &param) const override {
      return "";
    }
  
    int64_t getInt64(const std::string &param) const override {
      return 0;
    }
  
    double getDouble(const std::string &param) const override {
      return 0.0;
    }
  };
  
  std::shared_ptr<const ReactNativeConfig> mockReactNativeConfig_ =
      std::make_shared<const MockReactNativeConfig>();
  
  } // namespace react
  } // namespace facebook
  
  TEST(UITemplateProcessorTest, testSimpleBytecode) {
    auto surfaceId = 11;
    auto eventDispatcher = std::shared_ptr<EventDispatcher const>();
    auto componentDescriptorRegistry =
        getComponentRegistryFactory()(eventDispatcher, nullptr);
    auto nativeModuleRegistry = buildNativeModuleRegistry();
  
    auto bytecode = R"delim({"version":0.1,"commands":[
      ["createNode",2,"RCTView",-1,{"opacity": 0.5, "testId": "root"}],
      ["createNode",4,"RCTView",2,{"testId": "child"}],
      ["returnRoot",2]
    ]})delim";
  
    mockSimpleTestValue_ = true;
  
    auto root1 = UITemplateProcessor::buildShadowTree(
        bytecode,
        surfaceId,
        folly::dynamic::object(),
        *componentDescriptorRegistry,
        nativeModuleRegistry,
        mockReactNativeConfig_);
  #ifndef NDEBUG
    LOG(INFO) << std::endl << root1->getDebugDescription();
  #endif
    auto props1 = std::dynamic_pointer_cast<const ViewProps>(root1->getProps());
    ASSERT_NEAR(props1->opacity, 0.5, 0.001);
    ASSERT_STREQ(props1->testId.c_str(), "root");
    auto children1 = root1->getChildren();
    ASSERT_EQ(children1.size(), 1);
    auto child_props1 =
        std::dynamic_pointer_cast<const ViewProps>(children1.at(0)->getProps());
    ASSERT_STREQ(child_props1->testId.c_str(), "child");
  }
  
  TEST(UITemplateProcessorTest, testConditionalBytecode) {
    auto surfaceId = 11;
    auto eventDispatcher = std::shared_ptr<EventDispatcher const>();
    auto componentDescriptorRegistry =
        getComponentRegistryFactory()(eventDispatcher, nullptr);
    auto nativeModuleRegistry = buildNativeModuleRegistry();
  
    auto bytecode = R"delim({"version":0.1,"commands":[
      ["createNode",2,"RCTView",-1,{"testId": "root"}],
      ["loadNativeBool",1,"MobileConfig","getBool",["qe:simple_test"]],
      ["conditional",1,
        [["createNode",4,"RCTView",2,{"testId": "cond_true"}]],
        [["createNode",4,"RCTView",2,{"testId": "cond_false"}]]
      ],
      ["returnRoot",2]
    ]})delim";
  
    mockSimpleTestValue_ = true;
  
    auto root1 = UITemplateProcessor::buildShadowTree(
        bytecode,
        surfaceId,
        folly::dynamic::object(),
        *componentDescriptorRegistry,
        nativeModuleRegistry,
        mockReactNativeConfig_);
  #ifndef NDEBUG
    LOG(INFO) << std::endl << root1->getDebugDescription();
  #endif
    auto props1 = std::dynamic_pointer_cast<const ViewProps>(root1->getProps());
    ASSERT_STREQ(props1->testId.c_str(), "root");
    auto children1 = root1->getChildren();
    ASSERT_EQ(children1.size(), 1);
    auto child_props1 =
        std::dynamic_pointer_cast<const ViewProps>(children1.at(0)->getProps());
    ASSERT_STREQ(child_props1->testId.c_str(), "cond_true");
  
    mockSimpleTestValue_ = false;
  
    auto root2 = UITemplateProcessor::buildShadowTree(
        bytecode,
        surfaceId,
        folly::dynamic::object(),
        *componentDescriptorRegistry,
        nativeModuleRegistry,
        mockReactNativeConfig_);
    auto child_props2 = std::dynamic_pointer_cast<const ViewProps>(
        root2->getChildren().at(0)->getProps());
    ASSERT_STREQ(child_props2->testId.c_str(), "cond_false");
  }
  