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 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