diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2009-06-22 23:18:10 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2009-06-22 23:18:10 (GMT) |
commit | c7fcd4b772092cf0764cfd97463c3aa3d7cc9e9f (patch) | |
tree | 836c2dacbfa3d55c07ab8242f57efd79e3deeeec /tests | |
parent | 631351d8b5699520267a80599a57e27f97b53d23 (diff) | |
parent | 308ed3913b406c43dfdab4fa734a332863dc4cbc (diff) | |
download | Qt-c7fcd4b772092cf0764cfd97463c3aa3d7cc9e9f.zip Qt-c7fcd4b772092cf0764cfd97463c3aa3d7cc9e9f.tar.gz Qt-c7fcd4b772092cf0764cfd97463c3aa3d7cc9e9f.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt into kinetic-declarativeui
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/qpainter/tst_qpainter.cpp | 21 | ||||
-rw-r--r-- | tests/auto/qsqldatabase/tst_databases.h | 42 | ||||
-rw-r--r-- | tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 22 | ||||
-rw-r--r-- | tests/auto/qsqldriver/qsqldriver.pro | 16 | ||||
-rw-r--r-- | tests/auto/qsqldriver/tst_qsqldriver.cpp | 218 | ||||
-rw-r--r-- | tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp | 455 | ||||
-rw-r--r-- | tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp | 15 | ||||
-rw-r--r-- | tests/auto/qstatemachine/tst_qstatemachine.cpp | 49 | ||||
-rw-r--r-- | tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 272 |
9 files changed, 1034 insertions, 76 deletions
diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index 7e42da8..5e5bd39 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -202,6 +202,7 @@ private slots: void drawImage_task217400_data(); void drawImage_task217400(); + void drawImage_1x1(); void drawRect_task215378(); void drawRect_task247505(); @@ -4237,5 +4238,25 @@ void tst_QPainter::emptyClip() p.fillPath(path, Qt::green); } +void tst_QPainter::drawImage_1x1() +{ + QImage source(1, 1, QImage::Format_ARGB32_Premultiplied); + source.fill(0xffffffff); + + QImage img(32, 32, QImage::Format_ARGB32_Premultiplied); + img.fill(0xff000000); + QPainter p(&img); + p.drawImage(QRectF(0.9, 0.9, 32, 32), source); + p.end(); + + QImage expected = img; + expected.fill(0xff000000); + p.begin(&expected); + p.fillRect(1, 1, 31, 31, Qt::white); + p.end(); + + QCOMPARE(img, expected); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index 77d1d5b..a490a2f 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -105,11 +105,7 @@ inline static QString qTableName( const QString& prefix, QSqlDriver* driver = 0 inline static bool testWhiteSpaceNames( const QString &name ) { -/* return name.startsWith( "QPSQL" ) - || name.startsWith( "QODBC" ) - || name.startsWith( "QSQLITE" ) - || name.startsWith( "QMYSQL" );*/ - return name != QLatin1String("QSQLITE2"); + return name != QLatin1String("QTDS7"); } inline static QString toHex( const QString& binary ) @@ -211,7 +207,7 @@ public: // This requires a local ODBC data source to be configured( pointing to a MySql database ) // addDb( "QODBC", "mysqlodbc", "troll", "trond" ); // addDb( "QODBC", "SqlServer", "troll", "trond" ); -// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead.nokia.troll.no" ); +// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead" ); // addDb( "QODBC", "silencetestdb", "troll", "trond", "silence" ); // addDb( "QODBC", "horseheadtestdb", "troll", "trondk", "horsehead" ); @@ -221,7 +217,7 @@ public: // addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3309, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 5.0.18 Linux // addDb( "QMYSQL3", "testdb", "troll", "trond", "iceblink.nokia.troll.no" ); // MySQL 5.0.13 Windows // addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql4-nokia.trolltech.com.au" ); // MySQL 4.1.22-2.el4 linux -// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux +// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux // addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no" ); // V7.2 NOT SUPPORTED! // addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5434 ); // V7.2 NOT SUPPORTED! Multi-byte @@ -242,17 +238,17 @@ public: // addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird2-nokia.trolltech.com.au" ); // Firebird 2.1.1 // use in-memory database to prevent local files -// addDb("QSQLITE", ":memory:"); - addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); + addDb("QSQLITE", ":memory:"); +// addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); // addDb( "QSQLITE2", QDir::toNativeSeparators(QDir::tempPath()+"/foo2.db") ); // addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.nokia.troll.no\\ICEBLINK", "troll", "trond", "" ); // addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" ); // addDb( "QODBC", "DRIVER={MySQL ODBC 3.51 Driver};SERVER=mysql5-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond", "troll", "trond", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_", "testuser", "Ee4Gabf6_", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_", "testuser", "Ee4Gabf6_", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk;TDS_Version=8.0", "troll", "trondk", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond;TDS_Version=8.0", "troll", "trond", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "testuser", "Ee4Gabf6_", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "testuser", "Ee4Gabf6_", "" ); // addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2003" ); // addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2008" ); } @@ -320,16 +316,18 @@ public: QSqlQuery q( db ); QStringList dbtables=db.tables(); - foreach(const QString &tableName, tableNames) { + foreach(QString tableName, tableNames) + { wasDropped = true; - foreach(const QString dbtablesName, dbtables) { - if(dbtablesName.toUpper() == tableName.toUpper()) { - dbtables.removeAll(dbtablesName); - wasDropped = q.exec("drop table " + db.driver()->escapeIdentifier( dbtablesName, QSqlDriver::TableName )); - if(!wasDropped) - wasDropped = q.exec("drop table " + dbtablesName); - } - } + QString table=tableName; + if ( db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName)) + table = db.driver()->stripDelimiters(table, QSqlDriver::TableName); + + if ( dbtables.contains( table, Qt::CaseSensitive ) ) + wasDropped = q.exec( "drop table " + tableName); + else if ( dbtables.contains( table, Qt::CaseInsensitive ) ) + wasDropped = q.exec( "drop table " + tableName); + if ( !wasDropped ) qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError().text() << "tables:" << dbtables; } diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 13ec263..cce4602 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -1625,7 +1625,7 @@ void tst_QSqlDatabase::precisionPolicy() q.bindValue(1, 123); QVERIFY_SQL(q, exec()); q.bindValue(0, 2); - q.bindValue(1, QString("1850000000000.0001")); + q.bindValue(1, 1850000000000.0001); QVERIFY_SQL(q, exec()); // These are expected to pass @@ -1633,29 +1633,39 @@ void tst_QSqlDatabase::precisionPolicy() QString query = QString("SELECT num FROM %1 WHERE id = 1").arg(tableName); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::String); q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(q.value(0).type() != QVariant::LongLong) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::LongLong); QCOMPARE(q.value(0).toLongLong(), (qlonglong)123); q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt32); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::Int); QCOMPARE(q.value(0).toInt(), 123); q.setNumericalPrecisionPolicy(QSql::LowPrecisionDouble); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::Double); QCOMPARE(q.value(0).toDouble(), (double)123); query = QString("SELECT num FROM %1 WHERE id = 2").arg(tableName); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::Double); QCOMPARE(q.value(0).toDouble(), QString("1850000000000.0001").toDouble()); @@ -1663,21 +1673,27 @@ void tst_QSqlDatabase::precisionPolicy() q.setNumericalPrecisionPolicy(QSql::HighPrecision); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::String); q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64); QEXPECT_FAIL("QOCI", "Oracle fails here, to retrieve next", Continue); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::LongLong); QSql::NumericalPrecisionPolicy oldPrecision= db.numericalPrecisionPolicy(); - db.setNumericalPrecisionPolicy(QSql::LowPrecisionDouble); + db.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64); QSqlQuery q2(db); q2.exec(QString("SELECT num FROM %1 WHERE id = 2").arg(tableName)); QVERIFY_SQL(q2, exec(query)); QVERIFY_SQL(q2, next()); - QCOMPARE(q2.value(0).type(), QVariant::Double); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); + QCOMPARE(q2.value(0).type(), QVariant::LongLong); db.setNumericalPrecisionPolicy(oldPrecision); } diff --git a/tests/auto/qsqldriver/qsqldriver.pro b/tests/auto/qsqldriver/qsqldriver.pro new file mode 100644 index 0000000..0024841 --- /dev/null +++ b/tests/auto/qsqldriver/qsqldriver.pro @@ -0,0 +1,16 @@ +load(qttest_p4) +SOURCES += tst_qsqldriver.cpp + +QT += sql + +wince*: { + plugFiles.sources = ../../../plugins/sqldrivers + plugFiles.path = . + DEPLOYMENT += plugFiles +} else { + win32-g++ { + LIBS += -lws2_32 + } else:win32 { + LIBS += ws2_32.lib + } +} diff --git a/tests/auto/qsqldriver/tst_qsqldriver.cpp b/tests/auto/qsqldriver/tst_qsqldriver.cpp new file mode 100644 index 0000000..bbd7483 --- /dev/null +++ b/tests/auto/qsqldriver/tst_qsqldriver.cpp @@ -0,0 +1,218 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <QtSql/QtSql> + +#include "../qsqldatabase/tst_databases.h" + + + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QSqlDriver : public QObject +{ + Q_OBJECT + +public: + void recreateTestTables(QSqlDatabase); + + tst_Databases dbs; + +public slots: + void initTestCase_data(); + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void record(); + void primaryIndex(); +}; + + +void tst_QSqlDriver::initTestCase_data() +{ + dbs.open(); + if (dbs.fillTestTable() == 0) { + qWarning("NO DATABASES"); + QSKIP("No database drivers are available in this Qt configuration", SkipAll); + } +} + +void tst_QSqlDriver::recreateTestTables(QSqlDatabase db) +{ + QSqlQuery q(db); + + QStringList tableNames; + tableNames << qTableName( "relTEST1" ); + tst_Databases::safeDropTables( db, tableNames ); + + QVERIFY_SQL( q, exec("create table " + qTableName("relTEST1") + + " (id int not null primary key, name varchar(20), title_key int, another_title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(1, 'harry', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(2, 'trond', 2, 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(3, 'vohi', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(4, 'boris', 2, 2)")); +} + +void tst_QSqlDriver::initTestCase() +{ + foreach (const QString &dbname, dbs.dbNames) + recreateTestTables(QSqlDatabase::database(dbname)); +} + +void tst_QSqlDriver::cleanupTestCase() +{ + QStringList tableNames; + tableNames << qTableName( "relTEST1" ); + foreach (const QString &dbName, dbs.dbNames) { + QSqlDatabase db = QSqlDatabase::database(dbName); + tst_Databases::safeDropTables( db, tableNames ); + } + dbs.close(); +} + +void tst_QSqlDriver::init() +{ +} + +void tst_QSqlDriver::cleanup() +{ +} + +void tst_QSqlDriver::record() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QString tablename = qTableName("relTEST1"); + QStringList fields; + fields << "id" << "name" << "title_key" << "another_title_key"; + + //check we can get records using an unquoted mixed case table name + QSqlRecord rec = db.driver()->record(tablename); + QCOMPARE(rec.count(), 4); + + if (db.driverName().startsWith("QIBASE")|| db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + for(int i = 0; i < fields.count(); ++i) + fields[i] = fields[i].toUpper(); + + for (int i = 0; i < fields.count(); ++i) + QCOMPARE(rec.fieldName(i), fields[i]); + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toUpper(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toLower(); + + //check we can get records using a properly quoted table name + rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); + QCOMPARE(rec.count(), 4); + + for (int i = 0; i < fields.count(); ++i) + QCOMPARE(rec.fieldName(i), fields[i]); + + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toLower(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toUpper(); + + //check that we can't get records using incorrect tablename casing that's been quoted + rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); + if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) + QCOMPARE(rec.count(), 4); //mysql, sqlite and tds will match + else + QCOMPARE(rec.count(), 0); + +} + +void tst_QSqlDriver::primaryIndex() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QString tablename = qTableName("relTEST1"); + //check that we can get primary index using unquoted mixed case table name + QSqlIndex index = db.driver()->primaryIndex(tablename); + QCOMPARE(index.count(), 1); + + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + QCOMPARE(index.fieldName(0), QString::fromLatin1("ID")); + else + QCOMPARE(index.fieldName(0), QString::fromLatin1("id")); + + + //check that we can get the primary index using a quoted tablename + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toUpper(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toLower(); + + index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); + QCOMPARE(index.count(), 1); + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + QCOMPARE(index.fieldName(0), QString::fromLatin1("ID")); + else + QCOMPARE(index.fieldName(0), QString::fromLatin1("id")); + + + + //check that we can not get the primary index using a quoted but incorrect table name casing + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toLower(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toUpper(); + + index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); + if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) + QCOMPARE(index.count(), 1); //mysql will always find the table name regardless of casing + else + QCOMPARE(index.count(), 0); +} + +QTEST_MAIN(tst_QSqlDriver) +#include "tst_qsqldriver.moc" diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index 5725548..4588af8 100644 --- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -82,6 +82,10 @@ private slots: void insertRecordDuplicateFieldNames(); void invalidData(); void relationModel(); + void casing(); + void escapedRelations(); + void escapedTableName(); + void whiteSpaceInIdentifiers(); }; @@ -103,7 +107,9 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) << qTableName( "reltest2" ) << qTableName( "reltest3" ) << qTableName( "reltest4" ) - << qTableName( "reltest5" ); + << qTableName( "reltest5" ) + << db.driver()->escapeIdentifier(qTableName( "rel test6" ), QSqlDriver::TableName) + << db.driver()->escapeIdentifier(qTableName( "rel test7" ), QSqlDriver::TableName); tst_Databases::safeDropTables( db, tableNames ); QVERIFY_SQL( q, exec("create table " + qTableName("reltest1") + @@ -128,6 +134,19 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) QVERIFY_SQL( q, exec("create table " + qTableName("reltest5") + " (title varchar(20) not null primary key, abbrev varchar(20))")); QVERIFY_SQL( q, exec("insert into " + qTableName("reltest5") + " values('herr', 'Hr')")); QVERIFY_SQL( q, exec("insert into " + qTableName("reltest5") + " values('mister', 'Mr')")); + + if (testWhiteSpaceNames(db.driverName())) { + QString reltest6 = db.driver()->escapeIdentifier(qTableName("rel test6"), QSqlDriver::TableName); + QVERIFY_SQL( q, exec("create table " + reltest6 + " (id int not null primary key, " + db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName) + + " int, " + db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName) + " int)")); + QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(1, 1,9)")); + QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(2, 2,8)")); + + QString reltest7 = db.driver()->escapeIdentifier(qTableName("rel test7"), QSqlDriver::TableName); + QVERIFY_SQL( q, exec("create table " + reltest7 + " (" + db.driver()->escapeIdentifier("city id", QSqlDriver::TableName) + " int not null primary key, " + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName) + " varchar(20))")); + QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(1, 'New York')")); + QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(2, 'Washington')")); + } } void tst_QSqlRelationalTableModel::initTestCase() @@ -142,10 +161,14 @@ void tst_QSqlRelationalTableModel::cleanupTestCase() tableNames << qTableName( "reltest1" ) << qTableName( "reltest2" ) << qTableName( "reltest3" ) - << qTableName( "reltest4" ); + << qTableName( "reltest4" ) + << qTableName( "reltest5" ); foreach (const QString &dbName, dbs.dbNames) { QSqlDatabase db = QSqlDatabase::database(dbName); - tst_Databases::safeDropTables( db, tableNames ); + QStringList tables = tableNames; + tables << db.driver()->escapeIdentifier(qTableName( "rel test6" ), QSqlDriver::TableName) + << db.driver()->escapeIdentifier(qTableName( "rel test7" ), QSqlDriver::TableName); + tst_Databases::safeDropTables( db, tables ); } dbs.close(); } @@ -273,7 +296,12 @@ void tst_QSqlRelationalTableModel::setData() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + //sybase doesn't allow tables with the same alias used twice as col names + //so don't set up an identical relation when using the tds driver + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setEditStrategy(QSqlTableModel::OnManualSubmit); model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); @@ -284,7 +312,10 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi2")); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); QVERIFY_SQL(model, submitAll()); } @@ -299,10 +330,15 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); } //check setting of data when the relational key is a non-integer type @@ -336,7 +372,8 @@ void tst_QSqlRelationalTableModel::multipleRelation() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(2, 0)).toInt(), 3); @@ -344,7 +381,7 @@ void tst_QSqlRelationalTableModel::multipleRelation() QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("Trondheim")); } void tst_QSqlRelationalTableModel::insertRecord() @@ -357,6 +394,7 @@ void tst_QSqlRelationalTableModel::insertRecord() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QSqlRecord rec; @@ -398,6 +436,7 @@ void tst_QSqlRelationalTableModel::setRecord() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QSqlRecord rec; @@ -450,13 +489,18 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0,0)).toInt(), 1); QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); model.insertRows(0, 1); model.setData(model.index(0, 0), 1011); @@ -467,12 +511,20 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(), 1011); QCOMPARE(model.data(model.index(0,1)).toString(), QString("test")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 1); QCOMPARE(model.data(model.index(1,0)).toInt(), 1); QCOMPARE(model.data(model.index(1,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(1,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(1,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(1,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(1,3)).toInt(), 2); + + QVERIFY_SQL(model, submitAll()); @@ -481,9 +533,16 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(), 1); QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); - model.setData(model.index(0,3),1); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + + if (!db.driverName().startsWith("QTDS")) { + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + model.setData(model.index(0,3),1); + QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + } else { + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); + model.setData(model.index(0,3),1); + QCOMPARE(model.data(model.index(0,3)).toInt(), 1); + } model.insertRows(0, 2); model.setData(model.index(0, 0), 1012); @@ -499,17 +558,27 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(),1012); QCOMPARE(model.data(model.index(0,1)).toString(), QString("george")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); + QCOMPARE(model.data(model.index(1,0)).toInt(),1013); QCOMPARE(model.data(model.index(1,1)).toString(), QString("kramer")); QCOMPARE(model.data(model.index(1,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(1,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(1,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(1,3)).toInt(), 1); QCOMPARE(model.data(model.index(2,0)).toInt(), 1); QCOMPARE(model.data(model.index(2,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(2,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(2,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(2,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(2,3)).toInt(), 1); QVERIFY_SQL(model, submitAll()); } @@ -574,7 +643,8 @@ void tst_QSqlRelationalTableModel::sort() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); model.setSort(2, Qt::DescendingOrder); QVERIFY_SQL(model, select()); @@ -589,11 +659,19 @@ void tst_QSqlRelationalTableModel::sort() model.setSort(3, Qt::AscendingOrder); QVERIFY_SQL(model, select()); - QCOMPARE(model.rowCount(), 4); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(1, 3)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) { + QCOMPARE(model.rowCount(), 4); + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + QCOMPARE(model.data(model.index(1, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + } else { + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); + QCOMPARE(model.data(model.index(1, 3)).toInt(), 2); + QCOMPARE(model.data(model.index(2, 3)).toInt(), 2); + QCOMPARE(model.data(model.index(3, 3)).toInt(), 2); + } + } static void testRevert(QSqlRelationalTableModel &model) @@ -663,7 +741,7 @@ void tst_QSqlRelationalTableModel::revert() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); model.setSort(0, Qt::AscendingOrder); @@ -689,7 +767,9 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); model.setSort(1, Qt::AscendingOrder); model.setEditStrategy(QSqlTableModel::OnManualSubmit); @@ -698,7 +778,10 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(3, 0)).toInt(), 3); QCOMPARE(model.data(model.index(3, 1)).toString(), QString("vohi")); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(3, 3)).toInt(), 2 ); model.insertRow(model.rowCount()); QVERIFY(model.setData(model.index(4, 0), 5, Qt::EditRole)); @@ -710,11 +793,18 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(0, 0)).toInt(), 5); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("anders")); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); + QCOMPARE(model.data(model.index(4, 0)).toInt(), 3); QCOMPARE(model.data(model.index(4, 1)).toString(), QString("vohi")); QCOMPARE(model.data(model.index(4, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(4, 3)).toInt(), 2); } // For task 140782 and 176374: If the main table and the the related tables uses the same @@ -729,27 +819,38 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames() QSqlRelationalTableModel model(0, db); model.setTable(qTableName("reltest3")); model.setEditStrategy(QSqlTableModel::OnManualSubmit); + model.setSort(0, Qt::AscendingOrder); // Duplication of "name", used in both reltest3 and reltest4. model.setRelation(2, QSqlRelation(qTableName("reltest4"), "id", "name")); QVERIFY_SQL(model, select()); - QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name"))).toString(), + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name")).toUpper()).toString(), + QString("Trondheim")); + } else { + QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name"))).toString(), QString("Trondheim")); + } QSqlRecord rec = model.record(); rec.setValue(0, 3); rec.setValue(1, "Berge"); rec.setValue(2, 1); // Must insert the key value - QCOMPARE(rec.fieldName(0), QLatin1String("id")); - QCOMPARE(rec.fieldName(1), QLatin1String("name")); // This comes from main table + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + QCOMPARE(rec.fieldName(0), QLatin1String("ID")); + QCOMPARE(rec.fieldName(1), QLatin1String("NAME")); // This comes from main table + } else { + QCOMPARE(rec.fieldName(0), QLatin1String("id")); + QCOMPARE(rec.fieldName(1), QLatin1String("name")); + } // The duplicate field names is aliased because it's comes from the relation's display column. - if(!db.driverName().startsWith("QIBASE")) - QCOMPARE(rec.fieldName(2), qTableName("reltest4").append(QLatin1String("_name"))); - else + if(db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) QCOMPARE(rec.fieldName(2), (qTableName("reltest4").append(QLatin1String("_name"))).toUpper()); + else + QCOMPARE(rec.fieldName(2), qTableName("reltest4").append(QLatin1String("_name"))); QVERIFY(model.insertRecord(-1, rec)); QCOMPARE(model.data(model.index(2, 2)).toString(), QString("Oslo")); @@ -793,7 +894,7 @@ void tst_QSqlRelationalTableModel::relationModel() QVERIFY(model.relationModel(3) == NULL); QVERIFY(model.relationModel(4) == NULL); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); QVERIFY_SQL(model, select()); QVERIFY(model.relationModel(0) == NULL); @@ -806,5 +907,285 @@ void tst_QSqlRelationalTableModel::relationModel() QCOMPARE(rel_model->data(rel_model->index(0,1)).toString(), QString("herr")); } +void tst_QSqlRelationalTableModel::casing() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + if (db.driverName().startsWith("QSQLITE")) + QSKIP("The casing test for SQLITE is irrelevant since SQLITE is case insensitive", SkipAll); + + QStringList tableNames; + tableNames << qTableName("CASETEST1", db.driver()).toUpper(); + tableNames << qTableName("casetest1", db.driver()); + tst_Databases::safeDropTables(db, tableNames); + + QSqlQuery q(db); + QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() + + " (id int not null primary key, name varchar(20), title_key int, another_title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(1, 'harry', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(2, 'trond', 2, 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(3, 'vohi', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(4, 'boris', 2, 2)")); + + QVERIFY_SQL( q, exec("create table " + qTableName("casetest1", db.driver()) + + " (ident int not null primary key, name varchar(20), title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(1, 'jerry', 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(2, 'george', 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(4, 'kramer', 2)")); + + if (db.driverName().startsWith("QOCI")) { + //try an owner that doesn't exist + QSqlRecord rec = db.driver()->record("doug." + qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 0); + + //try an owner that does exist + rec = db.driver()->record(db.userName() + "." + qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 4); + } + QSqlRecord rec = db.driver()->record(qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 4); + + rec = db.driver()->record(qTableName("casetest1", db.driver())); + QCOMPARE( rec.count(), 3); + + QSqlTableModel upperCaseModel(0, db); + upperCaseModel.setTable(qTableName("CASETEST1", db.driver()).toUpper()); + + QCOMPARE(upperCaseModel.tableName(),qTableName("CASETEST1",db.driver()).toUpper()); + + QVERIFY_SQL(upperCaseModel, select()); + + QCOMPARE(upperCaseModel.rowCount(), 4); + + QSqlTableModel lowerCaseModel(0, db); + lowerCaseModel.setTable(qTableName("casetest1", db.driver())); + QCOMPARE(lowerCaseModel.tableName(), qTableName("casetest1",db.driver())); + QVERIFY_SQL(lowerCaseModel, select()); + + QCOMPARE(lowerCaseModel.rowCount(), 3); + + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("CASETEST1", db.driver()).toUpper()); + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + tst_Databases::safeDropTables(db, tableNames); +} + +void tst_QSqlRelationalTableModel::escapedRelations() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + recreateTestTables(db); + + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("reltest1")); + + //try with relation table name quoted + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(qTableName("reltest2").toUpper(),QSqlDriver::TableName), + "tid", + "title")); + } else { + model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(qTableName("reltest2"),QSqlDriver::TableName), + "tid", + "title")); + + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with index column quoted + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName).toUpper(), + "title")); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName), + "title")); + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with display column quoted + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); + } + + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with tablename and index and display columns quoted in the relation + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); +} + +void tst_QSqlRelationalTableModel::escapedTableName() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + // set the values using OnRowChange Strategy with an escaped tablename + { + QSqlRelationalTableModel model(0, db); + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setTable(db.driver()->escapeIdentifier(qTableName("reltest1").toUpper(), QSqlDriver::TableName)); + } else { + model.setTable(db.driver()->escapeIdentifier(qTableName("reltest1"), QSqlDriver::TableName)); + } + model.setSort(0, Qt::AscendingOrder); + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + + QVERIFY(model.setData(model.index(0, 1), QString("harry2"))); + QVERIFY(model.setData(model.index(0, 2), 2)); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); + + model.submit(); + + QVERIFY(model.setData(model.index(3,1), QString("boris2"))); + QVERIFY(model.setData(model.index(3, 2), 1)); + + QCOMPARE(model.data(model.index(3,1)).toString(), QString("boris2")); + QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); + + model.submit(); + } + { //verify values + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("reltest1")); + model.setSort(0, Qt::AscendingOrder); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 2); + QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2")); + QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); + + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr")); + + } +} + +void tst_QSqlRelationalTableModel::whiteSpaceInIdentifiers() { + + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + if (!testWhiteSpaceNames(db.driverName())) + QSKIP("White space test irrelevant for driver", SkipAll); + QSqlRelationalTableModel model(0, db); + model.setTable(db.driver()->escapeIdentifier(qTableName("rel test6"), QSqlDriver::TableName)); + model.setSort(0, Qt::DescendingOrder); + model.setRelation(1, QSqlRelation(db.driver()->escapeIdentifier(qTableName("rel test7"), QSqlDriver::TableName), + db.driver()->escapeIdentifier("city id", QSqlDriver::FieldName), + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName))); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0,1)).toString(), QString("Washington")); + QCOMPARE(model.data(model.index(1,1)).toString(), QString("New York")); + + QSqlRecord rec; + QSqlField f1("id", QVariant::Int); + QSqlField f2(db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName), QVariant::Int); + QSqlField f3(db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName), QVariant::Int); + + f1.setValue(3); + f2.setValue(2); + f3.setValue(7); + + f1.setGenerated(true); + f2.setGenerated(true); + f3.setGenerated(true); + + rec.append(f1); + rec.append(f2); + rec.append(f3); + + QVERIFY_SQL(model, insertRecord(-1, rec)); + model.submitAll(); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 3); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Washington")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 7); + + //TODO: For some reson setting a record using manual submit fails + //model.setEditStrategy(QSqlTableModel::OnManualSubmit); + + QSqlRecord recNew; + QSqlField f1New("id", QVariant::Int); + QSqlField f2New(db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName), QVariant::Int); + QSqlField f3New(db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName), QVariant::Int); + + f1New.setValue(4); + f2New.setValue(1); + f3New.setValue(6); + + f1New.setGenerated(true); + f2New.setGenerated(true); + f3New.setGenerated(true); + + recNew.append(f1New); + recNew.append(f2New); + recNew.append(f3New); + + QVERIFY_SQL(model, setRecord(0, recNew)); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 4); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("New York")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 6); + + QVERIFY_SQL(model, submitAll()); + QCOMPARE(model.data(model.index(0, 0)).toInt(), 4); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("New York")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 6); +} + QTEST_MAIN(tst_QSqlRelationalTableModel) #include "tst_qsqlrelationaltablemodel.moc" diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp index 5d1f9d4..aa882be 100644 --- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp @@ -145,7 +145,7 @@ void tst_QSqlTableModel::dropTestTables() << qTableName("bigtable") << qTableName("foo"); if (testWhiteSpaceNames(db.driverName())) - tableNames << qTableName("qtestw hitespace"); + tableNames << qTableName("qtestw hitespace", db.driver()); tst_Databases::safeDropTables(db, tableNames); @@ -277,6 +277,7 @@ void tst_QSqlTableModel::setRecord() QList<QSqlTableModel::EditStrategy> policies = QList<QSqlTableModel::EditStrategy>() << QSqlTableModel::OnFieldChange << QSqlTableModel::OnRowChange << QSqlTableModel::OnManualSubmit; + QString Xsuffix; foreach( QSqlTableModel::EditStrategy submitpolicy, policies) { QSqlTableModel model(0, db); @@ -295,6 +296,8 @@ void tst_QSqlTableModel::setRecord() if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnManualSubmit) QVERIFY(model.submitAll()); + else if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnRowChange && i == model.rowCount() -1) + model.submit(); else { // dataChanged() is not emitted when submitAll() is called QCOMPARE(spy.count(), 2); @@ -304,10 +307,12 @@ void tst_QSqlTableModel::setRecord() } } - QCOMPARE(model.data(model.index(0, 1)).toString(), QString("fooX")); - QCOMPARE(model.data(model.index(0, 2)).toString(), QString("barX")); - QCOMPARE(model.data(model.index(1, 1)).toString(), QString("bazX")); - QCOMPARE(model.data(model.index(1, 2)).toString(), QString("joeX")); + Xsuffix.append('X'); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("foo").append(Xsuffix)); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("bar").append(Xsuffix)); + QCOMPARE(model.data(model.index(1, 1)).toString(), QString("baz").append(Xsuffix)); + QCOMPARE(model.data(model.index(1, 2)).toString(), QString("joe").append(Xsuffix)); } } diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index b39f0a1..553833c 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -118,6 +118,7 @@ private slots: void postEvent(); void stateFinished(); void parallelStates(); + void parallelRootState(); void allSourceToTargetConfigurations(); void signalTransitions(); void eventTransitions(); @@ -1633,6 +1634,29 @@ void tst_QStateMachine::parallelStates() QVERIFY(machine.configuration().contains(s2)); } +void tst_QStateMachine::parallelRootState() +{ + QStateMachine machine; + QState *root = machine.rootState(); + QCOMPARE(root->childMode(), QState::ExclusiveStates); + root->setChildMode(QState::ParallelStates); + QCOMPARE(root->childMode(), QState::ParallelStates); + + QState *s1 = new QState(root); + QFinalState *s1_f = new QFinalState(s1); + s1->setInitialState(s1_f); + QState *s2 = new QState(root); + QFinalState *s2_f = new QFinalState(s2); + s2->setInitialState(s2_f); + + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start."); + machine.start(); + QCoreApplication::processEvents(); + QEXPECT_FAIL("", "parallel root state is not supported (task 256587)", Continue); + QCOMPARE(startedSpy.count(), 1); +} + void tst_QStateMachine::allSourceToTargetConfigurations() { QStateMachine machine; @@ -1957,6 +1981,31 @@ void tst_QStateMachine::signalTransitions() QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s3)); } + // signature normalization + { + QStateMachine machine; + SignalEmitter emitter; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL( signalWithNoArg( ) ), s1); + QVERIFY(t0 != 0); + QCOMPARE(t0->signal(), QByteArray(SIGNAL( signalWithNoArg( ) ))); + + QSignalTransition *t1 = s0->addTransition(&emitter, SIGNAL( signalWithStringArg( const QString & ) ), s1); + QVERIFY(t1 != 0); + QCOMPARE(t1->signal(), QByteArray(SIGNAL( signalWithStringArg( const QString & ) ))); + + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QTRY_COMPARE(startedSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + + emitter.emitSignalWithNoArg(); + + QTRY_COMPARE(finishedSpy.count(), 1); + } } void tst_QStateMachine::eventTransitions() diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index e8cb089..f11aff9 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -75,7 +75,11 @@ private slots: void stylePropagation() const; void matrixForElement() const; void gradientStops() const; + void gradientRefs(); void fillRule(); + void opacity(); + void paths(); + void displayMode(); #ifndef QT_NO_COMPRESS void testGzLoading(); @@ -331,7 +335,7 @@ void tst_QSvgRenderer::nestedQXmlStreamReader() const QCOMPARE(reader.readNext(), QXmlStreamReader::StartDocument); QCOMPARE(reader.readNext(), QXmlStreamReader::StartElement); QCOMPARE(reader.name().toString(), QLatin1String("bar")); - + QPicture picture; QPainter painter(&picture); QSvgRenderer renderer(&reader); @@ -533,7 +537,10 @@ void tst_QSvgRenderer::gradientStops() const QCOMPARE(image, refImage); } +} +void tst_QSvgRenderer::gradientRefs() +{ const char *svgs[] = { "<svg>" "<defs>" @@ -565,6 +572,17 @@ void tst_QSvgRenderer::gradientStops() const "</linearGradient>" "</defs>" "<rect fill=\"url(#gradient)\" height=\"8\" width=\"256\" x=\"0\" y=\"0\"/>" + "</svg>", + "<svg>" + "<rect fill=\"url(#gradient)\" height=\"8\" width=\"256\" x=\"0\" y=\"0\"/>" + "<defs>" + "<linearGradient id=\"gradient0\">" + "<stop offset=\"0\" stop-color=\"red\" stop-opacity=\"0\"/>" + "<stop offset=\"1\" stop-color=\"blue\"/>" + "</linearGradient>" + "<linearGradient id=\"gradient\" xlink:href=\"#gradient0\">" + "</linearGradient>" + "</defs>" "</svg>" }; for (int i = 0 ; i < sizeof(svgs) / sizeof(svgs[0]) ; ++i) @@ -589,6 +607,7 @@ void tst_QSvgRenderer::gradientStops() const } } + #ifndef QT_NO_COMPRESS void tst_QSvgRenderer::testGzLoading() { @@ -653,22 +672,257 @@ void tst_QSvgRenderer::testGzHelper() void tst_QSvgRenderer::fillRule() { - QByteArray data( + static const char *svgs[] = { + // Paths + // Default fill-rule (nonzero) "<svg>" - "<rect x=\"0\" y=\"0\" height=\"300\" width=\"400\" fill=\"blue\" />" - "<path d=\"M100 200 L300 200 L300 100 L100 100 M100 200 L300 200 L300 100 L100 100 Z\" fill=\"red\" stroke=\"black\" />" - "</svg>"); + " <rect x=\"0\" y=\"0\" height=\"30\" width=\"30\" fill=\"blue\" />" + " <path d=\"M10 0 L30 0 L30 30 L0 30 L0 10 L20 10 L20 20 L10 20 Z\" fill=\"red\" />" + "</svg>", + // nonzero + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"30\" width=\"30\" fill=\"blue\" />" + " <path d=\"M10 0 L30 0 L30 30 L0 30 L0 10 L20 10 L20 20 L10 20 Z\" fill=\"red\" fill-rule=\"nonzero\" />" + "</svg>", + // evenodd + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"30\" width=\"30\" fill=\"blue\" />" + " <path d=\"M10 0 L30 0 L30 30 L0 30 L0 10 L20 10 L20 20 L10 20 Z\" fill=\"red\" fill-rule=\"evenodd\" />" + "</svg>", - QSvgRenderer renderer(data); + // Polygons + // Default fill-rule (nonzero) + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"30\" width=\"30\" fill=\"blue\" />" + " <polygon points=\"10 0 30 0 30 30 0 30 0 10 20 10 20 20 10 20\" fill=\"red\" />" + "</svg>", + // nonzero + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"30\" width=\"30\" fill=\"blue\" />" + " <polygon points=\"10 0 30 0 30 30 0 30 0 10 20 10 20 20 10 20\" fill=\"red\" fill-rule=\"nonzero\" />" + "</svg>", + // evenodd + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"30\" width=\"30\" fill=\"blue\" />" + " <polygon points=\"10 0 30 0 30 30 0 30 0 10 20 10 20 20 10 20\" fill=\"red\" fill-rule=\"evenodd\" />" + "</svg>" + }; - QImage image(128, 128, QImage::Format_ARGB32_Premultiplied); - image.fill(0); + const int COUNT = sizeof(svgs) / sizeof(svgs[0]); + QImage refImageNonZero(30, 30, QImage::Format_ARGB32_Premultiplied); + QImage refImageEvenOdd(30, 30, QImage::Format_ARGB32_Premultiplied); + refImageNonZero.fill(0xffff0000); + refImageEvenOdd.fill(0xffff0000); + QPainter p; + p.begin(&refImageNonZero); + p.fillRect(QRectF(0, 0, 10, 10), Qt::blue); + p.end(); + p.begin(&refImageEvenOdd); + p.fillRect(QRectF(0, 0, 10, 10), Qt::blue); + p.fillRect(QRectF(10, 10, 10, 10), Qt::blue); + p.end(); + + for (int i = 0; i < COUNT; ++i) { + QByteArray data(svgs[i]); + QSvgRenderer renderer(data); + QImage image(30, 30, QImage::Format_ARGB32_Premultiplied); + image.fill(0); + p.begin(&image); + renderer.render(&p); + p.end(); + QCOMPARE(image, i % 3 == 2 ? refImageEvenOdd : refImageNonZero); + } +} +static void opacity_drawSvgAndVerify(const QByteArray &data) +{ + QSvgRenderer renderer(data); + QVERIFY(renderer.isValid()); + QImage image(10, 10, QImage::Format_ARGB32_Premultiplied); + image.fill(0xffff00ff); QPainter painter(&image); renderer.render(&painter); painter.end(); + QCOMPARE(image.pixel(5, 5), 0xff7f7f7f); +} + +void tst_QSvgRenderer::opacity() +{ + static const char *opacities[] = {"-1,4641", "0", "0.5", "1", "1.337"}; + static const char *firstColors[] = {"#7f7f7f", "#7f7f7f", "#402051", "blue", "#123456"}; + static const char *secondColors[] = {"red", "#bad", "#bedead", "#7f7f7f", "#7f7f7f"}; + + // Fill-opacity + for (int i = 0; i < 5; ++i) { + QByteArray data("<svg><rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\""); + data.append(firstColors[i]); + data.append("\"/><rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\""); + data.append(secondColors[i]); + data.append("\" fill-opacity=\""); + data.append(opacities[i]); + data.append("\"/></svg>"); + opacity_drawSvgAndVerify(data); + } + // Stroke-opacity + for (int i = 0; i < 5; ++i) { + QByteArray data("<svg viewBox=\"0 0 10 10\"><polyline points=\"0 5 10 5\" fill=\"none\" stroke=\""); + data.append(firstColors[i]); + data.append("\" stroke-width=\"10\"/><line x1=\"5\" y1=\"0\" x2=\"5\" y2=\"10\" fill=\"none\" stroke=\""); + data.append(secondColors[i]); + data.append("\" stroke-width=\"10\" stroke-opacity=\""); + data.append(opacities[i]); + data.append("\"/></svg>"); + opacity_drawSvgAndVerify(data); + } + // As gradients: + // Fill-opacity + for (int i = 0; i < 5; ++i) { + QByteArray data("<svg><defs><linearGradient id=\"gradient\"><stop offset=\"0\" stop-color=\""); + data.append(secondColors[i]); + data.append("\"/><stop offset=\"1\" stop-color=\""); + data.append(secondColors[i]); + data.append("\"/></linearGradient></defs><rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\""); + data.append(firstColors[i]); + data.append("\"/><rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"url(#gradient)\" fill-opacity=\""); + data.append(opacities[i]); + data.append("\"/></svg>"); + opacity_drawSvgAndVerify(data); + } + // When support for gradients on strokes has been implemented, add the code below. + /* + // Stroke-opacity + for (int i = 0; i < 5; ++i) { + QByteArray data("<svg viewBox=\"0 0 10 10\"><defs><linearGradient id=\"grad\"><stop offset=\"0\" stop-color=\""); + data.append(secondColors[i]); + data.append("\"/><stop offset=\"1\" stop-color=\""); + data.append(secondColors[i]); + data.append("\"/></linearGradient></defs><polyline points=\"0 5 10 5\" fill=\"none\" stroke=\""); + data.append(firstColors[i]); + data.append("\" stroke-width=\"10\" /><line x1=\"5\" y1=\"0\" x2=\"5\" y2=\"10\" fill=\"none\" stroke=\"url(#grad)\" stroke-width=\"10\" stroke-opacity=\""); + data.append(opacities[i]); + data.append("\" /></svg>"); + opacity_drawSvgAndVerify(data); + } + */ +} + +void tst_QSvgRenderer::paths() +{ + static const char *svgs[] = { + // Absolute coordinates, explicit commands. + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"50\" width=\"50\" fill=\"blue\" />" + " <path d=\"M50 0 V50 H0 Q0 25 25 25 T50 0 C25 0 50 50 25 50 S25 0 0 0 Z\" fill=\"red\" fill-rule=\"evenodd\"/>" + "</svg>", + // Absolute coordinates, implicit commands. + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"50\" width=\"50\" fill=\"blue\" />" + " <path d=\"M50 0 50 50 0 50 Q0 25 25 25 Q50 25 50 0 C25 0 50 50 25 50 C0 50 25 0 0 0 Z\" fill=\"red\" fill-rule=\"evenodd\" />" + "</svg>", + // Relative coordinates, explicit commands. + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"50\" width=\"50\" fill=\"blue\" />" + " <path d=\"m50 0 v50 h-50 q0 -25 25 -25 t25 -25 c-25 0 0 50 -25 50 s0 -50 -25 -50 z\" fill=\"red\" fill-rule=\"evenodd\" />" + "</svg>", + // Relative coordinates, implicit commands. + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"50\" width=\"50\" fill=\"blue\" />" + " <path d=\"m50 0 0 50 -50 0 q0 -25 25 -25 25 0 25 -25 c-25 0 0 50 -25 50 -25 0 0 -50 -25 -50 z\" fill=\"red\" fill-rule=\"evenodd\" />" + "</svg>", + // Absolute coordinates, explicit commands, minimal whitespace. + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"50\" width=\"50\" fill=\"blue\" />" + " <path d=\"m50 0v50h-50q0-25 25-25t25-25c-25 0 0 50-25 50s0-50-25-50z\" fill=\"red\" fill-rule=\"evenodd\" />" + "</svg>", + // Absolute coordinates, explicit commands, extra whitespace. + "<svg>" + " <rect x=\"0\" y=\"0\" height=\"50\" width=\"50\" fill=\"blue\" />" + " <path d=\" M 50 0 V 50 H 0 Q 0 25 25 25 T 50 0 C 25 0 50 50 25 50 S 25 0 0 0 Z \" fill=\"red\" fill-rule=\"evenodd\" />" + "</svg>" + }; + + const int COUNT = sizeof(svgs) / sizeof(svgs[0]); + QImage images[COUNT]; + QPainter p; + + for (int i = 0; i < COUNT; ++i) { + QByteArray data(svgs[i]); + QSvgRenderer renderer(data); + QVERIFY(renderer.isValid()); + images[i] = QImage(50, 50, QImage::Format_ARGB32_Premultiplied); + images[i].fill(0); + p.begin(&images[i]); + renderer.render(&p); + p.end(); + if (i != 0) { + QCOMPARE(images[i], images[0]); + } + } +} + +void tst_QSvgRenderer::displayMode() +{ + static const char *svgs[] = { + // All visible. + "<svg>" + " <g>" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"red\" />" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"blue\" />" + " </g>" + "</svg>", + // Don't display svg element. + "<svg display=\"none\">" + " <g>" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"red\" />" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"blue\" />" + " </g>" + "</svg>", + // Don't display g element. + "<svg>" + " <g display=\"none\">" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"red\" />" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"blue\" />" + " </g>" + "</svg>", + // Don't display first rect element. + "<svg>" + " <g>" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"red\" display=\"none\" />" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"blue\" />" + " </g>" + "</svg>", + // Don't display second rect element. + "<svg>" + " <g>" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"red\" />" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"blue\" display=\"none\" />" + " </g>" + "</svg>", + // Don't display svg element, but set display mode to "inline" for other elements. + "<svg display=\"none\">" + " <g display=\"inline\">" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"red\" display=\"inline\" />" + " <rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"blue\" display=\"inline\" />" + " </g>" + "</svg>" + }; + + QRgb expectedColors[] = {0xff0000ff, 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xffff0000, 0xff00ff00}; + + const int COUNT = sizeof(svgs) / sizeof(svgs[0]); + QPainter p; - QCOMPARE(image.pixel(64, 64), QColor(Qt::red).rgba()); + for (int i = 0; i < COUNT; ++i) { + QByteArray data(svgs[i]); + QSvgRenderer renderer(data); + QVERIFY(renderer.isValid()); + QImage image(10, 10, QImage::Format_ARGB32_Premultiplied); + image.fill(0xff00ff00); + p.begin(&image); + renderer.render(&p); + p.end(); + QCOMPARE(image.pixel(5, 5), expectedColors[i]); + } } QTEST_MAIN(tst_QSvgRenderer) |