object_factory_ut.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include <library/cpp/object_factory/object_factory.h>
  2. #include <library/cpp/testing/unittest/registar.h>
  3. #include <util/generic/noncopyable.h>
  4. #include <util/generic/string.h>
  5. #include <util/generic/ptr.h>
  6. using namespace NObjectFactory;
  7. struct TArgument {
  8. TString Name;
  9. void* Discarded;
  10. };
  11. class ICommonInterface {
  12. public:
  13. virtual ~ICommonInterface() {
  14. }
  15. virtual TString GetValue() const = 0;
  16. };
  17. class TDirectOrder: public ICommonInterface {
  18. public:
  19. TDirectOrder(const TString& provider, float factor, TArgument& argument)
  20. : Provider(provider)
  21. , Factor(factor)
  22. , Argument(argument)
  23. {
  24. }
  25. TString GetValue() const override {
  26. return Provider + ToString(Factor) + Argument.Name;
  27. }
  28. private:
  29. const TString Provider;
  30. const float Factor;
  31. const TArgument Argument;
  32. };
  33. class TInverseOrder: public ICommonInterface {
  34. public:
  35. TInverseOrder(const TString& provider, float factor, TArgument& argument)
  36. : Provider(provider)
  37. , Factor(factor)
  38. , Argument(argument)
  39. {
  40. }
  41. TString GetValue() const override {
  42. return Argument.Name + ToString(Factor) + Provider;
  43. }
  44. private:
  45. const TString Provider;
  46. const float Factor;
  47. const TArgument Argument;
  48. };
  49. struct TDirectOrderCreator: public IFactoryObjectCreator<ICommonInterface, const TString&, float, TArgument&> {
  50. ICommonInterface* Create(const TString& provider, float factor, TArgument& argument) const override {
  51. ++CallsCounter;
  52. return new TDirectOrder(provider, factor, argument);
  53. }
  54. static int CallsCounter;
  55. };
  56. int TDirectOrderCreator::CallsCounter = 0;
  57. using TTestFactory = TParametrizedObjectFactory<ICommonInterface, TString, const TString&, float, TArgument&>;
  58. static TTestFactory::TRegistrator<TDirectOrder> Direct("direct", new TDirectOrderCreator);
  59. static TTestFactory::TRegistrator<TInverseOrder> Inverse("inverse");
  60. class IMoveableOnlyInterface {
  61. public:
  62. virtual ~IMoveableOnlyInterface() {
  63. }
  64. virtual TString GetValue() const = 0;
  65. };
  66. class TMoveableOnly: public IMoveableOnlyInterface, public TMoveOnly {
  67. public:
  68. TMoveableOnly(TString&& value)
  69. : Value(value)
  70. {}
  71. TString GetValue() const override {
  72. return Value;
  73. }
  74. private:
  75. const TString Value;
  76. };
  77. using TMoveableOnlyFactory = TParametrizedObjectFactory<IMoveableOnlyInterface, TString, TString&&>;
  78. static TMoveableOnlyFactory::TRegistrator<TMoveableOnly> MoveableOnlyReg("move");
  79. class TMoveableOnly2: public IMoveableOnlyInterface, public TMoveOnly {
  80. public:
  81. TMoveableOnly2(THolder<TString>&& value)
  82. : Value(std::move(value))
  83. {}
  84. TString GetValue() const override {
  85. return *Value;
  86. }
  87. private:
  88. const THolder<TString> Value;
  89. };
  90. using TMoveableOnly2Factory = TParametrizedObjectFactory<IMoveableOnlyInterface, TString, THolder<TString>&&>;
  91. static TMoveableOnly2Factory::TRegistrator<TMoveableOnly2> MoveableOnly2Reg("move2");
  92. class TDirectOrderDifferentSignature : public TDirectOrder {
  93. public:
  94. TDirectOrderDifferentSignature(const TString& provider, TArgument& argument) :
  95. TDirectOrder(provider, 0.01f, argument)
  96. {
  97. }
  98. };
  99. struct TDirectOrderDSCreator: public IFactoryObjectCreator<ICommonInterface, const TString&, float, TArgument&> {
  100. ICommonInterface* Create(const TString& provider, float factor, TArgument& argument) const override {
  101. Y_UNUSED(factor);
  102. return new TDirectOrderDifferentSignature(provider, argument);
  103. }
  104. };
  105. static TTestFactory::TRegistrator<TDirectOrderDifferentSignature> DirectDs("direct_ds", new TDirectOrderDSCreator);
  106. Y_UNIT_TEST_SUITE(TestObjectFactory) {
  107. Y_UNIT_TEST(TestParametrized) {
  108. TArgument directArg{"Name", nullptr};
  109. TArgument inverseArg{"Fake", nullptr};
  110. THolder<ICommonInterface> direct(TTestFactory::Construct("direct", "prov", 0.42, directArg));
  111. THolder<ICommonInterface> inverse(TTestFactory::Construct("inverse", "prov2", 1, inverseArg));
  112. UNIT_ASSERT(!!direct);
  113. UNIT_ASSERT(!!inverse);
  114. UNIT_ASSERT(direct->GetValue() == "prov0.42Name");
  115. UNIT_ASSERT(inverse->GetValue() == "Fake1prov2");
  116. UNIT_ASSERT_EQUAL(TDirectOrderCreator::CallsCounter, 1);
  117. }
  118. Y_UNIT_TEST(TestMoveableOnly) {
  119. TString v = "value1";
  120. THolder<IMoveableOnlyInterface> moveableOnly(TMoveableOnlyFactory::Construct("move", std::move(v)));
  121. UNIT_ASSERT(!!moveableOnly);
  122. UNIT_ASSERT(moveableOnly->GetValue() == "value1");
  123. }
  124. Y_UNIT_TEST(TestMoveableOnly2) {
  125. THolder<TString> v = MakeHolder<TString>("value2");
  126. THolder<IMoveableOnlyInterface> moveableOnly2(TMoveableOnly2Factory::Construct("move2", std::move(v)));
  127. UNIT_ASSERT(!!moveableOnly2);
  128. UNIT_ASSERT(moveableOnly2->GetValue() == "value2");
  129. }
  130. Y_UNIT_TEST(TestDifferentSignature) {
  131. TArgument directArg{"Name", nullptr};
  132. THolder<ICommonInterface> directDs(TTestFactory::Construct("direct_ds", "prov", 0.42, directArg));
  133. UNIT_ASSERT(!!directDs);
  134. UNIT_ASSERT_EQUAL(directDs->GetValue(), "prov0.01Name");
  135. }
  136. }