LeechCraft 0.6.70-17609-g3dde4097dd
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
oraltest.cpp
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#include "oraltest.h"
10#include "common.h"
11
12QTEST_GUILESS_MAIN (LC::Util::OralTest)
13
14using LC::operator""_ct;
15
17{
19 QString Value_;
20
21 constexpr static auto ClassName = "AutogenPKeyRecord"_ct;
22
23 auto AsTuple () const
24 {
25 return std::tie (ID_, Value_);
26 }
27};
28
30 ID_,
31 Value_)
32
34
35struct NoPKeyRecord
36{
37 int ID_;
38 QString Value_;
39
40 constexpr static auto ClassName = "NoPKeyRecord"_ct;
41
42 auto AsTuple () const
43 {
44 return std::tie (ID_, Value_);
45 }
46};
47
48ORAL_ADAPT_STRUCT (NoPKeyRecord,
49 ID_,
50 Value_)
51
52TOSTRING (NoPKeyRecord)
53
54struct NonInPlaceConstructibleRecord
55{
56 int ID_;
57 QString Value_;
58
59 NonInPlaceConstructibleRecord () = default;
60
61 NonInPlaceConstructibleRecord (int id, const QString& value, double someExtraArgument)
62 : ID_ { id }
63 , Value_ { value }
64 {
65 Q_UNUSED (someExtraArgument)
66 }
67
68 constexpr static auto ClassName = "NonInPlaceConstructibleRecord"_ct;
69
70 auto AsTuple () const
71 {
72 return std::tie (ID_, Value_);
73 }
74};
75
76ORAL_ADAPT_STRUCT (NonInPlaceConstructibleRecord,
77 ID_,
78 Value_)
79
80TOSTRING (NonInPlaceConstructibleRecord)
81
82struct ComplexConstraintsRecord
83{
84 int ID_;
85 QString Value_;
86 int Age_;
87 int Weight_;
88
89 constexpr static auto ClassName = "ComplexConstraintsRecord"_ct;
90
91 auto AsTuple () const
92 {
93 return std::tie (ID_, Value_, Age_, Weight_);
94 }
95
96 using Constraints = lco::Constraints<
99 >;
100};
101
102ORAL_ADAPT_STRUCT (ComplexConstraintsRecord,
103 ID_,
104 Value_,
105 Age_,
106 Weight_)
107
108TOSTRING (ComplexConstraintsRecord)
109
110#if QT_VERSION < QT_VERSION_CHECK (6, 9, 0)
111template<typename... Args>
112QDebug operator<< (QDebug dbg, const std::tuple<Args...>& tup)
113{
114 return std::apply ([&] (auto&&... args) { return ((dbg.nospace () << args << ' '), ...); }, tup);
115}
116#endif
117
118namespace LC
119{
120namespace Util
121{
122 namespace sph = oral::sph;
123
124 void OralTest::testAutoPKeyRecordInsertSelect ()
125 {
128 const auto& list = adapted->Select ();
129 QCOMPARE (list, (QList<AutogenPKeyRecord> { { 1, "0" }, { 2, "1" }, { 3, "2" } }));
130 }
131
132 void OralTest::testAutoPKeyRecordInsertRvalueReturnsPKey ()
133 {
135
136 QList<int> ids;
137 for (int i = 0; i < 3; ++i)
138 ids << adapted->Insert ({ 0, QString::number (i) });
139
140 QCOMPARE (ids, (QList<int> { 1, 2, 3 }));
141 }
142
143 void OralTest::testAutoPKeyRecordInsertConstLvalueReturnsPKey ()
144 {
146
147 QList<AutogenPKeyRecord> records;
148 for (int i = 0; i < 3; ++i)
149 records.push_back ({ 0, QString::number (i) });
150
151 QList<int> ids;
152 for (const auto& record : records)
153 ids << adapted->Insert (record);
154
155 QCOMPARE (ids, (QList<int> { 1, 2, 3 }));
156 }
157
158 void OralTest::testAutoPKeyRecordInsertSetsPKey ()
159 {
161
162 QList<AutogenPKeyRecord> records;
163 for (int i = 0; i < 3; ++i)
164 records.push_back ({ 0, QString::number (i) });
165
166 for (auto& record : records)
167 adapted->Insert (record);
168
169 QCOMPARE (records, (QList<AutogenPKeyRecord> { { 1, "0" }, { 2, "1" }, { 3, "2" } }));
170 }
171
172 void OralTest::testNoPKeyRecordInsertSelect ()
173 {
174 auto adapted = PrepareRecords<NoPKeyRecord> (MakeDatabase ());
175 const auto& list = adapted->Select ();
176 QCOMPARE (list, (QList<NoPKeyRecord> { { 0, "0" }, { 1, "1" }, { 2, "2" } }));
177 }
178
179 void OralTest::testNonInPlaceConstructibleRecordInsertSelect ()
180 {
182 for (int i = 0; i < 3; ++i)
183 adapted->Insert ({ i, QString::number (i), 0 });
184
185 const auto& list = adapted->Select ();
186 QCOMPARE (list, (QList<NonInPlaceConstructibleRecord> { { 0, "0", 0 }, { 1, "1", 0 }, { 2, "2", 0 } }));
187 }
188
189 namespace
190 {
191 template<typename Ex, typename F>
192 void ShallThrow (F&& f)
193 {
194 bool failed = false;
195 try
196 {
197 f ();
198 }
199 catch (const Ex&)
200 {
201 failed = true;
202 }
203
204 QCOMPARE (failed, true);
205 }
206 }
207
208 void OralTest::testComplexConstraintsRecordInsertSelectDefault ()
209 {
211
212 adapted->Insert ({ 0, "first", 1, 2 });
213 ShallThrow<oral::QueryException> ([&] { adapted->Insert ({ 0, "second", 1, 2 }); });
214 ShallThrow<oral::QueryException> ([&] { adapted->Insert ({ 0, "first", 1, 3 }); });
215 adapted->Insert ({ 0, "second", 1, 3 });
216 ShallThrow<oral::QueryException> ([&] { adapted->Insert ({ 0, "first", 1, 3 }); });
217
218 const auto& list = adapted->Select ();
219 QCOMPARE (list, (QList<ComplexConstraintsRecord> { { 0, "first", 1, 2 }, { 0, "second", 1, 3 } }));
220 }
221
222 void OralTest::testComplexConstraintsRecordInsertSelectIgnore ()
223 {
225
226 adapted->Insert ({ 0, "first", 1, 2 }, lco::InsertAction::Ignore);
227 adapted->Insert ({ 0, "second", 1, 2 }, lco::InsertAction::Ignore);
228 adapted->Insert ({ 0, "first", 1, 3 }, lco::InsertAction::Ignore);
229 adapted->Insert ({ 0, "second", 1, 3 }, lco::InsertAction::Ignore);
230 adapted->Insert ({ 0, "first", 1, 3 }, lco::InsertAction::Ignore);
231
232 const auto& list = adapted->Select ();
233 QCOMPARE (list, (QList<ComplexConstraintsRecord> { { 0, "first", 1, 2 }, { 0, "second", 1, 3 } }));
234 }
235
236 void OralTest::testComplexConstraintsRecordInsertSelectReplace ()
237 {
239
240 const auto idValueFields = lco::InsertAction::Replace::Fields<
241 &ComplexConstraintsRecord::ID_,
242 &ComplexConstraintsRecord::Value_
243 >;
244 const auto weightAgeFields = lco::InsertAction::Replace::Fields<
245 &ComplexConstraintsRecord::Weight_,
246 &ComplexConstraintsRecord::Age_
247 >;
248 adapted->Insert ({ 0, "first", 1, 2 }, idValueFields);
249 adapted->Insert ({ 0, "second", 1, 2 }, weightAgeFields);
250 adapted->Insert ({ 0, "first", 1, 3 }, idValueFields);
251 adapted->Insert ({ 0, "third", 1, 3 }, weightAgeFields);
252 adapted->Insert ({ 0, "first", 1, 3 }, weightAgeFields);
253
254 const auto& list = adapted->Select ();
255 QCOMPARE (list, (QList<ComplexConstraintsRecord> { {0, "second", 1, 2 }, { 0, "first", 1, 3 } }));
256 }
257}
258}
#define TOSTRING(n)
Definition common.h:52
constexpr auto FieldNames
Definition oral.h:156
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition oral.h:945
Typelist< Args... > Constraints
Definition oraltypes.h:139
ObjectInfo_ptr< T > AdaptPtr(const QSqlDatabase &db)
Definition oral.h:1665
auto PrepareRecords(QSqlDatabase db, int count=3)
Definition common.h:104
QSqlDatabase MakeDatabase(const QString &name=":memory:")
Definition common.h:73
Definition constants.h:15
#define ORAL_ADAPT_STRUCT(sname,...)
Definition oral.h:52
QDataStream & operator<<(QDataStream &out, const LC::Util::RegExp &rx)
Definition regexp.cpp:61
auto AsTuple() const
Definition oraltest.cpp:23
static constexpr auto ClassName
Definition oraltest.cpp:21
lco::PKey< int > ID_
Definition oraltest.cpp:18
static constexpr FieldsType< Ptrs... > Fields
Definition oraltypes.h:173
static constexpr struct LC::Util::oral::InsertAction::IgnoreTag Ignore