Coverage Report

Created: 2024-04-30 09:35

test/zserio/JsonDecoderTest.cpp
Line
Count
Source
1
#include "gtest/gtest.h"
2
#include "zserio/JsonDecoder.h"
3
4
namespace zserio
5
{
6
7
using JsonDecoder = BasicJsonDecoder<>;
8
9
class JsonDecoderTest : public ::testing::Test
10
{
11
protected:
12
    template <typename T>
13
    void checkDecoderSuccess(const char* input, size_t expectedNumRead, T expectedValue)
14
46
    {
15
46
        const auto decoderResult = m_decoder.decodeValue(input);
16
92
        ASSERT_EQ(expectedNumRead, decoderResult.numReadChars) << input;
17
92
        ASSERT_TRUE(decoderResult.value.isType<T>()) << input;
18
92
        ASSERT_EQ(expectedValue, decoderResult.value.get<T>()) << input;
19
46
    }
20
21
    void checkDecoderFailure(const char* input, size_t expectedNumRead)
22
41
    {
23
41
        const auto decoderResult = m_decoder.decodeValue(input);
24
82
        ASSERT_EQ(expectedNumRead, decoderResult.numReadChars) << input;
25
82
        ASSERT_FALSE(decoderResult.value.hasValue()) << input;
26
41
    }
27
28
    JsonDecoder m_decoder;
29
};
30
31
TEST_F(JsonDecoderTest, decodeInvalid)
32
1
{
33
1
    checkDecoderFailure("invalid", 1);
34
1
}
35
36
TEST_F(JsonDecoderTest, decodeNull)
37
1
{
38
1
    checkDecoderSuccess("null", 4, nullptr);
39
1
    checkDecoderSuccess("null {}", 4, nullptr);
40
1
    checkDecoderSuccess("null{}", 4, nullptr);
41
1
    checkDecoderSuccess("nullix", 4, nullptr);
42
43
1
    checkDecoderFailure("nvalid", 2);
44
1
    checkDecoderFailure("nul", 3);
45
1
}
46
47
TEST_F(JsonDecoderTest, decodeTrue)
48
1
{
49
1
    checkDecoderSuccess("true", 4, true);
50
1
    checkDecoderSuccess("true {}", 4, true);
51
52
1
    checkDecoderFailure("trust", 4);
53
1
    checkDecoderFailure("tru", 3);
54
1
}
55
56
TEST_F(JsonDecoderTest, decodeFalse)
57
1
{
58
1
    checkDecoderSuccess("false", 5, false);
59
1
    checkDecoderSuccess("false {}", 5, false);
60
61
1
    checkDecoderFailure("ffalse", 2);
62
1
    checkDecoderFailure("fa", 2);
63
1
}
64
65
TEST_F(JsonDecoderTest, decodeNan)
66
1
{
67
1
    {
68
1
        const auto decoderResult = m_decoder.decodeValue("NaN");
69
1
        ASSERT_EQ(3, decoderResult.numReadChars);
70
1
        ASSERT_TRUE(decoderResult.value.isType<double>());
71
1
        ASSERT_TRUE(std::isnan(decoderResult.value.get<double>()));
72
1
    }
73
74
1
    {
75
1
        const auto decoderResult = m_decoder.decodeValue("NaN {}");
76
1
        ASSERT_EQ(3, decoderResult.numReadChars);
77
1
        ASSERT_TRUE(decoderResult.value.isType<double>());
78
1
        ASSERT_TRUE(std::isnan(decoderResult.value.get<double>()));
79
1
    }
80
81
1
    checkDecoderFailure("Nanic", 3);
82
1
    checkDecoderFailure("Na", 2);
83
1
}
84
85
TEST_F(JsonDecoderTest, decodePositiveInfinity)
86
1
{
87
1
    {
88
1
        const auto decoderResult = m_decoder.decodeValue("Infinity");
89
1
        ASSERT_EQ(8, decoderResult.numReadChars);
90
1
        ASSERT_TRUE(decoderResult.value.isType<double>());
91
1
        ASSERT_TRUE(std::isinf(decoderResult.value.get<double>()));
92
1
        ASSERT_LT(0.0, decoderResult.value.get<double>());
93
1
    }
94
95
1
    {
96
1
        const auto decoderResult = m_decoder.decodeValue("Infinity {}");
97
1
        ASSERT_EQ(8, decoderResult.numReadChars);
98
1
        ASSERT_TRUE(decoderResult.value.isType<double>());
99
1
        ASSERT_TRUE(std::isinf(decoderResult.value.get<double>()));
100
1
        ASSERT_LT(0.0, decoderResult.value.get<double>());
101
1
    }
102
103
1
    checkDecoderFailure("Infiniinfiny", 7);
104
1
    checkDecoderFailure("Inf", 3);
105
1
}
106
107
TEST_F(JsonDecoderTest, decodeNegativeInfinity)
108
1
{
109
1
    {
110
1
        const auto decoderResult = m_decoder.decodeValue("-Infinity");
111
1
        ASSERT_EQ(9, decoderResult.numReadChars);
112
1
        ASSERT_TRUE(decoderResult.value.isType<double>());
113
1
        ASSERT_TRUE(std::isinf(decoderResult.value.get<double>()));
114
1
        ASSERT_GT(0.0, decoderResult.value.get<double>());
115
1
    }
116
117
1
    {
118
1
        const auto decoderResult = m_decoder.decodeValue("-Infinity {}");
119
1
        ASSERT_EQ(9, decoderResult.numReadChars);
120
1
        ASSERT_TRUE(decoderResult.value.isType<double>());
121
1
        ASSERT_TRUE(std::isinf(decoderResult.value.get<double>()));
122
1
        ASSERT_GT(0.0, decoderResult.value.get<double>());
123
1
    }
124
125
1
    checkDecoderFailure("-Infinvalid", 7);
126
1
    checkDecoderFailure("-Infin", 6);
127
1
    checkDecoderFailure("-Infix", 6);
128
1
}
129
130
TEST_F(JsonDecoderTest, decodeSignedIntegral)
131
1
{
132
1
    checkDecoderSuccess("-0", 2, static_cast<int64_t>(0));
133
1
    checkDecoderSuccess("-1", 2, static_cast<int64_t>(-1));
134
1
    checkDecoderSuccess("-9223372036854775808", 20, INT64_MIN);
135
136
1
    checkDecoderFailure("--10", 1);
137
1
    checkDecoderFailure("-", 1);
138
1
    checkDecoderFailure("-A", 1);
139
1
}
140
141
TEST_F(JsonDecoderTest, decodeUnsignedIntegral)
142
1
{
143
1
    checkDecoderSuccess("0", 1, static_cast<uint64_t>(0));
144
1
    checkDecoderSuccess("1", 1, static_cast<uint64_t>(1));
145
1
    checkDecoderSuccess("9223372036854775807", 19, static_cast<uint64_t>(INT64_MAX));
146
1
    checkDecoderSuccess("18446744073709551615", 20, UINT64_MAX);
147
148
1
    checkDecoderFailure("+", 1);
149
1
    checkDecoderFailure("+10", 1);
150
1
    checkDecoderFailure("184467440737095516156", 21);
151
1
}
152
153
TEST_F(JsonDecoderTest, decodeDouble)
154
1
{
155
1
    checkDecoderSuccess("0.0", 3, 0.0);
156
1
    checkDecoderSuccess("-1.0", 4, -1.0);
157
1
    checkDecoderSuccess("1.0", 3, 1.0);
158
1
    checkDecoderSuccess("3.5", 3, 3.5);
159
1
    checkDecoderSuccess("9.875", 5, 9.875);
160
1
    checkDecoderSuccess("0.6171875", 9, 0.6171875);
161
162
1
    checkDecoderSuccess("1e+20", 5, 1e+20);
163
1
    checkDecoderSuccess("1E+20", 5, 1E+20);
164
1
    checkDecoderSuccess("1e-20", 5, 1e-20);
165
1
    checkDecoderSuccess("1E-20", 5, 1E-20);
166
1
    checkDecoderSuccess("-1e+20", 6, -1e+20);
167
1
    checkDecoderSuccess("-1E+20", 6, -1E+20);
168
1
    checkDecoderSuccess("-1e-20", 6, -1e-20);
169
1
    checkDecoderSuccess("-1E-20", 6, -1E-20);
170
171
1
    checkDecoderSuccess("1.0E-20", 7, 1.0E-20);
172
1
    checkDecoderSuccess("-1.0E-20", 8, -1.0E-20);
173
1
    checkDecoderSuccess("9.875E+3", 8, 9.875E+3);
174
1
    checkDecoderSuccess("-9.875E-3", 9, -9.875E-3);
175
176
1
    checkDecoderFailure("1EE20", 2);
177
1
    checkDecoderFailure("1E.E20", 2);
178
1
    checkDecoderFailure("1E++20", 3);
179
1
    checkDecoderFailure("1E--20", 3);
180
181
1
    checkDecoderFailure("1e", 2);
182
1
    checkDecoderFailure("1e+", 3);
183
1
    checkDecoderFailure("1E-", 3);
184
1
}
185
186
TEST_F(JsonDecoderTest, decodeString)
187
1
{
188
1
    checkDecoderSuccess("\"\"", 2, std::string(""));
189
1
    checkDecoderSuccess("\"test\"", 6, std::string("test"));
190
1
    checkDecoderSuccess("\"München\"", 10, std::string("München"));
191
1
    checkDecoderSuccess("\"€\"", 5, std::string("€"));
192
193
    // escapes
194
1
    checkDecoderSuccess("\"\\\\\"", 4, std::string("\\"));
195
1
    checkDecoderSuccess("\"\\\"\"", 4, std::string("\""));
196
1
    checkDecoderSuccess("\"\\b\"", 4, std::string("\b"));
197
1
    checkDecoderSuccess("\"\\f\"", 4, std::string("\f"));
198
1
    checkDecoderSuccess("\"\\n\"", 4, std::string("\n"));
199
1
    checkDecoderSuccess("\"\\r\"", 4, std::string("\r"));
200
1
    checkDecoderSuccess("\"\\t\"", 4, std::string("\t"));
201
202
1
    checkDecoderSuccess("\"\\n\\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\\\\\"'Hello World2\"", 62,
203
1
            std::string("\n\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\"\'Hello World2"));
204
205
    // <= 0x1F -> unicode escape
206
1
    checkDecoderSuccess("\"\\u001f\"", 8, std::string("\x1F"));
207
208
1
    checkDecoderFailure("\"\\u001x\"", 7);
209
1
    checkDecoderFailure("\"unterminated", 13);
210
1
    checkDecoderFailure("\"wrong escape \\", 15);
211
1
    checkDecoderFailure("\"wrong unicode escape - 0 char \\u", 33);
212
1
    checkDecoderFailure("\"wrong unicode escape - 1 char \\u0", 34);
213
1
    checkDecoderFailure("\"wrong unicode escape - 1 char \\u1", 34);
214
1
    checkDecoderFailure("\"wrong unicode escape - 2 chars \\u00", 36);
215
1
    checkDecoderFailure("\"wrong unicode escape - 2 chars \\u01", 36);
216
1
    checkDecoderFailure("\"wrong unicode escape - 3 chars \\u00-", 37);
217
1
    checkDecoderFailure("\"wrong unicode escape - 3 chars \\u00A", 37);
218
1
    checkDecoderFailure("\"wrong unicode escape - 3 chars \\u00G", 37);
219
1
    checkDecoderFailure("\"wrong unicode escape - 4 chars \\u000G", 38);
220
1
    checkDecoderFailure("\"unknown escape \\x", 18);
221
1
}
222
223
TEST_F(JsonDecoderTest, wrong_arguments)
224
1
{
225
1
    checkDecoderFailure("", 0);
226
1
}
227
228
} // namespace zserio