binsaver_ut.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include <library/cpp/binsaver/util_stream_io.h>
  2. #include <library/cpp/binsaver/mem_io.h>
  3. #include <library/cpp/binsaver/bin_saver.h>
  4. #include <library/cpp/binsaver/ut_util/ut_util.h>
  5. #include <library/cpp/testing/unittest/registar.h>
  6. #include <util/stream/buffer.h>
  7. #include <util/generic/map.h>
  8. struct TBinarySerializable {
  9. ui32 Data = 0;
  10. };
  11. struct TNonBinarySerializable {
  12. ui32 Data = 0;
  13. TString StrData;
  14. };
  15. struct TCustomSerializer {
  16. ui32 Data = 0;
  17. TString StrData;
  18. SAVELOAD(StrData, Data);
  19. };
  20. struct TCustomOuterSerializer {
  21. ui32 Data = 0;
  22. TString StrData;
  23. };
  24. void operator&(TCustomOuterSerializer& s, IBinSaver& f);
  25. struct TCustomOuterSerializerTmpl {
  26. ui32 Data = 0;
  27. TString StrData;
  28. };
  29. struct TCustomOuterSerializerTmplDerived: public TCustomOuterSerializerTmpl {
  30. ui32 Data = 0;
  31. TString StrData;
  32. };
  33. struct TMoveOnlyType {
  34. ui32 Data = 0;
  35. TMoveOnlyType() = default;
  36. TMoveOnlyType(TMoveOnlyType&&) = default;
  37. bool operator==(const TMoveOnlyType& obj) const {
  38. return Data == obj.Data;
  39. }
  40. };
  41. struct TTypeWithArray {
  42. ui32 Data = 1;
  43. TString Array[2][2]{{"test", "data"}, {"and", "more"}};
  44. SAVELOAD(Data, Array);
  45. bool operator==(const TTypeWithArray& obj) const {
  46. return Data == obj.Data && std::equal(std::begin(Array[0]), std::end(Array[0]), obj.Array[0]) && std::equal(std::begin(Array[1]), std::end(Array[1]), obj.Array[1]);
  47. }
  48. };
  49. template <typename T, typename = std::enable_if_t<std::is_base_of<TCustomOuterSerializerTmpl, T>::value>>
  50. int operator&(T& s, IBinSaver& f);
  51. static bool operator==(const TBlob& l, const TBlob& r) {
  52. return TStringBuf(l.AsCharPtr(), l.Size()) == TStringBuf(r.AsCharPtr(), r.Size());
  53. }
  54. Y_UNIT_TEST_SUITE(BinSaver){
  55. Y_UNIT_TEST(HasTrivialSerializer){
  56. UNIT_ASSERT(!IBinSaver::HasNonTrivialSerializer<TBinarySerializable>(0u));
  57. UNIT_ASSERT(!IBinSaver::HasNonTrivialSerializer<TNonBinarySerializable>(0u));
  58. UNIT_ASSERT(IBinSaver::HasNonTrivialSerializer<TCustomSerializer>(0u));
  59. UNIT_ASSERT(IBinSaver::HasNonTrivialSerializer<TCustomOuterSerializer>(0u));
  60. UNIT_ASSERT(IBinSaver::HasNonTrivialSerializer<TCustomOuterSerializerTmpl>(0u));
  61. UNIT_ASSERT(IBinSaver::HasNonTrivialSerializer<TCustomOuterSerializerTmplDerived>(0u));
  62. UNIT_ASSERT(IBinSaver::HasNonTrivialSerializer<TVector<TCustomSerializer>>(0u));
  63. }
  64. Y_UNIT_TEST(TestStroka) {
  65. TestBinSaverSerialization(TString("QWERTY"));
  66. }
  67. Y_UNIT_TEST(TestMoveOnlyType) {
  68. TestBinSaverSerializationToBuffer(TMoveOnlyType());
  69. }
  70. Y_UNIT_TEST(TestVectorStrok) {
  71. TestBinSaverSerialization(TVector<TString>{"A", "B", "C"});
  72. }
  73. Y_UNIT_TEST(TestCArray) {
  74. TestBinSaverSerialization(TTypeWithArray());
  75. }
  76. Y_UNIT_TEST(TestSets) {
  77. TestBinSaverSerialization(THashSet<TString>{"A", "B", "C"});
  78. TestBinSaverSerialization(TSet<TString>{"A", "B", "C"});
  79. }
  80. Y_UNIT_TEST(TestMaps) {
  81. TestBinSaverSerialization(THashMap<TString, ui32>{{"A", 1}, {"B", 2}, {"C", 3}});
  82. TestBinSaverSerialization(TMap<TString, ui32>{{"A", 1}, {"B", 2}, {"C", 3}});
  83. }
  84. Y_UNIT_TEST(TestBlob) {
  85. TestBinSaverSerialization(TBlob::FromStringSingleThreaded("qwerty"));
  86. }
  87. Y_UNIT_TEST(TestVariant) {
  88. {
  89. using T = std::variant<TString, int>;
  90. TestBinSaverSerialization(T(TString("")));
  91. TestBinSaverSerialization(T(0));
  92. }
  93. {
  94. using T = std::variant<TString, int, float>;
  95. TestBinSaverSerialization(T(TString("ask")));
  96. TestBinSaverSerialization(T(12));
  97. TestBinSaverSerialization(T(0.64f));
  98. }
  99. }
  100. Y_UNIT_TEST(TestPod) {
  101. struct TPod {
  102. ui32 A = 5;
  103. ui64 B = 7;
  104. bool operator==(const TPod& other) const {
  105. return A == other.A && B == other.B;
  106. }
  107. };
  108. TestBinSaverSerialization(TPod());
  109. TPod custom;
  110. custom.A = 25;
  111. custom.B = 37;
  112. TestBinSaverSerialization(custom);
  113. TestBinSaverSerialization(TVector<TPod>{custom});
  114. }
  115. Y_UNIT_TEST(TestSubPod) {
  116. struct TPod {
  117. struct TSub {
  118. ui32 X = 10;
  119. bool operator==(const TSub& other) const {
  120. return X == other.X;
  121. }
  122. };
  123. TVector<TSub> B;
  124. int operator&(IBinSaver& f) {
  125. f.Add(0, &B);
  126. return 0;
  127. }
  128. bool operator==(const TPod& other) const {
  129. return B == other.B;
  130. }
  131. };
  132. TestBinSaverSerialization(TPod());
  133. TPod::TSub sub;
  134. sub.X = 1;
  135. TPod custom;
  136. custom.B = {sub};
  137. TestBinSaverSerialization(TVector<TPod>{custom});
  138. }
  139. Y_UNIT_TEST(TestMemberAndOpIsMain) {
  140. struct TBase {
  141. TString S;
  142. virtual int operator&(IBinSaver& f) {
  143. f.Add(0, &S);
  144. return 0;
  145. }
  146. virtual ~TBase() = default;
  147. };
  148. struct TDerived: public TBase {
  149. int A = 0;
  150. int operator&(IBinSaver& f)override {
  151. f.Add(0, static_cast<TBase*>(this));
  152. f.Add(0, &A);
  153. return 0;
  154. }
  155. bool operator==(const TDerived& other) const {
  156. return A == other.A && S == other.S;
  157. }
  158. };
  159. TDerived obj;
  160. obj.S = "TString";
  161. obj.A = 42;
  162. TestBinSaverSerialization(obj);
  163. }
  164. }