1 /* This file is part of QJson
3 * Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
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 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library 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.
21 #include <QtTest/QtTest>
24 #include "serializer.h"
26 #include <QtCore/QVariant>
29 class TestParser: public QObject
33 void parseNonAsciiString();
34 void parseSimpleObject();
35 void parseEmptyObject();
36 void parseEmptyValue();
38 void parseMultipleObject();
40 void parseSimpleArray();
41 void parseInvalidObject();
42 void parseInvalidObject_data();
43 void parseMultipleArray();
45 void testTrueFalseNullValues();
46 void testEscapeChars();
48 void testNumbers_data();
49 void testTopLevelValues();
50 void testTopLevelValues_data();
51 void testSpecialNumbers();
52 void testSpecialNumbers_data();
54 void testReadWrite_data();
57 Q_DECLARE_METATYPE(QVariant)
58 Q_DECLARE_METATYPE(QVariant::Type)
60 using namespace QJson;
62 void TestParser::parseSimpleObject() {
63 QByteArray json = "{\"foo\":\"bar\"}";
65 map.insert (QLatin1String("foo"), QLatin1String("bar"));
66 QVariant expected(map);
70 QVariant result = parser.parse (json, &ok);
72 QCOMPARE(result, expected);
75 void TestParser::parseEmptyObject() {
76 QByteArray json = "{}";
78 QVariant expected (map);
82 QVariant result = parser.parse (json, &ok);
84 QCOMPARE(result, expected);
87 void TestParser::parseEmptyValue() {
88 QByteArray json = "{\"value\": \"\"}";
91 map.insert (QLatin1String("value"), QString(QLatin1String("")));
92 QVariant expected (map);
96 QVariant result = parser.parse (json, &ok);
98 QCOMPARE(result, expected);
99 QVERIFY (result.toMap().value(QLatin1String("value")).type() == QVariant::String);
101 QString value = result.toMap().value(QLatin1String("value")).toString();
102 QVERIFY (value.isEmpty());
105 void TestParser::parseInvalidObject() {
106 QFETCH(QByteArray, json);
110 QVariant result = parser.parse (json, &ok);
114 void TestParser::parseInvalidObject_data() {
115 QTest::addColumn<QByteArray>("json");
117 QTest::newRow("unclosed object") << QByteArray("{\"foo\":\"bar\"");
118 QTest::newRow("infinum (disallow") << QByteArray("Infinum");
119 QTest::newRow("Nan (disallow") << QByteArray("NaN");
123 void TestParser::parseNonAsciiString() {
124 QByteArray json = "{\"artist\":\"Queensr\\u00ffche\"}";
127 QChar unicode_char (0x00ff);
128 QString unicode_string;
129 unicode_string.setUnicode(&unicode_char, 1);
130 unicode_string = QLatin1String("Queensr") + unicode_string + QLatin1String("che");
132 map.insert (QLatin1String("artist"), unicode_string);
133 QVariant expected (map);
137 QVariant result = parser.parse (json, &ok);
139 QCOMPARE(result, expected);
142 void TestParser::parseMultipleObject() {
143 //put also some extra spaces inside the json string
144 QByteArray json = "{ \"foo\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
146 map.insert (QLatin1String("foo"), QLatin1String("bar"));
147 map.insert (QLatin1String("number"), 51.3);
149 list.append (QLatin1String("item1"));
150 list.append (QLatin1String("123"));
151 map.insert (QLatin1String("array"), list);
152 QVariant expected (map);
156 QVariant result = parser.parse (json, &ok);
158 QCOMPARE(result, expected);
159 QVERIFY (result.toMap().value(QLatin1String("number")).canConvert<float>());
160 QVERIFY (result.toMap().value(QLatin1String("array")).canConvert<QVariantList>());
163 void TestParser::parseUrl(){
164 //"http:\/\/www.last.fm\/venue\/8926427"
165 QByteArray json = "[\"http:\\/\\/www.last.fm\\/venue\\/8926427\"]";
167 list.append (QVariant(QLatin1String("http://www.last.fm/venue/8926427")));
168 QVariant expected (list);
172 QVariant result = parser.parse (json, &ok);
174 QCOMPARE(result, expected);
177 void TestParser::parseSimpleArray() {
178 QByteArray json = "[\"foo\",\"bar\"]";
180 list.append (QLatin1String("foo"));
181 list.append (QLatin1String("bar"));
182 QVariant expected (list);
186 QVariant result = parser.parse (json, &ok);
188 QCOMPARE(result, expected);
191 void TestParser::parseMultipleArray() {
192 //put also some extra spaces inside the json string
193 QByteArray json = "[ {\"foo\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
195 map.insert (QLatin1String("foo"), QLatin1String("bar"));
198 array.append (QLatin1String("item1"));
203 list.append (QLatin1String("number"));
204 list.append (QLatin1String("51.3"));
205 list.append ((QVariant) array);
207 QVariant expected (list);
211 QVariant result = parser.parse (json, &ok);
213 QCOMPARE(result, expected);
216 void TestParser::testTrueFalseNullValues() {
217 QByteArray json = "[true,false, null, {\"foo\" : true}]";
219 list.append (QVariant(true));
220 list.append (QVariant(false));
221 list.append (QVariant());
223 map.insert (QLatin1String("foo"), true);
225 QVariant expected (list);
229 QVariant result = parser.parse (json, &ok);
231 QCOMPARE(result, expected);
232 QCOMPARE (result.toList().at(0).toBool(), true);
233 QCOMPARE (result.toList().at(1).toBool(), false);
234 QVERIFY (result.toList().at(2).isNull());
237 void TestParser::testEscapeChars() {
238 QByteArray json = "[\"\\b \\f \\n \\r \\t \", \" \\\\ \\/ \\\\\", \"http:\\/\\/foo.com\"]";
241 list.append (QLatin1String("\b \f \n \r \t "));
242 list.append (QLatin1String(" \\ / \\"));
243 list.append (QLatin1String("http://foo.com"));
245 QVariant expected (list);
249 QVariant result = parser.parse (json, &ok);
251 QCOMPARE(result.toList().size(), expected.toList().size() );
252 QCOMPARE(result, expected);
255 void TestParser::testNumbers() {
256 QFETCH(QByteArray, input);
257 QFETCH(QVariant, expected);
258 QFETCH(QVariant::Type, type);
262 QVariant result = parser.parse ("[" + input +"]", &ok);
265 QVariant value = result.toList().at(0);
266 QCOMPARE(value, expected);
267 QCOMPARE( value.type(), type);
270 void TestParser::testNumbers_data() {
271 QTest::addColumn<QByteArray>( "input" );
272 QTest::addColumn<QVariant>( "expected" );
273 QTest::addColumn<QVariant::Type>( "type" );
279 input = QByteArray("1");
280 output = QVariant(QVariant::ULongLong);
283 QTest::newRow("simple ulonglong") << input << output << QVariant::ULongLong;
286 input = QByteArray("12345678901234567890");
287 output = QVariant(QVariant::ULongLong);
288 output.setValue(12345678901234567890ull);
290 QTest::newRow("big number") << input << output << QVariant::ULongLong;
293 input = QByteArray("2.004");
294 output = QVariant(QVariant::Double);
295 output.setValue(2.004);
297 QTest::newRow("simple double") << input << output << QVariant::Double;
300 input = QByteArray("-100");
301 output = QVariant(QVariant::LongLong);
302 output.setValue(-100);
304 QTest::newRow("negative int") << input << output << QVariant::LongLong;
307 input = QByteArray("-3.4");
308 output = QVariant(QVariant::Double);
309 output.setValue(-3.4);
311 QTest::newRow("negative double") << input << output << QVariant::Double;
314 input = QByteArray("-5e+");
315 output = QVariant(QVariant::ByteArray);
316 output.setValue(input);
318 QTest::newRow("exp1") << input << output << QVariant::ByteArray;
321 input = QByteArray("2e");
322 output = QVariant(QVariant::ByteArray);
323 output.setValue(input);
325 QTest::newRow("exp2") << input << output << QVariant::ByteArray;
328 input = QByteArray("3e+");
329 output = QVariant(QVariant::ByteArray);
330 output.setValue(input);
332 QTest::newRow("exp3") << input << output << QVariant::ByteArray;
335 input = QByteArray("4.3E");
336 output = QVariant(QVariant::ByteArray);
337 output.setValue(input);
339 QTest::newRow("exp4") << input << output << QVariant::ByteArray;
342 input = QByteArray("5.4E-");
343 output = QVariant(QVariant::ByteArray);
344 output.setValue(input);
346 QTest::newRow("exp5") << input << output << QVariant::ByteArray;
349 void TestParser::testTopLevelValues() {
350 QFETCH(QByteArray, input);
351 QFETCH(QVariant, expected);
352 QFETCH(QVariant::Type, type);
356 QVariant result = parser.parse (input, &ok);
359 QCOMPARE(result, expected);
360 QCOMPARE(result.type(), type);
363 void TestParser::testTopLevelValues_data() {
364 QTest::addColumn<QByteArray>( "input" );
365 QTest::addColumn<QVariant>( "expected" );
366 QTest::addColumn<QVariant::Type>( "type" );
372 input = QByteArray("\"foo bar\"");
373 output = QVariant(QLatin1String("foo bar"));
374 QTest::newRow("string") << input << output << QVariant::String;
377 input = QByteArray("2.4");
378 output = QVariant(QVariant::Double);
379 output.setValue(2.4);
380 QTest::newRow("simple double") << input << output << QVariant::Double;
383 input = QByteArray("true");
384 output = QVariant(QVariant::Bool);
385 output.setValue(true);
386 QTest::newRow("bool") << input << output << QVariant::Bool;
389 input = QByteArray("null");
391 QTest::newRow("null") << input << output << QVariant::Invalid;
394 input = QByteArray("[1,2,3]");
396 list << QVariant(1) << QVariant(2) << QVariant(3);
397 output = QVariant(QVariant::List);
398 output.setValue(list);
399 QTest::newRow("array") << input << output << QVariant::List;
402 input = QByteArray("{\"foo\" : \"bar\"}");
404 map.insert(QLatin1String("foo"), QLatin1String("bar"));
405 output = QVariant(QVariant::Map);
406 output.setValue(map);
407 QTest::newRow("object") << input << output << QVariant::Map;
410 void TestParser::testSpecialNumbers() {
411 QFETCH(QByteArray, input);
413 QFETCH(bool, isInfinity);
414 QFETCH(bool, isNegative);
418 QVERIFY(!parser.specialNumbersAllowed());
419 parser.allowSpecialNumbers(true);
420 QVERIFY(parser.specialNumbersAllowed());
422 QVariant value = parser.parse(input, &ok);
424 QVERIFY(value.type() == QVariant::Double);
426 double v = value.toDouble();
428 QCOMPARE(bool(isinf(v)), isInfinity);
430 // skip this test for MSVC, because there is no "isinf" function.
432 QCOMPARE(bool(std::isinf(v)), isInfinity);
435 QCOMPARE(v<0, isNegative);
437 QCOMPARE(bool(isnan(v)), isNan);
439 // skip this test for MSVC, because there is no "isinf" function.
441 QCOMPARE(bool(std::isnan(v)), isNan);
446 void TestParser::testSpecialNumbers_data() {
447 QTest::addColumn<QByteArray>("input");
448 QTest::addColumn<bool>("isOk");
449 QTest::addColumn<bool>("isInfinity");
450 QTest::addColumn<bool>("isNegative");
451 QTest::addColumn<bool>("isNan");
453 QTest::newRow("42.0") << QByteArray("42.0") << true << false << false << false;
454 QTest::newRow("0.0") << QByteArray("0.0") << true << false << false << false;
455 QTest::newRow("-42.0") << QByteArray("-42.0") << true << false << true << false;
456 QTest::newRow("Infinity") << QByteArray("Infinity") << true << true << false << false;
457 QTest::newRow("-Infinity") << QByteArray("-Infinity") << true << true << true << false;
458 QTest::newRow("NaN") << QByteArray("NaN") << true << false << false << true;
461 void TestParser::testReadWrite()
463 QFETCH( QVariant, variant );
464 Serializer serializer;
467 QByteArray json = serializer.serialize(variant);
468 QVERIFY(!json.isNull());
471 QVariant result = parser.parse( json, &ok );
473 QCOMPARE( result, variant );
476 void TestParser::testReadWrite_data()
478 QTest::addColumn<QVariant>( "variant" );
481 QTest::newRow( "empty array" ) << QVariant(QVariantList());
485 list << QString(QLatin1String("hello"));
487 QTest::newRow( "basic array" ) << QVariant(list);
491 map[QString(QLatin1String("Name"))] = 32;
492 QTest::newRow( "complicated array" ) << QVariant(map);
495 QTEST_MAIN(TestParser)
498 #include "testparser.moc"
500 #include "moc_testparser.cxx"