simple_reflection_ut.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. #include "simple_reflection.h"
  2. #include <library/cpp/protobuf/util/ut/sample_for_simple_reflection.pb.h>
  3. #include <library/cpp/protobuf/util/ut/extensions.pb.h>
  4. #include <library/cpp/testing/unittest/registar.h>
  5. using namespace NProtoBuf;
  6. Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) {
  7. static TSample GenSampleForMergeFrom() {
  8. TSample smf;
  9. smf.SetOneStr("one str");
  10. smf.MutableOneMsg()->AddRepInt(1);
  11. smf.AddRepMsg()->AddRepInt(2);
  12. smf.AddRepMsg()->AddRepInt(3);
  13. smf.AddRepStr("one rep str");
  14. smf.AddRepStr("two rep str");
  15. smf.SetAnotherOneStr("another one str");
  16. return smf;
  17. }
  18. Y_UNIT_TEST(MergeFromGeneric) {
  19. const TSample src(GenSampleForMergeFrom());
  20. TSample dst;
  21. const Descriptor* descr = dst.GetDescriptor();
  22. {
  23. TMutableField dstOneStr(dst, descr->FindFieldByName("OneStr"));
  24. TConstField srcOneStr(src, descr->FindFieldByName("OneStr"));
  25. dstOneStr.MergeFrom(srcOneStr);
  26. UNIT_ASSERT_VALUES_EQUAL(dst.GetOneStr(), src.GetOneStr());
  27. }
  28. { // MergeFrom for single message fields acts like a Message::MergeFrom
  29. TMutableField dstOneMsg(dst, descr->FindFieldByName("OneMsg"));
  30. dstOneMsg.MergeFrom(TConstField(src, descr->FindFieldByName("OneMsg")));
  31. UNIT_ASSERT_VALUES_EQUAL(dst.GetOneMsg().RepIntSize(), src.GetOneMsg().RepIntSize());
  32. dstOneMsg.MergeFrom(TConstField(src, descr->FindFieldByName("OneMsg")));
  33. UNIT_ASSERT_VALUES_EQUAL(dst.GetOneMsg().RepIntSize(), src.GetOneMsg().RepIntSize() * 2);
  34. }
  35. { // MergeFrom for repeated fields acts like append
  36. TMutableField dstRepMsg(dst, descr->FindFieldByName("RepMsg"));
  37. dstRepMsg.MergeFrom(TConstField(src, descr->FindFieldByName("RepMsg")));
  38. UNIT_ASSERT_VALUES_EQUAL(dst.RepMsgSize(), src.RepMsgSize());
  39. dstRepMsg.MergeFrom(TConstField(src, descr->FindFieldByName("RepMsg")));
  40. UNIT_ASSERT_VALUES_EQUAL(dst.RepMsgSize(), src.RepMsgSize() * 2);
  41. for (size_t repMsgIndex = 0; repMsgIndex < dst.RepMsgSize(); ++repMsgIndex) {
  42. UNIT_ASSERT_VALUES_EQUAL(dst.GetRepMsg(repMsgIndex).RepIntSize(), src.GetRepMsg(0).RepIntSize());
  43. }
  44. }
  45. }
  46. Y_UNIT_TEST(MergeFromSelf) {
  47. const TSample sample(GenSampleForMergeFrom());
  48. TSample msg(sample);
  49. const Descriptor* descr = msg.GetDescriptor();
  50. TMutableField oneStr(msg, descr->FindFieldByName("OneStr"));
  51. oneStr.MergeFrom(oneStr);
  52. UNIT_ASSERT_VALUES_EQUAL(msg.GetOneStr(), sample.GetOneStr());
  53. TMutableField oneMsg(msg, descr->FindFieldByName("OneMsg"));
  54. oneMsg.MergeFrom(oneMsg); // nothing should change
  55. UNIT_ASSERT_VALUES_EQUAL(msg.GetOneMsg().RepIntSize(), sample.GetOneMsg().RepIntSize());
  56. }
  57. Y_UNIT_TEST(MergeFromAnotherFD) {
  58. const TSample sample(GenSampleForMergeFrom());
  59. TSample msg(GenSampleForMergeFrom());
  60. const Descriptor* descr = msg.GetDescriptor();
  61. { // string
  62. TMutableField oneStr(msg, descr->FindFieldByName("OneStr"));
  63. TMutableField repStr(msg, descr->FindFieldByName("RepStr"));
  64. TMutableField anotherOneStr(msg, descr->FindFieldByName("AnotherOneStr"));
  65. oneStr.MergeFrom(anotherOneStr);
  66. UNIT_ASSERT_VALUES_EQUAL(msg.GetOneStr(), sample.GetAnotherOneStr());
  67. oneStr.MergeFrom(repStr);
  68. const size_t sampleRepStrSize = sample.RepStrSize();
  69. UNIT_ASSERT_VALUES_EQUAL(msg.GetOneStr(), sample.GetRepStr(sampleRepStrSize - 1));
  70. repStr.MergeFrom(anotherOneStr);
  71. UNIT_ASSERT_VALUES_EQUAL(msg.RepStrSize(), sampleRepStrSize + 1);
  72. UNIT_ASSERT_VALUES_EQUAL(msg.GetRepStr(sampleRepStrSize), msg.GetAnotherOneStr());
  73. }
  74. { // Message
  75. TMutableField oneMsg(msg, descr->FindFieldByName("OneMsg"));
  76. TMutableField repMsg(msg, descr->FindFieldByName("RepMsg"));
  77. oneMsg.MergeFrom(repMsg);
  78. const size_t oneMsgRepIntSize = sample.GetOneMsg().RepIntSize();
  79. const size_t sizeOfAllRepIntsInRepMsg = sample.RepMsgSize();
  80. UNIT_ASSERT_VALUES_EQUAL(msg.GetOneMsg().RepIntSize(), oneMsgRepIntSize + sizeOfAllRepIntsInRepMsg);
  81. repMsg.MergeFrom(oneMsg);
  82. UNIT_ASSERT_VALUES_EQUAL(msg.RepMsgSize(), sample.RepMsgSize() + 1);
  83. }
  84. }
  85. Y_UNIT_TEST(RemoveByIndex) {
  86. TSample msg;
  87. const Descriptor* descr = msg.GetDescriptor();
  88. {
  89. TMutableField fld(msg, descr->FindFieldByName("RepMsg"));
  90. msg.AddRepMsg()->AddRepInt(1);
  91. msg.AddRepMsg()->AddRepInt(2);
  92. msg.AddRepMsg()->AddRepInt(3);
  93. UNIT_ASSERT_VALUES_EQUAL(3, msg.RepMsgSize()); // 1, 2, 3
  94. fld.Remove(1); // from middle
  95. UNIT_ASSERT_VALUES_EQUAL(2, msg.RepMsgSize());
  96. UNIT_ASSERT_VALUES_EQUAL(1, msg.GetRepMsg(0).GetRepInt(0));
  97. UNIT_ASSERT_VALUES_EQUAL(3, msg.GetRepMsg(1).GetRepInt(0));
  98. msg.AddRepMsg()->AddRepInt(5);
  99. UNIT_ASSERT_VALUES_EQUAL(3, msg.RepMsgSize()); // 1, 3, 5
  100. fld.Remove(2); // from end
  101. UNIT_ASSERT_VALUES_EQUAL(2, msg.RepMsgSize());
  102. UNIT_ASSERT_VALUES_EQUAL(1, msg.GetRepMsg(0).GetRepInt(0));
  103. UNIT_ASSERT_VALUES_EQUAL(3, msg.GetRepMsg(1).GetRepInt(0));
  104. msg.ClearRepMsg();
  105. }
  106. {
  107. TMutableField fld(msg, descr->FindFieldByName("RepStr"));
  108. msg.AddRepStr("1");
  109. msg.AddRepStr("2");
  110. msg.AddRepStr("3");
  111. UNIT_ASSERT_VALUES_EQUAL(3, msg.RepStrSize()); // "1", "2", "3"
  112. fld.Remove(0); // from begin
  113. UNIT_ASSERT_VALUES_EQUAL(2, msg.RepStrSize());
  114. UNIT_ASSERT_VALUES_EQUAL("2", msg.GetRepStr(0));
  115. UNIT_ASSERT_VALUES_EQUAL("3", msg.GetRepStr(1));
  116. }
  117. {
  118. TMutableField fld(msg, descr->FindFieldByName("OneStr"));
  119. msg.SetOneStr("1");
  120. UNIT_ASSERT(msg.HasOneStr());
  121. fld.Remove(0); // not repeated
  122. UNIT_ASSERT(!msg.HasOneStr());
  123. }
  124. }
  125. Y_UNIT_TEST(GetFieldByPath) {
  126. // Simple get by path
  127. {
  128. TSample msg;
  129. msg.SetOneStr("1");
  130. msg.MutableOneMsg()->AddRepInt(2);
  131. msg.MutableOneMsg()->AddRepInt(3);
  132. msg.AddRepMsg()->AddRepInt(4);
  133. msg.MutableRepMsg(0)->AddRepInt(5);
  134. msg.AddRepMsg()->AddRepInt(6);
  135. {
  136. TMaybe<TConstField> field = TConstField::ByPath(msg, "OneStr");
  137. UNIT_ASSERT(field);
  138. UNIT_ASSERT(field->HasValue());
  139. UNIT_ASSERT_VALUES_EQUAL("1", (field->Get<TString>()));
  140. }
  141. {
  142. TMaybe<TConstField> field = TConstField::ByPath(msg, "OneMsg");
  143. UNIT_ASSERT(field);
  144. UNIT_ASSERT(field->HasValue());
  145. UNIT_ASSERT(field->IsMessageInstance<TInnerSample>());
  146. }
  147. {
  148. TMaybe<TConstField> field = TConstField::ByPath(msg, "/OneMsg/RepInt");
  149. UNIT_ASSERT(field);
  150. UNIT_ASSERT(field->HasValue());
  151. UNIT_ASSERT_VALUES_EQUAL(2, field->Size());
  152. UNIT_ASSERT_VALUES_EQUAL(2, field->Get<int>(0));
  153. UNIT_ASSERT_VALUES_EQUAL(3, field->Get<int>(1));
  154. }
  155. {
  156. TMaybe<TConstField> field = TConstField::ByPath(msg, "RepMsg/RepInt");
  157. UNIT_ASSERT(field);
  158. UNIT_ASSERT(field->HasValue());
  159. UNIT_ASSERT_VALUES_EQUAL(2, field->Size());
  160. UNIT_ASSERT_VALUES_EQUAL(4, field->Get<int>(0));
  161. UNIT_ASSERT_VALUES_EQUAL(5, field->Get<int>(1));
  162. }
  163. }
  164. // get of unset fields
  165. {
  166. TSample msg;
  167. msg.MutableOneMsg();
  168. {
  169. TMaybe<TConstField> field = TConstField::ByPath(msg, "OneStr");
  170. UNIT_ASSERT(field);
  171. UNIT_ASSERT(!field->HasValue());
  172. }
  173. {
  174. TMaybe<TConstField> field = TConstField::ByPath(msg, "OneMsg/RepInt");
  175. UNIT_ASSERT(field);
  176. UNIT_ASSERT(!field->HasValue());
  177. }
  178. {
  179. TMaybe<TConstField> field = TConstField::ByPath(msg, "RepMsg/RepInt");
  180. UNIT_ASSERT(!field);
  181. }
  182. }
  183. // mutable
  184. {
  185. TSample msg;
  186. msg.MutableOneMsg();
  187. {
  188. TMaybe<TMutableField> field = TMutableField::ByPath(msg, "OneStr");
  189. UNIT_ASSERT(field);
  190. UNIT_ASSERT(!field->HasValue());
  191. field->Set(TString("zz"));
  192. UNIT_ASSERT(field->HasValue());
  193. UNIT_ASSERT_VALUES_EQUAL("zz", msg.GetOneStr());
  194. }
  195. {
  196. TMaybe<TMutableField> field = TMutableField::ByPath(msg, "OneStr");
  197. UNIT_ASSERT(field);
  198. UNIT_ASSERT(field->HasValue());
  199. field->Set(TString("dd"));
  200. UNIT_ASSERT(field->HasValue());
  201. UNIT_ASSERT_VALUES_EQUAL("dd", msg.GetOneStr());
  202. }
  203. {
  204. TMaybe<TMutableField> field = TMutableField::ByPath(msg, "OneMsg/RepInt");
  205. UNIT_ASSERT(field);
  206. UNIT_ASSERT(!field->HasValue());
  207. field->Add(10);
  208. UNIT_ASSERT_VALUES_EQUAL(10, msg.GetOneMsg().GetRepInt(0));
  209. }
  210. {
  211. TMaybe<TMutableField> field = TMutableField::ByPath(msg, "RepMsg/RepInt");
  212. UNIT_ASSERT(!field);
  213. }
  214. }
  215. // mutable with path creation
  216. {
  217. TSample msg;
  218. {
  219. TMaybe<TMutableField> field = TMutableField::ByPath(msg, "OneStr", true);
  220. UNIT_ASSERT(field);
  221. UNIT_ASSERT(!field->HasValue());
  222. }
  223. {
  224. TMaybe<TMutableField> field = TMutableField::ByPath(msg, "OneMsg/RepInt", true);
  225. UNIT_ASSERT(field);
  226. UNIT_ASSERT(!field->HasValue());
  227. UNIT_ASSERT(msg.HasOneMsg());
  228. field->Add(10);
  229. UNIT_ASSERT_VALUES_EQUAL(10, msg.GetOneMsg().GetRepInt(0));
  230. }
  231. {
  232. TMaybe<TMutableField> field = TMutableField::ByPath(msg, "RepMsg/RepInt", true);
  233. TMaybe<TMutableField> fieldCopy = TMutableField::ByPath(msg, "RepMsg/RepInt", true);
  234. Y_UNUSED(fieldCopy);
  235. UNIT_ASSERT(field);
  236. UNIT_ASSERT(!field->HasValue());
  237. UNIT_ASSERT_VALUES_EQUAL(1, msg.RepMsgSize());
  238. field->Add(12);
  239. UNIT_ASSERT_VALUES_EQUAL(12, field->Get<int>());
  240. }
  241. }
  242. // error
  243. {
  244. {TSample msg;
  245. UNIT_ASSERT(!TConstField::ByPath(msg, "SomeField"));
  246. }
  247. {
  248. TSample msg;
  249. UNIT_ASSERT(!TMutableField::ByPath(msg, "SomeField/FieldSome"));
  250. }
  251. {
  252. TSample msg;
  253. UNIT_ASSERT(!TMutableField::ByPath(msg, "SomeField/FieldSome", true));
  254. }
  255. }
  256. // extension
  257. {
  258. TSample msg;
  259. msg.SetExtension(NExt::TTestExt::ExtField, "ext");
  260. msg.SetExtension(NExt::ExtField, 2);
  261. msg.AddExtension(NExt::Ext2Field, 33);
  262. TInnerSample* subMsg = msg.MutableExtension(NExt::SubMsgExt);
  263. subMsg->AddRepInt(20);
  264. subMsg->SetExtension(NExt::Ext3Field, 54);
  265. {
  266. TMaybe<TConstField> field = TConstField::ByPath(msg, "NExt.TTestExt.ExtField");
  267. UNIT_ASSERT(field);
  268. UNIT_ASSERT(field->HasValue());
  269. UNIT_ASSERT_VALUES_EQUAL("ext", field->Get<TString>());
  270. }
  271. {
  272. TMaybe<TConstField> field = TConstField::ByPath(msg, "NExt.ExtField");
  273. UNIT_ASSERT(field);
  274. UNIT_ASSERT(field->HasValue());
  275. UNIT_ASSERT_VALUES_EQUAL(2, field->Get<int>());
  276. }
  277. {
  278. TMaybe<TConstField> field = TConstField::ByPath(msg, "ExtField"); // ambiguity
  279. UNIT_ASSERT(!field);
  280. }
  281. {
  282. TMaybe<TConstField> field = TConstField::ByPath(msg, "NExt.Ext2Field");
  283. UNIT_ASSERT(field);
  284. UNIT_ASSERT(field->HasValue());
  285. UNIT_ASSERT_VALUES_EQUAL(33, field->Get<int>());
  286. }
  287. {
  288. TMaybe<TConstField> field = TConstField::ByPath(msg, "Ext2Field");
  289. UNIT_ASSERT(field);
  290. UNIT_ASSERT(field->HasValue());
  291. UNIT_ASSERT_VALUES_EQUAL(33, field->Get<int>());
  292. }
  293. {
  294. TMaybe<TConstField> field = TConstField::ByPath(msg, "SubMsgExt");
  295. UNIT_ASSERT(field);
  296. UNIT_ASSERT(field->HasValue());
  297. const TInnerSample* subMsg2 = field->GetAs<TInnerSample>();
  298. UNIT_ASSERT(subMsg2);
  299. UNIT_ASSERT_VALUES_EQUAL(1, subMsg2->RepIntSize());
  300. UNIT_ASSERT_VALUES_EQUAL(20, subMsg2->GetRepInt(0));
  301. UNIT_ASSERT_VALUES_EQUAL(54, subMsg2->GetExtension(NExt::Ext3Field));
  302. }
  303. {
  304. TMaybe<TConstField> field = TConstField::ByPath(msg, "SubMsgExt/Ext3Field");
  305. UNIT_ASSERT(field);
  306. UNIT_ASSERT(field->HasValue());
  307. UNIT_ASSERT_VALUES_EQUAL(54, field->Get<int>());
  308. }
  309. {
  310. TMaybe<TConstField> field = TConstField::ByPath(msg, "SubMsgExt/RepInt");
  311. UNIT_ASSERT(field);
  312. UNIT_ASSERT(field->HasValue());
  313. UNIT_ASSERT_VALUES_EQUAL(20, field->Get<int>());
  314. }
  315. }
  316. }
  317. }