From 04ec3b71ff6327a17da2c5044a4086e9eddca5cd Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 24 Sep 2009 14:51:26 +1000 Subject: Track changes from qtwebkit-4.6-snapshot-18092009 Tidy js. --- tests/auto/declarative/sql/data/test1.js | 3 +-- tests/auto/declarative/sql/tst_sql.cpp | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/declarative/sql/data/test1.js b/tests/auto/declarative/sql/data/test1.js index 2ae9988..ea3b7b0 100644 --- a/tests/auto/declarative/sql/data/test1.js +++ b/tests/auto/declarative/sql/data/test1.js @@ -1,5 +1,4 @@ -var db; -db = openDatabase("QmlTestDB", "", "Test database from Qt autotests", 1000000); +var db = openDatabase("QmlTestDB", "", "Test database from Qt autotests", 1000000); var r="testerror"; // Asynchronous in WebKit, so must wait before calling test() diff --git a/tests/auto/declarative/sql/tst_sql.cpp b/tests/auto/declarative/sql/tst_sql.cpp index 3179c99..b0a6021 100644 --- a/tests/auto/declarative/sql/tst_sql.cpp +++ b/tests/auto/declarative/sql/tst_sql.cpp @@ -91,6 +91,8 @@ void tst_sql::verifyAgainstWebKit() QWebPageWithJavaScriptConsoleMessages webpage; QDir().mkpath(tmpdir); webpage.settings()->setOfflineStoragePath(tmpdir); + 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); -- cgit v0.12 From 74a66e291be2f216f88491e518add9ef72a730f2 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 24 Sep 2009 14:57:22 +1000 Subject: Tidy JS --- tests/auto/declarative/sql/data/test1.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/auto/declarative/sql/data/test1.js b/tests/auto/declarative/sql/data/test1.js index ea3b7b0..95fa99e 100644 --- a/tests/auto/declarative/sql/data/test1.js +++ b/tests/auto/declarative/sql/data/test1.js @@ -1,14 +1,17 @@ var db = openDatabase("QmlTestDB", "", "Test database from Qt autotests", 1000000); -var r="testerror"; +var r="transaction_not_finished"; // 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" }); +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() -- cgit v0.12 From 2af81c611841ba19c952f638da802e3ae8bb21fa Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 24 Sep 2009 14:58:54 +1000 Subject: Revert "Add some visual autotests for QFxTextEdit" This reverts commit 9b6a71ec68edf836ab29cc3e5db71b53fe3d9346. Turns out that (at least now) visual tests don't work like that. --- .../declarative/qfxtextedit/data/QT-669-test.qml | 8 ---- tests/auto/declarative/qfxtextedit/data/QT-669.png | Bin 4762 -> 0 bytes tests/auto/declarative/qfxtextedit/data/QT-669.qml | 11 ------ .../declarative/qfxtextedit/data/basic-test.qml | 5 --- tests/auto/declarative/qfxtextedit/data/basic.png | Bin 8051 -> 0 bytes tests/auto/declarative/qfxtextedit/data/basic.qml | 12 ------ .../declarative/qfxtextedit/data/colorful-test.qml | 5 --- .../auto/declarative/qfxtextedit/data/colorful.png | Bin 9645 -> 0 bytes .../auto/declarative/qfxtextedit/data/colorful.qml | 18 --------- .../declarative/qfxtextedit/tst_qfxtextedit.cpp | 41 --------------------- 10 files changed, 100 deletions(-) delete mode 100644 tests/auto/declarative/qfxtextedit/data/QT-669-test.qml delete mode 100644 tests/auto/declarative/qfxtextedit/data/QT-669.png delete mode 100644 tests/auto/declarative/qfxtextedit/data/QT-669.qml delete mode 100644 tests/auto/declarative/qfxtextedit/data/basic-test.qml delete mode 100644 tests/auto/declarative/qfxtextedit/data/basic.png delete mode 100644 tests/auto/declarative/qfxtextedit/data/basic.qml delete mode 100644 tests/auto/declarative/qfxtextedit/data/colorful-test.qml delete mode 100644 tests/auto/declarative/qfxtextedit/data/colorful.png delete mode 100644 tests/auto/declarative/qfxtextedit/data/colorful.qml 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 deleted file mode 100644 index 657fce9..0000000 Binary files a/tests/auto/declarative/qfxtextedit/data/QT-669.png and /dev/null differ 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 deleted file mode 100644 index b3cf1bf..0000000 Binary files a/tests/auto/declarative/qfxtextedit/data/basic.png and /dev/null differ 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 deleted file mode 100644 index 16189e5..0000000 Binary files a/tests/auto/declarative/qfxtextedit/data/colorful.png and /dev/null differ 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 #include #include -#include -#include -#include 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("cursorInstance")); } -void tst_qfxtextedit::visualTests_data() -{ - QTest::addColumn("qmlFile"); - QTest::addColumn("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" -- cgit v0.12 From 64279c11f2092a5e6e03f1b7e4bfc7a9065807f8 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 24 Sep 2009 15:53:38 +1000 Subject: More testing, validate tests before running them. Run all WebKit validations first (no point testing QML if the test are wrong). --- tests/auto/declarative/sql/data/README | 3 ++ tests/auto/declarative/sql/data/test2.js | 30 +++++++++++ tests/auto/declarative/sql/tst_sql.cpp | 92 ++++++++++++++++++++++---------- 3 files changed, 97 insertions(+), 28 deletions(-) create mode 100644 tests/auto/declarative/sql/data/README create mode 100644 tests/auto/declarative/sql/data/test2.js 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/test2.js b/tests/auto/declarative/sql/data/test2.js new file mode 100644 index 0000000..3acf686 --- /dev/null +++ b/tests/auto/declarative/sql/data/test2.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/tst_sql.cpp b/tests/auto/declarative/sql/tst_sql.cpp index b0a6021..cb13427 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,47 @@ 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("jsfile"); // The input file QTest::addColumn("result"); // The required output from the js test() function QTest::addColumn("databases"); // The number of databases that should have been created QTest::newRow("basic creation") << "data/test1.js" << "passed" << 1; + QTest::newRow("basic select") << "data/test2.js" << "passed" << 1; } -void tst_sql::verifyAgainstWebKit() +void tst_sql::validateAgainstWebkit_data() { - // Tests QML SQL Database support, and tests the same thing against - // WebKit (HTML5) support to validate the test. + testQml_data(); +} + +void tst_sql::validateAgainstWebkit() +{ + // 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_). @@ -66,31 +103,12 @@ void tst_sql::verifyAgainstWebKit() QFETCH(QString, result); QFETCH(int, databases); - QString tmpdir = QString(SRCDIR)+"/output"; - - // QML... - QString qml= - "import Qt 4.6\n" - "Text { Script { source: \""+jsfile+"\" } text: test() }"; - - // 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(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); @@ -100,9 +118,27 @@ void tst_sql::verifyAgainstWebKit() QWebSecurityOrigin origin = webpage.mainFrame()->securityOrigin(); QList 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); + QString qml= + "import Qt 4.6\n" + "Text { Script { source: \""+jsfile+"\" } text: test() }"; - removeRecursive(tmpdir); + engine.setOfflineStoragePath(dbDir()); + QmlComponent component(&engine, qml.toUtf8(), QUrl::fromLocalFile(SRCDIR "/empty.qml")); // just a file for relative local imports + QFxText *text = qobject_cast(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) -- cgit v0.12 From 686583c37af269137898ab01af4c2b585f91baea Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 24 Sep 2009 18:16:42 +1000 Subject: Only same-as-webkit iteration example (QML actually supports more) --- examples/declarative/sql/hello.qml | 9 +-------- 1 file changed, 1 insertion(+), 8 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) { -- cgit v0.12 From df68368889bcd71d935b916681c70ce178280fef Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 24 Sep 2009 18:18:47 +1000 Subject: More tests for QmlSql, more WebKit-tested-validity. --- src/declarative/qml/qmlsqldatabase.cpp | 118 +++++++++++++++++++-- tests/auto/declarative/sql/data/1-creation.js | 20 ++++ tests/auto/declarative/sql/data/2-selection.js | 30 ++++++ .../sql/data/3-iteration-item-function.js | 27 +++++ .../declarative/sql/data/5-iteration-iterator.js | 27 +++++ .../declarative/sql/data/6-iteration-efficient.js | 28 +++++ tests/auto/declarative/sql/data/test1.js | 20 ---- tests/auto/declarative/sql/data/test2.js | 30 ------ tests/auto/declarative/sql/tst_sql.cpp | 15 ++- 9 files changed, 256 insertions(+), 59 deletions(-) create mode 100644 tests/auto/declarative/sql/data/1-creation.js create mode 100644 tests/auto/declarative/sql/data/2-selection.js create mode 100644 tests/auto/declarative/sql/data/3-iteration-item-function.js create mode 100644 tests/auto/declarative/sql/data/5-iteration-iterator.js create mode 100644 tests/auto/declarative/sql/data/6-iteration-efficient.js delete mode 100644 tests/auto/declarative/sql/data/test1.js delete mode 100644 tests/auto/declarative/sql/data/test2.js 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 #include #include +#include #include #include #include @@ -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(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(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(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; jundefinedValue(); +} + static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEngine *engine) { QSqlDatabase db = qscriptvalue_cast(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/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/test1.js b/tests/auto/declarative/sql/data/test1.js deleted file mode 100644 index 95fa99e..0000000 --- a/tests/auto/declarative/sql/data/test1.js +++ /dev/null @@ -1,20 +0,0 @@ -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/test2.js b/tests/auto/declarative/sql/data/test2.js deleted file mode 100644 index 3acf686..0000000 --- a/tests/auto/declarative/sql/data/test2.js +++ /dev/null @@ -1,30 +0,0 @@ -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/tst_sql.cpp b/tests/auto/declarative/sql/tst_sql.cpp index cb13427..10ce6d8 100644 --- a/tests/auto/declarative/sql/tst_sql.cpp +++ b/tests/auto/declarative/sql/tst_sql.cpp @@ -82,9 +82,14 @@ void tst_sql::testQml_data() QTest::addColumn("jsfile"); // The input file QTest::addColumn("result"); // The required output from the js test() function QTest::addColumn("databases"); // The number of databases that should have been created - - QTest::newRow("basic creation") << "data/test1.js" << "passed" << 1; - QTest::newRow("basic select") << "data/test2.js" << "passed" << 1; + QTest::addColumn("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; } void tst_sql::validateAgainstWebkit_data() @@ -102,6 +107,10 @@ void tst_sql::validateAgainstWebkit() QFETCH(QString, jsfile); QFETCH(QString, result); QFETCH(int, databases); + QFETCH(bool, qmlextension); + + if (qmlextension) // WebKit can't do it (yet?) + return; QFile f(jsfile); QVERIFY(f.open(QIODevice::ReadOnly)); -- cgit v0.12 From 764601ac70042b3f733d114496b2fd5e4bbacda6 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 24 Sep 2009 18:39:12 +1000 Subject: Prevent qmlviewer from confusing people when root items are small. Task-number: QT-711 --- src/declarative/util/qmlview.cpp | 2 ++ 1 file changed, 2 insertions(+) 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()); -- cgit v0.12 From 6a741a1d3facd7a3e0f7308c7ce71a513f30ba17 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 24 Sep 2009 18:59:44 +1000 Subject: Mark an inefficency in TextEdit --- src/declarative/fx/qfxtextedit.cpp | 1 + 1 file changed, 1 insertion(+) 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()); -- cgit v0.12 From 6a297d3626c1779047812965a12f32e143e63b7d Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 24 Sep 2009 20:26:49 +1000 Subject: Fixed compile of QtDeclarative with aggressively parallel builds. QtDeclarative depends on QtWebKit. qmake has to be told about this or it might try to link QtDeclarative to QtWebKit before it has been built. Reviewed-by: Marius Storm-Olsen --- src/src.pro | 1 + 1 file changed, 1 insertion(+) 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 -- cgit v0.12