21#define MINIMAL_CONTAINER_TESTS
24#include "cutelee_paths.h"
26#include "test_macros.h"
28#include "coverageobject.h"
29#include <QtCore/QQueue>
30#include <QtCore/QStack>
31#include <QtCore/QVariant>
32#include <QtTest/QTest>
34class TestGenericContainers :
public CoverageObject
41 void testContainer_Builtins();
44TestGenericContainers::TestGenericContainers(
QObject *parent)
61 Q_FOREACH (
const int item, getItems<int>())
62 items.push_back(
QString::number(item));
69 Q_FOREACH (
const int item, getItems<int>())
70 items.push_back(item);
78 for (
auto i = 0; i < 3; ++i) {
91 for (
auto i = 9; i > 4; i -= 2) {
101 static void populateSequential(Container &container)
103 Q_FOREACH (
const typename Container::value_type item,
104 getItems<typename Container::value_type>())
105 container.push_back(item);
107 static void populateAssociative(Container &container)
110 Q_FOREACH (
const typename Container::mapped_type item,
111 getItems<typename Container::mapped_type>())
112 container[i++] = item;
117 static void populateSequential(
QSet<T> &container)
119 Q_FOREACH (
const T item, getItems<T>())
128 Q_FOREACH (
const T item, getItems<T>())
137 Q_FOREACH (
const T item, getItems<T>())
143 static void populateAssociative(std::map<QString, T> &container)
146 Q_FOREACH (
const T item, getItems<T>())
151template <
typename T>
QString getTemplate()
153 return QStringLiteral(
"{{ container.size }};{{ container.count }};{% for "
154 "item in container %}{{ item }},{% endfor %}");
157template <>
QString getTemplate<QDateTime>()
159 return QStringLiteral(
"{{ container.size }};{{ container.count }};{% for "
160 "item in container %}{{ item|date }},{% endfor %}");
163template <>
QString getTemplate<QObject *>()
165 return QStringLiteral(
166 "{{ container.size }};{{ container.count }};{% for item in container "
167 "%}{{ item.objectName }},{% endfor %}");
170template <
typename T>
QString getAssociativeTemplate()
172 return QStringLiteral(
"{{ container.size }};{{ container.count }};{% for "
173 "item in container.values %}{{ item }},{% endfor %}");
176template <>
QString getAssociativeTemplate<QDateTime>()
178 return QStringLiteral(
179 "{{ container.size }};{{ container.count }};{% for item in "
180 "container.values %}{{ item|date }},{% endfor %}");
183template <>
QString getAssociativeTemplate<QObject *>()
185 return QStringLiteral(
186 "{{ container.size }};{{ container.count }};{% for item in "
187 "container.values %}{{ item.objectName }},{% endfor %}");
192 return {QStringLiteral(
"3;3;"), QStringLiteral(
"9,"), QStringLiteral(
"7,"),
193 QStringLiteral(
"5,")};
198 return {QStringLiteral(
"3;3;"), QStringLiteral(
"Jan. 1, 1970,"),
199 QStringLiteral(
"Jan. 2, 1970,"), QStringLiteral(
"Jan. 3, 1970,")};
202template <
typename Container,
typename T =
typename Container::value_type>
204 static void clean(Container &) {}
207template <
typename Container,
typename T =
typename Container::mapped_type>
209 static void clean(Container &) {}
212template <
typename Container>
214 static void clean(Container &c) { qDeleteAll(c); }
217template <
typename Container>
219 static void clean(Container &c) { qDeleteAll(c); }
224 static void clean(std::map<T, QObject *> &c)
226 typename std::map<T, QObject *>::iterator it = c.begin();
227 const typename std::map<T, QObject *>::iterator end = c.end();
228 for (; it != end; ++it) {
235template <
typename Container>
void cleanupSequential(Container c)
237 CleanupSequentialContainer<Container>::clean(c);
240template <
typename Container>
void cleanupAssociative(Container c)
242 CleanupAssociativeContainer<Container>::clean(c);
245void testContainer(
const QString &stringTemplate,
247 const QStringList &expectedResults,
bool unordered)
254 c.
insert(QStringLiteral(
"container"), containerVariant);
256 auto t1 = engine.
newTemplate(stringTemplate, QStringLiteral(
"template1"));
258 auto result = t1->
render(&c);
262 QVERIFY(result.size() == expectedResults.
join(
QString()).size());
263 Q_FOREACH (
const QString &expectedResult, expectedResults)
264 QVERIFY(result.contains(expectedResult));
267 auto t2 = engine.
newTemplate(QStringLiteral(
"-{{ container.doesnotexist }}-"),
268 QStringLiteral(
"template2"));
270 auto result2 = t2->
render(&c);
272 QCOMPARE(result2, QStringLiteral(
"--"));
275template <
typename Container>
276void doTestSequentialContainer(
bool unordered = {})
279 ContainerPopulator<Container>::populateSequential(container);
281 testContainer(getTemplate<typename Container::value_type>(),
283 getResults<typename Container::value_type>(), unordered);
284 cleanupSequential(container);
287template <
typename Container>
288void doTestAssociativeContainer(
bool unordered = {})
291 ContainerPopulator<Container>::populateAssociative(container);
293 testContainer(getAssociativeTemplate<typename Container::mapped_type>(),
295 getResults<typename Container::mapped_type>(), unordered);
296 cleanupAssociative(container);
299template <
typename T>
void doTestNonHashableContainers()
301 doTestSequentialContainer<QVector<T>>();
302 doTestSequentialContainer<QList<T>>();
303 doTestSequentialContainer<QQueue<T>>();
304 doTestSequentialContainer<QStack<T>>();
305 doTestSequentialContainer<std::list<T>>();
306#ifndef MINIMAL_CONTAINER_TESTS
307 doTestAssociativeContainer<QMap<qint16, T>>();
308 doTestAssociativeContainer<QMap<qint64, T>>();
309 doTestAssociativeContainer<QMap<quint16, T>>();
310 doTestAssociativeContainer<QMap<quint32, T>>();
311 doTestAssociativeContainer<QMap<quint64, T>>();
312 doTestAssociativeContainer<QMap<QString, T>>();
313 doTestAssociativeContainer<std::map<qint16, T>>();
314 doTestAssociativeContainer<std::map<qint64, T>>();
315 doTestAssociativeContainer<std::map<quint16, T>>();
316 doTestAssociativeContainer<std::map<quint32, T>>();
317 doTestAssociativeContainer<std::map<quint64, T>>();
318 doTestAssociativeContainer<std::map<QString, T>>();
319 doTestAssociativeContainer<QHash<qint16, T>>(
true);
320 doTestAssociativeContainer<QHash<qint64, T>>(
true);
321 doTestAssociativeContainer<QHash<quint16, T>>(
true);
322 doTestAssociativeContainer<QHash<quint32, T>>(
true);
323 doTestAssociativeContainer<QHash<quint64, T>>(
true);
324 doTestAssociativeContainer<QHash<QString, T>>(
true);
328template <
typename T>
void doTestContainers()
330 doTestNonHashableContainers<T>();
331 doTestSequentialContainer<QSet<T>>(
true);
334void TestGenericContainers::testContainer_Builtins()
336 doTestContainers<qint32>();
337#ifndef MINIMAL_CONTAINER_TESTS
338 doTestContainers<qint16>();
339 doTestContainers<qint64>();
340 doTestContainers<quint16>();
341 doTestContainers<quint32>();
342 doTestContainers<quint64>();
343 doTestNonHashableContainers<float>();
344 doTestNonHashableContainers<double>();
345 doTestContainers<QString>();
346 doTestNonHashableContainers<QVariant>();
347 doTestNonHashableContainers<QDateTime>();
348 doTestContainers<QObject *>();
353#include "testgenericcontainers.moc"
The Context class holds the context to render a Template with.
void insert(const QString &name, QObject *object)
Cutelee::Engine is the main entry point for creating Cutelee Templates.
void setPluginPaths(const QStringList &dirs)
Template newTemplate(const QString &content, const QString &name) const
QString render(Context *c) const
QDateTime addDays(qint64 ndays) const const
void setMSecsSinceEpoch(qint64 msecs)
QHash< Key, T >::iterator insert(Key &&key, T &&value)
void push_back(QList< T >::parameter_type value)
void reserve(qsizetype size)
QMap< Key, T >::iterator insert(QMap< Key, T >::const_iterator pos, const Key &key, const T &value)
QObject * parent() const const
void setObjectName(QAnyStringView name)
QSet< T >::iterator insert(QSet< T >::const_iterator it, const T &value)
QString number(double n, char format, int precision)
QString join(QChar separator) const const
QVariant fromValue(T &&value)