21 #ifndef BUILTINSTEST_H
22 #define BUILTINSTEST_H
24 #include <QtCore/QDebug>
25 #include <QtCore/QFileInfo>
26 #include <QtTest/QTest>
28 #include "cachingloaderdecorator.h"
30 #include "coverageobject.h"
32 #include "filterexpression.h"
33 #include "cutelee_paths.h"
36 #include <metaenumvariable_p.h>
38 typedef QHash<QString, QVariant> Dict;
50 Q_PROPERTY(
QString method READ method CONSTANT)
51 Q_PROPERTY(Animals animals READ animals CONSTANT)
53 enum Animals { Lions, Tigers, Bears };
56 OtherClass(QObject *parent = {}) : QObject(parent) {}
57 OtherClass(Animals animals, QObject *parent =
nullptr) : QObject(parent), m_animals(animals) {}
59 Animals animals()
const {
return m_animals; }
61 QString method()
const {
return QStringLiteral(
"OtherClass::method"); }
64 Animals m_animals = Tigers;
73 Q_PROPERTY(
QString method READ method CONSTANT)
74 Q_PROPERTY(
QVariant otherClass READ otherClass CONSTANT)
77 enum FirstEnum { Employee, Employer, Manager };
80 enum SecondEnum { Voter = 2, Consumer = 4, Citizen = 8 };
84 : QObject(parent), m_other(
new OtherClass(
this))
88 QString method()
const {
return QStringLiteral(
"SomeClass::method"); }
90 QVariant otherClass()
const {
return QVariant::fromValue(m_other); }
104 Q_PROPERTY(PersonName personName READ personName)
106 enum PersonName { Mike = 0, Natalie, Oliver };
112 PersonName personName()
const {
return m_personName; }
114 PersonName m_personName = Oliver;
125 std::shared_ptr<OutputStream>
clone(QTextStream *stream)
const override
140 std::shared_ptr<OutputStream>
clone(QTextStream *stream)
const override
142 return std::shared_ptr<JSOutputStream>(
new JSOutputStream{stream});
147 QList<std::pair<QString, QString>> jsEscapes;
148 jsEscapes << std::pair<QString, QString>(QChar::fromLatin1(
'\\'),
149 QStringLiteral(
"\\u005C"))
150 << std::pair<QString, QString>(QChar::fromLatin1(
'\''),
151 QStringLiteral(
"\\u0027"))
152 << std::pair<QString, QString>(QChar::fromLatin1(
'\"'),
153 QStringLiteral(
"\\u0022"))
154 << std::pair<QString, QString>(QChar::fromLatin1(
'>'),
155 QStringLiteral(
"\\u003E"))
156 << std::pair<QString, QString>(QChar::fromLatin1(
'<'),
157 QStringLiteral(
"\\u003C"))
158 << std::pair<QString, QString>(QChar::fromLatin1(
'&'),
159 QStringLiteral(
"\\u0026"))
160 << std::pair<QString, QString>(QChar::fromLatin1(
'='),
161 QStringLiteral(
"\\u003D"))
162 << std::pair<QString, QString>(QChar::fromLatin1(
'-'),
163 QStringLiteral(
"\\u002D"))
164 << std::pair<QString, QString>(QChar::fromLatin1(
';'),
165 QStringLiteral(
"\\u003B"))
166 << std::pair<QString, QString>(QChar(0x2028),
167 QStringLiteral(
"\\u2028"))
168 << std::pair<QString, QString>(QChar(0x2029),
169 QStringLiteral(
"\\u2029"));
171 for (
auto i = 0; i < 32; ++i) {
172 jsEscapes << std::pair<QString, QString>(
174 QStringLiteral(
"\\u00")
175 + QStringLiteral(
"%1").arg(i, 2, 16, QLatin1Char(
'0')).toUpper());
178 auto retString = input;
179 for (
const std::pair<QString, QString> &escape : jsEscapes) {
180 retString = retString.replace(escape.first, escape.second);
195 void testTruthiness_data();
196 void testTruthiness();
198 void testRenderAfterError();
200 void testBasicSyntax_data();
201 void testBasicSyntax() { doTest(); }
203 void testEnums_data();
204 void testEnums() { doTest(); }
206 void testListIndex_data();
207 void testListIndex() { doTest(); }
209 void testFilterSyntax_data();
210 void testFilterSyntax() { doTest(); }
212 void testCommentSyntax_data();
213 void testCommentSyntax() { doTest(); }
215 void testMultiline_data();
216 void testMultiline() { doTest(); }
218 void testEscaping_data();
219 void testEscaping() { doTest(); }
221 void testTypeAccessors_data();
222 void testTypeAccessors() { doTest(); }
223 void testTypeAccessorsUnordered_data();
224 void testTypeAccessorsUnordered();
226 void testMultipleStates();
227 void testAlternativeEscaping();
229 void testTemplatePathSafety_data();
230 void testTemplatePathSafety();
232 void testMediaPathSafety_data();
233 void testMediaPathSafety();
235 void testDynamicProperties_data();
236 void testDynamicProperties() { doTest(); }
238 void testGarbageInput_data();
239 void testGarbageInput();
241 void testInsignificantWhitespace_data();
242 void testInsignificantWhitespace();
244 void cleanupTestCase();
249 std::shared_ptr<InMemoryTemplateLoader> m_loader;
256 void TestBuiltinSyntax::testObjects()
260 loader->setTemplateDirs(
261 {QStringLiteral(
"/path/one"), QStringLiteral(
"/path/two")});
287 c1.setMutating(
true);
288 QVERIFY(c1.isMutating());
296 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
297 QMetaType::construct(qMetaTypeId<MetaEnumVariable>(), 0, 0);
299 QMetaType(qMetaTypeId<MetaEnumVariable>()).construct(0, 0);
303 void TestBuiltinSyntax::testTruthiness_data()
305 QTest::addColumn<QVariant>(
"input");
306 QTest::addColumn<bool>(
"expected");
308 QTest::newRow(
"truthtest-01") <<
QVariant() <<
false;
309 QTest::newRow(
"truthtest-02") <<
QVariant(
false) <<
false;
310 QTest::newRow(
"truthtest-03") <<
QVariant(
true) <<
true;
312 QTest::newRow(
"truthtest-04") <<
QVariant(0) <<
false;
313 QTest::newRow(
"truthtest-05") <<
QVariant(1) <<
true;
316 auto falseV = QVariant::fromValue<int>(0);
317 QTest::newRow(
"truthtest-06") << falseV <<
false;
318 auto trueV = QVariant::fromValue<int>(1);
319 QTest::newRow(
"truthtest-07") << trueV <<
true;
322 auto falseV = QVariant::fromValue<uint>(0);
323 QTest::newRow(
"truthtest-08") << falseV <<
false;
324 auto trueV = QVariant::fromValue<uint>(1);
325 QTest::newRow(
"truthtest-09") << trueV <<
true;
328 auto falseV = QVariant::fromValue<qlonglong>(0);
329 QTest::newRow(
"truthtest-10") << falseV <<
false;
330 auto trueV = QVariant::fromValue<qlonglong>(1);
331 QTest::newRow(
"truthtest-11") << trueV <<
true;
334 auto falseV = QVariant::fromValue<qulonglong>(0);
335 QTest::newRow(
"truthtest-12") << falseV <<
false;
336 auto trueV = QVariant::fromValue<qulonglong>(1);
337 QTest::newRow(
"truthtest-13") << trueV <<
true;
340 auto falseV = QVariant::fromValue<double>(0);
341 QTest::newRow(
"truthtest-14") << falseV <<
false;
342 auto trueV = QVariant::fromValue<double>(1);
343 QTest::newRow(
"truthtest-15") << trueV <<
true;
346 auto falseV = QVariant::fromValue<float>(0);
347 QTest::newRow(
"truthtest-16") << falseV <<
false;
348 auto trueV = QVariant::fromValue<float>(1);
349 QTest::newRow(
"truthtest-17") << trueV <<
true;
352 auto falseV = QVariant::fromValue<char>(0);
353 QTest::newRow(
"truthtest-18") << falseV <<
false;
354 auto trueV = QVariant::fromValue<char>(1);
355 QTest::newRow(
"truthtest-19") << trueV <<
true;
358 QTest::newRow(
"truthtest-20") << QVariant::fromValue(
QString()) <<
false;
359 QTest::newRow(
"truthtest-21")
360 << QVariant::fromValue(QStringLiteral(
"")) <<
false;
361 QTest::newRow(
"truthtest-22")
362 << QVariant::fromValue(QStringLiteral(
"false")) <<
true;
363 QTest::newRow(
"truthtest-23")
364 << QVariant::fromValue(QStringLiteral(
"true")) <<
true;
365 QTest::newRow(
"truthtest-24")
366 << QVariant::fromValue(QStringLiteral(
"anystring")) <<
true;
370 QTest::newRow(
"truthtest-25") << QVariant::fromValue(l) <<
false;
372 QTest::newRow(
"truthtest-26") << QVariant::fromValue(l) <<
true;
376 QTest::newRow(
"truthtest-27") << QVariant::fromValue(h) <<
false;
377 h.insert(QStringLiteral(
"value"), 1);
378 QTest::newRow(
"truthtest-28") << QVariant::fromValue(h) <<
true;
382 QTest::newRow(
"truthtest-29")
383 << QVariant::fromValue<QObject *>(
nullptr) <<
false;
384 auto plainO =
new QObject(
this);
385 QTest::newRow(
"truthtest-30") << QVariant::fromValue(plainO) <<
true;
386 auto trueO =
new QObject(
this);
387 trueO->setProperty(
"__true__",
true);
388 QTest::newRow(
"truthtest-31") << QVariant::fromValue(trueO) <<
true;
389 auto falseO =
new QObject(
this);
390 falseO->setProperty(
"__true__",
false);
391 QTest::newRow(
"truthtest-32") << QVariant::fromValue(falseO) <<
false;
395 void TestBuiltinSyntax::testTruthiness()
398 QFETCH(
bool, expected);
403 void TestBuiltinSyntax::testRenderAfterError()
410 loader->setTemplate(QStringLiteral(
"template1"),
411 QStringLiteral(
"This template has an error {{ va>r }}"));
412 loader->setTemplate(QStringLiteral(
"template2"), QStringLiteral(
"Ok"));
413 loader->setTemplate(QStringLiteral(
"main"),
414 QStringLiteral(
"{% include template_var %}"));
421 t = engine.
loadByName(QStringLiteral(
"main"));
423 c.
insert(QStringLiteral(
"template_var"), QLatin1String(
"template1"));
424 auto output = t->
render(&c);
426 QCOMPARE(t->
error(), TagSyntaxError);
428 c.
insert(QStringLiteral(
"template_var"), QLatin1String(
"template2"));
429 QCOMPARE(t->
render(&c), QLatin1String(
"Ok"));
430 QCOMPARE(t->
error(), NoError);
433 void TestBuiltinSyntax::initTestCase()
435 m_engine = getEngine();
438 m_engine->addTemplateLoader(m_loader);
439 QVERIFY(m_engine->templateLoaders().contains(m_loader));
442 Engine *TestBuiltinSyntax::getEngine()
444 auto engine =
new Engine(
this);
449 void TestBuiltinSyntax::cleanupTestCase() {
delete m_engine; }
451 void TestBuiltinSyntax::doTest()
458 auto t = m_engine->newTemplate(input, QLatin1String(QTest::currentDataTag()));
460 if (t->
error() != NoError) {
461 if (t->
error() != error)
463 QCOMPARE(t->
error(), error);
469 auto result = t->
render(&context);
470 if (t->
error() != NoError) {
471 if (t->
error() != error)
473 QCOMPARE(t->
error(), error);
477 QCOMPARE(t->
error(), NoError);
480 QCOMPARE(NoError, error);
482 QCOMPARE(result, output);
485 void TestBuiltinSyntax::testBasicSyntax_data()
487 QTest::addColumn<QString>(
"input");
488 QTest::addColumn<Dict>(
"dict");
489 QTest::addColumn<QString>(
"output");
490 QTest::addColumn<Cutelee::Error>(
"error");
494 QTest::newRow(
"basic-syntax00") <<
QString() << dict <<
QString() << NoError;
497 QTest::newRow(
"basic-syntax01")
498 << QStringLiteral(
"something cool") << dict
499 << QStringLiteral(
"something cool") << NoError;
503 dict.insert(QStringLiteral(
"headline"), QStringLiteral(
"Success"));
504 QTest::newRow(
"basic-syntax02") << QStringLiteral(
"{{ headline }}") << dict
505 << QStringLiteral(
"Success") << NoError;
508 dict.insert(QStringLiteral(
"first"), 1);
509 dict.insert(QStringLiteral(
"second"), 2);
512 QTest::newRow(
"basic-syntax03")
513 << QStringLiteral(
"{{ first }} --- {{ second }}") << dict
514 << QStringLiteral(
"1 --- 2") << NoError;
518 QTest::newRow(
"basic-syntax04") << QStringLiteral(
"as{{ missing }}df") << dict
519 << QStringLiteral(
"asdf") << NoError;
522 QTest::newRow(
"basic-syntax06") << QStringLiteral(
"{{ multi word variable }}")
523 << dict <<
QString() << TagSyntaxError;
525 QTest::newRow(
"basic-syntax07")
526 << QStringLiteral(
"{{ }}") << dict <<
QString() << EmptyVariableError;
527 QTest::newRow(
"basic-syntax08") << QStringLiteral(
"{{ }}") << dict
528 <<
QString() << EmptyVariableError;
533 dict.insert(QStringLiteral(
"var"), QVariant::fromValue(someClass));
535 QTest::newRow(
"basic-syntax09")
536 << QStringLiteral(
"{{ var.method }}") << dict
537 << QStringLiteral(
"SomeClass::method") << NoError;
540 QTest::newRow(
"basic-syntax10")
541 << QStringLiteral(
"{{ var.otherClass.method }}") << dict
542 << QStringLiteral(
"OtherClass::method") << NoError;
545 QTest::newRow(
"basic-syntax11")
546 << QStringLiteral(
"{{ var.blech }}") << dict <<
QString() << NoError;
554 hash.insert(QStringLiteral(
"__dict__"), QStringLiteral(
"foo"));
555 dict.insert(QStringLiteral(
"var"), hash);
556 QTest::newRow(
"basic-syntax12") << QStringLiteral(
"{{ var.__dict__ }}")
557 << dict <<
QString() << TagSyntaxError;
562 QTest::newRow(
"basic-syntax13")
563 << QStringLiteral(
"{{ va>r }}") << dict <<
QString() << TagSyntaxError;
564 QTest::newRow(
"basic-syntax14")
565 << QStringLiteral(
"{{ (var.r) }}") << dict <<
QString() << TagSyntaxError;
566 QTest::newRow(
"basic-syntax15")
567 << QStringLiteral(
"{{ sp%am }}") << dict <<
QString() << TagSyntaxError;
568 QTest::newRow(
"basic-syntax16")
569 << QStringLiteral(
"{{ eggs! }}") << dict <<
QString() << TagSyntaxError;
570 QTest::newRow(
"basic-syntax17")
571 << QStringLiteral(
"{{ moo? }}") << dict <<
QString() << TagSyntaxError;
572 QTest::newRow(
"basic-syntax-error01")
573 << QStringLiteral(
"{{ moo:arg }}") << dict <<
QString() << TagSyntaxError;
574 QTest::newRow(
"basic-syntax-error02")
575 << QStringLiteral(
"{{ moo|cut:'foo':'bar' }}") << dict <<
QString()
581 hash.insert(QStringLiteral(
"bar"), QStringLiteral(
"baz"));
582 dict.insert(QStringLiteral(
"foo"), hash);
583 QTest::newRow(
"basic-syntax18") << QStringLiteral(
"{{ foo.bar }}") << dict
584 << QStringLiteral(
"baz") << NoError;
587 QTest::newRow(
"basic-syntax19")
588 << QStringLiteral(
"{{ foo.spam }}") << dict <<
QString() << NoError;
591 dict.insert(QStringLiteral(
"var"), QVariant::fromValue(someClass));
593 QTest::newRow(
"basic-syntax20")
594 << QStringLiteral(
"{{ var.nonAccessibleMethod }}") << dict <<
QString()
600 QTest::newRow(
"basic-syntax21") << QStringLiteral(
"a {{ moo %} b") << dict
601 << QStringLiteral(
"a {{ moo %} b") << NoError;
602 QTest::newRow(
"basic-syntax22") << QStringLiteral(
"{{ moo #}") << dict
603 << QStringLiteral(
"{{ moo #}") << NoError;
605 dict.insert(QStringLiteral(
"cow"), QStringLiteral(
"cow"));
608 QTest::newRow(
"basic-syntax23") << QStringLiteral(
"{{ moo #} {{ cow }}")
609 << dict <<
QString() << TagSyntaxError;
613 QTest::newRow(
"basic-syntax24")
614 <<
"{{ moo\n }}" << dict <<
"{{ moo\n }}" << NoError;
617 QTest::newRow(
"basic-syntax25")
618 <<
"{{ \"fred\" }}" << dict << QString::fromLatin1(
"fred" ) << NoError;
619 QTest::newRow(
"basic-syntax26")
620 <<
"{{ \"\\\"fred\\\"\" }}" << dict <<
"\"fred\"" << NoError;
621 QTest::newRow(
"basic-syntax27")
622 <<
"{{ _(\"\\\"fred\\\"\") }}" << dict <<
""fred"" << NoError;
626 QVariantHash innerHash;
627 innerHash.insert(QStringLiteral(
"3"), QStringLiteral(
"d"));
628 hash.insert(QStringLiteral(
"2"), innerHash);
629 dict.insert(QStringLiteral(
"1"), hash);
631 QTest::newRow(
"basic-syntax28") << QStringLiteral(
"{{ 1.2.3 }}") << dict
632 << QStringLiteral(
"d") << NoError;
636 QVariantList list{QStringLiteral(
"a"), QStringLiteral(
"b"),
637 QStringLiteral(
"c"), QStringLiteral(
"d")};
638 hash.insert(QStringLiteral(
"2"), list);
639 dict.insert(QStringLiteral(
"1"), hash);
640 QTest::newRow(
"basic-syntax29") << QStringLiteral(
"{{ 1.2.3 }}") << dict
641 << QStringLiteral(
"d") << NoError;
645 QVariantList innerList{QStringLiteral(
"x"), QStringLiteral(
"x"),
646 QStringLiteral(
"x"), QStringLiteral(
"x")};
648 innerList = {QStringLiteral(
"y"), QStringLiteral(
"y"), QStringLiteral(
"y"),
649 QStringLiteral(
"y")};
651 innerList = {QStringLiteral(
"a"), QStringLiteral(
"b"), QStringLiteral(
"c"),
652 QStringLiteral(
"d")};
654 dict.insert(QStringLiteral(
"1"), list);
656 QTest::newRow(
"basic-syntax30") << QStringLiteral(
"{{ 1.2.3 }}") << dict
657 << QStringLiteral(
"d") << NoError;
661 innerList = {QStringLiteral(
"x"), QStringLiteral(
"x"), QStringLiteral(
"x"),
662 QStringLiteral(
"x")};
664 innerList = {QStringLiteral(
"y"), QStringLiteral(
"y"), QStringLiteral(
"y"),
665 QStringLiteral(
"y")};
667 innerList = {QStringLiteral(
"a"), QStringLiteral(
"b"), QStringLiteral(
"c"),
668 QStringLiteral(
"d")};
670 dict.insert(QStringLiteral(
"1"), list);
672 QTest::newRow(
"basic-syntax31") << QStringLiteral(
"{{ 1.2.3 }}") << dict
673 << QStringLiteral(
"d") << NoError;
678 hash.insert(QStringLiteral(
"x"), QStringLiteral(
"x"));
681 hash.insert(QStringLiteral(
"y"), QStringLiteral(
"y"));
684 hash.insert(QStringLiteral(
"3"), QStringLiteral(
"d"));
687 dict.insert(QStringLiteral(
"1"), list);
689 QTest::newRow(
"basic-syntax32") << QStringLiteral(
"{{ 1.2.3 }}") << dict
690 << QStringLiteral(
"d") << NoError;
694 dict.insert(QStringLiteral(
"1"), QStringLiteral(
"abc"));
695 QTest::newRow(
"basic-syntax33")
696 << QStringLiteral(
"{{ 1 }}") << dict << QStringLiteral(
"1") << NoError;
697 QTest::newRow(
"basic-syntax34") << QStringLiteral(
"{{ 1.2 }}") << dict
698 << QStringLiteral(
"1.2") << NoError;
702 dict.insert(QStringLiteral(
"abc"), QStringLiteral(
"def"));
704 QTest::newRow(
"basic-syntax35")
705 << QStringLiteral(
"{{ abc._something }} {{ abc._something|upper }}")
706 << dict <<
QString() << TagSyntaxError;
708 QTest::newRow(
"basic-syntax36")
709 <<
"{{ \"fred }}" << dict <<
QString() << TagSyntaxError;
710 QTest::newRow(
"basic-syntax37")
711 <<
"{{ \'fred }}" << dict <<
QString() << TagSyntaxError;
712 QTest::newRow(
"basic-syntax38")
713 <<
"{{ \"fred\' }}" << dict <<
QString() << TagSyntaxError;
714 QTest::newRow(
"basic-syntax39")
715 <<
"{{ \'fred\" }}" << dict <<
QString() << TagSyntaxError;
716 QTest::newRow(
"basic-syntax40")
717 <<
"{{ _(\'fred }}" << dict <<
QString() << TagSyntaxError;
718 QTest::newRow(
"basic-syntax41")
719 <<
"{{ abc|removetags:_(\'fred }}" << dict <<
QString() << TagSyntaxError;
722 void TestBuiltinSyntax::testEnums_data()
724 QTest::addColumn<QString>(
"input");
725 QTest::addColumn<Dict>(
"dict");
726 QTest::addColumn<QString>(
"output");
727 QTest::addColumn<Cutelee::Error>(
"error");
732 dict.insert(QStringLiteral(
"var"), QVariant::fromValue(otherClass));
734 QTest::newRow(
"class-enums01") << QStringLiteral(
"{{ var.Lions }}") << dict
735 << QStringLiteral(
"0") << NoError;
736 QTest::newRow(
"class-enums02") << QStringLiteral(
"{{ var.Tigers }}") << dict
737 << QStringLiteral(
"1") << NoError;
738 QTest::newRow(
"class-enums03") << QStringLiteral(
"{{ var.Bears }}") << dict
739 << QStringLiteral(
"2") << NoError;
740 QTest::newRow(
"class-enums04")
741 << QStringLiteral(
"{{ var.Hamsters }}") << dict <<
QString() << NoError;
742 QTest::newRow(
"class-enums05")
743 << QStringLiteral(
"{{ var.Tigers.name }}") << dict
744 << QStringLiteral(
"Animals") << NoError;
745 QTest::newRow(
"class-enums06")
746 << QStringLiteral(
"{{ var.Tigers.scope }}") << dict
747 << QStringLiteral(
"OtherClass") << NoError;
748 QTest::newRow(
"class-enums07") << QStringLiteral(
"{{ var.Tigers.value }}")
749 << dict << QStringLiteral(
"1") << NoError;
750 QTest::newRow(
"class-enums08") << QStringLiteral(
"{{ var.Tigers.key }}")
751 << dict << QStringLiteral(
"Tigers") << NoError;
752 QTest::newRow(
"class-enums09") << QStringLiteral(
"{{ var.animals }}") << dict
753 << QStringLiteral(
"1") << NoError;
754 QTest::newRow(
"class-enums10")
755 << QStringLiteral(
"{{ var.animals.name }}") << dict
756 << QStringLiteral(
"Animals") << NoError;
757 QTest::newRow(
"class-enums11")
758 << QStringLiteral(
"{{ var.animals.scope }}") << dict
759 << QStringLiteral(
"OtherClass") << NoError;
760 QTest::newRow(
"class-enums12") << QStringLiteral(
"{{ var.animals.value }}")
761 << dict << QStringLiteral(
"1") << NoError;
762 QTest::newRow(
"class-enums13") << QStringLiteral(
"{{ var.animals.key }}")
763 << dict << QStringLiteral(
"Tigers") << NoError;
764 QTest::newRow(
"class-enums14") << QStringLiteral(
"{{ var.Animals.0 }}")
765 << dict << QStringLiteral(
"0") << NoError;
766 QTest::newRow(
"class-enums15") << QStringLiteral(
"{{ var.Animals.2 }}")
767 << dict << QStringLiteral(
"2") << NoError;
768 QTest::newRow(
"class-enums16")
769 << QStringLiteral(
"{{ var.Animals.3 }}") << dict <<
QString() << NoError;
770 QTest::newRow(
"class-enums17")
771 << QStringLiteral(
"{{ var.Animals.0.name }}") << dict
772 << QStringLiteral(
"Animals") << NoError;
773 QTest::newRow(
"class-enums18")
774 << QStringLiteral(
"{{ var.Animals.0.scope }}") << dict
775 << QStringLiteral(
"OtherClass") << NoError;
776 QTest::newRow(
"class-enums19") << QStringLiteral(
"{{ var.Animals.0.value }}")
777 << dict << QStringLiteral(
"0") << NoError;
778 QTest::newRow(
"class-enums20") << QStringLiteral(
"{{ var.Animals.0.key }}")
779 << dict << QStringLiteral(
"Lions") << NoError;
780 QTest::newRow(
"class-enums21") << QStringLiteral(
"{{ var.Animals.2.key }}")
781 << dict << QStringLiteral(
"Bears") << NoError;
782 QTest::newRow(
"class-enums22") << QStringLiteral(
"{{ var.Tigers.samba }}")
783 << dict <<
QString() << NoError;
784 QTest::newRow(
"class-enums23")
785 << QStringLiteral(
"{% with var.animals as result %}{{ result.key }},{{ "
786 "result }},{{ result.scope }}{% endwith %}")
787 << dict << QStringLiteral(
"Tigers,1,OtherClass") << NoError;
788 QTest::newRow(
"class-enums24")
789 << QStringLiteral(
"{% with var.Animals.2 as result %}{{ result.key }},{{ "
790 "result }},{{ result.scope }}{% endwith %}")
791 << dict << QStringLiteral(
"Bears,2,OtherClass") << NoError;
792 QTest::newRow(
"class-enums25")
793 << QStringLiteral(
"{% with var.Bears as result %}{{ result.key }},{{ "
794 "result }},{{ result.scope }}{% endwith %}")
795 << dict << QStringLiteral(
"Bears,2,OtherClass") << NoError;
796 QTest::newRow(
"class-enums26")
797 << QStringLiteral(
"{% with var.Animals as result %}{{ result.0.key }},{{ "
798 "result.1.key }},{{ result.2.key }}{% endwith %}")
799 << dict << QStringLiteral(
"Lions,Tigers,Bears") << NoError;
804 dict.insert(QStringLiteral(
"var"), QVariant::fromValue(someClass));
806 QTest::newRow(
"class-enums27") << QStringLiteral(
"{{ var.Employee }}") << dict
807 << QStringLiteral(
"0") << NoError;
808 QTest::newRow(
"class-enums28") << QStringLiteral(
"{{ var.Employer }}") << dict
809 << QStringLiteral(
"1") << NoError;
810 QTest::newRow(
"class-enums29") << QStringLiteral(
"{{ var.Manager }}") << dict
811 << QStringLiteral(
"2") << NoError;
812 QTest::newRow(
"class-enums30") << QStringLiteral(
"{{ var.Voter }}") << dict
813 << QStringLiteral(
"2") << NoError;
814 QTest::newRow(
"class-enums31") << QStringLiteral(
"{{ var.Consumer }}") << dict
815 << QStringLiteral(
"4") << NoError;
816 QTest::newRow(
"class-enums32") << QStringLiteral(
"{{ var.Citizen }}") << dict
817 << QStringLiteral(
"8") << NoError;
818 QTest::newRow(
"class-enums33")
819 << QStringLiteral(
"{{ var.FirstEnum }}") << dict <<
QString() << NoError;
820 QTest::newRow(
"class-enums34")
821 << QStringLiteral(
"{{ var.SecondEnum }}") << dict <<
QString() << NoError;
823 QTest::newRow(
"class-enums35")
824 << QString::fromLatin1(
825 "{% with var.SecondEnum as result %}"
826 "{{ result.0 }},{{ result.1 }},{{ result.2 }},"
827 "{{ result.0.key }},{{ result.1.key }},{{ result.2.key }},"
828 "{{ result }},{{ result.scope }}"
830 << dict << QStringLiteral(
"2,4,8,Voter,Consumer,Citizen,,SomeClass")
833 QTest::newRow(
"class-enums36")
834 << QStringLiteral(
"{% ifequal var.Employee 2 %}{% endifequal %}") << dict
837 dict.insert(QStringLiteral(
"var"), QVariant::fromValue(otherClass));
839 QTest::newRow(
"enums-loops01")
840 << QString::fromLatin1(
841 "{% for enum in var.Animals %}{% ifequal enum var.Tigers %}"
842 "<b>{{ enum.key }}</b>{% else %}{{ enum.key }}{% endifequal %},"
843 "{% empty %}No content{% endfor %}")
844 << dict << QStringLiteral(
"Lions,<b>Tigers</b>,Bears,") << NoError;
846 QTest::newRow(
"enums-loops02")
847 << QString::fromLatin1(
"{% for enum in var.Tigers %}"
848 "{% ifequal enum result %}<b>{{ enum.key }}</b>"
849 "{% else %}{{ enum.key }}{% endifequal %},"
850 "{% empty %}No content"
852 << dict << QStringLiteral(
"No content") << NoError;
854 QTest::newRow(
"enums-loops03")
855 << QString::fromLatin1(
"{% with var.animals as result %}"
856 "{% for enum in var.Animals %}"
857 "{% ifequal enum result %}<b>{{ enum.key }}</b>"
858 "{% else %}{{ enum.key }}{% endifequal %},"
859 "{% empty %}No content"
862 << dict << QStringLiteral(
"Lions,<b>Tigers</b>,Bears,") << NoError;
864 QTest::newRow(
"enums-keycount01")
865 << QStringLiteral(
"{{ var.Animals.keyCount }}") << dict
866 << QStringLiteral(
"3") << NoError;
867 QTest::newRow(
"enums-keycount02")
868 << QStringLiteral(
"{{ var.Lions.keyCount }}") << dict
869 << QStringLiteral(
"3") << NoError;
870 QTest::newRow(
"enums-keycount02")
871 << QStringLiteral(
"{{ var.animals.keyCount }}") << dict
872 << QStringLiteral(
"3") << NoError;
874 auto otherClass2 =
new OtherClass(OtherClass::Lions,
this);
875 dict.insert(QStringLiteral(
"var2"), QVariant::fromValue(otherClass2));
878 dict.insert(QStringLiteral(
"var3"), QVariant::fromValue(otherClass3));
880 QTest::newRow(
"enums-compare01")
881 << QStringLiteral(
"{% if var.animals == var3.animals %}true{% else %}false{% endif %}") << dict
882 << QStringLiteral(
"true") << NoError;
884 QTest::newRow(
"enums-compare02")
885 << QStringLiteral(
"{% if var.animals == var2.animals %}true{% else %}false{% endif %}") << dict
886 << QStringLiteral(
"false") << NoError;
888 QTest::newRow(
"enums-compare03")
889 << QStringLiteral(
"{% if var.animals >= var3.animals %}true{% else %}false{% endif %}") << dict
890 << QStringLiteral(
"true") << NoError;
892 QTest::newRow(
"enums-compare04")
893 << QStringLiteral(
"{% if var.animals >= var2.animals %}true{% else %}false{% endif %}") << dict
894 << QStringLiteral(
"true") << NoError;
895 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
896 QTest::newRow(
"enums-compare05")
897 << QStringLiteral(
"{% if var.animals > var3.animals %}true{% else %}false{% endif %}") << dict
898 << QStringLiteral(
"false") << NoError;
901 QTest::newRow(
"enums-compare06")
902 << QStringLiteral(
"{% if var.animals > var2.animals %}true{% else %}false{% endif %}") << dict
903 << QStringLiteral(
"true") << NoError;
904 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
905 QTest::newRow(
"enums-compare07")
906 << QStringLiteral(
"{% if var.animals <= var3.animals %}true{% else %}false{% endif %}") << dict
907 << QStringLiteral(
"true") << NoError;
909 QTest::newRow(
"enums-compare08")
910 << QStringLiteral(
"{% if var.animals <= var2.animals %}true{% else %}false{% endif %}") << dict
911 << QStringLiteral(
"false") << NoError;
913 QTest::newRow(
"enums-compare09")
914 << QStringLiteral(
"{% if var.animals < var3.animals %}true{% else %}false{% endif %}") << dict
915 << QStringLiteral(
"false") << NoError;
917 QTest::newRow(
"enums-compare10")
918 << QStringLiteral(
"{% if var.animals < var2.animals %}true{% else %}false{% endif %}") << dict
919 << QStringLiteral(
"false") << NoError;
922 QTest::newRow(
"qt-enums01") << QStringLiteral(
"{{ Qt.AlignRight }}") << dict
923 << QStringLiteral(
"2") << NoError;
924 QTest::newRow(
"qt-enums02") << QStringLiteral(
"{{ Qt.AlignRight.scope }}")
925 << dict << QStringLiteral(
"Qt") << NoError;
926 QTest::newRow(
"qt-enums03") << QStringLiteral(
"{{ Qt.AlignRight.name }}")
927 << dict << QStringLiteral(
"Alignment") << NoError;
928 QTest::newRow(
"qt-enums04") << QStringLiteral(
"{{ Qt.AlignRight.value }}")
929 << dict << QStringLiteral(
"2") << NoError;
930 QTest::newRow(
"qt-enums05")
931 << QStringLiteral(
"{{ Qt.AlignRight.key }}") << dict
932 << QStringLiteral(
"AlignRight") << NoError;
933 QTest::newRow(
"qt-enums06")
934 << QStringLiteral(
"{{ Qt.Alignment.2.key }}") << dict
935 << QStringLiteral(
"AlignRight") << NoError;
937 QTest::newRow(
"qt-enums07") << QStringLiteral(
"{{ Qt.DoesNotExist }}") << dict
939 QTest::newRow(
"qt-enums08")
940 << QStringLiteral(
"{{ Qt }}") << dict <<
QString() << NoError;
945 dict.insert(QStringLiteral(
"var"), QVariant::fromValue(gadgetClasss));
947 QTest::newRow(
"gadget-enums01") << QStringLiteral(
"{{ var.Mike }}") << dict
948 << QStringLiteral(
"0") << NoError;
949 QTest::newRow(
"gadget-enums02") << QStringLiteral(
"{{ var.Natalie }}") << dict
950 << QStringLiteral(
"1") << NoError;
951 QTest::newRow(
"gadget-enums03") << QStringLiteral(
"{{ var.Oliver }}") << dict
952 << QStringLiteral(
"2") << NoError;
953 QTest::newRow(
"gadget-enums04") << QStringLiteral(
"{{ var.Patricia }}") << dict
955 QTest::newRow(
"gadget-enums05") << QStringLiteral(
"{{ var.Natalie.name }}") << dict
956 << QStringLiteral(
"PersonName") << NoError;
957 QTest::newRow(
"gadget-enums06") << QStringLiteral(
"{{ var.Natalie.scope }}") << dict
958 << QStringLiteral(
"GadgetClass") << NoError;
959 QTest::newRow(
"gadget-enums07") << QStringLiteral(
"{{ var.Natalie.value }}") << dict
960 << QStringLiteral(
"1") << NoError;
961 QTest::newRow(
"gadget-enums08") << QStringLiteral(
"{{ var.Natalie.key }}") << dict
962 << QStringLiteral(
"Natalie") << NoError;
963 QTest::newRow(
"gadget-enums09") << QStringLiteral(
"{{ var.personName }}") << dict
964 << QStringLiteral(
"2") << NoError;
965 QTest::newRow(
"gadget-enums10") << QStringLiteral(
"{{ var.personName.name }}") << dict
966 << QStringLiteral(
"PersonName") << NoError;
967 QTest::newRow(
"gadget-enums11") << QStringLiteral(
"{{ var.personName.scope }}") << dict
968 << QStringLiteral(
"GadgetClass") << NoError;
969 QTest::newRow(
"gadget-enums12") << QStringLiteral(
"{{ var.personName.value }}") << dict
970 << QStringLiteral(
"2") << NoError;
971 QTest::newRow(
"gadget-enums13") << QStringLiteral(
"{{ var.personName.key }}") << dict
972 << QStringLiteral(
"Oliver") << NoError;
973 QTest::newRow(
"gadget-enums14") << QStringLiteral(
"{{ var.PersonName.0 }}") << dict
974 << QStringLiteral(
"0") << NoError;
975 QTest::newRow(
"gadget-enums15") << QStringLiteral(
"{{ var.PersonName.2 }}") << dict
976 << QStringLiteral(
"2") << NoError;
977 QTest::newRow(
"gadget-enums16") << QStringLiteral(
"{{ var.PersonName.3 }}") << dict
979 QTest::newRow(
"gadget-enums17") << QStringLiteral(
"{{ var.PersonName.0.name }}") << dict
980 << QStringLiteral(
"PersonName") << NoError;
981 QTest::newRow(
"gadget-enums18") << QStringLiteral(
"{{ var.PersonName.0.scope }}") << dict
982 << QStringLiteral(
"GadgetClass") << NoError;
983 QTest::newRow(
"gadget-enums19") << QStringLiteral(
"{{ var.PersonName.0.value }}")
984 << dict << QStringLiteral(
"0") << NoError;
985 QTest::newRow(
"gadget-enums20") << QStringLiteral(
"{{ var.PersonName.0.key }}")
986 << dict << QStringLiteral(
"Mike") << NoError;
987 QTest::newRow(
"gadget-enums21") << QStringLiteral(
"{{ var.PersonName.2.key }}")
988 << dict << QStringLiteral(
"Oliver") << NoError;
989 QTest::newRow(
"gadget-enums22") << QStringLiteral(
"{{ var.PersonName.samba }}")
990 << dict <<
QString() << NoError;
991 QTest::newRow(
"gadget-enums23")
992 << QStringLiteral(
"{% with var.personName as result %}{{ result.key }},{{ "
993 "result }},{{ result.scope }}{% endwith %}")
994 << dict << QStringLiteral(
"Oliver,2,GadgetClass") << NoError;
995 QTest::newRow(
"gadget-enums24")
996 << QStringLiteral(
"{% with var.PersonName.2 as result %}{{ result.key }},{{ "
997 "result }},{{ result.scope }}{% endwith %}")
998 << dict << QStringLiteral(
"Oliver,2,GadgetClass") << NoError;
999 QTest::newRow(
"gadget-enums25")
1000 << QStringLiteral(
"{% with var.Oliver as result %}{{ result.key }},{{ "
1001 "result }},{{ result.scope }}{% endwith %}")
1002 << dict << QStringLiteral(
"Oliver,2,GadgetClass") << NoError;
1003 QTest::newRow(
"gadget-enums26")
1004 << QStringLiteral(
"{% with var.PersonName as result %}{{ result.0.key }},{{ "
1005 "result.1.key }},{{ result.2.key }}{% endwith %}")
1006 << dict << QStringLiteral(
"Mike,Natalie,Oliver") << NoError;
1008 QTest::newRow(
"gadget-enums-loops01")
1009 << QString::fromLatin1(
1010 "{% for enum in var.PersonName %}{% ifequal enum var.Natalie %}"
1011 "<b>{{ enum.key }}</b>{% else %}{{ enum.key }}{% endifequal %},"
1012 "{% empty %}No content{% endfor %}")
1013 << dict << QStringLiteral(
"Mike,<b>Natalie</b>,Oliver,") << NoError;
1015 QTest::newRow(
"gadget-enums-loops02")
1016 << QString::fromLatin1(
"{% for enum in var.Tigers %}"
1017 "{% ifequal enum result %}<b>{{ enum.key }}</b>"
1018 "{% else %}{{ enum.key }}{% endifequal %},"
1019 "{% empty %}No content"
1021 << dict << QStringLiteral(
"No content") << NoError;
1023 QTest::newRow(
"gadget-enums-loops03")
1024 << QString::fromLatin1(
"{% with var.personName as result %}"
1025 "{% for enum in var.PersonName %}"
1026 "{% ifequal enum result %}<b>{{ enum.key }}</b>"
1027 "{% else %}{{ enum.key }}{% endifequal %},"
1028 "{% empty %}No content"
1031 << dict << QStringLiteral(
"Mike,Natalie,<b>Oliver</b>,") << NoError;
1033 QTest::newRow(
"gadget-enums-keycount01")
1034 << QStringLiteral(
"{{ var.PersonName.keyCount }}") << dict
1035 << QStringLiteral(
"3") << NoError;
1036 QTest::newRow(
"gadget-enums-keycount02")
1037 << QStringLiteral(
"{{ var.personName.keyCount }}") << dict
1038 << QStringLiteral(
"3") << NoError;
1041 dict.insert(QStringLiteral(
"var2"), QVariant::fromValue(gadgetClass2));
1044 dict.insert(QStringLiteral(
"var3"), QVariant::fromValue(gadgetClass3));
1046 QTest::newRow(
"gadget-enums-compare01")
1047 << QStringLiteral(
"{% if var.personName == var3.personName %}true{% else %}false{% endif %}") << dict
1048 << QStringLiteral(
"true") << NoError;
1050 QTest::newRow(
"gadget-enums-compare02")
1051 << QStringLiteral(
"{% if var.personName == var2.personName %}true{% else %}false{% endif %}") << dict
1052 << QStringLiteral(
"false") << NoError;
1054 QTest::newRow(
"gadget-enums-compare03")
1055 << QStringLiteral(
"{% if var.personName >= var3.personName %}true{% else %}false{% endif %}") << dict
1056 << QStringLiteral(
"true") << NoError;
1058 QTest::newRow(
"gadget-enums-compare04")
1059 << QStringLiteral(
"{% if var.personName >= var2.personName %}true{% else %}false{% endif %}") << dict
1060 << QStringLiteral(
"true") << NoError;
1062 QTest::newRow(
"gadget-enums-compare05")
1063 << QStringLiteral(
"{% if var.personName > var3.personName %}true{% else %}false{% endif %}") << dict
1064 << QStringLiteral(
"false") << NoError;
1066 QTest::newRow(
"gadget-enums-compare06")
1067 << QStringLiteral(
"{% if var.personName > var2.personName %}true{% else %}false{% endif %}") << dict
1068 << QStringLiteral(
"true") << NoError;
1070 QTest::newRow(
"gadget-enums-compare07")
1071 << QStringLiteral(
"{% if var.personName <= var3.personName %}true{% else %}false{% endif %}") << dict
1072 << QStringLiteral(
"true") << NoError;
1074 QTest::newRow(
"gadget-enums-compare08")
1075 << QStringLiteral(
"{% if var.personName <= var2.personName %}true{% else %}false{% endif %}") << dict
1076 << QStringLiteral(
"false") << NoError;
1078 QTest::newRow(
"gadget-enums-compare09")
1079 << QStringLiteral(
"{% if var.personName < var3.personName %}true{% else %}false{% endif %}") << dict
1080 << QStringLiteral(
"false") << NoError;
1082 QTest::newRow(
"gadget-enums-compare10")
1083 << QStringLiteral(
"{% if var.personName < var2.personName %}true{% else %}false{% endif %}") << dict
1084 << QStringLiteral(
"false") << NoError;
1087 void TestBuiltinSyntax::testListIndex_data()
1090 QTest::addColumn<QString>(
"input");
1091 QTest::addColumn<Dict>(
"dict");
1092 QTest::addColumn<QString>(
"output");
1093 QTest::addColumn<Cutelee::Error>(
"error");
1097 QVariantList l{QStringLiteral(
"first item"), QStringLiteral(
"second item")};
1099 dict.insert(QStringLiteral(
"var"), l);
1103 QTest::newRow(
"list-index01") << QStringLiteral(
"{{ var.1 }}") << dict
1104 << QStringLiteral(
"second item") << NoError;
1106 QTest::newRow(
"list-index02")
1107 << QStringLiteral(
"{{ var.5 }}") << dict <<
QString() << NoError;
1110 dict.insert(QStringLiteral(
"var"),
QVariant());
1113 QTest::newRow(
"list-index03")
1114 << QStringLiteral(
"{{ var.1 }}") << dict <<
QString() << NoError;
1117 dict.insert(QStringLiteral(
"var"), QVariantHash());
1119 QTest::newRow(
"list-index04")
1120 << QStringLiteral(
"{{ var.1 }}") << dict <<
QString() << NoError;
1125 hash.insert(QStringLiteral(
"1"), QStringLiteral(
"hello"));
1126 dict.insert(QStringLiteral(
"var"), hash);
1128 QTest::newRow(
"list-index05") << QStringLiteral(
"{{ var.1 }}") << dict
1129 << QStringLiteral(
"hello") << NoError;
1138 sl.append(QStringLiteral(
"hello"));
1139 sl.append(QStringLiteral(
"world"));
1140 dict.insert(QStringLiteral(
"var"), sl);
1142 QTest::newRow(
"list-index08")
1143 << QStringLiteral(
"{{ var.0 }}, {{ var.1 }}!") << dict
1144 << QStringLiteral(
"hello, world!") << NoError;
1147 void TestBuiltinSyntax::testFilterSyntax_data()
1149 QTest::addColumn<QString>(
"input");
1150 QTest::addColumn<Dict>(
"dict");
1151 QTest::addColumn<QString>(
"output");
1152 QTest::addColumn<Cutelee::Error>(
"error");
1157 dict.insert(QStringLiteral(
"var"), QStringLiteral(
"Django is the greatest!"));
1158 QTest::newRow(
"filter-syntax01")
1159 << QStringLiteral(
"{{ var|upper }}") << dict
1160 << QStringLiteral(
"DJANGO IS THE GREATEST!") << NoError;
1163 QTest::newRow(
"filter-syntax02")
1164 << QStringLiteral(
"{{ var|upper|lower }}") << dict
1165 << QStringLiteral(
"django is the greatest!") << NoError;
1169 QTest::newRow(
"filter-syntax03") << QStringLiteral(
"{{ var |upper }}") << dict
1170 <<
QString() << TagSyntaxError;
1173 QTest::newRow(
"filter-syntax04") << QStringLiteral(
"{{ var| upper }}") << dict
1174 <<
QString() << TagSyntaxError;
1177 QTest::newRow(
"filter-syntax05") << QStringLiteral(
"{{ var|does_not_exist }}")
1178 << dict <<
QString() << UnknownFilterError;
1182 QTest::newRow(
"filter-syntax06") << QStringLiteral(
"{{ var|fil(ter) }}")
1183 << dict <<
QString() << UnknownFilterError;
1186 QTest::newRow(
"filter-syntax07")
1187 << QStringLiteral(
"{% nothing_to_see_here %}") << dict <<
QString()
1188 << InvalidBlockTagError;
1190 QTest::newRow(
"filter-syntax08")
1191 << QStringLiteral(
"{% %}") << dict <<
QString() << EmptyBlockTagError;
1194 dict.insert(QStringLiteral(
"var"), QStringLiteral(
"<b><i>Yes</i></b>"));
1195 QTest::newRow(
"filter-syntax09") <<
"{{ var|removetags:\"b i\"|upper|lower }}"
1196 << dict << QStringLiteral(
"yes") << NoError;
1199 dict.insert(QStringLiteral(
"var"),
QVariant());
1200 QTest::newRow(
"filter-syntax10")
1201 <<
"{{ var|default_if_none:\" endquote\\\" hah\" }}" << dict
1202 <<
" endquote\" hah" << NoError;
1204 dict.insert(QStringLiteral(
"var2"), QStringLiteral(
"happy"));
1205 QTest::newRow(
"filter-syntax11")
1206 << QStringLiteral(
"{{ var|default_if_none:var2 }}") << dict
1207 << QStringLiteral(
"happy") << NoError;
1210 dict.insert(QStringLiteral(
"var"),
true);
1211 QTest::newRow(
"filter-syntax12")
1212 <<
"{{ var|yesno:\"yup,nup,mup\" }} {{ var|yesno }}" << dict
1213 << QStringLiteral(
"yup yes") << NoError;
1232 dict.insert(QStringLiteral(
"var"),
QVariant());
1233 QTest::newRow(
"filter-syntax15") <<
"{{ var|default_if_none:\"foo\\bar\" }}"
1234 << dict <<
"foo\\bar" << NoError;
1236 QTest::newRow(
"filter-syntax16") <<
"{{ var|default_if_none:\"foo\\now\" }}"
1237 << dict <<
"foo\\now" << NoError;
1240 dict.insert(QStringLiteral(
"var"),
1241 QVariantList{QStringLiteral(
"a"), QStringLiteral(
"b"),
1242 QStringLiteral(
"c")});
1243 QTest::newRow(
"filter-syntax17")
1244 <<
"{{ var|join:\"\" }}" << dict << QStringLiteral(
"abc") << NoError;
1253 dict.insert(QStringLiteral(
"var"), QStringLiteral(
"hello world"));
1254 QTest::newRow(
"filter-syntax19")
1255 << QStringLiteral(
"{{ var|truncatewords:1 }}") << dict
1256 << QStringLiteral(
"hello ...") << NoError;
1259 QTest::newRow(
"filter-syntax20") <<
"{{ \"\"|default_if_none:\"was none\" }}"
1260 << dict <<
QString() << NoError;
1262 QTest::newRow(
"filter-syntax21")
1263 <<
"{{ \"\"|default_if_none:|truncatewords }}" << dict <<
QString()
1264 << EmptyVariableError;
1267 void TestBuiltinSyntax::testCommentSyntax_data()
1269 QTest::addColumn<QString>(
"input");
1270 QTest::addColumn<Dict>(
"dict");
1271 QTest::addColumn<QString>(
"output");
1272 QTest::addColumn<Cutelee::Error>(
"error");
1276 QTest::newRow(
"comment-syntax01")
1277 << QStringLiteral(
"{# this is hidden #}hello") << dict
1278 << QStringLiteral(
"hello") << NoError;
1279 QTest::newRow(
"comment-syntax02")
1280 << QStringLiteral(
"{# this is hidden #}hello{# foo #}") << dict
1281 << QStringLiteral(
"hello") << NoError;
1283 QTest::newRow(
"comment-syntax03") << QStringLiteral(
"foo{# {% if %} #}")
1284 << dict << QStringLiteral(
"foo") << NoError;
1285 QTest::newRow(
"comment-syntax04")
1286 << QStringLiteral(
"foo{# {% endblock %} #}") << dict
1287 << QStringLiteral(
"foo") << NoError;
1288 QTest::newRow(
"comment-syntax05")
1289 << QStringLiteral(
"foo{# {% somerandomtag %} #}") << dict
1290 << QStringLiteral(
"foo") << NoError;
1291 QTest::newRow(
"comment-syntax06") << QStringLiteral(
"foo{# {% #}") << dict
1292 << QStringLiteral(
"foo") << NoError;
1293 QTest::newRow(
"comment-syntax07") << QStringLiteral(
"foo{# %} #}") << dict
1294 << QStringLiteral(
"foo") << NoError;
1295 QTest::newRow(
"comment-syntax08") << QStringLiteral(
"foo{# %} #}bar") << dict
1296 << QStringLiteral(
"foobar") << NoError;
1297 QTest::newRow(
"comment-syntax09") << QStringLiteral(
"foo{# {{ #}") << dict
1298 << QStringLiteral(
"foo") << NoError;
1299 QTest::newRow(
"comment-syntax10") << QStringLiteral(
"foo{# }} #}") << dict
1300 << QStringLiteral(
"foo") << NoError;
1301 QTest::newRow(
"comment-syntax11") << QStringLiteral(
"foo{# { #}") << dict
1302 << QStringLiteral(
"foo") << NoError;
1303 QTest::newRow(
"comment-syntax12") << QStringLiteral(
"foo{# } #}") << dict
1304 << QStringLiteral(
"foo") << NoError;
1307 void TestBuiltinSyntax::testMultiline_data()
1309 QTest::addColumn<QString>(
"input");
1310 QTest::addColumn<Dict>(
"dict");
1311 QTest::addColumn<QString>(
"output");
1312 QTest::addColumn<Cutelee::Error>(
"error");
1316 QTest::newRow(
"multiline01")
1317 <<
"Hello,\nboys.\nHow\nare\nyou\ngentlemen?" << dict
1318 <<
"Hello,\nboys.\nHow\nare\nyou\ngentlemen?" << NoError;
1321 void TestBuiltinSyntax::testEscaping_data()
1323 QTest::addColumn<QString>(
"input");
1324 QTest::addColumn<Dict>(
"dict");
1325 QTest::addColumn<QString>(
"output");
1326 QTest::addColumn<Cutelee::Error>(
"error");
1331 dict.insert(QStringLiteral(
"var"), QStringLiteral(
"< > & \" \' # = % $"));
1332 QTest::newRow(
"escape01") << QStringLiteral(
"{{ var }}") << dict
1333 <<
"< > & " ' # = % $" << NoError;
1336 dict.insert(QStringLiteral(
"var"), QStringLiteral(
"this & that"));
1337 QTest::newRow(
"escape02") << QStringLiteral(
"{{ var }}") << dict
1338 << QStringLiteral(
"this & that") << NoError;
1341 QTest::newRow(
"escape03")
1342 <<
"{% ifequal var \"this & that\" %}yes{% endifequal %}" << dict
1343 << QStringLiteral(
"yes") << NoError;
1346 QTest::newRow(
"escape04") <<
"{{ var|cut:\"&\" }}" << dict
1347 << QStringLiteral(
"this that") << NoError;
1349 dict.insert(QStringLiteral(
"varList"),
1350 QVariantList{QStringLiteral(
"Tom"), QStringLiteral(
"Dick"),
1351 QStringLiteral(
"Harry")});
1352 QTest::newRow(
"escape05") <<
"{{ varList|join:\" & \" }}" << dict
1353 << QStringLiteral(
"Tom & Dick & Harry") << NoError;
1356 dict.insert(QStringLiteral(
"amp"), QStringLiteral(
" & "));
1357 QTest::newRow(
"escape06")
1358 << QStringLiteral(
"{{ varList|join:amp }}") << dict
1359 << QStringLiteral(
"Tom & Dick & Harry") << NoError;
1362 QTest::newRow(
"escape07") <<
"{{ \"this & that\" }}" << dict
1363 << QStringLiteral(
"this & that") << NoError;
1367 QVariantList list{QStringLiteral(
"K"), QStringLiteral(
"&"),
1368 QStringLiteral(
"R")};
1369 dict.insert(QStringLiteral(
"list"), list);
1370 QTest::newRow(
"escape08")
1371 << QStringLiteral(
"{% for letter in list %}{{ letter }},{% endfor %}")
1372 << dict << QStringLiteral(
"K,&,R,") << NoError;
1377 hash.insert(QStringLiteral(
"key"), QStringLiteral(
"this & that"));
1378 dict.insert(QStringLiteral(
"var"), hash);
1379 QTest::newRow(
"escape09") << QStringLiteral(
"{{ var.key }}") << dict
1380 << QStringLiteral(
"this & that") << NoError;
1385 void TestBuiltinSyntax::testMultipleStates()
1387 auto engine1 = getEngine();
1392 loader1->setTemplate(QStringLiteral(
"template1"),
1393 QStringLiteral(
"Template 1"));
1394 engine1->addTemplateLoader(loader1);
1396 auto t1 = engine1->newTemplate(QStringLiteral(
"{% include \"template1\" %}"),
1397 QStringLiteral(
"\"template1\""));
1399 auto engine2 = getEngine();
1404 loader2->setTemplate(QStringLiteral(
"template2"),
1405 QStringLiteral(
"Template 2"));
1407 engine2->addTemplateLoader(loader2);
1409 auto t2 = engine2->newTemplate(QStringLiteral(
"{% include \"template2\" %}"),
1410 QStringLiteral(
"\"template2\""));
1412 auto engine3 = getEngine();
1417 loader3->setTemplate(QStringLiteral(
"template3"),
1418 QStringLiteral(
"Template 3"));
1420 engine3->addTemplateLoader(loader3);
1422 auto t3 = engine3->newTemplate(QStringLiteral(
"{% include var %}"),
1423 QStringLiteral(
"var"));
1426 h.insert(QStringLiteral(
"var"), QStringLiteral(
"template3"));
1430 auto expected1 = QStringLiteral(
"Template 1");
1431 auto expected2 = QStringLiteral(
"Template 2");
1432 auto expected3 = QStringLiteral(
"Template 3");
1433 QCOMPARE(t1->render(&c), expected1);
1434 QCOMPARE(t2->render(&c), expected2);
1435 QCOMPARE(t3->render(&c), expected3);
1438 void TestBuiltinSyntax::testAlternativeEscaping()
1440 auto engine1 = getEngine();
1442 auto t1 = engine1->newTemplate(
1443 QStringLiteral(
"{{ var }} {% spaceless %}{{ var }}{% endspaceless %}"),
1444 QStringLiteral(
"\"template1\""));
1446 auto input = QStringLiteral(
"< > \r\n & \" \' # = % $");
1449 h.insert(QStringLiteral(
"var"), input);
1453 QTextStream ts(&output);
1457 t1->render(&noEscapeOs, &c);
1459 QCOMPARE(output,
QString(input + QLatin1String(
" ") + input));
1464 t1->render(&jsOs, &c);
1466 QString jsOutput(QStringLiteral(
1467 "\\u003C \\u003E \\u000D\\u000A \\u0026 \\u0022 \\u0027 # \\u003D % $"));
1469 jsOutput = jsOutput + QLatin1String(
" ") + jsOutput;
1471 QCOMPARE(output, jsOutput);
1474 void TestBuiltinSyntax::testTemplatePathSafety_data()
1476 QTest::addColumn<QString>(
"inputPath");
1477 QTest::addColumn<QString>(
"output");
1479 QTest::newRow(
"template-path-safety01")
1480 << QStringLiteral(
"visible_file") << QStringLiteral(
"visible_file");
1481 QTest::newRow(
"template-path-safety02")
1482 << QStringLiteral(
"../invisible_file") <<
QString();
1485 void TestBuiltinSyntax::testTemplatePathSafety()
1492 loader->setTemplateDirs({QStringLiteral(
".")});
1495 auto opened = f.open(QFile::WriteOnly | QFile::Text);
1497 f.write(inputPath.toUtf8());
1500 auto t = loader->loadByName(inputPath, m_engine);
1502 if (output.isEmpty())
1505 QCOMPARE(t->
render(&c), inputPath);
1511 void TestBuiltinSyntax::testMediaPathSafety_data()
1513 QTest::addColumn<QString>(
"inputPath");
1514 QTest::addColumn<QString>(
"output");
1516 QTest::newRow(
"media-path-safety01")
1517 << QStringLiteral(
"visible_file") << QStringLiteral(
"./visible_file");
1518 QTest::newRow(
"media-path-safety02")
1519 << QStringLiteral(
"../invisible_file") <<
QString();
1522 void TestBuiltinSyntax::testMediaPathSafety()
1529 loader->setTemplateDirs({QStringLiteral(
".")});
1532 auto opened = f.open(QFile::WriteOnly | QFile::Text);
1534 f.write(inputPath.toUtf8());
1537 auto uri = loader->getMediaUri(inputPath);
1538 if (output.isEmpty())
1539 QVERIFY(uri.second.isEmpty());
1541 QCOMPARE(QFileInfo(uri.first + uri.second).absoluteFilePath(),
1542 QFileInfo(output).absoluteFilePath());
1548 void TestBuiltinSyntax::testTypeAccessorsUnordered()
1552 QFETCH(QStringList, output);
1555 auto t = m_engine->newTemplate(input, QLatin1String(QTest::currentDataTag()));
1559 auto result = t->
render(&context);
1560 if (t->
error() != NoError) {
1561 if (t->
error() != error)
1563 QCOMPARE(t->
error(), error);
1567 QCOMPARE(t->
error(), NoError);
1570 QCOMPARE(NoError, error);
1572 Q_FOREACH (
const QString &s, output) {
1573 QVERIFY(result.contains(s));
1576 QCOMPARE(result.length(), output.join(
QString()).length());
1579 void TestBuiltinSyntax::testTypeAccessorsUnordered_data()
1581 QTest::addColumn<QString>(
"input");
1582 QTest::addColumn<Dict>(
"dict");
1583 QTest::addColumn<QStringList>(
"output");
1584 QTest::addColumn<Cutelee::Error>(
"error");
1588 QVariantHash itemsHash;
1589 itemsHash.insert(QStringLiteral(
"one"), 1);
1590 itemsHash.insert(QStringLiteral(
"two"), 2);
1591 itemsHash.insert(QStringLiteral(
"three"), 3);
1593 dict.insert(QStringLiteral(
"hash"), itemsHash);
1595 QTest::newRow(
"type-accessors-hash-unordered01")
1596 << QStringLiteral(
"{% for key,value in hash.items %}{{ key }}:{{ value "
1599 << QStringList{QStringLiteral(
"one:1;"), QStringLiteral(
"two:2;"),
1600 QStringLiteral(
"three:3;")}
1602 QTest::newRow(
"type-accessors-hash-unordered02")
1603 << QStringLiteral(
"{% for key in hash.keys %}{{ key }};{% endfor %}")
1605 << QStringList{QStringLiteral(
"one;"), QStringLiteral(
"two;"),
1606 QStringLiteral(
"three;")}
1608 QTest::newRow(
"type-accessors-hash-unordered03")
1610 "{% for value in hash.values %}{{ value }};{% endfor %}")
1612 << QStringList{QStringLiteral(
"1;"), QStringLiteral(
"2;"),
1613 QStringLiteral(
"3;")}
1617 void TestBuiltinSyntax::testTypeAccessors_data()
1619 QTest::addColumn<QString>(
"input");
1620 QTest::addColumn<Dict>(
"dict");
1621 QTest::addColumn<QString>(
"output");
1622 QTest::addColumn<Cutelee::Error>(
"error");
1626 QVariantHash itemsHash;
1627 itemsHash.insert(QStringLiteral(
"one"), 1);
1628 itemsHash.insert(QStringLiteral(
"two"), 2);
1629 itemsHash.insert(QStringLiteral(
"three"), 3);
1631 dict.insert(QStringLiteral(
"hash"), itemsHash);
1633 QTest::newRow(
"type-accessors-hash01")
1634 << QStringLiteral(
"{{ hash.items|length }}") << dict
1635 << QStringLiteral(
"3") << NoError;
1636 QTest::newRow(
"type-accessors-hash02")
1637 << QStringLiteral(
"{{ hash.keys|length }}") << dict << QStringLiteral(
"3")
1639 QTest::newRow(
"type-accessors-hash03")
1640 << QStringLiteral(
"{{ hash.values|length }}") << dict
1641 << QStringLiteral(
"3") << NoError;
1644 dict.insert(QStringLiteral(
"str1"), QStringLiteral(
"my string"));
1645 dict.insert(QStringLiteral(
"str2"), QStringLiteral(
"mystring"));
1647 QTest::newRow(
"type-accessors-string01")
1648 << QStringLiteral(
"{{ str1.capitalize }}") << dict
1649 << QStringLiteral(
"My string") << NoError;
1650 QTest::newRow(
"type-accessors-string02")
1651 << QStringLiteral(
"{{ str2.capitalize }}") << dict
1652 << QStringLiteral(
"Mystring") << NoError;
1655 dict.insert(QStringLiteral(
"str1"), QStringLiteral(
"de24335fre"));
1656 dict.insert(QStringLiteral(
"str2"), QStringLiteral(
"de435f3.-5r"));
1658 QTest::newRow(
"type-accessors-string03")
1659 << QStringLiteral(
"{{ str1.isalnum }}") << dict << QStringLiteral(
"True")
1661 QTest::newRow(
"type-accessors-string04")
1662 << QStringLiteral(
"{{ str2.isalnum }}") << dict << QStringLiteral(
"False")
1666 dict.insert(QStringLiteral(
"str1"), QStringLiteral(
"24335"));
1667 dict.insert(QStringLiteral(
"str2"), QStringLiteral(
"de435f35r"));
1668 dict.insert(QStringLiteral(
"str3"), QStringLiteral(
"de435f3.-5r"));
1670 QTest::newRow(
"type-accessors-string05")
1671 << QStringLiteral(
"{{ str1.isdigit }}") << dict << QStringLiteral(
"True")
1673 QTest::newRow(
"type-accessors-string06")
1674 << QStringLiteral(
"{{ str2.isdigit }}") << dict << QStringLiteral(
"False")
1676 QTest::newRow(
"type-accessors-string07")
1677 << QStringLiteral(
"{{ str3.isdigit }}") << dict << QStringLiteral(
"False")
1681 dict.insert(QStringLiteral(
"str"), QStringLiteral(
"MyString"));
1682 dict.insert(QStringLiteral(
"lowerStr"), QStringLiteral(
"mystring"));
1684 QTest::newRow(
"type-accessors-string08")
1685 << QStringLiteral(
"{{ str.islower }}") << dict << QStringLiteral(
"False")
1687 QTest::newRow(
"type-accessors-string09")
1688 << QStringLiteral(
"{{ lowerStr.islower }}") << dict
1689 << QStringLiteral(
"True") << NoError;
1692 dict.insert(QStringLiteral(
"str1"), QStringLiteral(
" "));
1693 dict.insert(QStringLiteral(
"str2"), QStringLiteral(
" r "));
1694 dict.insert(QStringLiteral(
"str3"), QStringLiteral(
" \t\nr "));
1695 dict.insert(QStringLiteral(
"str4"), QStringLiteral(
" \t\n "));
1697 QTest::newRow(
"type-accessors-string10")
1698 << QStringLiteral(
"{{ str1.isspace }}") << dict << QStringLiteral(
"True")
1700 QTest::newRow(
"type-accessors-string11")
1701 << QStringLiteral(
"{{ str2.isspace }}") << dict << QStringLiteral(
"False")
1703 QTest::newRow(
"type-accessors-string12")
1704 << QStringLiteral(
"{{ str3.isspace }}") << dict << QStringLiteral(
"False")
1706 QTest::newRow(
"type-accessors-string13")
1707 << QStringLiteral(
"{{ str4.isspace }}") << dict << QStringLiteral(
"True")
1711 dict.insert(QStringLiteral(
"str1"), QStringLiteral(
"My String"));
1712 dict.insert(QStringLiteral(
"str2"), QStringLiteral(
"Mystring"));
1713 dict.insert(QStringLiteral(
"str3"), QStringLiteral(
"My string"));
1714 dict.insert(QStringLiteral(
"str4"), QStringLiteral(
"my string"));
1716 QTest::newRow(
"type-accessors-string14")
1717 << QStringLiteral(
"{{ str1.istitle }}") << dict << QStringLiteral(
"True")
1719 QTest::newRow(
"type-accessors-string15")
1720 << QStringLiteral(
"{{ str2.istitle }}") << dict << QStringLiteral(
"True")
1722 QTest::newRow(
"type-accessors-string16")
1723 << QStringLiteral(
"{{ str3.istitle }}") << dict << QStringLiteral(
"False")
1725 QTest::newRow(
"type-accessors-string17")
1726 << QStringLiteral(
"{{ str4.istitle }}") << dict << QStringLiteral(
"False")
1730 dict.insert(QStringLiteral(
"str"), QStringLiteral(
"MyString"));
1731 dict.insert(QStringLiteral(
"upperStr"), QStringLiteral(
"MYSTRING"));
1733 QTest::newRow(
"type-accessors-string18")
1734 << QStringLiteral(
"{{ str.isupper }}") << dict << QStringLiteral(
"False")
1736 QTest::newRow(
"type-accessors-string19")
1737 << QStringLiteral(
"{{ upperStr.isupper }}") << dict
1738 << QStringLiteral(
"True") << NoError;
1741 dict.insert(QStringLiteral(
"str1"), QStringLiteral(
"My String"));
1742 dict.insert(QStringLiteral(
"str2"), QStringLiteral(
"MYSTRING"));
1743 dict.insert(QStringLiteral(
"str3"), QStringLiteral(
"MY STRING"));
1745 QTest::newRow(
"type-accessors-string20")
1746 << QStringLiteral(
"{{ str1.lower }}") << dict
1747 << QStringLiteral(
"my string") << NoError;
1748 QTest::newRow(
"type-accessors-string21")
1749 << QStringLiteral(
"{{ str2.lower }}") << dict
1750 << QStringLiteral(
"mystring") << NoError;
1751 QTest::newRow(
"type-accessors-string22")
1752 << QStringLiteral(
"{{ str3.lower }}") << dict
1753 << QStringLiteral(
"my string") << NoError;
1756 dict.insert(QStringLiteral(
"str"), QStringLiteral(
"one\ntwo three\nfour"));
1758 QTest::newRow(
"type-accessors-string23")
1760 "{% for line in str.splitlines %}{{ line }};{% endfor %}")
1761 << dict << QStringLiteral(
"one;two three;four;") << NoError;
1764 dict.insert(QStringLiteral(
"str1"), QStringLiteral(
" one"));
1765 dict.insert(QStringLiteral(
"str2"), QStringLiteral(
" one "));
1766 dict.insert(QStringLiteral(
"str3"), QStringLiteral(
"one "));
1767 dict.insert(QStringLiteral(
"str4"), QStringLiteral(
" "));
1768 dict.insert(QStringLiteral(
"str5"), QStringLiteral(
""));
1770 QTest::newRow(
"type-accessors-string24")
1771 << QStringLiteral(
"{{ str1.strip }}") << dict << QStringLiteral(
"one")
1773 QTest::newRow(
"type-accessors-string25")
1774 << QStringLiteral(
"{{ str2.strip }}") << dict << QStringLiteral(
"one")
1776 QTest::newRow(
"type-accessors-string26")
1777 << QStringLiteral(
"{{ str3.strip }}") << dict << QStringLiteral(
"one")
1779 QTest::newRow(
"type-accessors-string27")
1780 << QStringLiteral(
"{{ str4.strip }}") << dict <<
QString() << NoError;
1781 QTest::newRow(
"type-accessors-string28")
1782 << QStringLiteral(
"{{ str5.strip }}") << dict <<
QString() << NoError;
1785 dict.insert(QStringLiteral(
"str1"), QStringLiteral(
"My String"));
1786 dict.insert(QStringLiteral(
"str2"), QStringLiteral(
"mY sTRING"));
1787 dict.insert(QStringLiteral(
"str3"), QStringLiteral(
"My StrInG"));
1788 dict.insert(QStringLiteral(
"str4"), QStringLiteral(
"my string"));
1789 dict.insert(QStringLiteral(
"str5"), QStringLiteral(
"MY STRING"));
1792 QTest::newRow(
"type-accessors-string29")
1793 << QStringLiteral(
"{{ str1.swapcase }}") << dict
1794 << QStringLiteral(
"mY sTRING") << NoError;
1795 QTest::newRow(
"type-accessors-string30")
1796 << QStringLiteral(
"{{ str2.swapcase }}") << dict
1797 << QStringLiteral(
"My String") << NoError;
1798 QTest::newRow(
"type-accessors-string31")
1799 << QStringLiteral(
"{{ str3.swapcase }}") << dict
1800 << QStringLiteral(
"mY sTRiNg") << NoError;
1801 QTest::newRow(
"type-accessors-string32")
1802 << QStringLiteral(
"{{ str4.swapcase }}") << dict
1803 << QStringLiteral(
"MY STRING") << NoError;
1804 QTest::newRow(
"type-accessors-string33")
1805 << QStringLiteral(
"{{ str5.swapcase }}") << dict
1806 << QStringLiteral(
"my string") << NoError;
1809 dict.insert(QStringLiteral(
"str1"), QStringLiteral(
"My String"));
1810 dict.insert(QStringLiteral(
"str2"), QStringLiteral(
"mystring"));
1811 dict.insert(QStringLiteral(
"str3"), QStringLiteral(
"my string"));
1812 dict.insert(QStringLiteral(
"str4"), QStringLiteral(
"my String"));
1813 dict.insert(QStringLiteral(
"str5"), QStringLiteral(
"My string"));
1814 dict.insert(QStringLiteral(
"str6"), QStringLiteral(
"123"));
1815 dict.insert(QStringLiteral(
"str7"),
QString());
1817 QTest::newRow(
"type-accessors-string34")
1818 << QStringLiteral(
"{{ str1.title }}") << dict
1819 << QStringLiteral(
"My String") << NoError;
1820 QTest::newRow(
"type-accessors-string35")
1821 << QStringLiteral(
"{{ str2.title }}") << dict
1822 << QStringLiteral(
"Mystring") << NoError;
1823 QTest::newRow(
"type-accessors-string36")
1824 << QStringLiteral(
"{{ str3.title }}") << dict
1825 << QStringLiteral(
"My String") << NoError;
1826 QTest::newRow(
"type-accessors-string37")
1827 << QStringLiteral(
"{{ str4.title }}") << dict
1828 << QStringLiteral(
"My String") << NoError;
1829 QTest::newRow(
"type-accessors-string38")
1830 << QStringLiteral(
"{{ str5.title }}") << dict
1831 << QStringLiteral(
"My String") << NoError;
1833 QTest::newRow(
"type-accessors-string39")
1834 << QStringLiteral(
"{{ str1.upper }}") << dict
1835 << QStringLiteral(
"MY STRING") << NoError;
1836 QTest::newRow(
"type-accessors-string40")
1837 << QStringLiteral(
"{{ str2.upper }}") << dict
1838 << QStringLiteral(
"MYSTRING") << NoError;
1839 QTest::newRow(
"type-accessors-string41")
1840 << QStringLiteral(
"{{ str3.upper }}") << dict
1841 << QStringLiteral(
"MY STRING") << NoError;
1842 QTest::newRow(
"type-accessors-string42")
1843 << QStringLiteral(
"{{ str3.dne }}") << dict <<
QString() << NoError;
1844 QTest::newRow(
"type-accessors-string43")
1845 << QStringLiteral(
"{{ str2.isalpha }}") << dict << QStringLiteral(
"True")
1847 QTest::newRow(
"type-accessors-string44")
1848 << QStringLiteral(
"{{ str3.isalpha }}") << dict << QStringLiteral(
"False")
1850 QTest::newRow(
"type-accessors-string45")
1851 << QStringLiteral(
"{{ str6.isalpha }}") << dict << QStringLiteral(
"False")
1853 QTest::newRow(
"type-accessors-string46")
1854 << QStringLiteral(
"{{ str7.isalpha }}") << dict << QStringLiteral(
"False")
1859 #define SON(obj) obj->setObjectName(QStringLiteral(#obj))
1861 auto obj1 =
new QObject(
this);
1863 auto obj2 =
new QObject(
this);
1865 obj2->setParent(obj1);
1866 auto obj3 =
new QObject(
this);
1867 obj3->setParent(obj2);
1869 auto obj4 =
new QObject(
this);
1870 obj4->setParent(obj2);
1873 dict.insert(QStringLiteral(
"object"), QVariant::fromValue(obj1));
1875 QTest::newRow(
"type-accessors-qobject01")
1876 << QStringLiteral(
"{{ object.objectName }}") << dict
1877 << QStringLiteral(
"obj1") << NoError;
1879 const QLatin1String objectDumper(
"<li>{{ object.objectName }}</li>"
1880 "{% if object.children %}"
1882 "{% for object in object.children %}"
1883 "{% include 'objectdumper.html' %}"
1888 m_loader->setTemplate(QStringLiteral(
"objectdumper.html"), objectDumper);
1890 QTest::newRow(
"type-accessors-qobject02")
1891 << QStringLiteral(
"<ul>{% include 'objectdumper.html' %}</ul>") << dict
1892 << QString::fromLatin1(
"<ul>"
1905 void TestBuiltinSyntax::testDynamicProperties_data()
1907 QTest::addColumn<QString>(
"input");
1908 QTest::addColumn<Dict>(
"dict");
1909 QTest::addColumn<QString>(
"output");
1910 QTest::addColumn<Cutelee::Error>(
"error");
1914 auto obj =
new QObject(
this);
1915 obj->setProperty(
"prop", 7);
1916 dict.insert(QStringLiteral(
"var"),
1917 QVariant::fromValue(
static_cast<QObject *
>(obj)));
1919 QTest::newRow(
"dynamic-properties01")
1920 << QStringLiteral(
"{{ var.prop }}") << dict << QStringLiteral(
"7")
1924 void TestBuiltinSyntax::testGarbageInput()
1928 auto t = m_engine->newTemplate(input, QLatin1String(QTest::currentDataTag()));
1934 auto result = t->
render(&context);
1936 QCOMPARE(t->
error(), NoError);
1938 QCOMPARE(result, input);
1941 void TestBuiltinSyntax::testGarbageInput_data()
1944 QTest::addColumn<QString>(
"input");
1946 QTest::newRow(
"garbage-input01") << QStringLiteral(
"content %}");
1947 QTest::newRow(
"garbage-input02") << QStringLiteral(
" content %}");
1948 QTest::newRow(
"garbage-input03") << QStringLiteral(
"content #}");
1949 QTest::newRow(
"garbage-input04") << QStringLiteral(
" content #}");
1950 QTest::newRow(
"garbage-input05") << QStringLiteral(
"content }}");
1951 QTest::newRow(
"garbage-input06") << QStringLiteral(
" content }}");
1952 QTest::newRow(
"garbage-input07") << QStringLiteral(
"% content %}");
1953 QTest::newRow(
"garbage-input08") << QStringLiteral(
"# content #}");
1954 QTest::newRow(
"garbage-input09") << QStringLiteral(
"{ content }}");
1955 QTest::newRow(
"garbage-input10") << QStringLiteral(
"{% content }");
1956 QTest::newRow(
"garbage-input11") << QStringLiteral(
"{% content %");
1957 QTest::newRow(
"garbage-input12") << QStringLiteral(
"{# content }");
1958 QTest::newRow(
"garbage-input13") << QStringLiteral(
"{# content #");
1959 QTest::newRow(
"garbage-input14") << QStringLiteral(
"{{ content }");
1960 QTest::newRow(
"garbage-input15") << QStringLiteral(
"{{ content }");
1961 QTest::newRow(
"garbage-input16") << QStringLiteral(
"{{ content %}");
1962 QTest::newRow(
"garbage-input17") << QStringLiteral(
"{% content }}");
1963 QTest::newRow(
"garbage-input18") << QStringLiteral(
"{{ content #}");
1964 QTest::newRow(
"garbage-input19") << QStringLiteral(
"{# content }}");
1965 QTest::newRow(
"garbage-input20") << QStringLiteral(
"{{ con #} tent #}");
1966 QTest::newRow(
"garbage-input21") << QStringLiteral(
"{{ con %} tent #}");
1967 QTest::newRow(
"garbage-input22") << QStringLiteral(
"{{ con #} tent %}");
1968 QTest::newRow(
"garbage-input23") << QStringLiteral(
"{{ con %} tent %}");
1969 QTest::newRow(
"garbage-input24") << QStringLiteral(
"{% con #} tent #}");
1970 QTest::newRow(
"garbage-input25") << QStringLiteral(
"{% con }} tent #}");
1971 QTest::newRow(
"garbage-input26") << QStringLiteral(
"{% con #} tent }}");
1972 QTest::newRow(
"garbage-input27") << QStringLiteral(
"{% con }} tent }}");
1973 QTest::newRow(
"garbage-input28") << QStringLiteral(
"{# con %} tent %}");
1974 QTest::newRow(
"garbage-input29") << QStringLiteral(
"{# con }} tent %}");
1975 QTest::newRow(
"garbage-input30") << QStringLiteral(
"{# con %} tent }}");
1976 QTest::newRow(
"garbage-input31") << QStringLiteral(
"{# con }} tent }}");
1977 QTest::newRow(
"garbage-input32") << QStringLiteral(
"{# con {# tent }}");
1978 QTest::newRow(
"garbage-input33") << QStringLiteral(
"{# con {% tent }}");
1979 QTest::newRow(
"garbage-input34") << QStringLiteral(
"{% con {% tent }}");
1980 QTest::newRow(
"garbage-input35") << QStringLiteral(
"{ { content }}");
1981 QTest::newRow(
"garbage-input36") << QStringLiteral(
"{ % content %}");
1982 QTest::newRow(
"garbage-input37") << QStringLiteral(
"{ # content #}");
1983 QTest::newRow(
"garbage-input38") << QStringLiteral(
"{\n{ content }}");
1984 QTest::newRow(
"garbage-input39") << QStringLiteral(
"{\n# content #}");
1985 QTest::newRow(
"garbage-input40") << QStringLiteral(
"{\n% content %}");
1986 QTest::newRow(
"garbage-input41") << QStringLiteral(
"{{\n content }}");
1987 QTest::newRow(
"garbage-input42") << QStringLiteral(
"{#\n content #}");
1988 QTest::newRow(
"garbage-input43") << QStringLiteral(
"{%\n content %}");
1989 QTest::newRow(
"garbage-input44") << QStringLiteral(
"{{ content \n}}");
1990 QTest::newRow(
"garbage-input45") << QStringLiteral(
"{# content \n#}");
1991 QTest::newRow(
"garbage-input46") << QStringLiteral(
"{% content \n%}");
1992 QTest::newRow(
"garbage-input47") << QStringLiteral(
"{{ content }\n}");
1993 QTest::newRow(
"garbage-input48") << QStringLiteral(
"{# content #\n}");
1994 QTest::newRow(
"garbage-input49") << QStringLiteral(
"{% content %\n}");
1995 QTest::newRow(
"garbage-input50") << QStringLiteral(
"{{ content } }");
1996 QTest::newRow(
"garbage-input51") << QStringLiteral(
"{% content % }");
1997 QTest::newRow(
"garbage-input52") << QStringLiteral(
"{# content # }");
1998 QTest::newRow(
"garbage-input53") << QStringLiteral(
"{ { content } }");
1999 QTest::newRow(
"garbage-input54") << QStringLiteral(
"{ % content % }");
2000 QTest::newRow(
"garbage-input55") << QStringLiteral(
"{ # content # }");
2001 QTest::newRow(
"garbage-input56") << QStringLiteral(
"{{ content }%");
2002 QTest::newRow(
"garbage-input57") << QStringLiteral(
"{# content #%");
2003 QTest::newRow(
"garbage-input58") << QStringLiteral(
"{% content %%");
2004 QTest::newRow(
"garbage-input59") << QStringLiteral(
"{{ content }A");
2005 QTest::newRow(
"garbage-input60") << QStringLiteral(
"{# content #A");
2006 QTest::newRow(
"garbage-input61") << QStringLiteral(
"{% content %A");
2007 QTest::newRow(
"garbage-input62") << QStringLiteral(
"{{ content A}");
2008 QTest::newRow(
"garbage-input63") << QStringLiteral(
"{# content A#");
2009 QTest::newRow(
"garbage-input64") << QStringLiteral(
"{% content A%");
2010 QTest::newRow(
"garbage-input65") << QStringLiteral(
"{# content A}");
2011 QTest::newRow(
"garbage-input66") << QStringLiteral(
"{% content A}");
2012 QTest::newRow(
"garbage-input67") << QStringLiteral(
"A{ content }}");
2013 QTest::newRow(
"garbage-input68") << QStringLiteral(
"A# content #}");
2014 QTest::newRow(
"garbage-input69") << QStringLiteral(
"A% content %}");
2015 QTest::newRow(
"garbage-input60") << QStringLiteral(
"{A content }}");
2016 QTest::newRow(
"garbage-input71") << QStringLiteral(
"{A content #}");
2017 QTest::newRow(
"garbage-input72") << QStringLiteral(
"{A content %}");
2018 QTest::newRow(
"garbage-input73") << QStringLiteral(
"{A content #}");
2019 QTest::newRow(
"garbage-input74") << QStringLiteral(
"{A content %}");
2020 QTest::newRow(
"garbage-input75") << QStringLiteral(
"{A content A}");
2021 QTest::newRow(
"garbage-input76") << QStringLiteral(
"}} content }}");
2022 QTest::newRow(
"garbage-input77") << QStringLiteral(
"}} content {{");
2023 QTest::newRow(
"garbage-input78") << QStringLiteral(
"#} content #}");
2024 QTest::newRow(
"garbage-input79") << QStringLiteral(
"#} content {#");
2025 QTest::newRow(
"garbage-input80") << QStringLiteral(
"%} content %}");
2026 QTest::newRow(
"garbage-input81") << QStringLiteral(
"%} content {%");
2027 QTest::newRow(
"garbage-input82") << QStringLiteral(
"#{ content }#");
2028 QTest::newRow(
"garbage-input83") << QStringLiteral(
"%{ content }%");
2031 void TestBuiltinSyntax::testInsignificantWhitespace()
2035 QFETCH(
QString, stripped_output);
2036 QFETCH(
QString, unstripped_output);
2040 QVERIFY(!m_engine->smartTrimEnabled());
2041 m_engine->setSmartTrimEnabled(
true);
2042 QVERIFY(m_engine->smartTrimEnabled());
2046 = m_engine->newTemplate(input, QLatin1String(QTest::currentDataTag()));
2048 auto result = t->
render(&context);
2050 QCOMPARE(t->
error(), NoError);
2052 QCOMPARE(result, stripped_output);
2054 m_engine->setSmartTrimEnabled(
false);
2057 = m_engine->newTemplate(input, QLatin1String(QTest::currentDataTag()));
2059 auto result = t->
render(&context);
2061 QCOMPARE(t->
error(), NoError);
2063 QCOMPARE(result, unstripped_output);
2067 void TestBuiltinSyntax::testInsignificantWhitespace_data()
2069 QTest::addColumn<QString>(
"input");
2070 QTest::addColumn<Dict>(
"dict");
2071 QTest::addColumn<QString>(
"stripped_output");
2072 QTest::addColumn<QString>(
"unstripped_output");
2076 QTest::newRow(
"insignificant-whitespace01")
2077 << QStringLiteral(
"\n {% templatetag openblock %}\n") << dict
2078 << QStringLiteral(
"{%\n") << QStringLiteral(
"\n {%\n");
2080 QTest::newRow(
"insignificant-whitespace02")
2081 << QStringLiteral(
"\n{% templatetag openblock %}\n") << dict
2082 << QStringLiteral(
"{%\n") << QStringLiteral(
"\n{%\n");
2084 QTest::newRow(
"insignificant-whitespace03")
2085 << QStringLiteral(
"{% templatetag openblock %}\n") << dict
2086 << QStringLiteral(
"{%\n") << QStringLiteral(
"{%\n");
2088 QTest::newRow(
"insignificant-whitespace04")
2089 << QStringLiteral(
"\n\t \t {% templatetag openblock %}\n") << dict
2090 << QStringLiteral(
"{%\n") << QStringLiteral(
"\n\t \t {%\n");
2093 QTest::newRow(
"insignificant-whitespace05")
2094 << QStringLiteral(
"\n some\ttext {% templatetag openblock %}\n") << dict
2095 << QStringLiteral(
"\n some\ttext {%\n")
2096 << QStringLiteral(
"\n some\ttext {%\n");
2099 QTest::newRow(
"insignificant-whitespace06")
2100 << QStringLiteral(
"\n some\ttext\n {% templatetag openblock %}\n") << dict
2101 << QStringLiteral(
"\n some\ttext{%\n")
2102 << QStringLiteral(
"\n some\ttext\n {%\n");
2103 QTest::newRow(
"insignificant-whitespace07")
2104 << QStringLiteral(
"\n some\ttext \n \t {% templatetag openblock %}\n")
2105 << dict << QStringLiteral(
"\n some\ttext {%\n")
2106 << QStringLiteral(
"\n some\ttext \n \t {%\n");
2109 QTest::newRow(
"insignificant-whitespace08")
2110 << QStringLiteral(
"\n some\ttext \t \n {% templatetag openblock %}\n")
2111 << dict << QStringLiteral(
"\n some\ttext \t {%\n")
2112 << QStringLiteral(
"\n some\ttext \t \n {%\n");
2115 QTest::newRow(
"insignificant-whitespace09")
2116 << QStringLiteral(
"\n some\ntext \t \n {% templatetag openblock %}\n")
2117 << dict << QStringLiteral(
"\n some\ntext \t {%\n")
2118 << QStringLiteral(
"\n some\ntext \t \n {%\n");
2119 QTest::newRow(
"insignificant-whitespace10")
2121 "\n some \t \n \t text \t \n {% templatetag openblock %}\n")
2122 << dict << QStringLiteral(
"\n some \t \n \t text \t {%\n")
2123 << QStringLiteral(
"\n some \t \n \t text \t \n {%\n");
2126 QTest::newRow(
"insignificant-whitespace11")
2127 << QStringLiteral(
"\n \t {% templatetag openblock %} some text\n")
2128 << dict << QStringLiteral(
"\n \t {% some text\n")
2129 << QStringLiteral(
"\n \t {% some text\n");
2132 QTest::newRow(
"insignificant-whitespace12")
2133 << QStringLiteral(
"\n \t {% templatetag openblock %} some text \t \n")
2134 << dict << QStringLiteral(
"\n \t {% some text \t \n")
2135 << QStringLiteral(
"\n \t {% some text \t \n");
2138 QTest::newRow(
"insignificant-whitespace13")
2140 "\n \t {% templatetag openblock %} \t \n \t some text \t \n")
2141 << dict << QStringLiteral(
"{% \t \n \t some text \t \n")
2142 << QStringLiteral(
"\n \t {% \t \n \t some text \t \n");
2145 QTest::newRow(
"insignificant-whitespace14")
2146 << QStringLiteral(
"\n\n\n{% templatetag openblock %}\n some text\n")
2147 << dict << QStringLiteral(
"\n\n{%\n some text\n")
2148 << QStringLiteral(
"\n\n\n{%\n some text\n");
2151 QTest::newRow(
"insignificant-whitespace15")
2153 "\n\n\n{% templatetag openblock %}\t \t \t\n some text\n")
2154 << dict << QStringLiteral(
"\n\n{%\t \t \t\n some text\n")
2155 << QStringLiteral(
"\n\n\n{%\t \t \t\n some text\n");
2158 QTest::newRow(
"insignificant-whitespace16")
2160 "\n\n\n\t \t \t{% templatetag openblock %}\n some text\n")
2161 << dict << QStringLiteral(
"\n\n{%\n some text\n")
2162 << QStringLiteral(
"\n\n\n\t \t \t{%\n some text\n");
2165 QTest::newRow(
"insignificant-whitespace17")
2167 "\n\n\n\t \t \t{% templatetag openblock %}\t \t \t\n some text\n")
2168 << dict << QStringLiteral(
"\n\n{%\t \t \t\n some text\n")
2169 << QStringLiteral(
"\n\n\n\t \t \t{%\t \t \t\n some text\n");
2172 QTest::newRow(
"insignificant-whitespace18")
2173 << QStringLiteral(
"\n{% templatetag openblock %}\n\n\n some text\n")
2174 << dict << QStringLiteral(
"{%\n\n\n some text\n")
2175 << QStringLiteral(
"\n{%\n\n\n some text\n");
2176 QTest::newRow(
"insignificant-whitespace19")
2177 << QStringLiteral(
"\n{% templatetag openblock %}\t \n\n\n some text\n")
2178 << dict << QStringLiteral(
"{%\t \n\n\n some text\n")
2179 << QStringLiteral(
"\n{%\t \n\n\n some text\n");
2182 QTest::newRow(
"insignificant-whitespace20")
2184 "\n{% templatetag openblock %}\n{% templatetag openblock %}\n{% "
2185 "templatetag openblock %}\n some text\n")
2186 << dict << QStringLiteral(
"{%{%{%\n some text\n")
2187 << QStringLiteral(
"\n{%\n{%\n{%\n some text\n");
2191 QTest::newRow(
"insignificant-whitespace21")
2193 "\n\n{% templatetag openblock %}\n\n{% templatetag openblock "
2194 "%}\n\n{% templatetag openblock %}\n\n some text\n")
2195 << dict << QStringLiteral(
"\n{%\n{%\n{%\n\n some text\n")
2196 << QStringLiteral(
"\n\n{%\n\n{%\n\n{%\n\n some text\n");
2200 QTest::newRow(
"insignificant-whitespace22")
2201 << QStringLiteral(
"\n\n\t {% templatetag openblock %}\t \n\n\t {% "
2202 "templatetag openblock %}\t \n\n\t {% templatetag "
2203 "openblock %}\t \n some text\n")
2204 << dict << QStringLiteral(
"\n{%\t \n{%\t \n{%\t \n some text\n")
2205 << QStringLiteral(
"\n\n\t {%\t \n\n\t {%\t \n\n\t {%\t \n some text\n");
2209 QTest::newRow(
"insignificant-whitespace23")
2211 "\n\t {% templatetag openblock %}\t \n\t {% templatetag openblock "
2212 "%}\t \n\t {% templatetag openblock %}\t \n some text\n")
2213 << dict << QStringLiteral(
"{%\t {%\t {%\t \n some text\n")
2214 << QStringLiteral(
"\n\t {%\t \n\t {%\t \n\t {%\t \n some text\n");
2220 QTest::newRow(
"insignificant-whitespace24")
2222 "\n\t {% templatetag openblock %}\t \t {% templatetag openblock "
2223 "%}\t \t {% templatetag openblock %}\t \n some text\n")
2224 << dict << QStringLiteral(
"\n\t {%\t \t {%\t \t {%\t \n some text\n")
2225 << QStringLiteral(
"\n\t {%\t \t {%\t \t {%\t \n some text\n");
2228 QTest::newRow(
"insignificant-whitespace25")
2230 "\n\n {% templatetag openblock %}\n \t {% templatetag openblock "
2231 "%}\n \t {% templatetag openblock %}\n some text\n")
2232 << dict << QStringLiteral(
"\n{%{%{%\n some text\n")
2233 << QStringLiteral(
"\n\n {%\n \t {%\n \t {%\n some text\n");
2236 QTest::newRow(
"insignificant-whitespace26")
2237 << QStringLiteral(
"\n\n {% templatetag openblock %}\n \t {# some comment "
2239 << dict << QStringLiteral(
"\n{%\n some text\n")
2240 << QStringLiteral(
"\n\n {%\n \t \n some text\n");
2243 QTest::newRow(
"insignificant-whitespace27")
2245 "\n\n {# a comment #}\n \t {# some comment #}\n some text\n")
2246 << dict << QStringLiteral(
"\n\n some text\n")
2247 << QStringLiteral(
"\n\n \n \t \n some text\n");
2250 QTest::newRow(
"insignificant-whitespace28")
2252 "\n\t {% templatetag openblock %}\t \n\t {# some comment #}\t "
2253 "\n\t {% templatetag openblock %}\t \n some text\n")
2254 << dict << QStringLiteral(
"{%\t \t {%\t \n some text\n")
2255 << QStringLiteral(
"\n\t {%\t \n\t \t \n\t {%\t \n some text\n");
2257 dict.insert(QStringLiteral(
"spam"), QStringLiteral(
"ham"));
2259 QTest::newRow(
"insignificant-whitespace29")
2260 << QStringLiteral(
"\n {% templatetag openblock %}\t\n \t {{ spam }}\t \n "
2261 "\t {% templatetag openblock %}\t \n some text\n")
2262 << dict << QStringLiteral(
"{%\tham\t {%\t \n some text\n")
2263 << QStringLiteral(
"\n {%\t\n \t ham\t \n \t {%\t \n some text\n");
2264 QTest::newRow(
"insignificant-whitespace30")
2266 "\n\n {% templatetag openblock %}\t\n\n \t {{ spam }}\t \n\n \t "
2267 "{% templatetag openblock %}\t \n some text\n")
2268 << dict << QStringLiteral(
"\n{%\t\nham\t \n{%\t \n some text\n")
2269 << QStringLiteral(
"\n\n {%\t\n\n \t ham\t \n\n \t {%\t \n some text\n");
2273 QTest::newRow(
"insignificant-whitespace31")
2274 << QStringLiteral(
"\n {% templatetag openblock %}\t \t {{ spam }}\t \t "
2275 "{% templatetag openblock %}\t \n some text\n")
2276 << dict << QStringLiteral(
"\n {%\t \t ham\t \t {%\t \n some text\n")
2277 << QStringLiteral(
"\n {%\t \t ham\t \t {%\t \n some text\n");
2280 QTest::newRow(
"insignificant-whitespace32")
2281 << QStringLiteral(
"\n {{ spam }}\t\n \t {% templatetag openblock %}\t \n "
2282 "\t {{ spam }}\t \n some text\n")
2283 << dict << QStringLiteral(
"ham\t{%\t ham\t \n some text\n")
2284 << QStringLiteral(
"\n ham\t\n \t {%\t \n \t ham\t \n some text\n");
2289 QTest::newRow(
"insignificant-whitespace33")
2291 "\n\n {# \n{% templatetag openblock #}\t \n some text\n")
2294 "\n\n {# \n{% templatetag openblock #}\t \n some text\n")
2296 "\n\n {# \n{% templatetag openblock #}\t \n some text\n");
2299 QTest::newRow(
"insignificant-whitespace34")
2301 "\n\n {# \n{# templatetag openblock #}\t \n some text\n")
2302 << dict << QStringLiteral(
"\n\n {# \t \n some text\n")
2303 << QStringLiteral(
"\n\n {# \n\t \n some text\n");
2304 QTest::newRow(
"insignificant-whitespace35")
2306 "\n\n {# \n{# templatetag openblock\n #}\t \n some text\n")
2309 "\n\n {# \n{# templatetag openblock\n #}\t \n some text\n")
2311 "\n\n {# \n{# templatetag openblock\n #}\t \n some text\n");
2312 QTest::newRow(
"insignificant-whitespace36")
2313 << QStringLiteral(
"\n\n {# \n{{ some comment #}\t \n some text\n") << dict
2314 << QStringLiteral(
"\n\n {# \n{{ some comment #}\t \n some text\n")
2315 << QStringLiteral(
"\n\n {# \n{{ some comment #}\t \n some text\n");
2316 QTest::newRow(
"insignificant-whitespace37")
2318 "\n\n {# \n \t {% templatetag openblock #}\t \n some text\n")
2321 "\n\n {# \n \t {% templatetag openblock #}\t \n some text\n")
2323 "\n\n {# \n \t {% templatetag openblock #}\t \n some text\n");
2324 QTest::newRow(
"insignificant-whitespace38")
2325 << QStringLiteral(
"\n\n {# templatetag openblock #\n}\t \n some text\n")
2327 << QStringLiteral(
"\n\n {# templatetag openblock #\n}\t \n some text\n")
2328 << QStringLiteral(
"\n\n {# templatetag openblock #\n}\t \n some text\n");
2329 QTest::newRow(
"insignificant-whitespace39")
2330 << QStringLiteral(
"\n\n {% templatetag openblock %\n}\t \n some text\n")
2332 << QStringLiteral(
"\n\n {% templatetag openblock %\n}\t \n some text\n")
2333 << QStringLiteral(
"\n\n {% templatetag openblock %\n}\t \n some text\n");
2334 QTest::newRow(
"insignificant-whitespace40")
2335 << QStringLiteral(
"\n\n {{ templatetag openblock }\n}\t \n some text\n")
2337 << QStringLiteral(
"\n\n {{ templatetag openblock }\n}\t \n some text\n")
2338 << QStringLiteral(
"\n\n {{ templatetag openblock }\n}\t \n some text\n");
2339 QTest::newRow(
"insignificant-whitespace41")
2341 "\n\n {\n# {# templatetag openblock #}\t \n some text\n")
2342 << dict << QStringLiteral(
"\n\n {\n# \t \n some text\n")
2343 << QStringLiteral(
"\n\n {\n# \t \n some text\n");
2344 QTest::newRow(
"insignificant-whitespace42")
2345 << QStringLiteral(
"\n\n {\n {# templatetag openblock #}\t \n some text\n")
2346 << dict << QStringLiteral(
"\n\n {\t \n some text\n")
2347 << QStringLiteral(
"\n\n {\n \t \n some text\n");
2348 QTest::newRow(
"insignificant-whitespace43")
2349 << QStringLiteral(
"\n{{# foo #};{# bar #}\n") << dict
2350 << QStringLiteral(
"\n{;\n") << QStringLiteral(
"\n{;\n");
2352 QTest::newRow(
"insignificant-whitespace44")
2353 << QStringLiteral(
"\n{{ foo }} ") << dict <<
QString()
2354 << QStringLiteral(
"\n ");
2358 #include "testbuiltins.moc"
Implements a loader decorator which caches compiled Template objects.
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.
Template loadByName(const QString &name) const
void setPluginPaths(const QStringList &dirs)
void addTemplateLoader(std::shared_ptr< AbstractTemplateLoader > loader)
The FileSystemTemplateLoader loads Templates from the file system.
A FilterExpression object represents a filter expression in a template.
The InMemoryTemplateLoader loads Templates set dynamically in memory.
The OutputStream class is used to render templates to a QTextStream.
A QString wrapper class for containing whether a string is safe or needs to be escaped.
The Template class is a tree of nodes which may be rendered.
QString errorString() const
QString render(Context *c) const
A container for static variables defined in Templates.
bool isTrue(Context *c) const
std::shared_ptr< OutputStream > clone(QTextStream *stream) const override
QString escape(const QString &input) const override
std::shared_ptr< OutputStream > clone(QTextStream *stream) const override
QString escape(const QString &input) const override
The Cutelee namespace holds all public Cutelee API.
bool variantIsTrue(const QVariant &variant)
Utility functions used throughout Cutelee.