Coverage Report

Created: 2023-12-13 14:58

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