1 /*
2 * Copyright 2017, Andrew Lindesay <apl@lindesay.co.nz>
3 * Distributed under the terms of the MIT License.
4 */
5 #include "JsonToMessageTest.h"
6
7 #include <Json.h>
8
9 #include <cppunit/TestCaller.h>
10 #include <cppunit/TestSuite.h>
11
12 #include "JsonSamples.h"
13
14
15 #define LOOPS_TEST_OBJECT_A_FOR_PERFORMANCE 100000
16
17 using namespace BPrivate;
18
19
JsonToMessageTest()20 JsonToMessageTest::JsonToMessageTest()
21 {
22 }
23
24
~JsonToMessageTest()25 JsonToMessageTest::~JsonToMessageTest()
26 {
27 }
28
29
30 void
TestArrayA()31 JsonToMessageTest::TestArrayA()
32 {
33 BMessage message;
34 BMessage subMessage;
35 BString stringValue;
36 double doubleValue;
37
38 // ----------------------
39 BJson::Parse(JSON_SAMPLE_ARRAY_A_IN, message);
40 // ----------------------
41
42 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [0]", B_OK,
43 message.FindString("0", &stringValue));
44 CPPUNIT_ASSERT_EQUAL_MESSAGE("!eq [0]", BString("1234"), stringValue);
45
46 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [1]", B_OK,
47 message.FindDouble("1", &doubleValue));
48 CPPUNIT_ASSERT_EQUAL_MESSAGE("!eq [1]", 4567, doubleValue);
49
50 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [2]", B_OK,
51 message.FindMessage("2", &subMessage));
52
53 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [2.0]", B_OK,
54 subMessage.FindString("0", &stringValue));
55 CPPUNIT_ASSERT_EQUAL_MESSAGE("!eq [2.0]", BString("A"), stringValue);
56
57 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [2.1]", B_OK,
58 subMessage.FindString("1", &stringValue));
59 CPPUNIT_ASSERT_EQUAL_MESSAGE("!eq [2.1]", BString("b"), stringValue);
60
61 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [2.2]", B_OK,
62 subMessage.FindString("2", &stringValue));
63 CPPUNIT_ASSERT_EQUAL_MESSAGE("!eq [2.2]", BString("C\xc3\xa9zanne"),
64 stringValue);
65 }
66
67
68 void
TestArrayB()69 JsonToMessageTest::TestArrayB()
70 {
71 BMessage message;
72 BMessage subMessage;
73 BMessage subSubMessage;
74 BString stringValue;
75
76 // ----------------------
77 BJson::Parse(JSON_SAMPLE_ARRAY_B_IN, message);
78 // ----------------------
79
80 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [0]", B_OK,
81 message.FindString("0", &stringValue));
82 CPPUNIT_ASSERT_EQUAL_MESSAGE("!eq [0]", BString("Whirinaki"), stringValue);
83
84 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [1]", B_OK,
85 message.FindString("1", &stringValue));
86 CPPUNIT_ASSERT_EQUAL_MESSAGE("!eq [1]", BString("Wellington"), stringValue);
87
88 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [2]", B_OK,
89 message.FindMessage("2", &subMessage));
90
91 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [2.0]", B_OK,
92 subMessage.FindMessage("key", &subSubMessage));
93
94 CPPUNIT_ASSERT_EQUAL_MESSAGE("!find [2.0.0]", B_OK,
95 subSubMessage.FindString("0", &stringValue));
96 CPPUNIT_ASSERT_EQUAL_MESSAGE("!eq [2.0.0]", BString("value"), stringValue);
97 }
98
99
100 void
TestObjectA()101 JsonToMessageTest::TestObjectA()
102 {
103 BMessage message;
104 BMessage subMessage;
105 BString stringValue;
106
107 // ----------------------
108 BJson::Parse(JSON_SAMPLE_OBJECT_A_IN, message);
109 // ----------------------
110
111 CPPUNIT_ASSERT_EQUAL(B_OK, message.FindString("weather", &stringValue));
112 CPPUNIT_ASSERT_EQUAL(BString("raining"), stringValue);
113
114 CPPUNIT_ASSERT_EQUAL(B_OK, message.FindString("humidity", &stringValue));
115 CPPUNIT_ASSERT_EQUAL(BString("too-high"), stringValue);
116
117 CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("daysOfWeek", &subMessage));
118
119 CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindString("0", &stringValue));
120 CPPUNIT_ASSERT_EQUAL(BString("MON"), stringValue);
121
122 CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindString("1", &stringValue));
123 CPPUNIT_ASSERT_EQUAL(BString("TUE"), stringValue);
124
125 CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindString("2", &stringValue));
126 CPPUNIT_ASSERT_EQUAL(BString("WED"), stringValue);
127
128 CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindString("3", &stringValue));
129 CPPUNIT_ASSERT_EQUAL(BString("THR"), stringValue);
130
131 CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindString("4", &stringValue));
132 CPPUNIT_ASSERT_EQUAL(BString("FRI"), stringValue);
133 }
134
135
136 /*! This is not a real test, but is a convenient point at which to implement a
137 performance test.
138 */
139
140 void
TestObjectAForPerformance()141 JsonToMessageTest::TestObjectAForPerformance()
142 {
143 int i;
144
145 for (i=0; i < LOOPS_TEST_OBJECT_A_FOR_PERFORMANCE; i++)
146 TestObjectA();
147 }
148
149
150 void
TestObjectB()151 JsonToMessageTest::TestObjectB()
152 {
153 BMessage message;
154 bool boolValue;
155 void *ptrValue; // this is how NULL is represented.
156
157 // ----------------------
158 BJson::Parse(JSON_SAMPLE_OBJECT_B_IN, message);
159 // ----------------------
160
161 CPPUNIT_ASSERT_EQUAL(B_OK, message.FindBool("testTrue", &boolValue));
162 CPPUNIT_ASSERT_EQUAL(true, boolValue);
163
164 CPPUNIT_ASSERT_EQUAL(B_OK, message.FindBool("testFalse", &boolValue));
165 CPPUNIT_ASSERT_EQUAL(false, boolValue);
166
167 CPPUNIT_ASSERT_EQUAL(B_OK, message.FindPointer("testNull", &ptrValue));
168 CPPUNIT_ASSERT_EQUAL(0, (addr_t)ptrValue);
169 }
170
171
172 void
TestObjectC()173 JsonToMessageTest::TestObjectC()
174 {
175 BMessage message;
176 BMessage subMessage;
177 BString stringValue;
178
179 // ----------------------
180 BJson::Parse(JSON_SAMPLE_OBJECT_C_IN, message);
181 // ----------------------
182
183 CPPUNIT_ASSERT_EQUAL(B_OK, message.FindString("key", &stringValue));
184 CPPUNIT_ASSERT_EQUAL(BString("value"), stringValue);
185 }
186
187
188 void
TestUnterminatedObject()189 JsonToMessageTest::TestUnterminatedObject()
190 {
191 BMessage message;
192
193 // ----------------------
194 status_t result = BJson::Parse(JSON_SAMPLE_BROKEN_UNTERMINATED_OBJECT,
195 message);
196 // ----------------------
197
198 CPPUNIT_ASSERT_EQUAL(B_BAD_DATA, result);
199 }
200
201
202 void
TestUnterminatedArray()203 JsonToMessageTest::TestUnterminatedArray()
204 {
205 BMessage message;
206
207 // ----------------------
208 status_t result = BJson::Parse(JSON_SAMPLE_BROKEN_UNTERMINATED_ARRAY,
209 message);
210 // ----------------------
211
212 CPPUNIT_ASSERT_EQUAL(B_BAD_DATA, result);
213 }
214
215
TestHaikuDepotFetchBatch()216 void JsonToMessageTest::TestHaikuDepotFetchBatch()
217 {
218 const unsigned char input[] = JSON_SAMPLE_HDS_FETCH_BATCH_PKGS;
219 BMessage message;
220 BMessage resultMessage;
221 BMessage pkgsMessage;
222 BMessage pkgMessage1;
223 double modifyTimestampDouble;
224 double expectedModifyTimestampDouble = 1488785331631.0;
225
226 // ----------------------
227 status_t result = BJson::Parse((char*)input,
228 message);
229 // ----------------------
230
231 CPPUNIT_ASSERT_EQUAL(B_OK, result);
232
233 // this is quite a large test input so a random sample "thing to
234 // check" is chosen to indicate that the parse was successful.
235
236 CPPUNIT_ASSERT_EQUAL_MESSAGE("result", B_OK,
237 message.FindMessage("result", &resultMessage));
238 CPPUNIT_ASSERT_EQUAL_MESSAGE("pkgs", B_OK,
239 resultMessage.FindMessage("pkgs", &pkgsMessage));
240 CPPUNIT_ASSERT_EQUAL_MESSAGE("1", B_OK,
241 pkgsMessage.FindMessage("1", &pkgMessage1));
242 CPPUNIT_ASSERT_EQUAL_MESSAGE("modifyTimestamp", B_OK,
243 pkgMessage1.FindDouble("modifyTimestamp", &modifyTimestampDouble));
244
245 CPPUNIT_ASSERT_EQUAL(expectedModifyTimestampDouble, modifyTimestampDouble);
246 }
247
248
249 /*static*/ void
AddTests(BTestSuite & parent)250 JsonToMessageTest::AddTests(BTestSuite& parent)
251 {
252 CppUnit::TestSuite& suite = *new CppUnit::TestSuite(
253 "JsonToMessageTest");
254
255 suite.addTest(new CppUnit::TestCaller<JsonToMessageTest>(
256 "JsonToMessageTest::TestArrayA",
257 &JsonToMessageTest::TestArrayA));
258
259 suite.addTest(new CppUnit::TestCaller<JsonToMessageTest>(
260 "JsonToMessageTest::TestArrayB",
261 &JsonToMessageTest::TestArrayB));
262
263 suite.addTest(new CppUnit::TestCaller<JsonToMessageTest>(
264 "JsonToMessageTest::TestObjectA",
265 &JsonToMessageTest::TestObjectA));
266
267 suite.addTest(new CppUnit::TestCaller<JsonToMessageTest>(
268 "JsonToMessageTest::TestObjectB",
269 &JsonToMessageTest::TestObjectB));
270
271 suite.addTest(new CppUnit::TestCaller<JsonToMessageTest>(
272 "JsonToMessageTest::TestObjectC",
273 &JsonToMessageTest::TestObjectC));
274
275 suite.addTest(new CppUnit::TestCaller<JsonToMessageTest>(
276 "JsonToMessageTest::TestUnterminatedObject",
277 &JsonToMessageTest::TestUnterminatedObject));
278
279 suite.addTest(new CppUnit::TestCaller<JsonToMessageTest>(
280 "JsonToMessageTest::TestUnterminatedArray",
281 &JsonToMessageTest::TestUnterminatedArray));
282
283 suite.addTest(new CppUnit::TestCaller<JsonToMessageTest>(
284 "JsonToMessageTest::TestHaikuDepotFetchBatch",
285 &JsonToMessageTest::TestHaikuDepotFetchBatch));
286
287 // suite.addTest(new CppUnit::TestCaller<JsonToMessageTest>(
288 // "JsonToMessageTest::TestObjectAForPerformance",
289 // &JsonToMessageTest::TestObjectAForPerformance));
290
291 parent.addTest("JsonToMessageTest", &suite);
292 }
293