23 #include "cutelee_paths.h"
26 #include "test_macros.h"
28 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
29 #include <QtCore/QLinkedList>
31 #include <QtCore/QMetaType>
32 #include <QtCore/QQueue>
33 #include <QtCore/QStack>
34 #include <QtCore/QVariant>
35 #include <QtCore/QVariantHash>
38 #include <QJsonObject>
39 #include <QJsonDocument>
40 #include <QtTest/QTest>
42 #include "coverageobject.h"
48 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(
ThreeArray)
52 Q_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)
54 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::deque)
64 void testGenericClassType();
65 void testSequentialContainer_Variant();
66 void testAssociativeContainer_Variant();
67 void testSequentialContainer_Type();
68 void testAssociativeContainer_Type();
69 void testSharedPointer();
70 void testThirdPartySharedPointer();
71 void testNestedContainers();
73 void testCustomQObjectDerived();
75 void propertyMacroTypes();
77 void testUnregistered();
78 void testPointerNonQObject();
80 void testGadgetMetaType();
90 Person(std::string _name,
int _age) : name(_name), age(_age)
96 bool operator==(
const Person &other)
const {
return uid == other.uid; }
106 Q_PROPERTY(
QString name MEMBER m_name)
112 int qHash(
const Person &p) {
return p.uid; }
114 Q_DECLARE_METATYPE(
Person)
118 if (property == QStringLiteral(
"name"))
119 return QString::fromStdString(
object.name);
120 else if (property == QStringLiteral(
"age"))
125 if (property == QStringLiteral(
"age"))
132 Q_PROPERTY(
QString name READ name CONSTANT)
133 Q_PROPERTY(
int age READ age CONSTANT)
136 : QObject(parent), m_name(name), m_age(age)
140 QString name()
const {
return m_name; }
141 int age()
const {
return m_age; }
148 void TestGenericTypes::initTestCase()
151 Cutelee::registerMetaType<Person>();
152 Cutelee::registerMetaType<PersonGadget>();
155 void TestGenericTypes::testGenericClassType()
163 "Person: \nName: {{p.name}}\nAge: {{p.age}}\nUnknown: {{p.unknown}}"),
164 QStringLiteral(
"template1"));
169 h.insert(QStringLiteral(
"p"), QVariant::fromValue(p));
171 QCOMPARE(t1->render(&c),
172 QStringLiteral(
"Person: \nName: Grant Lee\nAge: 2\nUnknown: "));
175 static QMap<int, Person> getPeople()
177 QMap<int, Person> people;
178 people.insert(23,
Person(
"Claire", 23));
179 people.insert(32,
Person(
"Grant", 32));
180 people.insert(50,
Person(
"Alan", 50));
184 template <
typename SequentialContainer>
187 auto people = getPeople();
188 auto it = people.constBegin();
189 const auto end = people.constEnd();
190 SequentialContainer container;
191 for (; it != end; ++it)
192 container.push_back(QVariant::fromValue(it.value()));
193 c.
insert(QStringLiteral(
"people"), QVariant::fromValue(container));
196 template <
typename AssociativeContainer>
199 auto people = getPeople();
200 auto it = people.constBegin();
201 const auto end = people.constEnd();
202 AssociativeContainer container;
203 for (; it != end; ++it)
204 container.insert(QString::number(it.key()),
205 QVariant::fromValue(it.value()));
206 c.
insert(QStringLiteral(
"people"), QVariant::fromValue(container));
212 insertAssociatedPeopleVariants<QMap<QString, QVariant>>(c);
218 insertAssociatedPeopleVariants<QHash<QString, QVariant>>(c);
221 template <
typename Container>
void testSequentialIteration(
Cutelee::Context &c)
230 "{% for person in people %}{{ person.name }},{% endfor %}"),
231 QStringLiteral(
"people_template"));
232 QCOMPARE(t1->
render(&c), QStringLiteral(
"Claire,Grant,Alan,"));
236 template <
typename Container>
void testSequentialIndexing(
Cutelee::Context &c)
245 "{{ people.0.name }},{{ people.1.name }},{{ people.2.name }},"),
246 QStringLiteral(
"people_template"));
247 QCOMPARE(t1->
render(&c), QStringLiteral(
"Claire,Grant,Alan,"));
254 testSequentialIteration<Container>(c);
259 testSequentialIndexing<Container>(c);
272 "{% for person in people %}{{ person.name }},{% endfor %}"),
273 QStringLiteral(
"people_template"));
274 auto result = t1->
render(&c);
275 QStringList output{QStringLiteral(
"Claire,"), QStringLiteral(
"Grant,"),
276 QStringLiteral(
"Alan,")};
277 Q_FOREACH (
const QString &s, output) {
278 QVERIFY(result.contains(s));
281 QCOMPARE(result.length(), output.join(
QString()).length());
287 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
291 testSequentialIteration<QLinkedList<T>>(c);
301 testSequentialIteration<std::list<T>>(c);
307 template <
typename Container>
void doTestSequentialContainer_Variant()
311 insertPeopleVariants<Container>(c);
317 template <
typename Container>
320 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
327 QStringLiteral(
"{% for person in people.values %}({{ person.name }}:{{ "
328 "person.age }}),{% endfor %}"),
329 QStringLiteral(
"people_template"));
331 auto result = t1->
render(&c);
333 QCOMPARE(result, QStringLiteral(
"(Claire:23),(Grant:32),(Alan:50),"));
335 QVERIFY(result.size() == 33);
336 QVERIFY(result.contains(QStringLiteral(
"(Claire:23),")));
337 QVERIFY(result.contains(QStringLiteral(
"(Grant:32),")));
338 QVERIFY(result.contains(QStringLiteral(
"(Alan:50),")));
344 template <
typename Container>
347 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
354 QStringLiteral(
"{% for item in people.items %}({{ item.1.name }}:{{ "
355 "item.1.age }}),{% endfor %}"),
356 QStringLiteral(
"people_template"));
357 auto result = t1->
render(&c);
359 QCOMPARE(result, QStringLiteral(
"(Claire:23),(Grant:32),(Alan:50),"));
361 QVERIFY(result.size() == 33);
362 QVERIFY(result.contains(QStringLiteral(
"(Claire:23),")));
363 QVERIFY(result.contains(QStringLiteral(
"(Grant:32),")));
364 QVERIFY(result.contains(QStringLiteral(
"(Alan:50),")));
370 template <
typename Container>
371 void doTestAssociativeContainer_Variant(
bool unordered = {})
379 insertPeopleVariants<Container>(c);
380 testAssociativeValues<Container>(c, unordered);
381 testAssociativeItems<Container>(c, unordered);
384 void TestGenericTypes::testSequentialContainer_Variant()
386 doTestSequentialContainer_Variant<QVariantList>();
387 doTestSequentialContainer_Variant<QVector<QVariant>>();
388 doTestSequentialContainer_Variant<QStack<QVariant>>();
389 doTestSequentialContainer_Variant<QQueue<QVariant>>();
390 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
391 doTestSequentialContainer_Variant<QLinkedList<QVariant>>();
395 void TestGenericTypes::testAssociativeContainer_Variant()
397 doTestAssociativeContainer_Variant<QVariantMap>();
398 doTestAssociativeContainer_Variant<QVariantHash>(
true);
401 template <
typename SequentialContainer>
void insertPeople(
Cutelee::Context &c)
403 auto people = getPeople();
404 auto it = people.constBegin();
405 const auto end = people.constEnd();
406 SequentialContainer container;
407 for (; it != end; ++it)
408 container.insert(container.end(), it.value());
409 c.
insert(QStringLiteral(
"people"), QVariant::fromValue(container));
414 auto people = getPeople();
415 auto it = people.constBegin();
416 const auto end = people.constEnd();
417 QSet<Person> container;
418 for (; it != end; ++it)
419 container.insert(it.value());
420 c.
insert(QStringLiteral(
"people"), QVariant::fromValue(container));
425 auto people = getPeople();
426 auto it = people.constBegin();
428 for (
auto i = 0; i < 3; ++i, ++it) {
429 Q_ASSERT(it != people.constEnd());
430 container[i] = it.value();
432 c.
insert(QStringLiteral(
"people"), QVariant::fromValue(container));
435 template <
typename AssociativeContainer>
438 auto people = getPeople();
439 auto it = people.constBegin();
440 const auto end = people.constEnd();
441 AssociativeContainer container;
442 for (; it != end; ++it)
443 container[QString::number(it.key())] = it.value();
444 c.
insert(QStringLiteral(
"people"), QVariant::fromValue(container));
447 template <
typename AssociativeContainer>
450 auto people = getPeople();
451 auto it = people.constBegin();
452 const auto end = people.constEnd();
453 AssociativeContainer container;
454 for (; it != end; ++it)
455 container[it.key()] = it.value();
456 c.
insert(QStringLiteral(
"people"), QVariant::fromValue(container));
459 template <
typename Container>
void doTestSequentialContainer_Type()
463 insertPeople<Container>(c);
469 template <
typename Container>
470 void doTestAssociativeContainer_Type(
bool unordered = {})
478 insertAssociatedPeople<Container>(c);
479 testAssociativeValues<Container>(c, unordered);
480 testAssociativeItems<Container>(c, unordered);
483 template <
typename Container>
484 void doTestAssociativeContainer_Type_Number(
bool unordered = {})
492 insertAssociatedPeople_Number<Container>(c);
493 testAssociativeValues<Container>(c, unordered);
494 testAssociativeItems<Container>(c, unordered);
498 = engine.
newTemplate(QStringLiteral(
"{{ people.23.name }}"),
499 QStringLiteral(
"claire_template"));
500 auto result = t1->
render(&c);
501 QCOMPARE(result, QStringLiteral(
"Claire"));
505 void TestGenericTypes::testSequentialContainer_Type()
507 doTestSequentialContainer_Type<QList<Person>>();
508 doTestSequentialContainer_Type<QVector<Person>>();
509 doTestSequentialContainer_Type<QStack<Person>>();
510 doTestSequentialContainer_Type<QQueue<Person>>();
511 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
512 doTestSequentialContainer_Type<QLinkedList<Person>>();
514 doTestSequentialContainer_Type<QSet<Person>>();
515 doTestSequentialContainer_Type<std::deque<Person>>();
516 doTestSequentialContainer_Type<std::vector<Person>>();
517 doTestSequentialContainer_Type<std::list<Person>>();
518 doTestSequentialContainer_Type<ThreeArray<Person>>();
521 void TestGenericTypes::testAssociativeContainer_Type()
523 doTestAssociativeContainer_Type<QMap<QString, Person>>();
524 doTestAssociativeContainer_Type_Number<QMap<qint16, Person>>();
525 doTestAssociativeContainer_Type_Number<QMap<qint32, Person>>();
526 doTestAssociativeContainer_Type_Number<QMap<qint64, Person>>();
527 doTestAssociativeContainer_Type_Number<QMap<quint16, Person>>();
528 doTestAssociativeContainer_Type_Number<QMap<quint32, Person>>();
529 doTestAssociativeContainer_Type_Number<QMap<quint64, Person>>();
530 doTestAssociativeContainer_Type<QHash<QString, Person>>(
true);
531 doTestAssociativeContainer_Type_Number<QHash<qint16, Person>>(
true);
532 doTestAssociativeContainer_Type_Number<QHash<qint32, Person>>(
true);
533 doTestAssociativeContainer_Type_Number<QHash<qint64, Person>>(
true);
534 doTestAssociativeContainer_Type_Number<QHash<quint16, Person>>(
true);
535 doTestAssociativeContainer_Type_Number<QHash<quint32, Person>>(
true);
536 doTestAssociativeContainer_Type_Number<QHash<quint64, Person>>(
true);
538 doTestAssociativeContainer_Type<std::map<QString, Person>>();
539 doTestAssociativeContainer_Type_Number<std::map<qint16, Person>>();
540 doTestAssociativeContainer_Type_Number<std::map<qint32, Person>>();
541 doTestAssociativeContainer_Type_Number<std::map<qint64, Person>>();
542 doTestAssociativeContainer_Type_Number<std::map<quint16, Person>>();
543 doTestAssociativeContainer_Type_Number<std::map<quint32, Person>>();
544 doTestAssociativeContainer_Type_Number<std::map<quint64, Person>>();
546 doTestAssociativeContainer_Type<QtUnorderedMap<QString, Person>>(
true);
547 doTestAssociativeContainer_Type_Number<QtUnorderedMap<qint16, Person>>(
true);
548 doTestAssociativeContainer_Type_Number<QtUnorderedMap<qint32, Person>>(
true);
549 doTestAssociativeContainer_Type_Number<QtUnorderedMap<qint64, Person>>(
true);
550 doTestAssociativeContainer_Type_Number<QtUnorderedMap<quint16, Person>>(
true);
551 doTestAssociativeContainer_Type_Number<QtUnorderedMap<quint32, Person>>(
true);
552 doTestAssociativeContainer_Type_Number<QtUnorderedMap<quint64, Person>>(
true);
555 void TestGenericTypes::testSharedPointer()
561 auto t1 = engine.
newTemplate(QStringLiteral(
"{{ p.name }} {{ p.age }}"),
562 QStringLiteral(
"template1"));
566 std::shared_ptr<PersonObject> p(
568 h.insert(QStringLiteral(
"p"), QVariant::fromValue(p));
570 QCOMPARE(t1->
render(&c), QStringLiteral(
"Grant Lee 2"));
573 void TestGenericTypes::testThirdPartySharedPointer()
579 auto t1 = engine.
newTemplate(QStringLiteral(
"{{ p.name }} {{ p.age }}"),
580 QStringLiteral(
"template1"));
584 std::shared_ptr<PersonObject> p(
586 h.insert(QStringLiteral(
"p"), QVariant::fromValue(p));
588 QCOMPARE(t1->
render(&c), QStringLiteral(
"Grant Lee 2"));
591 typedef QList<QVector<qint16>> ListVectorInt;
592 typedef QMap<int, QList<QVector<qint16>>> MapListVectorInt;
593 typedef QStack<QMap<int, QList<QVector<qint16>>>> StackMapListVectorInt;
595 static QVector<qint16> getNumbers()
598 QVector<qint16> nums;
604 static ListVectorInt getNumberLists()
607 for (
auto i = 0; i < 2; ++i) {
608 list.append(getNumbers());
613 static MapListVectorInt getNumberListMap()
615 MapListVectorInt map;
616 for (
auto i = 0; i < 2; ++i) {
617 map.insert(i, getNumberLists());
622 static StackMapListVectorInt getMapStack()
624 StackMapListVectorInt stack;
625 for (
auto i = 0; i < 2; ++i) {
626 stack.push(getNumberListMap());
631 void TestGenericTypes::testNestedContainers()
633 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
639 c.
insert(QStringLiteral(
"stack"), QVariant::fromValue(getMapStack()));
641 #if defined(Q_CC_MSVC)
644 #define STRING_LITERAL QLatin1String
646 #define STRING_LITERAL QStringLiteral
649 STRING_LITERAL(
"{% for map in stack %}"
650 "(M {% for key, list in map.items %}"
651 "({{ key }} : (L {% for vector in list %}"
652 "(V {% for number in vector %}"
658 QStringLiteral(
"template1"));
660 #undef STRING_LITERAL
662 auto result = t1->
render(&c);
664 auto expectedResult = QStringLiteral(
665 "(M (0 : (L (V 1,2,),(V 3,4,),),(1 : (L (V 5,6,),(V 7,8,),),),(M (0 : (L "
666 "(V 9,10,),(V 11,12,),),(1 : (L (V 13,14,),(V 15,16,),),),");
668 QCOMPARE(result, expectedResult);
676 explicit CustomObject(QObject *parent = {}) : QObject(parent) {}
687 m_custom->setProperty(
"nestedProp", QStringLiteral(
"nestedValue"));
696 void TestGenericTypes::testCustomQObjectDerived()
703 customObject->setProperty(
"someProp", QStringLiteral(
"propValue"));
706 c.
insert(QStringLiteral(
"custom"), QVariant::fromValue(customObject));
709 auto t1 = engine.
newTemplate(QStringLiteral(
"{{ custom.someProp }}"),
710 QStringLiteral(
"template1"));
712 auto result = t1->
render(&c);
713 auto expectedResult = QStringLiteral(
"propValue");
715 QCOMPARE(result, expectedResult);
720 c.
insert(QStringLiteral(
"other"), other);
724 = engine.
newTemplate(QStringLiteral(
"{{ other.custom.nestedProp }}"),
725 QStringLiteral(
"template1"));
727 auto result = t1->
render(&c);
728 auto expectedResult = QStringLiteral(
"nestedValue");
730 QCOMPARE(result, expectedResult);
746 if (property == QStringLiteral(
"property"))
750 static QVariantList dummy(
const UnregisteredType &) {
return QVariantList{42}; }
754 void TestGenericTypes::testUnregistered()
759 auto v = QVariant::fromValue(unregType);
761 auto result = Cutelee::MetaType::lookup(v, QStringLiteral(
"property"));
762 QVERIFY(!result.isValid());
764 QVERIFY(!v.canConvert<QVariantList>());
767 Cutelee::registerMetaType<RegisteredNotListType>();
771 auto v = QVariant::fromValue(nonListType);
772 auto result = Cutelee::MetaType::lookup(v, QStringLiteral(
"property"));
773 QVERIFY(result.isValid());
774 QVERIFY(!v.canConvert<QVariantList>());
778 QMetaType::registerConverter<UnregisteredType, QVariantList>(&dummy);
780 auto v = QVariant::fromValue(unregType);
781 auto result = Cutelee::MetaType::lookup(v, QStringLiteral(
"property"));
782 QVERIFY(!result.isValid());
790 Q_DECLARE_METATYPE(
Person *)
793 if (property == QStringLiteral(
"name"))
794 return QString::fromStdString(object->name);
795 else if (property == QStringLiteral(
"age"))
799 void TestGenericTypes::testPointerNonQObject()
801 auto p =
new Person(
"Adele", 21);
802 auto v = QVariant::fromValue(p);
804 Cutelee::registerMetaType<Person *>();
806 auto result = Cutelee::MetaType::lookup(v, QStringLiteral(
"name"));
808 QCOMPARE(result.toString(), QStringLiteral(
"Adele"));
816 Q_PROPERTY(
int fortyTwo READ fortyTwo)
818 int fortyTwo() {
return 42; }
821 void TestGenericTypes::testQGadget()
824 auto v = QVariant::fromValue(g);
826 auto result = Cutelee::MetaType::lookup(v, QStringLiteral(
"fortyTwo"));
828 QCOMPARE(result.value<
int>(), 42);
831 void TestGenericTypes::testGadgetMetaType()
837 QStringLiteral(
"Person: \nName: {{p.name}}\nAge: {{p.age}}"),
838 QStringLiteral(
"template1"));
841 p.m_name = QStringLiteral(
"Some Name");
843 c.
insert(QStringLiteral(
"p"), QVariant::fromValue(p));
845 QStringLiteral(
"Person: \nName: Some Name\nAge: 42"));
851 Q_PROPERTY(QList<int> numberList READ numberList CONSTANT)
852 Q_PROPERTY(QList<CustomGadget> gadgetList READ gadgetList CONSTANT)
853 Q_PROPERTY(QVector<PersonObject *> personList READ personList CONSTANT)
855 QVector<QSharedPointer<PersonObject>> personPtrList READ personPtrList CONSTANT)
860 m_numberList.push_back(42);
861 m_numberList.push_back(7);
864 m_personList.push_back(
new PersonObject{QStringLiteral(
"Joe"), 20});
865 m_personList.push_back(
new PersonObject{QStringLiteral(
"Mike"), 22});
866 m_personPtrList.push_back(
867 QSharedPointer<PersonObject>(
new PersonObject{QStringLiteral(
"Niall"), 23}));
868 m_personPtrList.push_back(
869 QSharedPointer<PersonObject>(
new PersonObject{QStringLiteral(
"Dave"), 24}));
872 QList<int> numberList() {
return m_numberList; }
873 QList<CustomGadget> gadgetList() {
return m_gadgetList; }
874 QVector<PersonObject *> personList() {
return m_personList; }
875 QVector<QSharedPointer<PersonObject>> personPtrList()
877 return m_personPtrList;
881 QList<int> m_numberList;
882 QList<CustomGadget> m_gadgetList;
883 QVector<PersonObject *> m_personList;
884 QVector<QSharedPointer<PersonObject>> m_personPtrList;
887 void TestGenericTypes::propertyMacroTypes()
891 qRegisterMetaType<QList<CustomGadget>>();
898 c.
insert(QStringLiteral(
"obj"), objectWithProperties);
902 QStringLiteral(
"{{ obj.numberList.0 }}--{{ obj.numberList.1 }}"),
903 QStringLiteral(
"template1"));
905 auto result = t1->
render(&c);
906 auto expectedResult = QStringLiteral(
"42--7");
908 QCOMPARE(result, expectedResult);
914 "{{ obj.gadgetList.0.fortyTwo }}--{{ obj.gadgetList.1.fortyTwo }}"),
915 QStringLiteral(
"template1"));
917 auto result = t1->
render(&c);
918 auto expectedResult = QStringLiteral(
"42--42");
920 QCOMPARE(result, expectedResult);
926 "{{ obj.personList.0.name }}({{ obj.personList.0.age }})"
927 "--{{ obj.personList.1.name }}({{ obj.personList.1.age }})"),
928 QStringLiteral(
"template1"));
930 auto result = t1->
render(&c);
931 auto expectedResult = QStringLiteral(
"Joe(20)--Mike(22)");
933 QCOMPARE(result, expectedResult);
939 "{{ obj.personPtrList.0.name }}({{ obj.personPtrList.0.age }})"
940 "--{{ obj.personPtrList.1.name }}({{ obj.personPtrList.1.age }})"),
941 QStringLiteral(
"template1"));
943 auto result = t1->
render(&c);
944 auto expectedResult = QStringLiteral(
"Niall(23)--Dave(24)");
946 QCOMPARE(result, expectedResult);
950 void TestGenericTypes::testJsonTypes()
958 arr.push_back(QJsonObject({
959 {QStringLiteral(
"name"), QStringLiteral(
"Joe")},
960 {QStringLiteral(
"age"), 20}
963 {QStringLiteral(
"name"), QStringLiteral(
"Mike")},
964 {QStringLiteral(
"age"), 22}
968 c.
insert(QStringLiteral(
"arr"), arr);
969 c.
insert(QStringLiteral(
"obj"), obj);
973 QStringLiteral(
"{{ arr.count }}"),
974 QStringLiteral(
"template"));
976 auto result = t->
render(&c);
977 auto expectedResult = QStringLiteral(
"2");
979 QCOMPARE(result, expectedResult);
984 QStringLiteral(
"{{ arr.1.name }}({{ arr.1.age }})"),
985 QStringLiteral(
"template"));
987 auto result = t->
render(&c);
988 auto expectedResult = QStringLiteral(
"Mike(22)");
990 QCOMPARE(result, expectedResult);
995 QStringLiteral(
"{% for person in arr %}{{ person.name }}({{ person.age }})\n{% endfor %}"),
996 QStringLiteral(
"template"));
998 auto result = t->
render(&c);
999 auto expectedResult = QStringLiteral(
"Joe(20)\nMike(22)\n");
1001 QCOMPARE(result, expectedResult);
1006 QStringLiteral(
"{% for name,age in arr %}{{ name }}({{ age }})\n{% endfor %}"),
1007 QStringLiteral(
"template"));
1009 auto result = t->
render(&c);
1010 auto expectedResult = QStringLiteral(
"Joe(20)\nMike(22)\n");
1012 QCOMPARE(result, expectedResult);
1017 QStringLiteral(
"{{ obj.count }}"),
1018 QStringLiteral(
"template"));
1020 auto result = t->
render(&c);
1021 auto expectedResult = QStringLiteral(
"2");
1023 QCOMPARE(result, expectedResult);
1028 QStringLiteral(
"{{ obj.name }}({{ obj.age }})"),
1029 QStringLiteral(
"template"));
1031 auto result = t->
render(&c);
1032 auto expectedResult = QStringLiteral(
"Mike(22)");
1034 QCOMPARE(result, expectedResult);
1039 QStringLiteral(
"{% for key in obj.keys %}{{ key }}\n{% endfor %}"),
1040 QStringLiteral(
"template"));
1042 auto result = t->
render(&c);
1044 QVERIFY(result == QStringLiteral(
"name\nage\n") || result == QStringLiteral(
"age\nname\n"));
1049 QStringLiteral(
"{% for val in obj.values %}{{ val }}\n{% endfor %}"),
1050 QStringLiteral(
"template"));
1052 auto result = t->
render(&c);
1054 QVERIFY(result == QStringLiteral(
"Mike\n22\n") || result == QStringLiteral(
"22\nMike\n"));
1059 QStringLiteral(
"{% for item in obj.items %}{{ item.0 }}:{{ item.1 }}\n{% endfor %}"),
1060 QStringLiteral(
"template"));
1062 auto result = t->
render(&c);
1064 QVERIFY(result == QStringLiteral(
"age:22\nname:Mike\n") || result == QStringLiteral(
"name:Mike\nage:22\n"));
1067 QJsonDocument arrDoc(arr);
1068 c.
insert(QStringLiteral(
"arrDoc"), arrDoc);
1072 QStringLiteral(
"{{ arrDoc.count }}"),
1073 QStringLiteral(
"template"));
1075 auto result = t->
render(&c);
1076 auto expectedResult = QStringLiteral(
"2");
1078 QCOMPARE(result, expectedResult);
1083 QStringLiteral(
"{{ arrDoc.1.name }}({{ arrDoc.1.age }})"),
1084 QStringLiteral(
"template"));
1086 auto result = t->
render(&c);
1087 auto expectedResult = QStringLiteral(
"Mike(22)");
1089 QCOMPARE(result, expectedResult);
1094 QStringLiteral(
"{% for person in arrDoc %}{{ person.name }}({{ person.age }})\n{% endfor %}"),
1095 QStringLiteral(
"template"));
1097 auto result = t->
render(&c);
1098 auto expectedResult = QStringLiteral(
"Joe(20)\nMike(22)\n");
1100 QCOMPARE(result, expectedResult);
1105 QStringLiteral(
"{% for name,age in arrDoc %}{{ name }}({{ age }})\n{% endfor %}"),
1106 QStringLiteral(
"template"));
1108 auto result = t->
render(&c);
1109 auto expectedResult = QStringLiteral(
"Joe(20)\nMike(22)\n");
1111 QCOMPARE(result, expectedResult);
1114 QJsonDocument objDoc(obj);
1115 c.
insert(QStringLiteral(
"objDoc"), objDoc);
1119 QStringLiteral(
"{{ objDoc.count }}"),
1120 QStringLiteral(
"template"));
1122 auto result = t->
render(&c);
1123 auto expectedResult = QStringLiteral(
"2");
1125 QCOMPARE(result, expectedResult);
1130 QStringLiteral(
"{{ objDoc.name }}({{ objDoc.age }})"),
1131 QStringLiteral(
"template"));
1133 auto result = t->
render(&c);
1134 auto expectedResult = QStringLiteral(
"Mike(22)");
1136 QCOMPARE(result, expectedResult);
1141 QStringLiteral(
"{% for key in objDoc.keys %}{{ key }}\n{% endfor %}"),
1142 QStringLiteral(
"template"));
1144 auto result = t->
render(&c);
1146 QVERIFY(result == QStringLiteral(
"name\nage\n") || result == QStringLiteral(
"age\nname\n"));
1151 QStringLiteral(
"{% for val in objDoc.values %}{{ val }}\n{% endfor %}"),
1152 QStringLiteral(
"template"));
1154 auto result = t->
render(&c);
1156 QVERIFY(result == QStringLiteral(
"Mike\n22\n") || result == QStringLiteral(
"22\nMike\n"));
1161 QStringLiteral(
"{% for item in objDoc.items %}{{ item.0 }}:{{ item.1 }}\n{% endfor %}"),
1162 QStringLiteral(
"template"));
1164 auto result = t->
render(&c);
1166 QVERIFY(result == QStringLiteral(
"age:22\nname:Mike\n") || result == QStringLiteral(
"name:Mike\nage:22\n"));
1169 QJsonObject emptyObj;
1170 c.
insert(QStringLiteral(
"emptyObj"), emptyObj);
1174 QStringLiteral(
"{{ emptyObj.name }}"),
1175 QStringLiteral(
"template"));
1177 auto result = t->
render(&c);
1178 auto expectedResult = QStringLiteral(
"");
1180 QCOMPARE(result, expectedResult);
1183 QJsonArray emptyArr;
1184 c.
insert(QStringLiteral(
"emptyArr"), emptyArr);
1188 QStringLiteral(
"{{ emptyArr.1 }}"),
1189 QStringLiteral(
"template"));
1191 auto result = t->
render(&c);
1192 auto expectedResult = QStringLiteral(
"");
1194 QCOMPARE(result, expectedResult);
1197 QJsonDocument emptyDoc;
1198 c.
insert(QStringLiteral(
"emptyDoc"), emptyDoc);
1202 QStringLiteral(
"{{ emptyDoc }}"),
1203 QStringLiteral(
"template"));
1205 auto result = t->
render(&c);
1206 auto expectedResult = QStringLiteral(
"");
1208 QCOMPARE(result, expectedResult);
1211 c.
insert(QStringLiteral(
"valBool"), QJsonValue(
true));
1215 QStringLiteral(
"{{ valBool }}"),
1216 QStringLiteral(
"template"));
1218 auto result = t->
render(&c);
1219 auto expectedResult = QStringLiteral(
"true");
1221 QCOMPARE(result, expectedResult);
1224 c.
insert(QStringLiteral(
"valDouble"), QJsonValue(15));
1228 QStringLiteral(
"{{ valDouble }}"),
1229 QStringLiteral(
"template"));
1231 auto result = t->
render(&c);
1232 auto expectedResult = QStringLiteral(
"15");
1234 QCOMPARE(result, expectedResult);
1237 c.
insert(QStringLiteral(
"valString"), QJsonValue(QStringLiteral(
"Sapere aude")));
1241 QStringLiteral(
"{{ valString }}"),
1242 QStringLiteral(
"template"));
1244 auto result = t->
render(&c);
1245 auto expectedResult = QStringLiteral(
"Sapere aude");
1247 QCOMPARE(result, expectedResult);
1250 c.
insert(QStringLiteral(
"valArray"), QJsonValue(arr));
1254 QStringLiteral(
"{% for person in valArray %}{{ person.name }}({{ person.age }})\n{% endfor %}"),
1255 QStringLiteral(
"template"));
1257 auto result = t->
render(&c);
1258 auto expectedResult = QStringLiteral(
"Joe(20)\nMike(22)\n");
1260 QCOMPARE(result, expectedResult);
1263 c.
insert(QStringLiteral(
"valObj"), QJsonValue(obj));
1267 QStringLiteral(
"{{ valObj.name }}({{ valObj.age }})"),
1268 QStringLiteral(
"template"));
1270 auto result = t->
render(&c);
1271 auto expectedResult = QStringLiteral(
"Mike(22)");
1273 QCOMPARE(result, expectedResult);
1276 c.
insert(QStringLiteral(
"valNull"), QJsonValue());
1280 QStringLiteral(
"{{ valNull }}"),
1281 QStringLiteral(
"template"));
1283 auto result = t->
render(&c);
1284 auto expectedResult = QStringLiteral(
"");
1286 QCOMPARE(result, expectedResult);
1291 #include "testgenerictypes.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
The Template class is a tree of nodes which may be rendered.
QString render(Context *c) const