Coverage Report

Created: 2023-12-13 14:58

test/zserio/JsonParserTest.cpp
Line
Count
Source
1
#include "gtest/gtest.h"
2
3
#include <sstream>
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
        try
163
1
        {
164
1
            jsonParser.parse();
165
1
        }
166
1
        catch (const JsonParserException& e)
167
1
        {
168
1
            ASSERT_STREQ("JsonParser:3:1: unexpected token: BEGIN_OBJECT, expecting END_OBJECT!", e.what());
169
1
            throw;
170
1
        }
171
1
    }, JsonParserException);
172
173
1
    std::vector<std::string> expectedReport = {{
174
1
        "beginObject"
175
1
    }};
176
1
    ASSERT_EQ(expectedReport, observer.getReport());
177
1
}
178
179
TEST(JsonParserTest, unexpectedObjectAfterItemSeparator)
180
1
{
181
1
    std::stringstream str("{\n  \"key\": 10,\n  {\n");
182
1
    DummyObserver observer;
183
1
    JsonParser jsonParser(str, observer);
184
1
    ASSERT_THROW({
185
1
        try
186
1
        {
187
1
            jsonParser.parse();
188
1
        }
189
1
        catch (const JsonParserException& e)
190
1
        {
191
1
            ASSERT_STREQ("JsonParser:3:3: unexpected token: BEGIN_OBJECT, expecting VALUE!", e.what());
192
1
            throw;
193
1
        }
194
1
    }, JsonParserException);
195
196
1
    std::vector<std::string> expectedReport = {{
197
1
        {"beginObject"},
198
1
        {"visitKey: key"},
199
1
        {"visitValue: 10"}
200
1
    }};
201
1
    ASSERT_EQ(expectedReport, observer.getReport());
202
1
}
203
204
TEST(JsonParserTest, missingObjectItemSeparator)
205
1
{
206
1
    std::stringstream str("{\n\"item1\":\"text\"\n\"item2\":\"text\"\n}");
207
1
    DummyObserver observer;
208
1
    JsonParser jsonParser(str, observer);
209
1
    ASSERT_THROW({
210
1
        try
211
1
        {
212
1
            jsonParser.parse();
213
1
        }
214
1
        catch (const JsonParserException& e)
215
1
        {
216
1
            ASSERT_STREQ("JsonParser:3:1: unexpected token: VALUE, expecting END_OBJECT!", e.what());
217
1
            throw;
218
1
        }
219
1
    }, JsonParserException);
220
221
1
    std::vector<std::string> expectedReport = {{
222
1
        {"beginObject"},
223
1
        {"visitKey: item1"},
224
1
        {"visitValue: text"}
225
1
    }};
226
1
    ASSERT_EQ(expectedReport, observer.getReport());
227
1
}
228
229
TEST(JsonParserTest, wrongKeyType)
230
1
{
231
1
    std::stringstream str("{\n10:\"text\"\n}");
232
1
    DummyObserver observer;
233
1
    JsonParser jsonParser(str, observer);
234
1
    ASSERT_THROW({
235
1
        try
236
1
        {
237
1
            jsonParser.parse();
238
1
        }
239
1
        catch (const JsonParserException& e)
240
1
        {
241
1
            ASSERT_STREQ("JsonParser:2:1: Key must be a string value!", e.what());
242
1
            throw;
243
1
        }
244
1
    }, JsonParserException);
245
246
1
    std::vector<std::string> expectedReport = {{
247
1
        "beginObject"
248
1
    }};
249
1
    ASSERT_EQ(expectedReport, observer.getReport());
250
1
}
251
252
TEST(JsonParserTest, unexpectedElementToken)
253
1
{
254
1
    std::stringstream str("{\n\"item\":}");
255
1
    DummyObserver observer;
256
1
    JsonParser jsonParser(str, observer);
257
1
    ASSERT_THROW({
258
1
        try
259
1
        {
260
1
            jsonParser.parse();
261
1
        }
262
1
        catch (const JsonParserException& e)
263
1
        {
264
1
            ASSERT_STREQ("JsonParser:2:8: unexpected token: END_OBJECT, "
265
1
                    "expecting one of [BEGIN_OBJECT, BEGIN_ARRAY, VALUE]!", e.what());
266
1
            throw;
267
1
        }
268
1
    }, JsonParserException);
269
270
1
    std::vector<std::string> expectedReport = {{
271
1
        {"beginObject"},
272
1
        {"visitKey: item"}
273
1
    }};
274
1
    ASSERT_EQ(expectedReport, observer.getReport());
275
1
}
276
277
TEST(JsonParserTest, missingArrayElementSeparator)
278
1
{
279
1
    std::stringstream str("{\n\"array\":\n[10\n20\n]}");
280
1
    DummyObserver observer;
281
1
    JsonParser jsonParser(str, observer);
282
1
    ASSERT_THROW({
283
1
        try
284
1
        {
285
1
            jsonParser.parse();
286
1
        }
287
1
        catch (const JsonParserException& e)
288
1
        {
289
1
            ASSERT_STREQ("JsonParser:4:1: unexpected token: VALUE, expecting END_ARRAY!", e.what());
290
1
            throw;
291
1
        }
292
1
    }, JsonParserException);
293
294
1
    std::vector<std::string> expectedReport = {{
295
1
        {"beginObject"},
296
1
        {"visitKey: array"},
297
1
        {"beginArray"},
298
1
        {"visitValue: 10"}
299
1
    }};
300
1
    ASSERT_EQ(expectedReport, observer.getReport());
301
1
}
302
303
} // namespace zserio