1/*
2 * Copyright 2017, Andrew Lindesay <apl@lindesay.co.nz>
3 * Distributed under the terms of the MIT License.
4 */
5#include "JsonTextWriterTest.h"
6
7#include <AutoDeleter.h>
8
9#include <Json.h>
10#include <JsonTextWriter.h>
11
12#include <cppunit/TestCaller.h>
13#include <cppunit/TestSuite.h>
14
15#include "JsonSamples.h"
16
17
18#define LOOPS_TEST_OBJECT_A_FOR_PERFORMANCE 100000
19
20
21using namespace BPrivate;
22
23
24JsonTextWriterTest::JsonTextWriterTest()
25{
26}
27
28
29JsonTextWriterTest::~JsonTextWriterTest()
30{
31}
32
33
34void
35JsonTextWriterTest::TestArrayA()
36{
37	BMallocIO* outputData = new BMallocIO();
38	ObjectDeleter<BMallocIO> outputDataDeleter(outputData);
39	BJsonTextWriter writer(outputData);
40
41	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteArrayStart());
42	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("1234"));
43	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteInteger(4567));
44	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteArrayStart());
45	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("A"));
46	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("b"));
47	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("C\xc3\xa9zanne"));
48	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteArrayEnd());
49	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteArrayEnd());
50	writer.Complete();
51
52	BString outputString((char*)outputData->Buffer(),
53		outputData->BufferLength());
54	fprintf(stderr, "expected out >%s<\n", JSON_SAMPLE_ARRAY_A_EXPECTED_OUT);
55	fprintf(stderr, "actual out   >%s< (%" B_PRIuSIZE ")\n", outputString.String(),
56		outputData->BufferLength());
57
58	CPPUNIT_ASSERT_EQUAL(BString(JSON_SAMPLE_ARRAY_A_EXPECTED_OUT),
59		outputString);
60}
61
62
63void
64JsonTextWriterTest::TestObjectA()
65{
66	BMallocIO* outputData = new BMallocIO();
67	ObjectDeleter<BMallocIO> outputDataDeleter(outputData);
68	BJsonTextWriter writer(outputData);
69
70	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteObjectStart());
71	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteObjectName("weather"));
72	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("raining"));
73	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteObjectName("humidity"));
74	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("too-high"));
75	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteObjectName("daysOfWeek"));
76	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteArrayStart());
77	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("MON"));
78	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("TUE"));
79	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("WED"));
80	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("THR"));
81	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString("FRI"));
82	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteArrayEnd());
83	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteObjectEnd());
84	writer.Complete();
85
86	BString outputString((char*)outputData->Buffer(),
87		outputData->BufferLength());
88	fprintf(stderr, "expected out >%s<\n", JSON_SAMPLE_OBJECT_A_EXPECTED_OUT);
89	fprintf(stderr, "actual out   >%s< (%" B_PRIuSIZE ")\n", outputString.String(),
90		outputData->BufferLength());
91
92	CPPUNIT_ASSERT_EQUAL(BString(JSON_SAMPLE_OBJECT_A_EXPECTED_OUT),
93		outputString);
94}
95
96
97void
98JsonTextWriterTest::TestObjectAForPerformance()
99{
100	int i;
101
102	for (i = 0; i < LOOPS_TEST_OBJECT_A_FOR_PERFORMANCE; i++) {
103		TestObjectA();
104	}
105}
106
107
108void
109JsonTextWriterTest::TestInteger()
110{
111	BMallocIO* outputData = new BMallocIO();
112	ObjectDeleter<BMallocIO> outputDataDeleter(outputData);
113	BJsonTextWriter writer(outputData);
114	static const char* expectedOut = JSON_SAMPLE_NUMBER_B_EXPECTED_OUT;
115
116	CPPUNIT_ASSERT_EQUAL(B_OK,
117		writer.WriteInteger(JSON_SAMPLE_NUMBER_B_LITERAL));
118	writer.Complete();
119
120	BString outputString((char *)outputData->Buffer(),
121		outputData->BufferLength());
122	fprintf(stderr, "expected out >%s<\n", expectedOut);
123	fprintf(stderr, "actual out   >%s< (%" B_PRIuSIZE ")\n", outputString.String(),
124		outputData->BufferLength());
125
126	CPPUNIT_ASSERT_EQUAL(BString(expectedOut),
127		outputString);
128}
129
130
131void
132JsonTextWriterTest::TestDouble()
133{
134	BMallocIO* outputData = new BMallocIO();
135	ObjectDeleter<BMallocIO> outputDataDeleter(outputData);
136	BJsonTextWriter writer(outputData);
137	static const char* expectedOut = "3.142857";
138
139	CPPUNIT_ASSERT_EQUAL(B_OK,
140		writer.WriteDouble(JSON_SAMPLE_NUMBER_A_LITERAL));
141	writer.Complete();
142
143	BString outputString((char *)outputData->Buffer(),
144		outputData->BufferLength());
145	fprintf(stderr, "expected out >%s<\n", expectedOut);
146	fprintf(stderr, "actual out   >%s< (%" B_PRIuSIZE ")\n", outputString.String(),
147		outputData->BufferLength());
148
149	CPPUNIT_ASSERT_EQUAL(BString(expectedOut),
150		outputString);
151}
152
153
154void
155JsonTextWriterTest::TestFalse()
156{
157	BMallocIO* outputData = new BMallocIO();
158	ObjectDeleter<BMallocIO> outputDataDeleter(outputData);
159	BJsonTextWriter writer(outputData);
160	static const char* expectedOut = "false";
161
162	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteFalse());
163	writer.Complete();
164
165	BString outputString((char*)outputData->Buffer(),
166		outputData->BufferLength());
167	fprintf(stderr, "expected out >%s<\n", expectedOut);
168	fprintf(stderr, "actual out   >%s< (%" B_PRIuSIZE ")\n",
169		outputString.String(), outputData->BufferLength());
170
171	CPPUNIT_ASSERT_EQUAL(BString(expectedOut),
172		outputString);
173}
174
175
176void
177JsonTextWriterTest::TestStringGeneric(const char *input,
178	const char *expectedOut)
179{
180	BMallocIO* outputData = new BMallocIO();
181	ObjectDeleter<BMallocIO> outputDataDeleter(outputData);
182	BJsonTextWriter writer(outputData);
183
184	CPPUNIT_ASSERT_EQUAL(B_OK, writer.WriteString(input));
185	writer.Complete();
186
187	BString outputString((char*)outputData->Buffer(),
188		outputData->BufferLength());
189	fprintf(stderr, "expected out >%s<\n", expectedOut);
190	fprintf(stderr, "actual out   >%s< (%" B_PRIuSIZE ")\n",
191		outputString.String(), outputData->BufferLength());
192
193	CPPUNIT_ASSERT_EQUAL(BString(expectedOut),
194		outputString);
195}
196
197void
198JsonTextWriterTest::TestString()
199{
200	TestStringGeneric(
201		"\"Eichh\xc3\xb6rnchen\"\nsind\nTiere.",
202		"\"\\\"Eichh\\u00f6rnchen\\\"\\nsind\\nTiere.\"");
203		// complex example with unicode, escapes and simple sequences.
204	TestStringGeneric("", "\"\"");
205	TestStringGeneric("Press \"C\" to continue",
206		"\"Press \\\"C\\\" to continue\"");
207		// test of a simple string of one character enclosed with escape
208		// characters to check handling of one character simple sub-sequences.
209	TestStringGeneric("\xc3\xb6", "\"\\u00f6\"");
210		// test of a unicode character on its own.
211	TestStringGeneric("simple", "\"simple\"");
212		// test of a simple string that contains no escapes or anything complex.
213	TestStringGeneric("\t", "\"\\t\"");
214		// test of a single escape character.
215	TestStringGeneric("\007B", "\"B\"");
216		// contains an illegal character which should be ignored.
217	TestStringGeneric("X", "\"X\"");
218		// a simple string with a single character
219}
220
221
222/*static*/ void
223JsonTextWriterTest::AddTests(BTestSuite& parent)
224{
225	CppUnit::TestSuite& suite = *new CppUnit::TestSuite(
226		"JsonTextWriterTest");
227
228	suite.addTest(new CppUnit::TestCaller<JsonTextWriterTest>(
229		"JsonTextWriterTest::TestDouble",
230		&JsonTextWriterTest::TestDouble));
231
232	suite.addTest(new CppUnit::TestCaller<JsonTextWriterTest>(
233		"JsonTextWriterTest::TestInteger",
234		&JsonTextWriterTest::TestInteger));
235
236	suite.addTest(new CppUnit::TestCaller<JsonTextWriterTest>(
237		"JsonTextWriterTest::TestFalse",
238		&JsonTextWriterTest::TestFalse));
239
240	suite.addTest(new CppUnit::TestCaller<JsonTextWriterTest>(
241		"JsonTextWriterTest::TestString",
242		&JsonTextWriterTest::TestString));
243
244	suite.addTest(new CppUnit::TestCaller<JsonTextWriterTest>(
245		"JsonTextWriterTest::TestArrayA",
246		&JsonTextWriterTest::TestArrayA));
247
248	suite.addTest(new CppUnit::TestCaller<JsonTextWriterTest>(
249		"JsonTextWriterTest::TestObjectA",
250		&JsonTextWriterTest::TestObjectA));
251
252//	suite.addTest(new CppUnit::TestCaller<JsonTextWriterTest>(
253//		"JsonTextWriterTest::TestObjectAForPerformance",
254//		&JsonTextWriterTest::TestObjectAForPerformance));
255
256	parent.addTest("JsonTextWriterTest", &suite);
257}