From 7167ce41b61d2ba2cdb526777a4233eb84a3b66a Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Sat, 6 Dec 2014 17:33:25 -0500 Subject: Imported Upstream version 2.99.6 --- .../CompletionHelperTest/CompletionHelperTest.pro | 21 + .../tst_completionhelpertest.cpp | 398 ++++ .../DbVersionConverterTest.pro | 21 + .../tst_dbversionconvertertesttest.cpp | 119 + .../Tests/DsvFormatsTest/DsvFormatsTest.pro | 20 + .../DsvFormatsTest/tst_dsvformatstesttest.cpp | 73 + .../Tests/HashTablesTest/HashTablesTest.pro | 21 + .../HashTablesTest/tst_hashtablestesttest.cpp | 219 ++ SQLiteStudio3/Tests/ParserTest/ParserTest.pro | 20 + SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp | 357 +++ .../SelectResolverTest/SelectResolverTest.pro | 19 + .../SelectResolverTest/tst_selectresolvertest.cpp | 248 ++ .../Tests/TableModifierTest/TableModifierTest.pro | 19 + .../TableModifierTest/tst_tablemodifiertest.cpp | 266 +++ SQLiteStudio3/Tests/TestUtils/TestUtils.pro | 52 + .../Tests/TestUtils/collationmanagermock.cpp | 29 + .../Tests/TestUtils/collationmanagermock.h | 18 + SQLiteStudio3/Tests/TestUtils/configmock.cpp | 206 ++ SQLiteStudio3/Tests/TestUtils/configmock.h | 60 + SQLiteStudio3/Tests/TestUtils/dbattachermock.cpp | 35 + SQLiteStudio3/Tests/TestUtils/dbattachermock.h | 23 + SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp | 81 + SQLiteStudio3/Tests/TestUtils/dbmanagermock.h | 30 + SQLiteStudio3/Tests/TestUtils/dbsqlite3mock.cpp | 8 + SQLiteStudio3/Tests/TestUtils/dbsqlite3mock.h | 15 + .../Tests/TestUtils/functionmanagermock.cpp | 38 + .../Tests/TestUtils/functionmanagermock.h | 21 + SQLiteStudio3/Tests/TestUtils/hippomocks.h | 2361 ++++++++++++++++++++ SQLiteStudio3/Tests/TestUtils/mocks.cpp | 37 + SQLiteStudio3/Tests/TestUtils/mocks.h | 11 + .../Tests/TestUtils/pluginmanagermock.cpp | 162 ++ SQLiteStudio3/Tests/TestUtils/pluginmanagermock.h | 46 + SQLiteStudio3/Tests/TestUtils/test_common.pri | 6 + SQLiteStudio3/Tests/TestUtils/testutils_global.h | 12 + SQLiteStudio3/Tests/Tests.pro | 31 + SQLiteStudio3/Tests/testdirs.pri | 4 + 36 files changed, 5107 insertions(+) create mode 100644 SQLiteStudio3/Tests/CompletionHelperTest/CompletionHelperTest.pro create mode 100644 SQLiteStudio3/Tests/CompletionHelperTest/tst_completionhelpertest.cpp create mode 100644 SQLiteStudio3/Tests/DbVersionConverterTest/DbVersionConverterTest.pro create mode 100644 SQLiteStudio3/Tests/DbVersionConverterTest/tst_dbversionconvertertesttest.cpp create mode 100644 SQLiteStudio3/Tests/DsvFormatsTest/DsvFormatsTest.pro create mode 100644 SQLiteStudio3/Tests/DsvFormatsTest/tst_dsvformatstesttest.cpp create mode 100644 SQLiteStudio3/Tests/HashTablesTest/HashTablesTest.pro create mode 100644 SQLiteStudio3/Tests/HashTablesTest/tst_hashtablestesttest.cpp create mode 100644 SQLiteStudio3/Tests/ParserTest/ParserTest.pro create mode 100644 SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp create mode 100644 SQLiteStudio3/Tests/SelectResolverTest/SelectResolverTest.pro create mode 100644 SQLiteStudio3/Tests/SelectResolverTest/tst_selectresolvertest.cpp create mode 100644 SQLiteStudio3/Tests/TableModifierTest/TableModifierTest.pro create mode 100644 SQLiteStudio3/Tests/TableModifierTest/tst_tablemodifiertest.cpp create mode 100644 SQLiteStudio3/Tests/TestUtils/TestUtils.pro create mode 100644 SQLiteStudio3/Tests/TestUtils/collationmanagermock.cpp create mode 100644 SQLiteStudio3/Tests/TestUtils/collationmanagermock.h create mode 100644 SQLiteStudio3/Tests/TestUtils/configmock.cpp create mode 100644 SQLiteStudio3/Tests/TestUtils/configmock.h create mode 100644 SQLiteStudio3/Tests/TestUtils/dbattachermock.cpp create mode 100644 SQLiteStudio3/Tests/TestUtils/dbattachermock.h create mode 100644 SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp create mode 100644 SQLiteStudio3/Tests/TestUtils/dbmanagermock.h create mode 100644 SQLiteStudio3/Tests/TestUtils/dbsqlite3mock.cpp create mode 100644 SQLiteStudio3/Tests/TestUtils/dbsqlite3mock.h create mode 100644 SQLiteStudio3/Tests/TestUtils/functionmanagermock.cpp create mode 100644 SQLiteStudio3/Tests/TestUtils/functionmanagermock.h create mode 100644 SQLiteStudio3/Tests/TestUtils/hippomocks.h create mode 100644 SQLiteStudio3/Tests/TestUtils/mocks.cpp create mode 100644 SQLiteStudio3/Tests/TestUtils/mocks.h create mode 100644 SQLiteStudio3/Tests/TestUtils/pluginmanagermock.cpp create mode 100644 SQLiteStudio3/Tests/TestUtils/pluginmanagermock.h create mode 100644 SQLiteStudio3/Tests/TestUtils/test_common.pri create mode 100644 SQLiteStudio3/Tests/TestUtils/testutils_global.h create mode 100644 SQLiteStudio3/Tests/Tests.pro create mode 100644 SQLiteStudio3/Tests/testdirs.pri (limited to 'SQLiteStudio3/Tests') diff --git a/SQLiteStudio3/Tests/CompletionHelperTest/CompletionHelperTest.pro b/SQLiteStudio3/Tests/CompletionHelperTest/CompletionHelperTest.pro new file mode 100644 index 0000000..d4c1e99 --- /dev/null +++ b/SQLiteStudio3/Tests/CompletionHelperTest/CompletionHelperTest.pro @@ -0,0 +1,21 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-03-29T21:35:35 +# +#------------------------------------------------- + +include($$PWD/../TestUtils/test_common.pri) + +QT += testlib +QT -= gui + +TARGET = tst_completionhelpertest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +SOURCES += tst_completionhelpertest.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" + +HEADERS += diff --git a/SQLiteStudio3/Tests/CompletionHelperTest/tst_completionhelpertest.cpp b/SQLiteStudio3/Tests/CompletionHelperTest/tst_completionhelpertest.cpp new file mode 100644 index 0000000..fc21a55 --- /dev/null +++ b/SQLiteStudio3/Tests/CompletionHelperTest/tst_completionhelpertest.cpp @@ -0,0 +1,398 @@ +#include "completionhelper.h" +#include "expectedtoken.h" +#include "dbsqlite3mock.h" +#include "parser/lexer.h" +#include "parser/token.h" +#include "parser/keywords.h" +#include "sqlitestudio.h" +#include "mocks.h" +#include +#include +#include + + +class CompletionHelperTest : public QObject +{ + Q_OBJECT + + public: + CompletionHelperTest(); + + private: + QList getEntryList(QList tokens); + QSet getTypeList(QList tokens); + + Db* db = nullptr; + + bool contains(const QList& tokens, ExpectedToken::Type type); + bool contains(const QList& tokens, ExpectedToken::Type type, + const QString& value); + bool contains(const QList& tokens, ExpectedToken::Type type, + const QString& value, const QString& prefix); + bool contains(const QList &tokens, ExpectedToken::Type type, + const QString &value, const QString &prefix, const QString &contextInfo); + + int find(const QList& tokens, ExpectedToken::Type type); + int find(const QList& tokens, ExpectedToken::Type type, + const QString& value); + int find(const QList& tokens, ExpectedToken::Type type, + const QString& value, const QString& prefix); + int find(const QList &tokens, ExpectedToken::Type type, + const QString &value, const QString &prefix, const QString &contextInfo); + + private Q_SLOTS: + void testResCol1(); + void testFrom1(); + void testFrom2(); + void testResCol2(); + void testResCol3(); + void testResCol4(); + void testResCol5(); + void testResCol6(); + void testFromKw(); + void testUpdateTable(); + void testUpdateCols1(); + void initTestCase(); + void cleanupTestCase(); +}; + +CompletionHelperTest::CompletionHelperTest() +{ +} + +QList CompletionHelperTest::getEntryList(QList tokens) +{ + QList entries; + foreach (ExpectedTokenPtr expectedToken, tokens) + entries += expectedToken.data(); + + return entries; +} + +QSet CompletionHelperTest::getTypeList(QList tokens) +{ + QSet entries; + foreach (ExpectedTokenPtr expectedToken, tokens) + entries += expectedToken->type; + + return entries; +} + +bool CompletionHelperTest::contains(const QList &tokens, ExpectedToken::Type type) +{ + return find(tokens, type) > -1; +} + +bool CompletionHelperTest::contains(const QList &tokens, ExpectedToken::Type type, const QString &value) +{ + return find(tokens, type, value) > -1; +} + +bool CompletionHelperTest::contains(const QList &tokens, ExpectedToken::Type type, const QString &value, const QString &prefix) +{ + return find(tokens, type, value, prefix) > -1; +} + +bool CompletionHelperTest::contains(const QList &tokens, ExpectedToken::Type type, const QString &value, const QString &prefix, const QString &contextInfo) +{ + return find(tokens, type, value, prefix, contextInfo) > -1; +} + +int CompletionHelperTest::find(const QList &tokens, ExpectedToken::Type type) +{ + int i = 0; + foreach (ExpectedTokenPtr token, tokens) + { + if (token->type == type) + return i; + + i++; + } + return -1; +} + +int CompletionHelperTest::find(const QList &tokens, ExpectedToken::Type type, const QString &value) +{ + int i = -1; + foreach (ExpectedTokenPtr token, tokens) + { + i++; + if (token->type != type) + continue; + + if (token->value == value) + return i; + } + return -1; +} + +int CompletionHelperTest::find(const QList &tokens, ExpectedToken::Type type, const QString &value, const QString &prefix) +{ + int i = -1; + foreach (ExpectedTokenPtr token, tokens) + { + i++; + if (token->type != type) + continue; + + if (token->value != value) + continue; + + if (token->prefix == prefix) + return i; + } + return -1; +} + +int CompletionHelperTest::find(const QList &tokens, ExpectedToken::Type type, const QString &value, const QString &prefix, const QString &contextInfo) +{ + int i = -1; + foreach (ExpectedTokenPtr token, tokens) + { + i++; + if (token->type != type) + continue; + + if (token->value != value) + continue; + + if (token->prefix != prefix) + continue; + + if (token->contextInfo == contextInfo) + return i; + } + return -1; +} + +void CompletionHelperTest::testFrom1() +{ + QString sql = "select * FROM "; + CompletionHelper helper(sql, db); + QList tokens = helper.getExpectedTokens().filtered(); + + QVERIFY(contains(tokens, ExpectedToken::TABLE, "test")); + QVERIFY(contains(tokens, ExpectedToken::TABLE, "sqlite_master")); + QVERIFY(contains(tokens, ExpectedToken::TABLE, "sqlite_temp_master")); + QVERIFY(contains(tokens, ExpectedToken::DATABASE, "main")); +} + +void CompletionHelperTest::testFrom2() +{ + QString sql = "select id from abc, "; + CompletionHelper helper(sql, db); + QList tokens = helper.getExpectedTokens().filtered(); + +// QList entries = getEntryList(tokens); + + QVERIFY(contains(tokens, ExpectedToken::TABLE)); + QVERIFY(contains(tokens, ExpectedToken::DATABASE)); + QVERIFY(!contains(tokens, ExpectedToken::FUNCTION)); + QVERIFY(!contains(tokens, ExpectedToken::COLUMN)); + + // Because abc was already used, the order should be: + // test + // sqlite_master + // sqlite_temp_master + // abc + QVERIFY(find(tokens, ExpectedToken::TABLE, "test") == 0); + QVERIFY(find(tokens, ExpectedToken::TABLE, "sqlite_master") == 1); + QVERIFY(find(tokens, ExpectedToken::TABLE, "sqlite_temp_master") == 2); + QVERIFY(find(tokens, ExpectedToken::TABLE, "abc") == 3); +} + +void CompletionHelperTest::testResCol1() +{ + QString sql = "select main.test."; + CompletionHelper helper(sql, db); + QList tokens = helper.getExpectedTokens().filtered(); + + QVERIFY(!contains(tokens, ExpectedToken::COLUMN, "name")); + QVERIFY(contains(tokens, ExpectedToken::COLUMN, "id")); + QVERIFY(contains(tokens, ExpectedToken::COLUMN, "val")); +} + +void CompletionHelperTest::testResCol2() +{ + QString sql = "select "; + CompletionHelper helper(sql, db); + QList tokens = helper.getExpectedTokens().filtered(); + + //QList entries = getEntryList(tokens); + + // Exclude JOIN keywords and FK MATCH keywords + QVERIFY(!contains(tokens, ExpectedToken::KEYWORD, "NATURAL")); + QVERIFY(!contains(tokens, ExpectedToken::KEYWORD, "CROSS")); + QVERIFY(!contains(tokens, ExpectedToken::KEYWORD, "SIMPLE")); + QVERIFY(!contains(tokens, ExpectedToken::KEYWORD, "FULL")); + + // Exclude OTHER as there is at least one CTX token available + QVERIFY(!contains(tokens, ExpectedToken::OTHER)); + + QVERIFY(contains(tokens, ExpectedToken::DATABASE)); + QVERIFY(contains(tokens, ExpectedToken::FUNCTION)); + QVERIFY(contains(tokens, ExpectedToken::TABLE, "sqlite_master")); + QVERIFY(contains(tokens, ExpectedToken::COLUMN, "name", QString::null)); + QVERIFY(contains(tokens, ExpectedToken::COLUMN, "id", QString::null)); +} + +void CompletionHelperTest::testResCol3() +{ + QString sql = "select from test"; + CompletionHelper helper(sql, 7, db); + QList tokens = helper.getExpectedTokens().filtered(); + + //QList entries = getEntryList(tokens); + + QVERIFY(contains(tokens, ExpectedToken::TABLE)); + QVERIFY(contains(tokens, ExpectedToken::DATABASE)); + QVERIFY(contains(tokens, ExpectedToken::FUNCTION)); + QVERIFY(contains(tokens, ExpectedToken::COLUMN, "id", QString::null)); + QVERIFY(contains(tokens, ExpectedToken::COLUMN, "val", QString::null)); + + // Order should be: + // id - test (no prefix value) + // val - test (default, no prefix value) + // val2 - test (default, no prefix value) + // id - abc (no prefix, we didn't mention other table in from clause) + QVERIFY(find(tokens, ExpectedToken::COLUMN, "id", QString::null, "test") == 0); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "val", QString::null, "test") == 1); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "val2", QString::null, "test") == 2); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "id", QString::null, "abc") == 3); +} + +void CompletionHelperTest::testResCol4() +{ + QString sql = "select test.id, from test"; + CompletionHelper helper(sql, 15, db); + QList tokens = helper.getExpectedTokens().filtered(); + + //QList entries = getEntryList(tokens); + + QVERIFY(contains(tokens, ExpectedToken::TABLE)); + QVERIFY(contains(tokens, ExpectedToken::DATABASE)); + QVERIFY(contains(tokens, ExpectedToken::FUNCTION)); + + // Because test.id was already used, the order should be: + // val - test (default, no prefix value) + // val2 - test (default, no prefix value) + // id - test (no prefix, only one table in FROM) + // id - abc (no prefix, only one table in FROM) + QVERIFY(find(tokens, ExpectedToken::COLUMN, "val", QString::null, "test") == 0); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "val2", QString::null, "test") == 1); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "id", QString::null, "test") == 2); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "id", QString::null, "abc") == 3); +} + +void CompletionHelperTest::testResCol5() +{ + QString sql = "select test.id, val from test"; + CompletionHelper helper(sql, 15, db); + QList tokens = helper.getExpectedTokens().filtered(); + + //QList entries = getEntryList(tokens); + + QVERIFY(contains(tokens, ExpectedToken::TABLE)); + QVERIFY(contains(tokens, ExpectedToken::DATABASE)); + QVERIFY(contains(tokens, ExpectedToken::FUNCTION)); + + // Because test.id and val were already used, the order should be: + // val2 - test (default, no prefix value) + // id - test + // val - test (default, no prefix value) + // id - abc (no prefix, only one table in FROM) + QVERIFY(find(tokens, ExpectedToken::COLUMN, "val2") == 0); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "id", QString::null, "test") == 1); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "val") == 2); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "id", QString::null, "abc") == 3); +} + +void CompletionHelperTest::testResCol6() +{ + QString sql = "select (select from sqlite_master as S, sqlite_master as S2) from test as A"; + CompletionHelper helper(sql, 15, db); + QList tokens = helper.getExpectedTokens().filtered(); + + //QList entries = getEntryList(tokens); + + QVERIFY(contains(tokens, ExpectedToken::TABLE)); + QVERIFY(contains(tokens, ExpectedToken::DATABASE)); + QVERIFY(contains(tokens, ExpectedToken::FUNCTION)); + + // Desired order: + // S.name - sqlite_master S (can be second or first) + // S.name - sqlite_master S2 (can be second or first) + // ... + // id - test (default, no prefix) + // ... + // id - abc (no prefix, only one table with this column in FROM) + // ... + int s_sqlite_master_name = find(tokens, ExpectedToken::COLUMN, "name", "S", "sqlite_master"); + int s2_sqlite_master_name = find(tokens, ExpectedToken::COLUMN, "name", "S2", "sqlite_master"); + int test_id = find(tokens, ExpectedToken::COLUMN, "id", "A", "test"); + int abc_id = find(tokens, ExpectedToken::COLUMN, "id", QString::null, "abc"); + QVERIFY(s_sqlite_master_name <= 1); + QVERIFY(s2_sqlite_master_name <= 1); + QVERIFY(test_id > s2_sqlite_master_name); + QVERIFY(abc_id > test_id); +} + +void CompletionHelperTest::testFromKw() +{ + QString sql = "select * FR"; + CompletionHelper helper(sql, db); + QList tokens = helper.getExpectedTokens().filtered(); + + QVERIFY(contains(tokens, ExpectedToken::KEYWORD, "FROM")); + QVERIFY(!contains(tokens, ExpectedToken::COLUMN)); + QVERIFY(tokens.size() == 1); +} + +void CompletionHelperTest::testUpdateTable() +{ + QString sql = "update "; + CompletionHelper helper(sql, db); + QList tokens = helper.getExpectedTokens().filtered(); + + QVERIFY(contains(tokens, ExpectedToken::TABLE)); +} + +void CompletionHelperTest::testUpdateCols1() +{ + QString sql = "update test set id = 5, "; + CompletionHelper helper(sql, db); + QList tokens = helper.getExpectedTokens().filtered(); + + // TODO if table is provided and there is at least one column in proposal for it, then skip columns from other tables. + // TODO Make the context more precise - distinguish between left side column from right side expression + + QVERIFY(find(tokens, ExpectedToken::COLUMN, "id", QString::null, "test") == 0); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "val", QString::null, "test") == 1); + QVERIFY(find(tokens, ExpectedToken::COLUMN, "val2", QString::null, "test") == 2); + //QVERIFY(!contains(tokens, ExpectedToken::COLUMN, "id", QString::null, "abc")); // TODO +} + +void CompletionHelperTest::initTestCase() +{ + initKeywords(); + Lexer::staticInit(); + CompletionHelper::init(); + initMocks(); + + db = new DbSqlite3Mock("testdb"); + db->open(); + db->exec("CREATE TABLE test (id int, val text, val2 text);"); + db->exec("CREATE TABLE abc (id int, xyz text);"); +} + +void CompletionHelperTest::cleanupTestCase() +{ + db->close(); + delete db; + db = nullptr; + deleteMockRepo(); +} + +QTEST_APPLESS_MAIN(CompletionHelperTest) + +#include "tst_completionhelpertest.moc" diff --git a/SQLiteStudio3/Tests/DbVersionConverterTest/DbVersionConverterTest.pro b/SQLiteStudio3/Tests/DbVersionConverterTest/DbVersionConverterTest.pro new file mode 100644 index 0000000..cc50c4d --- /dev/null +++ b/SQLiteStudio3/Tests/DbVersionConverterTest/DbVersionConverterTest.pro @@ -0,0 +1,21 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-05-04T00:44:01 +# +#------------------------------------------------- + +include($$PWD/../TestUtils/test_common.pri) + +QT += testlib + +QT -= gui + +TARGET = tst_dbversionconvertertesttest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + + +SOURCES += tst_dbversionconvertertesttest.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/SQLiteStudio3/Tests/DbVersionConverterTest/tst_dbversionconvertertesttest.cpp b/SQLiteStudio3/Tests/DbVersionConverterTest/tst_dbversionconvertertesttest.cpp new file mode 100644 index 0000000..7d69e7e --- /dev/null +++ b/SQLiteStudio3/Tests/DbVersionConverterTest/tst_dbversionconvertertesttest.cpp @@ -0,0 +1,119 @@ +#include "dbversionconverter.h" +#include "parser/lexer.h" +#include "parser/keywords.h" +#include +#include + +class DbVersionConverterTestTest : public QObject +{ + Q_OBJECT + + public: + DbVersionConverterTestTest(); + + private Q_SLOTS: + void initTestCase(); + void init(); + void cleanupTestCase(); + void testColumnAutoIncr(); + void testIndexedColumn(); + void testInsertMultiValues(); + void testSelectWith(); + void testTableWithoutRowId(); + void testTableWithDefaultCtime(); + + private: + void printErrors(); + + DbVersionConverter* converter = nullptr; +}; + +DbVersionConverterTestTest::DbVersionConverterTestTest() +{ +} + +void DbVersionConverterTestTest::testColumnAutoIncr() +{ + QString query = "CREATE TABLE test (col INTEGER PRIMARY KEY AUTOINCREMENT);"; + QString result = converter->convert3To2(query); + + printErrors(); + QVERIFY(converter->getErrors().size() == 0); + QVERIFY(result == "CREATE TABLE test (col INTEGER PRIMARY KEY);"); +} + +void DbVersionConverterTestTest::testIndexedColumn() +{ + QString query = "CREATE INDEX idx ON test (col COLLATE NOCASE ASC);"; + QString result = converter->convert3To2(query); + + printErrors(); + QVERIFY(converter->getErrors().size() == 0); + QVERIFY(result == "CREATE INDEX idx ON test (col ASC);"); +} + +void DbVersionConverterTestTest::testInsertMultiValues() +{ + QString query = "INSERT INTO test (col1, col2) VALUES (1, 'a'), (2, 'b');"; + QString result = converter->convert3To2(query); + + printErrors(); + QVERIFY(converter->getErrors().size() == 0); + QVERIFY(result == "INSERT INTO test (col1, col2) SELECT 1, 'a' UNION ALL SELECT 2, 'b';"); +} + +void DbVersionConverterTestTest::testSelectWith() +{ + QString query = "WITH RECURSIVE cnt (x) AS (VALUES(1) UNION ALL SELECT x + 1 FROM cnt WHERE x < 1000000) SELECT x FROM cnt;"; + QString result = converter->convert3To2(query); + + QVERIFY(converter->getErrors().size() == 1); + QVERIFY(result == ";"); +} + +void DbVersionConverterTestTest::testTableWithoutRowId() +{ + QString query = "CREATE TABLE test (col PRIMARY KEY) WITHOUT ROWID;"; + QString result = converter->convert3To2(query); + + printErrors(); + QVERIFY(converter->getErrors().size() == 0); + QVERIFY(result == "CREATE TABLE test (col PRIMARY KEY);"); +} + +void DbVersionConverterTestTest::testTableWithDefaultCtime() +{ + QString query = "CREATE TABLE test (col INT DEFAULT current_date NOT NULL);"; + QString result = converter->convert3To2(query); + + printErrors(); + QVERIFY(converter->getErrors().size() == 0); + QVERIFY(result == "CREATE TABLE test (col INT NOT NULL);"); +} + +void DbVersionConverterTestTest::printErrors() +{ + for (const QString& err : converter->getErrors()) + qWarning() << err; +} + +void DbVersionConverterTestTest::initTestCase() +{ + initKeywords(); + Lexer::staticInit(); + converter = new DbVersionConverter(); +} + +void DbVersionConverterTestTest::init() +{ + converter->reset(); +} + +void DbVersionConverterTestTest::cleanupTestCase() +{ + delete converter; +} + +QTEST_APPLESS_MAIN(DbVersionConverterTestTest) + +#include "tst_dbversionconvertertesttest.moc" diff --git a/SQLiteStudio3/Tests/DsvFormatsTest/DsvFormatsTest.pro b/SQLiteStudio3/Tests/DsvFormatsTest/DsvFormatsTest.pro new file mode 100644 index 0000000..42a08d3 --- /dev/null +++ b/SQLiteStudio3/Tests/DsvFormatsTest/DsvFormatsTest.pro @@ -0,0 +1,20 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-11-21T20:58:39 +# +#------------------------------------------------- + +include($$PWD/../TestUtils/test_common.pri) + +QT += testlib + +QT -= gui + +TARGET = tst_dsvformatstesttest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +SOURCES += tst_dsvformatstesttest.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/SQLiteStudio3/Tests/DsvFormatsTest/tst_dsvformatstesttest.cpp b/SQLiteStudio3/Tests/DsvFormatsTest/tst_dsvformatstesttest.cpp new file mode 100644 index 0000000..48e7280 --- /dev/null +++ b/SQLiteStudio3/Tests/DsvFormatsTest/tst_dsvformatstesttest.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include "tsvserializer.h" +#include "csvserializer.h" + +// TODO Add tests for CsvSerializer + +class DsvFormatsTestTest : public QObject +{ + Q_OBJECT + + public: + DsvFormatsTestTest(); + + private: + QList sampleData; + QString sampleTsv; + + private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + void testTsv1(); +}; + +DsvFormatsTestTest::DsvFormatsTestTest() +{ +} + +void DsvFormatsTestTest::initTestCase() +{ + sampleData << QStringList{"a", "b c", "\"d\""}; + sampleData << QStringList{"a\"a\"", "\"b\"c\"", "d\"\"e"}; + sampleData << QStringList{"a\na", "b\tc", "d\t\"e"}; + +#ifdef Q_OS_MACX + QString lineSep = "\r"; +#else + QString lineSep = "\n"; +#endif + + sampleTsv = ""; + sampleTsv += "a\tb c\t\"d\""; + sampleTsv += lineSep; + sampleTsv += "a\"a\"\t\"b\"c\"\td\"\"e"; + sampleTsv += lineSep; + sampleTsv += "\"a\na\"\t\"b\tc\"\t\"d\t\"\"e\""; +} + +void DsvFormatsTestTest::cleanupTestCase() +{ +} + +void DsvFormatsTestTest::testTsv1() +{ + QString result = TsvSerializer::serialize(sampleData); + + QString common = ""; + int i; + if (result != sampleTsv) + { + int lgt = qMax(result.length(), sampleTsv.length()); + for (i = 0; i < lgt && result[i] == sampleTsv[i]; i++) + common.append(result[i]); + } + + QVERIFY2(result == sampleTsv, QString("Mismatch after %1: %2\nSample: %3\nGot : %4").arg(i).arg(common, sampleTsv, result).toLocal8Bit().data()); +} + +QTEST_APPLESS_MAIN(DsvFormatsTestTest) + +#include "tst_dsvformatstesttest.moc" diff --git a/SQLiteStudio3/Tests/HashTablesTest/HashTablesTest.pro b/SQLiteStudio3/Tests/HashTablesTest/HashTablesTest.pro new file mode 100644 index 0000000..c0e071e --- /dev/null +++ b/SQLiteStudio3/Tests/HashTablesTest/HashTablesTest.pro @@ -0,0 +1,21 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-02-12T16:34:55 +# +#------------------------------------------------- + +include($$PWD/../TestUtils/test_common.pri) + +QT += testlib + +QT -= gui + +TARGET = tst_hashtablestesttest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + + +SOURCES += tst_hashtablestesttest.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/SQLiteStudio3/Tests/HashTablesTest/tst_hashtablestesttest.cpp b/SQLiteStudio3/Tests/HashTablesTest/tst_hashtablestesttest.cpp new file mode 100644 index 0000000..f729e37 --- /dev/null +++ b/SQLiteStudio3/Tests/HashTablesTest/tst_hashtablestesttest.cpp @@ -0,0 +1,219 @@ +#include "common/strhash.h" +#include "common/bistrhash.h" +#include "common/bihash.h" +#include +#include +#include + +class HashTablesTestTest : public QObject +{ + Q_OBJECT + + public: + HashTablesTestTest(); + + private Q_SLOTS: + void strHash1(); + void strHash2(); + void strHash3(); + void strHash4(); + void strHash5(); + void strHash6(); + void biStrHash1(); + void biStrHash2(); + void biStrHash3(); + void biHash1(); + void biHash2(); +}; + +HashTablesTestTest::HashTablesTestTest() +{ +} + +void HashTablesTestTest::strHash1() +{ + StrHash hash; + hash.insert("key1", "value1"); + hash.insert("key2", "value2"); + hash.insert("KEY2", "value3"); + + QVERIFY(hash.contains("KEY1", Qt::CaseInsensitive)); + QVERIFY(!hash.contains("KEY1", Qt::CaseSensitive)); + QVERIFY(hash.contains("key2", Qt::CaseInsensitive)); + QVERIFY(!hash.contains("key2", Qt::CaseSensitive)); + QVERIFY(hash.value("key2", Qt::CaseInsensitive) == "value3"); +} + +void HashTablesTestTest::strHash2() +{ + StrHash hash; + hash.insert("key1", "value1"); + hash.insert("KEY2", "value2"); + hash.insert("KEY3", "value3"); + + hash.remove("key2"); + QVERIFY(hash.count() == 3); + + hash.remove("key2", Qt::CaseInsensitive); + QVERIFY(hash.count() == 2); +} + +void HashTablesTestTest::strHash3() +{ + StrHash hash1; + hash1.insert("key1", "value1"); + hash1.insert("KEY2", "value2"); + hash1.insert("KEY3", "value3"); + + StrHash hash2; + hash2.insert("key3", "value6"); + hash2.insert("KEY4", "value7"); + hash2.insert("KEY5", "value8"); + + hash1.unite(hash2); + + QVERIFY(hash1.count() == 5); + QVERIFY(hash1.contains("key3", Qt::CaseSensitive)); + QVERIFY(hash1.value("key3", Qt::CaseInsensitive) == "value6"); +} + +void HashTablesTestTest::strHash4() +{ + StrHash hash; + hash["key1"] = "value1"; + hash["KEY2"] = "value2"; + hash["KEY3"] = "value3"; + hash["key3"] = "value4"; + + QVERIFY(hash.count() == 3); + QVERIFY(hash.value("key3", Qt::CaseSensitive) == "value4"); + QVERIFY(hash.values().size() == 3); + QVERIFY(hash.keys().size() == 3); +} + +void HashTablesTestTest::strHash5() +{ + StrHash hash; + hash["key1"] = "value1"; + hash["KEY2"] = "value2"; + hash["KEY3"] = "value3"; + hash["key3"] = "value4"; + + QVERIFY(hash.count("key1", Qt::CaseInsensitive) == 1); + QVERIFY(hash.count("key2", Qt::CaseInsensitive) == 1); + QVERIFY(hash.count("key3", Qt::CaseInsensitive) == 1); + QVERIFY(hash.count("KEY3", Qt::CaseInsensitive) == 1); + QVERIFY(hash.count("key1", Qt::CaseSensitive) == 1); + QVERIFY(hash.count("key2", Qt::CaseSensitive) == 0); + QVERIFY(hash.count("key3", Qt::CaseSensitive) == 1); +} + +void HashTablesTestTest::strHash6() +{ + StrHash hash; + hash["key1"] = "value1"; + hash["KEY2"] = "value2"; + hash["KEY3"] = "value3"; + + QVERIFY(hash["key3"] == "value3"); +} + +void HashTablesTestTest::biStrHash1() +{ + BiStrHash hash; + hash.insert("left1", "right1"); + hash.insert("LEFT2", "right2"); + hash.insert("left3", "RIGHT3"); + hash.insert("LEFT4", "RIGHT4"); + + QVERIFY(hash.count() == 4); + QVERIFY(hash.containsLeft("left1", Qt::CaseSensitive)); + QVERIFY(!hash.containsLeft("left2", Qt::CaseSensitive)); + QVERIFY(hash.containsLeft("left2", Qt::CaseInsensitive)); + QVERIFY(hash.containsRight("right1", Qt::CaseSensitive)); + QVERIFY(!hash.containsRight("right3", Qt::CaseSensitive)); + QVERIFY(hash.containsRight("right3", Qt::CaseInsensitive)); + QVERIFY(hash.valueByLeft("left4", Qt::CaseInsensitive) == "RIGHT4"); +} + +void HashTablesTestTest::biStrHash2() +{ + BiStrHash hash; + hash.insert("left1", "right1"); + hash.insert("LEFT2", "right2"); + hash.insert("left3", "RIGHT3"); + hash.insert("LEFT4", "RIGHT4"); + hash.insert("LEFT5", "RIGHT5"); + hash.insert("LEFT6", "RIGHT6"); + hash.insert("LEFT7", "RIGHT7"); + hash.insert("left5", "x"); + hash.insert("y", "right6"); + + QVERIFY(hash.count() == 7); + + hash.removeLeft("left2"); + hash.removeLeft("left3"); + hash.removeLeft("left4", Qt::CaseInsensitive); + hash.removeRight("RIGHT1"); + hash.removeRight("right7", Qt::CaseInsensitive); + + QVERIFY(hash.count() == 4); + QVERIFY(!hash.containsLeft("LEFT5")); + QVERIFY(hash.valueByLeft("LEFT5", Qt::CaseInsensitive) == "x"); + QVERIFY(!hash.containsRight("RIGHT6")); + QVERIFY(hash.valueByRight("RIGHT6", Qt::CaseInsensitive) == "y"); +} + +void HashTablesTestTest::biStrHash3() +{ + BiStrHash hash; + hash.insert("left1", "right1"); + hash.insert("LEFT2", "RIGHT2"); + + QVERIFY(hash.count() == 2); + + hash.insert("left2", "RIGHT1"); + + QVERIFY(hash.count() == 1); + QVERIFY(hash.valueByLeft("left2") == "RIGHT1"); + QVERIFY(hash.valueByRight("RIGHT1") == "left2"); + QVERIFY(hash.valueByLeft("LEFT2", Qt::CaseInsensitive) == "RIGHT1"); + QVERIFY(hash.valueByRight("right1", Qt::CaseInsensitive) == "left2"); +} + +void HashTablesTestTest::biHash1() +{ + BiHash hash; + hash.insert("left", "right"); + hash.insert("LEFT", "RIGHT"); + + QVERIFY(hash.count() == 2); + QVERIFY(hash.valueByLeft("left") == "right"); + QVERIFY(hash.valueByRight("RIGHT") == "LEFT"); + + QVERIFY(hash.removeLeft("x") == 0); + QVERIFY(hash.removeLeft("left") == 1); + QVERIFY(hash.count() == 1); + QVERIFY(hash.removeRight("RIGHT") == 1); + QVERIFY(hash.count() == 0); +} + +void HashTablesTestTest::biHash2() +{ + BiHash hash; + hash.insert("left", "right"); + hash.insert("LEFT", "RIGHT"); + + QVERIFY(hash.count() == 2); + + hash.insert("left", "RIGHT"); + + QVERIFY(hash.count() == 1); + QVERIFY(hash.valueByLeft("left") == "RIGHT"); + QVERIFY(hash.takeRight("RIGHT") == "left"); + QVERIFY(hash.count() == 0); +} + +QTEST_APPLESS_MAIN(HashTablesTestTest) + +#include "tst_hashtablestesttest.moc" diff --git a/SQLiteStudio3/Tests/ParserTest/ParserTest.pro b/SQLiteStudio3/Tests/ParserTest/ParserTest.pro new file mode 100644 index 0000000..baccb77 --- /dev/null +++ b/SQLiteStudio3/Tests/ParserTest/ParserTest.pro @@ -0,0 +1,20 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-05-30T16:51:11 +# +#------------------------------------------------- + +include($$PWD/../TestUtils/test_common.pri) + +QT += testlib +QT -= gui + +TARGET = tst_parsertest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + + +SOURCES += tst_parsertest.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp b/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp new file mode 100644 index 0000000..5eb96a8 --- /dev/null +++ b/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp @@ -0,0 +1,357 @@ +#include "parser/parser.h" +#include "parser/ast/sqliteselect.h" +#include "parser/ast/sqlitecreatetable.h" +#include "parser/keywords.h" +#include "parser/lexer.h" +#include "parser/parsererror.h" +#include +#include +#include + +class ParserTest : public QObject +{ + Q_OBJECT + + public: + ParserTest(); + + private: + Parser* parser2 = nullptr; + Parser* parser3 = nullptr; + + private Q_SLOTS: + void testGetTableTokens(); + void testGetTableTokens2(); + void testGetDatabaseTokens(); + void testGetFullObjects(); + void testGetFullObjects2(); + void testUnfinishedSingleSourceWithTolerance(); + void testCommentEnding1(); + void testCommentEnding2(); + void testOper1(); + void testBig1(); + void testTableFk(); + void testDoubleQuotes(); + void testInsertError(); + void testExpr(); + void testCommentBeginMultiline(); + void initTestCase(); + void cleanupTestCase(); +}; + +ParserTest::ParserTest() +{ +} + +void ParserTest::testGetTableTokens() +{ + QString sql = "select someTable.* FROM someTable;"; + + parser3->parse(sql); + QVERIFY(parser3->getErrors().size() == 0); + + SqliteQueryPtr query = parser3->getQueries()[0]; + TokenList tokens = query->getContextTableTokens(); + QVERIFY(tokens.size() == 2); + QVERIFY(tokens[0]->type == Token::OTHER); + QVERIFY(tokens[1]->type == Token::OTHER); +} + +void ParserTest::testGetTableTokens2() +{ + QString sql = "select db.tab.col FROM someTable;"; + + parser3->parse(sql); + QVERIFY(parser3->getErrors().size() == 0); + + SqliteQueryPtr query = parser3->getQueries()[0]; + TokenList tokens = query->getContextTableTokens(); + QVERIFY(tokens.size() == 2); + QVERIFY(tokens[0]->type == Token::OTHER); + QVERIFY(tokens[1]->type == Token::OTHER); +} + +void ParserTest::testGetDatabaseTokens() +{ + QString sql = "select * FROM someDb.[table];"; + + parser3->parse(sql); + QVERIFY(parser3->getErrors().size() == 0); + + SqliteQueryPtr query = parser3->getQueries()[0]; + TokenList tokens = query->getContextTableTokens(); + QVERIFY(tokens.size() == 1); + QVERIFY(tokens[0]->type == Token::OTHER); +} + +void ParserTest::testGetFullObjects() +{ + QString sql = "select col FROM someDb.[table];"; + + parser3->parse(sql); + QVERIFY(parser3->getErrors().size() == 0); + + SqliteQueryPtr query = parser3->getQueries()[0]; + QList fullObjects = query->getContextFullObjects(); + QVERIFY(fullObjects.size() == 2); + + foreach (const SqliteStatement::FullObject& fullObj, fullObjects) + { + switch (fullObj.type) + { + case SqliteStatement::FullObject::TABLE: + QVERIFY(fullObj.database && fullObj.database->value == "someDb"); + QVERIFY(fullObj.object && fullObj.object->value == "[table]"); + break; + case SqliteStatement::FullObject::DATABASE: + QVERIFY(fullObj.database && fullObj.database->value == "someDb"); + break; + default: + QFAIL("Unexpected FullObject type."); + } + } +} + +void ParserTest::testGetFullObjects2() +{ + QString sql = "select col, tab2.*, abcDb.abcTab.abcCol FROM someDb.[table];"; + + parser3->parse(sql); + QVERIFY(parser3->getErrors().size() == 0); + + SqliteQueryPtr query = parser3->getQueries()[0]; + QList fullObjects = query->getContextFullObjects(); + QVERIFY(fullObjects.size() == 5); + + foreach (const SqliteStatement::FullObject& fullObj, fullObjects) + { + switch (fullObj.type) + { + case SqliteStatement::FullObject::TABLE: + { + QVERIFY(fullObj.object); + if (fullObj.database && fullObj.database->value == "someDb") + QVERIFY(fullObj.object->value == "[table]"); + else if (fullObj.database && fullObj.database->value == "abcDb") + QVERIFY(fullObj.object->value == "abcTab"); + else if (!fullObj.database) + QVERIFY(fullObj.object->value == "tab2"); + else + QFAIL("Invalid TABLE full object."); + + break; + } + case SqliteStatement::FullObject::DATABASE: + { + if (fullObj.database) + QVERIFY(fullObj.database->value == "someDb" || fullObj.database->value == "abcDb"); + else + QFAIL("Invalid DATABASE full object."); + + break; + } + default: + QFAIL("Unexpected FullObject type."); + } + } +} + +void ParserTest::testUnfinishedSingleSourceWithTolerance() +{ + QString sql = "SELECT * FROM test.;"; + bool res = parser3->parse(sql, true); + QVERIFY(res); +} + +void ParserTest::testCommentEnding1() +{ + QString sql = "select 1 --aaa"; + bool res = parser3->parse(sql); + QVERIFY(res); +} + +void ParserTest::testCommentEnding2() +{ + QString sql = "select 1 /*aaa"; + bool res = parser3->parse(sql); + QVERIFY(res); +} + +void ParserTest::testOper1() +{ + QString sql = "SELECT dfgd<=2"; + TokenList tokens = Lexer::tokenize(sql, Dialect::Sqlite3); + QVERIFY(tokens[2]->value == "dfgd"); + QVERIFY(tokens[3]->value == "<="); + QVERIFY(tokens[4]->value == "2"); +} + +void ParserTest::testBig1() +{ + QString sql = "select " + "''|| " + "''|| " + "''|| " + "''|| " + "''|| " + "''|| " + "''|| " + "'Ð�TH;°Ñ禅TH;°Ð»Ñ즅TH;½Ð¸Ðº Ñ㦅TH;¿ÑঅTH;°Ð²Ð»ÐµÐ½Ð¸Ñ怜t;/P1>'|| " + "''|| " + "''||strftime('%d.%m.%Y',d.demdate)||''|| " + "'4642'||substr('000000'||d.id, -6, 6)||''|| " + "''|| " + "''||ins.fullname||''|| " + "''||ins.shortname||''|| " + "'0'||ins.regnum||''|| " + "''|| " + "''||ins.inn||''|| " + "''||ins.kpp||''|| " + "''||ins.addr||''|| " + "''||ins.postaddr||''|| " + "''||round(dem_s+dem_n+dem_f+dem_t,2)||''|| " + "''||strftime('%d.%m.%Y',d.demdate,'+15 day')||''|| " + "'0,00'|| " + "'0,00'|| " + "''|| " + "'0,00'|| " + "''|| " + "'0,00'|| " + "'0,00'|| " + "''|| " + "'0,00'|| " + "''|| " + "'0,00'|| " + "'0,00'|| " + "''||round(dem_s+dem_n+dem_f+dem_t,2)||''|| " + "''||round(dem_s+dem_n,2)||''|| " + "'0,00'|| " + "''||round(dem_s,2)||''|| " + "''||case when d.dem_s>0 then '(ÐꦅTH;ᦅTH;ꠧ'||kbk.kbk_s||')' else '' end || ''|| " + "''||round(dem_n,2)||''|| " + "''||case when d.dem_n>0 then '(ÐꦅTH;ᦅTH;ꠧ'||kbk.kbk_n||')' else '' end||''|| " + "''||round(dem_f,2)||''|| " + "''||case when d.dem_f>0 then '(ÐꦅTH;ᦅTH;ꠧ'||kbk.kbk_f||')' else '' end||''|| " + "''||round(dem_t,2)||''|| " + "''||case when d.dem_t>0 then '(ÐꦅTH;ᦅTH;ꠧ'||kbk.kbk_t||')' else '' end||''|| " + "'0,00'|| " + "'0,00 0,00 0,00 0,00'|| " + "'Ñ঎tilde;㦅TH;±.;'|| " + "'0,00'|| " + "''|| " + "'0,00'|| " + "''|| " + "'0,00'|| " + "''|| " + "'0,00'|| " + "''|| " + "'0,00'|| " + "''|| " + "''|| " + "''|| " + "''||strftime('%d.%m.%Y',d.demdate)||''|| " + "'0'|| " + "''|| " + "'0'|| " + "''|| " + "''||ins.Specname||''|| " + "''|| " + "'' " + "from demands d " + "left join ins on ins.regnum=d.regnum " + "left join kbk on kbk.cat=ins.Cat " + "limit 1"; + + bool res = parser3->parse(sql); + if (!res) + { + qWarning() << parser3->getErrorString(); + ParserError* error = parser3->getErrors().first(); + qDebug() << "Error starts at:" << sql.mid(error->getFrom()); + } + + QVERIFY(res); +} + +void ParserTest::testTableFk() +{ + QString sql = "CREATE TABLE test (id INTEGER, FOREIGN KEY (id) REFERENCES test2 (id2));"; + + parser3->parse(sql); + QVERIFY(parser3->getErrors().size() == 0); + + SqliteQueryPtr query = parser3->getQueries()[0]; + SqliteCreateTablePtr creatrTable = query.dynamicCast(); + QVERIFY(creatrTable->constraints.size() == 1); + QVERIFY(creatrTable->constraints.first()->indexedColumns.size() == 1); + QVERIFY(creatrTable->constraints.first()->indexedColumns.first()->name == "id"); + QVERIFY(creatrTable->constraints.first()->type == SqliteCreateTable::Constraint::FOREIGN_KEY); + QVERIFY(creatrTable->constraints.first()->foreignKey != nullptr); + QVERIFY(creatrTable->constraints.first()->foreignKey->foreignTable == "test2"); + QVERIFY(creatrTable->constraints.first()->foreignKey->indexedColumns.size() == 1); + QVERIFY(creatrTable->constraints.first()->foreignKey->indexedColumns.first()->name == "id2"); +} + +void ParserTest::testDoubleQuotes() +{ + QString sql = "select \"1\""; + bool res = parser3->parse(sql); + QVERIFY(res); + QVERIFY(parser3->getQueries().size() > 0); + + SqliteQueryPtr query = parser3->getQueries().first(); + QVERIFY(query); + + SqliteSelectPtr select = query.dynamicCast(); + QVERIFY(select); + QVERIFY(select->coreSelects.size() > 0); + QVERIFY(select->coreSelects.first()->resultColumns.size() > 0); + + SqliteSelect::Core::ResultColumn* rc = select->coreSelects.first()->resultColumns.first(); + SqliteExpr* e = rc->expr; + QVERIFY(e); + + QVERIFY(e->mode == SqliteExpr::Mode::ID); + QVERIFY(e->possibleDoubleQuotedString); +} + +void ParserTest::testInsertError() +{ + QString sql = "INSERT INTO test "; + bool res = parser3->parse(sql); + QVERIFY(!res); + QVERIFY(parser3->getErrors().size() == 1); +} + +void ParserTest::testExpr() +{ + QString sql = "CAST (CASE WHEN port REGEXP '^[A-Z]' THEN substr(port, 2) ELSE port END AS INT) AS port"; + SqliteExpr* expr = parser3->parseExpr(sql); + QVERIFY(expr); +} + +void ParserTest::testCommentBeginMultiline() +{ + QString sql = "/*"; + TokenList tokens = Lexer::tokenize(sql, Dialect::Sqlite3); + QVERIFY(tokens.size() == 1); + QVERIFY(tokens[0]->type == Token::COMMENT); +} + +void ParserTest::initTestCase() +{ + initKeywords(); + Lexer::staticInit(); + parser2 = new Parser(Dialect::Sqlite2); + parser3 = new Parser(Dialect::Sqlite3); +} + +void ParserTest::cleanupTestCase() +{ + delete parser2; + delete parser3; +} + +QTEST_APPLESS_MAIN(ParserTest) + +#include "tst_parsertest.moc" diff --git a/SQLiteStudio3/Tests/SelectResolverTest/SelectResolverTest.pro b/SQLiteStudio3/Tests/SelectResolverTest/SelectResolverTest.pro new file mode 100644 index 0000000..d533c7e --- /dev/null +++ b/SQLiteStudio3/Tests/SelectResolverTest/SelectResolverTest.pro @@ -0,0 +1,19 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-04-05T00:10:49 +# +#------------------------------------------------- + +include($$PWD/../TestUtils/test_common.pri) + +QT += testlib +QT -= gui + +TARGET = tst_selectresolvertest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +SOURCES += tst_selectresolvertest.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/SQLiteStudio3/Tests/SelectResolverTest/tst_selectresolvertest.cpp b/SQLiteStudio3/Tests/SelectResolverTest/tst_selectresolvertest.cpp new file mode 100644 index 0000000..969ebad --- /dev/null +++ b/SQLiteStudio3/Tests/SelectResolverTest/tst_selectresolvertest.cpp @@ -0,0 +1,248 @@ +#include "selectresolver.h" +#include "db/db.h" +#include "parser/keywords.h" +#include "parser/lexer.h" +#include "parser/parser.h" +#include "parser/parser.h" +#include "dbsqlite3mock.h" +#include "mocks.h" +#include "parser/parser.h" +#include +#include +#include + +class SelectResolverTest : public QObject +{ + Q_OBJECT + + public: + SelectResolverTest(); + + private: + Db* db = nullptr; + + private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + void testTableHash(); + void testColumnHash(); + void testWithCommonTableExpression(); + void testStarWithJoinAndError(); + void test1(); +}; + +SelectResolverTest::SelectResolverTest() +{ +} + +void SelectResolverTest::testTableHash() +{ + QSet tables; + + SelectResolver::Table t1; + t1.database = "d1"; + t1.table = "t1"; + t1.alias = "a1"; + tables << t1; + + // different alias and database + SelectResolver::Table t2; + t2.database = "d2"; + t2.table = "t1"; + t2.alias = QString::null; + tables << t2; + + // different database + SelectResolver::Table t3; + t3.database = "d2"; + t3.table = "t1"; + t3.alias = "a1"; + tables << t3; + + // same as t3 + SelectResolver::Table t4; + t4.database = "d2"; + t4.table = "t1"; + t4.alias = "a1"; + tables << t4; + + // all null + SelectResolver::Table t5; + tables << t5; + + // same as t5 + SelectResolver::Table t6; + tables << t6; + + // similar to t1, but different database + SelectResolver::Table t7; + t7.database = "x"; + t7.table = "t1"; + t7.alias = "a1"; + tables << t7; + + // similar to t1, but different table + SelectResolver::Table t8; + t8.database = "d1"; + t8.table = "x"; + t8.alias = "a1"; + tables << t8; + + // similar to t1, but different alias + SelectResolver::Table t9; + t9.database = "d1"; + t9.table = "t1"; + t9.alias = "x"; + tables << t9; + + QVERIFY(tables.size() == 7); +} + +void SelectResolverTest::testColumnHash() +{ + QSet columns; + + SelectResolver::Column c1; + c1.database = "d1"; + c1.table = "t1"; + c1.column = "c1"; + c1.alias = "a1"; + c1.tableAlias = "ta1"; + c1.displayName = "d1"; + c1.type = SelectResolver::Column::COLUMN; + columns << c1; + + // This should be treated as equal to c1. + SelectResolver::Column c2; + c2.database = "d1"; + c2.table = "t1"; + c2.column = "c1"; + c2.alias = "x"; + c2.tableAlias = "ta1"; + c2.displayName = "x"; + c2.type = SelectResolver::Column::OTHER; + columns << c2; + + // Different database + SelectResolver::Column c3; + c3.database = "x"; + c3.table = "t1"; + c3.column = "c1"; + c3.alias = "x"; + c3.tableAlias = "ta1"; + c3.displayName = "x"; + c3.type = SelectResolver::Column::OTHER; + columns << c3; + + // Different table + SelectResolver::Column c4; + c4.database = "d1"; + c4.table = "x"; + c4.column = "c1"; + c4.alias = "x"; + c4.tableAlias = "ta1"; + c4.displayName = "x"; + c4.type = SelectResolver::Column::OTHER; + columns << c4; + + // Different column + SelectResolver::Column c5; + c5.database = "d1"; + c5.table = "t1"; + c5.column = "x"; + c5.alias = "x"; + c5.tableAlias = "ta1"; + c5.displayName = "x"; + c5.type = SelectResolver::Column::OTHER; + columns << c5; + + // Different table alias + SelectResolver::Column c6; + c6.database = "d1"; + c6.table = "t1"; + c6.column = "c1"; + c6.alias = "x"; + c6.tableAlias = "x"; + c6.displayName = "x"; + c6.type = SelectResolver::Column::OTHER; + columns << c6; + + QVERIFY(columns.size() == 5); +} + +void SelectResolverTest::testWithCommonTableExpression() +{ + // Test with query from examples from SQLite documentation + QString sql = "WITH RECURSIVE works_for_alice(n) AS (" + " VALUES('Alice')" + " UNION" + " SELECT name" + " FROM org, works_for_alice" + " WHERE org.boss = works_for_alice.n" + " )" + " SELECT avg(height)" + " FROM org" + " WHERE org.name IN works_for_alice"; + + SelectResolver resolver(db, sql); + Parser parser(db->getDialect()); + QVERIFY(parser.parse(sql)); + + QList> columns = resolver.resolve(parser.getQueries().first().dynamicCast().data()); + QList coreColumns = columns.first(); + QVERIFY(coreColumns.size() == 1); + QVERIFY(coreColumns[0].type == SelectResolver::Column::OTHER); + QVERIFY(coreColumns[0].flags & SelectResolver::Flag::FROM_CTE_SELECT); +} + +void SelectResolverTest::testStarWithJoinAndError() +{ + QString sql = "SELECT t1.*, t2.* FROM test t1 JOIN test2 USING (col1)"; + SelectResolver resolver(db, sql); + Parser parser(db->getDialect()); + QVERIFY(parser.parse(sql)); + + QList > columns = resolver.resolve(parser.getQueries().first().dynamicCast().data()); + QVERIFY(columns.first().size() == 3); + QVERIFY(resolver.hasErrors()); +} + +void SelectResolverTest::test1() +{ + QString sql = "SELECT * FROM (SELECT count(col1), col2 FROM test)"; + SelectResolver resolver(db, sql); + Parser parser(db->getDialect()); + QVERIFY(parser.parse(sql)); + + QList > columns = resolver.resolve(parser.getQueries().first().dynamicCast().data()); + QList coreColumns = columns.first(); + QVERIFY(coreColumns[0].type == SelectResolver::Column::OTHER); + QVERIFY(coreColumns[1].type == SelectResolver::Column::COLUMN); + QVERIFY(coreColumns[1].table == "test"); + QVERIFY(coreColumns[1].column == "col2"); +} + +void SelectResolverTest::initTestCase() +{ + initKeywords(); + Lexer::staticInit(); + initMocks(); + + db = new DbSqlite3Mock("testdb"); + db->open(); + db->exec("CREATE TABLE test (col1, col2, col3);"); + db->exec("CREATE TABLE org (name TEXT PRIMARY KEY, boss TEXT REFERENCES org, height INT)"); + db->exec("CREATE TABLE test2 (col1);"); + //SqlQueryPtr results = db->exec("SELECT name FROM sqlite_master"); +} + +void SelectResolverTest::cleanupTestCase() +{ + db->close(); + delete db; + db = nullptr; +} + +QTEST_APPLESS_MAIN(SelectResolverTest) + +#include "tst_selectresolvertest.moc" diff --git a/SQLiteStudio3/Tests/TableModifierTest/TableModifierTest.pro b/SQLiteStudio3/Tests/TableModifierTest/TableModifierTest.pro new file mode 100644 index 0000000..ed0f6f7 --- /dev/null +++ b/SQLiteStudio3/Tests/TableModifierTest/TableModifierTest.pro @@ -0,0 +1,19 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-11-23T15:08:59 +# +#------------------------------------------------- + +include($$PWD/../TestUtils/test_common.pri) + +QT += testlib +QT -= gui + +TARGET = tst_tablemodifiertest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +SOURCES += tst_tablemodifiertest.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/SQLiteStudio3/Tests/TableModifierTest/tst_tablemodifiertest.cpp b/SQLiteStudio3/Tests/TableModifierTest/tst_tablemodifiertest.cpp new file mode 100644 index 0000000..2630f36 --- /dev/null +++ b/SQLiteStudio3/Tests/TableModifierTest/tst_tablemodifiertest.cpp @@ -0,0 +1,266 @@ +#include "parser/keywords.h" +#include "parser/lexer.h" +#include "tablemodifier.h" +#include "parser/parser.h" +#include "db/db.h" +#include "dbsqlite3mock.h" +#include "mocks.h" +#include +#include +#include + +class TableModifierTest : public QObject +{ + Q_OBJECT + + public: + TableModifierTest(); + + private: + void verifyRe(const QString& re, const QString& sql, Qt::CaseSensitivity cs = Qt::CaseSensitive); + + Db* db = nullptr; + static const constexpr char* mainTableDdl = "CREATE TABLE test (id int, val text, val2 text);"; + SqliteCreateTablePtr createTable; + + private Q_SLOTS: + void initTestCase(); + void init(); + void cleanup(); + void testCase1(); + void testCase2(); + void testCase3(); + void testCase4(); + void testCase5(); + void testCase6(); +}; + +TableModifierTest::TableModifierTest() +{ +} + +void TableModifierTest::verifyRe(const QString& re, const QString& sql, Qt::CaseSensitivity cs) +{ + QRegExp regExp(re, cs); + QVERIFY2(regExp.exactMatch(sql), QString("Failed RegExp validation:\n%1\nfor SQL:\n%2").arg(re).arg(sql).toLatin1().data()); +} + +void TableModifierTest::testCase1() +{ + db->exec("CREATE TABLE abc (id int, xyz text REFERENCES test (val));"); + + TableModifier mod(db, "test"); + createTable->table = "test2"; + mod.alterTable(createTable); + 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. + */ + QVERIFY(sqls.size() == 7); + int i = 0; + 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 abc .*", sqls[i++]); + verifyRe("INSERT INTO abc.*SELECT.*FROM sqlitestudio_temp_table.*", sqls[i++]); + verifyRe("DROP TABLE sqlitestudio_temp_table.*", sqls[i++]); +} + +void TableModifierTest::testCase2() +{ + db->exec("CREATE TABLE abc (id int, xyz text REFERENCES test (val));"); + + TableModifier mod(db, "test"); + createTable->columns[1]->name = "newCol"; + mod.alterTable(createTable); + 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. + */ + QVERIFY(sqls.size() == 8); + int i = 0; + verifyRe("ALTER TABLE test RENAME TO sqlitestudio_temp_table.*", 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 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++]); +} + +void TableModifierTest::testCase3() +{ + db->exec("CREATE TABLE abc (id int, xyz text REFERENCES test (val));"); + db->exec("CREATE INDEX i1 ON test (val);"); + db->exec("CREATE INDEX i2 ON abc (id);"); + + TableModifier mod(db, "test"); + createTable->table = "newTable"; + createTable->columns[1]->name = "newCol"; + mod.alterTable(createTable); + 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. + */ + QVERIFY(sqls.size() == 9); + int i = 0; + 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 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("CREATE INDEX i1 ON newTable \\(newCol\\);", sqls[i++]); +} + +void TableModifierTest::testCase4() +{ + db->exec("CREATE TRIGGER t1 AFTER UPDATE OF Val ON Test BEGIN " + "SELECT * FROM (SELECT Val FROM Test); " + "UPDATE Test SET Val = (SELECT Val FROM Test) WHERE x = (SELECT Val FROM Test); " + "INSERT INTO Test (val) VALUES (1); " + "END;"); + + TableModifier mod(db, "test"); + createTable->table = "newTable"; + createTable->columns[1]->name = "newCol"; + mod.alterTable(createTable); + 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. + */ + QVERIFY(sqls.size() == 4); + int i = 0; + verifyRe("CREATE TABLE newTable .*", sqls[i++]); + verifyRe("INSERT INTO newTable.*SELECT.*FROM test;", sqls[i++]); + verifyRe("DROP TABLE test;", sqls[i++]); + QVERIFY2("CREATE TRIGGER t1 AFTER UPDATE OF newCol ON newTable " + "BEGIN " + "SELECT * FROM (SELECT newCol FROM newTable); " + "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."); +} + +void TableModifierTest::testCase5() +{ + db->exec("CREATE VIEW v1 AS SELECT * FROM (SELECT Val FROM Test);"); + db->exec("CREATE TRIGGER t1 INSTEAD OF INSERT ON v1 BEGIN SELECT 1; END;"); + db->exec("CREATE TRIGGER t2 AFTER INSERT ON v1 BEGIN SELECT 1; END;"); + db->exec("CREATE TRIGGER t3 INSTEAD OF INSERT ON test BEGIN SELECT 1; END;"); + + TableModifier mod(db, "test"); + createTable->table = "newTable"; + createTable->columns[1]->name = "newCol"; + mod.alterTable(createTable); + 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. + */ + QVERIFY(sqls.size() == 6); + int i = 0; + 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++]); +} + +void TableModifierTest::testCase6() +{ + db->exec("CREATE VIEW v1 AS SELECT * FROM (SELECT Id, Val FROM Test);"); + db->exec("CREATE TRIGGER t2 AFTER UPDATE OF Id, Val ON Test BEGIN SELECT Val, Val2 FROM Test; END;"); + + TableModifier mod(db, "test"); + createTable->table = "newTable"; + createTable->columns.removeAt(1); + mod.alterTable(createTable); + 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. + */ + QVERIFY(sqls.size() == 6); + int i = 0; + 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++]); +} + +void TableModifierTest::initTestCase() +{ + initKeywords(); + Lexer::staticInit(); +} + +void TableModifierTest::init() +{ + initMocks(); + + db = new DbSqlite3Mock("testdb"); + db->open(); + db->exec(mainTableDdl); + + Parser parser(db->getDialect()); + Q_ASSERT(parser.parse(mainTableDdl)); + Q_ASSERT(parser.getQueries().size() > 0); + createTable = parser.getQueries().first().dynamicCast(); + Q_ASSERT(!createTable.isNull()); +} + +void TableModifierTest::cleanup() +{ + db->close(); + delete db; + db = nullptr; +} + + +QTEST_APPLESS_MAIN(TableModifierTest) + +#include "tst_tablemodifiertest.moc" diff --git a/SQLiteStudio3/Tests/TestUtils/TestUtils.pro b/SQLiteStudio3/Tests/TestUtils/TestUtils.pro new file mode 100644 index 0000000..26600e1 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/TestUtils.pro @@ -0,0 +1,52 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-03-29T23:25:17 +# +#------------------------------------------------- + +include(test_common.pri) + +QT -= gui + +TARGET = TestUtils +TEMPLATE = lib + +QMAKE_CXXFLAGS += -std=c++11 + +DEFINES += TESTUTILS_LIBRARY + +SOURCES += \ + dbsqlite3mock.cpp \ + functionmanagermock.cpp \ + pluginmanagermock.cpp \ + configmock.cpp \ + mocks.cpp \ + dbattachermock.cpp \ + dbmanagermock.cpp \ + collationmanagermock.cpp + +HEADERS +=\ + testutils_global.h \ + dbsqlite3mock.h \ + hippomocks.h \ + functionmanagermock.h \ + pluginmanagermock.h \ + configmock.h \ + mocks.h \ + dbattachermock.h \ + dbmanagermock.h \ + collationmanagermock.h + +unix:!symbian { + maemo5 { + target.path = /opt/usr/lib + } else { + target.path = /usr/lib + } + INSTALLS += target +} + +LIBS += -lcoreSQLiteStudio -lsqlite3 + +OTHER_FILES += \ + test_common.pri diff --git a/SQLiteStudio3/Tests/TestUtils/collationmanagermock.cpp b/SQLiteStudio3/Tests/TestUtils/collationmanagermock.cpp new file mode 100644 index 0000000..640a252 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/collationmanagermock.cpp @@ -0,0 +1,29 @@ +#include "collationmanagermock.h" + +CollationManagerMock::CollationManagerMock() +{ +} + +void CollationManagerMock::setCollations(const QList&) +{ +} + +QList CollationManagerMock::getAllCollations() const +{ + return QList(); +} + +QList CollationManagerMock::getCollationsForDatabase(const QString&) const +{ + return QList(); +} + +int CollationManagerMock::evaluate(const QString&, const QString&, const QString&) +{ + return 0; +} + +int CollationManagerMock::evaluateDefault(const QString&, const QString&) +{ + return 0; +} diff --git a/SQLiteStudio3/Tests/TestUtils/collationmanagermock.h b/SQLiteStudio3/Tests/TestUtils/collationmanagermock.h new file mode 100644 index 0000000..eb08b7b --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/collationmanagermock.h @@ -0,0 +1,18 @@ +#ifndef COLLATIONMANAGERMOCK_H +#define COLLATIONMANAGERMOCK_H + +#include "services/collationmanager.h" + +class CollationManagerMock : public CollationManager +{ + public: + CollationManagerMock(); + + void setCollations(const QList&); + QList getAllCollations() const; + QList getCollationsForDatabase(const QString&) const; + int evaluate(const QString&, const QString&, const QString&); + int evaluateDefault(const QString&, const QString&); +}; + +#endif // COLLATIONMANAGERMOCK_H diff --git a/SQLiteStudio3/Tests/TestUtils/configmock.cpp b/SQLiteStudio3/Tests/TestUtils/configmock.cpp new file mode 100644 index 0000000..8b62dc2 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/configmock.cpp @@ -0,0 +1,206 @@ +#include "configmock.h" + +void ConfigMock::init() +{ +} + +void ConfigMock::cleanUp() +{ +} + +const QString& ConfigMock::getConfigDir() +{ + static const QString cfg; + return cfg; +} + +void ConfigMock::beginMassSave() +{ +} + +void ConfigMock::commitMassSave() +{ +} + +void ConfigMock::rollbackMassSave() +{ +} + +void ConfigMock::set(const QString&, const QString&, const QVariant&) +{ +} + +QVariant ConfigMock::get(const QString&, const QString&) +{ + return QVariant(); +} + +QHash ConfigMock::getAll() +{ + return QHash(); +} + +bool ConfigMock::addDb(const QString&, const QString&, const QHash&) +{ + return true; +} + +bool ConfigMock::updateDb(const QString&, const QString&, const QString&, const QHash&) +{ + return true; +} + +bool ConfigMock::removeDb(const QString&) +{ + return true; +} + +bool ConfigMock::isDbInConfig(const QString&) +{ + return true; +} + +QString ConfigMock::getLastErrorString() const +{ + return QString(); +} + +QList ConfigMock::dbList() +{ + return QList(); +} + +Config::CfgDbPtr ConfigMock::getDb(const QString&) +{ + return Config::CfgDbPtr(); +} + +void ConfigMock::storeGroups(const QList&) +{ +} + +QList ConfigMock::getGroups() +{ + return QList(); +} + +Config::DbGroupPtr ConfigMock::getDbGroup(const QString&) +{ + return Config::DbGroupPtr(); +} + +qint64 ConfigMock::addSqlHistory(const QString&, const QString&, int, int) +{ + return 0; +} + +void ConfigMock::updateSqlHistory(qint64, const QString&, const QString&, int, int) +{ +} + +void ConfigMock::clearSqlHistory() +{ +} + +QAbstractItemModel* ConfigMock::getSqlHistoryModel() +{ + return nullptr; +} + +void ConfigMock::addCliHistory(const QString&) +{ +} + +void ConfigMock::applyCliHistoryLimit() +{ +} + +void ConfigMock::clearCliHistory() +{ +} + +QStringList ConfigMock::getCliHistory() const +{ + return QStringList(); +} + +void ConfigMock::addDdlHistory(const QString&, const QString&, const QString&) +{ +} + +QList ConfigMock::getDdlHistoryFor(const QString&, const QString&, const QDate&) +{ + return QList(); +} + +DdlHistoryModel* ConfigMock::getDdlHistoryModel() +{ + return nullptr; +} + +void ConfigMock::clearDdlHistory() +{ +} + +void ConfigMock::begin() +{ +} + +void ConfigMock::commit() +{ +} + +void ConfigMock::rollback() +{ +} + +bool ConfigMock::setCollations(const QList&) +{ + return true; +} + +QList ConfigMock::getCollations() const +{ + return QList(); +} + +const QString &ConfigMock::getConfigDir() const +{ + static QString s; + return s; +} + +QString ConfigMock::getConfigFilePath() const +{ + return QString(); +} + +bool ConfigMock::isMassSaving() const +{ + return false; +} + +void ConfigMock::addReportHistory(bool, const QString &, const QString &) +{ +} + +QList ConfigMock::getReportHistory() +{ + return QList(); +} + +void ConfigMock::deleteReport(int) +{ +} + +void ConfigMock::clearReportHistory() +{ +} + +void ConfigMock::refreshSqlHistory() +{ +} + +void ConfigMock::refreshDdlHistory() +{ +} diff --git a/SQLiteStudio3/Tests/TestUtils/configmock.h b/SQLiteStudio3/Tests/TestUtils/configmock.h new file mode 100644 index 0000000..2115ccf --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/configmock.h @@ -0,0 +1,60 @@ +#ifndef CONFIGMOCK_H +#define CONFIGMOCK_H + +#include "services/config.h" + +#include + +class ConfigMock : public Config +{ + public: + void init(); + void cleanUp(); + const QString& getConfigDir(); + void beginMassSave(); + void commitMassSave(); + void rollbackMassSave(); + void set(const QString&, const QString&, const QVariant&); + QVariant get(const QString&, const QString&); + QHash getAll(); + bool addDb(const QString&, const QString&, const QHash&); + bool updateDb(const QString&, const QString&, const QString&, const QHash&); + bool removeDb(const QString&); + bool isDbInConfig(const QString&); + QString getLastErrorString() const; + QList dbList(); + CfgDbPtr getDb(const QString&); + void storeGroups(const QList&); + QList getGroups(); + DbGroupPtr getDbGroup(const QString&); + qint64 addSqlHistory(const QString&, const QString&, int, int); + void updateSqlHistory(qint64, const QString&, const QString&, int, int); + void clearSqlHistory(); + QAbstractItemModel*getSqlHistoryModel(); + void addCliHistory(const QString&); + void applyCliHistoryLimit(); + void clearCliHistory(); + QStringList getCliHistory() const; + void addDdlHistory(const QString&, const QString&, const QString&); + QList getDdlHistoryFor(const QString&, const QString&, const QDate&); + DdlHistoryModel* getDdlHistoryModel(); + void clearDdlHistory(); + void begin(); + void commit(); + void rollback(); + bool setCollations(const QList&); + QList getCollations() const; + const QString &getConfigDir() const; + QString getConfigFilePath() const; + bool isMassSaving() const; + void addReportHistory(bool, const QString &, const QString &); + QList getReportHistory(); + void deleteReport(int); + void clearReportHistory(); + + public slots: + void refreshSqlHistory(); + void refreshDdlHistory(); +}; + +#endif // CONFIGMOCK_H diff --git a/SQLiteStudio3/Tests/TestUtils/dbattachermock.cpp b/SQLiteStudio3/Tests/TestUtils/dbattachermock.cpp new file mode 100644 index 0000000..9f61d2d --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/dbattachermock.cpp @@ -0,0 +1,35 @@ +#include "dbattachermock.h" + +bool DbAttacherMock::attachDatabases(const QString&) +{ + return true; +} + +bool DbAttacherMock::attachDatabases(const QList&) +{ + return true; +} + +bool DbAttacherMock::attachDatabases(SqliteQueryPtr) +{ + return true; +} + +void DbAttacherMock::detachDatabases() +{ +} + +BiStrHash DbAttacherMock::getDbNameToAttach() const +{ + return BiStrHash(); +} + +QString DbAttacherMock::getQuery() const +{ + return QString(); +} + +DbAttacher* DbAttacherFactoryMock::create(Db*) +{ + return new DbAttacherMock(); +} diff --git a/SQLiteStudio3/Tests/TestUtils/dbattachermock.h b/SQLiteStudio3/Tests/TestUtils/dbattachermock.h new file mode 100644 index 0000000..b3ab345 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/dbattachermock.h @@ -0,0 +1,23 @@ +#ifndef DBATTACHERMOCK_H +#define DBATTACHERMOCK_H + +#include "dbattacher.h" + +class DbAttacherMock : public DbAttacher +{ + public: + bool attachDatabases(const QString&); + bool attachDatabases(const QList&); + bool attachDatabases(SqliteQueryPtr); + void detachDatabases(); + BiStrHash getDbNameToAttach() const; + QString getQuery() const; +}; + +class DbAttacherFactoryMock : public DbAttacherFactory +{ + public: + DbAttacher* create(Db*); +}; + +#endif // DBATTACHERMOCK_H diff --git a/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp new file mode 100644 index 0000000..1bc5f7d --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp @@ -0,0 +1,81 @@ +#include "dbmanagermock.h" + +bool DbManagerMock::addDb(const QString&, const QString&, const QHash&, bool) +{ + return true; +} + +bool DbManagerMock::addDb(const QString&, const QString&, bool) +{ + return true; +} + +bool DbManagerMock::updateDb(Db*, const QString&, const QString&, const QHash&, bool) +{ + return true; +} + +void DbManagerMock::removeDbByName(const QString&, Qt::CaseSensitivity) +{ +} + +void DbManagerMock::removeDbByPath(const QString&) +{ +} + +void DbManagerMock::removeDb(Db*) +{ +} + +QList DbManagerMock::getDbList() +{ + return QList(); +} + +QList DbManagerMock::getValidDbList() +{ + return QList(); +} + +QList DbManagerMock::getConnectedDbList() +{ + return QList(); +} + +QStringList DbManagerMock::getDbNames() +{ + return QStringList(); +} + +Db* DbManagerMock::getByName(const QString&, Qt::CaseSensitivity) +{ + return nullptr; +} + +Db* DbManagerMock::getByPath(const QString&) +{ + return nullptr; +} + +Db*DbManagerMock::createInMemDb() +{ + return nullptr; +} + +bool DbManagerMock::isTemporary(Db*) +{ + return false; +} + +QString DbManagerMock::quickAddDb(const QString &, const QHash &) +{ + return QString(); +} + +void DbManagerMock::notifyDatabasesAreLoaded() +{ +} + +void DbManagerMock::scanForNewDatabasesInConfig() +{ +} diff --git a/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h new file mode 100644 index 0000000..2f28487 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h @@ -0,0 +1,30 @@ +#ifndef DBMANAGERMOCK_H +#define DBMANAGERMOCK_H + +#include "services/dbmanager.h" + +class DbManagerMock : public DbManager +{ + public: + bool addDb(const QString& name, const QString&, const QHash&, bool); + bool addDb(const QString&, const QString&, bool); + bool updateDb(Db*, const QString&, const QString&, const QHash&, bool); + void removeDbByName(const QString&, Qt::CaseSensitivity); + void removeDbByPath(const QString&); + void removeDb(Db*); + QList getDbList(); + QList getValidDbList(); + QList getConnectedDbList(); + QStringList getDbNames(); + Db*getByName(const QString&, Qt::CaseSensitivity); + Db*getByPath(const QString&); + Db*createInMemDb(); + bool isTemporary(Db*); + QString quickAddDb(const QString &path, const QHash &); + + public slots: + void notifyDatabasesAreLoaded(); + void scanForNewDatabasesInConfig(); +}; + +#endif // DBMANAGERMOCK_H diff --git a/SQLiteStudio3/Tests/TestUtils/dbsqlite3mock.cpp b/SQLiteStudio3/Tests/TestUtils/dbsqlite3mock.cpp new file mode 100644 index 0000000..b5070e3 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/dbsqlite3mock.cpp @@ -0,0 +1,8 @@ +#include "dbsqlite3mock.h" +#include "common/unused.h" +#include + +DbSqlite3Mock::DbSqlite3Mock(const QString &name, const QString &path, const QHash &options) + : DbSqlite3(name, path, options) +{ +} diff --git a/SQLiteStudio3/Tests/TestUtils/dbsqlite3mock.h b/SQLiteStudio3/Tests/TestUtils/dbsqlite3mock.h new file mode 100644 index 0000000..52ca264 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/dbsqlite3mock.h @@ -0,0 +1,15 @@ +#ifndef DBSQLITE3MOCK_H +#define DBSQLITE3MOCK_H + +#include "db/dbsqlite3.h" + +class DbSqlite3Mock : public DbSqlite3 +{ + Q_OBJECT + + public: + DbSqlite3Mock(const QString& name, const QString& path = ":memory:", + const QHash &options = QHash()); +}; + +#endif // DBSQLITE3MOCK_H diff --git a/SQLiteStudio3/Tests/TestUtils/functionmanagermock.cpp b/SQLiteStudio3/Tests/TestUtils/functionmanagermock.cpp new file mode 100644 index 0000000..8657f42 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/functionmanagermock.cpp @@ -0,0 +1,38 @@ +#include "functionmanagermock.h" + +void FunctionManagerMock::setScriptFunctions(const QList &) +{ +} + +QList FunctionManagerMock::getAllScriptFunctions() const +{ + return QList(); +} + +QList FunctionManagerMock::getScriptFunctionsForDatabase(const QString&) const +{ + return QList(); +} + +QList FunctionManagerMock::getAllNativeFunctions() const +{ + return QList(); +} + +QVariant FunctionManagerMock::evaluateScalar(const QString&, int, const QList&, Db*, bool&) +{ + return QVariant(); +} + +void FunctionManagerMock::evaluateAggregateInitial(const QString&, int, Db*, QHash&) +{ +} + +void FunctionManagerMock::evaluateAggregateStep(const QString&, int, const QList&, Db*, QHash&) +{ +} + +QVariant FunctionManagerMock::evaluateAggregateFinal(const QString&, int, Db*, bool&, QHash&) +{ + return QVariant(); +} diff --git a/SQLiteStudio3/Tests/TestUtils/functionmanagermock.h b/SQLiteStudio3/Tests/TestUtils/functionmanagermock.h new file mode 100644 index 0000000..d7a9192 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/functionmanagermock.h @@ -0,0 +1,21 @@ +#ifndef FUNCTIONMANAGERMOCK_H +#define FUNCTIONMANAGERMOCK_H + +#include "services/functionmanager.h" + +#include + +class FunctionManagerMock : public FunctionManager +{ + public: + void setScriptFunctions(const QList&); + QList getAllScriptFunctions() const; + QList getScriptFunctionsForDatabase(const QString&) const; + QList getAllNativeFunctions() const; + QVariant evaluateScalar(const QString&, int, const QList&, Db*, bool&); + void evaluateAggregateInitial(const QString&, int, Db*, QHash&); + void evaluateAggregateStep(const QString&, int, const QList&, Db*, QHash&); + QVariant evaluateAggregateFinal(const QString&, int, Db*, bool&, QHash&); +}; + +#endif // FUNCTIONMANAGERMOCK_H diff --git a/SQLiteStudio3/Tests/TestUtils/hippomocks.h b/SQLiteStudio3/Tests/TestUtils/hippomocks.h new file mode 100644 index 0000000..671ea1a --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/hippomocks.h @@ -0,0 +1,2361 @@ +/* + * This is a Hippo Mocks, a mocking framework for C++. + * It's created by a HippoMocks team, see https://www.assembla.com/spaces/hippomocks/team + * + * Project page: https://www.assembla.com/spaces/hippomocks/wiki + * + * Licensed under LGPL. + */ + +#ifndef HIPPOMOCKS_H +#define HIPPOMOCKS_H + +#ifndef EXCEPTION_BUFFER_SIZE +#define EXCEPTION_BUFFER_SIZE 65536 +#endif + +#ifndef VIRT_FUNC_LIMIT +#define VIRT_FUNC_LIMIT 1024 +#elif VIRT_FUNC_LIMIT > 1024 +#error Adjust the code to support more than 1024 virtual functions before setting the VIRT_FUNC_LIMIT above 1024 +#endif + +#ifdef __EDG__ +#define FUNCTION_BASE 3 +#define FUNCTION_STRIDE 2 +#else +#define FUNCTION_BASE 0 +#define FUNCTION_STRIDE 1 +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +// these warnings are pointless and huge, and will confuse new users. +#pragma warning(push) +// If you can't generate an assignment operator the least you can do is shut up. +#pragma warning(disable: 4512) +// Alignment not right in a union? +#pragma warning(disable: 4121) +// Template parameters have the tendency not to change between executions. +#pragma warning(disable: 4127) +// No deprecated warnings on functions that really aren't deprecated at all. +#pragma warning(disable: 4996) +#endif +class MockRepository; + +enum RegistrationType { + Never, + Once, + DontCare +}; + +// base type +class base_mock { +public: + void destroy() { unwriteVft(); delete this; } + virtual ~base_mock() {} + void *rewriteVft(void *newVf) + { + void *oldVf = *(void **)this; + *(void **)this = newVf; + return oldVf; + } + void unwriteVft() + { + *(void **)this = (*(void ***)this)[-1]; + } +}; + +class NullType +{ +public: + bool operator==(const NullType &) const + { + return true; + } +}; + +struct NotPrintable { template NotPrintable(T const&) {} }; + +inline std::ostream &operator<<(std::ostream &os, NotPrintable const&) +{ + os << "???"; + return os; +} + +template +struct printArg +{ + static inline void print(std::ostream &os, T arg, bool withComma) + { + if (withComma) os << ","; + os << arg; + } +}; + +template <> +struct printArg +{ + static void print(std::ostream &, NullType , bool) + { + } +}; + +class base_tuple +{ +protected: + base_tuple() + { + } +public: + virtual ~base_tuple() + { + } + virtual bool operator==(const base_tuple &) const = 0; + virtual void printTo(std::ostream &os) const = 0; +}; + +template +struct no_cref { typedef X type; }; + +template +struct no_cref { typedef X type; }; + +struct NotComparable { template NotComparable(const T&) {} }; + +inline bool operator==(NotComparable, NotComparable) +{ + return false; +} + +template +struct comparer +{ + static inline bool compare(T a, T b) + { + return a == b; + } +}; + +template +class tuple : public base_tuple +{ +public: + typename no_cref::type a; + typename no_cref::type b; + typename no_cref::type c; + typename no_cref::type d; + typename no_cref::type e; + typename no_cref::type f; + typename no_cref::type g; + typename no_cref::type h; + typename no_cref::type i; + typename no_cref::type j; + typename no_cref::type k; + typename no_cref::type l; + typename no_cref::type m; + typename no_cref::type n; + typename no_cref::type o; + typename no_cref

