File indexing completed on 2024-11-17 03:42:09

0001 /*
0002   This file is part of the KTextTemplate library
0003 
0004   SPDX-FileCopyrightText: 2009, 2010 Stephen Kelly <steveire@gmail.com>
0005 
0006   SPDX-License-Identifier: LGPL-2.1-or-later
0007 
0008 */
0009 
0010 #ifndef LOADERTAGSTEST_H
0011 #define LOADERTAGSTEST_H
0012 
0013 #include <QDebug>
0014 #include <QDir>
0015 #include <QFileInfo>
0016 #include <QTest>
0017 
0018 #include "context.h"
0019 #include "engine.h"
0020 #include "ktexttemplate_paths.h"
0021 #include "template.h"
0022 
0023 using Dict = QHash<QString, QVariant>;
0024 
0025 Q_DECLARE_METATYPE(KTextTemplate::Error)
0026 
0027 using namespace KTextTemplate;
0028 
0029 class TestLoaderTags : public QObject
0030 {
0031     Q_OBJECT
0032 
0033 private Q_SLOTS:
0034     void initTestCase();
0035     void cleanupTestCase();
0036 
0037     void testTemplateFromQrc();
0038 
0039     void testIncludeTag_data();
0040     void testIncludeTag()
0041     {
0042         doTest();
0043     }
0044 
0045     void testExtendsTag_data();
0046     void testExtendsTag()
0047     {
0048         doTest();
0049     }
0050 
0051     void testIncludeAndExtendsTag_data();
0052     void testIncludeAndExtendsTag()
0053     {
0054         doTest();
0055     }
0056 
0057     void testBlockTagErrors_data();
0058     void testBlockTagErrors()
0059     {
0060         doTest();
0061     }
0062 
0063 private:
0064     void doTest();
0065 
0066     QSharedPointer<InMemoryTemplateLoader> m_loader;
0067     Engine *m_engine;
0068 };
0069 
0070 void TestLoaderTags::initTestCase()
0071 {
0072     Q_INIT_RESOURCE(testresource);
0073 
0074     m_engine = new Engine(this);
0075 
0076     m_loader = QSharedPointer<InMemoryTemplateLoader>(new InMemoryTemplateLoader());
0077     m_engine->addTemplateLoader(m_loader);
0078 
0079     auto appDirPath = QFileInfo(QCoreApplication::applicationDirPath()).absoluteDir().path();
0080     m_engine->setPluginPaths({
0081         QStringLiteral(KTEXTTEMPLATE_PLUGIN_PATH),
0082         QStringLiteral(":/plugins/") // For testtags.qs
0083     });
0084 #ifdef HAVE_QTQML_LIB
0085     m_engine->addDefaultLibrary(QStringLiteral("ktexttemplate_scriptabletags"));
0086 #endif
0087 }
0088 
0089 void TestLoaderTags::cleanupTestCase()
0090 {
0091     delete m_engine;
0092 }
0093 
0094 void TestLoaderTags::testTemplateFromQrc()
0095 {
0096     Engine engine;
0097 
0098     auto loader = QSharedPointer<KTextTemplate::FileSystemTemplateLoader>::create();
0099     loader->setTemplateDirs({QStringLiteral(":/templates/")});
0100     engine.addTemplateLoader(loader);
0101     engine.setPluginPaths({QStringLiteral(KTEXTTEMPLATE_PLUGIN_PATH)});
0102 
0103     auto t = engine.loadByName(QStringLiteral("resourcetemplate1.html"));
0104 
0105     if (t->error() != NoError) {
0106         qDebug() << t->errorString();
0107         QCOMPARE(t->error(), NoError);
0108         return;
0109     }
0110 
0111     Context context;
0112     context.insert(QStringLiteral("numbertwo"), QStringLiteral("two"));
0113     context.insert(QStringLiteral("numberfour"), QStringLiteral("four"));
0114 
0115     auto result = t->render(&context);
0116 
0117     if (t->error() != NoError) {
0118         qDebug() << t->errorString();
0119         QCOMPARE(t->error(), NoError);
0120         return;
0121     }
0122 
0123     QCOMPARE(result, QStringLiteral("one-two-three-four\n\n"));
0124 }
0125 
0126 void TestLoaderTags::doTest()
0127 {
0128     QFETCH(QString, input);
0129     QFETCH(Dict, dict);
0130     QFETCH(QString, output);
0131     QFETCH(KTextTemplate::Error, error);
0132 
0133     auto t = m_engine->newTemplate(input, QLatin1String(QTest::currentDataTag()));
0134 
0135     if (t->error() != NoError) {
0136         if (t->error() != error)
0137             qDebug() << t->errorString();
0138         QCOMPARE(t->error(), error);
0139         return;
0140     }
0141 
0142     Context context(dict);
0143 
0144     auto result = t->render(&context);
0145 
0146     if (t->error() != NoError) {
0147         if (t->error() != error)
0148             qDebug() << t->errorString();
0149         QCOMPARE(t->error(), error);
0150         return;
0151     }
0152 
0153     // Didn't catch any errors, so make sure I didn't expect any.
0154     QCOMPARE(NoError, error);
0155 
0156     QCOMPARE(t->error(), NoError);
0157 
0158     QCOMPARE(result, output);
0159 }
0160 
0161 void TestLoaderTags::testIncludeTag_data()
0162 {
0163     QTest::addColumn<QString>("input");
0164     QTest::addColumn<Dict>("dict");
0165     QTest::addColumn<QString>("output");
0166     QTest::addColumn<KTextTemplate::Error>("error");
0167 
0168     Dict dict;
0169 
0170     m_loader->setTemplate(QStringLiteral("basic-syntax01"), QStringLiteral("Something cool"));
0171     m_loader->setTemplate(QStringLiteral("basic-syntax02"), QStringLiteral("{{ headline }}"));
0172 
0173     QTest::newRow("include01") << "{% include \"basic-syntax01\" %}" << dict << QStringLiteral("Something cool") << NoError;
0174 
0175     dict.insert(QStringLiteral("headline"), QStringLiteral("Included"));
0176 
0177     QTest::newRow("include02") << "{% include \"basic-syntax02\" %}" << dict << QStringLiteral("Included") << NoError;
0178 
0179     dict.insert(QStringLiteral("templateName"), QStringLiteral("basic-syntax02"));
0180 
0181     QTest::newRow("include03") << QStringLiteral("{% include templateName %}") << dict << QStringLiteral("Included") << NoError;
0182 
0183     dict.clear();
0184     QTest::newRow("include04") << "a{% include \"nonexistent\" %}b" << dict << QStringLiteral("ab") << TagSyntaxError;
0185 
0186     auto incl05 = QStringLiteral("template with a space");
0187     m_loader->setTemplate(QStringLiteral("include 05"), incl05);
0188 
0189     QTest::newRow("include 05") << incl05 << dict << QStringLiteral("template with a space") << NoError;
0190 
0191     QTest::newRow("include06") << "{% include \"include 05\" %}" << dict << QStringLiteral("template with a space") << NoError;
0192 
0193     dict.clear();
0194     dict.insert(QStringLiteral("list"), QVariantList{QVariant(), QVariant()});
0195     QTest::newRow("include07") << "{% for i in list %}{% include \"include 05\" %}{% endfor %}" << dict
0196                                << QStringLiteral("template with a spacetemplate with a space") << NoError;
0197 }
0198 
0199 void TestLoaderTags::testExtendsTag_data()
0200 {
0201     QTest::addColumn<QString>("input");
0202     QTest::addColumn<Dict>("dict");
0203     QTest::addColumn<QString>("output");
0204     QTest::addColumn<KTextTemplate::Error>("error");
0205 
0206     Dict dict;
0207     // Basic test
0208     QTest::newRow("namedendblocks01") << QStringLiteral(
0209         "1{% block first %}_{% block second %}2{% endblock "
0210         "second %}_{% endblock first %}3")
0211                                       << dict << QStringLiteral("1_2_3") << NoError;
0212     // Unbalanced blocks
0213     QTest::newRow("namedendblocks02") << QStringLiteral(
0214         "1{% block first %}_{% block second %}2{% endblock "
0215         "first %}_{% endblock second %}3")
0216                                       << dict << QString() << InvalidBlockTagError;
0217     QTest::newRow("namedendblocks03") << QStringLiteral(
0218         "1{% block first %}_{% block second %}2{% endblock "
0219         "%}_{% endblock second %}3") << dict
0220                                       << QString() << InvalidBlockTagError;
0221     QTest::newRow("namedendblocks04") << QStringLiteral(
0222         "1{% block first %}_{% block second %}2{% endblock "
0223         "second %}_{% endblock third %}3")
0224                                       << dict << QString() << InvalidBlockTagError;
0225     QTest::newRow("namedendblocks05") << QStringLiteral("1{% block first %}_{% block second %}2{% endblock first %}") << dict << QString()
0226                                       << InvalidBlockTagError;
0227     // Mixed named and unnamed endblocks
0228     QTest::newRow("namedendblocks06") << QStringLiteral(
0229         "1{% block first %}_{% block second %}2{% endblock "
0230         "%}_{% endblock first %}3") << dict
0231                                       << QStringLiteral("1_2_3") << NoError;
0232     QTest::newRow("namedendblocks07") << QStringLiteral(
0233         "1{% block first %}_{% block second %}2{% endblock "
0234         "second %}_{% endblock %}3") << dict
0235                                       << QStringLiteral("1_2_3") << NoError;
0236 
0237     // ## INHERITANCE ###########################################################
0238     //  Standard template with no inheritance
0239 
0240     auto inh1 = QStringLiteral("1{% block first %}&{% endblock %}3{% block second %}_{% endblock %}");
0241     m_loader->setTemplate(QStringLiteral("inheritance01"), inh1);
0242 
0243     QTest::newRow("inheritance01") << inh1 << dict << QStringLiteral("1&3_") << NoError;
0244 
0245     auto inh2 = QStringLiteral(
0246         "{% extends \"inheritance01\" %}{% block first %}2{% "
0247         "endblock %}{% block second %}4{% endblock %}");
0248     m_loader->setTemplate(QStringLiteral("inheritance02"), inh2);
0249 
0250     // Standard two-level inheritance
0251     QTest::newRow("inheritance02") << inh2 << dict << QStringLiteral("1234") << NoError;
0252     // Three-level with no redefinitions on third level
0253     QTest::newRow("inheritance03") << QStringLiteral("{% extends 'inheritance02' %}") << dict << QStringLiteral("1234") << NoError;
0254     // Two-level with no redefinitions on second level
0255 
0256     auto inh4 = QStringLiteral("{% extends \"inheritance01\" %}");
0257     m_loader->setTemplate(QStringLiteral("inheritance04"), inh4);
0258 
0259     QTest::newRow("inheritance04") << inh4 << dict << QStringLiteral("1&3_") << NoError;
0260     // Two-level with double quotes instead of single quotes
0261     QTest::newRow("inheritance05") << "{% extends \"inheritance02\" %}" << dict << QStringLiteral("1234") << NoError;
0262 
0263     dict.insert(QStringLiteral("foo"), QStringLiteral("inheritance02"));
0264     // Three-level with variable parent-template name
0265     QTest::newRow("inheritance06") << QStringLiteral("{% extends foo %}") << dict << QStringLiteral("1234") << NoError;
0266 
0267     auto inh7 = QStringLiteral("{% extends 'inheritance01' %}{% block second %}5{% endblock %}");
0268     m_loader->setTemplate(QStringLiteral("inheritance07"), inh7);
0269 
0270     dict.clear();
0271     // Two-level with one block defined, one block not defined
0272     QTest::newRow("inheritance07") << inh7 << dict << QStringLiteral("1&35") << NoError;
0273     // Three-level with one block defined on this level, two blocks defined next
0274     // level
0275     QTest::newRow("inheritance08") << QStringLiteral("{% extends 'inheritance02' %}{% block second %}5{% endblock %}") << dict << QStringLiteral("1235")
0276                                    << NoError;
0277 
0278     // Three-level with second and third levels blank
0279     QTest::newRow("inheritance09") << QStringLiteral("{% extends 'inheritance04' %}") << dict << QStringLiteral("1&3_") << NoError;
0280 
0281     dict.clear();
0282 
0283     // Three-level with space NOT in a block -- should be ignored
0284     QTest::newRow("inheritance10") << QStringLiteral("{% extends 'inheritance04' %}      ") << dict << QStringLiteral("1&3_") << NoError;
0285     // Three-level with both blocks defined on this level, but none on second
0286     // level
0287     QTest::newRow("inheritance11") << QStringLiteral(
0288         "{% extends 'inheritance04' %}{% block first %}2{% "
0289         "endblock %}{% block second %}4{% endblock %}")
0290                                    << dict << QStringLiteral("1234") << NoError;
0291     // Three-level with this level providing one and second level providing the
0292     // other
0293     QTest::newRow("inheritance12") << QStringLiteral("{% extends 'inheritance07' %}{% block first %}2{% endblock %}") << dict << QStringLiteral("1235")
0294                                    << NoError;
0295     // Three-level with this level overriding second level
0296     QTest::newRow("inheritance13") << QStringLiteral(
0297         "{% extends 'inheritance02' %}{% block first %}a{% "
0298         "endblock %}{% block second %}b{% endblock %}")
0299                                    << dict << QStringLiteral("1a3b") << NoError;
0300     // A block defined only in a child template shouldn't be displayed
0301     QTest::newRow("inheritance14") << QStringLiteral(
0302         "{% extends 'inheritance01' %}{% block newblock %}NO "
0303         "DISPLAY{% endblock %}") << dict
0304                                    << QStringLiteral("1&3_") << NoError;
0305 
0306     auto inh15 = QStringLiteral(
0307         "{% extends 'inheritance01' %}{% block first %}2{% "
0308         "block inner %}inner{% endblock %}{% endblock %}");
0309     m_loader->setTemplate(QStringLiteral("inheritance15"), inh15);
0310 
0311     // A block within another block
0312     QTest::newRow("inheritance15") << inh15 << dict << QStringLiteral("12inner3_") << NoError;
0313     // A block within another block (level 2)
0314 
0315     QTest::newRow("inheritance16") << QStringLiteral("{% extends 'inheritance15' %}{% block inner %}out{% endblock %}") << dict << QStringLiteral("12out3_")
0316                                    << NoError;
0317 
0318 #ifdef HAVE_QTQML_LIB
0319     // {% load %} tag (parent -- setup for exception04)
0320     auto inh17 = QStringLiteral("{% load testtags %}{% block first %}1234{% endblock %}");
0321     m_loader->setTemplate(QStringLiteral("inheritance17"), inh17);
0322 
0323     dict.clear();
0324     QTest::newRow("inheritance17") << inh17 << dict << QStringLiteral("1234") << NoError;
0325 
0326     // {% load %} tag (standard usage, without inheritance)
0327     QTest::newRow("inheritance18") << QStringLiteral("{% load testtags %}{% echo this that theother %}5678") << dict << QStringLiteral("this that theother5678")
0328                                    << NoError;
0329 
0330     // {% load %} tag (within a child template)
0331     QTest::newRow("inheritance19") << QStringLiteral(
0332         "{% extends 'inheritance01' %}{% block first %}{% load "
0333         "testtags %}{% echo 400 %}5678{% endblock %}")
0334                                    << dict << QStringLiteral("140056783_") << NoError;
0335 #endif
0336 
0337     auto inh20 = QStringLiteral(
0338         "{% extends 'inheritance01' %}{% block first "
0339         "%}{{ block.super }}a{% endblock %}");
0340     m_loader->setTemplate(QStringLiteral("inheritance20"), inh20);
0341 
0342     // Two-level inheritance with {{ block.super }}
0343     QTest::newRow("inheritance20") << inh20 << dict << QStringLiteral("1&a3_") << NoError;
0344     // Three-level inheritance with {{ block.super }} from parent
0345     QTest::newRow("inheritance21") << QStringLiteral(
0346         "{% extends 'inheritance02' %}{% block first %}{{ "
0347         "block.super }}a{% endblock %}")
0348                                    << dict << QStringLiteral("12a34") << NoError;
0349     // Three-level inheritance with {{ block.super }} from grandparent
0350     QTest::newRow("inheritance22") << QStringLiteral(
0351         "{% extends 'inheritance04' %}{% block first %}{{ "
0352         "block.super }}a{% endblock %}")
0353                                    << dict << QStringLiteral("1&a3_") << NoError;
0354     // Three-level inheritance with {{ block.super }} from parent and
0355     // grandparent
0356     QTest::newRow("inheritance23") << QStringLiteral(
0357         "{% extends 'inheritance20' %}{% block first %}{{ "
0358         "block.super }}b{% endblock %}")
0359                                    << dict << QStringLiteral("1&ab3_") << NoError;
0360 
0361     // Inheritance from local context without use of template loader
0362 
0363     auto t = m_engine->newTemplate(QStringLiteral("1{% block first %}_{% endblock %}3{% block second %}_{% "
0364                                                   "endblock %}"),
0365                                    QStringLiteral("context_template"));
0366     dict.insert(QStringLiteral("context_template"), QVariant::fromValue(t));
0367 
0368     QTest::newRow("inheritance24") << QStringLiteral(
0369         "{% extends context_template %}{% block first %}2{% "
0370         "endblock %}{% block second %}4{% endblock %}")
0371                                    << dict << QStringLiteral("1234") << NoError;
0372 
0373     dict.clear();
0374 
0375     auto t1 = m_engine->newTemplate(QStringLiteral("Wrong"), QStringLiteral("context_template_1"));
0376     auto t2 = m_engine->newTemplate(QStringLiteral("1{% block first %}_{% endblock %}3{% block second %}_{% "
0377                                                    "endblock %}"),
0378                                     QStringLiteral("context_template_2"));
0379     QVariantList list{QVariant::fromValue(t1), QVariant::fromValue(t2)};
0380 
0381     dict.insert(QStringLiteral("context_template"), list);
0382 
0383     // Inheritance from local context with variable parent template
0384     QTest::newRow("inheritance25") << QStringLiteral(
0385         "{% extends context_template.1 %}{% block first %}2{% "
0386         "endblock %}{% block second %}4{% endblock %}")
0387                                    << dict << QStringLiteral("1234") << NoError;
0388 
0389     dict.clear();
0390 
0391     // Set up a base template to extend
0392     auto inh26 = QStringLiteral("no tags");
0393     m_loader->setTemplate(QStringLiteral("inheritance26"), inh26);
0394 
0395     // Inheritance from a template that doesn't have any blocks
0396     QTest::newRow("inheritance27") << QStringLiteral("{% extends 'inheritance26' %}") << dict << QStringLiteral("no tags") << NoError;
0397 
0398     auto inh28 = QStringLiteral("{% block first %}!{% endblock %}");
0399     m_loader->setTemplate(QStringLiteral("inheritance 28"), inh28);
0400 
0401     QTest::newRow("inheritance 28") << inh28 << dict << QStringLiteral("!") << NoError;
0402 
0403     // Inheritance from a template with a space in its name should work.
0404     QTest::newRow("inheritance29") << QStringLiteral("{% extends 'inheritance 28' %}") << dict << QStringLiteral("!") << NoError;
0405 
0406     dict.insert(QStringLiteral("optional"), QStringLiteral("True"));
0407 
0408     auto inh30 = QStringLiteral("1{% if optional %}{% block opt %}2{% endblock %}{% endif %}3");
0409     m_loader->setTemplate(QStringLiteral("inheritance30"), inh30);
0410 
0411     QTest::newRow("inheritance30") << inh30 << dict << QStringLiteral("123") << NoError;
0412     QTest::newRow("inheritance31") << QStringLiteral("{% extends 'inheritance30' %}{% block opt %}two{% endblock %}") << dict << QStringLiteral("1two3")
0413                                    << NoError;
0414     dict.clear();
0415     QTest::newRow("inheritance32") << QStringLiteral("{% extends 'inheritance30' %}{% block opt %}two{% endblock %}") << dict << QStringLiteral("13")
0416                                    << NoError;
0417 
0418     dict.insert(QStringLiteral("optional"), 1);
0419     auto inh33 = QStringLiteral(
0420         "1{% ifequal optional 1 %}{% block opt %}2{% "
0421         "endblock %}{% endifequal %}3");
0422     m_loader->setTemplate(QStringLiteral("inheritance33"), inh33);
0423 
0424     QTest::newRow("inheritance33") << inh33 << dict << QStringLiteral("123") << NoError;
0425 
0426     QTest::newRow("inheritance34") << QStringLiteral("{% extends 'inheritance33' %}{% block opt %}two{% endblock %}") << dict << QStringLiteral("1two3")
0427                                    << NoError;
0428     dict.clear();
0429     QTest::newRow("inheritance35") << QStringLiteral("{% extends 'inheritance33' %}{% block opt %}two{% endblock %}") << dict << QStringLiteral("13")
0430                                    << NoError;
0431 
0432     dict.clear();
0433     dict.insert(QStringLiteral("numbers"), QVariantList{1, 2, 3});
0434 
0435     auto inh36 = QStringLiteral(
0436         "{% for n in numbers %}_{% block opt %}{{ n }}{% "
0437         "endblock %}{% endfor %}_");
0438     m_loader->setTemplate(QStringLiteral("inheritance36"), inh36);
0439 
0440     QTest::newRow("inheritance36") << inh36 << dict << QStringLiteral("_1_2_3_") << NoError;
0441     QTest::newRow("inheritance37") << QStringLiteral("{% extends 'inheritance36' %}{% block opt %}X{% endblock %}") << dict << QStringLiteral("_X_X_X_")
0442                                    << NoError;
0443     dict.clear();
0444     QTest::newRow("inheritance38") << QStringLiteral("{% extends 'inheritance36' %}{% block opt %}X{% endblock %}") << dict << QStringLiteral("_") << NoError;
0445 
0446     dict.insert(QStringLiteral("optional"), QStringLiteral("True"));
0447 
0448     QTest::newRow("inheritance39") << QStringLiteral(
0449         "{% extends 'inheritance30' %}{% block opt %}new{{ "
0450         "block.super }}{% endblock %}")
0451                                    << dict << QStringLiteral("1new23") << NoError;
0452 
0453     dict.insert(QStringLiteral("optional"), 1);
0454 
0455     QTest::newRow("inheritance40") << QStringLiteral(
0456         "{% extends 'inheritance33' %}{% block opt %}new{{ "
0457         "block.super }}{% endblock %}")
0458                                    << dict << QStringLiteral("1new23") << NoError;
0459 
0460     dict.clear();
0461     dict.insert(QStringLiteral("numbers"), QVariantList{1, 2, 3});
0462 
0463     QTest::newRow("inheritance41") << QStringLiteral(
0464         "{% extends 'inheritance36' %}{% block opt %}new{{ "
0465         "block.super }}{% endblock %}")
0466                                    << dict << QStringLiteral("_new1_new2_new3_") << NoError;
0467 
0468     QTest::newRow("inheritance42") << QStringLiteral("{% extends 'inheritance02'|cut:' ' %}") << dict << QStringLiteral("1234") << NoError;
0469 
0470     dict.clear();
0471     // Raise exception for invalid template name
0472     QTest::newRow("exception01") << QStringLiteral("{% extends 'nonexistent' %}") << dict << QString() << TagSyntaxError;
0473     // Raise exception for invalid template name (in variable)
0474     QTest::newRow("exception02") << QStringLiteral("{% extends nonexistent %}") << dict << QString() << TagSyntaxError;
0475     // Raise exception for extra {% extends %} tags
0476     QTest::newRow("exception03") << QStringLiteral(
0477         "{% extends 'inheritance01' %}{% block first %}2{% "
0478         "endblock %}{% extends 'inheritance16' %}")
0479                                  << dict << QString() << TagSyntaxError;
0480     // Raise exception for custom tags used in child with {% load %} tag in
0481     // parent, not in child
0482     QTest::newRow("exception04") << QStringLiteral(
0483         "{% extends 'inheritance17' %}{% block first %}{% echo "
0484         "400 %}5678{% endblock %}")
0485                                  << dict << QString() << InvalidBlockTagError;
0486 }
0487 
0488 void TestLoaderTags::testBlockTagErrors_data()
0489 {
0490     QTest::addColumn<QString>("input");
0491     QTest::addColumn<Dict>("dict");
0492     QTest::addColumn<QString>("output");
0493     QTest::addColumn<KTextTemplate::Error>("error");
0494 
0495     Dict dict;
0496 
0497     QTest::newRow("block-error-01") << QStringLiteral("{% block repeat %}{% endblock %}{% block repeat %}{% endblock %}") << dict << QString()
0498                                     << TagSyntaxError;
0499     QTest::newRow("block-error-02") << QStringLiteral("{% block %}{% endblock %}") << dict << QString() << TagSyntaxError;
0500     QTest::newRow("block-error-03") << QStringLiteral("{% block foo bar %}{% endblock %}") << dict << QString() << TagSyntaxError;
0501 }
0502 
0503 void TestLoaderTags::testIncludeAndExtendsTag_data()
0504 {
0505     QTest::addColumn<QString>("input");
0506     QTest::addColumn<Dict>("dict");
0507     QTest::addColumn<QString>("output");
0508     QTest::addColumn<KTextTemplate::Error>("error");
0509 
0510     Dict dict;
0511 
0512     m_loader->setTemplate(QStringLiteral("ext_base"), QStringLiteral("{% block block1 %}block1{% endblock %}"));
0513 
0514     m_loader->setTemplate(QStringLiteral("extender"),
0515                           QStringLiteral("{% extends 'ext_base' %}{% block block1 "
0516                                          "%}block1override{% endblock %}"));
0517 
0518     QTest::newRow("include-extender-twice") << QStringLiteral(R"django(
0519 {% include "extender" %}
0520 {% include "extender" %}
0521 )django") << dict << QStringLiteral("\nblock1override\nblock1override\n")
0522                                             << NoError;
0523 
0524     m_loader->setTemplate(QStringLiteral("anotherextender"),
0525                           QStringLiteral("{% extends 'extender' %}{% block block1 "
0526                                          "%}block1overrideagain{% endblock %}"));
0527 
0528     QTest::newRow("include-deeper-extender-twice") << QStringLiteral(R"django(
0529 {% include "anotherextender" %}
0530 {% include "anotherextender" %}
0531 )django") << dict << QStringLiteral("\nblock1overrideagain\nblock1overrideagain\n")
0532                                                    << NoError;
0533 }
0534 
0535 QTEST_MAIN(TestLoaderTags)
0536 #include "testloadertags.moc"
0537 
0538 #endif