userver: /data/code/userver/libraries/protobuf/tests/json/float_from_json_test.cpp Source File
Loading...
Searching...
No Matches
float_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 float kMax = std::numeric_limits<float>::max();
19constexpr float kMin = std::numeric_limits<float>::min();
20
21struct FloatFromJsonSuccessTestParam {
22 std::string input = {};
23 FloatMessageData expected_message = {};
24 ParseOptions options = {};
25
26 // This variable is used to disable some checks that fail in the native protobuf implementation.
27 bool skip_native_check = false;
28};
29
30struct FloatFromJsonFailureTestParam {
31 std::string input = {};
32 ParseErrorCode expected_errc = {};
33 std::string expected_path = {};
34 ParseOptions options = {};
35
36 // Native implementation does not emit error on some expected cases which we want to detect.
37 // This variable turns off checks for native implementation.
38 bool skip_native_check = false;
39};
40
41void PrintTo(const FloatFromJsonSuccessTestParam& param, std::ostream* os) {
42 *os << fmt::format("{{ input = '{}' }}", param.input);
43}
44
45void PrintTo(const FloatFromJsonFailureTestParam& param, std::ostream* os) {
46 *os << fmt::format("{{ input = '{}' }}", param.input);
47}
48
49class FloatFromJsonSuccessTest : public ::testing::TestWithParam<FloatFromJsonSuccessTestParam> {};
50class FloatFromJsonFailureTest : public ::testing::TestWithParam<FloatFromJsonFailureTestParam> {};
51
52INSTANTIATE_TEST_SUITE_P(
53 ,
54 FloatFromJsonSuccessTest,
55 ::testing::Values(
56 FloatFromJsonSuccessTestParam{R"({})", FloatMessageData{0}},
57 FloatFromJsonSuccessTestParam{R"({"field1":null})", FloatMessageData{0}},
58 FloatFromJsonSuccessTestParam{R"({"field1":-0.0e0})", FloatMessageData{0}},
59 FloatFromJsonSuccessTestParam{R"({"field1":"-0.0e0"})", FloatMessageData{0}},
60 FloatFromJsonSuccessTestParam{R"({"field1":123})", FloatMessageData{123}},
61 FloatFromJsonSuccessTestParam{R"({"field1":"-123"})", FloatMessageData{-123}},
62 FloatFromJsonSuccessTestParam{R"({"field1":100.123567})", FloatMessageData{100.123567}},
63 FloatFromJsonSuccessTestParam{R"({"field1":"100.123567"})", FloatMessageData{100.123567}},
64 FloatFromJsonSuccessTestParam{R"({"field1":-100.123567})", FloatMessageData{-100.123567}},
65 FloatFromJsonSuccessTestParam{R"({"field1":"-100.123567"})", FloatMessageData{-100.123567}},
66 FloatFromJsonSuccessTestParam{R"({"field1":100.123e-2})", FloatMessageData{1.00123}},
67 FloatFromJsonSuccessTestParam{R"({"field1":"-100.123567E2"})", FloatMessageData{-10012.3567}},
68 FloatFromJsonSuccessTestParam{R"({"field1":100.123e-2})", FloatMessageData{1.00123}},
69 FloatFromJsonSuccessTestParam{R"({"field1":"-100.123567E2"})", FloatMessageData{-10012.3567}},
70 FloatFromJsonSuccessTestParam{R"({"field1":3.40282347e+38})", FloatMessageData{kMax}},
71 FloatFromJsonSuccessTestParam{
72 R"({"field1":"3.40282347E38"})",
73 FloatMessageData{kMax},
74 {},
75 // Sign '+' or '-' is required in exponent notation in old protobuf versions.
76 !kIsModernProtoJson
77 },
78 FloatFromJsonSuccessTestParam{R"({"field1":-3.40282347E+38})", FloatMessageData{-kMax}},
79 FloatFromJsonSuccessTestParam{
80 R"({"field1":"-3.40282347e38"})",
81 FloatMessageData{-kMax},
82 {},
83 // Sign '+' or '-' is required in exponent notation in old protobuf versions.
84 !kIsModernProtoJson
85 },
86 FloatFromJsonSuccessTestParam{R"({"field1":1.17549435e-38})", FloatMessageData{kMin}},
87 FloatFromJsonSuccessTestParam{R"({"field1":"1.17549435E-38"})", FloatMessageData{kMin}},
88 FloatFromJsonSuccessTestParam{R"({"field1":-1.17549435E-38})", FloatMessageData{-kMin}},
89 FloatFromJsonSuccessTestParam{R"({"field1":"-1.17549435e-38"})", FloatMessageData{-kMin}}
90 )
91);
92
93INSTANTIATE_TEST_SUITE_P(
94 ,
95 FloatFromJsonFailureTest,
96 ::testing::Values(
97 FloatFromJsonFailureTestParam{R"({"field1":[]})", ParseErrorCode::kInvalidType, "field1"},
98 FloatFromJsonFailureTestParam{R"({"field1":{}})", ParseErrorCode::kInvalidType, "field1"},
99 FloatFromJsonFailureTestParam{R"({"field1":true})", ParseErrorCode::kInvalidType, "field1"},
100 FloatFromJsonFailureTestParam{R"({"field1":3.403e+38})", ParseErrorCode::kInvalidValue, "field1"},
101 FloatFromJsonFailureTestParam{R"({"field1":"3.403e+38"})", ParseErrorCode::kInvalidValue, "field1"},
102 FloatFromJsonFailureTestParam{R"({"field1":-3.403e+38})", ParseErrorCode::kInvalidValue, "field1"},
103 FloatFromJsonFailureTestParam{R"({"field1":"-3.403e+38"})", ParseErrorCode::kInvalidValue, "field1"},
104 FloatFromJsonFailureTestParam{R"({"field1":" 123"})", ParseErrorCode::kInvalidValue, "field1", {}, true},
105 FloatFromJsonFailureTestParam{R"({"field1":"123 "})", ParseErrorCode::kInvalidValue, "field1", {}, true},
106 FloatFromJsonFailureTestParam{R"({"field1":"1a3"})", ParseErrorCode::kInvalidValue, "field1"}
107 )
108);
109
110TEST_P(FloatFromJsonSuccessTest, Test) {
111 const auto& param = GetParam();
112
113 proto_json::messages::FloatMessage message;
114 proto_json::messages::FloatMessage expected_message;
115 proto_json::messages::FloatMessage sample_message;
116 formats::json::Value input = PrepareJsonTestData(param.input);
117 expected_message = PrepareTestData(param.expected_message);
118
119 message.set_field1(100.001);
120
121 UASSERT_NO_THROW((message = JsonToMessage<proto_json::messages::FloatMessage>(input, param.options)));
122
123 if (!param.skip_native_check) {
124 UASSERT_NO_THROW(InitSampleMessage(param.input, sample_message, param.options));
125 CheckMessageEqual(message, sample_message);
126 }
127
128 CheckMessageEqual(message, expected_message);
129}
130
131TEST_P(FloatFromJsonFailureTest, Test) {
132 const auto& param = GetParam();
133
134 proto_json::messages::FloatMessage sample_message;
135 formats::json::Value input = PrepareJsonTestData(param.input);
136
138 (void)JsonToMessage<proto_json::messages::FloatMessage>(input, param.options),
139 param.expected_errc,
140 param.expected_path
141 );
142
143 if (!param.skip_native_check) {
144 UEXPECT_THROW(InitSampleMessage(param.input, sample_message, param.options), SampleError);
145 }
146}
147
148} // namespace protobuf::json::tests
149
150USERVER_NAMESPACE_END