userver: /data/code/userver/libraries/protobuf/tests/json/enum_from_json_test.cpp Source File
Loading...
Searching...
No Matches
enum_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
18namespace msgs = proto_json::messages;
19
20constexpr std::int32_t kMax = std::numeric_limits<std::int32_t>::max(); // 2147483647
21constexpr std::int32_t kMin = std::numeric_limits<std::int32_t>::min(); // -2147483648
22
23struct EnumFromJsonSuccessTestParam {
24 std::string input = {};
25 EnumMessageData expected_message = {};
26 ParseOptions options = {};
27
28 // This variable is used to disable some checks that fail in the native protobuf implementation.
29 bool skip_native_check = false;
30};
31
32struct EnumFromJsonFailureTestParam {
33 std::string input = {};
34 ParseErrorCode expected_errc = {};
35 std::string expected_path = {};
36 ParseOptions options = {};
37};
38
39void PrintTo(const EnumFromJsonSuccessTestParam& param, std::ostream* os) {
40 *os << fmt::format("{{ input = '{}' }}", param.input);
41}
42
43void PrintTo(const EnumFromJsonFailureTestParam& param, std::ostream* os) {
44 *os << fmt::format("{{ input = '{}' }}", param.input);
45}
46
47class EnumFromJsonSuccessTest : public ::testing::TestWithParam<EnumFromJsonSuccessTestParam> {};
48class EnumFromJsonFailureTest : public ::testing::TestWithParam<EnumFromJsonFailureTestParam> {};
49
50INSTANTIATE_TEST_SUITE_P(
51 ,
52 EnumFromJsonSuccessTest,
53 ::testing::Values(
54 EnumFromJsonSuccessTestParam{R"({})", EnumMessageData{msgs::EnumMessage::TEST_UNSPECIFIED}},
55 EnumFromJsonSuccessTestParam{R"({"field1":null})", EnumMessageData{msgs::EnumMessage::TEST_UNSPECIFIED}},
56 EnumFromJsonSuccessTestParam{
57 R"({"field1":"TEST_UNSPECIFIED"})",
58 EnumMessageData{msgs::EnumMessage::TEST_UNSPECIFIED}
59 },
60 EnumFromJsonSuccessTestParam{R"({"field1":"TEST_VALUE1"})", EnumMessageData{msgs::EnumMessage::TEST_VALUE1}},
61 EnumFromJsonSuccessTestParam{R"({"field1":"TEST_VALUE2"})", EnumMessageData{msgs::EnumMessage::TEST_VALUE2}},
62 EnumFromJsonSuccessTestParam{
63 R"({"field1":"TEST_VALUE2_ALIAS"})",
64 EnumMessageData{msgs::EnumMessage::TEST_VALUE2}
65 },
66 EnumFromJsonSuccessTestParam{R"({"field1":"TEST_VALUE3"})", EnumMessageData{msgs::EnumMessage::TEST_VALUE3}},
67 EnumFromJsonSuccessTestParam{
68 R"({"field1":"TEST_NON_EXISTENT"})",
69 EnumMessageData{msgs::EnumMessage::TEST_UNSPECIFIED},
70 {.ignore_unknown_fields = true}
71 },
72 EnumFromJsonSuccessTestParam{
73 R"({"field2":"TEST_NON_EXISTENT"})",
74 EnumMessageData{},
75 {.ignore_unknown_fields = true}
76 },
77 EnumFromJsonSuccessTestParam{R"({"field1":"0"})", EnumMessageData{msgs::EnumMessage::TEST_UNSPECIFIED}},
78 EnumFromJsonSuccessTestParam{R"({"field1":1})", EnumMessageData{msgs::EnumMessage::TEST_VALUE1}},
79 EnumFromJsonSuccessTestParam{R"({"field1":"2"})", EnumMessageData{msgs::EnumMessage::TEST_VALUE2}},
80 EnumFromJsonSuccessTestParam{R"({"field1":3})", EnumMessageData{msgs::EnumMessage::TEST_VALUE3}},
81 EnumFromJsonSuccessTestParam{R"({"field1":5})", EnumMessageData{static_cast<msgs::EnumMessage::Test>(5)}},
82 EnumFromJsonSuccessTestParam{
83 R"({"field1":"-5"})",
84 EnumMessageData{static_cast<msgs::EnumMessage::Test>(-5)},
85 {},
86 !kIsModernProtoJson
87 },
88 EnumFromJsonSuccessTestParam{
89 R"({"field1":2147483647})",
90 EnumMessageData{static_cast<msgs::EnumMessage::Test>(kMax)}
91 },
92 EnumFromJsonSuccessTestParam{
93 R"({"field1":-2147483648})",
94 EnumMessageData{static_cast<msgs::EnumMessage::Test>(kMin)}
95 }
96 )
97);
98
99INSTANTIATE_TEST_SUITE_P(
100 ,
101 EnumFromJsonFailureTest,
102 ::testing::Values(
103 EnumFromJsonFailureTestParam{R"({"field1":[]})", ParseErrorCode::kInvalidType, "field1"},
104 EnumFromJsonFailureTestParam{R"({"field1":{}})", ParseErrorCode::kInvalidType, "field1"},
105 EnumFromJsonFailureTestParam{R"({"field1":true})", ParseErrorCode::kInvalidType, "field1"},
106 EnumFromJsonFailureTestParam{R"({"field1":"TEST_NON_EXISTENT"})", ParseErrorCode::kUnknownEnum, "field1"},
107 EnumFromJsonFailureTestParam{R"({"field1":"1+1"})", ParseErrorCode::kInvalidValue, "field1"},
108 EnumFromJsonFailureTestParam{R"({"field1":"-1a"})", ParseErrorCode::kInvalidValue, "field1"},
109 EnumFromJsonFailureTestParam{R"({"field1":2147483648})", ParseErrorCode::kInvalidValue, "field1"},
110 EnumFromJsonFailureTestParam{R"({"field1":-2147483649})", ParseErrorCode::kInvalidValue, "field1"}
111 )
112);
113
114TEST_P(EnumFromJsonSuccessTest, Test) {
115 const auto& param = GetParam();
116
117 proto_json::messages::EnumMessage message;
118 proto_json::messages::EnumMessage expected_message;
119 proto_json::messages::EnumMessage sample_message;
120 formats::json::Value input = PrepareJsonTestData(param.input);
121 expected_message = PrepareTestData(param.expected_message);
122
123 message.set_field1(static_cast<proto_json::messages::EnumMessage::Test>(100001));
124
125 UASSERT_NO_THROW((message = JsonToMessage<proto_json::messages::EnumMessage>(input, param.options)));
126
127 if (!param.skip_native_check) {
128 UASSERT_NO_THROW(InitSampleMessage(param.input, sample_message, param.options));
129 CheckMessageEqual(message, sample_message);
130 }
131
132 CheckMessageEqual(message, expected_message);
133}
134
135TEST_P(EnumFromJsonFailureTest, Test) {
136 const auto& param = GetParam();
137
138 proto_json::messages::EnumMessage sample_message;
139 formats::json::Value input = PrepareJsonTestData(param.input);
140
142 (void)JsonToMessage<proto_json::messages::EnumMessage>(input, param.options),
143 param.expected_errc,
144 param.expected_path
145 );
146
147 UEXPECT_THROW(InitSampleMessage(param.input, sample_message, param.options), SampleError);
148}
149
150} // namespace protobuf::json::tests
151
152USERVER_NAMESPACE_END