Mercurial > dedupe
changeset 76:8136057988bc
Fixes to automatic report generating system.
A lot of new unittests.
| author | Tom Fredrik Blenning Klaussen <bfg@bfgconsult.no> |
|---|---|
| date | Sat, 16 Feb 2013 15:32:20 +0100 |
| parents | aaf0a2878f67 |
| children | a827f3687c4a |
| files | BurnBitArray.cpp CMakeLists.txt TestDatabase.cpp TestDatabase.hpp TestFileDBLink.cpp TestFramework.cpp TestFramework.hpp TestMemoryDBLink.cpp TestSQLGenerator.cpp |
| diffstat | 9 files changed, 734 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BurnBitArray.cpp Sat Feb 16 15:32:20 2013 +0100 @@ -0,0 +1,198 @@ +#include "TestFramework.hpp" + +#include "BitDecoder.hpp" + +#define BURN_MAX 100000 +#define BURN for(size_t burn_counter = BURN_MAX; burn_counter > 0; --burn_counter) + +BOOST_AUTO_TEST_CASE( TestBasic ) +{ + BURN { + BitArray tbits(16, true); + BitArray fbits(16, false); + for (uint i = 0; i < tbits.size(); ++i) { + BOOST_REQUIRE_EQUAL(tbits.testBit(i), true); + BOOST_REQUIRE_EQUAL(fbits.testBit(i), false); + } + } + + BURN { + BitArray tbits(9, true); + BitArray fbits(9, false); + for (uint i = 0; i < tbits.size(); ++i) { + BOOST_REQUIRE_EQUAL(tbits.testBit(i), true); + BOOST_REQUIRE_EQUAL(fbits.testBit(i), false); + } + } + + BURN { + BitArray tbits(13, true); + BitArray fbits(13, false); + for (uint i = 0; i < tbits.size(); ++i) { + BOOST_REQUIRE_EQUAL(tbits.testBit(i), true); + BOOST_REQUIRE_EQUAL(fbits.testBit(i), false); + } + } + +} + + +BOOST_AUTO_TEST_CASE( TestSetBit ) +{ + + BURN { + for (uint i = 0; i < 13; ++i) { + BitArray tbits(13, true); + BitArray fbits(13, false); + tbits.setBit(i, false); + fbits.setBit(i, true); + for (uint j = 0; j < tbits.size(); ++j) { + BOOST_REQUIRE_EQUAL(tbits.testBit(j), i != j); + BOOST_REQUIRE_EQUAL(fbits.testBit(j), i == j); + } + } + } + +} + +BOOST_AUTO_TEST_CASE( TestSetBit2 ) +{ + BURN { + BitArray tbits(8, true); + BitArray fbits(8, false); + BOOST_REQUIRE_EQUAL(tbits, BitDecoder::bitsFromString("11111111")); + BOOST_REQUIRE_EQUAL(fbits, BitDecoder::bitsFromString("00000000")); + + tbits.setBit(0, false); + fbits.setBit(0, false); + BOOST_REQUIRE_EQUAL(tbits, BitDecoder::bitsFromString("01111111")); + BOOST_REQUIRE_EQUAL(fbits, BitDecoder::bitsFromString("00000000")); + + tbits.setBit(1, true); + fbits.setBit(1, true); + BOOST_REQUIRE_EQUAL(tbits, BitDecoder::bitsFromString("01111111")); + BOOST_REQUIRE_EQUAL(fbits, BitDecoder::bitsFromString("01000000")); + + tbits.setBit(2, false); + fbits.setBit(2, false); + BOOST_REQUIRE_EQUAL(tbits, BitDecoder::bitsFromString("01011111")); + BOOST_REQUIRE_EQUAL(fbits, BitDecoder::bitsFromString("01000000")); + + tbits.setBit(3, false); + fbits.setBit(3, false); + BOOST_REQUIRE_EQUAL(tbits, BitDecoder::bitsFromString("01001111")); + BOOST_REQUIRE_EQUAL(fbits, BitDecoder::bitsFromString("01000000")); + + tbits.setBit(4, false); + fbits.setBit(4, false); + BOOST_REQUIRE_EQUAL(tbits, BitDecoder::bitsFromString("01000111")); + BOOST_REQUIRE_EQUAL(fbits, BitDecoder::bitsFromString("01000000")); + + tbits.setBit(5, true); + fbits.setBit(5, true); + BOOST_REQUIRE_EQUAL(tbits, BitDecoder::bitsFromString("01000111")); + BOOST_REQUIRE_EQUAL(fbits, BitDecoder::bitsFromString("01000100")); + + tbits.setBit(6, true); + fbits.setBit(6, true); + BOOST_REQUIRE_EQUAL(tbits, BitDecoder::bitsFromString("01000111")); + BOOST_REQUIRE_EQUAL(fbits, BitDecoder::bitsFromString("01000110")); + + tbits.setBit(7, false); + fbits.setBit(7, false); + BOOST_REQUIRE_EQUAL(tbits, BitDecoder::bitsFromString("01000110")); + BOOST_REQUIRE_EQUAL(fbits, BitDecoder::bitsFromString("01000110")); + + } +} + +BOOST_AUTO_TEST_CASE( TestPaddedChar ) +{ + BURN { + BitArray bits = BitDecoder::bitsFromString("0100011011"); + + BOOST_REQUIRE_EQUAL(bits.size(), 10u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(0), 70); + + bits = BitDecoder::bitsFromString("0000000001"); + BOOST_REQUIRE_EQUAL(bits.size(), 10u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(2), 1u); + + bits = BitDecoder::bitsFromString("0000000011"); + BOOST_REQUIRE_EQUAL(bits.size(), 10u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(2), 3u); + + bits = BitDecoder::bitsFromString("000000000011"); + BOOST_REQUIRE_EQUAL(bits.size(), 12u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(4), 3u); + + bits = BitDecoder::bitsFromString("0000000000011"); + BOOST_REQUIRE_EQUAL(bits.size(), 13u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(5), 3u); + + bits = BitDecoder::bitsFromString("00000000000011"); + BOOST_REQUIRE_EQUAL(bits.size(), 14u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(6), 3u); + + bits = BitDecoder::bitsFromString("000000000000011"); + BOOST_REQUIRE_EQUAL(bits.size(), 15u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(7), 3u); + + bits = BitDecoder::bitsFromString("10000001"); + BOOST_REQUIRE_EQUAL(bits.size(), 8u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(0), 129u); + + bits = BitDecoder::bitsFromString("010000001"); + BOOST_REQUIRE_EQUAL(bits.size(), 9u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(1), 129u); + + bits = BitDecoder::bitsFromString("0010000001"); + BOOST_REQUIRE_EQUAL(bits.size(), 10u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(2), 129u); + + bits = BitDecoder::bitsFromString("00010000001"); + BOOST_REQUIRE_EQUAL(bits.size(), 11u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(3), 129u); + + bits = BitDecoder::bitsFromString("000010000001"); + BOOST_REQUIRE_EQUAL(bits.size(), 12u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(4), 129u); + + bits = BitDecoder::bitsFromString("0000010000001"); + BOOST_REQUIRE_EQUAL(bits.size(), 13u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(5), 129u); + + bits = BitDecoder::bitsFromString("00000010000001"); + BOOST_REQUIRE_EQUAL(bits.size(), 14u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(6), 129u); + + bits = BitDecoder::bitsFromString("000000010000001"); + BOOST_REQUIRE_EQUAL(bits.size(), 15u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(7), 129u); + + + bits = BitDecoder::bitsFromString("0100011011"); + BOOST_REQUIRE_EQUAL(bits.size(), 10u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(2), 27u); + } +} + +BOOST_AUTO_TEST_CASE( TestCorrectChar ) +{ + BURN { + BitArray bits = BitDecoder::bitsFromString("00000001"); + BOOST_REQUIRE_EQUAL(bits.size(), 8u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(0), 1u); + + bits = BitDecoder::bitsFromString("00000011"); + BOOST_REQUIRE_EQUAL(bits.size(), 8u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(0), 3u); + + bits = BitDecoder::bitsFromString("10000000"); + BOOST_REQUIRE_EQUAL(bits.size(), 8u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(0), 128u); + bits = BitDecoder::bitsFromString("11000000"); + BOOST_REQUIRE_EQUAL(bits.size(), 8u); + BOOST_REQUIRE_EQUAL(bits.getPaddedChar(0), 192u); + } +}
--- a/CMakeLists.txt Sat Feb 16 15:30:12 2013 +0100 +++ b/CMakeLists.txt Sat Feb 16 15:32:20 2013 +0100 @@ -9,11 +9,31 @@ SET(COVERAGE_FLAGS "--coverage") ENDIF() +SET(ALL_TESTS) + MACRO(NEW_TEST file) STRING(REPLACE "/" "_" TARGET ${file}) ADD_EXECUTABLE(${TARGET} ${file}.cpp ${TEST_SOURCES}) ADD_TEST(${TARGET} ${TARGET}) - TARGET_LINK_LIBRARIES(${TARGET} ${QT_LIBRARIES} ${Boost_LIBRARIES} ${COVERAGE_FLAGS}) + TARGET_LINK_LIBRARIES(${TARGET} ${QT_LIBRARIES} ${Boost_LIBRARIES} + ${COVERAGE_FLAGS}) + + ADD_CUSTOM_COMMAND(OUTPUT "BUILD_${TARGET}" + COMMAND "${CMAKE_COMMAND}" + --build ${CMAKE_BINARY_DIR} + --target ${TARGET} + COMMENT "Building test ${TARGET}" + ) + SET(BUILD_ALL_TESTS ${BUILD_ALL_TESTS} BUILD_${TARGET}) + + SET(ALL_TESTS ${ALL_TESTS} RUN_${TARGET}) + ADD_CUSTOM_TARGET(RUN_${TARGET} ${CMAKE_BINARY_DIR}/${TARGET} --log_level=nothing --report_level=no + DEPENDS zero_counters_test_with_base + BUILD_${TARGET} + COMMENT "Running test ${TARGET}" + +) + ENDMACRO() SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMake_Modules/") @@ -64,7 +84,6 @@ HuffmanString.cpp MemoryDBLink.cpp SqliteDBLink.cpp - UniqueString.cpp ) SET(CLASS_HEADERS @@ -98,6 +117,7 @@ SET(TEST_SOURCES ${CLASS_SOURCES} ${MOC_SOURCES} + TestDatabase.cpp TestFramework.cpp ) @@ -150,6 +170,8 @@ NEW_TEST(Exception/TestValueExistsException) NEW_TEST(Exception/TestPermissionException) NEW_TEST(TestBitArray) +NEW_TEST(TestSQLGenerator) +NEW_TEST(TestFileDBLink) NEW_TEST(TestBitDecoder) NEW_TEST(TestDBCache) NEW_TEST(TestEditDistance) @@ -159,35 +181,68 @@ NEW_TEST(TestMemoryDBLink) NEW_TEST(TestSqliteDBLink) + #ADD_PRECOMPILED_HEADER(TestEditDistance TestFramework.hpp) +ADD_CUSTOM_COMMAND(OUTPUT build_tests COMMAND "${CMAKE_COMMAND}" +--build ${CMAKE_BINARY_DIR} --target all) -ADD_CUSTOM_COMMAND(OUTPUT coverage.info - COMMAND lcov --no-external --capture +ADD_CUSTOM_TARGET(zero_counters_test_with_base + lcov -q -z -d ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${BUILD_ALL_TESTS} +) + +ADD_CUSTOM_COMMAND(OUTPUT test_with_base COMMAND +true +DEPENDS zero_counters_test_with_base ${ALL_TESTS} + COMMENT "All test have run" +) + +ADD_CUSTOM_COMMAND(OUTPUT coverage_base_raw.info + COMMAND lcov --no-external + --capture --initial --directory ${CMAKE_CURRENT_BINARY_DIR} --base-directory ${CMAKE_CURRENT_SOURCE_DIR} - --output-file coverage.info + --output-file coverage_base_raw.info +) + +ADD_CUSTOM_COMMAND(OUTPUT coverage_test.info + COMMAND lcov -q --no-external --capture + --directory ${CMAKE_CURRENT_BINARY_DIR} + --base-directory ${CMAKE_CURRENT_SOURCE_DIR} + --output-file + coverage_test.info + DEPENDS test_with_base ) ADD_CUSTOM_COMMAND(OUTPUT coverage.preprocessed2 - COMMAND lcov -r - coverage.info 'moc_*' + COMMAND lcov -q -r + coverage_test.info 'moc_*' --output-file coverage.preprocessed2 - DEPENDS coverage.info + DEPENDS coverage_test.info + COMMENT "Removing \"moc_\"-files" ) ADD_CUSTOM_COMMAND(OUTPUT coverage.preprocessed - COMMAND lcov -r + COMMAND lcov -q -r coverage.preprocessed2 'Test*' --output-file coverage.preprocessed - DEPENDS coverage.preprocessed2 + DEPENDS + coverage.preprocessed2 + COMMENT "Removing \"Test\"-files" ) -ADD_CUSTOM_TARGET(coverage_presentation genhtml +ADD_CUSTOM_TARGET(coverage_presentation genhtml -q ${CMAKE_CURRENT_BINARY_DIR}/coverage.preprocessed --output-directory ${CMAKE_CURRENT_BINARY_DIR}/coverage_presentation - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/coverage.preprocessed + DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/coverage.preprocessed ) + +ADD_CUSTOM_TARGET(coverage_base + DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/coverage_base.info +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TestDatabase.cpp Sat Feb 16 15:32:20 2013 +0100 @@ -0,0 +1,28 @@ +#include "TestDataBase.hpp" + +#include "Exception/IOException.hpp" + +TestDatabase::TestDatabase() : connectionName("TestDatabase"), + db(new QSqlDatabase) +{ + *db = QSqlDatabase::addDatabase("QSQLITE", connectionName); + const QString dbPath(":memory:"); + db->setDatabaseName(dbPath); + if (!db->open()) + throw + IOException(QString("Unable to open SQLite database with path '%1'") + .arg(dbPath)); + +} + +TestDatabase::~TestDatabase() +{ + db->close(); + delete db; + QSqlDatabase::removeDatabase(connectionName); +} + +QSqlDatabase TestDatabase::getDatabase() +{ + return *db; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TestDatabase.hpp Sat Feb 16 15:32:20 2013 +0100 @@ -0,0 +1,18 @@ +#ifndef TESTDATABASE_HPP +#define TESTDATABASE_HPP + +#include <QtSql/QSqlDatabase> + +class TestDatabase +{ +public: + QSqlDatabase getDatabase(); + TestDatabase(); + ~TestDatabase(); + +private: + const QString connectionName; + QSqlDatabase *db; +}; + +#endif //TESTDATABASE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TestFileDBLink.cpp Sat Feb 16 15:32:20 2013 +0100 @@ -0,0 +1,60 @@ +#include "FileDBLink.hpp" +#include "TestFramework.hpp" + +BOOST_AUTO_TEST_CASE( DBInfoSerialize ) +{ + QString dir("de"); + QString name("cd"); + QString path(QString("%1/%2").arg(dir).arg(name)); + int size = 64; + QDateTime time1 = QDateTime::currentDateTime(); + QByteArray hash = QByteArray::fromHex("ab"); + FileDBLink::DBInfo info(path, size, time1, hash); + + BOOST_REQUIRE_EQUAL(info.path(), path); + BOOST_REQUIRE_EQUAL(info.name(), name); + BOOST_REQUIRE_EQUAL(info.size(), size); + BOOST_REQUIRE_EQUAL(info.mtime(), time1); + BOOST_REQUIRE_EQUAL(info.checksum(), hash); + + BOOST_REQUIRE_EQUAL(info.serialize(), + QString("%1, %2, %3, %4") + .arg(info.path()) + .arg(size) + .arg(time1.toString()) + .arg(QString(hash.toHex())) + ); +} + +BOOST_AUTO_TEST_CASE( ExtendedDBInfoSerialize ) +{ + QString dir("de"); + QString name("cd"); + QString path(QString("%1/%2").arg(dir).arg(name)); + int size = 64; + QDateTime time1 = QDateTime::currentDateTime(); + QByteArray hash = QByteArray::fromHex("ab"); + QString closestEditPath = "aa"; + int editDistance = 1; + FileDBLink::ExtendedDBInfo info(FileDBLink::DBInfo(path, size, time1, hash), + closestEditPath, + editDistance + ); + + BOOST_REQUIRE_EQUAL(info.path(), path); + BOOST_REQUIRE_EQUAL(info.name(), name); + BOOST_REQUIRE_EQUAL(info.size(), size); + BOOST_REQUIRE_EQUAL(info.mtime(), time1); + BOOST_REQUIRE_EQUAL(info.checksum(), hash); + BOOST_REQUIRE_EQUAL(info.editDistance(), editDistance); + + BOOST_REQUIRE_EQUAL(info.serialize(), + QString("%1, %2, %3, %4, %5, %6") + .arg(info.path()) + .arg(size) + .arg(time1.toString()) + .arg(QString(hash.toHex())) + .arg(closestEditPath) + .arg(editDistance) + ); +}
--- a/TestFramework.cpp Sat Feb 16 15:30:12 2013 +0100 +++ b/TestFramework.cpp Sat Feb 16 15:32:20 2013 +0100 @@ -9,3 +9,9 @@ { return out << rhs.toString(); } + +std::ostream& operator<<(std::ostream& out, const QByteArray& rhs) +{ + QByteArray b64 = rhs.toBase64(); + return out << b64.constData(); +}
--- a/TestFramework.hpp Sat Feb 16 15:30:12 2013 +0100 +++ b/TestFramework.hpp Sat Feb 16 15:32:20 2013 +0100 @@ -19,5 +19,7 @@ std::ostream& operator<<(std::ostream& out, const QString& rhs); class QDateTime; std::ostream& operator<<(std::ostream& out, const QDateTime& rhs); +class QByteArray; +std::ostream& operator<<(std::ostream& out, const QByteArray& rhs); #endif //TESTFRAMEWORK_HPP
--- a/TestMemoryDBLink.cpp Sat Feb 16 15:30:12 2013 +0100 +++ b/TestMemoryDBLink.cpp Sat Feb 16 15:32:20 2013 +0100 @@ -6,33 +6,60 @@ { MemoryDBLink link; - QDateTime time1; + QDateTime time1 = QDateTime::currentDateTime(); QDateTime time2 = time1.addSecs(1); + BOOST_REQUIRE(!link.exists("test")); BOOST_REQUIRE_EQUAL(link.existsWithMtime("test", time1), FileDBLink::NONE); link.addFile("test", 1, time1, "a"); BOOST_REQUIRE_EQUAL(link.existsWithMtime("test", time1), FileDBLink::SAME); + BOOST_REQUIRE(link.exists("test")); BOOST_REQUIRE_THROW(link.addFile("test", 1, time1, "a"), ValueExistsException); link.updateFile("test", 1, time2, "a"); BOOST_REQUIRE_EQUAL(link.existsWithMtime("test", time1), FileDBLink::MTIME_DIFFERENT); + BOOST_REQUIRE(link.exists("test")); BOOST_REQUIRE_THROW(link.addFile("test", 1, time1, "a"), ValueExistsException); - /* - BOOST_REQUIRE(!map.find(k4)); - map.insert(k4); - BOOST_WARN_EQUAL(map.depth(), 2u); - BOOST_WARN_EQUAL(map.total_depth(), 8u); - BOOST_REQUIRE_EQUAL(map.size(), 4u); - BOOST_REQUIRE_EQUAL(map.optimal_depth(), 3u); - BOOST_REQUIRE_THROW(map.insert(k4), ValueExistsException); - BOOST_REQUIRE(map.find(k1)); - BOOST_REQUIRE_EQUAL(*map.find(k1), k1); - BOOST_REQUIRE(map.find(k2)); - BOOST_REQUIRE_EQUAL(*map.find(k2), k2); - BOOST_REQUIRE(map.find(k4)); - BOOST_REQUIRE_EQUAL(*map.find(k4), k4); - */ + } + +BOOST_AUTO_TEST_CASE( SortUnsortable ) +{ + MemoryDBLink link; + + QString path1 = "a"; + int size1 = 1; + QDateTime time1 = QDateTime::currentDateTime(); + QByteArray checksum1 = QByteArray::fromHex("a"); + + QString path2 = "b"; + int size2 = 2; + QDateTime time2 = time1.addSecs(1); + QByteArray checksum2 = QByteArray::fromHex("b"); + + + link.addFile(path2, size2, time2, checksum2); + link.addFile(path1, size1, time1, checksum1); + + + { + QList<FileDBLink::dbinf_ptr_t > out; + out = link.sortOn("", FileDBLink::PATH, false); + + bool first = true; + QString prev; + foreach(FileDBLink::dbinf_ptr_t info, out) { + if (first) { + first = false; + } + else { + BOOST_REQUIRE(prev <= info->path()); + } + prev = info->path(); + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TestSQLGenerator.cpp Sat Feb 16 15:32:20 2013 +0100 @@ -0,0 +1,312 @@ +#include "SQLGenerator.hpp" +#include "TestFramework.hpp" +#include "TestDataBase.hpp" + +#include "Exception/SQLException.hpp" + +BOOST_AUTO_TEST_CASE( CreateInsertAndRetrieveQString ) +{ + TestDatabase tdb; + QSqlDatabase db = tdb.getDatabase(); + QSqlQuery query(db); + + QString tableName = "test"; + + QString fieldCreateString1 = SQLGenerator<QString>::createFields("value1"); + QString fieldCreateString2 = SQLGenerator<QString>::createFields("value2"); + + + QString createQuery = QString("CREATE TABLE %1(%2, %3);") + .arg(tableName) + .arg(fieldCreateString1) + .arg(fieldCreateString2); + + BOOST_REQUIRE(query.exec(createQuery)); + + + QString queryString = QString("INSERT into %1 (%2, %3) VALUES(%4, %5);") + .arg(tableName) + .arg(SQLGenerator<QString>::fieldName("value1")) + .arg(SQLGenerator<QString>::fieldName("value2")) + .arg(SQLGenerator<QString>::valueString("value1")) + .arg(SQLGenerator<QString>::valueString("value2")); + QSqlQuery insertQuery = QSqlQuery(db); + BOOST_REQUIRE(insertQuery.prepare(queryString)); + + QList<QString> valueList1, valueList2; + for (int i = 1; i <= 3; ++i) { + valueList1 << QString("a%1").arg(i); + valueList2 << QString("b%1").arg(i); + } + + SQLGenerator<QString>::bindValues(insertQuery, valueList1, "value1"); + SQLGenerator<QString>::bindValues(insertQuery, valueList2, "value2"); + BOOST_REQUIRE(insertQuery.execBatch()); + insertQuery.finish(); + + QString fieldValueString1 = SQLGenerator<QString>::fieldName("value1"); + QString fieldValueString2 = SQLGenerator<QString>::fieldName("value2"); + + QString selectQuery = QString("SELECT %1, %2 FROM %3;") + .arg(fieldValueString1).arg(fieldValueString2).arg(tableName); + + BOOST_REQUIRE(query.exec(selectQuery)); + + while (query.next()) { + QString value1 = *SQLGenerator<QString>::extract(query, "value1"); + QString value2 = *SQLGenerator<QString>::extract(query, "value2"); + + BOOST_REQUIRE(valueList1.contains(value1)); + BOOST_REQUIRE(valueList2.contains(value2)); + + valueList1.removeAt(valueList1.indexOf(value1)); + valueList2.removeAt(valueList2.indexOf(value2)); + } + + boost::optional<QString> empty1 = + SQLGenerator<QString>::extract(query, "value1"); + boost::optional<QString> empty2 = + SQLGenerator<QString>::extract(query, "value2"); + + BOOST_REQUIRE(!empty1); + BOOST_REQUIRE(!empty2); + + BOOST_REQUIRE(valueList1.empty()); + BOOST_REQUIRE(valueList2.empty()); + + query.finish(); +} + +BOOST_AUTO_TEST_CASE( CreateInsertAndRetrieveUniqueString ) +{ + TestDatabase tdb; + QSqlDatabase db = tdb.getDatabase(); + QSqlQuery query(db); + + QString tableName = "test"; + + QString fieldCreateString1 = + SQLGenerator<UniqueString>::createFields("value1"); + QString fieldCreateString2 = + SQLGenerator<UniqueString>::createFields("value2"); + + + QString createQuery = QString("CREATE TABLE %1(%2, %3);") + .arg(tableName) + .arg(fieldCreateString1) + .arg(fieldCreateString2); + + BOOST_REQUIRE(query.exec(createQuery)); + + + QString queryString = QString("INSERT into %1 (%2, %3) VALUES(%4, %5);") + .arg(tableName) + .arg(SQLGenerator<UniqueString>::fieldName("value1")) + .arg(SQLGenerator<UniqueString>::fieldName("value2")) + .arg(SQLGenerator<UniqueString>::valueString("value1")) + .arg(SQLGenerator<UniqueString>::valueString("value2")); + QSqlQuery insertQuery = QSqlQuery(db); + BOOST_REQUIRE(insertQuery.prepare(queryString)); + + QList<UniqueString> valueList1, valueList2; + for (int i = 1; i <= 3; ++i) { + valueList1 << QString("a%1").arg(i); + valueList2 << QString("b%1").arg(i); + } + + SQLGenerator<UniqueString>::bindValues(insertQuery, valueList1, "value1"); + SQLGenerator<UniqueString>::bindValues(insertQuery, valueList2, "value2"); + BOOST_REQUIRE(insertQuery.execBatch()); + insertQuery.finish(); + + QString fieldValueString1 = SQLGenerator<UniqueString>::fieldName("value1"); + QString fieldValueString2 = SQLGenerator<UniqueString>::fieldName("value2"); + + QString selectQuery = QString("SELECT %1, %2 FROM %3;") + .arg(fieldValueString1).arg(fieldValueString2).arg(tableName); + + BOOST_REQUIRE(query.exec(selectQuery)); + + while (query.next()) { + UniqueString value1 = *SQLGenerator<UniqueString>::extract(query, "value1"); + UniqueString value2 = *SQLGenerator<UniqueString>::extract(query, "value2"); + + BOOST_REQUIRE(valueList1.contains(value1)); + BOOST_REQUIRE(valueList2.contains(value2)); + + valueList1.removeAt(valueList1.indexOf(value1)); + valueList2.removeAt(valueList2.indexOf(value2)); + } + + boost::optional<UniqueString> empty1 = + SQLGenerator<UniqueString>::extract(query, "value1"); + boost::optional<UniqueString> empty2 = + SQLGenerator<UniqueString>::extract(query, "value2"); + + BOOST_REQUIRE(!empty1); + BOOST_REQUIRE(!empty2); + + BOOST_REQUIRE(valueList1.empty()); + BOOST_REQUIRE(valueList2.empty()); + + query.finish(); +} + +BOOST_AUTO_TEST_CASE( CreateInsertAndRetrieveInt ) +{ + TestDatabase tdb; + QSqlDatabase db = tdb.getDatabase(); + + QSqlQuery query(db); + + QString tableName = "test"; + + QString fieldCreateString1 = SQLGenerator<int>::createFields("value1"); + QString fieldCreateString2 = SQLGenerator<int>::createFields("value2"); + + + QString createQuery = QString("CREATE TABLE %1(%2, %3);") + .arg(tableName) + .arg(fieldCreateString1) + .arg(fieldCreateString2); + + BOOST_REQUIRE(query.exec(createQuery)); + + QString queryString = QString("INSERT into %1 (%2, %3) VALUES(%4, %5);") + .arg(tableName) + .arg(SQLGenerator<int>::fieldName("value1")) + .arg(SQLGenerator<int>::fieldName("value2")) + .arg(SQLGenerator<int>::valueString("value1")) + .arg(SQLGenerator<int>::valueString("value2")); + QSqlQuery insertQuery = QSqlQuery(db); + BOOST_REQUIRE(insertQuery.prepare(queryString)); + + QList<int> valueList1, valueList2; + int p1 = 2; + int p2 = 3; + int v1 = p1; + int v2 = p2; + for (int i = 1; i <= 3; ++i) { + valueList1 << v1; + valueList2 << v2; + v1 *= p1; + v2 *= p2; + } + + SQLGenerator<int>::bindValues(insertQuery, valueList1, "value1"); + SQLGenerator<int>::bindValues(insertQuery, valueList2, "value2"); + BOOST_REQUIRE(insertQuery.execBatch()); + insertQuery.finish(); + + QString fieldValueString1 = SQLGenerator<int>::fieldName("value1"); + QString fieldValueString2 = SQLGenerator<int>::fieldName("value2"); + + QString selectQuery = QString("SELECT %1, %2 FROM %3;") + .arg(fieldValueString1).arg(fieldValueString2).arg(tableName); + + BOOST_REQUIRE(query.exec(selectQuery)); + + while (query.next()) { + int value1 = *SQLGenerator<int>::extract(query, "value1"); + int value2 = *SQLGenerator<int>::extract(query, "value2"); + + BOOST_REQUIRE(valueList1.contains(value1)); + BOOST_REQUIRE(valueList2.contains(value2)); + + valueList1.removeAt(valueList1.indexOf(value1)); + valueList2.removeAt(valueList2.indexOf(value2)); + } + boost::optional<int> empty1 = SQLGenerator<int>::extract(query, "value1"); + boost::optional<int> empty2 = SQLGenerator<int>::extract(query, "value2"); + + BOOST_REQUIRE(!empty1); + BOOST_REQUIRE(!empty2); + + BOOST_REQUIRE(valueList1.empty()); + BOOST_REQUIRE(valueList2.empty()); + +} + +BOOST_AUTO_TEST_CASE( CreateInsertAndRetrieveOrderedPair ) +{ + TestDatabase tdb; + QSqlDatabase db = tdb.getDatabase(); + QSqlQuery query(db); + + QString tableName = "test"; + + QString fieldCreateString1 = + SQLGenerator<OrderedPair<int> >::createFields("value1"); + QString fieldCreateString2 = + SQLGenerator<OrderedPair<int> >::createFields("value2"); + + + QString createQuery = QString("CREATE TABLE %1(%2, %3);") + .arg(tableName) + .arg(fieldCreateString1) + .arg(fieldCreateString2); + + BOOST_REQUIRE(query.exec(createQuery)); + + + QString queryString = QString("INSERT into %1 (%2, %3) VALUES(%4, %5);") + .arg(tableName) + .arg(SQLGenerator<OrderedPair<int> >::fieldName("value1")) + .arg(SQLGenerator<OrderedPair<int> >::fieldName("value2")) + .arg(SQLGenerator<OrderedPair<int> >::valueString("value1")) + .arg(SQLGenerator<OrderedPair<int> >::valueString("value2")); + QSqlQuery insertQuery = QSqlQuery(db); + BOOST_REQUIRE(insertQuery.prepare(queryString)); + + QList<OrderedPair<int> > valueList1, valueList2; + int p [] = { 2, 3, 5, 7}; + int v [] = { 2, 3, 5, 7}; + + for (int i = 1; i <= 3; ++i) { + valueList1 << OrderedPair<int>(v[0], v[1]); + valueList2 << OrderedPair<int>(v[2], v[3]); + for (int i = 0; i < 4; ++i) + v[i] *= p[i]; + } + + SQLGenerator<OrderedPair<int> >::bindValues(insertQuery, valueList1, "value1"); + SQLGenerator<OrderedPair<int> >::bindValues(insertQuery, valueList2, "value2"); + BOOST_REQUIRE(insertQuery.execBatch()); + insertQuery.finish(); + + QString fieldValueString1 = + SQLGenerator<OrderedPair<int> >::fieldName("value1"); + QString fieldValueString2 = + SQLGenerator<OrderedPair<int> >::fieldName("value2"); + + QString selectQuery = QString("SELECT %1, %2 FROM %3;") + .arg(fieldValueString1).arg(fieldValueString2).arg(tableName); + + BOOST_REQUIRE(query.exec(selectQuery)); + + while (query.next()) { + OrderedPair<int> value1 = + *SQLGenerator<OrderedPair<int> >::extract(query, "value1"); + OrderedPair<int> value2 = + *SQLGenerator<OrderedPair<int> >::extract(query, "value2"); + + BOOST_REQUIRE(valueList1.contains(value1)); + BOOST_REQUIRE(valueList2.contains(value2)); + + valueList1.removeAt(valueList1.indexOf(value1)); + valueList2.removeAt(valueList2.indexOf(value2)); + } + + boost::optional<OrderedPair<int> > empty1 = + SQLGenerator<OrderedPair<int> >::extract(query, "value1"); + boost::optional<OrderedPair<int> > empty2 = + SQLGenerator<OrderedPair<int> >::extract(query, "value2"); + + BOOST_REQUIRE(!empty1); + BOOST_REQUIRE(!empty2); + + BOOST_REQUIRE(valueList1.empty()); + BOOST_REQUIRE(valueList2.empty()); + + query.finish(); +}
