Coverage Report

Created: 2024-07-18 11:41

test/zserio/JsonParserTest.cpp
Line
Count
Source
1
#include <sstream>
2
3
#include "gtest/gtest.h"
4
#include "zserio/JsonParser.h"
5
6
namespace zserio
7
{
8
9
namespace
10
{
11
12
class DummyObserver : public JsonParser::IObserver
13
{
14
public:
15
    const std::vector<std::string>& getReport() const
16
12
    {
17
12
        return m_report;
18
12
    }
19
20
    void beginObject() override
21
9
    {
22
9
        m_report.push_back("beginObject");
23
9
    }
24
25
    void endObject() override
26
3
    {
27
3
        m_report.push_back("endObject");
28
3
    }
29
30
    void beginArray() override
31
2
    {
32
2
        m_report.push_back("beginArray");
33
2
    }
34
35
    void endArray() override
36
1
    {
37
1
        m_report.push_back("endArray");
38
1
    }
39
40
    void visitKey(StringView stringValue) override
41
7
    {
42
7
        m_report.push_back("visitKey: " + toString(stringValue));
43
7
    }
44
45
    void visitValue(std::nullptr_t) override
46
1
    {
47
1
        m_report.push_back("visitValue: null");
48
1
    }
49
50
    void visitValue(bool boolValue) override
51
1
    {
52
1
        m_report.push_back("visitValue: " + toString(boolValue));
53
1
    }
54
55
    void visitValue(int64_t intValue) override
56
1
    {
57
1
        m_report.push_back("visitValue: " + toString(intValue));
58
1
    }
59
60
    void visitValue(uint64_t uintValue) override
61
4
    {
62
4
        m_report.push_back("visitValue: " + toString(uintValue));
63
4
    }
64
65
    void visitValue(double doubleValue) override
66
1
    {
67
1
        m_report.push_back("visitValue: " + std::to_string(doubleValue));
68
1
    }
69
70
    void visitValue(StringView stringValue) override
71
6
    {
72
6
        m_report.push_back("visitValue: " + toString(stringValue));
73
6
    }
74
75
private:
76
    std::vector<std::string> m_report;
77
};
78
79
} // namespace
80
81
TEST(JsonParserTest, empty)
82
1
{
83
1
    std::stringstream str("");
84
1
    DummyObserver observer;
85
1
    JsonParser jsonParser(str, observer);
86
1
    ASSERT_TRUE(jsonParser.parse());
87
1
    ASSERT_EQ(0, observer.getReport().size());
88
1
}
89
90
TEST(JsonParserTest, oneString)
91
1
{
92
1
    std::stringstream str("\"text\"");
93
1
    DummyObserver observer;
94
1
    JsonParser jsonParser(str, observer);
95
1
    ASSERT_TRUE(jsonParser.parse());
96
1
    ASSERT_EQ(std::vector<std::string>{{"visitValue: text"}}, observer.getReport());
97
1
}
98
99
TEST(JsonParserTest, twoStrings)
100
1
{
101
1
    std::stringstream str("\"text\"\"second\"");
102
1
    DummyObserver observer;
103
1
    JsonParser jsonParser(str, observer);
104
1
    ASSERT_FALSE(jsonParser.parse());
105
1
    std::vector<std::string> expectedReport = {{"visitValue: text"}};
106
1
    ASSERT_EQ(expectedReport, observer.getReport());
107
1
    ASSERT_TRUE(jsonParser.parse());
108
1
    expectedReport.push_back("visitValue: second");
109
1
    ASSERT_EQ(expectedReport, observer.getReport());
110
1
}
111
112
TEST(JsonParserTest, parse)
113
1
{
114
1
    std::stringstream str("{\"array\":\n[\n{\"key1\":\n10, \"key2\":\n\"text\"}, {}]}");
115
1
    DummyObserver observer;
116
1
    JsonParser jsonParser(str, observer);
117
1
    ASSERT_TRUE(jsonParser.parse());
118
119
1
    std::vector<std::string> expectedReport = {{
120
1
            {"beginObject"},
121
1
            {"visitKey: array"},
122
1
            {"beginArray"},
123
1
            {"beginObject"},
124
1
            {"visitKey: key1"},
125
1
            {"visitValue: 10"},
126
1
            {"visitKey: key2"},
127
1
            {"visitValue: text"},
128
1
            {"endObject"},
129
1
            {"beginObject"},
130
1
            {"endObject"},
131
1
            {"endArray"},
132
1
            {"endObject"},
133
1
    }};
134
1
    ASSERT_EQ(expectedReport, observer.getReport());
135
1
}
136
137
TEST(JsonParserTest, valueTypes)
138
1
{
139
1
    std::stringstream str("null true 10 -10 1.1 \"str\"");
140
1
    DummyObserver observer;
141
1
    JsonParser jsonParser(str, observer);
142
6
    while (!jsonParser.parse())
143
5
    {}
144
145
1
    std::vector<std::string> expectedReport = {{
146
1
            {"visitValue: null"},
147
1
            {"visitValue: true"},
148
1
            {"visitValue: 10"},
149
1
            {"visitValue: -10"},
150
1
            {"visitValue: 1.100000"},
151
1
            {"visitValue: str"},
152
1
    }};
153
1
    ASSERT_EQ(expectedReport, observer.getReport());
154
1
}
155
156
TEST(JsonParserTest, unexpectedObject)
157
1
{
158
1
    std::stringstream str("{\n\n{\n\n");
159
1
    DummyObserver observer;
160
1
    JsonParser jsonParser(str, observer);
161
1
    ASSERT_THROW(
162
1
            {
163
1
                try
164
1
                {
165
1
                    jsonParser.parse();
166
1
                }
167
1
                catch (const JsonParserException& e)
168
1
                {
169
1
                    ASSERT_STREQ(
170
1
                            "JsonParser:3:1: unexpected token: BEGIN_OBJECT, expecting END_OBJECT!", e.what());
171
1
                    throw;
172
1
                }
173
1
            },
174
1
            JsonParserException);
175
176
1
    std::vector<std::string> expectedReport = {{"beginObject"}};
177
1
    ASSERT_EQ(expectedReport, observer.getReport());
178
1
}
179
180
TEST(JsonParserTest, unexpectedObjectAfterItemSeparator)
181
1
{
182
1
    std::stringstream str("{\n  \"key\": 10,\n  {\n");
183
1
    DummyObserver observer;
184
1
    JsonParser jsonParser(str, observer);
185
1
    ASSERT_THROW(
186
1
            {
187
1
                try
188
1
                {
189
1
                    jsonParser.parse();
190
1
                }
191
1
                catch (const JsonParserException& e)
192
1
                {
193
1
                    ASSERT_STREQ("JsonParser:3:3: unexpected token: BEGIN_OBJECT, expecting VALUE!", e.what());
194
1
                    throw;
195
1
                }
196
1
            },
197
1
            JsonParserException);
198
199
1
    std::vector<std::string> expectedReport = {{
200
1
            {"beginObject"},
201
1
            {"visitKey: key"},
202
1
            {"visitValue: 10"},
203
1
    }};
204
1
    ASSERT_EQ(expectedReport, observer.getReport());
205
1
}
206
207
TEST(JsonParserTest, missingObjectItemSeparator)
208
1
{
209
1
    std::stringstream str("{\n\"item1\":\"text\"\n\"item2\":\"text\"\n}");
210
1
    DummyObserver observer;
211
1
    JsonParser jsonParser(str, observer);
212
1
    ASSERT_THROW(
213
1
            {
214
1
                try
215
1
                {
216
1
                    jsonParser.parse();
217
1
                }
218
1
                catch (const JsonParserException& e)
219
1
                {
220
1
                    ASSERT_STREQ("JsonParser:3:1: unexpected token: VALUE, expecting END_OBJECT!", e.what());
221
1
                    throw;
222
1
                }
223
1
            },
224
1
            JsonParserException);
225
226
1
    std::vector<std::string> expectedReport = {{
227
1
            {"beginObject"},
228
1
            {"visitKey: item1"},
229
1
            {"visitValue: text"},
230
1
    }};
231
1
    ASSERT_EQ(expectedReport, observer.getReport());
232
1
}
233
234
TEST(JsonParserTest, wrongKeyType)
235
1
{
236
1
    std::stringstream str("{\n10:\"text\"\n}");
237
1
    DummyObserver observer;
238
1
    JsonParser jsonParser(str, observer);
239
1
    ASSERT_THROW(
240
1
            {
241
1
                try
242
1
                {
243
1
                    jsonParser.parse();
244
1
                }
245
1
                catch (const JsonParserException& e)
246
1
                {
247
1
                    ASSERT_STREQ("JsonParser:2:1: Key must be a string value!", e.what());
248
1
                    throw;
249
1
                }
250
1
            },
251
1
            JsonParserException);
252
253
1
    std::vector<std::string> expectedReport = {{"beginObject"}};
254
1
    ASSERT_EQ(expectedReport, observer.getReport());
255
1
}
256
257
TEST(JsonParserTest, unexpectedElementToken)
258
1
{
259
1
    std::stringstream str("{\n\"item\":}");
260
1
    DummyObserver observer;
261
1
    JsonParser jsonParser(str, observer);
262
1
    ASSERT_THROW(
263
1
            {
264
1
                try
265
1
                {
266
1
                    jsonParser.parse();
267
1
                }
268
1
                catch (const JsonParserException& e)
269
1
                {
270
1
                    ASSERT_STREQ("JsonParser:2:8: unexpected token: END_OBJECT, "
271
1
                                 "expecting one of [BEGIN_OBJECT, BEGIN_ARRAY, VALUE]!",
272
1
                            e.what());
273
1
                    throw;
274
1
                }
275
1
            },
276
1
            JsonParserException);
277
278
1
    std::vector<std::string> expectedReport = {{
279
1
            {"beginObject"},
280
1
            {"visitKey: item"},
281
1
    }};
282
1
    ASSERT_EQ(expectedReport, observer.getReport());
283
1
}
284
285
TEST(JsonParserTest, missingArrayElementSeparator)
286
1
{
287
1
    std::stringstream str("{\n\"array\":\n[10\n20\n]}");
288
1
    DummyObserver observer;
289
1
    JsonParser jsonParser(str, observer);
290
1
    ASSERT_THROW(
291
1
            {
292
1
                try
293
1
                {
294
1
                    jsonParser.parse();
295
1
                }
296
1
                catch (const JsonParserException& e)
297
1
                {
298
1
                    ASSERT_STREQ("JsonParser:4:1: unexpected token: VALUE, expecting END_ARRAY!", e.what());
299
1
                    throw;
300
1
                }
301
1
            },
302
1
            JsonParserException);
303
304
1
    std::vector<std::string> expectedReport = {{
305
1
            {"beginObject"},
306
1
            {"visitKey: array"},
307
1
            {"beginArray"},
308
1
            {"visitValue: 10"},
309
1
    }};
310
1
    ASSERT_EQ(expectedReport, observer.getReport());
311
1
}
312
313
} // namespace zserio