1 /* This file is part of QJson
3 * Copyright (C) 2009 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.
23 #include <QtTest/QtTest>
26 #include "serializer.h"
28 #include <QtCore/QVariant>
31 class TestSerializer: public QObject
35 void testReadWriteEmptyDocument();
37 void testReadWrite_data();
39 void testValueString();
40 void testValueString_data();
41 void testValueStringList();
42 void testValueStringList_data();
43 void testValueInteger();
44 void testValueInteger_data();
45 void testValueDouble();
46 void testValueDouble_data();
47 void testValueFloat();
48 void testValueFloat_data();
49 void testValueBoolean();
50 void testValueBoolean_data();
51 void testSpecialNumbers();
52 void testSpecialNumbers_data();
55 void valueTest( const QVariant& value, const QString& expectedRegExp, bool errorExpected = false );
56 void valueTest( const QObject* object, const QString& expectedRegExp );
59 Q_DECLARE_METATYPE(QVariant)
61 using namespace QJson;
63 void TestSerializer::testReadWriteEmptyDocument()
68 QVariant result = parser.parse( json, &ok );
70 QVERIFY( ! result.isValid() );
71 Serializer serializer;
72 const QByteArray serialized = serializer.serialize( result );
73 QVERIFY( !serialized.isNull() );
74 QByteArray expected = "null";
75 QCOMPARE(expected, serialized);
78 void TestSerializer::testReadWrite()
80 QFETCH( QByteArray, json );
83 QVariant result = parser.parse( json, &ok );
85 Serializer serializer;
86 const QByteArray serialized = serializer.serialize( result );
87 QVariant writtenThenRead = parser.parse( serialized, &ok );
89 QCOMPARE( result, writtenThenRead );
92 void TestSerializer::testReadWrite_data()
94 QTest::addColumn<QByteArray>( "json" );
97 QTest::newRow( "empty array" ) << QByteArray("[]");
98 QTest::newRow( "basic array" ) << QByteArray("[\"person\",\"bar\"]");
99 QTest::newRow( "single int array" ) << QByteArray("[6]");
100 QTest::newRow( "int array" ) << QByteArray("[6,5,6,7]");
101 const QByteArray json = "[1,2.4, -100, -3.4, -5e+, 2e,3e+,4.3E,5.4E-]";
102 QTest::newRow( QByteArray("array of various numbers") ) << json;
105 QTest::newRow( "empty object" ) << QByteArray("{}");
106 QTest::newRow( "basic document" ) << QByteArray("{\"person\":\"bar\"}");
107 QTest::newRow( "object with ints" ) << QByteArray("{\"person\":6}");
108 const QByteArray json2 = "{ \"person\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
109 QTest::newRow( "complicated document" ) << json2;
111 // more complex cases
112 const QByteArray json3 = "[ {\"person\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
113 QTest::newRow( "complicated array" ) << json3;
117 void TestSerializer::valueTest( const QVariant& value, const QString& expectedRegExp, bool errorExpected )
119 Serializer serializer;
120 const QByteArray serialized = serializer.serialize( value );
121 QCOMPARE(serialized.isNull(), errorExpected);
122 const QString serializedUnicode = QString::fromUtf8( serialized );
123 if (!errorExpected) {
124 QRegExp expected( expectedRegExp );
125 QVERIFY( expected.isValid() );
126 QVERIFY2( expected.exactMatch( serializedUnicode ),
127 qPrintable( QString( QLatin1String( "Expected regexp \"%1\" but got \"%2\"." ) )
128 .arg( expectedRegExp ).arg( serializedUnicode ) ) );
132 void TestSerializer::valueTest( const QObject* object, const QString& expectedRegExp )
134 Serializer serializer;
135 const QByteArray serialized = serializer.serialize( object );
136 const QString serializedUnicode = QString::fromUtf8( serialized );
137 QRegExp expected( expectedRegExp );
138 QVERIFY( expected.isValid() );
139 QVERIFY2( expected.exactMatch( serializedUnicode ),
140 qPrintable( QString( QLatin1String( "Expected regexp \"%1\" but got \"%2\"." ) )
141 .arg( expectedRegExp ).arg( serializedUnicode ) ) );
144 void TestSerializer::testValueNull()
146 valueTest( QVariant(), QLatin1String( "\\s*null\\s*" ) );
148 map[QLatin1String("value")] = QVariant();
149 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:\\s*null\\s*\\}\\s*" ) );
152 void TestSerializer::testValueString()
154 QFETCH( QVariant, value );
155 QFETCH( QString, expected );
156 valueTest( value, expected );
159 map[QLatin1String("value")] = value;
160 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ) );
163 void TestSerializer::testValueString_data()
165 QTest::addColumn<QVariant>( "value" );
166 QTest::addColumn<QString>( "expected" );
167 QTest::newRow( "null string" ) << QVariant( QString() ) << QString( QLatin1String( "\\s*\"\"\\s*" ) );
168 QTest::newRow( "empty string" ) << QVariant( QString( QLatin1String( "" ) ) ) << QString( QLatin1String( "\\s*\"\"\\s*" ) );
169 QTest::newRow( "Simple String" ) << QVariant( QString( QLatin1String( "simpleString" ) ) ) << QString( QLatin1String( "\\s*\"simpleString\"\\s*" ) );
170 QTest::newRow( "string with tab" ) << QVariant( QString( QLatin1String( "string\tstring" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\tstring\"\\s*" ) );
171 QTest::newRow( "string with newline" ) << QVariant( QString( QLatin1String( "string\nstring" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\nstring\"\\s*" ) );
172 QTest::newRow( "string with bell" ) << QVariant( QString( QLatin1String( "string\bstring" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\bstring\"\\s*" ) );
173 QTest::newRow( "string with return" ) << QVariant( QString( QLatin1String( "string\rstring" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\rstring\"\\s*" ) );
174 QTest::newRow( "string with double quote" ) << QVariant( QString( QLatin1String( "string\"string" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\\"string\"\\s*" ) );
175 QTest::newRow( "string with backslash" ) << QVariant( QString( QLatin1String( "string\\string" ) ) ) << QString( QLatin1String( "\\s*\"string\\\\\\\\string\"\\s*" ) );
176 QString testStringWithUnicode = QString( QLatin1String( "string" ) ) + QChar( 0x2665 ) + QLatin1String( "string" );
177 QString testEscapedString = QString( QLatin1String( "string" ) ) + QLatin1String("\\\\u2665") + QLatin1String( "string" );
178 QTest::newRow( "string with unicode" ) << QVariant( testStringWithUnicode ) << QLatin1String( "\\s*\"" ) + testEscapedString + QLatin1String( "\"\\s*" );
181 void TestSerializer::testValueStringList()
183 QFETCH( QVariant, value );
184 QFETCH( QString, expected );
185 valueTest( value, expected );
188 map[QLatin1String("value")] = value;
189 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ) );
192 void TestSerializer::testValueStringList_data()
194 QTest::addColumn<QVariant>( "value" );
195 QTest::addColumn<QString>( "expected" );
197 QStringList stringlist;
200 // simple QStringList
201 stringlist << QLatin1String("hello") << QLatin1String("world");
202 expected = QLatin1String( "\\s*\\[\\s*\"hello\"\\s*,\\s*\"world\"\\s*\\]\\s*" );
203 QTest::newRow( "simple QStringList" ) << QVariant( stringlist) << expected;
206 void TestSerializer::testValueInteger()
208 QFETCH( QVariant, value );
209 QFETCH( QString, expected );
210 valueTest( value, expected );
213 map[QLatin1String("value")] = value;
214 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ) );
217 void TestSerializer::testValueInteger_data()
219 QTest::addColumn<QVariant>( "value" );
220 QTest::addColumn<QString>( "expected" );
222 QTest::newRow( "int 0" ) << QVariant( static_cast<int>( 0 ) ) << QString( QLatin1String( "\\s*0\\s*" ) );
223 QTest::newRow( "uint 0" ) << QVariant( static_cast<uint>( 0 ) ) << QString( QLatin1String( "\\s*0\\s*" ) );
224 QTest::newRow( "int -1" ) << QVariant( static_cast<int>( -1 ) ) << QString( QLatin1String( "\\s*-1\\s*" ) );
225 QTest::newRow( "int 2133149800" ) << QVariant( static_cast<int>(2133149800) ) << QString( QLatin1String( "\\s*2133149800\\s*" ) );
226 QTest::newRow( "uint 4133149800" ) << QVariant( static_cast<uint>(4133149800u) ) << QString( QLatin1String( "\\s*4133149800\\s*" ) );
227 QTest::newRow( "uint64 932838457459459" ) << QVariant( Q_UINT64_C(932838457459459) ) << QString( QLatin1String( "\\s*932838457459459\\s*" ) );
228 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());
231 void TestSerializer::testValueDouble()
233 QFETCH( QVariant, value );
234 QFETCH( QString, expected );
235 QFETCH( bool, errorExpected );
236 valueTest( value, expected, errorExpected );
239 map[QLatin1String("value")] = value;
240 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ), errorExpected );
243 void TestSerializer::testValueDouble_data()
245 QTest::addColumn<QVariant>( "value" );
246 QTest::addColumn<QString>( "expected" );
247 QTest::addColumn<bool>( "errorExpected" );
249 QTest::newRow( "double 0" ) << QVariant( 0.0 ) << QString( QLatin1String( "\\s*0.0\\s*" ) ) << false;
250 QTest::newRow( "double -1" ) << QVariant( -1.0 ) << QString( QLatin1String( "\\s*-1.0\\s*" ) ) << false;
251 QTest::newRow( "double 1.5E-20" ) << QVariant( 1.5e-20 ) << QString( QLatin1String( "\\s*1.5[Ee]-20\\s*" ) ) << false;
252 QTest::newRow( "double -1.5E-20" ) << QVariant( -1.5e-20 ) << QString( QLatin1String( "\\s*-1.5[Ee]-20\\s*" ) ) << false;
253 QTest::newRow( "double 2.0E-20" ) << QVariant( 2.0e-20 ) << QString( QLatin1String( "\\s*2(?:.0)?[Ee]-20\\s*" ) ) << false;
254 QTest::newRow( "double infinity" ) << QVariant( std::numeric_limits< double >::infinity() ) << QString( ) << true;
255 QTest::newRow( "double -infinity" ) << QVariant( -std::numeric_limits< double >::infinity() ) << QString( ) << true;
256 QTest::newRow( "double NaN" ) << QVariant( std::numeric_limits< double >::quiet_NaN() ) << QString( ) << true;
259 void TestSerializer::testValueFloat()
261 QFETCH( QVariant, value );
262 QFETCH( QString, expected );
263 QFETCH( bool, errorExpected );
264 valueTest( value, expected, errorExpected );
267 map[QLatin1String("value")] = value;
268 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ), errorExpected );
271 void TestSerializer::testValueFloat_data()
273 QVariant v (QMetaType::Float);
276 QTest::addColumn<QVariant>( "value" );
277 QTest::addColumn<QString>( "expected" );
278 QTest::addColumn<bool>( "errorExpected" );
282 QTest::newRow( "float 0" ) << v << QString( QLatin1String( "\\s*0.0\\s*" ) ) << false;
286 QTest::newRow( "float -1" ) << v << QString( QLatin1String( "\\s*-1.0\\s*" ) ) << false;
290 QTest::newRow( "float 1.12" ) << v << QString( QLatin1String( "\\s*1.12\\s*" ) ) << false;
293 void TestSerializer::testValueBoolean()
295 QFETCH( QVariant, value );
296 QFETCH( QString, expected );
297 valueTest( value, expected );
300 map[QLatin1String("value")] = value;
301 valueTest( QVariant(map), QLatin1String( "\\s*\\{\\s*\"value\"\\s*:" ) + expected + QLatin1String( "\\}\\s*" ) );
304 void TestSerializer::testValueBoolean_data()
306 QTest::addColumn<QVariant>( "value" );
307 QTest::addColumn<QString>( "expected" );
309 QTest::newRow( "bool false" ) << QVariant( false ) << QString( QLatin1String( "\\s*false\\s*" ) );
310 QTest::newRow( "bool true" ) << QVariant( true ) << QString( QLatin1String( "\\s*true\\s*" ) );
313 void TestSerializer::testSpecialNumbers() {
314 QFETCH( QVariant, value );
315 QFETCH( QString, expected );
316 Serializer specialSerializer;
317 QVERIFY(!specialSerializer.specialNumbersAllowed());
318 specialSerializer.allowSpecialNumbers(true);
319 QVERIFY(specialSerializer.specialNumbersAllowed());
320 QByteArray serialized = specialSerializer.serialize(value);
321 QCOMPARE(QString::fromLocal8Bit(serialized), expected);
325 void TestSerializer::testSpecialNumbers_data() {
326 QTest::addColumn<QVariant>( "value" );
327 QTest::addColumn<QString>( "expected" );
329 QTest::newRow( "Infinity" ) << QVariant( std::numeric_limits< double >::infinity() ) << QString::fromLocal8Bit("Infinity");
330 QTest::newRow( "-Infinity" ) << QVariant( -std::numeric_limits< double >::infinity() ) << QString::fromLocal8Bit("-Infinity");
331 QTest::newRow( "Infinity" ) << QVariant( std::numeric_limits< double >::quiet_NaN() ) << QString::fromLocal8Bit("NaN");
334 QTEST_MAIN(TestSerializer)
337 #include "testserializer.moc"
339 #include "moc_testserializer.cxx"