userver: /data/code/userver/libraries/protobuf/tests/json/int64_from_json_test.cpp Source File
Loading...
Searching...
No Matches
int64_from_json_test.cpp
1#include <gtest/gtest.h>
2
3#include <limits>
4#include <ostream>
5#include <string>
6
7#include <fmt/format.h>
8
9#include <userver/protobuf/json/convert.hpp>
10#include <userver/utest/assert_macros.hpp>
11
12#include "utils.hpp"
13
14USERVER_NAMESPACE_BEGIN
15
16namespace protobuf::json::tests {
17
18constexpr std::int64_t kMax = std::numeric_limits<std::int64_t>::max(); // 9223372036854775807
19constexpr std::int64_t kMin = std::numeric_limits<std::int64_t>::min(); // -9223372036854775808
20
21struct Int64FromJsonSuccessTestParam {
22 std::string input = {};
23 Int64MessageData expected_message = {};
24 ParseOptions options = {};
25
26 // Older protobuf libraries does not support exponential notation for the quoted integers.
27 // This was fixed in the "v30.0-rc1" / "v6.30.0-rc1" (GOOGLE_PROTOBUF_VERSION = 6030000).
28 bool skip_native_parsing_for_older_versions = false;
29};
30
31struct Int64FromJsonFailureTestParam {
32 std::string input = {};
33 ParseErrorCode expected_errc = {};
34 std::string expected_path = {};
35 ParseOptions options = {};
36
37 // This variable is used to disable some checks that fail in the native protobuf implementation.
38 bool skip_native_check = false;
39};
40
41void PrintTo(const Int64FromJsonSuccessTestParam& param, std::ostream* os) {
42 *os << fmt::format("{{ input = '{}' }}", param.input);
43}
44
45void PrintTo(const Int64FromJsonFailureTestParam& param, std::ostream* os) {
46 *os << fmt::format("{{ input = '{}' }}", param.input);
47}
48
49class Int64FromJsonSuccessTest : public ::testing::TestWithParam<Int64FromJsonSuccessTestParam> {};
50class Int64FromJsonFailureTest : public ::testing::TestWithParam<Int64FromJsonFailureTestParam> {};
51
52INSTANTIATE_TEST_SUITE_P(
53 ,
54 Int64FromJsonSuccessTest,
55 ::testing::Values(
56 Int64FromJsonSuccessTestParam{R"({})", Int64MessageData{0, 0, 0}},
57 Int64FromJsonSuccessTestParam{R"({"field1":0,"field2":null,"field3":"0"})", Int64MessageData{0, 0, 0}},
58 Int64FromJsonSuccessTestParam{R"({"field1":1,"field2":-2,"field3":3})", Int64MessageData{1, -2, 3}},
59 Int64FromJsonSuccessTestParam{R"({"field1":"1","field2":"-2","field3":"3"})", Int64MessageData{1, -2, 3}},
60 Int64FromJsonSuccessTestParam{
61 R"({"field1":9223372036854775807,"field2":"9223372036854775807","field3":-9223372036854775808})",
62 Int64MessageData{kMax, kMax, kMin}
63 },
64 Int64FromJsonSuccessTestParam{
65 R"({"field1":-9223372036854775808,"field2":"-9223372036854775808","field3":9223372036854775807})",
66 Int64MessageData{kMin, kMin, kMax}
67 },
68 Int64FromJsonSuccessTestParam{
69 R"({"field1":10e2,"field2":-5e3,"field3":3e0})",
70 Int64MessageData{1000, -5000, 3}
71 },
72 Int64FromJsonSuccessTestParam{
73 R"({"field1":"10e2","field2":"-5e3","field3":"3e0"})",
74 Int64MessageData{1000, -5000, 3},
75 {},
76 true
77 },
78 Int64FromJsonSuccessTestParam{
79 R"({"field1":8500E-2,"field2":-1.8E+2,"field3":6.0E0})",
80 Int64MessageData{85, -180, 6}
81 },
82 Int64FromJsonSuccessTestParam{
83 R"({"field1":"8500E-2","field2":"-1.8E+2","field3":"6.0E0"})",
84 Int64MessageData{85, -180, 6},
85 {},
86 true
87 }
88 )
89);
90
91INSTANTIATE_TEST_SUITE_P(
92 ,
93 Int64FromJsonFailureTest,
94 ::testing::Values(
95 Int64FromJsonFailureTestParam{R"({"field1":[],"field2":1,"field3":1})", ParseErrorCode::kInvalidType, "field1"},
96 Int64FromJsonFailureTestParam{R"({"field1":1,"field2":{},"field3":1})", ParseErrorCode::kInvalidType, "field2"},
97 Int64FromJsonFailureTestParam{
98 R"({"field1":1,"field2":1,"field3":true})",
100 "field3"
101 },
102 Int64FromJsonFailureTestParam{
103 R"({"field1":9223372036854775808,"field2":1,"field3":1})",
105 "field1",
106 {},
107 // Old protobuf versions do not fail on out-of-range non-string int64.
108 !kIsModernProtoJson
109 },
110 Int64FromJsonFailureTestParam{
111 R"({"field1":1,"field2":-9223372036854775809,"field3":1})",
113 "field2",
114 {},
115 // Old protobuf versions do not fail on out-of-range non-string int64.
116 !kIsModernProtoJson
117 },
118 Int64FromJsonFailureTestParam{
119 R"({"field1":1,"field2":1,"field3":"9223372036854775808"})",
121 "field3"
122 },
123 Int64FromJsonFailureTestParam{
124 R"({"field1":"-9223372036854775809","field2":1,"field3":1})",
126 "field1"
127 },
128 Int64FromJsonFailureTestParam{
129 R"({"field1":1,"field2":1e50,"field3":1})",
131 "field2"
132 },
133 Int64FromJsonFailureTestParam{
134 R"({"field1":1,"field2":1,"field3":-1e50})",
136 "field3"
137 },
138 Int64FromJsonFailureTestParam{
139 R"({"field1":" 123","field2":1,"field3":1})",
141 "field1"
142 },
143 Int64FromJsonFailureTestParam{
144 R"({"field1":1,"field2":"-123 ","field3":1})",
146 "field2"
147 },
148 Int64FromJsonFailureTestParam{
149 R"({"field1":1,"field2":1,"field3":"1a3"})",
151 "field3"
152 },
153 Int64FromJsonFailureTestParam{
154 R"({"field1":"1.1","field2":1,"field3":1})",
156 "field1"
157 },
158 Int64FromJsonFailureTestParam{
159 R"({"field1":1,"field2":"1e50","field3":1})",
161 "field2"
162 },
163 Int64FromJsonFailureTestParam{
164 R"({"field1":1,"field2":1,"field3":"-1e50"})",
166 "field3"
167 }
168 )
169);
170
171TEST_P(Int64FromJsonSuccessTest, Test) {
172 const auto& param = GetParam();
173
174 proto_json::messages::Int64Message message;
175 proto_json::messages::Int64Message expected_message;
176 proto_json::messages::Int64Message sample_message;
177 formats::json::Value input = PrepareJsonTestData(param.input);
178 expected_message = PrepareTestData(param.expected_message);
179
180 message.set_field1(100001);
181 message.set_field2(200002);
182 message.set_field3(300003);
183
184 UASSERT_NO_THROW((message = JsonToMessage<proto_json::messages::Int64Message>(input, param.options)));
185
186#if GOOGLE_PROTOBUF_VERSION >= 6030000
187 UASSERT_NO_THROW(InitSampleMessage(param.input, sample_message, param.options));
188 CheckMessageEqual(message, sample_message);
189#else
190 if (!param.skip_native_parsing_for_older_versions) {
191 UASSERT_NO_THROW(InitSampleMessage(param.input, sample_message, param.options));
192 CheckMessageEqual(message, sample_message);
193 }
194#endif
195
196 CheckMessageEqual(message, expected_message);
197}
198
199TEST_P(Int64FromJsonFailureTest, Test) {
200 const auto& param = GetParam();
201
202 proto_json::messages::Int64Message sample_message;
203 formats::json::Value input = PrepareJsonTestData(param.input);
204
206 (void)JsonToMessage<proto_json::messages::Int64Message>(input, param.options),
207 param.expected_errc,
208 param.expected_path
209 );
210
211 if (!param.skip_native_check) {
212 UEXPECT_THROW(InitSampleMessage(param.input, sample_message, param.options), SampleError);
213 }
214}
215
216} // namespace protobuf::json::tests
217
218USERVER_NAMESPACE_END