diff options
| author | 2018-07-27 23:51:12 -0400 | |
|---|---|---|
| committer | 2018-07-27 23:51:12 -0400 | |
| commit | feda8a7db8d1d7c5439aa8f8feef7cc0dd2b59a0 (patch) | |
| tree | 1e50f5f666f419143f510d5ded00fe2006b7bd85 /SQLiteStudio3/Tests | |
| parent | d9aa870e5d509cc7309ab82dd102a937ab58613a (diff) | |
New upstream version 3.2.1+dfsg1upstream/3.2.1+dfsg1
Diffstat (limited to 'SQLiteStudio3/Tests')
17 files changed, 466 insertions, 67 deletions
diff --git a/SQLiteStudio3/Tests/CompletionHelperTest/tst_completionhelpertest.cpp b/SQLiteStudio3/Tests/CompletionHelperTest/tst_completionhelpertest.cpp index fc21a55..fd5611a 100644 --- a/SQLiteStudio3/Tests/CompletionHelperTest/tst_completionhelpertest.cpp +++ b/SQLiteStudio3/Tests/CompletionHelperTest/tst_completionhelpertest.cpp @@ -63,7 +63,7 @@ CompletionHelperTest::CompletionHelperTest() QList<ExpectedToken *> CompletionHelperTest::getEntryList(QList<ExpectedTokenPtr> tokens) { QList<ExpectedToken*> entries; - foreach (ExpectedTokenPtr expectedToken, tokens) + for (ExpectedTokenPtr expectedToken : tokens) entries += expectedToken.data(); return entries; @@ -72,7 +72,7 @@ QList<ExpectedToken *> CompletionHelperTest::getEntryList(QList<ExpectedTokenPtr QSet<ExpectedToken::Type> CompletionHelperTest::getTypeList(QList<ExpectedTokenPtr> tokens) { QSet<ExpectedToken::Type> entries; - foreach (ExpectedTokenPtr expectedToken, tokens) + for (ExpectedTokenPtr expectedToken : tokens) entries += expectedToken->type; return entries; @@ -101,7 +101,7 @@ bool CompletionHelperTest::contains(const QList<ExpectedTokenPtr> &tokens, Expec int CompletionHelperTest::find(const QList<ExpectedTokenPtr> &tokens, ExpectedToken::Type type) { int i = 0; - foreach (ExpectedTokenPtr token, tokens) + for (ExpectedTokenPtr token : tokens) { if (token->type == type) return i; @@ -114,7 +114,7 @@ int CompletionHelperTest::find(const QList<ExpectedTokenPtr> &tokens, ExpectedTo int CompletionHelperTest::find(const QList<ExpectedTokenPtr> &tokens, ExpectedToken::Type type, const QString &value) { int i = -1; - foreach (ExpectedTokenPtr token, tokens) + for (ExpectedTokenPtr token : tokens) { i++; if (token->type != type) @@ -129,7 +129,7 @@ int CompletionHelperTest::find(const QList<ExpectedTokenPtr> &tokens, ExpectedTo int CompletionHelperTest::find(const QList<ExpectedTokenPtr> &tokens, ExpectedToken::Type type, const QString &value, const QString &prefix) { int i = -1; - foreach (ExpectedTokenPtr token, tokens) + for (ExpectedTokenPtr token : tokens) { i++; if (token->type != type) @@ -147,7 +147,7 @@ int CompletionHelperTest::find(const QList<ExpectedTokenPtr> &tokens, ExpectedTo int CompletionHelperTest::find(const QList<ExpectedTokenPtr> &tokens, ExpectedToken::Type type, const QString &value, const QString &prefix, const QString &contextInfo) { int i = -1; - foreach (ExpectedTokenPtr token, tokens) + for (ExpectedTokenPtr token : tokens) { i++; if (token->type != type) diff --git a/SQLiteStudio3/Tests/DsvFormatsTest/tst_dsvformatstesttest.cpp b/SQLiteStudio3/Tests/DsvFormatsTest/tst_dsvformatstesttest.cpp index bd55d53..903e6f6 100644 --- a/SQLiteStudio3/Tests/DsvFormatsTest/tst_dsvformatstesttest.cpp +++ b/SQLiteStudio3/Tests/DsvFormatsTest/tst_dsvformatstesttest.cpp @@ -14,7 +14,7 @@ class DsvFormatsTestTest : public QObject public: DsvFormatsTestTest(); - private: +private: QString toString(const QList<QStringList>& input); QList<QStringList> sampleData; @@ -27,6 +27,7 @@ class DsvFormatsTestTest : public QObject void testTsv1(); void testTsv2(); void testCsv1(); + void testCsvPerformance(); }; DsvFormatsTestTest::DsvFormatsTestTest() @@ -79,7 +80,7 @@ void DsvFormatsTestTest::testTsv1() QString result = TsvSerializer::serialize(sampleData); QString common = ""; - int i; + int i = 0; if (result != sampleTsv) { int lgt = qMax(result.length(), sampleTsv.length()); @@ -105,6 +106,30 @@ void DsvFormatsTestTest::testCsv1() QVERIFY(result.first().size() == 2); } +void DsvFormatsTestTest::testCsvPerformance() +{ + QString input; + for (int i = 0; i < 10000; i++) + input += "abc,d,g,\"jkl\nh\",mno\r\n"; + + QTemporaryFile theFile; + theFile.open(); + theFile.write(input.toLatin1()); + theFile.seek(0); + QTextStream stream(&theFile); + + QTime timer; + timer.start(); + QList<QStringList> result = CsvSerializer::deserialize(stream, CsvFormat::DEFAULT); + int time = timer.elapsed(); + + QVERIFY(result.size() == 10000); + QVERIFY(result.first().size() == 5); + QVERIFY(result.last().size() == 5); + + qDebug() << "Deserialization time:" << time; +} + QTEST_APPLESS_MAIN(DsvFormatsTestTest) #include "tst_dsvformatstesttest.moc" diff --git a/SQLiteStudio3/Tests/LexerTest/LexerTest.pro b/SQLiteStudio3/Tests/LexerTest/LexerTest.pro new file mode 100644 index 0000000..a4f2630 --- /dev/null +++ b/SQLiteStudio3/Tests/LexerTest/LexerTest.pro @@ -0,0 +1,32 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2018-07-15T23:45:16 +# +#------------------------------------------------- + +include($$PWD/../TestUtils/test_common.pri) + +QT += testlib + +QT -= gui + +TARGET = tst_lexertest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + tst_lexertest.cpp diff --git a/SQLiteStudio3/Tests/LexerTest/tst_lexertest.cpp b/SQLiteStudio3/Tests/LexerTest/tst_lexertest.cpp new file mode 100644 index 0000000..deac898 --- /dev/null +++ b/SQLiteStudio3/Tests/LexerTest/tst_lexertest.cpp @@ -0,0 +1,66 @@ +#include "parser/lexer.h" +#include <QString> +#include <QtTest> + +class LexerTest : public QObject +{ + Q_OBJECT + + public: + LexerTest(); + + private Q_SLOTS: + void testStringCase1(); + void testFloat(); + void testHex1(); + void testHex2(); +}; + +LexerTest::LexerTest() +{ +} + +void LexerTest::testStringCase1() +{ + QString sql = "INSERT INTO tab VALUES (1, 2, :val); /* test"; + + Lexer lex(Dialect::Sqlite3); + TokenList tokens = lex.tokenize(sql); + QVERIFY(tokens.size() == 20); +} + +void LexerTest::testFloat() +{ + QString sql = "SELECT .2"; + + Lexer lex(Dialect::Sqlite3); + TokenList tokens = lex.tokenize(sql); + QVERIFY(tokens.size() == 3); + QVERIFY(tokens[2]->type == Token::FLOAT); +} + +void LexerTest::testHex1() +{ + QString sql = "SELECT 0x"; + + Lexer lex(Dialect::Sqlite3); + TokenList tokens = lex.tokenize(sql); + QVERIFY(tokens.size() == 3); + QVERIFY(tokens[2]->type == Token::INVALID); +} + +void LexerTest::testHex2() +{ + QString sql = "SELECT 0x5zzz"; + + Lexer lex(Dialect::Sqlite3); + TokenList tokens = lex.tokenize(sql); + QVERIFY(tokens.size() == 4); + QVERIFY(tokens[2]->type == Token::INTEGER); + QVERIFY(tokens[3]->type == Token::OTHER); + QVERIFY(tokens[3]->value == "zzz"); +} + +QTEST_APPLESS_MAIN(LexerTest) + +#include "tst_lexertest.moc" diff --git a/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp b/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp index 7355616..eb2a76f 100644 --- a/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp +++ b/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp @@ -1,12 +1,15 @@ #include "parser/parser.h" #include "parser/ast/sqliteselect.h" #include "parser/ast/sqlitecreatetable.h" +#include "parser/ast/sqliteinsert.h" +#include "parser/ast/sqlitewith.h" +#include "parser/ast/sqliteupdate.h" #include "parser/keywords.h" #include "parser/lexer.h" #include "parser/parsererror.h" +#include "common/utils_sql.h" #include <QString> #include <QtTest> -#include <parser/ast/sqliteinsert.h> class ParserTest : public QObject { @@ -40,6 +43,12 @@ class ParserTest : public QObject void testCommentBeginMultiline(); void testBetween(); void testBigNum(); + void testSelectWith(); + void testInsertWithDoubleQuoteValues(); + void testParseAndRebuildAlias(); + void testRebuildTokensUpdate(); + void testRebuildTokensInsertUpsert(); + void testGetColumnTokensFromInsertUpsert(); void initTestCase(); void cleanupTestCase(); }; @@ -134,7 +143,7 @@ void ParserTest::testGetFullObjects() QList<SqliteStatement::FullObject> fullObjects = query->getContextFullObjects(); QVERIFY(fullObjects.size() == 2); - foreach (const SqliteStatement::FullObject& fullObj, fullObjects) + for (const SqliteStatement::FullObject& fullObj : fullObjects) { switch (fullObj.type) { @@ -162,7 +171,7 @@ void ParserTest::testGetFullObjects2() QList<SqliteStatement::FullObject> fullObjects = query->getContextFullObjects(); QVERIFY(fullObjects.size() == 5); - foreach (const SqliteStatement::FullObject& fullObj, fullObjects) + for (const SqliteStatement::FullObject& fullObj : fullObjects) { switch (fullObj.type) { @@ -401,10 +410,99 @@ void ParserTest::testUniqConflict() QVERIFY(tokens[16]->type == Token::Type::PAR_RIGHT); } +void ParserTest::testSelectWith() +{ + QString sql = "WITH m (c1, c2) AS (VALUES (1, 'a'), (2, 'b')) SELECT * FROM m;"; + bool res = parser3->parse(sql); + QVERIFY(res); + QVERIFY(parser3->getErrors().isEmpty()); + + const SqliteQueryPtr query = parser3->getQueries().first(); + query->rebuildTokens(); + QString detokenized = query->detokenize().replace(" ", ""); + QVERIFY(sql.replace(" ", "") == detokenized); +} + +void ParserTest::testInsertWithDoubleQuoteValues() +{ + QString sql = "REPLACE INTO _Variables (Name, TextValue) VALUES (\"varNowTime\", strftime(\"%Y-%m-%dT%H:%M:%S\", \"now\", \"localtime\"));"; + bool res = parser3->parse(sql); + QVERIFY(res); + QVERIFY(parser3->getErrors().isEmpty()); + + const SqliteInsertPtr insert = parser3->getQueries().first().dynamicCast<SqliteInsert>(); + insert->rebuildTokens(); + QString detokenized = insert->detokenize().replace(" ", ""); + QVERIFY(sql.replace(" ", "") == detokenized); +} + +void ParserTest::testParseAndRebuildAlias() +{ + QString sql = "SELECT x AS [\"abc\".\"def\"];"; + bool res = parser3->parse(sql); + QVERIFY(res); + QVERIFY(parser3->getErrors().isEmpty()); + + SqliteQueryPtr query = parser3->getQueries().first(); + query->rebuildTokens(); + QString newSql = query->detokenize(); + QVERIFY(sql == newSql); +} + +void ParserTest::testRebuildTokensUpdate() +{ + QString sql = "UPDATE tab SET col1 = 1, (col2, col3) = 2 WHERE x = 3;"; + bool res = parser3->parse(sql); + QVERIFY(res); + QVERIFY(parser3->getErrors().isEmpty()); + + SqliteUpdatePtr update = parser3->getQueries().first().dynamicCast<SqliteUpdate>(); + QVERIFY(update->keyValueMap.size() == 2); + QVERIFY(update->keyValueMap[1].first.type() == QVariant::StringList); + QStringList set2List = update->keyValueMap[1].first.toStringList(); + QVERIFY(set2List[0] == "col2"); + QVERIFY(set2List[1] == "col3"); + QVERIFY(update->where); + QVERIFY(!update->table.isNull()); + QVERIFY(update->where); + update->rebuildTokens(); + QVERIFY(update->tokens.detokenize() == sql); +} + +void ParserTest::testRebuildTokensInsertUpsert() +{ + QString sql = "INSERT INTO tab (a1, a2) VALUES (123, 456) ON CONFLICT (b1, b2, b3) DO UPDATE SET col1 = 1, (col2, col3) = 2 WHERE x = 3;"; + bool res = parser3->parse(sql); + QVERIFY(res); + QVERIFY(parser3->getErrors().isEmpty()); + + SqliteInsertPtr insert = parser3->getQueries().first().dynamicCast<SqliteInsert>(); + QVERIFY(insert->upsert); + + insert->rebuildTokens(); + QVERIFY(insert->tokens.detokenize() == sql); +} + +void ParserTest::testGetColumnTokensFromInsertUpsert() +{ + QString sql = "INSERT INTO tab (a1, a2) VALUES (123, 456) ON CONFLICT (b1, b2, b3) DO UPDATE SET col1 = 1, (col2, col3) = 2 WHERE x = 3;"; + bool res = parser3->parse(sql); + QVERIFY(res); + QVERIFY(parser3->getErrors().isEmpty()); + + SqliteInsertPtr insert = parser3->getQueries().first().dynamicCast<SqliteInsert>(); + QVERIFY(insert->upsert); + + TokenList tk = insert->getContextColumnTokens(); + qSort(tk.begin(), tk.end(), [](const TokenPtr& t1, const TokenPtr& t2) {return t1->start < t2->start;}); + QVERIFY(tk.toValueList().join(" ") == "a1 a2 b1 b2 b3 col1 col2 col3 x"); +} + void ParserTest::initTestCase() { initKeywords(); Lexer::staticInit(); + initUtilsSql(); parser2 = new Parser(Dialect::Sqlite2); parser3 = new Parser(Dialect::Sqlite3); } diff --git a/SQLiteStudio3/Tests/SelectResolverTest/tst_selectresolvertest.cpp b/SQLiteStudio3/Tests/SelectResolverTest/tst_selectresolvertest.cpp index 2d6762e..13a30a9 100644 --- a/SQLiteStudio3/Tests/SelectResolverTest/tst_selectresolvertest.cpp +++ b/SQLiteStudio3/Tests/SelectResolverTest/tst_selectresolvertest.cpp @@ -27,7 +27,9 @@ class SelectResolverTest : public QObject void testTableHash(); void testColumnHash(); void testWithCommonTableExpression(); + void testWithCte2(); void testStarWithJoinAndError(); + void testTableFunction(); void test1(); void testSubselectWithAlias(); }; @@ -196,6 +198,26 @@ void SelectResolverTest::testWithCommonTableExpression() QVERIFY(coreColumns[0].flags & SelectResolver::Flag::FROM_CTE_SELECT); } +void SelectResolverTest::testWithCte2() +{ + QString sql = "with m(c1, c2) as (" + " values (1, 'a'), (2, 'b'), (3, 'c')" + ")" + "select * from m"; + + SelectResolver resolver(db, sql); + Parser parser(db->getDialect()); + QVERIFY(parser.parse(sql)); + + QList<QList<SelectResolver::Column>> columns = resolver.resolve(parser.getQueries().first().dynamicCast<SqliteSelect>().data()); + QList<SelectResolver::Column> coreColumns = columns.first(); + QVERIFY(coreColumns.size() == 2); + QVERIFY(coreColumns[0].type == SelectResolver::Column::COLUMN); + QVERIFY(coreColumns[0].flags & SelectResolver::Flag::FROM_CTE_SELECT); + QVERIFY(coreColumns[1].type == SelectResolver::Column::COLUMN); + QVERIFY(coreColumns[1].flags & SelectResolver::Flag::FROM_CTE_SELECT); +} + void SelectResolverTest::testStarWithJoinAndError() { QString sql = "SELECT t1.*, t2.* FROM test t1 JOIN test2 USING (col1)"; @@ -208,6 +230,27 @@ void SelectResolverTest::testStarWithJoinAndError() QVERIFY(resolver.hasErrors()); } +void SelectResolverTest::testTableFunction() +{ + QString sql = "select * from json_tree(json_array(1, 2, 3))"; + SelectResolver resolver(db, sql); + Parser parser(db->getDialect()); + QVERIFY(parser.parse(sql)); + + SqlQueryPtr versionResult = db->exec("select sqlite_version()"); + qDebug() << "SQLite3 version:" << versionResult->getSingleCell().toString(); + + SqliteSelectPtr select = parser.getQueries().first().dynamicCast<SqliteSelect>(); + QList<QList<SelectResolver::Column> > columns = resolver.resolve(select.data()); + if (resolver.hasErrors()) { + for (const QString& err : resolver.getErrors()) + qWarning() << err; + } + QVERIFY(!resolver.hasErrors()); + QVERIFY(columns.first().size() == 8); + QVERIFY(columns.first().first().type == SelectResolver::Column::OTHER); +} + void SelectResolverTest::test1() { QString sql = "SELECT * FROM (SELECT count(col1), col2 FROM test)"; diff --git a/SQLiteStudio3/Tests/TableModifierTest/tst_tablemodifiertest.cpp b/SQLiteStudio3/Tests/TableModifierTest/tst_tablemodifiertest.cpp index 2630f36..7bb8c0e 100644 --- a/SQLiteStudio3/Tests/TableModifierTest/tst_tablemodifiertest.cpp +++ b/SQLiteStudio3/Tests/TableModifierTest/tst_tablemodifiertest.cpp @@ -55,23 +55,29 @@ void TableModifierTest::testCase1() QStringList sqls = mod.generateSqls(); /* + * 1. Disable FK. * 1. Create new (with new name) * 2. Copy data to new - * 3. Drop old table. - * 4. Rename referencing table to temp name. - * 5. Create new referencing table. - * 6. Copy data to new referencing table. - * 7. Drop temp table. + * 4. Rename referencing table to temp name in 2 steps. + * 5. Second step of renaming - drop old table. + * 6. Create new referencing table. + * 7. Copy data to new referencing table. + * 8. Drop temp table. + * 9. Drop old table. + * 10. Re-enable FK. */ - QVERIFY(sqls.size() == 7); + QVERIFY(sqls.size() == 10); int i = 0; + verifyRe("PRAGMA foreign_keys = 0;", sqls[i++]); verifyRe("CREATE TABLE test2 .*", sqls[i++]); verifyRe("INSERT INTO test2.*SELECT.*FROM test;", sqls[i++]); - verifyRe("DROP TABLE test;", sqls[i++]); - verifyRe("ALTER TABLE abc RENAME TO sqlitestudio_temp_table.*", sqls[i++]); + verifyRe("CREATE TABLE sqlitestudio_temp_table.*AS SELECT.*FROM abc.*", sqls[i++]); + verifyRe("DROP TABLE abc;", sqls[i++]); verifyRe("CREATE TABLE abc .*", sqls[i++]); verifyRe("INSERT INTO abc.*SELECT.*FROM sqlitestudio_temp_table.*", sqls[i++]); verifyRe("DROP TABLE sqlitestudio_temp_table.*", sqls[i++]); + verifyRe("DROP TABLE test;", sqls[i++]); + verifyRe("PRAGMA foreign_keys = 1;", sqls[i++]); } void TableModifierTest::testCase2() @@ -84,25 +90,33 @@ void TableModifierTest::testCase2() QStringList sqls = mod.generateSqls(); /* - * 1. Rename to temp. - * 2. Create new. - * 3. Copy data from temp to new one. - * 4. Drop temp table. - * 5. Rename referencing table to temp name. - * 6. Create new referencing table. - * 7. Copy data to new referencing table. - * 8. Drop temp table. + * 1. Disable FK. + * 2. Rename to temp in 2 steps. + * 3. Second step of renaming (drop). + * 4. Create new. + * 5. Copy data from temp to new one. + * 6. Rename referencing table to temp name in 2 steps. + * 7. Second step of renaming (drop). + * 8. Create new referencing table. + * 9. Copy data to new referencing table. + * 10. Drop first temp table. + * 11. Drop second temp table. + * 12. Enable FK. */ - QVERIFY(sqls.size() == 8); + QVERIFY(sqls.size() == 12); int i = 0; - verifyRe("ALTER TABLE test RENAME TO sqlitestudio_temp_table.*", sqls[i++]); + verifyRe("PRAGMA foreign_keys = 0;", sqls[i++]); + verifyRe("CREATE TABLE sqlitestudio_temp_table.*AS SELECT.*FROM test.*", sqls[i++]); + verifyRe("DROP TABLE test;", sqls[i++]); verifyRe("CREATE TABLE test .*newCol.*", sqls[i++]); verifyRe("INSERT INTO test.*SELECT.*FROM sqlitestudio_temp_table.*", sqls[i++]); - verifyRe("DROP TABLE sqlitestudio_temp_table.*", sqls[i++]); - verifyRe("ALTER TABLE abc RENAME TO sqlitestudio_temp_table.*", sqls[i++]); + verifyRe("CREATE TABLE sqlitestudio_temp_table.*AS SELECT.*FROM abc.*", sqls[i++]); + verifyRe("DROP TABLE abc;", sqls[i++]); verifyRe("CREATE TABLE abc .*xyz text REFERENCES test \\(newCol\\).*", sqls[i++]); verifyRe("INSERT INTO abc.*SELECT.*FROM sqlitestudio_temp_table.*", sqls[i++]); verifyRe("DROP TABLE sqlitestudio_temp_table.*", sqls[i++]); + verifyRe("DROP TABLE sqlitestudio_temp_table.*", sqls[i++]); + verifyRe("PRAGMA foreign_keys = 1;", sqls[i++]); } void TableModifierTest::testCase3() @@ -118,27 +132,33 @@ void TableModifierTest::testCase3() QStringList sqls = mod.generateSqls(); /* - * 1. Create new (with new name) - * 2. Copy data to new - * 3. Drop old table. - * 4. Rename referencing table to temp name. - * 5. Create new referencing table. - * 6. Copy data to new referencing table. - * 7. Drop temp table. - * 8. Re-create index i2. - * 9. Re-create index i1 with new table name and column name. + * 1. Disable FK. + * 2. Create new (with new name) + * 3. Copy data to new + * 4. Drop old table. + * 5. Rename referencing table to temp name in two steps. + * 6. Second step of renaming (drop). + * 7. Create new referencing table. + * 8. Copy data to new referencing table. + * 9. Drop temp table. + * 10. Re-create index i2. + * 11. Re-create index i1 with new table name and column name. + * 12. Disable FK. */ - QVERIFY(sqls.size() == 9); + QVERIFY(sqls.size() == 12); int i = 0; + verifyRe("PRAGMA foreign_keys = 0;", sqls[i++]); verifyRe("CREATE TABLE newTable .*", sqls[i++]); verifyRe("INSERT INTO newTable.*SELECT.*FROM test;", sqls[i++]); - verifyRe("DROP TABLE test;", sqls[i++]); - verifyRe("ALTER TABLE abc RENAME TO sqlitestudio_temp_table.*", sqls[i++]); + verifyRe("CREATE TABLE sqlitestudio_temp_table.*AS SELECT.*FROM abc.*", sqls[i++]); + verifyRe("DROP TABLE abc;", sqls[i++]); verifyRe("CREATE TABLE abc .*xyz text REFERENCES newTable \\(newCol\\).*", sqls[i++]); verifyRe("INSERT INTO abc.*SELECT.*FROM sqlitestudio_temp_table.*", sqls[i++]); verifyRe("DROP TABLE sqlitestudio_temp_table.*", sqls[i++]); verifyRe("CREATE INDEX i2 ON abc \\(id\\);", sqls[i++]); + verifyRe("DROP TABLE test;", sqls[i++]); verifyRe("CREATE INDEX i1 ON newTable \\(newCol\\);", sqls[i++]); + verifyRe("PRAGMA foreign_keys = 1;", sqls[i++]); } void TableModifierTest::testCase4() @@ -156,13 +176,16 @@ void TableModifierTest::testCase4() QStringList sqls = mod.generateSqls(); /* - * 1. Create new (with new name) - * 2. Copy data to new - * 3. Drop old table. - * 4. Recreate trigger with all subqueries updated. + * 1. Disable FK. + * 2. Create new (with new name) + * 3. Copy data to new + * 4. Drop old table. + * 5. Recreate trigger with all subqueries updated. + * 6. Enable FK. */ - QVERIFY(sqls.size() == 4); + QVERIFY(sqls.size() == 6); int i = 0; + verifyRe("PRAGMA foreign_keys = 0;", sqls[i++]); verifyRe("CREATE TABLE newTable .*", sqls[i++]); verifyRe("INSERT INTO newTable.*SELECT.*FROM test;", sqls[i++]); verifyRe("DROP TABLE test;", sqls[i++]); @@ -172,6 +195,7 @@ void TableModifierTest::testCase4() "UPDATE newTable SET newCol = (SELECT newCol FROM newTable) WHERE x = (SELECT newCol FROM newTable); " "INSERT INTO newTable (newCol) VALUES (1); " "END;" == sqls[i++], "Trigger DDL incorrect."); + verifyRe("PRAGMA foreign_keys = 1;", sqls[i++]); } void TableModifierTest::testCase5() @@ -188,21 +212,25 @@ void TableModifierTest::testCase5() QStringList sqls = mod.generateSqls(); /* - * 1. Create new (with new name) - * 2. Copy data to new - * 3. Drop old table. - * 4. Drop old view. - * 5. Recreate view with new column and table. - * 6. Recreate trigger with all subqueries updated. + * 1. Disable FK. + * 2. Create new (with new name) + * 3. Copy data to new + * 4. Drop old table. + * 5. Drop old view. + * 6. Recreate view with new column and table. + * 7. Recreate trigger with all subqueries updated. + * 8. Enable FK. */ - QVERIFY(sqls.size() == 6); + QVERIFY(sqls.size() == 8); int i = 0; + verifyRe("PRAGMA foreign_keys = 0;", sqls[i++]); verifyRe("CREATE TABLE newTable .*", sqls[i++]); verifyRe("INSERT INTO newTable.*SELECT.*FROM test;", sqls[i++]); verifyRe("DROP TABLE test;", sqls[i++]); verifyRe("DROP VIEW v1;", sqls[i++]); verifyRe("CREATE VIEW v1 AS SELECT \\* FROM \\(SELECT newCol FROM newTable\\);", sqls[i++]); verifyRe("CREATE TRIGGER t1 INSTEAD OF INSERT ON v1 BEGIN SELECT 1; END;", sqls[i++]); + verifyRe("PRAGMA foreign_keys = 1;", sqls[i++]); } void TableModifierTest::testCase6() @@ -217,19 +245,25 @@ void TableModifierTest::testCase6() QStringList sqls = mod.generateSqls(); /* - * 1. Create new (with new name) - * 2. Copy data to new - * 3. Drop old table. - * 4. Recreate trigger with all subqueries updated. + * 1. Disable FK. + * 2. Create new (with new name) + * 3. Copy data to new + * 4. Drop old table. + * 5. Recreate trigger with all subqueries updated. + * 6. Drop view. + * 7. Recreate view with new table referenced. + * 8. Enable FK. */ - QVERIFY(sqls.size() == 6); + QVERIFY(sqls.size() == 8); int i = 0; + verifyRe("PRAGMA foreign_keys = 0;", sqls[i++]); verifyRe("CREATE TABLE newTable \\(id int, val2 text\\);", sqls[i++]); verifyRe("INSERT INTO newTable \\(id, val2\\) SELECT id, val2 FROM test;", sqls[i++]); verifyRe("DROP TABLE test;", sqls[i++]); verifyRe("CREATE TRIGGER t2 AFTER UPDATE OF Id ON newTable BEGIN SELECT NULL, Val2 FROM newTable; END;", sqls[i++]); verifyRe("DROP VIEW v1;", sqls[i++]); verifyRe("CREATE VIEW v1 AS SELECT \\* FROM \\(SELECT Id, NULL FROM newTable\\);", sqls[i++]); + verifyRe("PRAGMA foreign_keys = 1;", sqls[i++]); } void TableModifierTest::initTestCase() diff --git a/SQLiteStudio3/Tests/TestUtils/TestUtils.pro b/SQLiteStudio3/Tests/TestUtils/TestUtils.pro index f448ccb..77e0b19 100644 --- a/SQLiteStudio3/Tests/TestUtils/TestUtils.pro +++ b/SQLiteStudio3/Tests/TestUtils/TestUtils.pro @@ -23,7 +23,8 @@ SOURCES += \ mocks.cpp \
dbattachermock.cpp \
dbmanagermock.cpp \
- collationmanagermock.cpp
+ collationmanagermock.cpp \
+ extensionmanagermock.cpp
HEADERS +=\
testutils_global.h \
@@ -35,7 +36,8 @@ HEADERS +=\ mocks.h \
dbattachermock.h \
dbmanagermock.h \
- collationmanagermock.h
+ collationmanagermock.h \
+ extensionmanagermock.h
unix:!symbian {
maemo5 {
diff --git a/SQLiteStudio3/Tests/TestUtils/configmock.cpp b/SQLiteStudio3/Tests/TestUtils/configmock.cpp index 9bf3863..5a9169a 100644 --- a/SQLiteStudio3/Tests/TestUtils/configmock.cpp +++ b/SQLiteStudio3/Tests/TestUtils/configmock.cpp @@ -35,6 +35,11 @@ QVariant ConfigMock::get(const QString&, const QString&) return QVariant(); } +QVariant ConfigMock::get(const QString &, const QString &, const QVariant &) +{ + return QVariant(); +} + QHash<QString, QVariant> ConfigMock::getAll() { return QHash<QString, QVariant>(); @@ -102,6 +107,10 @@ void ConfigMock::clearSqlHistory() { } +void ConfigMock::deleteSqlHistory(const QList<qint64>&) +{ +} + QAbstractItemModel* ConfigMock::getSqlHistoryModel() { return nullptr; @@ -124,6 +133,37 @@ QStringList ConfigMock::getCliHistory() const return QStringList(); } +void ConfigMock::addBindParamHistory(const QVector<QPair<QString, QVariant> >&) +{ +} + +void ConfigMock::applyBindParamHistoryLimit() +{ +} + +QVector<QPair<QString, QVariant> > ConfigMock::getBindParamHistory(const QStringList&) const +{ + return QVector<QPair<QString, QVariant>>(); +} + +void ConfigMock::addPopulateHistory(const QString&, const QString&, int, const QHash<QString, QPair<QString, QVariant> >&) +{ +} + +void ConfigMock::applyPopulateHistoryLimit() +{ +} + +QHash<QString, QPair<QString, QVariant>> ConfigMock::getPopulateHistory(const QString&, const QString&, int&) const +{ + return QHash<QString, QPair<QString, QVariant>>(); +} + +QVariant ConfigMock::getPopulateHistory(const QString&) const +{ + return QVariant(); +} + void ConfigMock::addDdlHistory(const QString&, const QString&, const QString&) { } diff --git a/SQLiteStudio3/Tests/TestUtils/configmock.h b/SQLiteStudio3/Tests/TestUtils/configmock.h index 89c870e..7f04e98 100644 --- a/SQLiteStudio3/Tests/TestUtils/configmock.h +++ b/SQLiteStudio3/Tests/TestUtils/configmock.h @@ -16,6 +16,7 @@ class ConfigMock : public Config void rollbackMassSave(); void set(const QString&, const QString&, const QVariant&); QVariant get(const QString&, const QString&); + QVariant get(const QString&, const QString&, const QVariant&); QHash<QString, QVariant> getAll(); bool addDb(const QString&, const QString&, const QHash<QString, QVariant>&); bool updateDb(const QString&, const QString&, const QString&, const QHash<QString, QVariant>&); @@ -30,11 +31,19 @@ class ConfigMock : public Config qint64 addSqlHistory(const QString&, const QString&, int, int); void updateSqlHistory(qint64, const QString&, const QString&, int, int); void clearSqlHistory(); + void deleteSqlHistory(const QList<qint64>&); QAbstractItemModel*getSqlHistoryModel(); void addCliHistory(const QString&); void applyCliHistoryLimit(); void clearCliHistory(); QStringList getCliHistory() const; + void addBindParamHistory(const QVector<QPair<QString, QVariant>>&); + void applyBindParamHistoryLimit(); + QVector<QPair<QString, QVariant>> getBindParamHistory(const QStringList&) const; + void addPopulateHistory(const QString&, const QString&, int, const QHash<QString, QPair<QString, QVariant>>&); + void applyPopulateHistoryLimit(); + QHash<QString, QPair<QString, QVariant>> getPopulateHistory(const QString&, const QString&, int&) const; + QVariant getPopulateHistory(const QString&) const; void addDdlHistory(const QString&, const QString&, const QString&); QList<DdlHistoryEntryPtr> getDdlHistoryFor(const QString&, const QString&, const QDate&); DdlHistoryModel* getDdlHistoryModel(); diff --git a/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp index 926e57b..10caed4 100644 --- a/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp +++ b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp @@ -57,7 +57,7 @@ Db* DbManagerMock::getByPath(const QString&) return nullptr; } -Db*DbManagerMock::createInMemDb() +Db*DbManagerMock::createInMemDb(bool) { return nullptr; } diff --git a/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h index ce7eb51..ee69fa1 100644 --- a/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h +++ b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h @@ -16,9 +16,9 @@ class DbManagerMock : public DbManager QList<Db*> getValidDbList(); QList<Db*> getConnectedDbList(); QStringList getDbNames(); - Db*getByName(const QString&, Qt::CaseSensitivity); - Db*getByPath(const QString&); - Db*createInMemDb(); + Db* getByName(const QString&, Qt::CaseSensitivity); + Db* getByPath(const QString&); + Db* createInMemDb(bool = false); bool isTemporary(Db*); QString quickAddDb(const QString &path, const QHash<QString, QVariant> &); DbPlugin* getPluginForDbFile(const QString&); diff --git a/SQLiteStudio3/Tests/TestUtils/extensionmanagermock.cpp b/SQLiteStudio3/Tests/TestUtils/extensionmanagermock.cpp new file mode 100644 index 0000000..dc4669b --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/extensionmanagermock.cpp @@ -0,0 +1,19 @@ +#include "extensionmanagermock.h" + +ExtensionManagerMock::ExtensionManagerMock() +{ +} + +void ExtensionManagerMock::setExtensions(const QList<SqliteExtensionManager::ExtensionPtr>&) +{ +} + +QList<SqliteExtensionManager::ExtensionPtr> ExtensionManagerMock::getAllExtensions() const +{ + return QList<SqliteExtensionManager::ExtensionPtr>(); +} + +QList<SqliteExtensionManager::ExtensionPtr> ExtensionManagerMock::getExtensionForDatabase(const QString&) const +{ + return QList<SqliteExtensionManager::ExtensionPtr>(); +} diff --git a/SQLiteStudio3/Tests/TestUtils/extensionmanagermock.h b/SQLiteStudio3/Tests/TestUtils/extensionmanagermock.h new file mode 100644 index 0000000..7a7a1f4 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/extensionmanagermock.h @@ -0,0 +1,17 @@ +#ifndef EXTENSIONMANAGERMOCK_H +#define EXTENSIONMANAGERMOCK_H + +#include "services/sqliteextensionmanager.h" + +class ExtensionManagerMock : public SqliteExtensionManager +{ + public: + ExtensionManagerMock(); + + public: + void setExtensions(const QList<ExtensionPtr>&); + QList<ExtensionPtr> getAllExtensions() const; + QList<ExtensionPtr> getExtensionForDatabase(const QString&) const; +}; + +#endif // EXTENSIONMANAGERMOCK_H diff --git a/SQLiteStudio3/Tests/TestUtils/mocks.cpp b/SQLiteStudio3/Tests/TestUtils/mocks.cpp index dee3bfd..bb1a226 100644 --- a/SQLiteStudio3/Tests/TestUtils/mocks.cpp +++ b/SQLiteStudio3/Tests/TestUtils/mocks.cpp @@ -7,6 +7,7 @@ #include "collationmanagermock.h" #include "dbattachermock.h" #include "dbmanagermock.h" +#include "extensionmanagermock.h" MockRepository* mockRepository = nullptr; @@ -34,4 +35,5 @@ void initMocks() SQLITESTUDIO->setDbAttacherFactory(new DbAttacherFactoryMock()); SQLITESTUDIO->setDbManager(new DbManagerMock()); SQLITESTUDIO->setCollationManager(new CollationManagerMock()); + SQLITESTUDIO->setSqliteExtensionManager(new ExtensionManagerMock()); } diff --git a/SQLiteStudio3/Tests/Tests.pro b/SQLiteStudio3/Tests/Tests.pro index 2690494..b48ea8d 100644 --- a/SQLiteStudio3/Tests/Tests.pro +++ b/SQLiteStudio3/Tests/Tests.pro @@ -32,4 +32,5 @@ SUBDIRS += \ hash_tables \
db_ver_conv \
dsv \
- UtilsTest
+ UtilsTest \
+ LexerTest
diff --git a/SQLiteStudio3/Tests/UtilsTest/tst_utilssqltest.cpp b/SQLiteStudio3/Tests/UtilsTest/tst_utilssqltest.cpp index 97c9234..2719ae4 100644 --- a/SQLiteStudio3/Tests/UtilsTest/tst_utilssqltest.cpp +++ b/SQLiteStudio3/Tests/UtilsTest/tst_utilssqltest.cpp @@ -14,6 +14,7 @@ private Q_SLOTS: void testRemoveEmpties();
void testRemoveComments();
void testRemoveCommentsAndEmpties();
+ void testDoubleToString();
};
UtilsSqlTest::UtilsSqlTest()
@@ -70,6 +71,16 @@ void UtilsSqlTest::testRemoveCommentsAndEmpties() QVERIFY2(sp[0] == "select 'dfgh ;sdg /*''*/ dfga' from aa;", failure.arg(sp[0]).toLatin1().data());
}
+void UtilsSqlTest::testDoubleToString()
+{
+ QVERIFY(doubleToString(QVariant(5.001)) == "5.001");
+ QVERIFY(doubleToString(QVariant(5.0000001)) == "5.0000001");
+ QVERIFY(doubleToString(QVariant(5.000000000000000000000000001)) == "5.0"); // too big, considered as round 5
+ QVERIFY(doubleToString(QVariant(0.0000001)) == "0.0000001");
+ QVERIFY(doubleToString(QVariant(9.99999999999998)) == "9.99999999999998");
+ QVERIFY(doubleToString(QVariant(0.1 + 0.1 + 0.1)) == "0.3");
+}
+
QTEST_APPLESS_MAIN(UtilsSqlTest)
#include "tst_utilssqltest.moc"
|
