21 #ifndef LOADERTAGSTEST_H
22 #define LOADERTAGSTEST_H
24 #include <QtCore/QDebug>
25 #include <QtCore/QDir>
26 #include <QtCore/QFileInfo>
27 #include <QtTest/QTest>
30 #include "coverageobject.h"
32 #include "cutelee_paths.h"
35 typedef QHash<QString, QVariant> Dict;
47 void cleanupTestCase();
49 void testTemplateFromQrc();
51 void testIncludeTag_data();
52 void testIncludeTag() { doTest(); }
54 void testExtendsTag_data();
55 void testExtendsTag() { doTest(); }
57 void testIncludeAndExtendsTag_data();
58 void testIncludeAndExtendsTag() { doTest(); }
60 void testBlockTagErrors_data();
61 void testBlockTagErrors() { doTest(); }
66 std::shared_ptr<InMemoryTemplateLoader> loader;
70 void TestLoaderTags::initTestCase()
72 Q_INIT_RESOURCE(testresource);
74 m_engine =
new Engine(
this);
77 m_engine->addTemplateLoader(loader);
79 m_engine->setPluginPaths({
80 QStringLiteral(CUTELEE_PLUGIN_PATH),
81 QStringLiteral(
":/plugins/")
84 m_engine->addDefaultLibrary(QStringLiteral(
"cutelee_scriptabletags"));
88 void TestLoaderTags::cleanupTestCase() {
delete m_engine; }
90 void TestLoaderTags::testTemplateFromQrc()
95 loader->setTemplateDirs({QStringLiteral(
":/templates/")});
99 auto t = engine.
loadByName(QStringLiteral(
"resourcetemplate1.html"));
101 if (t->error() != NoError) {
103 QCOMPARE(t->error(), NoError);
108 context.
insert(QStringLiteral(
"numbertwo"), QStringLiteral(
"two"));
109 context.
insert(QStringLiteral(
"numberfour"), QStringLiteral(
"four"));
111 auto result = t->render(&context);
113 if (t->error() != NoError) {
114 qDebug() << t->errorString();
115 QCOMPARE(t->error(), NoError);
119 QCOMPARE(result, QStringLiteral(
"one-two-three-four\n\n"));
122 void TestLoaderTags::doTest()
129 auto t = m_engine->newTemplate(input, QLatin1String(QTest::currentDataTag()));
131 if (t->error() != NoError) {
132 if (t->error() != error)
133 qDebug() << t->errorString();
134 QCOMPARE(t->error(), error);
140 auto result = t->render(&context);
142 if (t->error() != NoError) {
143 if (t->error() != error)
144 qDebug() << t->errorString();
145 QCOMPARE(t->error(), error);
150 QCOMPARE(NoError, error);
152 QCOMPARE(t->error(), NoError);
154 QCOMPARE(result, output);
157 void TestLoaderTags::testIncludeTag_data()
159 QTest::addColumn<QString>(
"input");
160 QTest::addColumn<Dict>(
"dict");
161 QTest::addColumn<QString>(
"output");
162 QTest::addColumn<Cutelee::Error>(
"error");
166 loader->setTemplate(QStringLiteral(
"basic-syntax01"),
167 QStringLiteral(
"Something cool"));
168 loader->setTemplate(QStringLiteral(
"basic-syntax02"),
169 QStringLiteral(
"{{ headline }}"));
171 QTest::newRow(
"include01") <<
"{% include \"basic-syntax01\" %}" << dict
172 << QStringLiteral(
"Something cool") << NoError;
174 dict.insert(QStringLiteral(
"headline"), QStringLiteral(
"Included"));
176 QTest::newRow(
"include02") <<
"{% include \"basic-syntax02\" %}" << dict
177 << QStringLiteral(
"Included") << NoError;
179 dict.insert(QStringLiteral(
"templateName"), QStringLiteral(
"basic-syntax02"));
181 QTest::newRow(
"include03") << QStringLiteral(
"{% include templateName %}")
182 << dict << QStringLiteral(
"Included") << NoError;
185 QTest::newRow(
"include04") <<
"a{% include \"nonexistent\" %}b" << dict
186 << QStringLiteral(
"ab") << TagSyntaxError;
188 auto incl05 = QStringLiteral(
"template with a space");
189 loader->setTemplate(QStringLiteral(
"include 05"), incl05);
191 QTest::newRow(
"include 05")
192 << incl05 << dict << QStringLiteral(
"template with a space") << NoError;
194 QTest::newRow(
"include06")
195 <<
"{% include \"include 05\" %}" << dict
196 << QStringLiteral(
"template with a space") << NoError;
200 QTest::newRow(
"include07")
201 <<
"{% for i in list %}{% include \"include 05\" %}{% endfor %}" << dict
202 << QStringLiteral(
"template with a spacetemplate with a space")
206 void TestLoaderTags::testExtendsTag_data()
208 QTest::addColumn<QString>(
"input");
209 QTest::addColumn<Dict>(
"dict");
210 QTest::addColumn<QString>(
"output");
211 QTest::addColumn<Cutelee::Error>(
"error");
215 QTest::newRow(
"namedendblocks01")
216 << QStringLiteral(
"1{% block first %}_{% block second %}2{% endblock "
217 "second %}_{% endblock first %}3")
218 << dict << QStringLiteral(
"1_2_3") << NoError;
220 QTest::newRow(
"namedendblocks02")
221 << QStringLiteral(
"1{% block first %}_{% block second %}2{% endblock "
222 "first %}_{% endblock second %}3")
223 << dict <<
QString() << InvalidBlockTagError;
224 QTest::newRow(
"namedendblocks03")
225 << QStringLiteral(
"1{% block first %}_{% block second %}2{% endblock "
226 "%}_{% endblock second %}3")
227 << dict <<
QString() << InvalidBlockTagError;
228 QTest::newRow(
"namedendblocks04")
229 << QStringLiteral(
"1{% block first %}_{% block second %}2{% endblock "
230 "second %}_{% endblock third %}3")
231 << dict <<
QString() << InvalidBlockTagError;
232 QTest::newRow(
"namedendblocks05")
234 "1{% block first %}_{% block second %}2{% endblock first %}")
235 << dict <<
QString() << InvalidBlockTagError;
237 QTest::newRow(
"namedendblocks06")
238 << QStringLiteral(
"1{% block first %}_{% block second %}2{% endblock "
239 "%}_{% endblock first %}3")
240 << dict << QStringLiteral(
"1_2_3") << NoError;
241 QTest::newRow(
"namedendblocks07")
242 << QStringLiteral(
"1{% block first %}_{% block second %}2{% endblock "
243 "second %}_{% endblock %}3")
244 << dict << QStringLiteral(
"1_2_3") << NoError;
249 auto inh1 = QStringLiteral(
250 "1{% block first %}&{% endblock %}3{% block second %}_{% endblock %}");
251 loader->setTemplate(QStringLiteral(
"inheritance01"), inh1);
253 QTest::newRow(
"inheritance01")
254 << inh1 << dict << QStringLiteral(
"1&3_") << NoError;
257 = QStringLiteral(
"{% extends \"inheritance01\" %}{% block first %}2{% "
258 "endblock %}{% block second %}4{% endblock %}");
259 loader->setTemplate(QStringLiteral(
"inheritance02"), inh2);
262 QTest::newRow(
"inheritance02")
263 << inh2 << dict << QStringLiteral(
"1234") << NoError;
265 QTest::newRow(
"inheritance03")
266 << QStringLiteral(
"{% extends 'inheritance02' %}") << dict
267 << QStringLiteral(
"1234") << NoError;
270 auto inh4 = QStringLiteral(
"{% extends \"inheritance01\" %}");
271 loader->setTemplate(QStringLiteral(
"inheritance04"), inh4);
273 QTest::newRow(
"inheritance04")
274 << inh4 << dict << QStringLiteral(
"1&3_") << NoError;
276 QTest::newRow(
"inheritance05") <<
"{% extends \"inheritance02\" %}" << dict
277 << QStringLiteral(
"1234") << NoError;
279 dict.insert(QStringLiteral(
"foo"), QStringLiteral(
"inheritance02"));
281 QTest::newRow(
"inheritance06") << QStringLiteral(
"{% extends foo %}") << dict
282 << QStringLiteral(
"1234") << NoError;
284 auto inh7 = QStringLiteral(
285 "{% extends 'inheritance01' %}{% block second %}5{% endblock %}");
286 loader->setTemplate(QStringLiteral(
"inheritance07"), inh7);
290 QTest::newRow(
"inheritance07")
291 << inh7 << dict << QStringLiteral(
"1&35") << NoError;
294 QTest::newRow(
"inheritance08") << QStringLiteral(
295 "{% extends 'inheritance02' %}{% block second %}5{% endblock %}")
296 << dict << QStringLiteral(
"1235") << NoError;
299 QTest::newRow(
"inheritance09")
300 << QStringLiteral(
"{% extends 'inheritance04' %}") << dict
301 << QStringLiteral(
"1&3_") << NoError;
306 QTest::newRow(
"inheritance10")
307 << QStringLiteral(
"{% extends 'inheritance04' %} ") << dict
308 << QStringLiteral(
"1&3_") << NoError;
311 QTest::newRow(
"inheritance11")
312 << QStringLiteral(
"{% extends 'inheritance04' %}{% block first %}2{% "
313 "endblock %}{% block second %}4{% endblock %}")
314 << dict << QStringLiteral(
"1234") << NoError;
317 QTest::newRow(
"inheritance12") << QStringLiteral(
318 "{% extends 'inheritance07' %}{% block first %}2{% endblock %}")
319 << dict << QStringLiteral(
"1235") << NoError;
321 QTest::newRow(
"inheritance13")
322 << QStringLiteral(
"{% extends 'inheritance02' %}{% block first %}a{% "
323 "endblock %}{% block second %}b{% endblock %}")
324 << dict << QStringLiteral(
"1a3b") << NoError;
326 QTest::newRow(
"inheritance14")
327 << QStringLiteral(
"{% extends 'inheritance01' %}{% block newblock %}NO "
328 "DISPLAY{% endblock %}")
329 << dict << QStringLiteral(
"1&3_") << NoError;
332 = QStringLiteral(
"{% extends 'inheritance01' %}{% block first %}2{% "
333 "block inner %}inner{% endblock %}{% endblock %}");
334 loader->setTemplate(QStringLiteral(
"inheritance15"), inh15);
337 QTest::newRow(
"inheritance15")
338 << inh15 << dict << QStringLiteral(
"12inner3_") << NoError;
341 QTest::newRow(
"inheritance16")
343 "{% extends 'inheritance15' %}{% block inner %}out{% endblock %}")
344 << dict << QStringLiteral(
"12out3_") << NoError;
346 #ifdef HAVE_QTQML_LIB
348 auto inh17 = QStringLiteral(
349 "{% load testtags %}{% block first %}1234{% endblock %}");
350 loader->setTemplate(QStringLiteral(
"inheritance17"), inh17);
353 QTest::newRow(
"inheritance17")
354 << inh17 << dict << QStringLiteral(
"1234") << NoError;
357 QTest::newRow(
"inheritance18")
358 << QStringLiteral(
"{% load testtags %}{% echo this that theother %}5678")
359 << dict << QStringLiteral(
"this that theother5678") << NoError;
362 QTest::newRow(
"inheritance19")
363 << QStringLiteral(
"{% extends 'inheritance01' %}{% block first %}{% load "
364 "testtags %}{% echo 400 %}5678{% endblock %}")
365 << dict << QStringLiteral(
"140056783_") << NoError;
368 auto inh20 = QStringLiteral(
"{% extends 'inheritance01' %}{% block first "
369 "%}{{ block.super }}a{% endblock %}");
370 loader->setTemplate(QStringLiteral(
"inheritance20"), inh20);
373 QTest::newRow(
"inheritance20")
374 << inh20 << dict << QStringLiteral(
"1&a3_") << NoError;
376 QTest::newRow(
"inheritance21")
377 << QStringLiteral(
"{% extends 'inheritance02' %}{% block first %}{{ "
378 "block.super }}a{% endblock %}")
379 << dict << QStringLiteral(
"12a34") << NoError;
381 QTest::newRow(
"inheritance22")
382 << QStringLiteral(
"{% extends 'inheritance04' %}{% block first %}{{ "
383 "block.super }}a{% endblock %}")
384 << dict << QStringLiteral(
"1&a3_") << NoError;
387 QTest::newRow(
"inheritance23")
388 << QStringLiteral(
"{% extends 'inheritance20' %}{% block first %}{{ "
389 "block.super }}b{% endblock %}")
390 << dict << QStringLiteral(
"1&ab3_") << NoError;
394 auto t = m_engine->newTemplate(
395 QStringLiteral(
"1{% block first %}_{% endblock %}3{% block second %}_{% "
397 QStringLiteral(
"context_template"));
398 dict.insert(QStringLiteral(
"context_template"), QVariant::fromValue(t));
400 QTest::newRow(
"inheritance24")
401 << QStringLiteral(
"{% extends context_template %}{% block first %}2{% "
402 "endblock %}{% block second %}4{% endblock %}")
403 << dict << QStringLiteral(
"1234") << NoError;
407 auto t1 = m_engine->newTemplate(QStringLiteral(
"Wrong"),
408 QStringLiteral(
"context_template_1"));
409 auto t2 = m_engine->newTemplate(
410 QStringLiteral(
"1{% block first %}_{% endblock %}3{% block second %}_{% "
412 QStringLiteral(
"context_template_2"));
413 QVariantList list{QVariant::fromValue(t1), QVariant::fromValue(t2)};
415 dict.insert(QStringLiteral(
"context_template"), list);
418 QTest::newRow(
"inheritance25")
419 << QStringLiteral(
"{% extends context_template.1 %}{% block first %}2{% "
420 "endblock %}{% block second %}4{% endblock %}")
421 << dict << QStringLiteral(
"1234") << NoError;
426 auto inh26 = QStringLiteral(
"no tags");
427 loader->setTemplate(QStringLiteral(
"inheritance26"), inh26);
430 QTest::newRow(
"inheritance27")
431 << QStringLiteral(
"{% extends 'inheritance26' %}") << dict
432 << QStringLiteral(
"no tags") << NoError;
434 auto inh28 = QStringLiteral(
"{% block first %}!{% endblock %}");
435 loader->setTemplate(QStringLiteral(
"inheritance 28"), inh28);
437 QTest::newRow(
"inheritance 28")
438 << inh28 << dict << QStringLiteral(
"!") << NoError;
441 QTest::newRow(
"inheritance29")
442 << QStringLiteral(
"{% extends 'inheritance 28' %}") << dict
443 << QStringLiteral(
"!") << NoError;
445 dict.insert(QStringLiteral(
"optional"), QStringLiteral(
"True"));
447 auto inh30 = QStringLiteral(
448 "1{% if optional %}{% block opt %}2{% endblock %}{% endif %}3");
449 loader->setTemplate(QStringLiteral(
"inheritance30"), inh30);
451 QTest::newRow(
"inheritance30")
452 << inh30 << dict << QStringLiteral(
"123") << NoError;
453 QTest::newRow(
"inheritance31") << QStringLiteral(
454 "{% extends 'inheritance30' %}{% block opt %}two{% endblock %}")
455 << dict << QStringLiteral(
"1two3") << NoError;
457 QTest::newRow(
"inheritance32") << QStringLiteral(
458 "{% extends 'inheritance30' %}{% block opt %}two{% endblock %}")
459 << dict << QStringLiteral(
"13") << NoError;
461 dict.insert(QStringLiteral(
"optional"), 1);
462 auto inh33 = QStringLiteral(
"1{% ifequal optional 1 %}{% block opt %}2{% "
463 "endblock %}{% endifequal %}3");
464 loader->setTemplate(QStringLiteral(
"inheritance33"), inh33);
466 QTest::newRow(
"inheritance33")
467 << inh33 << dict << QStringLiteral(
"123") << NoError;
469 QTest::newRow(
"inheritance34") << QStringLiteral(
470 "{% extends 'inheritance33' %}{% block opt %}two{% endblock %}")
471 << dict << QStringLiteral(
"1two3") << NoError;
473 QTest::newRow(
"inheritance35") << QStringLiteral(
474 "{% extends 'inheritance33' %}{% block opt %}two{% endblock %}")
475 << dict << QStringLiteral(
"13") << NoError;
478 dict.insert(QStringLiteral(
"numbers"), QVariantList{1, 2, 3});
480 auto inh36 = QStringLiteral(
"{% for n in numbers %}_{% block opt %}{{ n }}{% "
481 "endblock %}{% endfor %}_");
482 loader->setTemplate(QStringLiteral(
"inheritance36"), inh36);
484 QTest::newRow(
"inheritance36")
485 << inh36 << dict << QStringLiteral(
"_1_2_3_") << NoError;
486 QTest::newRow(
"inheritance37")
488 "{% extends 'inheritance36' %}{% block opt %}X{% endblock %}")
489 << dict << QStringLiteral(
"_X_X_X_") << NoError;
491 QTest::newRow(
"inheritance38") << QStringLiteral(
492 "{% extends 'inheritance36' %}{% block opt %}X{% endblock %}")
493 << dict << QStringLiteral(
"_") << NoError;
495 dict.insert(QStringLiteral(
"optional"), QStringLiteral(
"True"));
497 QTest::newRow(
"inheritance39")
498 << QStringLiteral(
"{% extends 'inheritance30' %}{% block opt %}new{{ "
499 "block.super }}{% endblock %}")
500 << dict << QStringLiteral(
"1new23") << NoError;
502 dict.insert(QStringLiteral(
"optional"), 1);
504 QTest::newRow(
"inheritance40")
505 << QStringLiteral(
"{% extends 'inheritance33' %}{% block opt %}new{{ "
506 "block.super }}{% endblock %}")
507 << dict << QStringLiteral(
"1new23") << NoError;
510 dict.insert(QStringLiteral(
"numbers"), QVariantList{1, 2, 3});
512 QTest::newRow(
"inheritance41")
513 << QStringLiteral(
"{% extends 'inheritance36' %}{% block opt %}new{{ "
514 "block.super }}{% endblock %}")
515 << dict << QStringLiteral(
"_new1_new2_new3_") << NoError;
517 QTest::newRow(
"inheritance42")
518 << QStringLiteral(
"{% extends 'inheritance02'|cut:' ' %}") << dict
519 << QStringLiteral(
"1234") << NoError;
523 QTest::newRow(
"exception01") << QStringLiteral(
"{% extends 'nonexistent' %}")
524 << dict <<
QString() << TagSyntaxError;
526 QTest::newRow(
"exception02") << QStringLiteral(
"{% extends nonexistent %}")
527 << dict <<
QString() << TagSyntaxError;
529 QTest::newRow(
"exception03")
530 << QStringLiteral(
"{% extends 'inheritance01' %}{% block first %}2{% "
531 "endblock %}{% extends 'inheritance16' %}")
532 << dict <<
QString() << TagSyntaxError;
535 QTest::newRow(
"exception04")
536 << QStringLiteral(
"{% extends 'inheritance17' %}{% block first %}{% echo "
537 "400 %}5678{% endblock %}")
538 << dict <<
QString() << InvalidBlockTagError;
541 void TestLoaderTags::testBlockTagErrors_data()
543 QTest::addColumn<QString>(
"input");
544 QTest::addColumn<Dict>(
"dict");
545 QTest::addColumn<QString>(
"output");
546 QTest::addColumn<Cutelee::Error>(
"error");
550 QTest::newRow(
"block-error-01") << QStringLiteral(
551 "{% block repeat %}{% endblock %}{% block repeat %}{% endblock %}")
552 << dict <<
QString() << TagSyntaxError;
553 QTest::newRow(
"block-error-02") << QStringLiteral(
"{% block %}{% endblock %}")
554 << dict <<
QString() << TagSyntaxError;
555 QTest::newRow(
"block-error-03")
556 << QStringLiteral(
"{% block foo bar %}{% endblock %}") << dict
557 <<
QString() << TagSyntaxError;
560 void TestLoaderTags::testIncludeAndExtendsTag_data()
562 QTest::addColumn<QString>(
"input");
563 QTest::addColumn<Dict>(
"dict");
564 QTest::addColumn<QString>(
"output");
565 QTest::addColumn<Cutelee::Error>(
"error");
569 loader->setTemplate(QStringLiteral(
"ext_base"),
570 QStringLiteral(
"{% block block1 %}block1{% endblock %}"));
572 loader->setTemplate(QStringLiteral(
"extender"),
573 QStringLiteral(
"{% extends 'ext_base' %}{% block block1 "
574 "%}block1override{% endblock %}"));
576 QTest::newRow(
"include-extender-twice") << QStringLiteral(R
"django(
577 {% include "extender" %}
578 {% include "extender" %}
579 )django") << dict << QStringLiteral("\nblock1override\nblock1override\n")
582 loader->setTemplate(QStringLiteral(
"anotherextender"),
583 QStringLiteral(
"{% extends 'extender' %}{% block block1 "
584 "%}block1overrideagain{% endblock %}"));
586 QTest::newRow(
"include-deeper-extender-twice")
587 << QStringLiteral(R
"django(
588 {% include "anotherextender" %}
589 {% include "anotherextender" %}
591 << dict << QStringLiteral("\nblock1overrideagain\nblock1overrideagain\n")
596 #include "testloadertags.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.
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.
The InMemoryTemplateLoader loads Templates set dynamically in memory.
QString errorString() const
The Cutelee namespace holds all public Cutelee API.