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