1 /* This file is part of QJson
2 *
3 * Copyright (C) 2009 Flavio Castelli <flavio.castelli@gmail.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License version 2.1, as published by the Free Software Foundation.
8 *
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #include <limits>
22
23 #include <QtCore/QVariant>
24
25 #include <QtTest/QtTest>
26
27 #include <QJson/Parser>
28 #include <QJson/Serializer>
29
30 class TestSerializer: public QObject
31 {
32 Q_OBJECT
33 private slots:
34 void testReadWriteEmptyDocument();
35 void testReadWrite();
36 void testReadWrite_data();
37 void testValueNull();
38 void testValueString();
39 void testValueString_data();
40 void testValueStringList();
41 void testValueStringList_data();
42 void testValueHashMap();
43 void testValueInteger();
44 void testValueInteger_data();
45 void testValueDouble();
46 void testValueDouble_data();
47 void testSetDoublePrecision();
48 void testValueFloat();
49 void testValueFloat_data();
50 void testValueBoolean();
51 void testValueBoolean_data();
52 void testSpecialNumbers();
53 void testSpecialNumbers_data();
54 void testIndentation();
55 void testIndentation_data();
56 void testSerializetoQIODevice();
57 void testSerializeWithoutOkParam();
58 void testEscapeChars();
59 void testEscapeChars_data();
60
61 private:
62 void valueTest( const QVariant& value, const QString& expectedRegExp, bool errorExpected = false );
63 void valueTest( const QObject* object, const QString& expectedRegExp );
64 };
65
66 Q_DECLARE_METATYPE(QVariant)
67
68 using namespace QJson;
69
testReadWriteEmptyDocument()70 void TestSerializer::testReadWriteEmptyDocument()
71 {
72 QByteArray json = "";
73 Parser parser;
74 bool ok;
75 QVariant result = parser.parse( json, &ok );
76 QVERIFY(!ok);
77 QVERIFY( ! result.isValid() );
78 Serializer serializer;
79 const QByteArray serialized = serializer.serialize( result, &ok);
80 QVERIFY( ok );
81 QByteArray expected = "null";
82 QCOMPARE(expected, serialized);
83 }
84
testReadWrite()85 void TestSerializer::testReadWrite()
86 {
87 QFETCH( QByteArray, json );
88 Parser parser;
89 bool ok;
90 QVariant result = parser.parse( json, &ok );
91 QVERIFY(ok);
92 Serializer serializer;
93 const QByteArray serialized = serializer.serialize( result, &ok);
94 QVERIFY(ok);
95 QVariant writtenThenRead = parser.parse( serialized, &ok );
96 QVERIFY(ok);
97 QCOMPARE( result, writtenThenRead );
98 }
99
testReadWrite_data()100 void TestSerializer::testReadWrite_data()
101 {
102 QTest::addColumn<QByteArray>( "json" );
103
104 // array tests
105 QTest::newRow( "empty array" ) << QByteArray("[]");
106 QTest::newRow( "basic array" ) << QByteArray("[\"person\",\"bar\"]");
107 QTest::newRow( "single int array" ) << QByteArray("[6]");
108 QTest::newRow( "int array" ) << QByteArray("[6,5,6,7]");
109 const QByteArray json = "[1,2.4, -100, -3.4, -5e+0, 2e0,3e+0,4.3E0,5.4E-0]";
110 QTest::newRow( QByteArray("array of various numbers") ) << json;
111
112 // document tests
113 QTest::newRow( "empty object" ) << QByteArray("{}");
114 QTest::newRow( "basic document" ) << QByteArray("{\"person\":\"bar\"}");
115 QTest::newRow( "object with ints" ) << QByteArray("{\"person\":6}");
116 const QByteArray json2 = "{ \"person\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
117 QTest::newRow( "complicated document" ) << json2;
118
119 // more complex cases
120 const QByteArray json3 = "[ {\"person\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
121 QTest::newRow( "complicated array" ) << json3;
122 }
123
testIndentation()124 void TestSerializer::testIndentation()
125 {
126 QFETCH( QByteArray, json );
127 QFETCH( QByteArray, expected_compact );
128 QFETCH( QByteArray, expected_min );
129 QFETCH( QByteArray, expected_med );
130 QFETCH( QByteArray, expected_full );
131
132 // parse
133 Parser parser;
134 bool ok;
135 QVariant parsed = parser.parse( json, &ok );
136 QVERIFY(ok);
137
138 Serializer serializer;
139 QVariant reparsed;
140 QByteArray serialized;
141
142 // serialize with indent compact and reparse
143 serializer.setIndentMode(QJson::IndentCompact);
144 serialized = serializer.serialize( parsed, &ok);
145 QVERIFY(ok);
146 QCOMPARE( serialized, expected_compact);
147 reparsed = parser.parse( serialized, &ok);
148 QVERIFY(ok);
149 QCOMPARE( parsed, reparsed);
150
151 // serialize with indent minimum and reparse
152 serializer.setIndentMode(QJson::IndentMinimum);
153 serialized = serializer.serialize( parsed, &ok);
154 QVERIFY(ok);
155 QCOMPARE( serialized, expected_min);
156 reparsed = parser.parse( serialized, &ok);
157 QVERIFY(ok);
158 QCOMPARE( parsed, reparsed);
159
160 // serialize with indent medium and reparse
161 serializer.setIndentMode(QJson::IndentMedium);
162 serialized = serializer.serialize( parsed, &ok);
163 QVERIFY(ok);
164 QCOMPARE( serialized, expected_med);
165 reparsed = parser.parse( serialized, &ok );
166 QVERIFY(ok);
167 QCOMPARE( parsed, reparsed);
168
169 // serialize with indent full and reparse
170 serializer.setIndentMode(QJson::IndentFull);
171 serialized = serializer.serialize( parsed, &ok);
172 QVERIFY(ok);
173 QCOMPARE( serialized, expected_full);
174 reparsed = parser.parse( serialized, &ok );
175 QVERIFY(ok);
176 QCOMPARE( parsed, reparsed);
177 }
178
testIndentation_data()179 void TestSerializer::testIndentation_data()
180 {
181 QTest::addColumn<QByteArray>( "json" );
182 QTest::addColumn<QByteArray>( "expected_compact" );
183 QTest::addColumn<QByteArray>( "expected_min" );
184 QTest::addColumn<QByteArray>( "expected_med" );
185 QTest::addColumn<QByteArray>( "expected_full" );
186 const QByteArray json = " { \"foo\" : 0, \"foo1\" : 1, \"foo2\" : [ { \"bar\" : 1, \"foo\" : 0, \"foobar\" : 0 }, { \"bar\" : 1, \"foo\" : 1, \"foobar\" : 1 } ], \"foo3\" : [ 1, 2, 3, 4, 5, 6 ], \"foobaz\" : [ \"one\", \"two\", \"three\", \"four\" ] }";
187 const QByteArray ex_compact =
188 "{\"foo\":0,\"foo1\":1,\"foo2\":[{\"bar\":1,\"foo\":0,\"foobar\":0},{\"bar\":1,\"foo\":1,\"foobar\":1}],\"foo3\":[1,2,3,4,5,6],\"foobaz\":[\"one\",\"two\",\"three\",\"four\"]}";
189
190 const QByteArray ex_min =
191 "{ \"foo\" : 0, \"foo1\" : 1, \"foo2\" : [\n"
192 " { \"bar\" : 1, \"foo\" : 0, \"foobar\" : 0 },\n"
193 " { \"bar\" : 1, \"foo\" : 1, \"foobar\" : 1 }\n"
194 " ], \"foo3\" : [\n"
195 " 1,\n"
196 " 2,\n"
197 " 3,\n"
198 " 4,\n"
199 " 5,\n"
200 " 6\n"
201 " ], \"foobaz\" : [\n"
202 " \"one\",\n"
203 " \"two\",\n"
204 " \"three\",\n"
205 " \"four\"\n"
206 " ] }";
207
208 const QByteArray ex_med =
209 "{\n"
210 " \"foo\" : 0, \"foo1\" : 1, \"foo2\" : [\n"
211 " {\n"
212 " \"bar\" : 1, \"foo\" : 0, \"foobar\" : 0\n"
213 " },\n"
214 " {\n"
215 " \"bar\" : 1, \"foo\" : 1, \"foobar\" : 1\n"
216 " }\n"
217 " ], \"foo3\" : [\n"
218 " 1,\n"
219 " 2,\n"
220 " 3,\n"
221 " 4,\n"
222 " 5,\n"
223 " 6\n"
224 " ], \"foobaz\" : [\n"
225 " \"one\",\n"
226 " \"two\",\n"
227 " \"three\",\n"
228 " \"four\"\n"
229 " ]\n}";
230
231 const QByteArray ex_full =
232 "{\n"
233 " \"foo\" : 0,\n"
234 " \"foo1\" : 1,\n"
235 " \"foo2\" : [\n"
236 " {\n"
237 " \"bar\" : 1,\n"
238 " \"foo\" : 0,\n"
239 " \"foobar\" : 0\n"
240 " },\n"
241 " {\n"
242 " \"bar\" : 1,\n"
243 " \"foo\" : 1,\n"
244 " \"foobar\" : 1\n"
245 " }\n"
246 " ],\n"
247 " \"foo3\" : [\n"
248 " 1,\n"
249 " 2,\n"
250 " 3,\n"
251 " 4,\n"
252 " 5,\n"
253 " 6\n"
254 " ],\n"
255 " \"foobaz\" : [\n"
256 " \"one\",\n"
257 " \"two\",\n"
258 " \"three\",\n"
259 " \"four\"\n"
260 " ]\n"
261 "}";
262
263 QTest::newRow( "test indents" ) << json << ex_compact << ex_min << ex_med << ex_full;
264 }
265
valueTest(const QVariant & value,const QString & expectedRegExp,bool errorExpected)266 void TestSerializer::valueTest( const QVariant& value, const QString& expectedRegExp, bool errorExpected )
267 {
268 Serializer serializer;
269 bool ok;
270 const QByteArray serialized = serializer.serialize( value, &ok);
271 QCOMPARE(ok, !errorExpected);
272 QCOMPARE(serialized.isNull(), errorExpected);
273 const QString serializedUnicode = QString::fromUtf8( serialized );
274 if (!errorExpected) {
275 QRegExp expected( expectedRegExp );
276 QVERIFY( expected.isValid() );
277 QVERIFY2( expected.exactMatch( serializedUnicode ),
278 qPrintable( QString( QLatin1String( "Expected regexp \"%1\" but got \"%2\"." ) )
279 .arg( expectedRegExp ).arg( serializedUnicode ) ) );
280 } else {
281 QVERIFY(!serializer.errorMessage().isEmpty());
282 }
283 }
284
valueTest(const QObject * object,const QString & expectedRegExp)285 void TestSerializer::valueTest( const QObject* object, const QString& expectedRegExp )
286 {
287 Serializer serializer;
288 bool ok;
289 const QByteArray serialized = serializer.serialize( object, &ok);
290 QVERIFY(ok);
291 const QString serializedUnicode = QString::fromUtf8( serialized );
292 QRegExp expected( expectedRegExp );
293 QVERIFY( expected.isValid() );
294 QVERIFY2( expected.exactMatch( serializedUnicode ),
295 qPrintable( QString( QLatin1String( "Expected regexp \"%1\" but got \"%2\"." ) )
296 .arg( expectedRegExp ).arg( serializedUnicode ) ) );
297 }
298
testValueNull()299 void TestSerializer::testValueNull()
300 {
301 valueTest( QVariant(), QLatin1String( "\\s*null\\s*" ) );
302 QVariantMap map;
303 map[QLatin1String("value")] = QVariant();
304 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:\\s*null\\s*\\}\\s*" ) );
305 }
306
testValueString()307 void TestSerializer::testValueString()
308 {
309 QFETCH( QVariant, value );
310 QFETCH( QString, expected );
311 valueTest( value, expected );
312
313 QVariantMap map;
314 map[QLatin1String("value")] = value;
315 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ) );
316 }
317
testValueString_data()318 void TestSerializer::testValueString_data()
319 {
320 QTest::addColumn<QVariant>( "value" );
321 QTest::addColumn<QString>( "expected" );
322 QTest::newRow( "null string" ) << QVariant( QString() ) << QString( QLatin1String( "\\s*\"\"\\s*" ) );
323 QTest::newRow( "empty string" ) << QVariant( QString( QLatin1String( "" ) ) ) << QString( QLatin1String( "\\s*\"\"\\s*" ) );
324 QTest::newRow( "Simple String" ) << QVariant( QString( QLatin1String( "simpleString" ) ) ) << QString( QLatin1String( "\\s*\"simpleString\"\\s*" ) );
325 QTest::newRow( "string with tab" ) << QVariant( QString( QLatin1String( "string\tstring" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\tstring\"\\s*" ) );
326 QTest::newRow( "string with newline" ) << QVariant( QString( QLatin1String( "string\nstring" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\nstring\"\\s*" ) );
327 QTest::newRow( "string with bell" ) << QVariant( QString( QLatin1String( "string\bstring" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\bstring\"\\s*" ) );
328 QTest::newRow( "string with return" ) << QVariant( QString( QLatin1String( "string\rstring" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\rstring\"\\s*" ) );
329 QTest::newRow( "string with double quote" ) << QVariant( QString( QLatin1String( "string\"string" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\\"string\"\\s*" ) );
330 QTest::newRow( "string with backslash" ) << QVariant( QString( QLatin1String( "string\\string" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\\\\\string\"\\s*" ) );
331 QString testStringWithUnicode = QString( QLatin1String( "string" ) ) + QChar( 0x2665 ) + QLatin1String( "string" );
332 QString testEscapedString = QString( QLatin1String( "string" ) ) + QLatin1String("\\\\u2665") + QLatin1String( "string" );
333 QTest::newRow( "string with unicode" ) << QVariant( testStringWithUnicode ) << QString( QLatin1String( "\\s*\"" ) + testEscapedString + QLatin1String( "\"\\s*" ) );
334 }
335
testValueStringList()336 void TestSerializer::testValueStringList()
337 {
338 QFETCH( QVariant, value );
339 QFETCH( QString, expected );
340 valueTest( value, expected );
341
342 QVariantMap map;
343 map[QLatin1String("value")] = value;
344 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ) );
345 }
346
testValueStringList_data()347 void TestSerializer::testValueStringList_data()
348 {
349 QTest::addColumn<QVariant>( "value" );
350 QTest::addColumn<QString>( "expected" );
351
352 QStringList stringlist;
353 QString expected;
354
355 // simple QStringList
356 stringlist << QLatin1String("hello") << QLatin1String("world");
357 expected = QLatin1String( "\\s*\\[\\s*\"hello\"\\s*,\\s*\"world\"\\s*\\]\\s*" );
358 QTest::newRow( "simple QStringList" ) << QVariant( stringlist) << expected;
359 }
360
testValueInteger()361 void TestSerializer::testValueInteger()
362 {
363 QFETCH( QVariant, value );
364 QFETCH( QString, expected );
365 valueTest( value, expected );
366
367 QVariantMap map;
368 map[QLatin1String("value")] = value;
369 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ) );
370 }
371
testValueInteger_data()372 void TestSerializer::testValueInteger_data()
373 {
374 QTest::addColumn<QVariant>( "value" );
375 QTest::addColumn<QString>( "expected" );
376
377 QTest::newRow( "int 0" ) << QVariant( static_cast<int>( 0 ) ) << QString( QLatin1String( "\\s*0\\s*" ) );
378 QTest::newRow( "uint 0" ) << QVariant( static_cast<uint>( 0 ) ) << QString( QLatin1String( "\\s*0\\s*" ) );
379 QTest::newRow( "int -1" ) << QVariant( static_cast<int>( -1 ) ) << QString( QLatin1String( "\\s*-1\\s*" ) );
380 QTest::newRow( "int 2133149800" ) << QVariant( static_cast<int>(2133149800) ) << QString( QLatin1String( "\\s*2133149800\\s*" ) );
381 QTest::newRow( "uint 4133149800" ) << QVariant( static_cast<uint>(4133149800u) ) << QString( QLatin1String( "\\s*4133149800\\s*" ) );
382 QTest::newRow( "uint64 932838457459459" ) << QVariant( Q_UINT64_C(932838457459459) ) << QString( QLatin1String( "\\s*932838457459459\\s*" ) );
383 QTest::newRow( "max unsigned long long" ) << QVariant( std::numeric_limits<unsigned long long>::max() ) << QString( QLatin1String( "\\s*%1\\s*" ) ).arg(std::numeric_limits<unsigned long long>::max());
384 }
385
testValueDouble()386 void TestSerializer::testValueDouble()
387 {
388 QFETCH( QVariant, value );
389 QFETCH( QString, expected );
390 QFETCH( bool, errorExpected );
391 valueTest( value, expected, errorExpected );
392
393 QVariantMap map;
394 map[QLatin1String("value")] = value;
395 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ), errorExpected );
396 }
397
testValueDouble_data()398 void TestSerializer::testValueDouble_data()
399 {
400 QTest::addColumn<QVariant>( "value" );
401 QTest::addColumn<QString>( "expected" );
402 QTest::addColumn<bool>( "errorExpected" );
403
404 QTest::newRow( "double 0" ) << QVariant( 0.0 ) << QString( QLatin1String( "\\s*0.0\\s*" ) ) << false;
405 QTest::newRow( "double -1" ) << QVariant( -1.0 ) << QString( QLatin1String( "\\s*-1.0\\s*" ) ) << false;
406 QTest::newRow( "double 1.5E-20" ) << QVariant( 1.5e-20 ) << QString( QLatin1String( "\\s*1.5[Ee]-20\\s*" ) ) << false;
407 QTest::newRow( "double -1.5E-20" ) << QVariant( -1.5e-20 ) << QString( QLatin1String( "\\s*-1.5[Ee]-20\\s*" ) ) << false;
408 QTest::newRow( "double 2.0E-20" ) << QVariant( 2.0e-20 ) << QString( QLatin1String( "\\s*2(?:.0)?[Ee]-20\\s*" ) ) << false;
409 QTest::newRow( "double infinity" ) << QVariant( std::numeric_limits< double >::infinity() ) << QString( ) << true;
410 QTest::newRow( "double -infinity" ) << QVariant( -std::numeric_limits< double >::infinity() ) << QString( ) << true;
411 QTest::newRow( "double NaN" ) << QVariant( std::numeric_limits< double >::quiet_NaN() ) << QString( ) << true;
412 }
413
testSetDoublePrecision()414 void TestSerializer::testSetDoublePrecision()
415 {
416 bool ok;
417 Serializer serializer;
418 QByteArray actual;
419 QString expected, actualUnicode;
420
421 double num = 0.12345678;
422
423 // Set 1 as double precision
424 serializer.setDoublePrecision(1);
425 expected = QString(QLatin1String("0.1"));
426 actual = serializer.serialize( QVariant(num), &ok);
427 QVERIFY(ok);
428 actualUnicode = QString::fromUtf8(actual);
429
430 QVERIFY2( QString::compare(expected, actualUnicode ) == 0,
431 qPrintable( QString( QLatin1String( "Expected \"%1\" but got \"%2\"." ) )
432 .arg( expected ).arg( actualUnicode ) ) );
433
434 // Set 2 as double precision
435 serializer.setDoublePrecision(2);
436 expected = QString(QLatin1String("0.12"));
437 actual = serializer.serialize( QVariant(num), &ok);
438 QVERIFY(ok);
439 actualUnicode = QString::fromUtf8(actual);
440
441 QVERIFY2( QString::compare(expected, actualUnicode ) == 0,
442 qPrintable( QString( QLatin1String( "Expected \"%1\" but got \"%2\"." ) )
443 .arg( expected ).arg( actualUnicode ) ) );
444
445 // Set 4 as double precision
446 serializer.setDoublePrecision(4);
447 expected = QString(QLatin1String("0.1235"));
448 actual = serializer.serialize( QVariant(num), &ok);
449 QVERIFY(ok);
450 actualUnicode = QString::fromUtf8(actual);
451
452 QVERIFY2( QString::compare(expected, actualUnicode ) == 0,
453 qPrintable( QString( QLatin1String( "Expected \"%1\" but got \"%2\"." ) )
454 .arg( expected ).arg( actualUnicode ) ) );
455
456 // Set 14 as double precision
457 serializer.setDoublePrecision(14);
458 expected = QString(QLatin1String("0.12345678"));
459 actual = serializer.serialize( QVariant(num), &ok);
460 QVERIFY(ok);
461 actualUnicode = QString::fromUtf8(actual);
462
463 QVERIFY2( QString::compare(expected, actualUnicode ) == 0,
464 qPrintable( QString( QLatin1String( "Expected \"%1\" but got \"%2\"." ) )
465 .arg( expected ).arg( actualUnicode ) ) );
466 }
467
testValueFloat()468 void TestSerializer::testValueFloat()
469 {
470 QFETCH( QVariant, value );
471 QFETCH( QString, expected );
472 QFETCH( bool, errorExpected );
473 valueTest( value, expected, errorExpected );
474
475 QVariantMap map;
476 map[QLatin1String("value")] = value;
477 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ), errorExpected );
478 }
479
testValueFloat_data()480 void TestSerializer::testValueFloat_data()
481 {
482 QVariant v;
483 float value;
484
485 QTest::addColumn<QVariant>( "value" );
486 QTest::addColumn<QString>( "expected" );
487 QTest::addColumn<bool>( "errorExpected" );
488
489 value = 0;
490 v.setValue(value);
491 QTest::newRow( "float 0" ) << v << QString( QLatin1String( "\\s*0.0\\s*" ) ) << false;
492
493 value = -1;
494 v.setValue(value);
495 QTest::newRow( "float -1" ) << v << QString( QLatin1String( "\\s*-1.0\\s*" ) ) << false;
496
497 value = 1.12f;
498 v.setValue(value);
499 QTest::newRow( "float 1.12" ) << v << QString( QLatin1String( "\\s*1.12\\s*" ) ) << false;
500 }
501
testValueBoolean()502 void TestSerializer::testValueBoolean()
503 {
504 QFETCH( QVariant, value );
505 QFETCH( QString, expected );
506 valueTest( value, expected );
507
508 QVariantMap map;
509 map[QLatin1String("value")] = value;
510 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ) );
511 }
512
testValueBoolean_data()513 void TestSerializer::testValueBoolean_data()
514 {
515 QTest::addColumn<QVariant>( "value" );
516 QTest::addColumn<QString>( "expected" );
517
518 QTest::newRow( "bool false" ) << QVariant( false ) << QString( QLatin1String( "\\s*false\\s*" ) );
519 QTest::newRow( "bool true" ) << QVariant( true ) << QString( QLatin1String( "\\s*true\\s*" ) );
520 }
521
testSpecialNumbers()522 void TestSerializer::testSpecialNumbers() {
523 bool ok;
524 QFETCH( QVariant, value );
525 QFETCH( QString, expected );
526 Serializer specialSerializer;
527 QVERIFY(!specialSerializer.specialNumbersAllowed());
528 specialSerializer.allowSpecialNumbers(true);
529 QVERIFY(specialSerializer.specialNumbersAllowed());
530 QByteArray serialized = specialSerializer.serialize(value, &ok);
531 QVERIFY(ok);
532 QCOMPARE(QString::fromLocal8Bit(serialized), expected);
533 }
534
testSpecialNumbers_data()535 void TestSerializer::testSpecialNumbers_data() {
536 QTest::addColumn<QVariant>( "value" );
537 QTest::addColumn<QString>( "expected" );
538
539 QTest::newRow( "Infinity" ) << QVariant( std::numeric_limits< double >::infinity() ) << QString::fromLocal8Bit("Infinity");
540 QTest::newRow( "-Infinity" ) << QVariant( -std::numeric_limits< double >::infinity() ) << QString::fromLocal8Bit("-Infinity");
541 QTest::newRow( "Infinity" ) << QVariant( std::numeric_limits< double >::quiet_NaN() ) << QString::fromLocal8Bit("NaN");
542 }
543
testSerializetoQIODevice()544 void TestSerializer::testSerializetoQIODevice() {
545 QBuffer buffer;
546 QVariantList variant;
547 variant << QVariant(QLatin1String("Hello"));
548 variant << QVariant(QLatin1String("world!"));
549
550 Serializer serializer;
551 bool ok;
552
553 serializer.serialize(variant, &buffer, &ok);
554
555 QCOMPARE(QString(QLatin1String(buffer.data())),
556 QString(QLatin1String("[ \"Hello\", \"world!\" ]")));
557 QVERIFY(ok);
558 }
559
testSerializeWithoutOkParam()560 void TestSerializer::testSerializeWithoutOkParam() {
561 QBuffer buffer;
562 QVariantList variant;
563 variant << QVariant(QLatin1String("Hello"));
564 variant << QVariant(QLatin1String("world!"));
565
566 Serializer serializer;
567
568 const QByteArray serialized = serializer.serialize(variant);
569 const QByteArray expected = "[ \"Hello\", \"world!\" ]";
570 QCOMPARE(expected, serialized);
571
572
573 // test a serialization which produces an error
574 QVariant brokenVariant ( std::numeric_limits< double >::quiet_NaN() );
575 QVERIFY(serializer.serialize(brokenVariant).isEmpty());
576 }
577
testValueHashMap()578 void TestSerializer::testValueHashMap()
579 {
580 Serializer serializer;
581 bool ok;
582
583 QVariantHash hash;
584 hash[QLatin1String("one")] = 1;
585 hash[QLatin1String("three")] = 3;
586 hash[QLatin1String("seven")] = 7;
587
588 QByteArray json = serializer.serialize(hash, &ok);
589 QVERIFY(ok);
590
591 Parser parser;
592 QVariant var = parser.parse(json, &ok);
593 QVERIFY(ok);
594
595 QVariantMap vmap = var.toMap();
596 QHashIterator<QString, QVariant> hIt( hash );
597 while ( hIt.hasNext() ) {
598 hIt.next();
599 QString key = hIt.key();
600 QVariant value = hIt.value();
601
602 QMap<QString, QVariant>::const_iterator mIt = vmap.constFind(key);
603 QVERIFY(mIt != vmap.constEnd());
604 QCOMPARE(mIt.value(), value);
605 }
606
607 }
608
testEscapeChars()609 void TestSerializer::testEscapeChars()
610 {
611 QFETCH(QString, input);
612 QFETCH(QString, escaped);
613
614 Serializer serializer;
615 bool ok;
616
617 QVariantHash hash;
618 hash.insert(QLatin1String("key"), input);
619 QByteArray json = serializer.serialize(hash, &ok);
620 QVERIFY(ok);
621
622 QString expected = QString(QLatin1String("{ \"key\" : \"%1\" }")).arg(escaped);
623 QString actual = QString::fromUtf8(json.data(), json.length());
624 QCOMPARE(actual, expected);
625 }
626
testEscapeChars_data()627 void TestSerializer::testEscapeChars_data()
628 {
629 QTest::addColumn<QString>("input");
630 QTest::addColumn<QString>("escaped");
631
632 QTest::newRow("simple ASCII string") << "input" << "input";
633 QTest::newRow("ASCII new lines and tabs") << "line1\nline2\rline\t3" << "line1\\nline2\\rline\\t3";
634 QTest::newRow("backspace, backslash and quotes") << "one\\two\bthree\"four" << "one\\\\two\\bthree\\\"four";
635
636 QChar unicodeSnowman(0x2603);
637 QTest::newRow("non-ASCII unicode char") << QString(unicodeSnowman) << "\\u2603";
638
639 QTest::newRow("control chars") << QString(QChar(0x06)) << "\\u0006";
640 }
641
642 #if QT_VERSION < QT_VERSION_CHECK(5,0,0)
643 // using Qt4 rather then Qt5
644 QTEST_MAIN(TestSerializer)
645 #include "moc_testserializer.cxx"
646 #else
647 QTEST_GUILESS_MAIN(TestSerializer)
648 #include "testserializer.moc"
649 #endif
650