<commit_before>#include "DatabaseFactory.h"
#include "Person.h"

#include <QtTest>

#include <QMetaOrm/MetaEntityBuilder.h>
#include <QMetaOrm/ValueCriterion.h>
#include <QMetaOrm/SessionFactory.h>
#include <QMetaOrm/Session.h>

using namespace QMetaOrm;

class SqlHelper
{
public:
   typedef QSharedPointer<SqlHelper> Ptr;
   static Ptr factory(DatabaseFactory::Ptr databaseFactory) {
      return Ptr(new SqlHelper(databaseFactory));
   }

public:
   SqlHelper(DatabaseFactory::Ptr databaseFactory):
      m_databaseFactory(databaseFactory)
   {
   }

   void insert(const QString &aSql, const QVariantList &params = QVariantList()) {
      auto database = m_databaseFactory->createDatabase();
      QSqlQuery query(database);
      bool okPrepare = query.prepare(aSql);
      Q_ASSERT(okPrepare);

      for (int i = 0; i < params.size(); i++)
         query.bindValue(i, params[i]);
      bool okExec = query.exec();
      Q_ASSERT(okExec);
   }

   QList<QVariantList> select(const QString &aSql, const QVariantList &params = QVariantList()) {
      auto database = m_databaseFactory->createDatabase();
      QSqlQuery query(database);
      bool okPrepare = query.prepare(aSql);
      Q_ASSERT(okPrepare);

      for (int i = 0; i < params.size(); i++)
         query.bindValue(i, params[i]);
      bool okExec = query.exec();
      Q_ASSERT(okExec);

      QList<QVariantList> result;
      while (query.next()) {
         QVariantList record;
         for (int i = 0; i < query.record().count(); i++)
            record << query.value(i);
         result << record;
      }
      return result;
   }

private:
   DatabaseFactory::Ptr m_databaseFactory;
};

class AnyBuilder {
public:
   static QString anyString(int size = 10) {
      return QString().fill('A', size);
   }
};

/*
   TODO:
   - Caching when save() and select() is called in sequence.
*/
class SessionIT : public QObject
{
   Q_OBJECT

private:
   DatabaseFactory::Ptr m_databaseFactory;
   SessionFactory::Ptr m_sessionFactory;
   SqlHelper::Ptr m_sqlHelper;

public:
   SessionIT() {}

private Q_SLOTS :

   void init()
   {
      m_databaseFactory = SQLiteEmbeddedDatabaseFactory::factory();
      m_sessionFactory = DefaultSessionFactory::factory(
         m_databaseFactory,
         StandardQtLogger::factory(),
         StandardEntityCacheFactory::factory());
      m_sqlHelper = SqlHelper::factory(m_databaseFactory);
   }

   void cleanup() {
      m_sqlHelper.clear();
      m_sessionFactory.clear();
      m_databaseFactory.clear();
   }

   void selectOneBySql_noPersonExists_nullptr()
   {
      auto session = m_sessionFactory->createSession();

      auto item = session->selectOneBySql<PersonSimple>("select * from person limit 1");

      QVERIFY(item == nullptr);
   }

   void selectOneBySql_onePersonIsSelected_thatPerson()
   {
      QString name = "Mueller", surname = "Hans";
      int id = 1;
      m_sqlHelper->insert("insert into person (id, name, surname) values (?,?,?)", QVariantList() << id << name << surname);

      auto session = m_sessionFactory->createSession();
      auto item = session->selectOneBySql<PersonSimple>("select * from person limit 1");

      QVERIFY(item != nullptr);
      QCOMPARE(item->getId(), id);
      QCOMPARE(item->getName(), name);
      QCOMPARE(item->getSurname(), surname);
   }

   void selectOneBySql_twoPersonsAreSelected_exception()
   {
      QString sql = "insert into person (id, name, surname) values (?,?,?)";
      m_sqlHelper->insert(sql, QVariantList() << 1 << AnyBuilder::anyString() << AnyBuilder::anyString());
      m_sqlHelper->insert(sql, QVariantList() << 2 << AnyBuilder::anyString() << AnyBuilder::anyString());

      auto session = m_sessionFactory->createSession();
      QVERIFY_EXCEPTION_THROWN(session->selectOneBySql<PersonSimple>("select * from person"), MoreThanOneResultException);
   }

