2012-01-18 09:12:50 +00:00
/****************************************************************************
* *
2016-01-15 12:36:27 +00:00
* * Copyright ( C ) 2016 The Qt Company Ltd .
* * Contact : https : //www.qt.io/licensing/
2012-01-18 09:12:50 +00:00
* *
* * This file is part of the test suite of the Qt Toolkit .
* *
2016-01-15 12:36:27 +00:00
* * $ QT_BEGIN_LICENSE : GPL - EXCEPT $
2012-09-19 12:28:29 +00:00
* * Commercial License Usage
* * Licensees holding valid commercial Qt licenses may use this file in
* * accordance with the commercial license agreement provided with the
* * Software or , alternatively , in accordance with the terms contained in
2015-01-28 08:44:43 +00:00
* * a written agreement between you and The Qt Company . For licensing terms
2016-01-15 12:36:27 +00:00
* * and conditions see https : //www.qt.io/terms-conditions. For further
* * information use the contact form at https : //www.qt.io/contact-us.
2012-09-19 12:28:29 +00:00
* *
2016-01-15 12:36:27 +00:00
* * GNU General Public License Usage
* * Alternatively , this file may be used under the terms of the GNU
* * General Public License version 3 as published by the Free Software
* * Foundation with exceptions as appearing in the file LICENSE . GPL3 - EXCEPT
* * included in the packaging of this file . Please review the following
* * information to ensure the GNU General Public License requirements will
* * be met : https : //www.gnu.org/licenses/gpl-3.0.html.
2012-01-18 09:12:50 +00:00
* *
* * $ QT_END_LICENSE $
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <QtTest>
2013-07-02 11:16:48 +00:00
2012-01-18 09:12:50 +00:00
# include "qjsonarray.h"
# include "qjsonobject.h"
# include "qjsonvalue.h"
# include "qjsondocument.h"
2013-02-10 07:18:42 +00:00
# include <limits>
2012-01-18 09:12:50 +00:00
2013-10-06 09:40:47 +00:00
# define INVALID_UNICODE "\xCE\xBA\xE1"
# define UNICODE_NON_CHARACTER "\xEF\xBF\xBF"
2012-02-22 08:26:27 +00:00
# define UNICODE_DJE "\320\202" // Character from the Serbian Cyrillic alphabet
2012-10-22 10:39:02 +00:00
class tst_QtJson : public QObject
2012-01-18 09:12:50 +00:00
{
Q_OBJECT
private Q_SLOTS :
void initTestCase ( ) ;
void testValueSimple ( ) ;
void testNumbers ( ) ;
2013-07-02 11:16:48 +00:00
void testNumbers_2 ( ) ;
void testNumbers_3 ( ) ;
2012-01-18 09:12:50 +00:00
void testObjectSimple ( ) ;
2012-01-26 10:13:41 +00:00
void testObjectSmallKeys ( ) ;
2012-01-18 09:12:50 +00:00
void testArraySimple ( ) ;
void testValueObject ( ) ;
void testValueArray ( ) ;
void testObjectNested ( ) ;
void testArrayNested ( ) ;
void testArrayNestedEmpty ( ) ;
2013-12-29 21:19:13 +00:00
void testArrayComfortOperators ( ) ;
2012-01-18 09:12:50 +00:00
void testObjectNestedEmpty ( ) ;
void testValueRef ( ) ;
void testObjectIteration ( ) ;
void testArrayIteration ( ) ;
void testObjectFind ( ) ;
void testDocument ( ) ;
void nullValues ( ) ;
void nullArrays ( ) ;
void nullObject ( ) ;
2014-05-23 11:45:27 +00:00
void constNullObject ( ) ;
2012-01-18 09:12:50 +00:00
void keySorting ( ) ;
void undefinedValues ( ) ;
2014-03-04 12:48:31 +00:00
void fromVariant ( ) ;
2012-01-18 09:12:50 +00:00
void fromVariantMap ( ) ;
2014-10-30 09:59:11 +00:00
void fromVariantHash ( ) ;
2012-01-18 09:12:50 +00:00
void toVariantMap ( ) ;
2014-10-30 09:59:11 +00:00
void toVariantHash ( ) ;
2012-01-30 13:37:36 +00:00
void toVariantList ( ) ;
2012-01-18 09:12:50 +00:00
void toJson ( ) ;
2013-02-10 07:18:42 +00:00
void toJsonSillyNumericValues ( ) ;
2013-02-10 09:02:00 +00:00
void toJsonLargeNumericValues ( ) ;
2012-01-18 09:12:50 +00:00
void fromJson ( ) ;
2012-02-17 20:38:23 +00:00
void fromJsonErrors ( ) ;
2012-01-18 09:12:50 +00:00
void fromBinary ( ) ;
void toAndFromBinary_data ( ) ;
void toAndFromBinary ( ) ;
2016-11-02 13:10:47 +00:00
void invalidBinaryData ( ) ;
2012-01-18 09:12:50 +00:00
void parseNumbers ( ) ;
void parseStrings ( ) ;
void parseDuplicateKeys ( ) ;
void testParser ( ) ;
void compactArray ( ) ;
void compactObject ( ) ;
void validation ( ) ;
void assignToDocument ( ) ;
void testDuplicateKeys ( ) ;
void testCompaction ( ) ;
void testDebugStream ( ) ;
void testCompactionError ( ) ;
2012-03-06 12:05:09 +00:00
void parseUnicodeEscapes ( ) ;
2012-03-08 09:41:55 +00:00
void assignObjects ( ) ;
void assignArrays ( ) ;
2012-03-12 18:33:39 +00:00
void testTrailingComma ( ) ;
2012-03-29 10:25:09 +00:00
void testDetachBug ( ) ;
2014-06-10 08:41:28 +00:00
void testJsonValueRefDefault ( ) ;
2012-04-05 09:35:09 +00:00
void valueEquals ( ) ;
2014-06-26 11:02:54 +00:00
void objectEquals_data ( ) ;
void objectEquals ( ) ;
2014-07-08 12:56:25 +00:00
void arrayEquals_data ( ) ;
void arrayEquals ( ) ;
2012-05-10 11:24:28 +00:00
void bom ( ) ;
2012-05-12 10:09:35 +00:00
void nesting ( ) ;
2013-05-22 07:53:39 +00:00
void longStrings ( ) ;
2014-05-21 10:28:27 +00:00
void arrayInitializerList ( ) ;
2014-05-21 14:22:49 +00:00
void objectInitializerList ( ) ;
2014-09-05 10:58:19 +00:00
void unicodeKeys ( ) ;
2014-09-05 11:26:16 +00:00
void garbageAtEnd ( ) ;
2015-03-17 15:01:05 +00:00
void removeNonLatinKey ( ) ;
2012-02-15 04:22:48 +00:00
private :
QString testDataDir ;
2012-01-18 09:12:50 +00:00
} ;
2012-10-22 10:39:02 +00:00
void tst_QtJson : : initTestCase ( )
2012-01-18 09:12:50 +00:00
{
2012-02-15 04:22:48 +00:00
testDataDir = QFileInfo ( QFINDTESTDATA ( " test.json " ) ) . absolutePath ( ) ;
if ( testDataDir . isEmpty ( ) )
testDataDir = QCoreApplication : : applicationDirPath ( ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testValueSimple ( )
2012-01-18 09:12:50 +00:00
{
2012-03-20 06:07:03 +00:00
QJsonObject object ;
object . insert ( " number " , 999. ) ;
QJsonArray array ;
for ( int i = 0 ; i < 10 ; + + i )
array . append ( ( double ) i ) ;
2012-01-18 09:12:50 +00:00
QJsonValue value ( true ) ;
QCOMPARE ( value . type ( ) , QJsonValue : : Bool ) ;
QCOMPARE ( value . toDouble ( ) , 0. ) ;
QCOMPARE ( value . toString ( ) , QString ( ) ) ;
QCOMPARE ( value . toBool ( ) , true ) ;
QCOMPARE ( value . toObject ( ) , QJsonObject ( ) ) ;
QCOMPARE ( value . toArray ( ) , QJsonArray ( ) ) ;
2012-03-20 06:07:03 +00:00
QCOMPARE ( value . toDouble ( 99. ) , 99. ) ;
QCOMPARE ( value . toString ( QString ( " test " ) ) , QString ( " test " ) ) ;
QCOMPARE ( value . toObject ( object ) , object ) ;
QCOMPARE ( value . toArray ( array ) , array ) ;
2012-01-18 09:12:50 +00:00
value = 999. ;
QCOMPARE ( value . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( value . toDouble ( ) , 999. ) ;
QCOMPARE ( value . toString ( ) , QString ( ) ) ;
QCOMPARE ( value . toBool ( ) , false ) ;
2012-03-20 06:07:03 +00:00
QCOMPARE ( value . toBool ( true ) , true ) ;
2012-01-18 09:12:50 +00:00
QCOMPARE ( value . toObject ( ) , QJsonObject ( ) ) ;
QCOMPARE ( value . toArray ( ) , QJsonArray ( ) ) ;
value = QLatin1String ( " test " ) ;
QCOMPARE ( value . toDouble ( ) , 0. ) ;
QCOMPARE ( value . toString ( ) , QLatin1String ( " test " ) ) ;
QCOMPARE ( value . toBool ( ) , false ) ;
QCOMPARE ( value . toObject ( ) , QJsonObject ( ) ) ;
QCOMPARE ( value . toArray ( ) , QJsonArray ( ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testNumbers ( )
2012-01-18 09:12:50 +00:00
{
{
int numbers [ ] = {
0 ,
- 1 ,
1 ,
( 1 < < 26 ) ,
( 1 < < 27 ) ,
( 1 < < 28 ) ,
- ( 1 < < 26 ) ,
- ( 1 < < 27 ) ,
- ( 1 < < 28 ) ,
( 1 < < 26 ) - 1 ,
( 1 < < 27 ) - 1 ,
( 1 < < 28 ) - 1 ,
- ( ( 1 < < 26 ) - 1 ) ,
- ( ( 1 < < 27 ) - 1 ) ,
- ( ( 1 < < 28 ) - 1 )
} ;
int n = sizeof ( numbers ) / sizeof ( int ) ;
QJsonArray array ;
for ( int i = 0 ; i < n ; + + i )
array . append ( ( double ) numbers [ i ] ) ;
2013-05-14 12:19:47 +00:00
QByteArray serialized = QJsonDocument ( array ) . toJson ( ) ;
QJsonDocument json = QJsonDocument : : fromJson ( serialized ) ;
QJsonArray array2 = json . array ( ) ;
QCOMPARE ( array . size ( ) , array2 . size ( ) ) ;
for ( int i = 0 ; i < array . size ( ) ; + + i ) {
QCOMPARE ( array . at ( i ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( array . at ( i ) . toDouble ( ) , ( double ) numbers [ i ] ) ;
QCOMPARE ( array2 . at ( i ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( array2 . at ( i ) . toDouble ( ) , ( double ) numbers [ i ] ) ;
}
}
{
qint64 numbers [ ] = {
0 ,
- 1 ,
1 ,
2013-06-06 08:14:26 +00:00
( 1ll < < 54 ) ,
( 1ll < < 55 ) ,
( 1ll < < 56 ) ,
- ( 1ll < < 54 ) ,
- ( 1ll < < 55 ) ,
- ( 1ll < < 56 ) ,
( 1ll < < 54 ) - 1 ,
( 1ll < < 55 ) - 1 ,
( 1ll < < 56 ) - 1 ,
- ( ( 1ll < < 54 ) - 1 ) ,
- ( ( 1ll < < 55 ) - 1 ) ,
- ( ( 1ll < < 56 ) - 1 )
2013-05-14 12:19:47 +00:00
} ;
int n = sizeof ( numbers ) / sizeof ( qint64 ) ;
QJsonArray array ;
for ( int i = 0 ; i < n ; + + i )
array . append ( ( double ) numbers [ i ] ) ;
QByteArray serialized = QJsonDocument ( array ) . toJson ( ) ;
QJsonDocument json = QJsonDocument : : fromJson ( serialized ) ;
QJsonArray array2 = json . array ( ) ;
QCOMPARE ( array . size ( ) , array2 . size ( ) ) ;
2012-01-18 09:12:50 +00:00
for ( int i = 0 ; i < array . size ( ) ; + + i ) {
QCOMPARE ( array . at ( i ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( array . at ( i ) . toDouble ( ) , ( double ) numbers [ i ] ) ;
2013-05-14 12:19:47 +00:00
QCOMPARE ( array2 . at ( i ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( array2 . at ( i ) . toDouble ( ) , ( double ) numbers [ i ] ) ;
2012-01-18 09:12:50 +00:00
}
}
{
double numbers [ ] = {
0 ,
- 1 ,
1 ,
2013-06-06 08:14:26 +00:00
double ( 1ll < < 54 ) ,
double ( 1ll < < 55 ) ,
double ( 1ll < < 56 ) ,
double ( - ( 1ll < < 54 ) ) ,
double ( - ( 1ll < < 55 ) ) ,
double ( - ( 1ll < < 56 ) ) ,
double ( ( 1ll < < 54 ) - 1 ) ,
double ( ( 1ll < < 55 ) - 1 ) ,
double ( ( 1ll < < 56 ) - 1 ) ,
double ( - ( ( 1ll < < 54 ) - 1 ) ) ,
double ( - ( ( 1ll < < 55 ) - 1 ) ) ,
double ( - ( ( 1ll < < 56 ) - 1 ) ) ,
2012-01-18 09:12:50 +00:00
1.1 ,
0.1 ,
- 0.1 ,
- 1.1 ,
1e200 ,
- 1e200
} ;
int n = sizeof ( numbers ) / sizeof ( double ) ;
QJsonArray array ;
for ( int i = 0 ; i < n ; + + i )
array . append ( numbers [ i ] ) ;
2013-05-14 12:19:47 +00:00
QByteArray serialized = QJsonDocument ( array ) . toJson ( ) ;
QJsonDocument json = QJsonDocument : : fromJson ( serialized ) ;
QJsonArray array2 = json . array ( ) ;
QCOMPARE ( array . size ( ) , array2 . size ( ) ) ;
2012-01-18 09:12:50 +00:00
for ( int i = 0 ; i < array . size ( ) ; + + i ) {
QCOMPARE ( array . at ( i ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( array . at ( i ) . toDouble ( ) , numbers [ i ] ) ;
2013-05-14 12:19:47 +00:00
QCOMPARE ( array2 . at ( i ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( array2 . at ( i ) . toDouble ( ) , numbers [ i ] ) ;
2012-01-18 09:12:50 +00:00
}
}
}
2013-07-02 11:16:48 +00:00
void tst_QtJson : : testNumbers_2 ( )
{
// test cases from TC39 test suite for ECMAScript
// http://hg.ecmascript.org/tests/test262/file/d067d2f0ca30/test/suite/ch08/8.5/8.5.1.js
// Fill an array with 2 to the power of (0 ... -1075)
double value = 1 ;
double floatValues [ 1076 ] , floatValues_1 [ 1076 ] ;
QJsonObject jObject ;
for ( int power = 0 ; power < = 1075 ; power + + ) {
floatValues [ power ] = value ;
jObject . insert ( QString : : number ( power ) , QJsonValue ( floatValues [ power ] ) ) ;
// Use basic math operations for testing, which are required to support 'gradual underflow' rather
// than Math.pow etc..., which are defined as 'implementation dependent'.
value = value * 0.5 ;
}
QJsonDocument jDocument1 ( jObject ) ;
QByteArray ba ( jDocument1 . toJson ( ) ) ;
QJsonDocument jDocument2 ( QJsonDocument : : fromJson ( ba ) ) ;
for ( int power = 0 ; power < = 1075 ; power + + ) {
floatValues_1 [ power ] = jDocument2 . object ( ) . value ( QString : : number ( power ) ) . toDouble ( ) ;
2014-03-26 12:52:09 +00:00
# ifdef Q_OS_QNX
2014-02-26 08:18:35 +00:00
if ( power > = 970 )
QEXPECT_FAIL ( " " , " See QTBUG-37066 " , Abort ) ;
# endif
2013-07-02 11:16:48 +00:00
QVERIFY2 ( floatValues [ power ] = = floatValues_1 [ power ] , QString ( " floatValues[%1] != floatValues_1[%1] " ) . arg ( power ) . toLatin1 ( ) ) ;
}
// The last value is below min denorm and should round to 0, everything else should contain a value
QVERIFY2 ( floatValues_1 [ 1075 ] = = 0 , " Value after min denorm should round to 0 " ) ;
// Validate the last actual value is min denorm
QVERIFY2 ( floatValues_1 [ 1074 ] = = 4.9406564584124654417656879286822e-324 , QString ( " Min denorm value is incorrect: %1 " ) . arg ( floatValues_1 [ 1074 ] ) . toLatin1 ( ) ) ;
// Validate that every value is half the value before it up to 1
for ( int index = 1074 ; index > 0 ; index - - ) {
QVERIFY2 ( floatValues_1 [ index ] ! = 0 , QString ( " 2**- %1 should not be 0 " ) . arg ( index ) . toLatin1 ( ) ) ;
QVERIFY2 ( floatValues_1 [ index - 1 ] = = ( floatValues_1 [ index ] * 2 ) , QString ( " Value should be double adjacent value at index %1 " ) . arg ( index ) . toLatin1 ( ) ) ;
}
}
void tst_QtJson : : testNumbers_3 ( )
{
// test case from QTBUG-31926
double d1 = 1.123451234512345 ;
double d2 = 1.123451234512346 ;
QJsonObject jObject ;
jObject . insert ( " d1 " , QJsonValue ( d1 ) ) ;
jObject . insert ( " d2 " , QJsonValue ( d2 ) ) ;
QJsonDocument jDocument1 ( jObject ) ;
QByteArray ba ( jDocument1 . toJson ( ) ) ;
QJsonDocument jDocument2 ( QJsonDocument : : fromJson ( ba ) ) ;
double d1_1 ( jDocument2 . object ( ) . value ( " d1 " ) . toDouble ( ) ) ;
double d2_1 ( jDocument2 . object ( ) . value ( " d2 " ) . toDouble ( ) ) ;
QVERIFY ( d1_1 ! = d2_1 ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testObjectSimple ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject object ;
object . insert ( " number " , 999. ) ;
QCOMPARE ( object . value ( " number " ) . type ( ) , QJsonValue : : Double ) ;
QJsonObject: add some overloads taking QLatin1String
QXmlStreamReader also has QLatin1String overloads, which
greatly benefits parsers, since the vast majority of keys
in both JSON and XML are US-ASCII. This patch adds such an
overload to the JSON parser.
The value() function is all typical parsers need, so even
though many more QJsonObject functions taking QString could
benefit from the same treatment, value() is the single most
important one for read-only JSON access.
Add some more overloads, too, for functions that don't need
more internal scaffolding than value(). Requires adding a
dummy op[](QL1S) (forwarding to the QString overload) so as
not to make
QJsonObject json;
json[QLatin1String("key")]; // mutable
ambiguous between const op[](QL1S) and mutable op[](QString).
[ChangeLog][QtCore][QJsonObject] Added value(), op[] const,
find(), constFind(), contains() overloads taking QLatin1String.
Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-04-28 07:40:49 +00:00
QCOMPARE ( object . value ( QLatin1String ( " number " ) ) . toDouble ( ) , 999. ) ;
2012-01-18 09:12:50 +00:00
object . insert ( " string " , QString : : fromLatin1 ( " test " ) ) ;
QCOMPARE ( object . value ( " string " ) . type ( ) , QJsonValue : : String ) ;
QJsonObject: add some overloads taking QLatin1String
QXmlStreamReader also has QLatin1String overloads, which
greatly benefits parsers, since the vast majority of keys
in both JSON and XML are US-ASCII. This patch adds such an
overload to the JSON parser.
The value() function is all typical parsers need, so even
though many more QJsonObject functions taking QString could
benefit from the same treatment, value() is the single most
important one for read-only JSON access.
Add some more overloads, too, for functions that don't need
more internal scaffolding than value(). Requires adding a
dummy op[](QL1S) (forwarding to the QString overload) so as
not to make
QJsonObject json;
json[QLatin1String("key")]; // mutable
ambiguous between const op[](QL1S) and mutable op[](QString).
[ChangeLog][QtCore][QJsonObject] Added value(), op[] const,
find(), constFind(), contains() overloads taking QLatin1String.
Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-04-28 07:40:49 +00:00
QCOMPARE ( object . value ( QLatin1String ( " string " ) ) . toString ( ) , QString ( " test " ) ) ;
2012-01-18 09:12:50 +00:00
object . insert ( " boolean " , true ) ;
QCOMPARE ( object . value ( " boolean " ) . toBool ( ) , true ) ;
QJsonObject: add some overloads taking QLatin1String
QXmlStreamReader also has QLatin1String overloads, which
greatly benefits parsers, since the vast majority of keys
in both JSON and XML are US-ASCII. This patch adds such an
overload to the JSON parser.
The value() function is all typical parsers need, so even
though many more QJsonObject functions taking QString could
benefit from the same treatment, value() is the single most
important one for read-only JSON access.
Add some more overloads, too, for functions that don't need
more internal scaffolding than value(). Requires adding a
dummy op[](QL1S) (forwarding to the QString overload) so as
not to make
QJsonObject json;
json[QLatin1String("key")]; // mutable
ambiguous between const op[](QL1S) and mutable op[](QString).
[ChangeLog][QtCore][QJsonObject] Added value(), op[] const,
find(), constFind(), contains() overloads taking QLatin1String.
Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-04-28 07:40:49 +00:00
QCOMPARE ( object . value ( QLatin1String ( " boolean " ) ) . toBool ( ) , true ) ;
2012-01-18 09:12:50 +00:00
QStringList keys = object . keys ( ) ;
QVERIFY2 ( keys . contains ( " number " ) , " key number not found " ) ;
QVERIFY2 ( keys . contains ( " string " ) , " key string not found " ) ;
QVERIFY2 ( keys . contains ( " boolean " ) , " key boolean not found " ) ;
2012-07-11 12:44:38 +00:00
// if we put a JsonValue into the JsonObject and retrieve
2012-01-18 09:12:50 +00:00
// it, it should be identical.
QJsonValue value ( QLatin1String ( " foo " ) ) ;
object . insert ( " value " , value ) ;
QCOMPARE ( object . value ( " value " ) , value ) ;
int size = object . size ( ) ;
object . remove ( " boolean " ) ;
QCOMPARE ( object . size ( ) , size - 1 ) ;
QVERIFY2 ( ! object . contains ( " boolean " ) , " key boolean should have been removed " ) ;
QJsonValue taken = object . take ( " value " ) ;
2012-06-04 16:48:51 +00:00
QCOMPARE ( taken , value ) ;
2012-01-18 09:12:50 +00:00
QVERIFY2 ( ! object . contains ( " value " ) , " key value should have been removed " ) ;
QString before = object . value ( " string " ) . toString ( ) ;
object . insert ( " string " , QString : : fromLatin1 ( " foo " ) ) ;
QJsonObject: add some overloads taking QLatin1String
QXmlStreamReader also has QLatin1String overloads, which
greatly benefits parsers, since the vast majority of keys
in both JSON and XML are US-ASCII. This patch adds such an
overload to the JSON parser.
The value() function is all typical parsers need, so even
though many more QJsonObject functions taking QString could
benefit from the same treatment, value() is the single most
important one for read-only JSON access.
Add some more overloads, too, for functions that don't need
more internal scaffolding than value(). Requires adding a
dummy op[](QL1S) (forwarding to the QString overload) so as
not to make
QJsonObject json;
json[QLatin1String("key")]; // mutable
ambiguous between const op[](QL1S) and mutable op[](QString).
[ChangeLog][QtCore][QJsonObject] Added value(), op[] const,
find(), constFind(), contains() overloads taking QLatin1String.
Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-04-28 07:40:49 +00:00
QVERIFY2 ( object . value ( QLatin1String ( " string " ) ) . toString ( ) ! = before , " value should have been updated " ) ;
2012-06-04 16:48:51 +00:00
size = object . size ( ) ;
QJsonObject subobject ;
subobject . insert ( " number " , 42 ) ;
subobject . insert ( QLatin1String ( " string " ) , QLatin1String ( " foobar " ) ) ;
object . insert ( " subobject " , subobject ) ;
QCOMPARE ( object . size ( ) , size + 1 ) ;
QJsonValue subvalue = object . take ( QLatin1String ( " subobject " ) ) ;
QCOMPARE ( object . size ( ) , size ) ;
QCOMPARE ( subvalue . toObject ( ) , subobject ) ;
// make object detach by modifying it many times
for ( int i = 0 ; i < 64 ; + + i )
object . insert ( QLatin1String ( " string " ) , QLatin1String ( " bar " ) ) ;
QCOMPARE ( object . size ( ) , size ) ;
QCOMPARE ( subvalue . toObject ( ) , subobject ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testObjectSmallKeys ( )
2012-01-26 10:13:41 +00:00
{
QJsonObject data1 ;
2013-08-22 14:25:13 +00:00
data1 . insert ( QStringLiteral ( " 1 " ) , 123. ) ;
2012-01-26 10:13:41 +00:00
QVERIFY ( data1 . contains ( QStringLiteral ( " 1 " ) ) ) ;
QCOMPARE ( data1 . value ( QStringLiteral ( " 1 " ) ) . toDouble ( ) , ( double ) 123 ) ;
2013-08-22 14:25:13 +00:00
data1 . insert ( QStringLiteral ( " 12 " ) , 133. ) ;
2012-01-26 10:13:41 +00:00
QCOMPARE ( data1 . value ( QStringLiteral ( " 12 " ) ) . toDouble ( ) , ( double ) 133 ) ;
QVERIFY ( data1 . contains ( QStringLiteral ( " 12 " ) ) ) ;
2013-08-22 14:25:13 +00:00
data1 . insert ( QStringLiteral ( " 123 " ) , 323. ) ;
2012-01-26 10:13:41 +00:00
QCOMPARE ( data1 . value ( QStringLiteral ( " 12 " ) ) . toDouble ( ) , ( double ) 133 ) ;
QVERIFY ( data1 . contains ( QStringLiteral ( " 123 " ) ) ) ;
QCOMPARE ( data1 . value ( QStringLiteral ( " 123 " ) ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( data1 . value ( QStringLiteral ( " 123 " ) ) . toDouble ( ) , ( double ) 323 ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testArraySimple ( )
2012-01-18 09:12:50 +00:00
{
QJsonArray array ;
array . append ( 999. ) ;
array . append ( QString : : fromLatin1 ( " test " ) ) ;
array . append ( true ) ;
QJsonValue val = array . at ( 0 ) ;
QCOMPARE ( array . at ( 0 ) . toDouble ( ) , 999. ) ;
QCOMPARE ( array . at ( 1 ) . toString ( ) , QString ( " test " ) ) ;
QCOMPARE ( array . at ( 2 ) . toBool ( ) , true ) ;
QCOMPARE ( array . size ( ) , 3 ) ;
2012-07-11 12:44:38 +00:00
// if we put a JsonValue into the JsonArray and retrieve
2012-01-18 09:12:50 +00:00
// it, it should be identical.
QJsonValue value ( QLatin1String ( " foo " ) ) ;
array . append ( value ) ;
QCOMPARE ( array . at ( 3 ) , value ) ;
int size = array . size ( ) ;
array . removeAt ( 2 ) ;
- - size ;
QCOMPARE ( array . size ( ) , size ) ;
QJsonValue taken = array . takeAt ( 0 ) ;
- - size ;
QCOMPARE ( taken . toDouble ( ) , 999. ) ;
QCOMPARE ( array . size ( ) , size ) ;
// check whether null values work
array . append ( QJsonValue ( ) ) ;
+ + size ;
QCOMPARE ( array . size ( ) , size ) ;
QCOMPARE ( array . last ( ) . type ( ) , QJsonValue : : Null ) ;
QCOMPARE ( array . last ( ) , QJsonValue ( ) ) ;
QCOMPARE ( array . first ( ) . type ( ) , QJsonValue : : String ) ;
QCOMPARE ( array . first ( ) , QJsonValue ( QLatin1String ( " test " ) ) ) ;
array . prepend ( false ) ;
QCOMPARE ( array . first ( ) . type ( ) , QJsonValue : : Bool ) ;
QCOMPARE ( array . first ( ) , QJsonValue ( false ) ) ;
QCOMPARE ( array . at ( - 1 ) , QJsonValue ( QJsonValue : : Undefined ) ) ;
QCOMPARE ( array . at ( array . size ( ) ) , QJsonValue ( QJsonValue : : Undefined ) ) ;
array . replace ( 0 , - 555. ) ;
QCOMPARE ( array . first ( ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( array . first ( ) , QJsonValue ( - 555. ) ) ;
QCOMPARE ( array . at ( 1 ) . type ( ) , QJsonValue : : String ) ;
QCOMPARE ( array . at ( 1 ) , QJsonValue ( QLatin1String ( " test " ) ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testValueObject ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject object ;
object . insert ( " number " , 999. ) ;
object . insert ( " string " , QLatin1String ( " test " ) ) ;
object . insert ( " boolean " , true ) ;
QJsonValue value ( object ) ;
// if we don't modify the original JsonObject, toObject()
// on the JsonValue should return the same object (non-detached).
QCOMPARE ( value . toObject ( ) , object ) ;
// if we modify the original object, it should detach
object . insert ( " test " , QJsonValue ( QLatin1String ( " test " ) ) ) ;
QVERIFY2 ( value . toObject ( ) ! = object , " object should have detached " ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testValueArray ( )
2012-01-18 09:12:50 +00:00
{
QJsonArray array ;
array . append ( 999. ) ;
array . append ( QLatin1String ( " test " ) ) ;
array . append ( true ) ;
QJsonValue value ( array ) ;
// if we don't modify the original JsonArray, toArray()
// on the JsonValue should return the same object (non-detached).
QCOMPARE ( value . toArray ( ) , array ) ;
// if we modify the original array, it should detach
array . append ( QLatin1String ( " test " ) ) ;
QVERIFY2 ( value . toArray ( ) ! = array , " array should have detached " ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testObjectNested ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject inner , outer ;
inner . insert ( " number " , 999. ) ;
outer . insert ( " nested " , inner ) ;
// if we don't modify the original JsonObject, value()
// should return the same object (non-detached).
QJsonObject value = outer . value ( " nested " ) . toObject ( ) ;
QCOMPARE ( value , inner ) ;
QCOMPARE ( value . value ( " number " ) . toDouble ( ) , 999. ) ;
// if we modify the original object, it should detach and not
// affect the nested object
inner . insert ( " number " , 555. ) ;
value = outer . value ( " nested " ) . toObject ( ) ;
QVERIFY2 ( inner . value ( " number " ) . toDouble ( ) ! = value . value ( " number " ) . toDouble ( ) ,
" object should have detached " ) ;
// array in object
QJsonArray array ;
array . append ( 123. ) ;
array . append ( 456. ) ;
outer . insert ( " array " , array ) ;
QCOMPARE ( outer . value ( " array " ) . toArray ( ) , array ) ;
QCOMPARE ( outer . value ( " array " ) . toArray ( ) . at ( 1 ) . toDouble ( ) , 456. ) ;
// two deep objects
QJsonObject twoDeep ;
twoDeep . insert ( " boolean " , true ) ;
inner . insert ( " nested " , twoDeep ) ;
outer . insert ( " nested " , inner ) ;
QCOMPARE ( outer . value ( " nested " ) . toObject ( ) . value ( " nested " ) . toObject ( ) , twoDeep ) ;
QCOMPARE ( outer . value ( " nested " ) . toObject ( ) . value ( " nested " ) . toObject ( ) . value ( " boolean " ) . toBool ( ) ,
true ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testArrayNested ( )
2012-01-18 09:12:50 +00:00
{
QJsonArray inner , outer ;
inner . append ( 999. ) ;
outer . append ( inner ) ;
// if we don't modify the original JsonArray, value()
// should return the same array (non-detached).
QJsonArray value = outer . at ( 0 ) . toArray ( ) ;
QCOMPARE ( value , inner ) ;
QCOMPARE ( value . at ( 0 ) . toDouble ( ) , 999. ) ;
// if we modify the original array, it should detach and not
// affect the nested array
inner . append ( 555. ) ;
value = outer . at ( 0 ) . toArray ( ) ;
QVERIFY2 ( inner . size ( ) ! = value . size ( ) , " array should have detached " ) ;
// objects in arrays
QJsonObject object ;
object . insert ( " boolean " , true ) ;
outer . append ( object ) ;
QCOMPARE ( outer . last ( ) . toObject ( ) , object ) ;
QCOMPARE ( outer . last ( ) . toObject ( ) . value ( " boolean " ) . toBool ( ) , true ) ;
// two deep arrays
QJsonArray twoDeep ;
twoDeep . append ( QJsonValue ( QString : : fromLatin1 ( " nested " ) ) ) ;
inner . append ( twoDeep ) ;
outer . append ( inner ) ;
QCOMPARE ( outer . last ( ) . toArray ( ) . last ( ) . toArray ( ) , twoDeep ) ;
QCOMPARE ( outer . last ( ) . toArray ( ) . last ( ) . toArray ( ) . at ( 0 ) . toString ( ) , QString ( " nested " ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testArrayNestedEmpty ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject object ;
QJsonArray inner ;
object . insert ( " inner " , inner ) ;
QJsonValue val = object . value ( " inner " ) ;
QJsonArray value = object . value ( " inner " ) . toArray ( ) ;
QCOMPARE ( value . size ( ) , 0 ) ;
QCOMPARE ( value , inner ) ;
QCOMPARE ( value . size ( ) , 0 ) ;
object . insert ( " count " , 0. ) ;
QCOMPARE ( object . value ( " inner " ) . toArray ( ) . size ( ) , 0 ) ;
QVERIFY ( object . value ( " inner " ) . toArray ( ) . isEmpty ( ) ) ;
QJsonDocument ( object ) . toBinaryData ( ) ;
QCOMPARE ( object . value ( " inner " ) . toArray ( ) . size ( ) , 0 ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testObjectNestedEmpty ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject object ;
QJsonObject inner ;
QJsonObject inner2 ;
object . insert ( " inner " , inner ) ;
object . insert ( " inner2 " , inner2 ) ;
QJsonObject value = object . value ( " inner " ) . toObject ( ) ;
QCOMPARE ( value . size ( ) , 0 ) ;
QCOMPARE ( value , inner ) ;
QCOMPARE ( value . size ( ) , 0 ) ;
object . insert ( " count " , 0. ) ;
QCOMPARE ( object . value ( " inner " ) . toObject ( ) . size ( ) , 0 ) ;
QCOMPARE ( object . value ( " inner " ) . type ( ) , QJsonValue : : Object ) ;
QJsonDocument ( object ) . toBinaryData ( ) ;
QVERIFY ( object . value ( " inner " ) . toObject ( ) . isEmpty ( ) ) ;
QVERIFY ( object . value ( " inner2 " ) . toObject ( ) . isEmpty ( ) ) ;
QJsonDocument doc = QJsonDocument : : fromBinaryData ( QJsonDocument ( object ) . toBinaryData ( ) ) ;
QVERIFY ( ! doc . isNull ( ) ) ;
QJsonObject reconstituted ( doc . object ( ) ) ;
QCOMPARE ( reconstituted . value ( " inner " ) . toObject ( ) . size ( ) , 0 ) ;
QCOMPARE ( reconstituted . value ( " inner " ) . type ( ) , QJsonValue : : Object ) ;
QCOMPARE ( reconstituted . value ( " inner2 " ) . type ( ) , QJsonValue : : Object ) ;
}
2013-12-29 21:19:13 +00:00
void tst_QtJson : : testArrayComfortOperators ( )
{
QJsonArray first ;
first . append ( 123. ) ;
first . append ( QLatin1String ( " foo " ) ) ;
QJsonArray second = QJsonArray ( ) < < 123. < < QLatin1String ( " foo " ) ;
QCOMPARE ( first , second ) ;
first = first + QLatin1String ( " bar " ) ;
second + = QLatin1String ( " bar " ) ;
QCOMPARE ( first , second ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testValueRef ( )
2012-01-18 09:12:50 +00:00
{
QJsonArray array ;
array . append ( 1. ) ;
array . append ( 2. ) ;
array . append ( 3. ) ;
2013-08-22 14:25:13 +00:00
array . append ( 4 ) ;
array . append ( 4.1 ) ;
2012-01-18 09:12:50 +00:00
array [ 1 ] = false ;
2013-08-22 14:25:13 +00:00
QCOMPARE ( array . size ( ) , 5 ) ;
2012-01-18 09:12:50 +00:00
QCOMPARE ( array . at ( 0 ) . toDouble ( ) , 1. ) ;
QCOMPARE ( array . at ( 2 ) . toDouble ( ) , 3. ) ;
2013-08-22 14:25:13 +00:00
QCOMPARE ( array . at ( 3 ) . toInt ( ) , 4 ) ;
QCOMPARE ( array . at ( 4 ) . toInt ( ) , 0 ) ;
2012-01-18 09:12:50 +00:00
QCOMPARE ( array . at ( 1 ) . type ( ) , QJsonValue : : Bool ) ;
QCOMPARE ( array . at ( 1 ) . toBool ( ) , false ) ;
QJsonObject object ;
object [ QLatin1String ( " key " ) ] = true ;
QCOMPARE ( object . size ( ) , 1 ) ;
object . insert ( QLatin1String ( " null " ) , QJsonValue ( ) ) ;
QCOMPARE ( object . value ( QLatin1String ( " null " ) ) , QJsonValue ( ) ) ;
object [ QLatin1String ( " null " ) ] = 100. ;
QCOMPARE ( object . value ( QLatin1String ( " null " ) ) . type ( ) , QJsonValue : : Double ) ;
QJsonObject: add some overloads taking QLatin1String
QXmlStreamReader also has QLatin1String overloads, which
greatly benefits parsers, since the vast majority of keys
in both JSON and XML are US-ASCII. This patch adds such an
overload to the JSON parser.
The value() function is all typical parsers need, so even
though many more QJsonObject functions taking QString could
benefit from the same treatment, value() is the single most
important one for read-only JSON access.
Add some more overloads, too, for functions that don't need
more internal scaffolding than value(). Requires adding a
dummy op[](QL1S) (forwarding to the QString overload) so as
not to make
QJsonObject json;
json[QLatin1String("key")]; // mutable
ambiguous between const op[](QL1S) and mutable op[](QString).
[ChangeLog][QtCore][QJsonObject] Added value(), op[] const,
find(), constFind(), contains() overloads taking QLatin1String.
Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-04-28 07:40:49 +00:00
QJsonValue val = qAsConst ( object ) [ QLatin1String ( " null " ) ] ;
2012-01-18 09:12:50 +00:00
QCOMPARE ( val . toDouble ( ) , 100. ) ;
QCOMPARE ( object . size ( ) , 2 ) ;
2012-05-07 16:09:39 +00:00
array [ 1 ] = array [ 2 ] = object [ QLatin1String ( " key " ) ] = 42 ;
QCOMPARE ( array [ 1 ] , array [ 2 ] ) ;
QCOMPARE ( array [ 2 ] , object [ QLatin1String ( " key " ) ] ) ;
QCOMPARE ( object . value ( QLatin1String ( " key " ) ) , QJsonValue ( 42 ) ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testObjectIteration ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject object ;
2014-06-26 11:02:54 +00:00
for ( QJsonObject : : iterator it = object . begin ( ) ; it ! = object . end ( ) ; + + it )
QVERIFY ( false ) ;
const QString property = " kkk " ;
object . insert ( property , 11 ) ;
object . take ( property ) ;
for ( QJsonObject : : iterator it = object . begin ( ) ; it ! = object . end ( ) ; + + it )
QVERIFY ( false ) ;
2012-01-18 09:12:50 +00:00
for ( int i = 0 ; i < 10 ; + + i )
object [ QString : : number ( i ) ] = ( double ) i ;
QCOMPARE ( object . size ( ) , 10 ) ;
2014-08-15 13:41:44 +00:00
QCOMPARE ( object . begin ( ) - > toDouble ( ) , object . constBegin ( ) - > toDouble ( ) ) ;
2012-01-18 09:12:50 +00:00
for ( QJsonObject : : iterator it = object . begin ( ) ; it ! = object . end ( ) ; + + it ) {
QJsonValue value = it . value ( ) ;
QCOMPARE ( ( double ) it . key ( ) . toInt ( ) , value . toDouble ( ) ) ;
}
{
QJsonObject object2 = object ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( object , object2 ) ;
2012-01-18 09:12:50 +00:00
QJsonValue val = * object2 . begin ( ) ;
object2 . erase ( object2 . begin ( ) ) ;
QCOMPARE ( object . size ( ) , 10 ) ;
QCOMPARE ( object2 . size ( ) , 9 ) ;
for ( QJsonObject : : const_iterator it = object2 . constBegin ( ) ; it ! = object2 . constEnd ( ) ; + + it ) {
QJsonValue value = it . value ( ) ;
QVERIFY ( it . value ( ) ! = val ) ;
QCOMPARE ( ( double ) it . key ( ) . toInt ( ) , value . toDouble ( ) ) ;
}
}
2012-06-04 16:52:36 +00:00
{
QJsonObject object2 = object ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( object , object2 ) ;
2012-06-04 16:52:36 +00:00
QJsonObject : : iterator it = object2 . find ( QString : : number ( 5 ) ) ;
object2 . erase ( it ) ;
QCOMPARE ( object . size ( ) , 10 ) ;
QCOMPARE ( object2 . size ( ) , 9 ) ;
}
2012-01-18 09:12:50 +00:00
{
QJsonObject : : Iterator it = object . begin ( ) ;
it + = 5 ;
QCOMPARE ( QJsonValue ( it . value ( ) ) . toDouble ( ) , 5. ) ;
it - = 3 ;
QCOMPARE ( QJsonValue ( it . value ( ) ) . toDouble ( ) , 2. ) ;
QJsonObject : : Iterator it2 = it + 5 ;
QCOMPARE ( QJsonValue ( it2 . value ( ) ) . toDouble ( ) , 7. ) ;
it2 = it - 1 ;
QCOMPARE ( QJsonValue ( it2 . value ( ) ) . toDouble ( ) , 1. ) ;
}
{
QJsonObject : : ConstIterator it = object . constBegin ( ) ;
it + = 5 ;
QCOMPARE ( QJsonValue ( it . value ( ) ) . toDouble ( ) , 5. ) ;
it - = 3 ;
QCOMPARE ( QJsonValue ( it . value ( ) ) . toDouble ( ) , 2. ) ;
QJsonObject : : ConstIterator it2 = it + 5 ;
QCOMPARE ( QJsonValue ( it2 . value ( ) ) . toDouble ( ) , 7. ) ;
it2 = it - 1 ;
QCOMPARE ( QJsonValue ( it2 . value ( ) ) . toDouble ( ) , 1. ) ;
}
QJsonObject : : Iterator it = object . begin ( ) ;
while ( ! object . isEmpty ( ) )
it = object . erase ( it ) ;
QCOMPARE ( object . size ( ) , 0 ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( it , object . end ( ) ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testArrayIteration ( )
2012-01-18 09:12:50 +00:00
{
QJsonArray array ;
for ( int i = 0 ; i < 10 ; + + i )
array . append ( i ) ;
QCOMPARE ( array . size ( ) , 10 ) ;
int i = 0 ;
for ( QJsonArray : : iterator it = array . begin ( ) ; it ! = array . end ( ) ; + + it , + + i ) {
QJsonValue value = ( * it ) ;
QCOMPARE ( ( double ) i , value . toDouble ( ) ) ;
}
2014-08-15 13:41:44 +00:00
QCOMPARE ( array . begin ( ) - > toDouble ( ) , array . constBegin ( ) - > toDouble ( ) ) ;
2012-01-18 09:12:50 +00:00
{
QJsonArray array2 = array ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( array , array2 ) ;
2012-01-18 09:12:50 +00:00
QJsonValue val = * array2 . begin ( ) ;
array2 . erase ( array2 . begin ( ) ) ;
QCOMPARE ( array . size ( ) , 10 ) ;
QCOMPARE ( array2 . size ( ) , 9 ) ;
i = 1 ;
for ( QJsonArray : : const_iterator it = array2 . constBegin ( ) ; it ! = array2 . constEnd ( ) ; + + it , + + i ) {
QJsonValue value = ( * it ) ;
QCOMPARE ( ( double ) i , value . toDouble ( ) ) ;
}
}
{
QJsonArray : : Iterator it = array . begin ( ) ;
it + = 5 ;
QCOMPARE ( QJsonValue ( ( * it ) ) . toDouble ( ) , 5. ) ;
it - = 3 ;
QCOMPARE ( QJsonValue ( ( * it ) ) . toDouble ( ) , 2. ) ;
QJsonArray : : Iterator it2 = it + 5 ;
QCOMPARE ( QJsonValue ( * it2 ) . toDouble ( ) , 7. ) ;
it2 = it - 1 ;
QCOMPARE ( QJsonValue ( * it2 ) . toDouble ( ) , 1. ) ;
}
{
QJsonArray : : ConstIterator it = array . constBegin ( ) ;
it + = 5 ;
QCOMPARE ( QJsonValue ( ( * it ) ) . toDouble ( ) , 5. ) ;
it - = 3 ;
QCOMPARE ( QJsonValue ( ( * it ) ) . toDouble ( ) , 2. ) ;
QJsonArray : : ConstIterator it2 = it + 5 ;
QCOMPARE ( QJsonValue ( * it2 ) . toDouble ( ) , 7. ) ;
it2 = it - 1 ;
QCOMPARE ( QJsonValue ( * it2 ) . toDouble ( ) , 1. ) ;
}
QJsonArray : : Iterator it = array . begin ( ) ;
while ( ! array . isEmpty ( ) )
it = array . erase ( it ) ;
QCOMPARE ( array . size ( ) , 0 ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( it , array . end ( ) ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testObjectFind ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject object ;
for ( int i = 0 ; i < 10 ; + + i )
object [ QString : : number ( i ) ] = i ;
QCOMPARE ( object . size ( ) , 10 ) ;
QJsonObject : : iterator it = object . find ( QLatin1String ( " 1 " ) ) ;
QCOMPARE ( ( * it ) . toDouble ( ) , 1. ) ;
QJsonObject: add some overloads taking QLatin1String
QXmlStreamReader also has QLatin1String overloads, which
greatly benefits parsers, since the vast majority of keys
in both JSON and XML are US-ASCII. This patch adds such an
overload to the JSON parser.
The value() function is all typical parsers need, so even
though many more QJsonObject functions taking QString could
benefit from the same treatment, value() is the single most
important one for read-only JSON access.
Add some more overloads, too, for functions that don't need
more internal scaffolding than value(). Requires adding a
dummy op[](QL1S) (forwarding to the QString overload) so as
not to make
QJsonObject json;
json[QLatin1String("key")]; // mutable
ambiguous between const op[](QL1S) and mutable op[](QString).
[ChangeLog][QtCore][QJsonObject] Added value(), op[] const,
find(), constFind(), contains() overloads taking QLatin1String.
Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-04-28 07:40:49 +00:00
it = object . find ( QString ( " 11 " ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( ( * it ) . type ( ) , QJsonValue : : Undefined ) ;
QCOMPARE ( it , object . end ( ) ) ;
2012-01-18 09:12:50 +00:00
QJsonObject : : const_iterator cit = object . constFind ( QLatin1String ( " 1 " ) ) ;
QCOMPARE ( ( * cit ) . toDouble ( ) , 1. ) ;
QJsonObject: add some overloads taking QLatin1String
QXmlStreamReader also has QLatin1String overloads, which
greatly benefits parsers, since the vast majority of keys
in both JSON and XML are US-ASCII. This patch adds such an
overload to the JSON parser.
The value() function is all typical parsers need, so even
though many more QJsonObject functions taking QString could
benefit from the same treatment, value() is the single most
important one for read-only JSON access.
Add some more overloads, too, for functions that don't need
more internal scaffolding than value(). Requires adding a
dummy op[](QL1S) (forwarding to the QString overload) so as
not to make
QJsonObject json;
json[QLatin1String("key")]; // mutable
ambiguous between const op[](QL1S) and mutable op[](QString).
[ChangeLog][QtCore][QJsonObject] Added value(), op[] const,
find(), constFind(), contains() overloads taking QLatin1String.
Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-04-28 07:40:49 +00:00
cit = object . constFind ( QString ( " 11 " ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( ( * it ) . type ( ) , QJsonValue : : Undefined ) ;
QCOMPARE ( it , object . end ( ) ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testDocument ( )
2012-01-18 09:12:50 +00:00
{
QJsonDocument doc ;
QCOMPARE ( doc . isEmpty ( ) , true ) ;
QCOMPARE ( doc . isArray ( ) , false ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
QJsonObject object ;
doc . setObject ( object ) ;
QCOMPARE ( doc . isEmpty ( ) , false ) ;
QCOMPARE ( doc . isArray ( ) , false ) ;
QCOMPARE ( doc . isObject ( ) , true ) ;
object . insert ( QLatin1String ( " Key " ) , QLatin1String ( " Value " ) ) ;
doc . setObject ( object ) ;
QCOMPARE ( doc . isEmpty ( ) , false ) ;
QCOMPARE ( doc . isArray ( ) , false ) ;
QCOMPARE ( doc . isObject ( ) , true ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( doc . object ( ) , object ) ;
QCOMPARE ( doc . array ( ) , QJsonArray ( ) ) ;
2012-01-18 09:12:50 +00:00
doc = QJsonDocument ( ) ;
QCOMPARE ( doc . isEmpty ( ) , true ) ;
QCOMPARE ( doc . isArray ( ) , false ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
QJsonArray array ;
doc . setArray ( array ) ;
QCOMPARE ( doc . isEmpty ( ) , false ) ;
QCOMPARE ( doc . isArray ( ) , true ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
array . append ( QLatin1String ( " Value " ) ) ;
doc . setArray ( array ) ;
QCOMPARE ( doc . isEmpty ( ) , false ) ;
QCOMPARE ( doc . isArray ( ) , true ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( doc . array ( ) , array ) ;
QCOMPARE ( doc . object ( ) , QJsonObject ( ) ) ;
2012-01-18 09:12:50 +00:00
QJsonObject outer ;
outer . insert ( QLatin1String ( " outerKey " ) , 22 ) ;
QJsonObject inner ;
inner . insert ( QLatin1String ( " innerKey " ) , 42 ) ;
outer . insert ( QLatin1String ( " innter " ) , inner ) ;
QJsonArray innerArray ;
innerArray . append ( 23 ) ;
outer . insert ( QLatin1String ( " innterArray " ) , innerArray ) ;
QJsonDocument doc2 ( outer . value ( QLatin1String ( " innter " ) ) . toObject ( ) ) ;
QVERIFY ( doc2 . object ( ) . contains ( QLatin1String ( " innerKey " ) ) ) ;
QCOMPARE ( doc2 . object ( ) . value ( QLatin1String ( " innerKey " ) ) , QJsonValue ( 42 ) ) ;
QJsonDocument doc3 ;
doc3 . setObject ( outer . value ( QLatin1String ( " innter " ) ) . toObject ( ) ) ;
QCOMPARE ( doc3 . isArray ( ) , false ) ;
QCOMPARE ( doc3 . isObject ( ) , true ) ;
QJsonObject: add some overloads taking QLatin1String
QXmlStreamReader also has QLatin1String overloads, which
greatly benefits parsers, since the vast majority of keys
in both JSON and XML are US-ASCII. This patch adds such an
overload to the JSON parser.
The value() function is all typical parsers need, so even
though many more QJsonObject functions taking QString could
benefit from the same treatment, value() is the single most
important one for read-only JSON access.
Add some more overloads, too, for functions that don't need
more internal scaffolding than value(). Requires adding a
dummy op[](QL1S) (forwarding to the QString overload) so as
not to make
QJsonObject json;
json[QLatin1String("key")]; // mutable
ambiguous between const op[](QL1S) and mutable op[](QString).
[ChangeLog][QtCore][QJsonObject] Added value(), op[] const,
find(), constFind(), contains() overloads taking QLatin1String.
Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-04-28 07:40:49 +00:00
QVERIFY ( doc3 . object ( ) . contains ( QString ( " innerKey " ) ) ) ;
2012-01-18 09:12:50 +00:00
QCOMPARE ( doc3 . object ( ) . value ( QLatin1String ( " innerKey " ) ) , QJsonValue ( 42 ) ) ;
QJsonDocument doc4 ( outer . value ( QLatin1String ( " innterArray " ) ) . toArray ( ) ) ;
QCOMPARE ( doc4 . isArray ( ) , true ) ;
QCOMPARE ( doc4 . isObject ( ) , false ) ;
QCOMPARE ( doc4 . array ( ) . size ( ) , 1 ) ;
QCOMPARE ( doc4 . array ( ) . at ( 0 ) , QJsonValue ( 23 ) ) ;
QJsonDocument doc5 ;
doc5 . setArray ( outer . value ( QLatin1String ( " innterArray " ) ) . toArray ( ) ) ;
QCOMPARE ( doc5 . isArray ( ) , true ) ;
QCOMPARE ( doc5 . isObject ( ) , false ) ;
QCOMPARE ( doc5 . array ( ) . size ( ) , 1 ) ;
QCOMPARE ( doc5 . array ( ) . at ( 0 ) , QJsonValue ( 23 ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : nullValues ( )
2012-01-18 09:12:50 +00:00
{
QJsonArray array ;
array . append ( QJsonValue ( ) ) ;
QCOMPARE ( array . size ( ) , 1 ) ;
QCOMPARE ( array . at ( 0 ) , QJsonValue ( ) ) ;
QJsonObject object ;
object . insert ( QString ( " key " ) , QJsonValue ( ) ) ;
QJsonObject: add some overloads taking QLatin1String
QXmlStreamReader also has QLatin1String overloads, which
greatly benefits parsers, since the vast majority of keys
in both JSON and XML are US-ASCII. This patch adds such an
overload to the JSON parser.
The value() function is all typical parsers need, so even
though many more QJsonObject functions taking QString could
benefit from the same treatment, value() is the single most
important one for read-only JSON access.
Add some more overloads, too, for functions that don't need
more internal scaffolding than value(). Requires adding a
dummy op[](QL1S) (forwarding to the QString overload) so as
not to make
QJsonObject json;
json[QLatin1String("key")]; // mutable
ambiguous between const op[](QL1S) and mutable op[](QString).
[ChangeLog][QtCore][QJsonObject] Added value(), op[] const,
find(), constFind(), contains() overloads taking QLatin1String.
Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-04-28 07:40:49 +00:00
QCOMPARE ( object . contains ( QLatin1String ( " key " ) ) , true ) ;
2012-01-18 09:12:50 +00:00
QCOMPARE ( object . size ( ) , 1 ) ;
QJsonObject: add some overloads taking QLatin1String
QXmlStreamReader also has QLatin1String overloads, which
greatly benefits parsers, since the vast majority of keys
in both JSON and XML are US-ASCII. This patch adds such an
overload to the JSON parser.
The value() function is all typical parsers need, so even
though many more QJsonObject functions taking QString could
benefit from the same treatment, value() is the single most
important one for read-only JSON access.
Add some more overloads, too, for functions that don't need
more internal scaffolding than value(). Requires adding a
dummy op[](QL1S) (forwarding to the QString overload) so as
not to make
QJsonObject json;
json[QLatin1String("key")]; // mutable
ambiguous between const op[](QL1S) and mutable op[](QString).
[ChangeLog][QtCore][QJsonObject] Added value(), op[] const,
find(), constFind(), contains() overloads taking QLatin1String.
Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-04-28 07:40:49 +00:00
QCOMPARE ( object . value ( QString ( " key " ) ) , QJsonValue ( ) ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : nullArrays ( )
2012-01-18 09:12:50 +00:00
{
QJsonArray nullArray ;
QJsonArray nonNull ;
nonNull . append ( QLatin1String ( " bar " ) ) ;
QCOMPARE ( nullArray , QJsonArray ( ) ) ;
QVERIFY ( nullArray ! = nonNull ) ;
QVERIFY ( nonNull ! = nullArray ) ;
QCOMPARE ( nullArray . size ( ) , 0 ) ;
QCOMPARE ( nullArray . takeAt ( 0 ) , QJsonValue ( QJsonValue : : Undefined ) ) ;
QCOMPARE ( nullArray . first ( ) , QJsonValue ( QJsonValue : : Undefined ) ) ;
QCOMPARE ( nullArray . last ( ) , QJsonValue ( QJsonValue : : Undefined ) ) ;
nullArray . removeAt ( 0 ) ;
nullArray . removeAt ( - 1 ) ;
nullArray . append ( QString ( " bar " ) ) ;
nullArray . removeAt ( 0 ) ;
QCOMPARE ( nullArray . size ( ) , 0 ) ;
QCOMPARE ( nullArray . takeAt ( 0 ) , QJsonValue ( QJsonValue : : Undefined ) ) ;
QCOMPARE ( nullArray . first ( ) , QJsonValue ( QJsonValue : : Undefined ) ) ;
QCOMPARE ( nullArray . last ( ) , QJsonValue ( QJsonValue : : Undefined ) ) ;
nullArray . removeAt ( 0 ) ;
nullArray . removeAt ( - 1 ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : nullObject ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject nullObject ;
QJsonObject nonNull ;
nonNull . insert ( QLatin1String ( " foo " ) , QLatin1String ( " bar " ) ) ;
QCOMPARE ( nullObject , QJsonObject ( ) ) ;
QVERIFY ( nullObject ! = nonNull ) ;
QVERIFY ( nonNull ! = nullObject ) ;
QCOMPARE ( nullObject . size ( ) , 0 ) ;
QCOMPARE ( nullObject . keys ( ) , QStringList ( ) ) ;
nullObject . remove ( " foo " ) ;
QCOMPARE ( nullObject , QJsonObject ( ) ) ;
QCOMPARE ( nullObject . take ( " foo " ) , QJsonValue ( QJsonValue : : Undefined ) ) ;
QCOMPARE ( nullObject . contains ( " foo " ) , false ) ;
nullObject . insert ( " foo " , QString ( " bar " ) ) ;
nullObject . remove ( " foo " ) ;
QCOMPARE ( nullObject . size ( ) , 0 ) ;
QCOMPARE ( nullObject . keys ( ) , QStringList ( ) ) ;
nullObject . remove ( " foo " ) ;
QCOMPARE ( nullObject , QJsonObject ( ) ) ;
QCOMPARE ( nullObject . take ( " foo " ) , QJsonValue ( QJsonValue : : Undefined ) ) ;
QCOMPARE ( nullObject . contains ( " foo " ) , false ) ;
}
2014-05-23 11:45:27 +00:00
void tst_QtJson : : constNullObject ( )
{
const QJsonObject nullObject ;
QJsonObject nonNull ;
nonNull . insert ( QLatin1String ( " foo " ) , QLatin1String ( " bar " ) ) ;
QCOMPARE ( nullObject , QJsonObject ( ) ) ;
QVERIFY ( nullObject ! = nonNull ) ;
QVERIFY ( nonNull ! = nullObject ) ;
QCOMPARE ( nullObject . size ( ) , 0 ) ;
QCOMPARE ( nullObject . keys ( ) , QStringList ( ) ) ;
QCOMPARE ( nullObject , QJsonObject ( ) ) ;
QCOMPARE ( nullObject . contains ( " foo " ) , false ) ;
QCOMPARE ( nullObject [ " foo " ] , QJsonValue ( QJsonValue : : Undefined ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : keySorting ( )
2012-01-18 09:12:50 +00:00
{
const char * json = " { \" B \" : true, \" A \" : false } " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QCOMPARE ( doc . isObject ( ) , true ) ;
QJsonObject o = doc . object ( ) ;
QCOMPARE ( o . size ( ) , 2 ) ;
QJsonObject : : const_iterator it = o . constBegin ( ) ;
QCOMPARE ( it . key ( ) , QLatin1String ( " A " ) ) ;
+ + it ;
QCOMPARE ( it . key ( ) , QLatin1String ( " B " ) ) ;
2015-01-22 09:38:34 +00:00
QCOMPARE ( o . keys ( ) , QStringList ( ) < < QLatin1String ( " A " ) < < QLatin1String ( " B " ) ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : undefinedValues ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject object ;
object . insert ( " Key " , QJsonValue ( QJsonValue : : Undefined ) ) ;
QCOMPARE ( object . size ( ) , 0 ) ;
object . insert ( " Key " , QLatin1String ( " Value " ) ) ;
QCOMPARE ( object . size ( ) , 1 ) ;
QCOMPARE ( object . value ( " Key " ) . type ( ) , QJsonValue : : String ) ;
QCOMPARE ( object . value ( " foo " ) . type ( ) , QJsonValue : : Undefined ) ;
object . insert ( " Key " , QJsonValue ( QJsonValue : : Undefined ) ) ;
QCOMPARE ( object . size ( ) , 0 ) ;
QCOMPARE ( object . value ( " Key " ) . type ( ) , QJsonValue : : Undefined ) ;
QJsonArray array ;
array . append ( QJsonValue ( QJsonValue : : Undefined ) ) ;
QCOMPARE ( array . size ( ) , 1 ) ;
QCOMPARE ( array . at ( 0 ) . type ( ) , QJsonValue : : Null ) ;
QCOMPARE ( array . at ( 1 ) . type ( ) , QJsonValue : : Undefined ) ;
QCOMPARE ( array . at ( - 1 ) . type ( ) , QJsonValue : : Undefined ) ;
}
2014-03-04 12:48:31 +00:00
void tst_QtJson : : fromVariant ( )
{
bool boolValue = true ;
int intValue = - 1 ;
uint uintValue = 1 ;
long long longlongValue = - 2 ;
unsigned long long ulonglongValue = 2 ;
float floatValue = 3.3f ;
double doubleValue = 4.4 ;
QString stringValue ( " str " ) ;
QStringList stringList ;
stringList . append ( stringValue ) ;
stringList . append ( " str2 " ) ;
QJsonArray jsonArray_string ;
jsonArray_string . append ( stringValue ) ;
jsonArray_string . append ( " str2 " ) ;
QVariantList variantList ;
variantList . append ( boolValue ) ;
variantList . append ( floatValue ) ;
variantList . append ( doubleValue ) ;
variantList . append ( stringValue ) ;
variantList . append ( stringList ) ;
variantList . append ( QVariant ( ) ) ;
QJsonArray jsonArray_variant ;
jsonArray_variant . append ( boolValue ) ;
jsonArray_variant . append ( floatValue ) ;
jsonArray_variant . append ( doubleValue ) ;
jsonArray_variant . append ( stringValue ) ;
jsonArray_variant . append ( jsonArray_string ) ;
jsonArray_variant . append ( QJsonValue ( ) ) ;
QVariantMap variantMap ;
variantMap [ " bool " ] = boolValue ;
variantMap [ " float " ] = floatValue ;
variantMap [ " string " ] = stringValue ;
variantMap [ " array " ] = variantList ;
QJsonObject jsonObject ;
jsonObject [ " bool " ] = boolValue ;
jsonObject [ " float " ] = floatValue ;
jsonObject [ " string " ] = stringValue ;
jsonObject [ " array " ] = jsonArray_variant ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( boolValue ) ) , QJsonValue ( boolValue ) ) ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( intValue ) ) , QJsonValue ( intValue ) ) ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( uintValue ) ) , QJsonValue ( static_cast < double > ( uintValue ) ) ) ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( longlongValue ) ) , QJsonValue ( longlongValue ) ) ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( ulonglongValue ) ) , QJsonValue ( static_cast < double > ( ulonglongValue ) ) ) ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( floatValue ) ) , QJsonValue ( static_cast < double > ( floatValue ) ) ) ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( doubleValue ) ) , QJsonValue ( doubleValue ) ) ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( stringValue ) ) , QJsonValue ( stringValue ) ) ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( stringList ) ) , QJsonValue ( jsonArray_string ) ) ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( variantList ) ) , QJsonValue ( jsonArray_variant ) ) ;
QCOMPARE ( QJsonValue : : fromVariant ( QVariant ( variantMap ) ) , QJsonValue ( jsonObject ) ) ;
2015-03-20 12:05:43 +00:00
QVERIFY ( QJsonValue : : fromVariant ( QVariant ( QJsonValue ( true ) ) ) . isBool ( ) ) ;
QVERIFY ( QJsonValue : : fromVariant ( QVariant ( jsonArray_string ) ) . isArray ( ) ) ;
QVERIFY ( QJsonValue : : fromVariant ( QVariant ( QJsonDocument ( jsonArray_string ) ) ) . isArray ( ) ) ;
QVERIFY ( QJsonValue : : fromVariant ( QVariant ( jsonObject ) ) . isObject ( ) ) ;
QVERIFY ( QJsonValue : : fromVariant ( QVariant ( QJsonDocument ( jsonObject ) ) ) . isObject ( ) ) ;
2014-03-04 12:48:31 +00:00
}
2012-01-18 09:12:50 +00:00
2012-10-22 10:39:02 +00:00
void tst_QtJson : : fromVariantMap ( )
2012-01-18 09:12:50 +00:00
{
QVariantMap map ;
map . insert ( QLatin1String ( " key1 " ) , QLatin1String ( " value1 " ) ) ;
map . insert ( QLatin1String ( " key2 " ) , QLatin1String ( " value2 " ) ) ;
QJsonObject object = QJsonObject : : fromVariantMap ( map ) ;
QCOMPARE ( object . size ( ) , 2 ) ;
QCOMPARE ( object . value ( QLatin1String ( " key1 " ) ) , QJsonValue ( QLatin1String ( " value1 " ) ) ) ;
QCOMPARE ( object . value ( QLatin1String ( " key2 " ) ) , QJsonValue ( QLatin1String ( " value2 " ) ) ) ;
QVariantList list ;
list . append ( true ) ;
list . append ( QVariant ( ) ) ;
list . append ( 999. ) ;
list . append ( QLatin1String ( " foo " ) ) ;
map . insert ( " list " , list ) ;
object = QJsonObject : : fromVariantMap ( map ) ;
QCOMPARE ( object . size ( ) , 3 ) ;
QCOMPARE ( object . value ( QLatin1String ( " key1 " ) ) , QJsonValue ( QLatin1String ( " value1 " ) ) ) ;
QCOMPARE ( object . value ( QLatin1String ( " key2 " ) ) , QJsonValue ( QLatin1String ( " value2 " ) ) ) ;
QCOMPARE ( object . value ( QLatin1String ( " list " ) ) . type ( ) , QJsonValue : : Array ) ;
QJsonArray array = object . value ( QLatin1String ( " list " ) ) . toArray ( ) ;
QCOMPARE ( array . size ( ) , 4 ) ;
QCOMPARE ( array . at ( 0 ) . type ( ) , QJsonValue : : Bool ) ;
QCOMPARE ( array . at ( 0 ) . toBool ( ) , true ) ;
QCOMPARE ( array . at ( 1 ) . type ( ) , QJsonValue : : Null ) ;
QCOMPARE ( array . at ( 2 ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( array . at ( 2 ) . toDouble ( ) , 999. ) ;
QCOMPARE ( array . at ( 3 ) . type ( ) , QJsonValue : : String ) ;
QCOMPARE ( array . at ( 3 ) . toString ( ) , QLatin1String ( " foo " ) ) ;
}
2014-10-30 09:59:11 +00:00
void tst_QtJson : : fromVariantHash ( )
{
QVariantHash map ;
map . insert ( QLatin1String ( " key1 " ) , QLatin1String ( " value1 " ) ) ;
map . insert ( QLatin1String ( " key2 " ) , QLatin1String ( " value2 " ) ) ;
QJsonObject object = QJsonObject : : fromVariantHash ( map ) ;
QCOMPARE ( object . size ( ) , 2 ) ;
QCOMPARE ( object . value ( QLatin1String ( " key1 " ) ) , QJsonValue ( QLatin1String ( " value1 " ) ) ) ;
QCOMPARE ( object . value ( QLatin1String ( " key2 " ) ) , QJsonValue ( QLatin1String ( " value2 " ) ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : toVariantMap ( )
2012-01-18 09:12:50 +00:00
{
2013-07-23 13:42:55 +00:00
QCOMPARE ( QMetaType : : Type ( QJsonValue ( QJsonObject ( ) ) . toVariant ( ) . type ( ) ) , QMetaType : : QVariantMap ) ; // QTBUG-32524
2012-01-18 09:12:50 +00:00
QJsonObject object ;
2012-01-30 13:37:36 +00:00
QVariantMap map = object . toVariantMap ( ) ;
QVERIFY ( map . isEmpty ( ) ) ;
2012-01-18 09:12:50 +00:00
object . insert ( " Key " , QString ( " Value " ) ) ;
object . insert ( " null " , QJsonValue ( ) ) ;
QJsonArray array ;
array . append ( true ) ;
array . append ( 999. ) ;
array . append ( QLatin1String ( " string " ) ) ;
array . append ( QJsonValue ( ) ) ;
object . insert ( " Array " , array ) ;
2012-01-30 13:37:36 +00:00
map = object . toVariantMap ( ) ;
2012-01-18 09:12:50 +00:00
QCOMPARE ( map . size ( ) , 3 ) ;
QCOMPARE ( map . value ( " Key " ) , QVariant ( QString ( " Value " ) ) ) ;
QCOMPARE ( map . value ( " null " ) , QVariant ( ) ) ;
QCOMPARE ( map . value ( " Array " ) . type ( ) , QVariant : : List ) ;
QVariantList list = map . value ( " Array " ) . toList ( ) ;
QCOMPARE ( list . size ( ) , 4 ) ;
QCOMPARE ( list . at ( 0 ) , QVariant ( true ) ) ;
QCOMPARE ( list . at ( 1 ) , QVariant ( 999. ) ) ;
QCOMPARE ( list . at ( 2 ) , QVariant ( QLatin1String ( " string " ) ) ) ;
2014-10-30 09:59:11 +00:00
QCOMPARE ( list . at ( 3 ) , QVariant ( ) ) ;
}
void tst_QtJson : : toVariantHash ( )
{
QJsonObject object ;
QVariantHash hash = object . toVariantHash ( ) ;
QVERIFY ( hash . isEmpty ( ) ) ;
object . insert ( " Key " , QString ( " Value " ) ) ;
object . insert ( " null " , QJsonValue ( ) ) ;
QJsonArray array ;
array . append ( true ) ;
array . append ( 999. ) ;
array . append ( QLatin1String ( " string " ) ) ;
array . append ( QJsonValue ( ) ) ;
object . insert ( " Array " , array ) ;
hash = object . toVariantHash ( ) ;
QCOMPARE ( hash . size ( ) , 3 ) ;
QCOMPARE ( hash . value ( " Key " ) , QVariant ( QString ( " Value " ) ) ) ;
QCOMPARE ( hash . value ( " null " ) , QVariant ( ) ) ;
QCOMPARE ( hash . value ( " Array " ) . type ( ) , QVariant : : List ) ;
QVariantList list = hash . value ( " Array " ) . toList ( ) ;
QCOMPARE ( list . size ( ) , 4 ) ;
QCOMPARE ( list . at ( 0 ) , QVariant ( true ) ) ;
QCOMPARE ( list . at ( 1 ) , QVariant ( 999. ) ) ;
QCOMPARE ( list . at ( 2 ) , QVariant ( QLatin1String ( " string " ) ) ) ;
2012-01-18 09:12:50 +00:00
QCOMPARE ( list . at ( 3 ) , QVariant ( ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : toVariantList ( )
2012-01-30 13:37:36 +00:00
{
2013-07-23 13:42:55 +00:00
QCOMPARE ( QMetaType : : Type ( QJsonValue ( QJsonArray ( ) ) . toVariant ( ) . type ( ) ) , QMetaType : : QVariantList ) ; // QTBUG-32524
2012-01-30 13:37:36 +00:00
QJsonArray array ;
QVariantList list = array . toVariantList ( ) ;
QVERIFY ( list . isEmpty ( ) ) ;
array . append ( QString ( " Value " ) ) ;
array . append ( QJsonValue ( ) ) ;
QJsonArray inner ;
inner . append ( true ) ;
inner . append ( 999. ) ;
inner . append ( QLatin1String ( " string " ) ) ;
inner . append ( QJsonValue ( ) ) ;
array . append ( inner ) ;
list = array . toVariantList ( ) ;
QCOMPARE ( list . size ( ) , 3 ) ;
QCOMPARE ( list [ 0 ] , QVariant ( QString ( " Value " ) ) ) ;
QCOMPARE ( list [ 1 ] , QVariant ( ) ) ;
QCOMPARE ( list [ 2 ] . type ( ) , QVariant : : List ) ;
QVariantList vlist = list [ 2 ] . toList ( ) ;
QCOMPARE ( vlist . size ( ) , 4 ) ;
QCOMPARE ( vlist . at ( 0 ) , QVariant ( true ) ) ;
QCOMPARE ( vlist . at ( 1 ) , QVariant ( 999. ) ) ;
QCOMPARE ( vlist . at ( 2 ) , QVariant ( QLatin1String ( " string " ) ) ) ;
QCOMPARE ( vlist . at ( 3 ) , QVariant ( ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : toJson ( )
2012-01-18 09:12:50 +00:00
{
2012-12-28 00:23:16 +00:00
// Test QJsonDocument::Indented format
{
QJsonObject object ;
object . insert ( " \\ Key \n " , QString ( " Value " ) ) ;
object . insert ( " null " , QJsonValue ( ) ) ;
QJsonArray array ;
array . append ( true ) ;
array . append ( 999. ) ;
array . append ( QLatin1String ( " string " ) ) ;
array . append ( QJsonValue ( ) ) ;
array . append ( QLatin1String ( " \\ \a \n \r \b \t abcABC \" " ) ) ;
object . insert ( " Array " , array ) ;
QByteArray json = QJsonDocument ( object ) . toJson ( ) ;
QByteArray expected =
" { \n "
" \" Array \" : [ \n "
" true, \n "
" 999, \n "
" \" string \" , \n "
" null, \n "
" \" \\ \\ \\ u0007 \\ n \\ r \\ b \\ tabcABC \\ \" \" \n "
" ], \n "
" \" \\ \\ Key \\ n \" : \" Value \" , \n "
" \" null \" : null \n "
" } \n " ;
QCOMPARE ( json , expected ) ;
QJsonDocument doc ;
doc . setObject ( object ) ;
json = doc . toJson ( ) ;
QCOMPARE ( json , expected ) ;
doc . setArray ( array ) ;
json = doc . toJson ( ) ;
expected =
" [ \n "
" true, \n "
" 999, \n "
" \" string \" , \n "
" null, \n "
" \" \\ \\ \\ u0007 \\ n \\ r \\ b \\ tabcABC \\ \" \" \n "
" ] \n " ;
QCOMPARE ( json , expected ) ;
}
2012-01-18 09:12:50 +00:00
2012-12-28 00:23:16 +00:00
// Test QJsonDocument::Compact format
{
QJsonObject object ;
object . insert ( " \\ Key \n " , QString ( " Value " ) ) ;
object . insert ( " null " , QJsonValue ( ) ) ;
QJsonArray array ;
array . append ( true ) ;
array . append ( 999. ) ;
array . append ( QLatin1String ( " string " ) ) ;
array . append ( QJsonValue ( ) ) ;
array . append ( QLatin1String ( " \\ \a \n \r \b \t abcABC \" " ) ) ;
object . insert ( " Array " , array ) ;
QByteArray json = QJsonDocument ( object ) . toJson ( QJsonDocument : : Compact ) ;
QByteArray expected =
2014-02-14 08:33:21 +00:00
" { \" Array \" :[true,999, \" string \" ,null, \" \\ \\ \\ u0007 \\ n \\ r \\ b \\ tabcABC \\ \" \" ], \" \\ \\ Key \\ n \" : \" Value \" , \" null \" :null} " ;
2012-12-28 00:23:16 +00:00
QCOMPARE ( json , expected ) ;
QJsonDocument doc ;
doc . setObject ( object ) ;
json = doc . toJson ( QJsonDocument : : Compact ) ;
QCOMPARE ( json , expected ) ;
doc . setArray ( array ) ;
json = doc . toJson ( QJsonDocument : : Compact ) ;
expected = " [true,999, \" string \" ,null, \" \\ \\ \\ u0007 \\ n \\ r \\ b \\ tabcABC \\ \" \" ] " ;
QCOMPARE ( json , expected ) ;
}
2012-01-18 09:12:50 +00:00
}
2013-02-10 07:18:42 +00:00
void tst_QtJson : : toJsonSillyNumericValues ( )
{
QJsonObject object ;
QJsonArray array ;
array . append ( QJsonValue ( std : : numeric_limits < double > : : infinity ( ) ) ) ; // encode to: null
array . append ( QJsonValue ( - std : : numeric_limits < double > : : infinity ( ) ) ) ; // encode to: null
array . append ( QJsonValue ( std : : numeric_limits < double > : : quiet_NaN ( ) ) ) ; // encode to: null
object . insert ( " Array " , array ) ;
QByteArray json = QJsonDocument ( object ) . toJson ( ) ;
QByteArray expected =
" { \n "
" \" Array \" : [ \n "
" null, \n "
" null, \n "
" null \n "
" ] \n "
" } \n " ;
QCOMPARE ( json , expected ) ;
QJsonDocument doc ;
doc . setObject ( object ) ;
json = doc . toJson ( ) ;
QCOMPARE ( json , expected ) ;
}
2013-02-10 09:02:00 +00:00
void tst_QtJson : : toJsonLargeNumericValues ( )
{
QJsonObject object ;
QJsonArray array ;
array . append ( QJsonValue ( 1.234567 ) ) ; // actual precision bug in Qt 5.0.0
array . append ( QJsonValue ( 1.7976931348623157e+308 ) ) ; // JS Number.MAX_VALUE
array . append ( QJsonValue ( 5e-324 ) ) ; // JS Number.MIN_VALUE
array . append ( QJsonValue ( std : : numeric_limits < double > : : min ( ) ) ) ;
array . append ( QJsonValue ( std : : numeric_limits < double > : : max ( ) ) ) ;
array . append ( QJsonValue ( std : : numeric_limits < double > : : epsilon ( ) ) ) ;
array . append ( QJsonValue ( std : : numeric_limits < double > : : denorm_min ( ) ) ) ;
array . append ( QJsonValue ( 0.0 ) ) ;
array . append ( QJsonValue ( - std : : numeric_limits < double > : : min ( ) ) ) ;
array . append ( QJsonValue ( - std : : numeric_limits < double > : : max ( ) ) ) ;
array . append ( QJsonValue ( - std : : numeric_limits < double > : : epsilon ( ) ) ) ;
array . append ( QJsonValue ( - std : : numeric_limits < double > : : denorm_min ( ) ) ) ;
array . append ( QJsonValue ( - 0.0 ) ) ;
2013-02-13 17:25:15 +00:00
array . append ( QJsonValue ( 9007199254740992LL ) ) ; // JS Number max integer
array . append ( QJsonValue ( - 9007199254740992LL ) ) ; // JS Number min integer
2013-02-10 09:02:00 +00:00
object . insert ( " Array " , array ) ;
QByteArray json = QJsonDocument ( object ) . toJson ( ) ;
QByteArray expected =
" { \n "
" \" Array \" : [ \n "
" 1.234567, \n "
" 1.7976931348623157e+308, \n "
2015-11-10 14:41:01 +00:00
# ifdef QT_NO_DOUBLECONVERSION // "shortest" double conversion is not very short then
2013-02-10 09:02:00 +00:00
" 4.9406564584124654e-324, \n "
" 2.2250738585072014e-308, \n "
" 1.7976931348623157e+308, \n "
" 2.2204460492503131e-16, \n "
" 4.9406564584124654e-324, \n "
" 0, \n "
" -2.2250738585072014e-308, \n "
" -1.7976931348623157e+308, \n "
" -2.2204460492503131e-16, \n "
" -4.9406564584124654e-324, \n "
2015-11-10 14:41:01 +00:00
# else
" 5e-324, \n "
" 2.2250738585072014e-308, \n "
" 1.7976931348623157e+308, \n "
" 2.220446049250313e-16, \n "
" 5e-324, \n "
" 0, \n "
" -2.2250738585072014e-308, \n "
" -1.7976931348623157e+308, \n "
" -2.220446049250313e-16, \n "
" -5e-324, \n "
# endif
2013-02-13 17:25:15 +00:00
" 0, \n "
" 9007199254740992, \n "
" -9007199254740992 \n "
2013-02-10 09:02:00 +00:00
" ] \n "
" } \n " ;
2014-03-26 12:52:09 +00:00
# ifdef Q_OS_QNX
2014-02-26 08:18:35 +00:00
QEXPECT_FAIL ( " " , " See QTBUG-37066 " , Continue ) ;
# endif
2013-02-10 09:02:00 +00:00
QCOMPARE ( json , expected ) ;
QJsonDocument doc ;
doc . setObject ( object ) ;
json = doc . toJson ( ) ;
2014-03-26 12:52:09 +00:00
# ifdef Q_OS_QNX
2014-02-26 08:18:35 +00:00
QEXPECT_FAIL ( " " , " See QTBUG-37066 " , Continue ) ;
# endif
2013-02-10 09:02:00 +00:00
QCOMPARE ( json , expected ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : fromJson ( )
2012-01-18 09:12:50 +00:00
{
{
QByteArray json = " [ \n true \n ] \n " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , true ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
QJsonArray array = doc . array ( ) ;
QCOMPARE ( array . size ( ) , 1 ) ;
QCOMPARE ( array . at ( 0 ) . type ( ) , QJsonValue : : Bool ) ;
QCOMPARE ( array . at ( 0 ) . toBool ( ) , true ) ;
QCOMPARE ( doc . toJson ( ) , json ) ;
}
2013-10-06 09:40:47 +00:00
{
//regression test: test if unicode_control_characters are correctly decoded
QByteArray json = " [ \n \" " UNICODE_NON_CHARACTER " \" \n ] \n " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , true ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
QJsonArray array = doc . array ( ) ;
QCOMPARE ( array . size ( ) , 1 ) ;
QCOMPARE ( array . at ( 0 ) . type ( ) , QJsonValue : : String ) ;
QCOMPARE ( array . at ( 0 ) . toString ( ) , QString : : fromUtf8 ( UNICODE_NON_CHARACTER ) ) ;
QCOMPARE ( doc . toJson ( ) , json ) ;
}
2012-01-18 09:12:50 +00:00
{
QByteArray json = " [] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , true ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
QJsonArray array = doc . array ( ) ;
QCOMPARE ( array . size ( ) , 0 ) ;
}
{
QByteArray json = " {} " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , false ) ;
QCOMPARE ( doc . isObject ( ) , true ) ;
QJsonObject object = doc . object ( ) ;
QCOMPARE ( object . size ( ) , 0 ) ;
}
{
QByteArray json = " { \n \" Key \" : true \n } \n " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , false ) ;
QCOMPARE ( doc . isObject ( ) , true ) ;
QJsonObject object = doc . object ( ) ;
QCOMPARE ( object . size ( ) , 1 ) ;
QCOMPARE ( object . value ( " Key " ) , QJsonValue ( true ) ) ;
QCOMPARE ( doc . toJson ( ) , json ) ;
}
{
QByteArray json = " [ null, true, false, \" Foo \" , 1, [], {} ] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , true ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
QJsonArray array = doc . array ( ) ;
QCOMPARE ( array . size ( ) , 7 ) ;
QCOMPARE ( array . at ( 0 ) . type ( ) , QJsonValue : : Null ) ;
QCOMPARE ( array . at ( 1 ) . type ( ) , QJsonValue : : Bool ) ;
QCOMPARE ( array . at ( 1 ) . toBool ( ) , true ) ;
QCOMPARE ( array . at ( 2 ) . type ( ) , QJsonValue : : Bool ) ;
QCOMPARE ( array . at ( 2 ) . toBool ( ) , false ) ;
QCOMPARE ( array . at ( 3 ) . type ( ) , QJsonValue : : String ) ;
QCOMPARE ( array . at ( 3 ) . toString ( ) , QLatin1String ( " Foo " ) ) ;
QCOMPARE ( array . at ( 4 ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( array . at ( 4 ) . toDouble ( ) , 1. ) ;
QCOMPARE ( array . at ( 5 ) . type ( ) , QJsonValue : : Array ) ;
QCOMPARE ( array . at ( 5 ) . toArray ( ) . size ( ) , 0 ) ;
QCOMPARE ( array . at ( 6 ) . type ( ) , QJsonValue : : Object ) ;
QCOMPARE ( array . at ( 6 ) . toObject ( ) . size ( ) , 0 ) ;
}
{
QByteArray json = " { \" 0 \" : null, \" 1 \" : true, \" 2 \" : false, \" 3 \" : \" Foo \" , \" 4 \" : 1, \" 5 \" : [], \" 6 \" : {} } " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , false ) ;
QCOMPARE ( doc . isObject ( ) , true ) ;
QJsonObject object = doc . object ( ) ;
QCOMPARE ( object . size ( ) , 7 ) ;
QCOMPARE ( object . value ( " 0 " ) . type ( ) , QJsonValue : : Null ) ;
QCOMPARE ( object . value ( " 1 " ) . type ( ) , QJsonValue : : Bool ) ;
QCOMPARE ( object . value ( " 1 " ) . toBool ( ) , true ) ;
QCOMPARE ( object . value ( " 2 " ) . type ( ) , QJsonValue : : Bool ) ;
QCOMPARE ( object . value ( " 2 " ) . toBool ( ) , false ) ;
QCOMPARE ( object . value ( " 3 " ) . type ( ) , QJsonValue : : String ) ;
QCOMPARE ( object . value ( " 3 " ) . toString ( ) , QLatin1String ( " Foo " ) ) ;
QCOMPARE ( object . value ( " 4 " ) . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( object . value ( " 4 " ) . toDouble ( ) , 1. ) ;
QCOMPARE ( object . value ( " 5 " ) . type ( ) , QJsonValue : : Array ) ;
QCOMPARE ( object . value ( " 5 " ) . toArray ( ) . size ( ) , 0 ) ;
QCOMPARE ( object . value ( " 6 " ) . type ( ) , QJsonValue : : Object ) ;
QCOMPARE ( object . value ( " 6 " ) . toObject ( ) . size ( ) , 0 ) ;
}
2012-12-28 00:23:16 +00:00
{
QByteArray compactJson = " { \" Array \" : [true,999, \" string \" ,null, \" \\ \\ \\ u0007 \\ n \\ r \\ b \\ tabcABC \\ \" \" ], \" \\ \\ Key \\ n \" : \" Value \" , \" null \" : null} " ;
QJsonDocument doc = QJsonDocument : : fromJson ( compactJson ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , false ) ;
QCOMPARE ( doc . isObject ( ) , true ) ;
QJsonObject object = doc . object ( ) ;
QCOMPARE ( object . size ( ) , 3 ) ;
QCOMPARE ( object . value ( " \\ Key \n " ) . isString ( ) , true ) ;
QCOMPARE ( object . value ( " \\ Key \n " ) . toString ( ) , QString ( " Value " ) ) ;
QCOMPARE ( object . value ( " null " ) . isNull ( ) , true ) ;
QCOMPARE ( object . value ( " Array " ) . isArray ( ) , true ) ;
QJsonArray array = object . value ( " Array " ) . toArray ( ) ;
QCOMPARE ( array . size ( ) , 5 ) ;
QCOMPARE ( array . at ( 0 ) . isBool ( ) , true ) ;
QCOMPARE ( array . at ( 0 ) . toBool ( ) , true ) ;
QCOMPARE ( array . at ( 1 ) . isDouble ( ) , true ) ;
QCOMPARE ( array . at ( 1 ) . toDouble ( ) , 999. ) ;
QCOMPARE ( array . at ( 2 ) . isString ( ) , true ) ;
QCOMPARE ( array . at ( 2 ) . toString ( ) , QLatin1String ( " string " ) ) ;
QCOMPARE ( array . at ( 3 ) . isNull ( ) , true ) ;
QCOMPARE ( array . at ( 4 ) . isString ( ) , true ) ;
QCOMPARE ( array . at ( 4 ) . toString ( ) , QLatin1String ( " \\ \a \n \r \b \t abcABC \" " ) ) ;
}
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : fromJsonErrors ( )
2012-02-17 20:38:23 +00:00
{
{
QJsonParseError error ;
QByteArray json = " { \n \n \n " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : UnterminatedObject ) ;
QCOMPARE ( error . offset , 8 ) ;
}
{
QJsonParseError error ;
QByteArray json = " { \n \" key \" 10 \n " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : MissingNameSeparator ) ;
QCOMPARE ( error . offset , 13 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n \n \n " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : UnterminatedArray ) ;
QCOMPARE ( error . offset , 8 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n 1, true \n \n " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : UnterminatedArray ) ;
QCOMPARE ( error . offset , 14 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n 1 true \n \n " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : MissingValueSeparator ) ;
QCOMPARE ( error . offset , 7 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n nul " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : IllegalValue ) ;
QCOMPARE ( error . offset , 7 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n nulzz " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : IllegalValue ) ;
QCOMPARE ( error . offset , 10 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n tru " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : IllegalValue ) ;
QCOMPARE ( error . offset , 7 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n trud] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : IllegalValue ) ;
QCOMPARE ( error . offset , 10 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n fal " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : IllegalValue ) ;
QCOMPARE ( error . offset , 7 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n falsd] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : IllegalValue ) ;
QCOMPARE ( error . offset , 11 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n 11111 " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
2012-03-13 14:10:12 +00:00
QCOMPARE ( error . error , QJsonParseError : : TerminationByNumber ) ;
2012-02-17 20:38:23 +00:00
QCOMPARE ( error . offset , 11 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n -1E10000] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : IllegalNumber ) ;
QCOMPARE ( error . offset , 14 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n -1e-10000] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
QCOMPARE ( error . error , QJsonParseError : : IllegalNumber ) ;
QCOMPARE ( error . offset , 15 ) ;
}
{
QJsonParseError error ;
QByteArray json = " [ \n \" \\ u12 \" ] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
2012-03-13 14:10:12 +00:00
QCOMPARE ( error . error , QJsonParseError : : IllegalEscapeSequence ) ;
2012-02-17 20:38:23 +00:00
QCOMPARE ( error . offset , 11 ) ;
}
{
QJsonParseError error ;
2012-02-23 11:24:49 +00:00
QByteArray json = " [ \n \" foo " INVALID_UNICODE " bar \" ] " ;
2012-02-17 20:38:23 +00:00
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
2012-03-13 14:10:12 +00:00
QCOMPARE ( error . error , QJsonParseError : : IllegalUTF8String ) ;
2013-10-20 03:04:47 +00:00
QCOMPARE ( error . offset , 12 ) ;
2012-02-17 20:38:23 +00:00
}
{
QJsonParseError error ;
QByteArray json = " [ \n \" " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
2012-03-13 14:10:12 +00:00
QCOMPARE ( error . error , QJsonParseError : : UnterminatedString ) ;
2012-02-17 20:38:23 +00:00
QCOMPARE ( error . offset , 8 ) ;
}
{
QJsonParseError error ;
2012-02-23 11:24:49 +00:00
QByteArray json = " [ \n \" c " UNICODE_DJE " a \\ u12 \" ] " ;
2012-02-17 20:38:23 +00:00
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
2012-03-13 14:10:12 +00:00
QCOMPARE ( error . error , QJsonParseError : : IllegalEscapeSequence ) ;
2012-02-17 20:38:23 +00:00
QCOMPARE ( error . offset , 15 ) ;
}
{
QJsonParseError error ;
2012-02-23 11:24:49 +00:00
QByteArray json = " [ \n \" c " UNICODE_DJE " a " INVALID_UNICODE " bar \" ] " ;
2012-02-17 20:38:23 +00:00
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
2012-03-13 14:10:12 +00:00
QCOMPARE ( error . error , QJsonParseError : : IllegalUTF8String ) ;
2013-10-20 03:04:47 +00:00
QCOMPARE ( error . offset , 13 ) ;
2012-02-17 20:38:23 +00:00
}
{
QJsonParseError error ;
2012-02-23 11:24:49 +00:00
QByteArray json = " [ \n \" c " UNICODE_DJE " a ] " ;
2012-02-17 20:38:23 +00:00
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isEmpty ( ) ) ;
2012-03-13 14:10:12 +00:00
QCOMPARE ( error . error , QJsonParseError : : UnterminatedString ) ;
2012-02-17 20:38:23 +00:00
QCOMPARE ( error . offset , 14 ) ;
}
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : fromBinary ( )
2012-01-18 09:12:50 +00:00
{
2012-02-15 04:22:48 +00:00
QFile file ( testDataDir + " /test.json " ) ;
2012-01-18 09:12:50 +00:00
file . open ( QFile : : ReadOnly ) ;
QByteArray testJson = file . readAll ( ) ;
QJsonDocument doc = QJsonDocument : : fromJson ( testJson ) ;
QJsonDocument outdoc = QJsonDocument : : fromBinaryData ( doc . toBinaryData ( ) ) ;
QVERIFY ( ! outdoc . isNull ( ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( doc , outdoc ) ;
2012-01-18 09:12:50 +00:00
2012-02-15 04:22:48 +00:00
QFile bfile ( testDataDir + " /test.bjson " ) ;
2012-01-18 09:12:50 +00:00
bfile . open ( QFile : : ReadOnly ) ;
QByteArray binary = bfile . readAll ( ) ;
QJsonDocument bdoc = QJsonDocument : : fromBinaryData ( binary ) ;
QVERIFY ( ! bdoc . isNull ( ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( doc . toVariant ( ) , bdoc . toVariant ( ) ) ;
QCOMPARE ( doc , bdoc ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : toAndFromBinary_data ( )
2012-01-18 09:12:50 +00:00
{
QTest : : addColumn < QString > ( " filename " ) ;
2012-02-15 04:22:48 +00:00
QTest : : newRow ( " test.json " ) < < ( testDataDir + " /test.json " ) ;
QTest : : newRow ( " test2.json " ) < < ( testDataDir + " /test2.json " ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : toAndFromBinary ( )
2012-01-18 09:12:50 +00:00
{
QFETCH ( QString , filename ) ;
QFile file ( filename ) ;
QVERIFY ( file . open ( QFile : : ReadOnly ) ) ;
QByteArray data = file . readAll ( ) ;
QJsonDocument doc = QJsonDocument : : fromJson ( data ) ;
QVERIFY ( ! doc . isNull ( ) ) ;
QJsonDocument outdoc = QJsonDocument : : fromBinaryData ( doc . toBinaryData ( ) ) ;
QVERIFY ( ! outdoc . isNull ( ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( doc , outdoc ) ;
2012-01-18 09:12:50 +00:00
}
2016-11-02 13:10:47 +00:00
void tst_QtJson : : invalidBinaryData ( )
{
QDir dir ( testDataDir + " /invalidBinaryData " ) ;
QFileInfoList files = dir . entryInfoList ( ) ;
for ( int i = 0 ; i < files . size ( ) ; + + i ) {
if ( ! files . at ( i ) . isFile ( ) )
continue ;
QFile file ( files . at ( i ) . filePath ( ) ) ;
file . open ( QIODevice : : ReadOnly ) ;
QByteArray bytes = file . readAll ( ) ;
QJsonDocument document = QJsonDocument : : fromRawData ( bytes . constData ( ) , bytes . size ( ) ) ;
QVERIFY ( document . isNull ( ) ) ;
}
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : parseNumbers ( )
2012-01-18 09:12:50 +00:00
{
{
// test number parsing
struct Numbers {
const char * str ;
int n ;
} ;
Numbers numbers [ ] = {
{ " 0 " , 0 } ,
{ " 1 " , 1 } ,
{ " 10 " , 10 } ,
{ " -1 " , - 1 } ,
{ " 100000 " , 100000 } ,
{ " -999 " , - 999 }
} ;
int size = sizeof ( numbers ) / sizeof ( Numbers ) ;
for ( int i = 0 ; i < size ; + + i ) {
QByteArray json = " [ " ;
json + = numbers [ i ] . str ;
json + = " ] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , true ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
QJsonArray array = doc . array ( ) ;
QCOMPARE ( array . size ( ) , 1 ) ;
QJsonValue val = array . at ( 0 ) ;
QCOMPARE ( val . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( val . toDouble ( ) , ( double ) numbers [ i ] . n ) ;
}
}
{
// test number parsing
struct Numbers {
const char * str ;
double n ;
} ;
Numbers numbers [ ] = {
{ " 0 " , 0 } ,
{ " 1 " , 1 } ,
{ " 10 " , 10 } ,
{ " -1 " , - 1 } ,
{ " 100000 " , 100000 } ,
{ " -999 " , - 999 } ,
{ " 1.1 " , 1.1 } ,
{ " 1e10 " , 1e10 } ,
{ " -1.1 " , - 1.1 } ,
{ " -1e10 " , - 1e10 } ,
{ " -1E10 " , - 1e10 } ,
{ " 1.1e10 " , 1.1e10 } ,
{ " 1.1e308 " , 1.1e308 } ,
{ " -1.1e308 " , - 1.1e308 } ,
{ " 1.1e-308 " , 1.1e-308 } ,
{ " -1.1e-308 " , - 1.1e-308 } ,
{ " 1.1e+308 " , 1.1e+308 } ,
{ " -1.1e+308 " , - 1.1e+308 } ,
{ " 1.e+308 " , 1.e+308 } ,
{ " -1.e+308 " , - 1.e+308 }
} ;
int size = sizeof ( numbers ) / sizeof ( Numbers ) ;
for ( int i = 0 ; i < size ; + + i ) {
QByteArray json = " [ " ;
json + = numbers [ i ] . str ;
json + = " ] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
2014-03-26 12:52:09 +00:00
# ifdef Q_OS_QNX
2014-02-26 08:18:35 +00:00
if ( 0 = = QString : : compare ( numbers [ i ] . str , " 1.1e-308 " ) )
QEXPECT_FAIL ( " " , " See QTBUG-37066 " , Abort ) ;
# endif
2012-01-18 09:12:50 +00:00
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , true ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
QJsonArray array = doc . array ( ) ;
QCOMPARE ( array . size ( ) , 1 ) ;
QJsonValue val = array . at ( 0 ) ;
QCOMPARE ( val . type ( ) , QJsonValue : : Double ) ;
QCOMPARE ( val . toDouble ( ) , numbers [ i ] . n ) ;
}
}
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : parseStrings ( )
2012-01-18 09:12:50 +00:00
{
const char * strings [ ] =
{
" Foo " ,
" abc \\ \" abc " ,
" abc \\ \\ abc " ,
" abc \\ babc " ,
" abc \\ fabc " ,
" abc \\ nabc " ,
" abc \\ rabc " ,
" abc \\ tabc " ,
" abc \\ u0019abc " ,
2012-02-23 11:24:49 +00:00
" abc " UNICODE_DJE " abc " ,
2013-10-06 09:40:47 +00:00
UNICODE_NON_CHARACTER
2012-01-18 09:12:50 +00:00
} ;
int size = sizeof ( strings ) / sizeof ( const char * ) ;
for ( int i = 0 ; i < size ; + + i ) {
QByteArray json = " [ \n \" " ;
json + = strings [ i ] ;
json + = " \" \n ] \n " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , true ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
QJsonArray array = doc . array ( ) ;
QCOMPARE ( array . size ( ) , 1 ) ;
QJsonValue val = array . at ( 0 ) ;
QCOMPARE ( val . type ( ) , QJsonValue : : String ) ;
QCOMPARE ( doc . toJson ( ) , json ) ;
}
struct Pairs {
const char * in ;
const char * out ;
} ;
Pairs pairs [ ] = {
{ " abc \\ /abc " , " abc/abc " } ,
2012-02-23 11:24:49 +00:00
{ " abc \\ u0402abc " , " abc " UNICODE_DJE " abc " } ,
2013-10-06 09:40:47 +00:00
{ " abc \\ u0065abc " , " abceabc " } ,
{ " abc \\ uFFFFabc " , " abc " UNICODE_NON_CHARACTER " abc " }
2012-01-18 09:12:50 +00:00
} ;
size = sizeof ( pairs ) / sizeof ( Pairs ) ;
for ( int i = 0 ; i < size ; + + i ) {
QByteArray json = " [ \n \" " ;
json + = pairs [ i ] . in ;
json + = " \" \n ] \n " ;
QByteArray out = " [ \n \" " ;
out + = pairs [ i ] . out ;
out + = " \" \n ] \n " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , true ) ;
QCOMPARE ( doc . isObject ( ) , false ) ;
QJsonArray array = doc . array ( ) ;
QCOMPARE ( array . size ( ) , 1 ) ;
QJsonValue val = array . at ( 0 ) ;
QCOMPARE ( val . type ( ) , QJsonValue : : String ) ;
QCOMPARE ( doc . toJson ( ) , out ) ;
}
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : parseDuplicateKeys ( )
2012-01-18 09:12:50 +00:00
{
const char * json = " { \" B \" : true, \" A \" : null, \" B \" : false } " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QCOMPARE ( doc . isObject ( ) , true ) ;
QJsonObject o = doc . object ( ) ;
QCOMPARE ( o . size ( ) , 2 ) ;
QJsonObject : : const_iterator it = o . constBegin ( ) ;
QCOMPARE ( it . key ( ) , QLatin1String ( " A " ) ) ;
QCOMPARE ( it . value ( ) , QJsonValue ( ) ) ;
+ + it ;
QCOMPARE ( it . key ( ) , QLatin1String ( " B " ) ) ;
QCOMPARE ( it . value ( ) , QJsonValue ( false ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testParser ( )
2012-01-18 09:12:50 +00:00
{
2012-02-15 04:22:48 +00:00
QFile file ( testDataDir + " /test.json " ) ;
2012-01-18 09:12:50 +00:00
file . open ( QFile : : ReadOnly ) ;
QByteArray testJson = file . readAll ( ) ;
QJsonDocument doc = QJsonDocument : : fromJson ( testJson ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : compactArray ( )
2012-01-18 09:12:50 +00:00
{
QJsonArray array ;
array . append ( QLatin1String ( " First Entry " ) ) ;
array . append ( QLatin1String ( " Second Entry " ) ) ;
array . append ( QLatin1String ( " Third Entry " ) ) ;
QJsonDocument doc ( array ) ;
int s = doc . toBinaryData ( ) . size ( ) ;
array . removeAt ( 1 ) ;
doc . setArray ( array ) ;
QVERIFY ( s > doc . toBinaryData ( ) . size ( ) ) ;
s = doc . toBinaryData ( ) . size ( ) ;
QCOMPARE ( doc . toJson ( ) ,
QByteArray ( " [ \n "
" \" First Entry \" , \n "
" \" Third Entry \" \n "
" ] \n " ) ) ;
array . removeAt ( 0 ) ;
doc . setArray ( array ) ;
QVERIFY ( s > doc . toBinaryData ( ) . size ( ) ) ;
s = doc . toBinaryData ( ) . size ( ) ;
QCOMPARE ( doc . toJson ( ) ,
QByteArray ( " [ \n "
" \" Third Entry \" \n "
" ] \n " ) ) ;
array . removeAt ( 0 ) ;
doc . setArray ( array ) ;
QVERIFY ( s > doc . toBinaryData ( ) . size ( ) ) ;
s = doc . toBinaryData ( ) . size ( ) ;
QCOMPARE ( doc . toJson ( ) ,
QByteArray ( " [ \n "
" ] \n " ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : compactObject ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject object ;
object . insert ( QLatin1String ( " Key1 " ) , QLatin1String ( " First Entry " ) ) ;
object . insert ( QLatin1String ( " Key2 " ) , QLatin1String ( " Second Entry " ) ) ;
object . insert ( QLatin1String ( " Key3 " ) , QLatin1String ( " Third Entry " ) ) ;
QJsonDocument doc ( object ) ;
int s = doc . toBinaryData ( ) . size ( ) ;
object . remove ( QLatin1String ( " Key2 " ) ) ;
doc . setObject ( object ) ;
QVERIFY ( s > doc . toBinaryData ( ) . size ( ) ) ;
s = doc . toBinaryData ( ) . size ( ) ;
QCOMPARE ( doc . toJson ( ) ,
QByteArray ( " { \n "
" \" Key1 \" : \" First Entry \" , \n "
" \" Key3 \" : \" Third Entry \" \n "
" } \n " ) ) ;
object . remove ( QLatin1String ( " Key1 " ) ) ;
doc . setObject ( object ) ;
QVERIFY ( s > doc . toBinaryData ( ) . size ( ) ) ;
s = doc . toBinaryData ( ) . size ( ) ;
QCOMPARE ( doc . toJson ( ) ,
QByteArray ( " { \n "
" \" Key3 \" : \" Third Entry \" \n "
" } \n " ) ) ;
object . remove ( QLatin1String ( " Key3 " ) ) ;
doc . setObject ( object ) ;
QVERIFY ( s > doc . toBinaryData ( ) . size ( ) ) ;
s = doc . toBinaryData ( ) . size ( ) ;
QCOMPARE ( doc . toJson ( ) ,
QByteArray ( " { \n "
" } \n " ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : validation ( )
2012-01-18 09:12:50 +00:00
{
// this basically tests that we don't crash on corrupt data
2012-02-15 04:22:48 +00:00
QFile file ( testDataDir + " /test.json " ) ;
2012-01-26 10:50:07 +00:00
QVERIFY ( file . open ( QFile : : ReadOnly ) ) ;
2012-01-18 09:12:50 +00:00
QByteArray testJson = file . readAll ( ) ;
2012-01-26 10:50:07 +00:00
QVERIFY ( ! testJson . isEmpty ( ) ) ;
2012-01-18 09:12:50 +00:00
QJsonDocument doc = QJsonDocument : : fromJson ( testJson ) ;
2012-01-26 11:12:44 +00:00
QVERIFY ( ! doc . isNull ( ) ) ;
2012-01-18 09:12:50 +00:00
QByteArray binary = doc . toBinaryData ( ) ;
// only test the first 1000 bytes. Testing the full file takes too long
for ( int i = 0 ; i < 1000 ; + + i ) {
QByteArray corrupted = binary ;
2012-02-22 08:26:27 +00:00
corrupted [ i ] = char ( 0xff ) ;
2012-01-18 09:12:50 +00:00
QJsonDocument doc = QJsonDocument : : fromBinaryData ( corrupted ) ;
if ( doc . isNull ( ) )
continue ;
QByteArray json = doc . toJson ( ) ;
}
2012-02-15 04:22:48 +00:00
QFile file2 ( testDataDir + " /test3.json " ) ;
2012-01-18 09:12:50 +00:00
file2 . open ( QFile : : ReadOnly ) ;
testJson = file2 . readAll ( ) ;
2012-01-26 11:12:44 +00:00
QVERIFY ( ! testJson . isEmpty ( ) ) ;
2012-01-18 09:12:50 +00:00
doc = QJsonDocument : : fromJson ( testJson ) ;
2012-01-26 11:12:44 +00:00
QVERIFY ( ! doc . isNull ( ) ) ;
2012-01-18 09:12:50 +00:00
binary = doc . toBinaryData ( ) ;
for ( int i = 0 ; i < binary . size ( ) ; + + i ) {
QByteArray corrupted = binary ;
2012-02-22 08:26:27 +00:00
corrupted [ i ] = char ( 0xff ) ;
2012-01-18 09:12:50 +00:00
QJsonDocument doc = QJsonDocument : : fromBinaryData ( corrupted ) ;
if ( doc . isNull ( ) )
continue ;
QByteArray json = doc . toJson ( ) ;
corrupted = binary ;
corrupted [ i ] = 0x00 ;
doc = QJsonDocument : : fromBinaryData ( corrupted ) ;
if ( doc . isNull ( ) )
continue ;
json = doc . toJson ( ) ;
}
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : assignToDocument ( )
2012-01-18 09:12:50 +00:00
{
{
const char * json = " { \" inner \" : { \" key \" : true } } " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QJsonObject o = doc . object ( ) ;
QJsonValue inner = o . value ( " inner " ) ;
QJsonDocument innerDoc ( inner . toObject ( ) ) ;
QVERIFY ( innerDoc ! = doc ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( innerDoc . object ( ) , inner . toObject ( ) ) ;
2012-01-18 09:12:50 +00:00
}
{
const char * json = " [ [ true ] ] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QJsonArray a = doc . array ( ) ;
QJsonValue inner = a . at ( 0 ) ;
QJsonDocument innerDoc ( inner . toArray ( ) ) ;
QVERIFY ( innerDoc ! = doc ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( innerDoc . array ( ) , inner . toArray ( ) ) ;
2012-01-18 09:12:50 +00:00
}
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testDuplicateKeys ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject obj ;
obj . insert ( QLatin1String ( " foo " ) , QLatin1String ( " bar " ) ) ;
obj . insert ( QLatin1String ( " foo " ) , QLatin1String ( " zap " ) ) ;
QCOMPARE ( obj . size ( ) , 1 ) ;
QCOMPARE ( obj . value ( QLatin1String ( " foo " ) ) . toString ( ) , QLatin1String ( " zap " ) ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testCompaction ( )
2012-01-18 09:12:50 +00:00
{
// modify object enough times to trigger compactionCounter
// and make sure the data is still valid
QJsonObject obj ;
for ( int i = 0 ; i < 33 ; + + i ) {
obj . remove ( QLatin1String ( " foo " ) ) ;
obj . insert ( QLatin1String ( " foo " ) , QLatin1String ( " bar " ) ) ;
}
QCOMPARE ( obj . size ( ) , 1 ) ;
QCOMPARE ( obj . value ( QLatin1String ( " foo " ) ) . toString ( ) , QLatin1String ( " bar " ) ) ;
QJsonDocument doc = QJsonDocument : : fromBinaryData ( QJsonDocument ( obj ) . toBinaryData ( ) ) ;
QVERIFY ( ! doc . isNull ( ) ) ;
QVERIFY ( ! doc . isEmpty ( ) ) ;
QCOMPARE ( doc . isArray ( ) , false ) ;
QCOMPARE ( doc . isObject ( ) , true ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( doc . object ( ) , obj ) ;
2012-01-18 09:12:50 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testDebugStream ( )
2012-01-18 09:12:50 +00:00
{
{
// QJsonObject
QJsonObject object ;
2013-10-16 13:59:27 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonObject() " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < object ;
object . insert ( QLatin1String ( " foo " ) , QLatin1String ( " bar " ) ) ;
2014-02-14 08:33:21 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonObject({ \" foo \" : \" bar \" }) " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < object ;
}
{
// QJsonArray
QJsonArray array ;
2013-10-16 13:59:27 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonArray() " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < array ;
array . append ( 1 ) ;
array . append ( QLatin1String ( " foo " ) ) ;
2013-10-16 13:59:27 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonArray([1, \" foo \" ]) " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < array ;
}
{
// QJsonDocument
QJsonDocument doc ;
2013-10-16 13:59:27 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonDocument() " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < doc ;
QJsonObject object ;
object . insert ( QLatin1String ( " foo " ) , QLatin1String ( " bar " ) ) ;
doc . setObject ( object ) ;
2014-02-14 08:33:21 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonDocument({ \" foo \" : \" bar \" }) " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < doc ;
QJsonArray array ;
array . append ( 1 ) ;
array . append ( QLatin1String ( " foo " ) ) ;
2013-10-16 13:59:27 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonDocument([1, \" foo \" ]) " ) ;
2012-01-18 09:12:50 +00:00
doc . setArray ( array ) ;
qDebug ( ) < < doc ;
}
{
// QJsonValue
QJsonValue value ;
2013-10-16 13:59:27 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonValue(null) " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < value ;
value = QJsonValue ( true ) ; // bool
2013-10-16 13:59:27 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonValue(bool, true) " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < value ;
value = QJsonValue ( ( double ) 4.2 ) ; // double
2013-10-16 13:59:27 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonValue(double, 4.2) " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < value ;
value = QJsonValue ( ( int ) 42 ) ; // int
2013-10-16 13:59:27 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonValue(double, 42) " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < value ;
value = QJsonValue ( QLatin1String ( " foo " ) ) ; // string
2013-10-16 13:59:27 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonValue(string, \" foo \" ) " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < value ;
QJsonArray array ;
array . append ( 1 ) ;
array . append ( QLatin1String ( " foo " ) ) ;
value = QJsonValue ( array ) ; // array
2015-01-23 15:19:11 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonValue(array, QJsonArray([1, \" foo \" ])) " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < value ;
QJsonObject object ;
object . insert ( QLatin1String ( " foo " ) , QLatin1String ( " bar " ) ) ;
value = QJsonValue ( object ) ; // object
2015-01-23 15:19:11 +00:00
QTest : : ignoreMessage ( QtDebugMsg , " QJsonValue(object, QJsonObject({ \" foo \" : \" bar \" })) " ) ;
2012-01-18 09:12:50 +00:00
qDebug ( ) < < value ;
}
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testCompactionError ( )
2012-01-18 09:12:50 +00:00
{
QJsonObject schemaObject ;
schemaObject . insert ( " _Type " , QLatin1String ( " _SchemaType " ) ) ;
schemaObject . insert ( " name " , QLatin1String ( " Address " ) ) ;
schemaObject . insert ( " schema " , QJsonObject ( ) ) ;
{
QJsonObject content ( schemaObject ) ;
QJsonDocument doc ( content ) ;
QVERIFY ( ! doc . isNull ( ) ) ;
QByteArray hash = QCryptographicHash : : hash ( doc . toBinaryData ( ) , QCryptographicHash : : Md5 ) . toHex ( ) ;
schemaObject . insert ( " _Version " , QString : : fromLatin1 ( hash . constData ( ) , hash . size ( ) ) ) ;
}
QJsonObject schema ;
schema . insert ( " streetNumber " , schema . value ( " number " ) . toObject ( ) ) ;
schemaObject . insert ( " schema " , schema ) ;
{
QJsonObject content ( schemaObject ) ;
content . remove ( " _Uuid " ) ;
content . remove ( " _Version " ) ;
QJsonDocument doc ( content ) ;
QVERIFY ( ! doc . isNull ( ) ) ;
QByteArray hash = QCryptographicHash : : hash ( doc . toBinaryData ( ) , QCryptographicHash : : Md5 ) . toHex ( ) ;
schemaObject . insert ( " _Version " , QString : : fromLatin1 ( hash . constData ( ) , hash . size ( ) ) ) ;
}
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : parseUnicodeEscapes ( )
2012-03-06 12:05:09 +00:00
{
const QByteArray json = " [ \" A \\ u00e4 \\ u00C4 \" ] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QJsonArray array = doc . array ( ) ;
QString result = QLatin1String ( " A " ) ;
result + = QChar ( 0xe4 ) ;
result + = QChar ( 0xc4 ) ;
QCOMPARE ( array . first ( ) . toString ( ) , result ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : assignObjects ( )
2012-03-08 09:41:55 +00:00
{
const char * json =
" [ { \" Key \" : 1 }, { \" Key \" : 2 } ] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QJsonArray array = doc . array ( ) ;
QJsonObject object = array . at ( 0 ) . toObject ( ) ;
QCOMPARE ( object . value ( " Key " ) . toDouble ( ) , 1. ) ;
object = array . at ( 1 ) . toObject ( ) ;
QCOMPARE ( object . value ( " Key " ) . toDouble ( ) , 2. ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : assignArrays ( )
2012-03-08 09:41:55 +00:00
{
const char * json =
" [ [ 1 ], [ 2 ] ] " ;
QJsonDocument doc = QJsonDocument : : fromJson ( json ) ;
QJsonArray array = doc . array ( ) ;
QJsonArray inner = array . at ( 0 ) . toArray ( ) ;
QCOMPARE ( inner . at ( 0 ) . toDouble ( ) , 1. ) ;
inner = array . at ( 1 ) . toArray ( ) ;
QCOMPARE ( inner . at ( 0 ) . toDouble ( ) , 2. ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testTrailingComma ( )
2012-03-12 18:33:39 +00:00
{
const char * jsons [ ] = { " { \" Key \" : 1, } " , " [ { \" Key \" : 1 }, ] " } ;
for ( unsigned i = 0 ; i < sizeof ( jsons ) / sizeof ( jsons [ 0 ] ) ; + + i ) {
QJsonParseError error ;
QJsonDocument doc = QJsonDocument : : fromJson ( jsons [ i ] , & error ) ;
QCOMPARE ( error . error , QJsonParseError : : MissingObject ) ;
}
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : testDetachBug ( )
2012-03-29 10:25:09 +00:00
{
QJsonObject dynamic ;
QJsonObject embedded ;
QJsonObject local ;
embedded . insert ( " Key1 " , QString ( " Value1 " ) ) ;
embedded . insert ( " Key2 " , QString ( " Value2 " ) ) ;
dynamic . insert ( QStringLiteral ( " Bogus " ) , QString ( " bogusValue " ) ) ;
dynamic . insert ( " embedded " , embedded ) ;
local = dynamic . value ( " embedded " ) . toObject ( ) ;
dynamic . remove ( " embedded " ) ;
QCOMPARE ( local . keys ( ) . size ( ) , 2 ) ;
local . remove ( " Key1 " ) ;
local . remove ( " Key2 " ) ;
QCOMPARE ( local . keys ( ) . size ( ) , 0 ) ;
local . insert ( " Key1 " , QString ( " anotherValue " ) ) ;
QCOMPARE ( local . keys ( ) . size ( ) , 1 ) ;
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : valueEquals ( )
2012-04-05 09:35:09 +00:00
{
2015-07-24 13:39:39 +00:00
QCOMPARE ( QJsonValue ( ) , QJsonValue ( ) ) ;
2012-04-05 09:35:09 +00:00
QVERIFY ( QJsonValue ( ) ! = QJsonValue ( QJsonValue : : Undefined ) ) ;
QVERIFY ( QJsonValue ( ) ! = QJsonValue ( true ) ) ;
QVERIFY ( QJsonValue ( ) ! = QJsonValue ( 1. ) ) ;
QVERIFY ( QJsonValue ( ) ! = QJsonValue ( QJsonArray ( ) ) ) ;
QVERIFY ( QJsonValue ( ) ! = QJsonValue ( QJsonObject ( ) ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( QJsonValue ( true ) , QJsonValue ( true ) ) ;
2012-04-05 09:35:09 +00:00
QVERIFY ( QJsonValue ( true ) ! = QJsonValue ( false ) ) ;
QVERIFY ( QJsonValue ( true ) ! = QJsonValue ( QJsonValue : : Undefined ) ) ;
QVERIFY ( QJsonValue ( true ) ! = QJsonValue ( ) ) ;
QVERIFY ( QJsonValue ( true ) ! = QJsonValue ( 1. ) ) ;
QVERIFY ( QJsonValue ( true ) ! = QJsonValue ( QJsonArray ( ) ) ) ;
QVERIFY ( QJsonValue ( true ) ! = QJsonValue ( QJsonObject ( ) ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( QJsonValue ( 1 ) , QJsonValue ( 1 ) ) ;
2013-08-22 14:25:13 +00:00
QVERIFY ( QJsonValue ( 1 ) ! = QJsonValue ( 2 ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( QJsonValue ( 1 ) , QJsonValue ( 1. ) ) ;
2013-08-22 14:25:13 +00:00
QVERIFY ( QJsonValue ( 1 ) ! = QJsonValue ( 1.1 ) ) ;
QVERIFY ( QJsonValue ( 1 ) ! = QJsonValue ( QJsonValue : : Undefined ) ) ;
QVERIFY ( QJsonValue ( 1 ) ! = QJsonValue ( ) ) ;
QVERIFY ( QJsonValue ( 1 ) ! = QJsonValue ( true ) ) ;
QVERIFY ( QJsonValue ( 1 ) ! = QJsonValue ( QJsonArray ( ) ) ) ;
QVERIFY ( QJsonValue ( 1 ) ! = QJsonValue ( QJsonObject ( ) ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( QJsonValue ( 1. ) , QJsonValue ( 1. ) ) ;
2012-04-05 09:35:09 +00:00
QVERIFY ( QJsonValue ( 1. ) ! = QJsonValue ( 2. ) ) ;
QVERIFY ( QJsonValue ( 1. ) ! = QJsonValue ( QJsonValue : : Undefined ) ) ;
QVERIFY ( QJsonValue ( 1. ) ! = QJsonValue ( ) ) ;
QVERIFY ( QJsonValue ( 1. ) ! = QJsonValue ( true ) ) ;
QVERIFY ( QJsonValue ( 1. ) ! = QJsonValue ( QJsonArray ( ) ) ) ;
QVERIFY ( QJsonValue ( 1. ) ! = QJsonValue ( QJsonObject ( ) ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( QJsonValue ( QJsonArray ( ) ) , QJsonValue ( QJsonArray ( ) ) ) ;
2012-04-05 09:35:09 +00:00
QJsonArray nonEmptyArray ;
nonEmptyArray . append ( true ) ;
QVERIFY ( QJsonValue ( QJsonArray ( ) ) ! = nonEmptyArray ) ;
QVERIFY ( QJsonValue ( QJsonArray ( ) ) ! = QJsonValue ( QJsonValue : : Undefined ) ) ;
QVERIFY ( QJsonValue ( QJsonArray ( ) ) ! = QJsonValue ( ) ) ;
QVERIFY ( QJsonValue ( QJsonArray ( ) ) ! = QJsonValue ( true ) ) ;
QVERIFY ( QJsonValue ( QJsonArray ( ) ) ! = QJsonValue ( 1. ) ) ;
QVERIFY ( QJsonValue ( QJsonArray ( ) ) ! = QJsonValue ( QJsonObject ( ) ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( QJsonValue ( QJsonObject ( ) ) , QJsonValue ( QJsonObject ( ) ) ) ;
2012-04-05 09:35:09 +00:00
QJsonObject nonEmptyObject ;
nonEmptyObject . insert ( " Key " , true ) ;
QVERIFY ( QJsonValue ( QJsonObject ( ) ) ! = nonEmptyObject ) ;
QVERIFY ( QJsonValue ( QJsonObject ( ) ) ! = QJsonValue ( QJsonValue : : Undefined ) ) ;
QVERIFY ( QJsonValue ( QJsonObject ( ) ) ! = QJsonValue ( ) ) ;
QVERIFY ( QJsonValue ( QJsonObject ( ) ) ! = QJsonValue ( true ) ) ;
QVERIFY ( QJsonValue ( QJsonObject ( ) ) ! = QJsonValue ( 1. ) ) ;
QVERIFY ( QJsonValue ( QJsonObject ( ) ) ! = QJsonValue ( QJsonArray ( ) ) ) ;
2014-01-04 22:59:32 +00:00
2015-07-24 13:39:39 +00:00
QCOMPARE ( QJsonValue ( " foo " ) , QJsonValue ( QLatin1String ( " foo " ) ) ) ;
QCOMPARE ( QJsonValue ( " foo " ) , QJsonValue ( QString ( " foo " ) ) ) ;
QCOMPARE ( QJsonValue ( " \x66 \x6f \x6f " ) , QJsonValue ( QString ( " foo " ) ) ) ;
QCOMPARE ( QJsonValue ( " \x62 \x61 \x72 " ) , QJsonValue ( " bar " ) ) ;
QCOMPARE ( QJsonValue ( UNICODE_NON_CHARACTER ) , QJsonValue ( QString ( UNICODE_NON_CHARACTER ) ) ) ;
QCOMPARE ( QJsonValue ( UNICODE_DJE ) , QJsonValue ( QString ( UNICODE_DJE ) ) ) ;
QCOMPARE ( QJsonValue ( " \xc3 \xa9 " ) , QJsonValue ( QString ( " \xc3 \xa9 " ) ) ) ;
2012-04-05 09:35:09 +00:00
}
2014-06-26 11:02:54 +00:00
void tst_QtJson : : objectEquals_data ( )
{
QTest : : addColumn < QJsonObject > ( " left " ) ;
QTest : : addColumn < QJsonObject > ( " right " ) ;
QTest : : addColumn < bool > ( " result " ) ;
QTest : : newRow ( " two defaults " ) < < QJsonObject ( ) < < QJsonObject ( ) < < true ;
QJsonObject object1 ;
object1 . insert ( " property " , 1 ) ;
QJsonObject object2 ;
object2 [ " property " ] = 1 ;
QJsonObject object3 ;
object3 . insert ( " property1 " , 1 ) ;
object3 . insert ( " property2 " , 2 ) ;
QTest : : newRow ( " the same object (1 vs 2) " ) < < object1 < < object2 < < true ;
QTest : : newRow ( " the same object (3 vs 3) " ) < < object3 < < object3 < < true ;
QTest : : newRow ( " different objects (2 vs 3) " ) < < object2 < < object3 < < false ;
QTest : : newRow ( " object vs default " ) < < object1 < < QJsonObject ( ) < < false ;
QJsonObject empty ;
empty . insert ( " property " , 1 ) ;
empty . take ( " property " ) ;
QTest : : newRow ( " default vs empty " ) < < QJsonObject ( ) < < empty < < true ;
QTest : : newRow ( " empty vs empty " ) < < empty < < empty < < true ;
QTest : : newRow ( " object vs empty " ) < < object1 < < empty < < false ;
QJsonObject referencedEmpty ;
referencedEmpty [ " undefined " ] ;
QTest : : newRow ( " referenced empty vs referenced empty " ) < < referencedEmpty < < referencedEmpty < < true ;
QTest : : newRow ( " referenced empty vs object " ) < < referencedEmpty < < object1 < < false ;
QJsonObject referencedObject1 ;
referencedObject1 . insert ( " property " , 1 ) ;
referencedObject1 [ " undefined " ] ;
QJsonObject referencedObject2 ;
referencedObject2 . insert ( " property " , 1 ) ;
referencedObject2 [ " aaaaaaaaa " ] ; // earlier then "property"
referencedObject2 [ " zzzzzzzzz " ] ; // after "property"
QTest : : newRow ( " referenced object vs default " ) < < referencedObject1 < < QJsonObject ( ) < < false ;
QTest : : newRow ( " referenced object vs referenced object " ) < < referencedObject1 < < referencedObject1 < < true ;
QTest : : newRow ( " referenced object vs object (different) " ) < < referencedObject1 < < object3 < < false ;
}
void tst_QtJson : : objectEquals ( )
{
QFETCH ( QJsonObject , left ) ;
QFETCH ( QJsonObject , right ) ;
QFETCH ( bool , result ) ;
2014-06-26 11:14:25 +00:00
QCOMPARE ( left = = right , result ) ;
QCOMPARE ( right = = left , result ) ;
2014-06-26 11:02:54 +00:00
// invariants checks
QCOMPARE ( left , left ) ;
QCOMPARE ( right , right ) ;
2014-06-26 11:14:25 +00:00
QCOMPARE ( left ! = right , ! result ) ;
QCOMPARE ( right ! = left , ! result ) ;
2014-07-08 12:56:25 +00:00
// The same but from QJsonValue perspective
QCOMPARE ( QJsonValue ( left ) = = QJsonValue ( right ) , result ) ;
QCOMPARE ( QJsonValue ( left ) ! = QJsonValue ( right ) , ! result ) ;
QCOMPARE ( QJsonValue ( right ) = = QJsonValue ( left ) , result ) ;
QCOMPARE ( QJsonValue ( right ) ! = QJsonValue ( left ) , ! result ) ;
}
void tst_QtJson : : arrayEquals_data ( )
{
QTest : : addColumn < QJsonArray > ( " left " ) ;
QTest : : addColumn < QJsonArray > ( " right " ) ;
QTest : : addColumn < bool > ( " result " ) ;
QTest : : newRow ( " two defaults " ) < < QJsonArray ( ) < < QJsonArray ( ) < < true ;
QJsonArray array1 ;
array1 . append ( 1 ) ;
QJsonArray array2 ;
array2 . append ( 2111 ) ;
array2 [ 0 ] = 1 ;
QJsonArray array3 ;
array3 . insert ( 0 , 1 ) ;
array3 . insert ( 1 , 2 ) ;
QTest : : newRow ( " the same array (1 vs 2) " ) < < array1 < < array2 < < true ;
QTest : : newRow ( " the same array (3 vs 3) " ) < < array3 < < array3 < < true ;
QTest : : newRow ( " different arrays (2 vs 3) " ) < < array2 < < array3 < < false ;
QTest : : newRow ( " array vs default " ) < < array1 < < QJsonArray ( ) < < false ;
QJsonArray empty ;
empty . append ( 1 ) ;
empty . takeAt ( 0 ) ;
QTest : : newRow ( " default vs empty " ) < < QJsonArray ( ) < < empty < < true ;
QTest : : newRow ( " empty vs default " ) < < empty < < QJsonArray ( ) < < true ;
QTest : : newRow ( " empty vs empty " ) < < empty < < empty < < true ;
QTest : : newRow ( " array vs empty " ) < < array1 < < empty < < false ;
}
void tst_QtJson : : arrayEquals ( )
{
QFETCH ( QJsonArray , left ) ;
QFETCH ( QJsonArray , right ) ;
QFETCH ( bool , result ) ;
QCOMPARE ( left = = right , result ) ;
QCOMPARE ( right = = left , result ) ;
// invariants checks
QCOMPARE ( left , left ) ;
QCOMPARE ( right , right ) ;
QCOMPARE ( left ! = right , ! result ) ;
QCOMPARE ( right ! = left , ! result ) ;
2014-06-26 11:14:25 +00:00
// The same but from QJsonValue perspective
QCOMPARE ( QJsonValue ( left ) = = QJsonValue ( right ) , result ) ;
QCOMPARE ( QJsonValue ( left ) ! = QJsonValue ( right ) , ! result ) ;
QCOMPARE ( QJsonValue ( right ) = = QJsonValue ( left ) , result ) ;
QCOMPARE ( QJsonValue ( right ) ! = QJsonValue ( left ) , ! result ) ;
2014-06-26 11:02:54 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : bom ( )
2012-05-10 11:24:28 +00:00
{
QFile file ( testDataDir + " /bom.json " ) ;
file . open ( QFile : : ReadOnly ) ;
QByteArray json = file . readAll ( ) ;
// Import json document into a QJsonDocument
QJsonParseError error ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( ! doc . isNull ( ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( error . error , QJsonParseError : : NoError ) ;
2012-05-10 11:24:28 +00:00
}
2012-10-22 10:39:02 +00:00
void tst_QtJson : : nesting ( )
2012-05-12 10:09:35 +00:00
{
// check that we abort parsing too deeply nested json documents.
// this is to make sure we don't crash because the parser exhausts the
// stack.
const char * array_data =
" [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "
" [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "
" [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "
" [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "
" [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "
" [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "
" [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "
" [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "
" ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] "
" ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] "
" ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] "
" ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] "
" ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] "
" ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] "
" ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] "
" ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] " ;
QByteArray json ( array_data ) ;
QJsonParseError error ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( ! doc . isNull ( ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( error . error , QJsonParseError : : NoError ) ;
2012-05-12 10:09:35 +00:00
2015-10-13 07:46:56 +00:00
json . prepend ( ' [ ' ) ;
json . append ( ' ] ' ) ;
2012-05-12 10:09:35 +00:00
doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isNull ( ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( error . error , QJsonParseError : : DeepNesting ) ;
2012-05-12 10:09:35 +00:00
json = QByteArray ( " true " ) ;
for ( int i = 0 ; i < 1024 ; + + i ) {
json . prepend ( " { \" Key \" : " ) ;
json . append ( " } " ) ;
}
doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( ! doc . isNull ( ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( error . error , QJsonParseError : : NoError ) ;
2012-05-12 10:09:35 +00:00
2015-10-13 07:46:56 +00:00
json . prepend ( ' [ ' ) ;
json . append ( ' ] ' ) ;
2012-05-12 10:09:35 +00:00
doc = QJsonDocument : : fromJson ( json , & error ) ;
QVERIFY ( doc . isNull ( ) ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( error . error , QJsonParseError : : DeepNesting ) ;
2012-05-12 10:09:35 +00:00
}
2013-05-22 07:53:39 +00:00
void tst_QtJson : : longStrings ( )
{
// test around 15 and 16 bit boundaries, as these are limits
// in the data structures (for Latin1String in qjson_p.h)
QString s ( 0x7ff0 , ' a ' ) ;
for ( int i = 0x7ff0 ; i < 0x8010 ; i + + ) {
2015-10-13 07:46:56 +00:00
s . append ( QLatin1Char ( ' c ' ) ) ;
2013-05-22 07:53:39 +00:00
QMap < QString , QVariant > map ;
map [ " key " ] = s ;
/* Create a QJsonDocument from the QMap ... */
QJsonDocument d1 = QJsonDocument : : fromVariant ( QVariant ( map ) ) ;
/* ... and a QByteArray from the QJsonDocument */
QByteArray a1 = d1 . toJson ( ) ;
/* Create a QJsonDocument from the QByteArray ... */
QJsonDocument d2 = QJsonDocument : : fromJson ( a1 ) ;
/* ... and a QByteArray from the QJsonDocument */
QByteArray a2 = d2 . toJson ( ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( a1 , a2 ) ;
2013-05-22 07:53:39 +00:00
}
s = QString ( 0xfff0 , ' a ' ) ;
for ( int i = 0xfff0 ; i < 0x10010 ; i + + ) {
2015-10-13 07:46:56 +00:00
s . append ( QLatin1Char ( ' c ' ) ) ;
2013-05-22 07:53:39 +00:00
QMap < QString , QVariant > map ;
map [ " key " ] = s ;
/* Create a QJsonDocument from the QMap ... */
QJsonDocument d1 = QJsonDocument : : fromVariant ( QVariant ( map ) ) ;
/* ... and a QByteArray from the QJsonDocument */
QByteArray a1 = d1 . toJson ( ) ;
/* Create a QJsonDocument from the QByteArray ... */
QJsonDocument d2 = QJsonDocument : : fromJson ( a1 ) ;
/* ... and a QByteArray from the QJsonDocument */
QByteArray a2 = d2 . toJson ( ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( a1 , a2 ) ;
2013-05-22 07:53:39 +00:00
}
}
2014-06-10 08:41:28 +00:00
void tst_QtJson : : testJsonValueRefDefault ( )
{
QJsonObject empty ;
QCOMPARE ( empty [ " n/a " ] . toString ( ) , QString ( ) ) ;
QCOMPARE ( empty [ " n/a " ] . toString ( " default " ) , QStringLiteral ( " default " ) ) ;
QCOMPARE ( empty [ " n/a " ] . toBool ( ) , false ) ;
QCOMPARE ( empty [ " n/a " ] . toBool ( true ) , true ) ;
QCOMPARE ( empty [ " n/a " ] . toInt ( ) , 0 ) ;
QCOMPARE ( empty [ " n/a " ] . toInt ( 42 ) , 42 ) ;
QCOMPARE ( empty [ " n/a " ] . toDouble ( ) , 0.0 ) ;
QCOMPARE ( empty [ " n/a " ] . toDouble ( 42.0 ) , 42.0 ) ;
}
2014-05-21 10:28:27 +00:00
void tst_QtJson : : arrayInitializerList ( )
{
# ifndef Q_COMPILER_INITIALIZER_LISTS
QSKIP ( " initializer_list is enabled only with c++11 support " ) ;
# else
QVERIFY ( QJsonArray { } . isEmpty ( ) ) ;
QCOMPARE ( QJsonArray { " one " } . count ( ) , 1 ) ;
QCOMPARE ( QJsonArray { 1 } . count ( ) , 1 ) ;
{
QJsonArray a { 1.3 , " hello " , 0 } ;
QCOMPARE ( QJsonValue ( a [ 0 ] ) , QJsonValue ( 1.3 ) ) ;
QCOMPARE ( QJsonValue ( a [ 1 ] ) , QJsonValue ( " hello " ) ) ;
QCOMPARE ( QJsonValue ( a [ 2 ] ) , QJsonValue ( 0 ) ) ;
QCOMPARE ( a . count ( ) , 3 ) ;
}
{
QJsonObject o ;
o [ " property " ] = 1 ;
QJsonArray a1 { o } ;
QCOMPARE ( a1 . count ( ) , 1 ) ;
QCOMPARE ( a1 [ 0 ] . toObject ( ) , o ) ;
QJsonArray a2 { o , 23 } ;
QCOMPARE ( a2 . count ( ) , 2 ) ;
QCOMPARE ( a2 [ 0 ] . toObject ( ) , o ) ;
QCOMPARE ( QJsonValue ( a2 [ 1 ] ) , QJsonValue ( 23 ) ) ;
QJsonArray a3 { a1 , o , a2 } ;
QCOMPARE ( QJsonValue ( a3 [ 0 ] ) , QJsonValue ( a1 ) ) ;
QCOMPARE ( QJsonValue ( a3 [ 1 ] ) , QJsonValue ( o ) ) ;
QCOMPARE ( QJsonValue ( a3 [ 2 ] ) , QJsonValue ( a2 ) ) ;
2014-05-21 14:22:49 +00:00
QJsonArray a4 { 1 , QJsonArray { 1 , 2 , 3 } , QJsonArray { " hello " , 2 } , QJsonObject { { " one " , 1 } } } ;
QCOMPARE ( a4 . count ( ) , 4 ) ;
2014-05-21 10:28:27 +00:00
QCOMPARE ( QJsonValue ( a4 [ 0 ] ) , QJsonValue ( 1 ) ) ;
{
QJsonArray a41 = a4 [ 1 ] . toArray ( ) ;
QJsonArray a42 = a4 [ 2 ] . toArray ( ) ;
2014-05-21 14:22:49 +00:00
QJsonObject a43 = a4 [ 3 ] . toObject ( ) ;
2014-05-21 10:28:27 +00:00
QCOMPARE ( a41 . count ( ) , 3 ) ;
QCOMPARE ( a42 . count ( ) , 2 ) ;
2014-05-21 14:22:49 +00:00
QCOMPARE ( a43 . count ( ) , 1 ) ;
2014-05-21 10:28:27 +00:00
QCOMPARE ( QJsonValue ( a41 [ 2 ] ) , QJsonValue ( 3 ) ) ;
QCOMPARE ( QJsonValue ( a42 [ 1 ] ) , QJsonValue ( 2 ) ) ;
2014-05-21 14:22:49 +00:00
QCOMPARE ( QJsonValue ( a43 [ " one " ] ) , QJsonValue ( 1 ) ) ;
2014-05-21 10:28:27 +00:00
}
}
# endif
}
2014-05-21 14:22:49 +00:00
void tst_QtJson : : objectInitializerList ( )
{
# ifndef Q_COMPILER_INITIALIZER_LISTS
QSKIP ( " initializer_list is enabled only with c++11 support " ) ;
# else
QVERIFY ( QJsonObject { } . isEmpty ( ) ) ;
{ // one property
QJsonObject one { { " one " , 1 } } ;
QCOMPARE ( one . count ( ) , 1 ) ;
QVERIFY ( one . contains ( " one " ) ) ;
QCOMPARE ( QJsonValue ( one [ " one " ] ) , QJsonValue ( 1 ) ) ;
}
{ // two properties
QJsonObject two {
{ " one " , 1 } ,
{ " two " , 2 }
} ;
QCOMPARE ( two . count ( ) , 2 ) ;
QVERIFY ( two . contains ( " one " ) ) ;
QVERIFY ( two . contains ( " two " ) ) ;
QCOMPARE ( QJsonValue ( two [ " one " ] ) , QJsonValue ( 1 ) ) ;
QCOMPARE ( QJsonValue ( two [ " two " ] ) , QJsonValue ( 2 ) ) ;
}
{ // nested object
QJsonObject object { { " nested " , QJsonObject { { " innerProperty " , 2 } } } } ;
QCOMPARE ( object . count ( ) , 1 ) ;
QVERIFY ( object . contains ( " nested " ) ) ;
QVERIFY ( object [ " nested " ] . isObject ( ) ) ;
QJsonObject nested = object [ " nested " ] . toObject ( ) ;
QCOMPARE ( QJsonValue ( nested [ " innerProperty " ] ) , QJsonValue ( 2 ) ) ;
}
{ // nested array
QJsonObject object { { " nested " , QJsonArray { " innerValue " , 2.1 , " bum cyk cyk " } } } ;
QCOMPARE ( object . count ( ) , 1 ) ;
QVERIFY ( object . contains ( " nested " ) ) ;
QVERIFY ( object [ " nested " ] . isArray ( ) ) ;
QJsonArray nested = object [ " nested " ] . toArray ( ) ;
QCOMPARE ( nested . count ( ) , 3 ) ;
QCOMPARE ( QJsonValue ( nested [ 0 ] ) , QJsonValue ( " innerValue " ) ) ;
QCOMPARE ( QJsonValue ( nested [ 1 ] ) , QJsonValue ( 2.1 ) ) ;
}
# endif
}
2014-09-05 10:58:19 +00:00
void tst_QtJson : : unicodeKeys ( )
{
QByteArray json = " { "
2014-09-23 11:32:40 +00:00
" \" x \\ u2090_1 \" : \" hello_1 \" , "
" \" y \\ u2090_2 \" : \" hello_2 \" , "
" \" T \\ u2090_3 \" : \" hello_3 \" , "
2014-09-05 10:58:19 +00:00
" \" xyz_4 \" : \" hello_4 \" , "
" \" abc_5 \" : \" hello_5 \" "
" } " ;
QJsonParseError error ;
QJsonDocument doc = QJsonDocument : : fromJson ( json , & error ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( error . error , QJsonParseError : : NoError ) ;
2014-09-05 10:58:19 +00:00
QJsonObject o = doc . object ( ) ;
QCOMPARE ( o . keys ( ) . size ( ) , 5 ) ;
Q_FOREACH ( const QString & key , o . keys ( ) ) {
QString suffix = key . mid ( key . indexOf ( QLatin1Char ( ' _ ' ) ) ) ;
QCOMPARE ( o [ key ] . toString ( ) , QString ( " hello " ) + suffix ) ;
}
}
2014-09-05 11:26:16 +00:00
void tst_QtJson : : garbageAtEnd ( )
{
QJsonParseError error ;
QJsonDocument doc = QJsonDocument : : fromJson ( " {}, " , & error ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( error . error , QJsonParseError : : GarbageAtEnd ) ;
QCOMPARE ( error . offset , 2 ) ;
2014-09-05 11:26:16 +00:00
QVERIFY ( doc . isEmpty ( ) ) ;
doc = QJsonDocument : : fromJson ( " {} " , & error ) ;
2015-07-24 13:39:39 +00:00
QCOMPARE ( error . error , QJsonParseError : : NoError ) ;
2014-09-05 11:26:16 +00:00
QVERIFY ( ! doc . isEmpty ( ) ) ;
}
2015-03-17 15:01:05 +00:00
void tst_QtJson : : removeNonLatinKey ( )
{
const QString nonLatinKeyName = QString : : fromUtf8 ( " А тр иб у т100500" ) ;
QJsonObject sourceObject ;
sourceObject . insert ( " code " , 1 ) ;
sourceObject . remove ( " code " ) ;
sourceObject . insert ( nonLatinKeyName , 1 ) ;
const QByteArray json = QJsonDocument ( sourceObject ) . toJson ( ) ;
const QJsonObject restoredObject = QJsonDocument : : fromJson ( json ) . object ( ) ;
QCOMPARE ( sourceObject . keys ( ) , restoredObject . keys ( ) ) ;
QVERIFY ( sourceObject . contains ( nonLatinKeyName ) ) ;
QVERIFY ( restoredObject . contains ( nonLatinKeyName ) ) ;
}
2012-10-22 10:39:02 +00:00
QTEST_MAIN ( tst_QtJson )
2012-01-18 09:12:50 +00:00
# include "tst_qtjson.moc"