::type p = typename no_cref

::type()) + : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h), i(i), j(j), k(k), l(l), m(m), n(n), o(o), p(p) + {} + bool operator==(const base_tuple &bo) const { + const tuple &to = (const tuple &)bo; + return (comparer::compare(a, to.a) && + comparer::compare(b, to.b) && + comparer::compare(c, to.c) && + comparer::compare(d, to.d) && + comparer::compare(e, to.e) && + comparer::compare(f, to.f) && + comparer::compare(g, to.g) && + comparer::compare(h, to.h) && + comparer::compare(i, to.i) && + comparer::compare(j, to.j) && + comparer::compare(k, to.k) && + comparer::compare(l, to.l) && + comparer::compare(m, to.m) && + comparer::compare(n, to.n) && + comparer::compare(o, to.o) && + comparer

::compare(p, to.p)); + } + virtual void printTo(std::ostream &os) const + { + os << "("; + printArg::print(os, a, false); + printArg::print(os, b, true); + printArg::print(os, c, true); + printArg::print(os, d, true); + printArg::print(os, e, true); + printArg::print(os, f, true); + printArg::print(os, g, true); + printArg::print(os, h, true); + printArg::print(os, i, true); + printArg::print(os, j, true); + printArg::print(os, k, true); + printArg::print(os, l, true); + printArg::print(os, m, true); + printArg::print(os, n, true); + printArg::print(os, o, true); + printArg

::print(os, p, true); + os << ")"; + } +}; + +class BaseException : public std::exception { + char buffer[EXCEPTION_BUFFER_SIZE]; +public: + void setException(const char *description, MockRepository *repo); + const char *what() const throw() { return buffer; } +}; + +// exception types +class ExpectationException : public BaseException { +public: + ExpectationException(MockRepository *repo, const base_tuple *tuple, const char *funcName) + { + std::stringstream text; + text << "Function "; + text << funcName; + if (tuple) + tuple->printTo(text); + else + text << "(...)"; + text << " called with mismatching expectation!" << std::endl; + std::string description = text.str(); + setException(description.c_str(), repo); + } +}; + +class NotImplementedException : public BaseException { +public: + NotImplementedException(MockRepository *repo) + { + setException("Function called without expectation!", repo); + } +}; + +class CallMissingException : public BaseException { +public: + CallMissingException(MockRepository *repo) + { + setException("Function with expectation not called!", repo); + } +}; + +class NoResultSetUpException : public std::exception { + char buffer[EXCEPTION_BUFFER_SIZE]; +public: + const char *what() const throw() { return buffer; } + NoResultSetUpException(const base_tuple *tuple, const char *funcName) + { + std::stringstream text; + text << "No result set up on call to "; + text << funcName; + if (tuple) + tuple->printTo(text); + else + text << "(...)"; + text << std::endl; + std::string result = text.str(); + strncpy(buffer, result.c_str(), sizeof(buffer)-1); + } +}; + +// function-index-of-type +class func_index { +public: + virtual int f0() { return 0; } virtual int f1() { return 1; } virtual int f2() { return 2; } virtual int f3() { return 3; } + virtual int f4() { return 4; } virtual int f5() { return 5; } virtual int f6() { return 6; } virtual int f7() { return 7; } + virtual int f8() { return 8; } virtual int f9() { return 9; } virtual int f10() { return 10; } virtual int f11() { return 11; } + virtual int f12() { return 12; } virtual int f13() { return 13; } virtual int f14() { return 14; } virtual int f15() { return 15; } + virtual int f16() { return 16; } virtual int f17() { return 17; } virtual int f18() { return 18; } virtual int f19() { return 19; } + virtual int f20() { return 20; } virtual int f21() { return 21; } virtual int f22() { return 22; } virtual int f23() { return 23; } + virtual int f24() { return 24; } virtual int f25() { return 25; } virtual int f26() { return 26; } virtual int f27() { return 27; } + virtual int f28() { return 28; } virtual int f29() { return 29; } virtual int f30() { return 30; } virtual int f31() { return 31; } + virtual int f32() { return 32; } virtual int f33() { return 33; } virtual int f34() { return 34; } virtual int f35() { return 35; } + virtual int f36() { return 36; } virtual int f37() { return 37; } virtual int f38() { return 38; } virtual int f39() { return 39; } + virtual int f40() { return 40; } virtual int f41() { return 41; } virtual int f42() { return 42; } virtual int f43() { return 43; } + virtual int f44() { return 44; } virtual int f45() { return 45; } virtual int f46() { return 46; } virtual int f47() { return 47; } + virtual int f48() { return 48; } virtual int f49() { return 49; } virtual int f50() { return 50; } virtual int f51() { return 51; } + virtual int f52() { return 52; } virtual int f53() { return 53; } virtual int f54() { return 54; } virtual int f55() { return 55; } + virtual int f56() { return 56; } virtual int f57() { return 57; } virtual int f58() { return 58; } virtual int f59() { return 59; } + virtual int f60() { return 60; } virtual int f61() { return 61; } virtual int f62() { return 62; } virtual int f63() { return 63; } + virtual int f64() { return 64; } virtual int f65() { return 65; } virtual int f66() { return 66; } virtual int f67() { return 67; } + virtual int f68() { return 68; } virtual int f69() { return 69; } virtual int f70() { return 70; } virtual int f71() { return 71; } + virtual int f72() { return 72; } virtual int f73() { return 73; } virtual int f74() { return 74; } virtual int f75() { return 75; } + virtual int f76() { return 76; } virtual int f77() { return 77; } virtual int f78() { return 78; } virtual int f79() { return 79; } + virtual int f80() { return 80; } virtual int f81() { return 81; } virtual int f82() { return 82; } virtual int f83() { return 83; } + virtual int f84() { return 84; } virtual int f85() { return 85; } virtual int f86() { return 86; } virtual int f87() { return 87; } + virtual int f88() { return 88; } virtual int f89() { return 89; } virtual int f90() { return 90; } virtual int f91() { return 91; } + virtual int f92() { return 92; } virtual int f93() { return 93; } virtual int f94() { return 94; } virtual int f95() { return 95; } + virtual int f96() { return 96; } virtual int f97() { return 97; } virtual int f98() { return 98; } virtual int f99() { return 99; } + virtual int f100() { return 100; } virtual int f101() { return 101; } virtual int f102() { return 102; } virtual int f103() { return 103; } + virtual int f104() { return 104; } virtual int f105() { return 105; } virtual int f106() { return 106; } virtual int f107() { return 107; } + virtual int f108() { return 108; } virtual int f109() { return 109; } virtual int f110() { return 110; } virtual int f111() { return 111; } + virtual int f112() { return 112; } virtual int f113() { return 113; } virtual int f114() { return 114; } virtual int f115() { return 115; } + virtual int f116() { return 116; } virtual int f117() { return 117; } virtual int f118() { return 118; } virtual int f119() { return 119; } + virtual int f120() { return 120; } virtual int f121() { return 121; } virtual int f122() { return 122; } virtual int f123() { return 123; } + virtual int f124() { return 124; } virtual int f125() { return 125; } virtual int f126() { return 126; } virtual int f127() { return 127; } + virtual int f128() { return 128; } virtual int f129() { return 129; } virtual int f130() { return 130; } virtual int f131() { return 131; } + virtual int f132() { return 132; } virtual int f133() { return 133; } virtual int f134() { return 134; } virtual int f135() { return 135; } + virtual int f136() { return 136; } virtual int f137() { return 137; } virtual int f138() { return 138; } virtual int f139() { return 139; } + virtual int f140() { return 140; } virtual int f141() { return 141; } virtual int f142() { return 142; } virtual int f143() { return 143; } + virtual int f144() { return 144; } virtual int f145() { return 145; } virtual int f146() { return 146; } virtual int f147() { return 147; } + virtual int f148() { return 148; } virtual int f149() { return 149; } virtual int f150() { return 150; } virtual int f151() { return 151; } + virtual int f152() { return 152; } virtual int f153() { return 153; } virtual int f154() { return 154; } virtual int f155() { return 155; } + virtual int f156() { return 156; } virtual int f157() { return 157; } virtual int f158() { return 158; } virtual int f159() { return 159; } + virtual int f160() { return 160; } virtual int f161() { return 161; } virtual int f162() { return 162; } virtual int f163() { return 163; } + virtual int f164() { return 164; } virtual int f165() { return 165; } virtual int f166() { return 166; } virtual int f167() { return 167; } + virtual int f168() { return 168; } virtual int f169() { return 169; } virtual int f170() { return 170; } virtual int f171() { return 171; } + virtual int f172() { return 172; } virtual int f173() { return 173; } virtual int f174() { return 174; } virtual int f175() { return 175; } + virtual int f176() { return 176; } virtual int f177() { return 177; } virtual int f178() { return 178; } virtual int f179() { return 179; } + virtual int f180() { return 180; } virtual int f181() { return 181; } virtual int f182() { return 182; } virtual int f183() { return 183; } + virtual int f184() { return 184; } virtual int f185() { return 185; } virtual int f186() { return 186; } virtual int f187() { return 187; } + virtual int f188() { return 188; } virtual int f189() { return 189; } virtual int f190() { return 190; } virtual int f191() { return 191; } + virtual int f192() { return 192; } virtual int f193() { return 193; } virtual int f194() { return 194; } virtual int f195() { return 195; } + virtual int f196() { return 196; } virtual int f197() { return 197; } virtual int f198() { return 198; } virtual int f199() { return 199; } + virtual int f200() { return 200; } virtual int f201() { return 201; } virtual int f202() { return 202; } virtual int f203() { return 203; } + virtual int f204() { return 204; } virtual int f205() { return 205; } virtual int f206() { return 206; } virtual int f207() { return 207; } + virtual int f208() { return 208; } virtual int f209() { return 209; } virtual int f210() { return 210; } virtual int f211() { return 211; } + virtual int f212() { return 212; } virtual int f213() { return 213; } virtual int f214() { return 214; } virtual int f215() { return 215; } + virtual int f216() { return 216; } virtual int f217() { return 217; } virtual int f218() { return 218; } virtual int f219() { return 219; } + virtual int f220() { return 220; } virtual int f221() { return 221; } virtual int f222() { return 222; } virtual int f223() { return 223; } + virtual int f224() { return 224; } virtual int f225() { return 225; } virtual int f226() { return 226; } virtual int f227() { return 227; } + virtual int f228() { return 228; } virtual int f229() { return 229; } virtual int f230() { return 230; } virtual int f231() { return 231; } + virtual int f232() { return 232; } virtual int f233() { return 233; } virtual int f234() { return 234; } virtual int f235() { return 235; } + virtual int f236() { return 236; } virtual int f237() { return 237; } virtual int f238() { return 238; } virtual int f239() { return 239; } + virtual int f240() { return 240; } virtual int f241() { return 241; } virtual int f242() { return 242; } virtual int f243() { return 243; } + virtual int f244() { return 244; } virtual int f245() { return 245; } virtual int f246() { return 246; } virtual int f247() { return 247; } + virtual int f248() { return 248; } virtual int f249() { return 249; } virtual int f250() { return 250; } virtual int f251() { return 251; } + virtual int f252() { return 252; } virtual int f253() { return 253; } virtual int f254() { return 254; } virtual int f255() { return 255; } + virtual int f256() { return 256; } virtual int f257() { return 257; } virtual int f258() { return 258; } virtual int f259() { return 259; } + virtual int f260() { return 260; } virtual int f261() { return 261; } virtual int f262() { return 262; } virtual int f263() { return 263; } + virtual int f264() { return 264; } virtual int f265() { return 265; } virtual int f266() { return 266; } virtual int f267() { return 267; } + virtual int f268() { return 268; } virtual int f269() { return 269; } virtual int f270() { return 270; } virtual int f271() { return 271; } + virtual int f272() { return 272; } virtual int f273() { return 273; } virtual int f274() { return 274; } virtual int f275() { return 275; } + virtual int f276() { return 276; } virtual int f277() { return 277; } virtual int f278() { return 278; } virtual int f279() { return 279; } + virtual int f280() { return 280; } virtual int f281() { return 281; } virtual int f282() { return 282; } virtual int f283() { return 283; } + virtual int f284() { return 284; } virtual int f285() { return 285; } virtual int f286() { return 286; } virtual int f287() { return 287; } + virtual int f288() { return 288; } virtual int f289() { return 289; } virtual int f290() { return 290; } virtual int f291() { return 291; } + virtual int f292() { return 292; } virtual int f293() { return 293; } virtual int f294() { return 294; } virtual int f295() { return 295; } + virtual int f296() { return 296; } virtual int f297() { return 297; } virtual int f298() { return 298; } virtual int f299() { return 299; } + virtual int f300() { return 300; } virtual int f301() { return 301; } virtual int f302() { return 302; } virtual int f303() { return 303; } + virtual int f304() { return 304; } virtual int f305() { return 305; } virtual int f306() { return 306; } virtual int f307() { return 307; } + virtual int f308() { return 308; } virtual int f309() { return 309; } virtual int f310() { return 310; } virtual int f311() { return 311; } + virtual int f312() { return 312; } virtual int f313() { return 313; } virtual int f314() { return 314; } virtual int f315() { return 315; } + virtual int f316() { return 316; } virtual int f317() { return 317; } virtual int f318() { return 318; } virtual int f319() { return 319; } + virtual int f320() { return 320; } virtual int f321() { return 321; } virtual int f322() { return 322; } virtual int f323() { return 323; } + virtual int f324() { return 324; } virtual int f325() { return 325; } virtual int f326() { return 326; } virtual int f327() { return 327; } + virtual int f328() { return 328; } virtual int f329() { return 329; } virtual int f330() { return 330; } virtual int f331() { return 331; } + virtual int f332() { return 332; } virtual int f333() { return 333; } virtual int f334() { return 334; } virtual int f335() { return 335; } + virtual int f336() { return 336; } virtual int f337() { return 337; } virtual int f338() { return 338; } virtual int f339() { return 339; } + virtual int f340() { return 340; } virtual int f341() { return 341; } virtual int f342() { return 342; } virtual int f343() { return 343; } + virtual int f344() { return 344; } virtual int f345() { return 345; } virtual int f346() { return 346; } virtual int f347() { return 347; } + virtual int f348() { return 348; } virtual int f349() { return 349; } virtual int f350() { return 350; } virtual int f351() { return 351; } + virtual int f352() { return 352; } virtual int f353() { return 353; } virtual int f354() { return 354; } virtual int f355() { return 355; } + virtual int f356() { return 356; } virtual int f357() { return 357; } virtual int f358() { return 358; } virtual int f359() { return 359; } + virtual int f360() { return 360; } virtual int f361() { return 361; } virtual int f362() { return 362; } virtual int f363() { return 363; } + virtual int f364() { return 364; } virtual int f365() { return 365; } virtual int f366() { return 366; } virtual int f367() { return 367; } + virtual int f368() { return 368; } virtual int f369() { return 369; } virtual int f370() { return 370; } virtual int f371() { return 371; } + virtual int f372() { return 372; } virtual int f373() { return 373; } virtual int f374() { return 374; } virtual int f375() { return 375; } + virtual int f376() { return 376; } virtual int f377() { return 377; } virtual int f378() { return 378; } virtual int f379() { return 379; } + virtual int f380() { return 380; } virtual int f381() { return 381; } virtual int f382() { return 382; } virtual int f383() { return 383; } + virtual int f384() { return 384; } virtual int f385() { return 385; } virtual int f386() { return 386; } virtual int f387() { return 387; } + virtual int f388() { return 388; } virtual int f389() { return 389; } virtual int f390() { return 390; } virtual int f391() { return 391; } + virtual int f392() { return 392; } virtual int f393() { return 393; } virtual int f394() { return 394; } virtual int f395() { return 395; } + virtual int f396() { return 396; } virtual int f397() { return 397; } virtual int f398() { return 398; } virtual int f399() { return 399; } + virtual int f400() { return 400; } virtual int f401() { return 401; } virtual int f402() { return 402; } virtual int f403() { return 403; } + virtual int f404() { return 404; } virtual int f405() { return 405; } virtual int f406() { return 406; } virtual int f407() { return 407; } + virtual int f408() { return 408; } virtual int f409() { return 409; } virtual int f410() { return 410; } virtual int f411() { return 411; } + virtual int f412() { return 412; } virtual int f413() { return 413; } virtual int f414() { return 414; } virtual int f415() { return 415; } + virtual int f416() { return 416; } virtual int f417() { return 417; } virtual int f418() { return 418; } virtual int f419() { return 419; } + virtual int f420() { return 420; } virtual int f421() { return 421; } virtual int f422() { return 422; } virtual int f423() { return 423; } + virtual int f424() { return 424; } virtual int f425() { return 425; } virtual int f426() { return 426; } virtual int f427() { return 427; } + virtual int f428() { return 428; } virtual int f429() { return 429; } virtual int f430() { return 430; } virtual int f431() { return 431; } + virtual int f432() { return 432; } virtual int f433() { return 433; } virtual int f434() { return 434; } virtual int f435() { return 435; } + virtual int f436() { return 436; } virtual int f437() { return 437; } virtual int f438() { return 438; } virtual int f439() { return 439; } + virtual int f440() { return 440; } virtual int f441() { return 441; } virtual int f442() { return 442; } virtual int f443() { return 443; } + virtual int f444() { return 444; } virtual int f445() { return 445; } virtual int f446() { return 446; } virtual int f447() { return 447; } + virtual int f448() { return 448; } virtual int f449() { return 449; } virtual int f450() { return 450; } virtual int f451() { return 451; } + virtual int f452() { return 452; } virtual int f453() { return 453; } virtual int f454() { return 454; } virtual int f455() { return 455; } + virtual int f456() { return 456; } virtual int f457() { return 457; } virtual int f458() { return 458; } virtual int f459() { return 459; } + virtual int f460() { return 460; } virtual int f461() { return 461; } virtual int f462() { return 462; } virtual int f463() { return 463; } + virtual int f464() { return 464; } virtual int f465() { return 465; } virtual int f466() { return 466; } virtual int f467() { return 467; } + virtual int f468() { return 468; } virtual int f469() { return 469; } virtual int f470() { return 470; } virtual int f471() { return 471; } + virtual int f472() { return 472; } virtual int f473() { return 473; } virtual int f474() { return 474; } virtual int f475() { return 475; } + virtual int f476() { return 476; } virtual int f477() { return 477; } virtual int f478() { return 478; } virtual int f479() { return 479; } + virtual int f480() { return 480; } virtual int f481() { return 481; } virtual int f482() { return 482; } virtual int f483() { return 483; } + virtual int f484() { return 484; } virtual int f485() { return 485; } virtual int f486() { return 486; } virtual int f487() { return 487; } + virtual int f488() { return 488; } virtual int f489() { return 489; } virtual int f490() { return 490; } virtual int f491() { return 491; } + virtual int f492() { return 492; } virtual int f493() { return 493; } virtual int f494() { return 494; } virtual int f495() { return 495; } + virtual int f496() { return 496; } virtual int f497() { return 497; } virtual int f498() { return 498; } virtual int f499() { return 499; } + virtual int f500() { return 500; } virtual int f501() { return 501; } virtual int f502() { return 502; } virtual int f503() { return 503; } + virtual int f504() { return 504; } virtual int f505() { return 505; } virtual int f506() { return 506; } virtual int f507() { return 507; } + virtual int f508() { return 508; } virtual int f509() { return 509; } virtual int f510() { return 510; } virtual int f511() { return 511; } + virtual int f512() { return 512; } virtual int f513() { return 513; } virtual int f514() { return 514; } virtual int f515() { return 515; } + virtual int f516() { return 516; } virtual int f517() { return 517; } virtual int f518() { return 518; } virtual int f519() { return 519; } + virtual int f520() { return 520; } virtual int f521() { return 521; } virtual int f522() { return 522; } virtual int f523() { return 523; } + virtual int f524() { return 524; } virtual int f525() { return 525; } virtual int f526() { return 526; } virtual int f527() { return 527; } + virtual int f528() { return 528; } virtual int f529() { return 529; } virtual int f530() { return 530; } virtual int f531() { return 531; } + virtual int f532() { return 532; } virtual int f533() { return 533; } virtual int f534() { return 534; } virtual int f535() { return 535; } + virtual int f536() { return 536; } virtual int f537() { return 537; } virtual int f538() { return 538; } virtual int f539() { return 539; } + virtual int f540() { return 540; } virtual int f541() { return 541; } virtual int f542() { return 542; } virtual int f543() { return 543; } + virtual int f544() { return 544; } virtual int f545() { return 545; } virtual int f546() { return 546; } virtual int f547() { return 547; } + virtual int f548() { return 548; } virtual int f549() { return 549; } virtual int f550() { return 550; } virtual int f551() { return 551; } + virtual int f552() { return 552; } virtual int f553() { return 553; } virtual int f554() { return 554; } virtual int f555() { return 555; } + virtual int f556() { return 556; } virtual int f557() { return 557; } virtual int f558() { return 558; } virtual int f559() { return 559; } + virtual int f560() { return 560; } virtual int f561() { return 561; } virtual int f562() { return 562; } virtual int f563() { return 563; } + virtual int f564() { return 564; } virtual int f565() { return 565; } virtual int f566() { return 566; } virtual int f567() { return 567; } + virtual int f568() { return 568; } virtual int f569() { return 569; } virtual int f570() { return 570; } virtual int f571() { return 571; } + virtual int f572() { return 572; } virtual int f573() { return 573; } virtual int f574() { return 574; } virtual int f575() { return 575; } + virtual int f576() { return 576; } virtual int f577() { return 577; } virtual int f578() { return 578; } virtual int f579() { return 579; } + virtual int f580() { return 580; } virtual int f581() { return 581; } virtual int f582() { return 582; } virtual int f583() { return 583; } + virtual int f584() { return 584; } virtual int f585() { return 585; } virtual int f586() { return 586; } virtual int f587() { return 587; } + virtual int f588() { return 588; } virtual int f589() { return 589; } virtual int f590() { return 590; } virtual int f591() { return 591; } + virtual int f592() { return 592; } virtual int f593() { return 593; } virtual int f594() { return 594; } virtual int f595() { return 595; } + virtual int f596() { return 596; } virtual int f597() { return 597; } virtual int f598() { return 598; } virtual int f599() { return 599; } + virtual int f600() { return 600; } virtual int f601() { return 601; } virtual int f602() { return 602; } virtual int f603() { return 603; } + virtual int f604() { return 604; } virtual int f605() { return 605; } virtual int f606() { return 606; } virtual int f607() { return 607; } + virtual int f608() { return 608; } virtual int f609() { return 609; } virtual int f610() { return 610; } virtual int f611() { return 611; } + virtual int f612() { return 612; } virtual int f613() { return 613; } virtual int f614() { return 614; } virtual int f615() { return 615; } + virtual int f616() { return 616; } virtual int f617() { return 617; } virtual int f618() { return 618; } virtual int f619() { return 619; } + virtual int f620() { return 620; } virtual int f621() { return 621; } virtual int f622() { return 622; } virtual int f623() { return 623; } + virtual int f624() { return 624; } virtual int f625() { return 625; } virtual int f626() { return 626; } virtual int f627() { return 627; } + virtual int f628() { return 628; } virtual int f629() { return 629; } virtual int f630() { return 630; } virtual int f631() { return 631; } + virtual int f632() { return 632; } virtual int f633() { return 633; } virtual int f634() { return 634; } virtual int f635() { return 635; } + virtual int f636() { return 636; } virtual int f637() { return 637; } virtual int f638() { return 638; } virtual int f639() { return 639; } + virtual int f640() { return 640; } virtual int f641() { return 641; } virtual int f642() { return 642; } virtual int f643() { return 643; } + virtual int f644() { return 644; } virtual int f645() { return 645; } virtual int f646() { return 646; } virtual int f647() { return 647; } + virtual int f648() { return 648; } virtual int f649() { return 649; } virtual int f650() { return 650; } virtual int f651() { return 651; } + virtual int f652() { return 652; } virtual int f653() { return 653; } virtual int f654() { return 654; } virtual int f655() { return 655; } + virtual int f656() { return 656; } virtual int f657() { return 657; } virtual int f658() { return 658; } virtual int f659() { return 659; } + virtual int f660() { return 660; } virtual int f661() { return 661; } virtual int f662() { return 662; } virtual int f663() { return 663; } + virtual int f664() { return 664; } virtual int f665() { return 665; } virtual int f666() { return 666; } virtual int f667() { return 667; } + virtual int f668() { return 668; } virtual int f669() { return 669; } virtual int f670() { return 670; } virtual int f671() { return 671; } + virtual int f672() { return 672; } virtual int f673() { return 673; } virtual int f674() { return 674; } virtual int f675() { return 675; } + virtual int f676() { return 676; } virtual int f677() { return 677; } virtual int f678() { return 678; } virtual int f679() { return 679; } + virtual int f680() { return 680; } virtual int f681() { return 681; } virtual int f682() { return 682; } virtual int f683() { return 683; } + virtual int f684() { return 684; } virtual int f685() { return 685; } virtual int f686() { return 686; } virtual int f687() { return 687; } + virtual int f688() { return 688; } virtual int f689() { return 689; } virtual int f690() { return 690; } virtual int f691() { return 691; } + virtual int f692() { return 692; } virtual int f693() { return 693; } virtual int f694() { return 694; } virtual int f695() { return 695; } + virtual int f696() { return 696; } virtual int f697() { return 697; } virtual int f698() { return 698; } virtual int f699() { return 699; } + virtual int f700() { return 700; } virtual int f701() { return 701; } virtual int f702() { return 702; } virtual int f703() { return 703; } + virtual int f704() { return 704; } virtual int f705() { return 705; } virtual int f706() { return 706; } virtual int f707() { return 707; } + virtual int f708() { return 708; } virtual int f709() { return 709; } virtual int f710() { return 710; } virtual int f711() { return 711; } + virtual int f712() { return 712; } virtual int f713() { return 713; } virtual int f714() { return 714; } virtual int f715() { return 715; } + virtual int f716() { return 716; } virtual int f717() { return 717; } virtual int f718() { return 718; } virtual int f719() { return 719; } + virtual int f720() { return 720; } virtual int f721() { return 721; } virtual int f722() { return 722; } virtual int f723() { return 723; } + virtual int f724() { return 724; } virtual int f725() { return 725; } virtual int f726() { return 726; } virtual int f727() { return 727; } + virtual int f728() { return 728; } virtual int f729() { return 729; } virtual int f730() { return 730; } virtual int f731() { return 731; } + virtual int f732() { return 732; } virtual int f733() { return 733; } virtual int f734() { return 734; } virtual int f735() { return 735; } + virtual int f736() { return 736; } virtual int f737() { return 737; } virtual int f738() { return 738; } virtual int f739() { return 739; } + virtual int f740() { return 740; } virtual int f741() { return 741; } virtual int f742() { return 742; } virtual int f743() { return 743; } + virtual int f744() { return 744; } virtual int f745() { return 745; } virtual int f746() { return 746; } virtual int f747() { return 747; } + virtual int f748() { return 748; } virtual int f749() { return 749; } virtual int f750() { return 750; } virtual int f751() { return 751; } + virtual int f752() { return 752; } virtual int f753() { return 753; } virtual int f754() { return 754; } virtual int f755() { return 755; } + virtual int f756() { return 756; } virtual int f757() { return 757; } virtual int f758() { return 758; } virtual int f759() { return 759; } + virtual int f760() { return 760; } virtual int f761() { return 761; } virtual int f762() { return 762; } virtual int f763() { return 763; } + virtual int f764() { return 764; } virtual int f765() { return 765; } virtual int f766() { return 766; } virtual int f767() { return 767; } + virtual int f768() { return 768; } virtual int f769() { return 769; } virtual int f770() { return 770; } virtual int f771() { return 771; } + virtual int f772() { return 772; } virtual int f773() { return 773; } virtual int f774() { return 774; } virtual int f775() { return 775; } + virtual int f776() { return 776; } virtual int f777() { return 777; } virtual int f778() { return 778; } virtual int f779() { return 779; } + virtual int f780() { return 780; } virtual int f781() { return 781; } virtual int f782() { return 782; } virtual int f783() { return 783; } + virtual int f784() { return 784; } virtual int f785() { return 785; } virtual int f786() { return 786; } virtual int f787() { return 787; } + virtual int f788() { return 788; } virtual int f789() { return 789; } virtual int f790() { return 790; } virtual int f791() { return 791; } + virtual int f792() { return 792; } virtual int f793() { return 793; } virtual int f794() { return 794; } virtual int f795() { return 795; } + virtual int f796() { return 796; } virtual int f797() { return 797; } virtual int f798() { return 798; } virtual int f799() { return 799; } + virtual int f800() { return 800; } virtual int f801() { return 801; } virtual int f802() { return 802; } virtual int f803() { return 803; } + virtual int f804() { return 804; } virtual int f805() { return 805; } virtual int f806() { return 806; } virtual int f807() { return 807; } + virtual int f808() { return 808; } virtual int f809() { return 809; } virtual int f810() { return 810; } virtual int f811() { return 811; } + virtual int f812() { return 812; } virtual int f813() { return 813; } virtual int f814() { return 814; } virtual int f815() { return 815; } + virtual int f816() { return 816; } virtual int f817() { return 817; } virtual int f818() { return 818; } virtual int f819() { return 819; } + virtual int f820() { return 820; } virtual int f821() { return 821; } virtual int f822() { return 822; } virtual int f823() { return 823; } + virtual int f824() { return 824; } virtual int f825() { return 825; } virtual int f826() { return 826; } virtual int f827() { return 827; } + virtual int f828() { return 828; } virtual int f829() { return 829; } virtual int f830() { return 830; } virtual int f831() { return 831; } + virtual int f832() { return 832; } virtual int f833() { return 833; } virtual int f834() { return 834; } virtual int f835() { return 835; } + virtual int f836() { return 836; } virtual int f837() { return 837; } virtual int f838() { return 838; } virtual int f839() { return 839; } + virtual int f840() { return 840; } virtual int f841() { return 841; } virtual int f842() { return 842; } virtual int f843() { return 843; } + virtual int f844() { return 844; } virtual int f845() { return 845; } virtual int f846() { return 846; } virtual int f847() { return 847; } + virtual int f848() { return 848; } virtual int f849() { return 849; } virtual int f850() { return 850; } virtual int f851() { return 851; } + virtual int f852() { return 852; } virtual int f853() { return 853; } virtual int f854() { return 854; } virtual int f855() { return 855; } + virtual int f856() { return 856; } virtual int f857() { return 857; } virtual int f858() { return 858; } virtual int f859() { return 859; } + virtual int f860() { return 860; } virtual int f861() { return 861; } virtual int f862() { return 862; } virtual int f863() { return 863; } + virtual int f864() { return 864; } virtual int f865() { return 865; } virtual int f866() { return 866; } virtual int f867() { return 867; } + virtual int f868() { return 868; } virtual int f869() { return 869; } virtual int f870() { return 870; } virtual int f871() { return 871; } + virtual int f872() { return 872; } virtual int f873() { return 873; } virtual int f874() { return 874; } virtual int f875() { return 875; } + virtual int f876() { return 876; } virtual int f877() { return 877; } virtual int f878() { return 878; } virtual int f879() { return 879; } + virtual int f880() { return 880; } virtual int f881() { return 881; } virtual int f882() { return 882; } virtual int f883() { return 883; } + virtual int f884() { return 884; } virtual int f885() { return 885; } virtual int f886() { return 886; } virtual int f887() { return 887; } + virtual int f888() { return 888; } virtual int f889() { return 889; } virtual int f890() { return 890; } virtual int f891() { return 891; } + virtual int f892() { return 892; } virtual int f893() { return 893; } virtual int f894() { return 894; } virtual int f895() { return 895; } + virtual int f896() { return 896; } virtual int f897() { return 897; } virtual int f898() { return 898; } virtual int f899() { return 899; } + virtual int f900() { return 900; } virtual int f901() { return 901; } virtual int f902() { return 902; } virtual int f903() { return 903; } + virtual int f904() { return 904; } virtual int f905() { return 905; } virtual int f906() { return 906; } virtual int f907() { return 907; } + virtual int f908() { return 908; } virtual int f909() { return 909; } virtual int f910() { return 910; } virtual int f911() { return 911; } + virtual int f912() { return 912; } virtual int f913() { return 913; } virtual int f914() { return 914; } virtual int f915() { return 915; } + virtual int f916() { return 916; } virtual int f917() { return 917; } virtual int f918() { return 918; } virtual int f919() { return 919; } + virtual int f920() { return 920; } virtual int f921() { return 921; } virtual int f922() { return 922; } virtual int f923() { return 923; } + virtual int f924() { return 924; } virtual int f925() { return 925; } virtual int f926() { return 926; } virtual int f927() { return 927; } + virtual int f928() { return 928; } virtual int f929() { return 929; } virtual int f930() { return 930; } virtual int f931() { return 931; } + virtual int f932() { return 932; } virtual int f933() { return 933; } virtual int f934() { return 934; } virtual int f935() { return 935; } + virtual int f936() { return 936; } virtual int f937() { return 937; } virtual int f938() { return 938; } virtual int f939() { return 939; } + virtual int f940() { return 940; } virtual int f941() { return 941; } virtual int f942() { return 942; } virtual int f943() { return 943; } + virtual int f944() { return 944; } virtual int f945() { return 945; } virtual int f946() { return 946; } virtual int f947() { return 947; } + virtual int f948() { return 948; } virtual int f949() { return 949; } virtual int f950() { return 950; } virtual int f951() { return 951; } + virtual int f952() { return 952; } virtual int f953() { return 953; } virtual int f954() { return 954; } virtual int f955() { return 955; } + virtual int f956() { return 956; } virtual int f957() { return 957; } virtual int f958() { return 958; } virtual int f959() { return 959; } + virtual int f960() { return 960; } virtual int f961() { return 961; } virtual int f962() { return 962; } virtual int f963() { return 963; } + virtual int f964() { return 964; } virtual int f965() { return 965; } virtual int f966() { return 966; } virtual int f967() { return 967; } + virtual int f968() { return 968; } virtual int f969() { return 969; } virtual int f970() { return 970; } virtual int f971() { return 971; } + virtual int f972() { return 972; } virtual int f973() { return 973; } virtual int f974() { return 974; } virtual int f975() { return 975; } + virtual int f976() { return 976; } virtual int f977() { return 977; } virtual int f978() { return 978; } virtual int f979() { return 979; } + virtual int f980() { return 980; } virtual int f981() { return 981; } virtual int f982() { return 982; } virtual int f983() { return 983; } + virtual int f984() { return 984; } virtual int f985() { return 985; } virtual int f986() { return 986; } virtual int f987() { return 987; } + virtual int f988() { return 988; } virtual int f989() { return 989; } virtual int f990() { return 990; } virtual int f991() { return 991; } + virtual int f992() { return 992; } virtual int f993() { return 993; } virtual int f994() { return 994; } virtual int f995() { return 995; } + virtual int f996() { return 996; } virtual int f997() { return 997; } virtual int f998() { return 998; } virtual int f999() { return 999; } + virtual int f1000() { return 1000; } virtual int f1001() { return 1001; } virtual int f1002() { return 1002; } virtual int f1003() { return 1003; } + virtual int f1004() { return 1004; } virtual int f1005() { return 1005; } virtual int f1006() { return 1006; } virtual int f1007() { return 1007; } + virtual int f1008() { return 1008; } virtual int f1009() { return 1009; } virtual int f1010() { return 1010; } virtual int f1011() { return 1011; } + virtual int f1012() { return 1012; } virtual int f1013() { return 1013; } virtual int f1014() { return 1014; } virtual int f1015() { return 1015; } + virtual int f1016() { return 1016; } virtual int f1017() { return 1017; } virtual int f1018() { return 1018; } virtual int f1019() { return 1019; } + virtual int f1020() { return 1020; } virtual int f1021() { return 1021; } virtual int f1022() { return 1022; } virtual int f1023() { return 1023; } +}; + +template +T getNonvirtualMemberFunctionAddress(U u) +{ +#ifdef __EDG__ + // Edison Design Group C++ frontend (Comeau, Portland Group, Greenhills, etc) + union { + struct { + short delta; + short vindex; + T t; + } mfp_structure; + U u; + } conv; +#else + // Visual Studio, GCC, others + union { + struct { + T t; + } mfp_structure; + U u; + } conv; +#endif + conv.u = u; + return conv.mfp_structure.t; +} + +template +int getFunctionIndex(T func) { + func_index idx; + return ((&idx)->*reinterpret_cast(func))() * FUNCTION_STRIDE + FUNCTION_BASE; +} + +// mock types +template +class mock : public base_mock +{ + friend class MockRepository; + unsigned char remaining[sizeof(T)]; + void NotImplemented() { throw NotImplementedException(repo); } +protected: + void *oldVft; + void (*funcs[VIRT_FUNC_LIMIT])(); + MockRepository *repo; +public: + int funcMap[VIRT_FUNC_LIMIT]; + mock(MockRepository *repo) + : repo(repo) + { + for (int i = 0; i < VIRT_FUNC_LIMIT; i++) + { + funcs[i] = getNonvirtualMemberFunctionAddress(&mock::NotImplemented); + funcMap[i] = -1; + } + memset(remaining, 0, sizeof(remaining)); + oldVft = base_mock::rewriteVft(funcs); + } + int translateX(int x) + { + for (int i = 0; i < VIRT_FUNC_LIMIT; i++) + { + if (funcMap[i] == x) return i; + } + return -1; + } +}; + +template +class classMock : public mock +{ + void *backupVft; +public: + classMock(MockRepository *repo) + : mock(repo) + { + mock::oldVft = base_mock::rewriteVft((void *)mock::funcs); + new(this)T(); + backupVft = base_mock::rewriteVft((void *)mock::funcs); + } + ~classMock() + { + base_mock::rewriteVft(backupVft); + ((T *)this)->~T(); + } +}; + +//Type-safe exception wrapping +class ExceptionHolder +{ +public: + virtual ~ExceptionHolder() {} + virtual void rethrow() = 0; +}; + +template +class ExceptionWrapper : public ExceptionHolder { + T exception; +public: + ExceptionWrapper(T exception) : exception(exception) {} + void rethrow() { throw exception; } +}; + +// Do() function wrapping +class VirtualDestructable { public: virtual ~VirtualDestructable() {} }; + +template +class TupleInvocable : public VirtualDestructable +{ +public: + virtual Y operator()(const base_tuple &tupl) = 0; +}; + +template +class Invocable : public TupleInvocable +{ +public: + virtual Y operator()(A a = A(), B b = B(), C c = C(), D d = D(), E e = E(), F f = F(), G g = G(), H h = H(), I i = I(), J j = J(), K k = K(), L l = L(), M m = M(), N n = N(), O o = O(), P p = P()) = 0; + virtual Y operator()(const base_tuple &tupl) { + const tuple &rTupl = reinterpret_cast &>(tupl); + return (*this)(rTupl.a, rTupl.b, rTupl.c, rTupl.d, rTupl.e, rTupl.f, rTupl.g, rTupl.h, + rTupl.i, rTupl.j, rTupl.k, rTupl.l, rTupl.m, rTupl.n, rTupl.o, rTupl.p); + } +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, O o, P p) + { + return t(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, O o, NullType) + { + return t(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, NullType, NullType) + { + return t(a,b,c,d,e,f,g,h,i,j,k,l,m,n); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, NullType, NullType, NullType) + { + return t(a,b,c,d,e,f,g,h,i,j,k,l,m); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, NullType, NullType, NullType, NullType) + { + return t(a,b,c,d,e,f,g,h,i,j,k,l); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, NullType, NullType, NullType, NullType, NullType) + { + return t(a,b,c,d,e,f,g,h,i,j,k); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(a,b,c,d,e,f,g,h,i,j); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable{ + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, G g, H h, I i, NullType, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(a,b,c,d,e,f,g,h,i); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, G g, H h, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(a,b,c,d,e,f,g,h); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, G g, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(a,b,c,d,e,f,g); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, F f, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(a,b,c,d,e,f); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, E e, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(a,b,c,d,e); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, D d, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(a,b,c,d); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, C c, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(a,b,c); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, B b, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(a,b); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(A a, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(a); + } + using Invocable::operator(); +}; +template +class DoWrapper : public Invocable { + T &t; +public: + DoWrapper(T &t) : t(t) {} + virtual Y operator()(NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType) + { + return t(); + } + using Invocable::operator(); +}; + +class ReturnValueHolder { +public: + virtual ~ReturnValueHolder() {} +}; + +template +class ReturnValueWrapper : public ReturnValueHolder { +public: + typename no_cref::type rv; + ReturnValueWrapper(T rv) : rv(rv) {} +}; + +//Call wrapping +class Call { +public: + virtual bool matchesArgs(const base_tuple &tuple) = 0; + ReturnValueHolder *retVal; + ExceptionHolder *eHolder; + base_mock *mock; + VirtualDestructable *functor; + int funcIndex; + std::list previousCalls; + RegistrationType expectation; + bool satisfied; + int lineno; + const char *funcName; + const char *fileName; +protected: + Call(RegistrationType expectation, base_mock *mock, int funcIndex, int X, const char *funcName, const char *fileName) + : retVal(0), + eHolder(0), + mock(mock), + functor(0), + funcIndex(funcIndex), + expectation(expectation), + satisfied(false), + lineno(X), + funcName(funcName), + fileName(fileName) + { + } +public: + virtual const base_tuple *getArgs() const = 0; + virtual ~Call() + { + delete eHolder; + delete functor; + delete retVal; + } +}; + +std::ostream &operator<<(std::ostream &os, const Call &call); + +template +class TCall : public Call { +private: + tuple *args; +public: + const base_tuple *getArgs() const { return args; } + TCall(RegistrationType expectation, base_mock *mock, int funcIndex, int X, const char *funcName, const char *fileName) : Call(expectation, mock, funcIndex, X, funcName, fileName), args(0) {} + ~TCall() { delete args; } + bool matchesArgs(const base_tuple &tupl) { return !args || *args == reinterpret_cast &>(tupl); } + TCall &With(A a = A(), B b = B(), C c = C(), D d = D(), E e = E(), F f = F(), G g = G(), H h = H(), I i = I(), J j = J(), K k = K(), L l = L(), M m = M(), N n = N(), O o = O(), P p = P()) { + args = new tuple(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p); + return *this; + } + TCall &After(Call &call) { + previousCalls.push_back(&call); + return *this; + } + template + Call &Do(T &function) { functor = new DoWrapper(function); return *this; } + Call &Return(Y obj) { retVal = new ReturnValueWrapper(obj); return *this; } + template + Call &Throw(Ex exception) { eHolder = new ExceptionWrapper(exception); return *this; } +}; + +template +class TCall : public Call { +private: + tuple *args; +public: + const base_tuple *getArgs() const { return args; } + TCall(RegistrationType expectation, base_mock *mock, int funcIndex, int X, const char *funcName, const char *fileName) : Call(expectation, mock, funcIndex, X, funcName, fileName), args(0) {} + ~TCall() { delete args; } + bool matchesArgs(const base_tuple &tupl) { return (!args) || (*args == reinterpret_cast &>(tupl)); } + TCall &With(A a = A(), B b = B(), C c = C(), D d = D(), E e = E(), F f = F(), G g = G(), H h = H(), I i = I(), J j = J(), K k = K(), L l = L(), M m = M(), N n = N(), O o = O(), P p = P()) { + args = new tuple(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p); + return *this; + } + TCall &After(Call &call) { + previousCalls.push_back(&call); + return *this; + } + template + Call &Do(T &function) { functor = new DoWrapper(function); return *this; } + template + Call &Throw(Ex exception) { eHolder = new ExceptionWrapper(exception); return *this; } +}; + +class MockRepository { +private: + friend inline std::ostream &operator<<(std::ostream &os, const MockRepository &repo); + std::list mocks; + std::list neverCalls; + std::list expectations; + std::list optionals; +public: + bool autoExpect; +#ifdef _MSC_VER +#define OnCall(obj, func) RegisterExpect_<__COUNTER__, DontCare>(obj, &func, #func, __FILE__, __LINE__) +#define ExpectCall(obj, func) RegisterExpect_<__COUNTER__, Once>(obj, &func, #func, __FILE__, __LINE__) +#define NeverCall(obj, func) RegisterExpect_<__COUNTER__, Never>(obj, &func, #func, __FILE__, __LINE__) +#define OnCallOverload(obj, func) RegisterExpect_<__COUNTER__, DontCare>(obj, func, #func, __FILE__, __LINE__) +#define ExpectCallOverload(obj, func) RegisterExpect_<__COUNTER__, Once>(obj, func, #func, __FILE__, __LINE__) +#define NeverCallOverload(obj, func) RegisterExpect_<__COUNTER__, Never>(obj, func, #func, __FILE__, __LINE__) +#else +#define OnCall(obj, func) RegisterExpect_<__LINE__, DontCare>(obj, &func, #func, __FILE__, __LINE__) +#define ExpectCall(obj, func) RegisterExpect_<__LINE__, Once>(obj, &func, #func, __FILE__, __LINE__) +#define NeverCall(obj, func) RegisterExpect_<__LINE__, Never>(obj, &func, #func, __FILE__, __LINE__) +#define OnCallOverload(obj, func) RegisterExpect_<__LINE__, DontCare>(obj, func, #func, __FILE__, __LINE__) +#define ExpectCallOverload(obj, func) RegisterExpect_<__LINE__, Once>(obj, func, #func, __FILE__, __LINE__) +#define NeverCallOverload(obj, func) RegisterExpect_<__LINE__, Never>(obj, func, #func, __FILE__, __LINE__) +#endif + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O), const char *funcName, const char *fileName, unsigned long lineNo); + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P), const char *funcName, const char *fileName, unsigned long lineNo); + + //GCC 3.x doesn't seem to understand overloading on const or non-const member function. Volatile appears to work though. +#if !defined(__GNUC__) || __GNUC__ > 3 + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)() volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)())(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M,N))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P))(func), funcName, fileName, lineNo); } + + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)() const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)())(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M,N))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) const volatile, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P))(func), funcName, fileName, lineNo); } + + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)() const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)())(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M,N))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O))(func), funcName, fileName, lineNo); } + template + TCall &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) const, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P))(func), funcName, fileName, lineNo); } +#endif + template + void BasicRegisterExpect(mock *zMock, int funcIndex, void (base_mock::*func)(), int X); + template + Z DoExpectation(base_mock *mock, int funcno, const base_tuple &tuple); + void DoVoidExpectation(base_mock *mock, int funcno, const base_tuple &tuple) + { + for (std::list::iterator i = expectations.begin(); i != expectations.end(); ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno && + call->matchesArgs(tuple) && + !call->satisfied) + { + bool allSatisfy = true; + for (std::list::iterator callsBefore = call->previousCalls.begin(); + callsBefore != call->previousCalls.end(); ++callsBefore) + { + if (!(*callsBefore)->satisfied) + { + allSatisfy = false; + } + } + if (!allSatisfy) continue; + + call->satisfied = true; + + if (call->eHolder) + call->eHolder->rethrow(); + + if (call->functor != NULL) + (*(TupleInvocable *)(call->functor))(tuple); + + return; + } + } + for (std::list::iterator i = neverCalls.begin(); i != neverCalls.end(); ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno && + call->matchesArgs(tuple)) + { + bool allSatisfy = true; + for (std::list::iterator callsBefore = call->previousCalls.begin(); + callsBefore != call->previousCalls.end(); ++callsBefore) + { + if (!(*callsBefore)->satisfied) + { + allSatisfy = false; + } + } + if (!allSatisfy) continue; + + call->satisfied = true; + + throw ExpectationException(this, call->getArgs(), call->funcName); + } + } + for (std::list::iterator i = optionals.begin(); i != optionals.end(); ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno && + call->matchesArgs(tuple)) + { + bool allSatisfy = true; + for (std::list::iterator callsBefore = call->previousCalls.begin(); + callsBefore != call->previousCalls.end(); ++callsBefore) + { + if (!(*callsBefore)->satisfied) + { + allSatisfy = false; + } + } + if (!allSatisfy) continue; + + call->satisfied = true; + + if (call->eHolder) + call->eHolder->rethrow(); + + if (call->functor != NULL) + (*(TupleInvocable *)(call->functor))(tuple); + + return; + } + } + const char *funcName = NULL; + for (std::list::iterator i = expectations.begin(); i != expectations.end() && !funcName; ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno) + funcName = call->funcName; + } + for (std::list::iterator i = optionals.begin(); i != optionals.end() && !funcName; ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno) + funcName = call->funcName; + } + for (std::list::iterator i = neverCalls.begin(); i != neverCalls.end() && !funcName; ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno) + funcName = call->funcName; + } + throw ExpectationException(this, &tuple, funcName); + } + MockRepository() + : autoExpect(true) + { + } + ~MockRepository() + { + if (!std::uncaught_exception()) + VerifyAll(); + reset(); + for (std::list::iterator i = mocks.begin(); i != mocks.end(); i++) + { + (*i)->destroy(); + } + mocks.clear(); + } + void reset() + { + for (std::list::iterator i = expectations.begin(); i != expectations.end(); i++) + { + delete *i; + } + expectations.clear(); + for (std::list::iterator i = neverCalls.begin(); i != neverCalls.end(); i++) + { + delete *i; + } + neverCalls.clear(); + for (std::list::iterator i = optionals.begin(); i != optionals.end(); i++) + { + delete *i; + } + optionals.clear(); + } + void VerifyAll() + { + for (std::list::iterator i = expectations.begin(); i != expectations.end(); i++) + { + if (!(*i)->satisfied) + throw CallMissingException(this); + } + } + template + base *InterfaceMock(); + template + base *ClassMock(); +}; + +// mock function providers +template +class mockFuncs : public mock { +private: + mockFuncs(); +public: + template + Y expectation0() + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple<>()); + } + template + Y expectation1(A a) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a)); + } + template + Y expectation2(A a, B b) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b)); + } + template + Y expectation3(A a, B b, C c) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c)); + } + template + Y expectation4(A a, B b, C c, D d) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d)); + } + template + Y expectation5(A a, B b, C c, D d, E e) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e)); + } + template + Y expectation6(A a, B b, C c, D d, E e, F f) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f)); + } + template + Y expectation7(A a, B b, C c, D d, E e, F f, G g) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g)); + } + template + Y expectation8(A a, B b, C c, D d, E e, F f, G g, H h) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), new tuple(a,b,c,d,e,f,g,h)); + } + template + Y expectation9(A a, B b, C c, D d, E e, F f, G g, H h, I i) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i)); + } + template + Y expectation10(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j)); + } + template + Y expectation11(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k)); + } + template + Y expectation12(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k,l)); + } + template + Y expectation13(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k,l,m)); + } + template + Y expectation14(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k,l,m,n)); + } + template + Y expectation15(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, O o) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)); + } + template + Y expectation16(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, O o, P p) + { + MockRepository *repo = mock::repo; + return repo->template DoExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)); + } +}; + +template +class mockFuncs : public mock { +private: + mockFuncs(); +public: + template + void expectation0() + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple<>()); + } + template + void expectation1(A a) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a)); + } + template + void expectation2(A a, B b) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b)); + } + template + void expectation3(A a, B b, C c) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c)); + } + template + void expectation4(A a, B b, C c, D d) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d)); + } + template + void expectation5(A a, B b, C c, D d, E e) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e)); + } + template + void expectation6(A a, B b, C c, D d, E e, F f) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f)); + } + template + void expectation7(A a, B b, C c, D d, E e, F f, G g) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g)); + } + template + void expectation8(A a, B b, C c, D d, E e, F f, G g, H h) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h)); + } + template + void expectation9(A a, B b, C c, D d, E e, F f, G g, H h, I i) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i)); + } + template + void expectation10(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j)); + } + template + void expectation11(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k)); + } + template + void expectation12(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k,l)); + } + template + void expectation13(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k,l,m)); + } + template + void expectation14(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k,l,m,n)); + } + template + void expectation15(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, O o) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)); + } + template + void expectation16(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, O o, P p) + { + MockRepository *repo = mock::repo; + repo->DoVoidExpectation(this, mock::translateX(X), tuple(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)); + } +}; + +template +void MockRepository::BasicRegisterExpect(mock *zMock, int funcIndex, void (base_mock::*func)(), int X) +{ + if (zMock->funcMap[funcIndex] == -1) + { + zMock->funcs[funcIndex] = getNonvirtualMemberFunctionAddress(func); + zMock->funcMap[funcIndex] = X; + } +} + +// Mock repository implementation +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(); + mfp = &mockFuncs::template expectation0; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A); + mfp = &mockFuncs::template expectation1; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B); + mfp = &mockFuncs::template expectation2; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C); + mfp = &mockFuncs::template expectation3; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D); + mfp = &mockFuncs::template expectation4; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E); + mfp = &mockFuncs::template expectation5; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F); + mfp = &mockFuncs::template expectation6; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F,G); + mfp = &mockFuncs::template expectation7; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F,G,H); + mfp = &mockFuncs::template expectation8; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F,G,H,I); + mfp = &mockFuncs::template expectation9; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F,G,H,I,J); + mfp = &mockFuncs::template expectation10; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F,G,H,I,J,K); + mfp = &mockFuncs::template expectation11; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F,G,H,I,J,K,L); + mfp = &mockFuncs::template expectation12; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F,G,H,I,J,K,L,M); + mfp = &mockFuncs::template expectation13; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F,G,H,I,J,K,L,M,N); + mfp = &mockFuncs::template expectation14; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O); + mfp = &mockFuncs::template expectation15; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} + +template +TCall &MockRepository::RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P), const char *funcName, const char *fileName, unsigned long lineNo) +{ + int funcIndex = getFunctionIndex(func); + Y (mockFuncs::*mfp)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P); + mfp = &mockFuncs::template expectation16; + BasicRegisterExpect(reinterpret_cast *>(mck), + funcIndex, + reinterpret_cast(mfp),X); + TCall *call = new TCall(expect, reinterpret_cast(mck), funcIndex, lineNo, funcName, fileName); + switch(expect) + { + case Never: neverCalls.push_back(call); break; + case DontCare: optionals.push_back(call); break; + case Once: + if (autoExpect && expectations.size() > 0) + { + call->previousCalls.push_back(expectations.back()); + } + expectations.push_back(call); + break; + } + return *call; +} + +template +Z MockRepository::DoExpectation(base_mock *mock, int funcno, const base_tuple &tuple) +{ + for (std::list::iterator i = expectations.begin(); i != expectations.end(); ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno && + call->matchesArgs(tuple) && + !call->satisfied) + { + bool allSatisfy = true; + for (std::list::iterator callsBefore = call->previousCalls.begin(); + callsBefore != call->previousCalls.end(); ++callsBefore) + { + if (!(*callsBefore)->satisfied) + { + allSatisfy = false; + } + } + if (!allSatisfy) continue; + + call->satisfied = true; + + if (call->eHolder) + call->eHolder->rethrow(); + + if (call->retVal) + return ((ReturnValueWrapper *)call->retVal)->rv; + + if (call->functor != NULL) + return (*(TupleInvocable *)(call->functor))(tuple); + + throw NoResultSetUpException(call->getArgs(), call->funcName); + } + } + for (std::list::iterator i = neverCalls.begin(); i != neverCalls.end(); ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno && + call->matchesArgs(tuple)) + { + bool allSatisfy = true; + for (std::list::iterator callsBefore = call->previousCalls.begin(); + callsBefore != call->previousCalls.end(); ++callsBefore) + { + if (!(*callsBefore)->satisfied) + { + allSatisfy = false; + } + } + if (!allSatisfy) continue; + + call->satisfied = true; + + throw ExpectationException(this, call->getArgs(), call->funcName); + } + } + for (std::list::iterator i = optionals.begin(); i != optionals.end(); ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno && + call->matchesArgs(tuple)) + { + bool allSatisfy = true; + for (std::list::iterator callsBefore = call->previousCalls.begin(); + callsBefore != call->previousCalls.end(); ++callsBefore) + { + if (!(*callsBefore)->satisfied) + { + allSatisfy = false; + } + } + if (!allSatisfy) continue; + + call->satisfied = true; + + if (call->eHolder) + call->eHolder->rethrow(); + + if (call->retVal) + return ((ReturnValueWrapper *)call->retVal)->rv; + + if (call->functor != NULL) + return (*(TupleInvocable *)(call->functor))(tuple); + + throw NoResultSetUpException(call->getArgs(), call->funcName); + } + } + const char *funcName = NULL; + for (std::list::iterator i = expectations.begin(); i != expectations.end() && !funcName; ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno) + funcName = call->funcName; + } + for (std::list::iterator i = neverCalls.begin(); i != neverCalls.end() && !funcName; ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno) + funcName = call->funcName; + } + for (std::list::iterator i = optionals.begin(); i != optionals.end() && !funcName; ++i) + { + Call *call = *i; + if (call->mock == mock && + call->funcIndex == funcno) + funcName = call->funcName; + } + throw ExpectationException(this, &tuple, funcName); +} +template +base *MockRepository::InterfaceMock() { + mock *m = new mock(this); + mocks.push_back(m); + return reinterpret_cast(m); +} +template +base *MockRepository::ClassMock() { + classMock *m = new classMock(this); + mocks.push_back(m); + return reinterpret_cast(m); +} + +inline std::ostream &operator<<(std::ostream &os, const Call &call) +{ + os << call.fileName << "(" << call.lineno << ") "; + if (call.expectation == Once) + os << "Expectation for "; + else + os << "Result set for "; + + os << call.funcName; + + if (call.getArgs()) + call.getArgs()->printTo(os); + else + os << "(...)"; + + os << " on the mock at 0x" << call.mock << " was "; + + if (!call.satisfied) + os << "not "; + + if (call.expectation == Once) + os << "satisfied." << std::endl; + else + os << "used." << std::endl; + + return os; +} + +inline std::ostream &operator<<(std::ostream &os, const MockRepository &repo) +{ + if (repo.expectations.size()) + { + os << "Expections set:" << std::endl; + for (std::list::const_iterator exp = repo.expectations.begin(); exp != repo.expectations.end(); ++exp) + os << **exp; + os << std::endl; + } + + if (repo.neverCalls.size()) + { + os << "Functions explicitly expected to not be called:" << std::endl; + for (std::list::const_iterator exp = repo.neverCalls.begin(); exp != repo.neverCalls.end(); ++exp) + os << **exp; + os << std::endl; + } + + if (repo.optionals.size()) + { + os << "Optional results set up:" << std::endl; + for (std::list::const_iterator exp = repo.optionals.begin(); exp != repo.optionals.end(); ++exp) + os << **exp; + os << std::endl; + } + + return os; +} + +inline void BaseException::setException(const char *description, MockRepository *repo) +{ + std::stringstream text; + text << description; + text << *repo; + std::string result = text.str(); + strncpy(buffer, result.c_str(), sizeof(buffer)-1); + buffer[sizeof(buffer)-1] = '\0'; +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif + diff --git a/SQLiteStudio3/Tests/TestUtils/mocks.cpp b/SQLiteStudio3/Tests/TestUtils/mocks.cpp new file mode 100644 index 0000000..dee3bfd --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/mocks.cpp @@ -0,0 +1,37 @@ +#include "mocks.h" +#include "common/global.h" +#include "sqlitestudio.h" +#include "configmock.h" +#include "pluginmanagermock.h" +#include "functionmanagermock.h" +#include "collationmanagermock.h" +#include "dbattachermock.h" +#include "dbmanagermock.h" + +MockRepository* mockRepository = nullptr; + +MockRepository& mockRepo() +{ + if (!mockRepository) + { + mockRepository = new MockRepository; + mockRepository->autoExpect = false; + } + + return *mockRepository; +} + +void deleteMockRepo() +{ + safe_delete(mockRepository); +} + +void initMocks() +{ + SQLITESTUDIO->setConfig(new ConfigMock()); + SQLITESTUDIO->setFunctionManager(new FunctionManagerMock()); + SQLITESTUDIO->setPluginManager(new PluginManagerMock()); + SQLITESTUDIO->setDbAttacherFactory(new DbAttacherFactoryMock()); + SQLITESTUDIO->setDbManager(new DbManagerMock()); + SQLITESTUDIO->setCollationManager(new CollationManagerMock()); +} diff --git a/SQLiteStudio3/Tests/TestUtils/mocks.h b/SQLiteStudio3/Tests/TestUtils/mocks.h new file mode 100644 index 0000000..f3bd1f9 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/mocks.h @@ -0,0 +1,11 @@ +#ifndef UNITS_SETUP_H +#define UNITS_SETUP_H + +#include "hippomocks.h" + +MockRepository& mockRepo(); +void deleteMockRepo(); + +void initMocks(); + +#endif // UNITS_SETUP_H diff --git a/SQLiteStudio3/Tests/TestUtils/pluginmanagermock.cpp b/SQLiteStudio3/Tests/TestUtils/pluginmanagermock.cpp new file mode 100644 index 0000000..a8f9bca --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/pluginmanagermock.cpp @@ -0,0 +1,162 @@ +#include "pluginmanagermock.h" + +void PluginManagerMock::init() +{ +} + +void PluginManagerMock::deinit() +{ +} + +QList PluginManagerMock::getPluginTypes() const +{ + return QList(); +} + +QStringList PluginManagerMock::getPluginDirs() const +{ + return QStringList(); +} + +QString PluginManagerMock::getFilePath(Plugin*) const +{ + return QString(); +} + +bool PluginManagerMock::loadBuiltInPlugin(Plugin*) +{ + return true; +} + +bool PluginManagerMock::load(const QString&) +{ + return true; +} + +void PluginManagerMock::unload(const QString&) +{ +} + +void PluginManagerMock::unload(Plugin*) +{ +} + +bool PluginManagerMock::isLoaded(const QString&) const +{ + return false; +} + +bool PluginManagerMock::isBuiltIn(const QString&) const +{ + return false; +} + +Plugin* PluginManagerMock::getLoadedPlugin(const QString&) const +{ + return nullptr; +} + +QStringList PluginManagerMock::getAllPluginNames(PluginType*) const +{ + return QStringList(); +} + +QStringList PluginManagerMock::getAllPluginNames() const +{ + return QStringList(); +} + +PluginType* PluginManagerMock::getPluginType(const QString&) const +{ + return nullptr; +} + +QString PluginManagerMock::getAuthor(const QString&) const +{ + return QString(); +} + +QString PluginManagerMock::getTitle(const QString&) const +{ + return QString(); +} + +QString PluginManagerMock::getPrintableVersion(const QString&) const +{ + return QString(); +} + +int PluginManagerMock::getVersion(const QString&) const +{ + return 3; +} + +QString PluginManagerMock::getDescription(const QString&) const +{ + return QString(); +} + +PluginType* PluginManagerMock::getPluginType(Plugin*) const +{ + return nullptr; +} + +QList PluginManagerMock::getLoadedPlugins(PluginType*) const +{ + return QList(); +} + +ScriptingPlugin* PluginManagerMock::getScriptingPlugin(const QString&) const +{ + return nullptr; +} + +void PluginManagerMock::registerPluginType(PluginType*) +{ +} + +QHash PluginManagerMock::readMetaData(const QJsonObject&) +{ + return QHash(); +} + +QString PluginManagerMock::toPrintableVersion(int) const +{ + return QString(); +} + + +QStringList PluginManagerMock::getDependencies(const QString&) const +{ + return QStringList(); +} + +QStringList PluginManagerMock::getConflicts(const QString&) const +{ + return QStringList(); +} + +QList PluginManagerMock::getAllPluginDetails() const +{ + return QList(); +} + +QList PluginManagerMock::getLoadedPluginDetails() const +{ + return QList(); +} + +QStringList PluginManagerMock::getLoadedPluginNames() const +{ + return QStringList(); +} + +bool PluginManagerMock::arePluginsInitiallyLoaded() const +{ + return true; +} + +QList PluginManagerMock::getLoadedPlugins() const +{ + return QList(); +} diff --git a/SQLiteStudio3/Tests/TestUtils/pluginmanagermock.h b/SQLiteStudio3/Tests/TestUtils/pluginmanagermock.h new file mode 100644 index 0000000..06e5b39 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/pluginmanagermock.h @@ -0,0 +1,46 @@ +#ifndef PLUGINMANAGERMOCK_H +#define PLUGINMANAGERMOCK_H + +#include "services/pluginmanager.h" + +class PluginManagerMock : public PluginManager +{ + public: + void init(); + void deinit(); + QList getPluginTypes() const; + QStringList getPluginDirs() const; + QString getFilePath(Plugin*) const; + bool loadBuiltInPlugin(Plugin*); + bool load(const QString&); + void unload(const QString&); + void unload(Plugin*); + bool isLoaded(const QString&) const; + bool isBuiltIn(const QString&) const; + Plugin*getLoadedPlugin(const QString&) const; + QStringList getAllPluginNames(PluginType*) const; + QStringList getAllPluginNames() const; + PluginType*getPluginType(const QString&) const; + QString getAuthor(const QString&) const; + QString getTitle(const QString&) const; + QString getPrintableVersion(const QString&) const; + int getVersion(const QString&) const; + QString getDescription(const QString&) const; + PluginType*getPluginType(Plugin*) const; + QList getLoadedPlugins(PluginType*) const; + ScriptingPlugin* getScriptingPlugin(const QString&) const; + QHash readMetaData(const QJsonObject&); + QString toPrintableVersion(int) const; + QStringList getDependencies(const QString&) const; + QStringList getConflicts(const QString&) const; + QList getAllPluginDetails() const; + QList getLoadedPluginDetails() const; + QStringList getLoadedPluginNames() const; + bool arePluginsInitiallyLoaded() const; + QList getLoadedPlugins() const; + + protected: + void registerPluginType(PluginType*); +}; + +#endif // PLUGINMANAGERMOCK_H diff --git a/SQLiteStudio3/Tests/TestUtils/test_common.pri b/SQLiteStudio3/Tests/TestUtils/test_common.pri new file mode 100644 index 0000000..c265ba1 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/test_common.pri @@ -0,0 +1,6 @@ +include($$PWD/../../dirs.pri) +include($$PWD/../testdirs.pri) + +CONFIG += c++11 + +LIBS += -lTestUtils -lcoreSQLiteStudio diff --git a/SQLiteStudio3/Tests/TestUtils/testutils_global.h b/SQLiteStudio3/Tests/TestUtils/testutils_global.h new file mode 100644 index 0000000..c4ddfa3 --- /dev/null +++ b/SQLiteStudio3/Tests/TestUtils/testutils_global.h @@ -0,0 +1,12 @@ +#ifndef TESTUTILS_GLOBAL_H +#define TESTUTILS_GLOBAL_H + +#include + +#if defined(TESTUTILS_LIBRARY) +# define TESTUTILSSHARED_EXPORT Q_DECL_EXPORT +#else +# define TESTUTILSSHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // TESTUTILS_GLOBAL_H diff --git a/SQLiteStudio3/Tests/Tests.pro b/SQLiteStudio3/Tests/Tests.pro new file mode 100644 index 0000000..60ade33 --- /dev/null +++ b/SQLiteStudio3/Tests/Tests.pro @@ -0,0 +1,31 @@ +TEMPLATE = subdirs + +test_utils.subdir = TestUtils + +completion_helper.subdir = CompletionHelperTest +completion_helper.depends = test_utils + +select_resolver.subdir = SelectResolverTest +select_resolver.depends = test_utils + +parser.subdir = ParserTest +parser.depends = test_utils + +table_modifier.subdir = TableModifierTest +table_modifier.depends = test_utils + +hash_tables.subdir = HashTablesTest +hash_tables.depends = test_utils + +db_ver_conv.subdir = DbVersionConverterTest +db_ver_conv.depends = test_utils + +SUBDIRS += \ + test_utils \ + completion_helper \ + select_resolver \ + parser \ + table_modifier \ + hash_tables \ + db_ver_conv \ + DsvFormatsTest diff --git a/SQLiteStudio3/Tests/testdirs.pri b/SQLiteStudio3/Tests/testdirs.pri new file mode 100644 index 0000000..7e35f8d --- /dev/null +++ b/SQLiteStudio3/Tests/testdirs.pri @@ -0,0 +1,4 @@ +LIBS += -L$$PWD/../output/SQLiteStudio + +INCLUDEPATH += $$PWD/TestUtils +DEPENDPATH += $$PWD/TestUtils -- cgit v1.2.3

::type p; + tuple(typename no_cref::type a = typename no_cref::type(), typename no_cref::type b = typename no_cref::type(), + typename no_cref::type c = typename no_cref::type(), typename no_cref::type d = typename no_cref::type(), + typename no_cref::type e = typename no_cref::type(), typename no_cref::type f = typename no_cref::type(), + typename no_cref::type g = typename no_cref::type(), typename no_cref::type h = typename no_cref::type(), + typename no_cref::type i = typename no_cref::type(), typename no_cref::type j = typename no_cref::type(), + typename no_cref::type k = typename no_cref::type(), typename no_cref::type l = typename no_cref::type(), + typename no_cref::type m = typename no_cref::type(), typename no_cref::type n = typename no_cref::type(), + typename no_cref::type o = typename no_cref::type(), typename no_cref