Phrase test (#112)
* initial * fix: ci test fail * more test rules for phrases
This commit is contained in:
parent
abf8d246b8
commit
e70f68dfab
|
|
@ -889,14 +889,25 @@ QString AbstractSqlGenerator::escapeValue(const QVariant &v) const
|
|||
if (v.type() == QVariant::String && v.toString().isEmpty())
|
||||
return QStringLiteral("''");
|
||||
|
||||
if (v.type() == QVariant::List) {
|
||||
auto list = v.toList();
|
||||
QStringList ret;
|
||||
foreach (QVariant vi, list) {
|
||||
ret.append(QStringLiteral("'")
|
||||
+ _serializer->serialize(vi)
|
||||
+ QStringLiteral("'"));
|
||||
}
|
||||
return QStringLiteral("(")
|
||||
+ ret.join(QStringLiteral(", "))
|
||||
+ QStringLiteral(")");
|
||||
}
|
||||
|
||||
QString serialized = _serializer->serialize(v);
|
||||
if (serialized.isEmpty()) {
|
||||
qWarning("No field escape rule for: %s", v.typeName());
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (v.type() == QVariant::List)
|
||||
return serialized;
|
||||
|
||||
return QStringLiteral("'") + serialized + QStringLiteral("'");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ AbstractFieldPhrase AbstractFieldPhrase::operator ~()
|
|||
|
||||
AbstractFieldPhrase AbstractFieldPhrase::operator !()
|
||||
{
|
||||
AbstractFieldPhrase f(data->className, data->fieldName);
|
||||
AbstractFieldPhrase f(data->clone());
|
||||
f.data->isNot = !data->isNot;
|
||||
return f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,8 +185,9 @@ DECLARE_CONDITIONALPHRASE_OPERATORS_IMPL(&&, PhraseData::And)
|
|||
|
||||
ConditionalPhrase ConditionalPhrase::operator !()
|
||||
{
|
||||
ConditionalPhrase f(data);
|
||||
f.data->isNot = !data->isNot;
|
||||
ConditionalPhrase f;
|
||||
f.data = data->clone();
|
||||
f.data->isNot = !f.data->isNot;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,38 +51,11 @@ debug_and_release:!ReleaseBuild:!DebugBuild {
|
|||
}
|
||||
}
|
||||
|
||||
win32 {
|
||||
CONFIG(debug,debug|release): LIBDIR = $$absolute_path($$OUT_PWD/../../../src/nut/debug)
|
||||
CONFIG(release,debug|release): LIBDIR = $$absolute_path($$OUT_PWD/../../../src/nut/release)
|
||||
# LIBS += -L$$LIBDIR -lnut
|
||||
} else {
|
||||
LIBDIR = $$absolute_path($$OUT_PWD/../../../lib)
|
||||
android: {
|
||||
|
||||
contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
|
||||
LIBS += -L$$LIBDIR -lnut_armeabi-v7a
|
||||
}
|
||||
contains(ANDROID_TARGET_ARCH,arm64-v8a) {
|
||||
LIBS += -L$$LIBDIR -lnut_arm64-v8a
|
||||
}
|
||||
contains(ANDROID_TARGET_ARCH,x86) {
|
||||
LIBS += -L$$LIBDIR -lnut_x86
|
||||
}
|
||||
contains(ANDROID_TARGET_ARCH,x86_64) {
|
||||
LIBS += -L$$LIBDIR -lnut_x86_64
|
||||
}
|
||||
} else {
|
||||
# LIBS += -L$$LIBDIR
|
||||
}
|
||||
}
|
||||
|
||||
#INCLUDEPATH += $$PWD/../../../src/nut
|
||||
INCLUDEPATH += $$PWD/../common
|
||||
|
||||
QT += nut
|
||||
CONFIG += testcase
|
||||
|
||||
DEFINES += NUT_SHARED_POINTER
|
||||
DEFINES += NUT_PATH=\\\"$$PWD/../../\\\"
|
||||
|
||||
runtarget.target = run-tests
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#include "generator.h"
|
||||
|
||||
Generator::Generator() : Nut::SqliteGenerator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString Generator::where(const Nut::ConditionalPhrase &where)
|
||||
{
|
||||
return createConditionalPhrase(where.data);
|
||||
}
|
||||
|
||||
QString Generator::order(const Nut::PhraseList &order)
|
||||
{
|
||||
return createOrderPhrase(order);
|
||||
}
|
||||
|
||||
QString Generator::select(const Nut::PhraseList &select)
|
||||
{
|
||||
return createFieldPhrase(select);
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef GENERATOR_H
|
||||
#define GENERATOR_H
|
||||
|
||||
#include <QtNut/sqlitegenerator.h>
|
||||
|
||||
class Generator : public Nut::SqliteGenerator
|
||||
{
|
||||
public:
|
||||
Generator();
|
||||
|
||||
QString where(const Nut::ConditionalPhrase &where);
|
||||
QString order(const Nut::PhraseList &order);
|
||||
QString select(const Nut::PhraseList &select);
|
||||
};
|
||||
|
||||
#endif // GENERATOR_H
|
||||
|
|
@ -1,14 +1,24 @@
|
|||
#include <QtTest>
|
||||
#include <QDate>
|
||||
#include <qtestcase.h>
|
||||
|
||||
#include "tst_phrases.h"
|
||||
#include "phrase.h"
|
||||
#include "sqlitegenerator.h"
|
||||
#include "generator.h"
|
||||
|
||||
using namespace Nut;
|
||||
|
||||
#define COMPARE_WHERE(w, sql) QCOMPARE(g.where(w), sql);
|
||||
#define COMPARE_ORDER(o, sql) QCOMPARE(g.order(o), sql);
|
||||
#define COMPARE_SELECT(s, sql) QCOMPARE(g.select(s), sql);
|
||||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_CLANG("-Wdeprecated-declarations")
|
||||
QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations")
|
||||
|
||||
PhrasesTest::PhrasesTest(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PhrasesTest::initTestCase()
|
||||
|
|
@ -25,94 +35,143 @@ void PhrasesTest::no1()
|
|||
FieldPhrase<QDate> date("main", "date");
|
||||
auto w = (id == 4 && name == QStringLiteral("hi"));
|
||||
|
||||
SqliteGenerator g;
|
||||
Generator g;
|
||||
|
||||
COMPARE_WHERE(id == 10 || id.in({1, 2, 3, 4}), "([main].id = '10' OR [main].id IN ('1', '2', '3', '4'))");
|
||||
}
|
||||
}
|
||||
|
||||
void PhrasesTest::numeric()
|
||||
void PhrasesTest::condition_numeric_sqlite()
|
||||
{
|
||||
Generator g;
|
||||
|
||||
|
||||
FieldPhrase<int> n("main", "int");
|
||||
FieldPhrase<float> f("main", "float");
|
||||
|
||||
auto p1 = n == 1;
|
||||
auto p2 = n <= 1;
|
||||
auto p3 = n >= 1;
|
||||
auto p4 = n < 1;
|
||||
auto p5 = n > 1;
|
||||
auto p6 = n != 1;
|
||||
auto p7 = n = n + 1;
|
||||
auto p8 = n < n + 1;
|
||||
auto p9 = n <= n + 1;
|
||||
auto p10 = n > n + 1;
|
||||
auto p11 = n >= n + 1;
|
||||
auto p12 = n + 1 > n - 2;
|
||||
auto p13 = ++n;
|
||||
auto p14 = n++;
|
||||
auto p15 = n.between(1, 2);
|
||||
auto p16 = n + 1 < n + 2;
|
||||
COMPARE_WHERE(n < 1, "[main].int < '1'");
|
||||
COMPARE_WHERE(n > 1, "[main].int > '1'");
|
||||
COMPARE_WHERE(n <= 1, "[main].int <= '1'");
|
||||
COMPARE_WHERE(n >= 1, "[main].int >= '1'");
|
||||
COMPARE_WHERE(n != 1, "[main].int <> '1'");
|
||||
COMPARE_WHERE(n == 1, "[main].int = '1'");
|
||||
COMPARE_WHERE(n++, "[main].int + '1'");
|
||||
COMPARE_WHERE(++n, "[main].int + '1'");
|
||||
COMPARE_WHERE(n.between(10, 20), "[main].int BETWEEN '10' AND '20'");
|
||||
COMPARE_WHERE(n + 1 < n + 4, "[main].int + '1' < [main].int + '4'");
|
||||
|
||||
auto p21 = p1 && p2;
|
||||
auto p22 = p3 == p4;
|
||||
auto p23 = f == n + 1;
|
||||
auto p1 = n == 1;
|
||||
auto p2 = n <= 4;
|
||||
auto p3 = n >= 5;
|
||||
auto p4 = n < 7;
|
||||
|
||||
COMPARE_WHERE(p1 && p2, "([main].int = '1' AND [main].int <= '4')");
|
||||
COMPARE_WHERE(p3 == p4, "[main].int >= '5' = [main].int < '7'");
|
||||
COMPARE_WHERE(f == n + 1, "[main].float = [main].int + '1'");
|
||||
COMPARE_WHERE(f == 1.4 || (n == n + 1 && n < 100),
|
||||
"([main].float = '1.4' OR ([main].int = [main].int + '1' AND [main].int < '100'))");
|
||||
|
||||
auto p24 = n = 4;
|
||||
auto p26 = (n = 4) & (n = 5);
|
||||
auto p27 = n | f;
|
||||
}
|
||||
|
||||
void PhrasesTest::string()
|
||||
void PhrasesTest::condition_string_sqlite()
|
||||
{
|
||||
Generator g;
|
||||
FieldPhrase<QString> str("main", "string");
|
||||
|
||||
auto p1 = str == "salam";
|
||||
auto p2 = str.like("%hi%");
|
||||
auto p3 = str.isNull();
|
||||
auto p4 = str.in(QStringList() << "one" << "two" << "three");
|
||||
auto p5 = str != "hi" && str.like("%s");
|
||||
COMPARE_WHERE(str == "Hi", "[main].string = 'Hi'");
|
||||
COMPARE_WHERE(str.like("%hi%"), "[main].string LIKE '%hi%'");
|
||||
COMPARE_WHERE(str.isNull(), "[main].string IS NULL");
|
||||
COMPARE_WHERE(!str.isNull(), "[main].string IS NOT NULL");
|
||||
COMPARE_WHERE(str.in(QStringList() << "one"
|
||||
<< "two"
|
||||
<< "three"),
|
||||
"[main].string IN ('one', 'two', 'three')");
|
||||
|
||||
COMPARE_WHERE(!str.in(QStringList() << "one"
|
||||
<< "two"
|
||||
<< "three"),
|
||||
"[main].string NOT IN ('one', 'two', 'three')");
|
||||
COMPARE_WHERE(str != "hi" && str.like("%s"),
|
||||
"([main].string <> 'hi' AND [main].string LIKE '%s')");
|
||||
}
|
||||
|
||||
void PhrasesTest::boolean()
|
||||
void PhrasesTest::condition_bool_sqlite()
|
||||
{
|
||||
Generator g;
|
||||
FieldPhrase<bool> b("main", "bool");
|
||||
|
||||
auto p1 = b;
|
||||
auto p2 = !b;
|
||||
auto p3 = b == false;
|
||||
|
||||
QTEST_ASSERT(p1.data);
|
||||
QTEST_ASSERT(p2.data);
|
||||
QTEST_ASSERT(p3.data);
|
||||
COMPARE_WHERE(b, "[main].bool = 'true'");
|
||||
COMPARE_WHERE(!b, "[main].bool = 'false'");
|
||||
COMPARE_WHERE(b == true, "[main].bool = 'true'");
|
||||
COMPARE_WHERE(b == false, "[main].bool = 'false'");
|
||||
}
|
||||
|
||||
void PhrasesTest::datetime()
|
||||
void PhrasesTest::condition_datetime_sqlite()
|
||||
{
|
||||
Generator g;
|
||||
|
||||
FieldPhrase<QTime> time("main", "time");
|
||||
FieldPhrase<QDate> date("main", "date");
|
||||
FieldPhrase<QDateTime> datetime("main", "datetime");
|
||||
|
||||
auto p1 = time <= QTime::currentTime();
|
||||
auto p2 = time.addHours(2) < QTime::currentTime();
|
||||
auto p3 = date == QDate::currentDate();
|
||||
auto p4 = date.addDays(1) == QDate::currentDate();
|
||||
auto p5 = datetime > QDateTime::currentDateTime();
|
||||
auto p6 = datetime.addMonths(1) >= QDateTime::currentDateTime();
|
||||
auto p7 = time.between(QTime::currentTime().addSecs(-100), QTime::currentTime());
|
||||
auto p8 = time.hour() == 3;
|
||||
auto p9 = time = QTime::currentTime();
|
||||
QDate d(2020, 2, 20);
|
||||
QTime t(12, 34, 56);
|
||||
QDateTime dt(d, t);
|
||||
|
||||
// auto pi1 = time.addYears(1);
|
||||
// auto pi2 = date.addMinutes(3);
|
||||
COMPARE_WHERE(time.hour() == 1, "CAST(strftime('%H', [main].time) AS INT) = '1'");
|
||||
COMPARE_WHERE(time.minute() == 2, "CAST(strftime('%M', [main].time) AS INT) = '2'");
|
||||
COMPARE_WHERE(time.second() == 3, "CAST(strftime('%S', [main].time) AS INT) = '3'");
|
||||
|
||||
// QTEST_ASSERT(!pi1.data);
|
||||
// QTEST_ASSERT(!pi2.data);
|
||||
COMPARE_WHERE(date.year() == 1, "CAST(strftime('%Y', [main].date) AS INT) = '1'");
|
||||
COMPARE_WHERE(date.month() == 2, "CAST(strftime('%m', [main].date) AS INT) = '2'");
|
||||
COMPARE_WHERE(date.day() == 3, "CAST(strftime('%d', [main].date) AS INT) = '3'");
|
||||
|
||||
COMPARE_WHERE(time.isNull(), "[main].time IS NULL");
|
||||
COMPARE_WHERE(!time.isNull(), "[main].time IS NOT NULL");
|
||||
COMPARE_WHERE(time == t, "[main].time = '12:34:56'");
|
||||
COMPARE_WHERE(time.between(t.addSecs(-10),
|
||||
t),
|
||||
"[main].time BETWEEN '12:34:46' AND '12:34:56'");
|
||||
COMPARE_WHERE(date.addDays(2) == d, "DATE([main].date,'+2 DAY') = '2020-02-20'");
|
||||
COMPARE_WHERE(time.addMinutes(-3) == t, "TIME([main].time,'-3 MINUTE') = '12:34:56'");
|
||||
COMPARE_WHERE(datetime.addMinutes(1) == dt, "DATETIME([main].datetime,'+1 MINUTE') = '2020-02-20 12:34:56'");
|
||||
}
|
||||
|
||||
void PhrasesTest::order_sqlite()
|
||||
{
|
||||
Generator g;
|
||||
|
||||
FieldPhrase<int> id("main", "id");
|
||||
FieldPhrase<QString> name("main", "name");
|
||||
FieldPhrase<QString> last_name("main", "last_name");
|
||||
|
||||
COMPARE_ORDER(id, "[main].id");
|
||||
COMPARE_ORDER(id | name, "[main].id, [main].name");
|
||||
COMPARE_ORDER(id | !name | last_name, "[main].id, [main].name DESC, [main].last_name");
|
||||
}
|
||||
|
||||
void PhrasesTest::select_sqlite()
|
||||
{
|
||||
Generator g;
|
||||
|
||||
FieldPhrase<int> id("main", "id");
|
||||
FieldPhrase<QString> name("main", "name");
|
||||
FieldPhrase<QString> last_name("main", "last_name");
|
||||
|
||||
COMPARE_ORDER(id, "[main].id");
|
||||
COMPARE_ORDER(id | name, "[main].id, [main].name");
|
||||
COMPARE_ORDER(id | name | last_name, "[main].id, [main].name, [main].last_name");
|
||||
}
|
||||
|
||||
void PhrasesTest::extra()
|
||||
{
|
||||
Generator g;
|
||||
FieldPhrase<QUrl> url("main", "url");
|
||||
|
||||
auto p1 = url == QUrl();
|
||||
auto p2 = url == "http://google.com";
|
||||
COMPARE_WHERE(url == QUrl("http://google.com"), "[main].url = 'http://google.com'");
|
||||
}
|
||||
|
||||
void PhrasesTest::mix()
|
||||
|
|
@ -157,3 +216,5 @@ void PhrasesTest::order_by(const PhraseList &ph)
|
|||
}
|
||||
|
||||
QTEST_MAIN(PhrasesTest)
|
||||
|
||||
QT_WARNING_POP
|
||||
|
|
|
|||
|
|
@ -23,13 +23,18 @@ signals:
|
|||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void no1();
|
||||
|
||||
void numeric();
|
||||
void string();
|
||||
void boolean();
|
||||
void datetime();
|
||||
void condition_numeric_sqlite();
|
||||
void condition_string_sqlite();
|
||||
void condition_bool_sqlite();
|
||||
void condition_datetime_sqlite();
|
||||
|
||||
void order_sqlite();
|
||||
void select_sqlite();
|
||||
|
||||
void extra();
|
||||
|
||||
void no1();
|
||||
void mix();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@ CONFIG += warn_on c++11
|
|||
include(../common/nut-lib.pri)
|
||||
|
||||
SOURCES += \
|
||||
generator.cpp \
|
||||
tst_phrases.cpp
|
||||
|
||||
HEADERS += \
|
||||
generator.h \
|
||||
tst_phrases.h
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue