1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#include <library/cpp/protobuf/json/ut/inline_ut.pb.h>
#include <library/cpp/protobuf/json/inline.h>
#include <library/cpp/protobuf/json/field_option.h>
#include <library/cpp/protobuf/json/proto2json.h>
#include <library/cpp/testing/unittest/registar.h>
#include <util/generic/string.h>
using namespace NProtobufJson;
static NProtobufJsonUt::TInlineTest GetTestMsg() {
NProtobufJsonUt::TInlineTest msg;
msg.SetOptJson(R"({"a":1,"b":"000"})");
msg.SetNotJson("12{}34");
msg.AddRepJson("{}");
msg.AddRepJson("[1,2]");
msg.MutableInner()->AddNumber(100);
msg.MutableInner()->AddNumber(200);
msg.MutableInner()->SetInnerJson(R"({"xxx":[]})");
return msg;
}
Y_UNIT_TEST_SUITE(TProto2JsonInlineTest){
Y_UNIT_TEST(TestNormalPrint){
NProtobufJsonUt::TInlineTest msg = GetTestMsg();
// normal print should output these fields as just string values
TString expRaw = R"({"OptJson":"{\"a\":1,\"b\":\"000\"}","NotJson":"12{}34","RepJson":["{}","[1,2]"],)"
R"("Inner":{"Number":[100,200],"InnerJson":"{\"xxx\":[]}"}})";
TString myRaw;
Proto2Json(msg, myRaw);
UNIT_ASSERT_STRINGS_EQUAL(myRaw, expRaw);
myRaw = PrintInlined(msg, [](const NProtoBuf::Message&, const NProtoBuf::FieldDescriptor*) { return false; });
UNIT_ASSERT_STRINGS_EQUAL(myRaw, expRaw); // result is the same
}
Y_UNIT_TEST(TestInliningPrinter) {
NProtobufJsonUt::TInlineTest msg = GetTestMsg();
// inlined print should output these fields as inlined json sub-objects
TString expInlined = R"({"OptJson":{"a":1,"b":"000"},"NotJson":"12{}34","RepJson":[{},[1,2]],)"
R"("Inner":{"Number":[100,200],"InnerJson":{"xxx":[]}}})";
{
TString myInlined = PrintInlined(msg, MakeFieldOptionFunctor(NProtobufJsonUt::inline_test));
UNIT_ASSERT_STRINGS_EQUAL(myInlined, expInlined);
}
{
auto functor = [](const NProtoBuf::Message&, const NProtoBuf::FieldDescriptor* field) {
return field->name() == "OptJson" || field->name() == "RepJson" || field->name() == "InnerJson";
};
TString myInlined = PrintInlined(msg, functor);
UNIT_ASSERT_STRINGS_EQUAL(myInlined, expInlined);
}
}
Y_UNIT_TEST(TestNoValues) {
// no values - no printing
NProtobufJsonUt::TInlineTest msg;
msg.MutableInner()->AddNumber(100);
msg.MutableInner()->AddNumber(200);
TString expInlined = R"({"Inner":{"Number":[100,200]}})";
TString myInlined = PrintInlined(msg, MakeFieldOptionFunctor(NProtobufJsonUt::inline_test));
UNIT_ASSERT_STRINGS_EQUAL(myInlined, expInlined);
}
Y_UNIT_TEST(TestMissingKeyModeNull) {
NProtobufJsonUt::TInlineTest msg;
msg.MutableInner()->AddNumber(100);
msg.MutableInner()->AddNumber(200);
TString expInlined = R"({"OptJson":null,"NotJson":null,"RepJson":null,"Inner":{"Number":[100,200],"InnerJson":null}})";
TProto2JsonConfig cfg;
cfg.SetMissingSingleKeyMode(TProto2JsonConfig::MissingKeyNull).SetMissingRepeatedKeyMode(TProto2JsonConfig::MissingKeyNull);
TString myInlined = PrintInlined(msg, MakeFieldOptionFunctor(NProtobufJsonUt::inline_test), cfg);
UNIT_ASSERT_STRINGS_EQUAL(myInlined, expInlined);
}
Y_UNIT_TEST(TestMissingKeyModeDefault) {
NProtobufJsonUt::TInlineTestDefaultValues msg;
TString expInlined = R"({"OptJson":{"default":1},"Number":0,"RepJson":[],"Inner":{"OptJson":{"default":2}}})";
TProto2JsonConfig cfg;
cfg.SetMissingSingleKeyMode(TProto2JsonConfig::MissingKeyDefault).SetMissingRepeatedKeyMode(TProto2JsonConfig::MissingKeyDefault);
TString myInlined = PrintInlined(msg, MakeFieldOptionFunctor(NProtobufJsonUt::inline_test), cfg);
UNIT_ASSERT_STRINGS_EQUAL(myInlined, expInlined);
}
Y_UNIT_TEST(NoUnnecessaryCopyFunctor) {
size_t CopyCount = 0;
struct TFunctorMock {
TFunctorMock(size_t* copyCount)
: CopyCount(copyCount)
{
UNIT_ASSERT(*CopyCount <= 1);
}
TFunctorMock(const TFunctorMock& f)
: CopyCount(f.CopyCount)
{
++*CopyCount;
}
TFunctorMock(TFunctorMock&& f) = default;
bool operator()(const NProtoBuf::Message&, const NProtoBuf::FieldDescriptor*) const {
return false;
}
size_t* CopyCount;
};
TProto2JsonConfig cfg;
TInliningPrinter<> printer(TFunctorMock(&CopyCount), cfg);
UNIT_ASSERT(CopyCount <= 1);
}
}
;
|