diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-09-25 02:04:55 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-09-25 02:04:55 (GMT) |
commit | 7b94225ae26abcca8f2e8706cee8ed4843f5a53b (patch) | |
tree | 9b8ffb070a498ab1ef8586e31e6d92eac1e3b6de | |
parent | a7ee91c6db7dfeb38769c4828f5db926fbd37330 (diff) | |
parent | 6a297d3626c1779047812965a12f32e143e63b7d (diff) | |
download | Qt-7b94225ae26abcca8f2e8706cee8ed4843f5a53b.zip Qt-7b94225ae26abcca8f2e8706cee8ed4843f5a53b.tar.gz Qt-7b94225ae26abcca8f2e8706cee8ed4843f5a53b.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
23 files changed, 327 insertions, 160 deletions
diff --git a/examples/declarative/sql/hello.qml b/examples/declarative/sql/hello.qml index e43d320..db568a9 100644 --- a/examples/declarative/sql/hello.qml +++ b/examples/declarative/sql/hello.qml @@ -12,15 +12,8 @@ Text { tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]); tx.executeSql('SELECT * FROM Greeting', [], function(tx, rs) { - /* Inefficient HTML5-compatible way for(var i = 0; i < rs.rows.length; i++) { - r += rs.rows[i][0] + ", " + rs.rows[i][1] + "\n" - } - */ - /* Efficient way: forward only, not "length" query */ - rs.rows.forwardOnly = true; - for(var i = 0; rs.rows[i]; i++) { - r += rs.rows[i][0] + ", " + rs.rows[i][1] + "\n" + r += rs.rows.item(i).salutation + ", " + rs.rows.item(i).salutee + "\n" } }, function(tx, error) { diff --git a/src/declarative/fx/qfxtextedit.cpp b/src/declarative/fx/qfxtextedit.cpp index ce06348..935ccb7 100644 --- a/src/declarative/fx/qfxtextedit.cpp +++ b/src/declarative/fx/qfxtextedit.cpp @@ -1053,6 +1053,7 @@ void QFxTextEdit::updateSize() newWidth += cursorWidth; if(!d->document->isEmpty()) newWidth += 3;// ### Need a better way of accounting for space between char and cursor + // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed. setImplicitWidth(newWidth); setImplicitHeight(d->text.isEmpty() ? fm.height() : (int)d->document->size().height()); diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp index 5869a56..b132c55 100644 --- a/src/declarative/qml/qmlsqldatabase.cpp +++ b/src/declarative/qml/qmlsqldatabase.cpp @@ -46,6 +46,7 @@ #include <QtScript/qscriptvalueiterator.h> #include <QtScript/qscriptcontext.h> #include <QtScript/qscriptengine.h> +#include <QtScript/qscriptclasspropertyiterator.h> #include <QtSql/qsqldatabase.h> #include <QtSql/qsqlquery.h> #include <QtSql/qsqlerror.h> @@ -62,12 +63,14 @@ Q_DECLARE_METATYPE(QSqlDatabase) Q_DECLARE_METATYPE(QSqlQuery) +class QmlSqlQueryScriptClassPropertyIterator; + class QmlSqlQueryScriptClass: public QScriptClass { public: QmlSqlQueryScriptClass(QScriptEngine *engine) : QScriptClass(engine) { str_length = engine->toStringHandle(QLatin1String("length")); - str_forwardOnly = engine->toStringHandle(QLatin1String("forwardOnly")); // not in HTML5 (optimization) + str_forwardOnly = engine->toStringHandle(QLatin1String("forwardOnly")); // not in HTML5 (an optimization) } QueryFlags queryProperty(const QScriptValue &object, @@ -112,12 +115,11 @@ public: } else if (name == str_forwardOnly) { return query.isForwardOnly(); } else { - if (query.at() == id || query.seek(id)) { // Qt 4.6 doesn't optimize at()==id + if ((uint)query.at() == id || query.seek(id)) { // Qt 4.6 doesn't optimize seek(at()) QSqlRecord r = query.record(); - QScriptValue row = engine()->newArray(r.count()); + QScriptValue row = engine()->newObject(); for (int j=0; j<r.count(); ++j) { - // XXX only strings - row.setProperty(j, QScriptValue(engine(),r.value(j).toString())); + row.setProperty(r.fieldName(j), QScriptValue(engine(),r.value(j).toString())); // XXX only strings } return row; } @@ -134,11 +136,108 @@ public: } } + QScriptValue::PropertyFlags propertyFlags(const QScriptValue &/*object*/, const QScriptString &name, uint /*id*/) + { + if (name == str_length) { + return QScriptValue::Undeletable + | QScriptValue::SkipInEnumeration; + } + return QScriptValue::Undeletable; + } + + QScriptClassPropertyIterator *newIterator(const QScriptValue &object); + private: QScriptString str_length; QScriptString str_forwardOnly; }; +class QmlSqlQueryScriptClassPropertyIterator : public QScriptClassPropertyIterator +{ +public: + QmlSqlQueryScriptClassPropertyIterator(const QScriptValue &object) + : QScriptClassPropertyIterator(object) + { + toFront(); + } + + ~QmlSqlQueryScriptClassPropertyIterator() + { + } + + bool hasNext() const + { + QSqlQuery query = qscriptvalue_cast<QSqlQuery>(object().data()); + return query.at() == m_index || query.seek(m_index); // Qt 4.6 doesn't optimize seek(at()) + } + + void next() + { + m_last = m_index; + ++m_index; + } + + bool hasPrevious() const + { + return (m_index > 0); + } + + void previous() + { + --m_index; + m_last = m_index; + } + + void toFront() + { + m_index = 0; + m_last = -1; + } + + void toBack() + { + QSqlQuery query = qscriptvalue_cast<QSqlQuery>(object().data()); + m_index = query.size(); + m_last = -1; + } + + QScriptString name() const + { + return object().engine()->toStringHandle(QString::number(m_last)); + } + + uint id() const + { + return m_last; + } + +private: + int m_index; + int m_last; +}; + +QScriptClassPropertyIterator *QmlSqlQueryScriptClass::newIterator(const QScriptValue &object) +{ + return new QmlSqlQueryScriptClassPropertyIterator(object); +} + + + +static QScriptValue qmlsqldatabase_item(QScriptContext *context, QScriptEngine *engine) +{ + QSqlQuery query = qscriptvalue_cast<QSqlQuery>(context->thisObject().data()); + int i = context->argument(0).toNumber(); + if (query.at() == i || query.seek(i)) { // Qt 4.6 doesn't optimize seek(at()) + QSqlRecord r = query.record(); + QScriptValue row = engine->newObject(); + for (int j=0; j<r.count(); ++j) { + row.setProperty(r.fieldName(j), QScriptValue(engine,r.value(j).toString())); + } + return row; + } + return engine->undefinedValue(); +} + static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEngine *engine) { QSqlDatabase db = qscriptvalue_cast<QSqlDatabase>(context->thisObject()); @@ -163,6 +262,7 @@ static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEn QmlEnginePrivate::get(engine)->sqlQueryClass= new QmlSqlQueryScriptClass(engine); QScriptValue rows = engine->newObject(QmlEnginePrivate::get(engine)->sqlQueryClass); rows.setData(engine->newVariant(qVariantFromValue(query))); + rows.setProperty(QLatin1String("item"), engine->newFunction(qmlsqldatabase_item,1), QScriptValue::SkipInEnumeration); rs.setProperty(QLatin1String("rows"),rows); rs.setProperty(QLatin1String("rowsAffected"),query.numRowsAffected()); rs.setProperty(QLatin1String("insertId"),query.lastInsertId().toString()); // XXX only string @@ -234,7 +334,7 @@ static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine * database = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), dbid); } if (!database.isOpen()) { - QString basename = QmlEnginePrivate::get(engine)->offlineStoragePath + "/Databases/"; + QString basename = QmlEnginePrivate::get(engine)->offlineStoragePath + QLatin1String("/Databases/"); QDir().mkpath(basename); basename += dbid; database.setDatabaseName(basename+QLatin1String(".sqllite")); @@ -257,3 +357,9 @@ void qt_add_qmlsqldatabase(QScriptEngine *engine) engine->globalObject().setProperty(QLatin1String("openDatabase"), openDatabase); } +/* +HTML5 "spec" says "rs.rows[n]", but WebKit only impelments "rs.rows.item(n)". We do both (and property iterator). +We add a "forwardOnly" property that stops Qt caching results (code promises to only go forward +through the data. +*/ + diff --git a/src/declarative/util/qmlview.cpp b/src/declarative/util/qmlview.cpp index 7cce2da..805612e 100644 --- a/src/declarative/util/qmlview.cpp +++ b/src/declarative/util/qmlview.cpp @@ -340,6 +340,8 @@ void QmlView::continueExecute() d->initialSize.setWidth(d->root->width()); if (d->initialSize.height() <= 0 && d->root->height() > 0) d->initialSize.setHeight(d->root->height()); + resize(d->initialSize); + if (d->resizable) { d->root->setWidth(width()); d->root->setHeight(height()); diff --git a/src/src.pro b/src/src.pro index 40f744b..f7ace8d 100644 --- a/src/src.pro +++ b/src/src.pro @@ -126,6 +126,7 @@ src_declarative.target = sub-declarative contains(QT_CONFIG, webkit) { src_webkit.depends = src_gui src_sql src_network src_xml contains(QT_CONFIG, phonon):src_webkit.depends += src_phonon + contains(QT_CONFIG, declarative):src_declarative.depends += src_webkit #exists($$QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro): src_webkit.depends += src_javascriptcore } contains(QT_CONFIG, qt3support): src_plugins.depends += src_qt3support diff --git a/tests/auto/declarative/qfxtextedit/data/QT-669-test.qml b/tests/auto/declarative/qfxtextedit/data/QT-669-test.qml deleted file mode 100644 index 9d6b5e5..0000000 --- a/tests/auto/declarative/qfxtextedit/data/QT-669-test.qml +++ /dev/null @@ -1,8 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { msec: 0; image: "QT-669.png" } - Key { key: Qt.Key_Right; count: 20 } - Key { key: Qt.Key_Left; count: 20 } - Frame { msec: 100; image: "QT-669.png" } -} diff --git a/tests/auto/declarative/qfxtextedit/data/QT-669.png b/tests/auto/declarative/qfxtextedit/data/QT-669.png Binary files differdeleted file mode 100644 index 657fce9..0000000 --- a/tests/auto/declarative/qfxtextedit/data/QT-669.png +++ /dev/null diff --git a/tests/auto/declarative/qfxtextedit/data/QT-669.qml b/tests/auto/declarative/qfxtextedit/data/QT-669.qml deleted file mode 100644 index b9bf86a..0000000 --- a/tests/auto/declarative/qfxtextedit/data/QT-669.qml +++ /dev/null @@ -1,11 +0,0 @@ -import Qt 4.6 - -Rectangle { - color: "green" - width:400; - height:40; - TextEdit { - focus: true; - text: "Jackdaws love my big sphinx of Quartz" - } -} diff --git a/tests/auto/declarative/qfxtextedit/data/basic-test.qml b/tests/auto/declarative/qfxtextedit/data/basic-test.qml deleted file mode 100644 index 021bfc5..0000000 --- a/tests/auto/declarative/qfxtextedit/data/basic-test.qml +++ /dev/null @@ -1,5 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { msec: 0; image: "basic.png" } -} diff --git a/tests/auto/declarative/qfxtextedit/data/basic.png b/tests/auto/declarative/qfxtextedit/data/basic.png Binary files differdeleted file mode 100644 index b3cf1bf..0000000 --- a/tests/auto/declarative/qfxtextedit/data/basic.png +++ /dev/null diff --git a/tests/auto/declarative/qfxtextedit/data/basic.qml b/tests/auto/declarative/qfxtextedit/data/basic.qml deleted file mode 100644 index db4ec1c..0000000 --- a/tests/auto/declarative/qfxtextedit/data/basic.qml +++ /dev/null @@ -1,12 +0,0 @@ -import Qt 4.6 - -Item { - width:600; - height:100; - TextEdit { - focus: false; - font.pointSize: 14 - font.bold: false - text: "Jackdaws love my big sphinx of Quartz" - } -} diff --git a/tests/auto/declarative/qfxtextedit/data/colorful-test.qml b/tests/auto/declarative/qfxtextedit/data/colorful-test.qml deleted file mode 100644 index f148746..0000000 --- a/tests/auto/declarative/qfxtextedit/data/colorful-test.qml +++ /dev/null @@ -1,5 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { msec: 80; image: "colorful.png" } -} diff --git a/tests/auto/declarative/qfxtextedit/data/colorful.png b/tests/auto/declarative/qfxtextedit/data/colorful.png Binary files differdeleted file mode 100644 index 16189e5..0000000 --- a/tests/auto/declarative/qfxtextedit/data/colorful.png +++ /dev/null diff --git a/tests/auto/declarative/qfxtextedit/data/colorful.qml b/tests/auto/declarative/qfxtextedit/data/colorful.qml deleted file mode 100644 index 36d9c66..0000000 --- a/tests/auto/declarative/qfxtextedit/data/colorful.qml +++ /dev/null @@ -1,18 +0,0 @@ -import Qt 4.6 - -Rectangle { - color:"lightsteelblue" - width:600; - height:100; - Timer{ interval: 20; running: true; repeat: false; onTriggered: "Txt.selectionEnd = 14" } - TextEdit { - id: Txt - focus: false; - font.pointSize: 14 - font.bold: false - color: "red" - selectionColor: "yellow" - selectedTextColor: "blue" - text: "Jackdaws love my big sphinx of Quartz" - } -} diff --git a/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp b/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp index ab55454..e38e0e7 100644 --- a/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp +++ b/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp @@ -6,9 +6,6 @@ #include <QtDeclarative/qmlcomponent.h> #include <QtDeclarative/qfxtextedit.h> #include <QFontMetrics> -#include <QLibraryInfo> -#include <QProcess> -#include <QDir> class tst_qfxtextedit : public QObject @@ -31,8 +28,6 @@ private slots: void cursorDelegate(); - void visualTests_data(); - void visualTests(); private: QStringList standard; QStringList richText; @@ -46,7 +41,6 @@ private: QStringList colorStrings; QmlEngine engine; - QString qmlviewerBinary; }; tst_qfxtextedit::tst_qfxtextedit() @@ -90,16 +84,6 @@ tst_qfxtextedit::tst_qfxtextedit() // << "#AA0011DD" // << "#00F16B11"; // - - QString binaries = QLibraryInfo::location(QLibraryInfo::BinariesPath); - -#if defined(Q_WS_MAC) - qmlviewerBinary = QDir(binaries).absoluteFilePath("qmlviewer.app/Contents/MacOS/qmlviewer"); -#elif defined(Q_WS_WIN) - qmlviewerBinary = QDir(binaries).absoluteFilePath("qmlviewer.exe"); -#else - qmlviewerBinary = QDir(binaries).absoluteFilePath("qmlviewer"); -#endif } void tst_qfxtextedit::text() @@ -468,31 +452,6 @@ void tst_qfxtextedit::cursorDelegate() QVERIFY(!textEditObject->findChild<QFxItem*>("cursorInstance")); } -void tst_qfxtextedit::visualTests_data() -{ - QTest::addColumn<QString>("qmlFile"); - QTest::addColumn<QString>("scriptFile"); - QTest::newRow("basic") << "data/basic.qml" << "data/basic-test"; - QTest::newRow("colorful") << "data/colorful.qml" << "data/colorful-test"; - QTest::newRow("QT-669") << "data/QT-669.qml" << "data/QT-669-test"; -} - -void tst_qfxtextedit::visualTests() -{ - QFETCH(QString, qmlFile); - QFETCH(QString, scriptFile); - - QStringList arguments; - arguments << "-script" << scriptFile - << "-scriptopts" << "play,exitoncomplete,exitonfailure" - << qmlFile; - QProcess p; - p.start(qmlviewerBinary, arguments); - QVERIFY(p.waitForFinished()); - QCOMPARE(p.exitStatus(), QProcess::NormalExit); - QCOMPARE(p.exitCode(), 0); -} - QTEST_MAIN(tst_qfxtextedit) #include "tst_qfxtextedit.moc" diff --git a/tests/auto/declarative/sql/data/1-creation.js b/tests/auto/declarative/sql/data/1-creation.js new file mode 100644 index 0000000..95fa99e --- /dev/null +++ b/tests/auto/declarative/sql/data/1-creation.js @@ -0,0 +1,20 @@ +var db = openDatabase("QmlTestDB", "", "Test database from Qt autotests", 1000000); +var r="transaction_not_finished"; + +// Asynchronous in WebKit, so must wait before calling test() +db.transaction( + function(tx) { + tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)', [], + function(tx, rs) { }, function(tx, error) { r="CREATE FAILED: "+error.message }); + tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ], + function(tx, rs) { }, function(tx, error) { r="INSERT FAILED: "+error.message }); + }, + function(tx, error) { r="TRANSACTION FAILED: "+error.message }, + function(tx, result) { if (r=="transaction_not_finished") r="passed" } +); + + +function test() +{ + return r; +} diff --git a/tests/auto/declarative/sql/data/2-selection.js b/tests/auto/declarative/sql/data/2-selection.js new file mode 100644 index 0000000..3acf686 --- /dev/null +++ b/tests/auto/declarative/sql/data/2-selection.js @@ -0,0 +1,30 @@ +var db = openDatabase("QmlTestDB", "", "Test database from Qt autotests", 1000000); +var r=0; + +db.transaction( + function(tx) { + tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ], + function(tx, rs) { }, function(tx, error) { if (r==0) r="INSERT 1 FAILED: "+error.message }); + tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ], + function(tx, rs) { }, function(tx, error) { if (r==0) r="INSERT 2 FAILED: "+error.message }); + tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ], + function(tx, rs) { }, function(tx, error) { if (r==0) r="INSERT 3 FAILED: "+error.message }); + tx.executeSql('SELECT * FROM Greeting', [], + function(tx, rs) { + if ( rs.rows.length != 4 ) { // 1 from test1, 3 from this test. + if (r==0) r = "SELECT RETURNED WRONG VALUE "+rs.rows.length+rs.rows[0]+rs.rows[1] + } + }, + function(tx, error) { if (r==0) r="SELECT FAILED: "+error.message } + ); + }, + function(tx, error) { if (r==0) r="TRANSACTION FAILED: "+error.message }, + function(tx, result) { if (r==0) r="passed" } +); + + +function test() +{ + if (r == 0) r = "transaction_not_finished"; + return r; +} diff --git a/tests/auto/declarative/sql/data/3-iteration-item-function.js b/tests/auto/declarative/sql/data/3-iteration-item-function.js new file mode 100644 index 0000000..bad9b82 --- /dev/null +++ b/tests/auto/declarative/sql/data/3-iteration-item-function.js @@ -0,0 +1,27 @@ +var db = openDatabase("QmlTestDB", "", "Test database from Qt autotests", 1000000); +var r=0; + +db.transaction( + function(tx) { + tx.executeSql('SELECT * FROM Greeting', [], + function(tx, rs) { + var r1="" + for(var i = 0; i < rs.rows.length; i++) { + r1 += rs.rows.item(i).salutation + ", " + rs.rows.item(i).salutee + ";" + } + if (r1 != "hello, world;hello, world;hello, world;hello, world;") + r = "SELECTED DATA WRONG: "+r1; + }, + function(tx, error) { if (r==0) r="SELECT FAILED: "+error.message } + ); + }, + function(tx, error) { if (r==0) r="TRANSACTION FAILED: "+error.message }, + function(tx, result) { if (r==0) r="passed" } +); + + +function test() +{ + if (r == 0) r = "transaction_not_finished"; + return r; +} diff --git a/tests/auto/declarative/sql/data/5-iteration-iterator.js b/tests/auto/declarative/sql/data/5-iteration-iterator.js new file mode 100644 index 0000000..51f0504 --- /dev/null +++ b/tests/auto/declarative/sql/data/5-iteration-iterator.js @@ -0,0 +1,27 @@ +var db = openDatabase("QmlTestDB", "", "Test database from Qt autotests", 1000000); +var r=0; + +db.transaction( + function(tx) { + tx.executeSql('SELECT * FROM Greeting', [], + function(tx, rs) { + var r1="" + for(var i in rs.rows) { + r1 += rs.rows[i].salutation + ", " + rs.rows[i].salutee + ";" + } + if (r1 != "hello, world;hello, world;hello, world;hello, world;") + r = "SELECTED DATA WRONG: "+r1; + }, + function(tx, error) { if (r==0) r="SELECT FAILED: "+error.message } + ); + }, + function(tx, error) { if (r==0) r="TRANSACTION FAILED: "+error.message }, + function(tx, result) { if (r==0) r="passed" } +); + + +function test() +{ + if (r == 0) r = "transaction_not_finished"; + return r; +} diff --git a/tests/auto/declarative/sql/data/6-iteration-efficient.js b/tests/auto/declarative/sql/data/6-iteration-efficient.js new file mode 100644 index 0000000..2222b8a --- /dev/null +++ b/tests/auto/declarative/sql/data/6-iteration-efficient.js @@ -0,0 +1,28 @@ +var db = openDatabase("QmlTestDB", "", "Test database from Qt autotests", 1000000); +var r=0; + +db.transaction( + function(tx) { + tx.executeSql('SELECT * FROM Greeting', [], + function(tx, rs) { + var r1="" + rs.rows.forwardOnly = true; + for(var i=0; rs.rows[i]; ++i) { + r1 += rs.rows[i].salutation + ", " + rs.rows[i].salutee + ";" + } + if (r1 != "hello, world;hello, world;hello, world;hello, world;") + r = "SELECTED DATA WRONG: "+r1; + }, + function(tx, error) { if (r==0) r="SELECT FAILED: "+error.message } + ); + }, + function(tx, error) { if (r==0) r="TRANSACTION FAILED: "+error.message }, + function(tx, result) { if (r==0) r="passed" } +); + + +function test() +{ + if (r == 0) r = "transaction_not_finished"; + return r; +} diff --git a/tests/auto/declarative/sql/data/README b/tests/auto/declarative/sql/data/README new file mode 100644 index 0000000..7efca3a --- /dev/null +++ b/tests/auto/declarative/sql/data/README @@ -0,0 +1,3 @@ +These tests are executed in sequence - the database persist until the end of the +testing. This is done to better exercise the persistence of the database, since +that is how it is used. diff --git a/tests/auto/declarative/sql/data/test1.js b/tests/auto/declarative/sql/data/test1.js deleted file mode 100644 index 2ae9988..0000000 --- a/tests/auto/declarative/sql/data/test1.js +++ /dev/null @@ -1,18 +0,0 @@ -var db; -db = openDatabase("QmlTestDB", "", "Test database from Qt autotests", 1000000); -var r="testerror"; - -// Asynchronous in WebKit, so must wait before calling test() -db.transaction(function(tx) { - r = "passed"; - tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)', [], - function(tx, rs) { }, function(tx, error) { r="FAILED: "+error.message }); - tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ], - function(tx, rs) { }, function(tx, error) { r="FAILED: "+error.message }); -}, function(tx, error) { r="TXFAILED: "+error.message }, function(tx, result) { if (r=="testerror") r="passed" }); - - -function test() -{ - return r; -} diff --git a/tests/auto/declarative/sql/tst_sql.cpp b/tests/auto/declarative/sql/tst_sql.cpp index 3179c99..10ce6d8 100644 --- a/tests/auto/declarative/sql/tst_sql.cpp +++ b/tests/auto/declarative/sql/tst_sql.cpp @@ -17,10 +17,20 @@ public: tst_sql() {} private slots: - void verifyAgainstWebKit_data(); - void verifyAgainstWebKit(); + void initTestCase(); + + void checkDatabasePath(); + + void validateAgainstWebkit_data(); + void validateAgainstWebkit(); + + void testQml_data(); + void testQml(); + + void cleanupTestCase(); private: + QString dbDir() const; QmlEngine engine; }; @@ -28,7 +38,7 @@ class QWebPageWithJavaScriptConsoleMessages : public QWebPage { public: void javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID) { -qDebug() << sourceID << ":" << lineNumber << ":" << message; + qWarning() << sourceID << ":" << lineNumber << ":" << message; } }; @@ -44,20 +54,52 @@ void removeRecursive(const QString& dirname) QDir().rmdir(dirname); } +void tst_sql::initTestCase() +{ + removeRecursive(dbDir()); + QDir().mkpath(dbDir()); +} + +void tst_sql::cleanupTestCase() +{ + removeRecursive(dbDir()); +} + +QString tst_sql::dbDir() const +{ + return QString(SRCDIR)+"/output"; +} + +void tst_sql::checkDatabasePath() +{ + // Check default storage path (we can't use it since we don't want to mess with user's data) + QVERIFY(engine.offlineStoragePath().contains("Nokia")); + QVERIFY(engine.offlineStoragePath().contains("OfflineStorage")); +} -void tst_sql::verifyAgainstWebKit_data() +void tst_sql::testQml_data() { QTest::addColumn<QString>("jsfile"); // The input file QTest::addColumn<QString>("result"); // The required output from the js test() function QTest::addColumn<int>("databases"); // The number of databases that should have been created + QTest::addColumn<bool>("qmlextension"); // Things WebKit can't do + + QTest::newRow("creation") << "data/1-creation.js" << "passed" << 1 << false; + QTest::newRow("selection") << "data/2-selection.js" << "passed" << 1 << false; + QTest::newRow("iteration-item-function") << "data/3-iteration-item-function.js" << "passed" << 1 << false; + QTest::newRow("iteration-index") << "data/4-iteration-index.js" << "passed" << 1 << true; + QTest::newRow("iteration-iterator") << "data/5-iteration-iterator.js" << "passed" << 1 << true; + QTest::newRow("iteration-efficient") << "data/6-iteration-efficient.js" << "passed" << 1 << true; +} - QTest::newRow("basic creation") << "data/test1.js" << "passed" << 1; +void tst_sql::validateAgainstWebkit_data() +{ + testQml_data(); } -void tst_sql::verifyAgainstWebKit() +void tst_sql::validateAgainstWebkit() { - // Tests QML SQL Database support, and tests the same thing against - // WebKit (HTML5) support to validate the test. + // Validates tests against WebKit (HTML5) support. // // WebKit SQL is asynchronous, so tests are divided into code plus a test() // function which is executed "later" (via QTRY_). @@ -65,32 +107,19 @@ void tst_sql::verifyAgainstWebKit() QFETCH(QString, jsfile); QFETCH(QString, result); QFETCH(int, databases); + QFETCH(bool, qmlextension); - QString tmpdir = QString(SRCDIR)+"/output"; - - // QML... - QString qml= - "import Qt 4.6\n" - "Text { Script { source: \""+jsfile+"\" } text: test() }"; + if (qmlextension) // WebKit can't do it (yet?) + return; - // Check default storage path (we can't use it since we don't want to mess with user's data) - QVERIFY(engine.offlineStoragePath().contains("Nokia")); - QVERIFY(engine.offlineStoragePath().contains("OfflineStorage")); - engine.setOfflineStoragePath(tmpdir); - QmlComponent component(&engine, qml.toUtf8(), QUrl::fromLocalFile(SRCDIR "/empty.qml")); // just a file for relative local imports - QFxText *text = qobject_cast<QFxText*>(component.create()); - QVERIFY(text != 0); - QCOMPARE(text->text(),result); - QCOMPARE(QDir(tmpdir+"/Databases").entryInfoList(QDir::Files|QDir::NoDotAndDotDot).count(), databases*2); // *2 = .ini file + .sqlite file - - // WebKit... QFile f(jsfile); QVERIFY(f.open(QIODevice::ReadOnly)); QString js=f.readAll(); QWebPageWithJavaScriptConsoleMessages webpage; - QDir().mkpath(tmpdir); - webpage.settings()->setOfflineStoragePath(tmpdir); + webpage.settings()->setOfflineStoragePath(dbDir()); + webpage.settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true); + webpage.mainFrame()->evaluateJavaScript(js); QTest::qWait(200); // WebKit db access is asynchronous QTRY_COMPARE(webpage.mainFrame()->evaluateJavaScript("test()").toString(),result); @@ -98,9 +127,27 @@ void tst_sql::verifyAgainstWebKit() QWebSecurityOrigin origin = webpage.mainFrame()->securityOrigin(); QList<QWebDatabase> dbs = origin.databases(); QCOMPARE(dbs.count(), databases); +} +void tst_sql::testQml() +{ + // Tests QML SQL Database support with tests + // that have been validated against Webkit. + // + QFETCH(QString, jsfile); + QFETCH(QString, result); + QFETCH(int, databases); - removeRecursive(tmpdir); + QString qml= + "import Qt 4.6\n" + "Text { Script { source: \""+jsfile+"\" } text: test() }"; + + engine.setOfflineStoragePath(dbDir()); + QmlComponent component(&engine, qml.toUtf8(), QUrl::fromLocalFile(SRCDIR "/empty.qml")); // just a file for relative local imports + QFxText *text = qobject_cast<QFxText*>(component.create()); + QVERIFY(text != 0); + QCOMPARE(text->text(),result); + QCOMPARE(QDir(dbDir()+"/Databases").entryInfoList(QDir::Files|QDir::NoDotAndDotDot).count(), databases*2); // *2 = .ini file + .sqlite file } QTEST_MAIN(tst_sql) |