   void selectOneBySql_onePersonWithNameOnlyIsSelected_onePersonWithNameOnlyIsFilled()
   {
      QString name = "Mueller";
      m_sqlHelper->insert("insert into person (id, name, surname) values (?,?,?)", QVariantList() << 1 << name << "Hans");

      auto session = m_sessionFactory->createSession();
      auto item = session->selectOneBySql<PersonSimple>("select name from person limit 1");

      QVERIFY(item != nullptr);
      QCOMPARE(item->getId(), 0);
      QCOMPARE(item->getSurname(), QString());
      QCOMPARE(item->getName(), name);<commit_msg>Qt versions compatible exception test<commit_after>#include "DatabaseFactory.h"
#include "Person.h"

#include <QtTest>

#include <QMetaOrm/MetaEntityBuilder.h>
#include <QMetaOrm/ValueCriterion.h>
#include <QMetaOrm/SessionFactory.h>
#include <QMetaOrm/Session.h>

using namespace QMetaOrm;

/*
    Took from qt source for usage in old qt versions
*/
#  define VERIFY_EXCEPTION_THROWN(expression, exceptiontype) \
    do {\
        QT_TRY {\
            QT_TRY {\
                expression;\
                QTest::qFail("Expected exception of type " #exceptiontype " to be thrown" \
                             " but no exception caught", __FILE__, __LINE__);\
                return;\
            } QT_CATCH (const exceptiontype &) {\
            }\
        } QT_CATCH (const std::exception &e) {\
            QByteArray msg = QByteArray() + "Expected exception of type " #exceptiontype \
                             " to be thrown but std::exception caught with message: " + e.what(); \
            QTest::qFail(msg.constData(), __FILE__, __LINE__);\
            return;\
        } QT_CATCH (...) {\
            QTest::qFail("Expected exception of type " #exceptiontype " to be thrown" \
                         " but unknown exception caught", __FILE__, __LINE__);\
            return;\
        }\
    } while (0)

class SqlHelper
{
public:
   typedef QSharedPointer<SqlHelper> Ptr;
   static Ptr factory(DatabaseFactory::Ptr databaseFactory) {
      return Ptr(new SqlHelper(databaseFactory));
   }

public:
   SqlHelper(DatabaseFactory::Ptr databaseFactory):
      m_databaseFactory(databaseFactory)
   {
   }

   void insert(const QString &aSql, const QVariantList &params = QVariantList()) {
      auto database = m_databaseFactory->createDatabase();
      QSqlQuery query(database);
      bool okPrepare = query.prepare(aSql);
      Q_ASSERT(okPrepare);

      for (int i = 0; i < params.size(); i++)
         query.bindValue(i, params[i]);
      bool okExec = query.exec();
      Q_ASSERT(okExec);
   }

   QList<QVariantList> select(const QString &aSql, const QVariantList &params = QVariantList()) {
      auto database = m_databaseFactory->createDatabase();
      QSqlQuery query(database);
      bool okPrepare = query.prepare(aSql);
      Q_ASSERT(okPrepare);

      for (int i = 0; i < params.size(); i++)
         query.bindValue(i, params[i]);
      bool okExec = query.exec();
      Q_ASSERT(okExec);

      QList<QVariantList> result;
      while (query.next()) {
         QVariantList record;
         for (int i = 0; i < query.record().count(); i++)
            record << query.value(i);
         result << record;
      }
      return result;
   }

private:
   DatabaseFactory::Ptr m_databaseFactory;
};

class AnyBuilder {
public:
   static QString anyString(int size = 10) {
      return QString().fill('A', size);
   }
};

/*
   TODO:
   - Caching when save() and select() is called in sequence.
*/
class SessionIT : public QObject
{
   Q_OBJECT

private:
   DatabaseFactory::Ptr m_databaseFactory;
   SessionFactory::Ptr m_sessionFactory;
   SqlHelper::Ptr m_sqlHelper;

public:
   SessionIT() {}

private Q_SLOTS :

   void init()
   {
      m_databaseFactory = SQLiteEmbeddedDatabaseFactory::factory();
      m_sessionFactory = DefaultSessionFactory::factory(
         m_databaseFactory,
         StandardQtLogger::factory(),
         StandardEntityCacheFactory::factory());
      m_sqlHelper = SqlHelper::factory(m_databaseFactory);
   }

   void cleanup() {
      m_sqlHelper.clear();
      m_sessionFactory.clear();
      m_databaseFactory.clear();
   }

   void selectOneBySql_noPersonExists_nullptr()
   {
      auto session = m_sessionFactory->createSession();

      auto item = session->selectOneBySql<PersonSimple>("select * from person limit 1");

      QVERIFY(item == nullptr);
   }

   void selectOneBySql_onePersonIsSelected_thatPerson()
   {
      QString name = "Mueller", surname = "Hans";
      int id = 1;
      m_sqlHelper->insert("insert into person (id, name, surname) values (?,?,?)", QVariantList() << id << name << surname);

      auto session = m_sessionFactory->createSession();
      auto item = session->selectOneBySql<PersonSimple>("select * from person limit 1");

      QVERIFY(item != nullptr);
      QCOMPARE(item->getId(), id);
      QCOMPARE(item->getName(), name);
      QCOMPARE(item->getSurname(), surname);
   }

   void selectOneBySql_twoPersonsAreSelected_exception()
   {
      QString sql = "insert into person (id, name, surname) values (?,?,?)";
      m_sqlHelper->insert(sql, QVariantList() << 1 << AnyBuilder::anyString() << AnyBuilder::anyString());
      m_sqlHelper->insert(sql, QVariantList() << 2 << AnyBuilder::anyString() << AnyBuilder::anyString());

      auto session = m_sessionFactory->createSession();
      VERIFY_EXCEPTION_THROWN(session->selectOneBySql<PersonSimple>("select * from person"), MoreThanOneResultException);
   }

   void selectOneBySql_onePersonWithNameOnlyIsSelected_onePersonWithNameOnlyIsFilled()
   {
      QString name = "Mueller";
      m_sqlHelper->insert("insert into person (id, name, surname) values (?,?,?)", QVariantList() << 1 << name << "Hans");

      auto session = m_sessionFactory->createSession();
      auto item = session->selectOneBySql<PersonSimple>("select name from person limit 1");

      QVERIFY(item != nullptr);
      QCOMPARE(item->getId(), 0);
      QCOMPARE(item->getSurname(), QString());
      QCOMPARE(item->getName(), name);
{'fraction_non_alphanumeric': 0.1293974929235746, 'fraction_numerical': 0.0027294783663566516, 'mean_word_length': 3.25505376344086, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5297679', 'n_tokens_mistral': 2978, 'n_tokens_neox': 2909, 'n_words': 651}