Enable some tests which needed cycle tag to work.
[grantlee:grantlee.git] / tests / testdefaulttags.cpp
1 /*
2     Copyright (c) 2009 Stephen Kelly <steveire@gmail.com>
3 */
4
5 #ifndef DEFAULTTAGSTEST_H
6 #define DEFAULTTAGSTEST_H
7
8 #include <QtTest>
9 #include <QtCore>
10 #include <QObject>
11
12 #include "template.h"
13 #include "context.h"
14
15 #include "grantlee.h"
16
17 typedef QHash<QString, QVariant> Dict;
18
19 Q_DECLARE_METATYPE(Dict)
20 Q_DECLARE_METATYPE(Grantlee::Error)
21
22 using namespace Grantlee;
23
24 class TestDefaultTags : public QObject
25 {
26   Q_OBJECT
27
28 private slots:
29   void initTestCase();
30
31   void testCommentTag_data();
32   void testCommentTag() { doTest(); }
33
34   void testFirstOfTag_data();
35   void testFirstOfTag() {  doTest(); }
36
37   void testIfTag_data();
38   void testIfTag() {  doTest();  }
39
40   void testForTag_data();
41   void testForTag() {  doTest();  }
42
43   void testIfEqualTag_data();
44   void testIfEqualTag() {  doTest();  }
45
46   void testIfNotEqualTag_data();
47   void testIfNotEqualTag() {  doTest();  }
48
49   void testTemplateTagTag_data();
50   void testTemplateTagTag() {  doTest();  }
51
52   void testWithTag_data();
53   void testWithTag() {  doTest();  }
54
55   void testCycleTag_data();
56   void testCycleTag() {  doTest();  }
57
58   void testWidthRatioTag_data();
59   void testWidthRatioTag() {  doTest();  }
60
61   void testFilterTag_data();
62   void testFilterTag() {  doTest();  }
63
64   void testNowTag_data();
65   void testNowTag() {  doTest();  }
66
67   void testSpacelessTag_data();
68   void testSpacelessTag() {  doTest();  }
69
70   void testRegroupTag_data();
71   void testRegroupTag() {  doTest();  }
72
73   void testIfChangedTag_data();
74   void testIfChangedTag() {  doTest();  }
75
76 private:
77
78   void doTest();
79
80   TemplateLoader *m_tl;
81
82 };
83
84 void TestDefaultTags::initTestCase()
85 {
86   m_tl = TemplateLoader::instance();
87
88   m_tl->setPluginDirs(QStringList() << "/home/kde-devel/kde/lib/");
89
90 }
91
92 void TestDefaultTags::doTest()
93 {
94   QFETCH(QString, input);
95   QFETCH(Dict, dict);
96   QFETCH(QString, output);
97   QFETCH(Grantlee::Error, error);
98
99   Template* t = m_tl->getTemplate();
100
101   QSignalSpy spy(t, SIGNAL(error(int, const QString &)));
102   t->setContent(input);
103
104   if (spy.count() > 0)
105   {
106     QVariantList l = spy.takeFirst();
107     QCOMPARE(l.at(0).toInt(), (int)error );
108     return;
109   }
110
111   Context context(dict);
112
113   QString result = t->render(&context);
114
115   if (spy.count() > 0)
116   {
117     QVariantList l = spy.takeFirst();
118     QCOMPARE(l.at(0).toInt(), (int)error );
119     QCOMPARE(result, QString());
120     return;
121   }
122
123   // Didn't catch any errors, so make sure I didn't expect any.
124   QCOMPARE(NoError, error);
125
126   QCOMPARE(result, output);
127 }
128
129 void TestDefaultTags::testCommentTag_data()
130 {
131   QTest::addColumn<QString>("input");
132   QTest::addColumn<Dict>("dict");
133   QTest::addColumn<QString>("output");
134   QTest::addColumn<Grantlee::Error>("error");
135
136   Dict dict;
137
138   QTest::newRow("comment-tag01") << "{% comment %}this is hidden{% endcomment %}hello" << dict << "hello" << NoError;
139
140   QTest::newRow("comment-tag02") << "{% comment %}this is hidden{% endcomment %}hello{% comment %}foo{% endcomment %}" << dict << "hello" << NoError;
141   // Comment tag can contain invalid stuff.
142   QTest::newRow("comment-tag03") << "foo{% comment %} {% if %} {% endcomment %}" << dict << "foo" << NoError;
143   QTest::newRow("comment-tag04") << "foo{% comment %} {% endblock %} {% endcomment %}" << dict << "foo" << NoError;
144   QTest::newRow("comment-tag05") << "foo{% comment %} {% somerandomtag %} {% endcomment %}" << dict << "foo" << NoError;
145 }
146
147 void TestDefaultTags::testFirstOfTag_data()
148 {
149   QTest::addColumn<QString>("input");
150   QTest::addColumn<Dict>("dict");
151   QTest::addColumn<QString>("output");
152   QTest::addColumn<Grantlee::Error>("error");
153
154   Dict dict;
155   dict.insert("a", 0);
156   dict.insert("b", 0);
157   dict.insert("c", 0);
158   QTest::newRow("firstof01") << "{% firstof a b c %}" << dict << "" << NoError;
159
160   dict.clear();
161   dict.insert("a", 1);
162   dict.insert("b", 0);
163   dict.insert("c", 0);
164   QTest::newRow("firstof02") << "{% firstof a b c %}" << dict << "1" << NoError;
165
166   dict.clear();
167   dict.insert("a", 0);
168   dict.insert("b", 2);
169   dict.insert("c", 0);
170   QTest::newRow("firstof03") << "{% firstof a b c %}" << dict << "2" << NoError;
171
172   dict.clear();
173   dict.insert("a", 0);
174   dict.insert("b", 0);
175   dict.insert("c", 3);
176   QTest::newRow("firstof04") << "{% firstof a b c %}" << dict << "3" << NoError;
177
178   dict.clear();
179   dict.insert("a", 1);
180   dict.insert("b", 2);
181   dict.insert("c", 3);
182   QTest::newRow("firstof05") << "{% firstof a b c %}" << dict << "1" << NoError;
183
184   dict.clear();
185   dict.insert("b", 0);
186   dict.insert("c", 3);
187   QTest::newRow("firstof06") << "{% firstof a b c %}" << dict << "3" << NoError;
188
189   dict.clear();
190   dict.insert("a", 0);
191   QTest::newRow("firstof07") << "{% firstof a b \"c\" %}" << dict << "c" << NoError;
192
193   dict.clear();
194   dict.insert("a", 0);
195   dict.insert("b", 0);
196   QTest::newRow("firstof08") << "{% firstof a b \"c and d\" %}" << dict << "c and d" << NoError;
197   QTest::newRow("firstof09") << "{% firstof %}" << dict << "a" << TagSyntaxError;
198
199 }
200
201
202 void TestDefaultTags::testIfTag_data()
203 {
204   QTest::addColumn<QString>("input");
205   QTest::addColumn<Dict>("dict");
206   QTest::addColumn<QString>("output");
207   QTest::addColumn<Grantlee::Error>("error");
208
209   Dict dict;
210
211   dict.insert("foo", true);
212
213   QTest::newRow("if-tag01") << "{% if foo %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
214
215   dict.clear();
216   dict.insert("foo", false);
217   QTest::newRow("if-tag02") << "{% if foo %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
218
219   dict.clear();
220   QTest::newRow("if-tag03") << "{% if foo %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
221
222   // AND
223
224   dict.clear();
225   dict.insert("foo", true);
226   dict.insert("bar", true);
227   QTest::newRow("if-tag-and01") << "{% if foo and bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
228
229   dict.clear();
230   dict.insert("foo", true);
231   dict.insert("bar", false);
232   QTest::newRow("if-tag-and02") << "{% if foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
233
234   dict.clear();
235   dict.insert("foo", false);
236   dict.insert("bar", true);
237   QTest::newRow("if-tag-and03") << "{% if foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
238
239   dict.clear();
240   dict.insert("foo", false);
241   dict.insert("bar", false);
242   QTest::newRow("if-tag-and04") << "{% if foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
243
244   dict.clear();
245   dict.insert("foo", false);
246   QTest::newRow("if-tag-and05") << "{% if foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
247
248   dict.clear();
249   dict.insert("bar", false);
250   QTest::newRow("if-tag-and06") << "{% if foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
251
252   dict.clear();
253   dict.insert("foo", true);
254   QTest::newRow("if-tag-and07") << "{% if foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
255
256   dict.clear();
257   dict.insert("bar", true);
258   QTest::newRow("if-tag-and08") << "{% if foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
259
260   // OR
261
262   dict.clear();
263   dict.insert("foo", true);
264   dict.insert("bar", true);
265   QTest::newRow("if-tag-or01") << "{% if foo or bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
266
267   dict.clear();
268   dict.insert("foo", true);
269   dict.insert("bar", false);
270   QTest::newRow("if-tag-or02") << "{% if foo or bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
271
272   dict.clear();
273   dict.insert("foo", false);
274   dict.insert("bar", true);
275   QTest::newRow("if-tag-or03") << "{% if foo or bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
276
277   dict.clear();
278   dict.insert("foo", false);
279   dict.insert("bar", false);
280   QTest::newRow("if-tag-or04") << "{% if foo or bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
281
282   dict.clear();
283   dict.insert("foo", false);
284   QTest::newRow("if-tag-or05") << "{% if foo or bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
285
286   dict.clear();
287   dict.insert("bar", false);
288   QTest::newRow("if-tag-or06") << "{% if foo or bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
289
290   dict.clear();
291   dict.insert("foo", true);
292   QTest::newRow("if-tag-or07") << "{% if foo or bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
293
294   dict.clear();
295   dict.insert("bar", true);
296   QTest::newRow("if-tag-or08") << "{% if foo or bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
297
298   // TODO: multiple ORs
299
300
301   // NOT
302
303   dict.clear();
304   dict.insert("foo", true);
305   QTest::newRow("if-tag-not01") << "{% if not foo %}no{% else %}yes{% endif %}" << dict << "yes" << NoError;
306   QTest::newRow("if-tag-not02") << "{% if not %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
307
308   dict.clear();
309   dict.insert("not", true);
310   QTest::newRow("if-tag-not03") << "{% if not %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
311   QTest::newRow("if-tag-not04") << "{% if not not %}no{% else %}yes{% endif %}" << dict << "yes" << NoError;
312
313   dict.clear();
314   QTest::newRow("if-tag-not05") << "{% if not not %}no{% else %}yes{% endif %}" << dict << "no" << NoError;
315   QTest::newRow("if-tag-not06") << "{% if foo and not bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
316
317   dict.clear();
318   dict.insert("foo", true);
319   dict.insert("bar", true);
320   QTest::newRow("if-tag-not07") << "{% if foo and not bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
321
322   dict.clear();
323   dict.insert("foo", true);
324   dict.insert("bar", false);
325   QTest::newRow("if-tag-not08") << "{% if foo and not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
326
327   dict.clear();
328   dict.insert("foo", false);
329   dict.insert("bar", true);
330   QTest::newRow("if-tag-not09") << "{% if foo and not bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
331
332   dict.clear();
333   dict.insert("foo", false);
334   dict.insert("bar", false);
335   QTest::newRow("if-tag-not10") << "{% if foo and not bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
336
337   dict.clear();
338   QTest::newRow("if-tag-not11") << "{% if not foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
339
340   dict.clear();
341   dict.insert("foo", true);
342   dict.insert("bar", true);
343   QTest::newRow("if-tag-not12") << "{% if not foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
344
345   dict.clear();
346   dict.insert("foo", true);
347   dict.insert("bar", false);
348   QTest::newRow("if-tag-not13") << "{% if not foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
349
350   dict.clear();
351   dict.insert("foo", false);
352   dict.insert("bar", true);
353   QTest::newRow("if-tag-not14") << "{% if not foo and bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
354
355   dict.clear();
356   dict.insert("foo", false);
357   dict.insert("bar", false);
358   QTest::newRow("if-tag-not15") << "{% if not foo and bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
359
360   dict.clear();
361   QTest::newRow("if-tag-not16") << "{% if foo or not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
362
363   dict.clear();
364   dict.insert("foo", true);
365   dict.insert("bar", true);
366   QTest::newRow("if-tag-not17") << "{% if foo or not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
367
368   dict.clear();
369   dict.insert("foo", true);
370   dict.insert("bar", false);
371   QTest::newRow("if-tag-not18") << "{% if foo or not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
372
373   dict.clear();
374   dict.insert("foo", false);
375   dict.insert("bar", true);
376   QTest::newRow("if-tag-not19") << "{% if foo or not bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
377
378   dict.clear();
379   dict.insert("foo", false);
380   dict.insert("bar", false);
381   QTest::newRow("if-tag-not20") << "{% if foo or not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
382
383   dict.clear();
384   QTest::newRow("if-tag-not21") << "{% if not foo or bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
385
386   dict.clear();
387   dict.insert("foo", true);
388   dict.insert("bar", true);
389   QTest::newRow("if-tag-not22") << "{% if not foo or bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
390
391   dict.clear();
392   dict.insert("foo", true);
393   dict.insert("bar", false);
394   QTest::newRow("if-tag-not23") << "{% if not foo or bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
395
396   dict.clear();
397   dict.insert("foo", false);
398   dict.insert("bar", true);
399   QTest::newRow("if-tag-not24") << "{% if not foo or bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
400
401   dict.clear();
402   dict.insert("foo", false);
403   dict.insert("bar", false);
404   QTest::newRow("if-tag-not25") << "{% if not foo or bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
405
406   dict.clear();
407   QTest::newRow("if-tag-not26") << "{% if not foo and not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
408
409   dict.clear();
410   dict.insert("foo", true);
411   dict.insert("bar", true);
412   QTest::newRow("if-tag-not27") << "{% if not foo and not bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
413
414   dict.clear();
415   dict.insert("foo", true);
416   dict.insert("bar", false);
417   QTest::newRow("if-tag-not28") << "{% if not foo and not bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
418
419   dict.clear();
420   dict.insert("foo", false);
421   dict.insert("bar", true);
422   QTest::newRow("if-tag-not29") << "{% if not foo and not bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
423
424   dict.clear();
425   dict.insert("foo", false);
426   dict.insert("bar", false);
427   QTest::newRow("if-tag-not30") << "{% if not foo and not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
428
429   dict.clear();
430   QTest::newRow("if-tag-not31") << "{% if not foo or not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
431
432   dict.clear();
433   dict.insert("foo", true);
434   dict.insert("bar", true);
435   QTest::newRow("if-tag-not32") << "{% if not foo or not bar %}yes{% else %}no{% endif %}" << dict << "no" << NoError;
436
437   dict.clear();
438   dict.insert("foo", true);
439   dict.insert("bar", false);
440   QTest::newRow("if-tag-not33") << "{% if not foo or not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
441
442   dict.clear();
443   dict.insert("foo", false);
444   dict.insert("bar", true);
445   QTest::newRow("if-tag-not34") << "{% if not foo or not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
446
447   dict.clear();
448   dict.insert("foo", false);
449   dict.insert("bar", false);
450   QTest::newRow("if-tag-not35") << "{% if not foo or not bar %}yes{% else %}no{% endif %}" << dict << "yes" << NoError;
451
452   // AND and OR raises a TemplateSyntaxError
453   QTest::newRow("if-tag-error01") << "{% if foo or bar and baz %}yes{% else %}no{% endif %}" << dict << "" << TagSyntaxError;
454
455   dict.clear();
456   dict.insert("foo", true);
457   QTest::newRow("if-tag-error02") << "{% if foo and %}yes{% else %}no{% endif %}" << dict << "" << TagSyntaxError;
458   QTest::newRow("if-tag-error03") << "{% if foo or %}yes{% else %}no{% endif %}" << dict << "" << TagSyntaxError;
459   QTest::newRow("if-tag-error04") << "{% if not foo and %}yes{% else %}no{% endif %}" << dict << "" << TagSyntaxError;
460   QTest::newRow("if-tag-error05") << "{% if not foo or %}yes{% else %}no{% endif %}" << dict << "" << TagSyntaxError;
461
462 }
463
464 void TestDefaultTags::testForTag_data()
465 {
466   QTest::addColumn<QString>("input");
467   QTest::addColumn<Dict>("dict");
468   QTest::addColumn<QString>("output");
469   QTest::addColumn<Grantlee::Error>("error");
470
471   Dict dict;
472
473   QVariantList list;
474   list << 1 << 2 << 3;
475   dict.insert("values", list);
476   QTest::newRow("for-tag01") << "{% for val in values %}{{ val }}{% endfor %}" << dict << "123" << NoError;
477   QTest::newRow("for-tag02") << "{% for val in values reversed %}{{ val }}{% endfor %}" << dict << "321" << NoError;
478   list.clear();
479   list << 6 << 6 << 6;
480   QTest::newRow("for-tag-vars01") << "{% for val in values %}{{ forloop.counter }}{% endfor %}" << dict << "123" << NoError;
481   QTest::newRow("for-tag-vars02") << "{% for val in values %}{{ forloop.counter0 }}{% endfor %}" << dict << "012" << NoError;
482   QTest::newRow("for-tag-vars03") << "{% for val in values %}{{ forloop.revcounter }}{% endfor %}" << dict << "321" << NoError;
483   QTest::newRow("for-tag-vars04") << "{% for val in values %}{{ forloop.revcounter0 }}{% endfor %}" << dict << "210" << NoError;
484   QTest::newRow("for-tag-vars05") << "{% for val in values %}{% if forloop.first %}f{% else %}x{% endif %}{% endfor %}" << dict << "fxx" << NoError;
485   QTest::newRow("for-tag-vars06") << "{% for val in values %}{% if forloop.last %}l{% else %}x{% endif %}{% endfor %}" << dict << "xxl" << NoError;
486
487   dict.clear();
488   QVariantMap map;
489   map.insert("one", 1);
490   map.insert("two", 2);
491   dict.insert("items", map);
492   QTest::newRow("for-tag-unpack01") << "{% for key,value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
493
494   QTest::newRow("for-tag-unpack03") << "{% for key, value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
495   QTest::newRow("for-tag-unpack04") << "{% for key , value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
496   QTest::newRow("for-tag-unpack05") << "{% for key ,value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
497   QTest::newRow("for-tag-unpack06") << "{% for key value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
498   QTest::newRow("for-tag-unpack07") << "{% for key,,value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
499   QTest::newRow("for-tag-unpack08") << "{% for key,value, in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
500
501 // Ensure that a single loopvar doesn't truncate the list in val.
502   QTest::newRow("for-tag-unpack09") << "{% for val in items %}{{ val.0 }}:{{ val.1 }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
503 // // Otherwise, silently truncate if the length of loopvars differs to the length of each set of items.
504 // // #C# {"items": (('one'
505 // QTest::newRow("for-tag-unpack10") << "{% for x,y in items %}{{ x }}:{{ y }}/{% endfor %}" << dict << " 1, 'carrot'), ('two', 2, 'orange'))}, "one:1/two:2/"),";
506 // // #C# {"items": (('one'
507 // QTest::newRow("for-tag-unpack11") << "{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}" << dict << " 1), ('two', 2))}, ("one:1,/two:2,/", "one:1,INVALID/two:2,INVALID/")),";
508 // // #C# {"items": (('one'
509 // QTest::newRow("for-tag-unpack12") << "{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}" << dict << " 1, 'carrot'), ('two', 2))}, ("one:1,carrot/two:2,/", "one:1,carrot/two:2,INVALID/")),";
510 // // #C# {"items": (('one'
511
512   dict.clear();
513   list.clear();
514   QVariantList innerList;
515   innerList.clear();
516   innerList << "one" << 1 << "carrot";
517   list.append(QVariant(innerList));
518   innerList.clear();
519   innerList << "two" << 2 << "cheese";
520   list.append(QVariant(innerList));
521
522   dict.insert("items", list);
523
524   QTest::newRow("for-tag-unpack13") << "{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}" << dict << "one:1,carrot/two:2,cheese/" << NoError;
525
526 }
527
528 void TestDefaultTags::testIfEqualTag_data()
529 {
530   QTest::addColumn<QString>("input");
531   QTest::addColumn<Dict>("dict");
532   QTest::addColumn<QString>("output");
533   QTest::addColumn<Grantlee::Error>("error");
534
535   Dict dict;
536
537   dict.insert("a", 1);
538   dict.insert("b", 2);
539
540   QTest::newRow("ifequal01") << "{% ifequal a b %}yes{% endifequal %}" << dict << "" << NoError;
541   QTest::newRow("ifequal03") << "{% ifequal a b %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
542
543   dict.clear();
544   dict.insert("a", 1);
545   dict.insert("b", 1);
546
547   QTest::newRow("ifequal02") << "{% ifequal a b %}yes{% endifequal %}" << dict << "yes" << NoError;
548   QTest::newRow("ifequal04") << "{% ifequal a b %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
549
550   dict.clear();
551   dict.insert("a", "test");
552
553   QTest::newRow("ifequal05") << "{% ifequal a 'test' %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
554
555   dict.clear();
556   dict.insert("a", "no");
557
558   QTest::newRow("ifequal06") << "{% ifequal a 'test' %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
559
560   dict.clear();
561   dict.insert("a", "test");
562
563   QTest::newRow("ifequal07") << "{% ifequal a \"test\" %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
564
565   dict.clear();
566   dict.insert("a", "no");
567
568   QTest::newRow("ifequal08") << "{% ifequal a \"test\" %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
569
570   dict.clear();
571
572   QTest::newRow("ifequal09") << "{% ifequal a \"test\" %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
573
574   QTest::newRow("ifequal10") << "{% ifequal a b %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
575
576
577   QTest::newRow("ifequal-split01") << "{% ifequal a \"test man\" %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
578
579   dict.insert("a", "foo");
580   QTest::newRow("ifequal-split01") << "{% ifequal a \"test man\" %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
581   QTest::newRow("ifequal-split02") << "{% ifequal a \"test man\" %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
582
583   dict.clear();
584   dict.insert("a", "test man");
585   QTest::newRow("ifequal-split03") << "{% ifequal a \"test man\" %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
586   QTest::newRow("ifequal-split04") << "{% ifequal a 'test man' %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
587
588   dict.clear();
589   dict.insert("a", "");
590   QTest::newRow("ifequal-split05") << "{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
591
592   dict.clear();
593   dict.insert("a", "i \"love\" you");
594   QTest::newRow("ifequal-split06") << "{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
595
596   dict.clear();
597   dict.insert("a", "i love you");
598   QTest::newRow("ifequal-split07") << "{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
599
600   dict.clear();
601   dict.insert("a", "I'm happy");
602   QTest::newRow("ifequal-split08") << "{% ifequal a 'I\\'m happy' %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
603
604   dict.clear();
605   dict.insert("a", "slash\\man");
606   QTest::newRow("ifequal-split09") << "{% ifequal a 'slash\\man' %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
607
608   dict.clear();
609   dict.insert("a", "slashman");
610   QTest::newRow("ifequal-split10") << "{% ifequal a 'slash\\man' %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
611 // NUMERIC RESOLUTION
612
613   dict.clear();
614   dict.insert("x", "5");
615
616   QTest::newRow("ifequal-numeric01") << "{% ifequal x 5 %}yes{% endifequal %}" << dict << "" << NoError;
617
618   dict.clear();
619   dict.insert("x", 5);
620   QTest::newRow("ifequal-numeric02") << "{% ifequal x 5 %}yes{% endifequal %}" << dict << "yes" << NoError;
621
622   dict.clear();
623   dict.insert("x", 5.2);
624   QTest::newRow("ifequal-numeric03") << "{% ifequal x 5 %}yes{% endifequal %}" << dict << "" << NoError;
625   QTest::newRow("ifequal-numeric04") << "{% ifequal x 5.2 %}yes{% endifequal %}" << dict << "yes" << NoError;
626
627   dict.clear();
628   dict.insert("x", .2);
629
630   QTest::newRow("ifequal-numeric05") << "{% ifequal x 0.2 %}yes{% endifequal %}" << dict << "yes" << NoError;
631   QTest::newRow("ifequal-numeric06") << "{% ifequal x .2 %}yes{% endifequal %}" << dict << "yes" << NoError;
632
633   dict.clear();
634   dict.insert("x", 2);
635
636   QTest::newRow("ifequal-numeric07") << "{% ifequal x 2. %}yes{% endifequal %}" << dict << "" << NoError;
637
638   dict.clear();
639   dict.insert("x", 5);
640   QTest::newRow("ifequal-numeric08") << "{% ifequal x \"5\" %}yes{% endifequal %}" << dict << "" << NoError;
641
642   dict.clear();
643   dict.insert("x", "5");
644   QTest::newRow("ifequal-numeric09") << "{% ifequal x \"5\" %}yes{% endifequal %}" << dict << "yes" << NoError;
645
646   dict.clear();
647   dict.insert("x", -5);
648   QTest::newRow("ifequal-numeric10") << "{% ifequal x -5 %}yes{% endifequal %}" << dict << "yes" << NoError;
649
650   dict.clear();
651   dict.insert("x", -5.2);
652   QTest::newRow("ifequal-numeric11") << "{% ifequal x -5.2 %}yes{% endifequal %}" << dict << "yes" << NoError;
653
654   dict.clear();
655   dict.insert("x", 5);
656   QTest::newRow("ifequal-numeric12") << "{% ifequal x +5 %}yes{% endifequal %}" << dict << "yes" << NoError;
657
658 }
659
660 void TestDefaultTags::testIfNotEqualTag_data()
661 {
662   QTest::addColumn<QString>("input");
663   QTest::addColumn<Dict>("dict");
664   QTest::addColumn<QString>("output");
665   QTest::addColumn<Grantlee::Error>("error");
666
667   Dict dict;
668
669   dict.insert("a", 1);
670   dict.insert("b", 2);
671
672   QTest::newRow("ifnotequal01") << "{% ifnotequal a b %}yes{% endifnotequal %}" << dict << "yes" << NoError;
673   QTest::newRow("ifnotequal03") << "{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}" << dict << "yes" << NoError;
674
675   dict.clear();
676   dict.insert("a", 1);
677   dict.insert("b", 1);
678
679   QTest::newRow("ifnotequal02") << "{% ifnotequal a b %}yes{% endifnotequal %}" << dict << "" << NoError;
680   QTest::newRow("ifnotequal04") << "{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}" << dict << "no" << NoError;
681
682 }
683
684 void TestDefaultTags::testTemplateTagTag_data()
685 {
686   QTest::addColumn<QString>("input");
687   QTest::addColumn<Dict>("dict");
688   QTest::addColumn<QString>("output");
689   QTest::addColumn<Grantlee::Error>("error");
690
691   Dict dict;
692
693   QTest::newRow("templatetag01") << "{% templatetag openblock %}" << dict << "{%" << NoError;
694   QTest::newRow("templatetag02") << "{% templatetag closeblock %}" << dict << "%}" << NoError;
695   QTest::newRow("templatetag03") << "{% templatetag openvariable %}" << dict << "{{" << NoError;
696   QTest::newRow("templatetag04") << "{% templatetag closevariable %}" << dict << "}}" << NoError;
697   QTest::newRow("templatetag05") << "{% templatetag %}" << dict << "" << TagSyntaxError;
698   QTest::newRow("templatetag06") << "{% templatetag foo %}" << dict << "" << TagSyntaxError;
699   QTest::newRow("templatetag07") << "{% templatetag openbrace %}" << dict << "{" << NoError;
700   QTest::newRow("templatetag08") << "{% templatetag closebrace %}" << dict << "}" << NoError;
701   QTest::newRow("templatetag09") << "{% templatetag openbrace %}{% templatetag openbrace %}" << dict << "{{" << NoError;
702   QTest::newRow("templatetag10") << "{% templatetag closebrace %}{% templatetag closebrace %}" << dict << "}}" << NoError;
703   QTest::newRow("templatetag11") << "{% templatetag opencomment %}" << dict << "{#" << NoError;
704   QTest::newRow("templatetag12") << "{% templatetag closecomment %}" << dict << "#}" << NoError;
705
706 }
707
708 void TestDefaultTags::testWithTag_data()
709 {
710   QTest::addColumn<QString>("input");
711   QTest::addColumn<Dict>("dict");
712   QTest::addColumn<QString>("output");
713   QTest::addColumn<Grantlee::Error>("error");
714
715   Dict dict;
716
717   QVariantMap map;
718   map.insert("key", 50);
719   dict.insert("dict", map);
720   QTest::newRow("with01") << "{% with dict.key as key %}{{ key }}{% endwith %}" << dict << "50" << NoError;
721   QTest::newRow("with02")
722         << "{{ key }}{% with dict.key as key %}{{ key }}-{{ dict.key }}-{{ key }}{% endwith %}{{ key }}"
723         << dict << "50-50-50" << NoError;
724   QTest::newRow("with03") << "{% with dict.key xx key %}{{ key }}{% endwith %}" << dict << "" << TagSyntaxError;
725   QTest::newRow("with04") << "{% with dict.key as %}{{ key }}{% endwith %}" << dict << "" << TagSyntaxError;
726 }
727
728 void TestDefaultTags::testCycleTag_data()
729 {
730   QTest::addColumn<QString>("input");
731   QTest::addColumn<Dict>("dict");
732   QTest::addColumn<QString>("output");
733   QTest::addColumn<Grantlee::Error>("error");
734
735   Dict dict;
736
737   QTest::newRow("cycle01") << "{% cycle a %}" << dict << "" << TagSyntaxError;
738   QTest::newRow("cycle02") << "{% cycle a,b,c as abc %}{% cycle abc %}" << dict << "ab" << NoError;
739   QTest::newRow("cycle03") << "{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}" << dict << "abc" << NoError;
740   QTest::newRow("cycle04") << "{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}" << dict << "abca" << NoError;
741   QTest::newRow("cycle05") << "{% cycle a %}" << dict << "" << TagSyntaxError;
742   // TODO: This is the same as cycle01. Remove.
743   QTest::newRow("cycle06") << "{% cycle a %}" << dict << "" << TagSyntaxError;
744   QTest::newRow("cycle07") << "{% cycle a,b,c as foo %}{% cycle bar %}" << dict << "" << TagSyntaxError;
745   QTest::newRow("cycle08") << "{% cycle a,b,c as foo %}{% cycle foo %}{{ foo }}{{ foo }}{% cycle foo %}{{ foo }}" << dict << "abbbcc" << NoError;
746
747   dict.insert("test", QVariantList() << 0 << 1 << 2 << 3 << 4);
748   QTest::newRow("cycle09") << "{% for i in test %}{% cycle a,b %}{{ i }},{% endfor %}" << dict << "a0,b1,a2,b3,a4," << NoError;
749
750   dict.clear();
751   QTest::newRow("cycle10") << "{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}" << dict << "ab" << NoError;
752   QTest::newRow("cycle11") << "{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}" << dict << "abc" << NoError;
753   QTest::newRow("cycle12") << "{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}" << dict << "abca" << NoError;
754
755   dict.insert("test", QVariantList() << 0 << 1 << 2 << 3 << 4);
756   QTest::newRow("cycle13") << "{% for i in test %}{% cycle 'a' 'b' %}{{ i }},{% endfor %}" << dict << "a0,b1,a2,b3,a4," << NoError;
757
758   dict.clear();
759   dict.insert("one", "1");
760   dict.insert("two", "2");
761   QTest::newRow("cycle14") << "{% cycle one two as foo %}{% cycle foo %}" << dict << "12" << NoError;
762
763   // TODO: Same name as cycle13 in Django. Fix upstream.
764   dict.clear();
765   dict.insert("test", QVariantList() << 0 << 1 << 2 << 3 << 4);
766   dict.insert("aye", "a");
767   dict.insert("bee", "b");
768   QTest::newRow("cycle15") << "{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}" << dict << "a0,b1,a2,b3,a4," << NoError;
769 }
770
771 void TestDefaultTags::testWidthRatioTag_data()
772 {
773   QTest::addColumn<QString>("input");
774   QTest::addColumn<Dict>("dict");
775   QTest::addColumn<QString>("output");
776   QTest::addColumn<Grantlee::Error>("error");
777
778   Dict dict;
779
780   dict.insert("a", 50);
781   dict.insert("b", 100);
782   QTest::newRow("widthratio01") << "{% widthratio a b 0 %}" << dict << "0" << NoError;
783
784   dict.clear();
785   dict.insert("a", 0);
786   dict.insert("b", 0);
787   QTest::newRow("widthratio02") << "{% widthratio a b 0 %}" << dict << "" << NoError;
788
789   dict.clear();
790   dict.insert("a", 0);
791   dict.insert("b", 100);
792   QTest::newRow("widthratio03") << "{% widthratio a b 100 %}" << dict << "0" << NoError;
793
794   dict.clear();
795   dict.insert("a", 50);
796   dict.insert("b", 100);
797   QTest::newRow("widthratio04") << "{% widthratio a b 100 %}" << dict << "50" << NoError;
798
799   dict.clear();
800   dict.insert("a", 100);
801   dict.insert("b", 100);
802   QTest::newRow("widthratio05") << "{% widthratio a b 100 %}" << dict << "100" << NoError;
803
804   dict.clear();
805   dict.insert("a", 50);
806   dict.insert("b", 80);
807   QTest::newRow("widthratio06") << "{% widthratio a b 100 %}" << dict << "63" << NoError;
808
809   dict.clear();
810   dict.insert("a", 50);
811   dict.insert("b", 70);
812   QTest::newRow("widthratio07") << "{% widthratio a b 100 %}" << dict << "71" << NoError;
813
814   dict.clear();
815 // Raise exception if we don't have 3 args, last one an integer
816   QTest::newRow("widthratio08") << "{% widthratio %}" << dict << "" << TagSyntaxError;
817
818   dict.clear();
819   QTest::newRow("widthratio09") << "{% widthratio a b %}" << dict << "" << TagSyntaxError;
820
821   dict.clear();
822   QTest::newRow("widthratio10") << "{% widthratio a b 100.0 %}" << dict << "" << TagSyntaxError;
823 }
824
825
826 void TestDefaultTags::testFilterTag_data()
827 {
828   QTest::addColumn<QString>("input");
829   QTest::addColumn<Dict>("dict");
830   QTest::addColumn<QString>("output");
831   QTest::addColumn<Grantlee::Error>("error");
832
833   Dict dict;
834
835   QTest::newRow("filter01") << "{% filter upper %}{% endfilter %}" << dict << "" << NoError;
836   QTest::newRow("filter02") << "{% filter upper %}django{% endfilter %}" << dict << "DJANGO" << NoError;
837   QTest::newRow("filter03") << "{% filter upper|lower %}django{% endfilter %}" << dict << "django" << NoError;
838
839   dict.insert("remove", "spam");
840   QTest::newRow("filter04") << "{% filter cut:remove %}djangospam{% endfilter %}" << dict << "django" << NoError;
841
842 }
843
844 void TestDefaultTags::testNowTag_data()
845 {
846   QTest::addColumn<QString>("input");
847   QTest::addColumn<Dict>("dict");
848   QTest::addColumn<QString>("output");
849   QTest::addColumn<Grantlee::Error>("error");
850
851   Dict dict;
852
853   QDate today = QDateTime::currentDateTime().date();
854
855   QTest::newRow("now01") << "{% now \"d M yyyy\"%}" << dict << (QString::number(today.day()) + " " +  QString::number(today.month()) + " " + QString::number(today.year())) << NoError;
856
857
858 }
859
860 void TestDefaultTags::testSpacelessTag_data()
861 {
862   QTest::addColumn<QString>("input");
863   QTest::addColumn<Dict>("dict");
864   QTest::addColumn<QString>("output");
865   QTest::addColumn<Grantlee::Error>("error");
866
867   Dict dict;
868
869   QTest::newRow("spaceless01") << "{% spaceless %} <b>    <i> text </i>    </b> {% endspaceless %}" << dict << "<b><i> text </i></b>" << NoError;
870   QTest::newRow("spaceless02") << "{% spaceless %} <b> \n <i> text </i> \n </b> {% endspaceless %}" << dict << "<b><i> text </i></b>" << NoError;
871   QTest::newRow("spaceless03") << "{% spaceless %}<b><i>text</i></b>{% endspaceless %}" << dict << "<b><i>text</i></b>" << NoError;
872
873 }
874
875 void TestDefaultTags::testRegroupTag_data()
876 {
877   QTest::addColumn<QString>("input");
878   QTest::addColumn<Dict>("dict");
879   QTest::addColumn<QString>("output");
880   QTest::addColumn<Grantlee::Error>("error");
881
882   Dict dict;
883
884   QVariantList list;
885   QVariantMap map;
886
887   map.insert("foo", "c");
888   map.insert("bar", 1);
889   list.append(map);
890
891   map.clear();
892   map.insert("foo", "d");
893   map.insert("bar", 1);
894   list.append(map);
895
896   map.clear();
897   map.insert("foo", "a");
898   map.insert("bar", 2);
899   list.append(map);
900
901   map.clear();
902   map.insert("foo", "b");
903   map.insert("bar", 2);
904   list.append(map);
905
906   map.clear();
907   map.insert("foo", "x");
908   map.insert("bar", 3);
909   list.append(map);
910
911   dict.insert("data", list);
912
913   QTest::newRow("regroup01") << "{% regroup data by bar as grouped %}"
914                                   "{% for group in grouped %}"
915                                     "{{ group.grouper }}:"
916                                     "{% for item in group.list %}"
917                                       "{{ item.foo }}"
918                                     "{% endfor %},"
919                                   "{% endfor %}" << dict << "1:cd,2:ab,3:x," << NoError;
920
921 }
922
923 void TestDefaultTags::testIfChangedTag_data()
924 {
925   QTest::addColumn<QString>("input");
926   QTest::addColumn<Dict>("dict");
927   QTest::addColumn<QString>("output");
928   QTest::addColumn<Grantlee::Error>("error");
929
930   Dict dict;
931
932   dict.insert("num", QVariantList() << 1 << 2 << 3 );
933   QTest::newRow("ifchanged01") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}" << dict << "123" << NoError;
934
935   dict.clear();
936   dict.insert("num", QVariantList() << 1 << 1 << 3 );
937   QTest::newRow("ifchanged02") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}" << dict << "13" << NoError;
938
939   dict.clear();
940   dict.insert("num", QVariantList() << 1 << 1 << 1 );
941   QTest::newRow("ifchanged03") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}" << dict << "1" << NoError;
942
943   dict.clear();
944   dict.insert("num", QVariantList() << 1 << 2 << 3 );
945   dict.insert("numx", QVariantList() << 2 << 2 << 2 );
946   QTest::newRow("ifchanged04") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}" << dict << "122232" << NoError;
947
948   dict.clear();
949   dict.insert("num", QVariantList() << 1 << 1 << 1 );
950   dict.insert("numx", QVariantList() << 1 << 2 << 3 );
951   QTest::newRow("ifchanged05") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}" << dict << "1123123123" << NoError;
952
953   dict.clear();
954   dict.insert("num", QVariantList() << 1 << 1 << 1 );
955   dict.insert("numx", QVariantList() << 2 << 2 << 2 );
956   QTest::newRow("ifchanged06") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}" << dict << "1222" << NoError;
957
958   dict.clear();
959   dict.insert("num", QVariantList() << 1 << 1 << 1 );
960   dict.insert("numx", QVariantList() << 2 << 2 << 2 );
961   dict.insert("numy", QVariantList() << 3 << 3 << 3 );
962   QTest::newRow("ifchanged07") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% for y in numy %}{% ifchanged %}{{ y }}{% endifchanged %}{% endfor %}{% endfor %}{% endfor %}" << dict << "1233323332333" << NoError;
963
964   // datalist': [[(1, 'a'), (1, 'a'), (0, 'b'), (1, 'c')], [(0, 'a'), (1, 'c'), (1, 'd'), (1, 'd'), (0, 'e')]]}
965   dict.clear();
966   QVariantList list;
967   QVariantList innerList;
968   QVariantList tuple;
969   tuple << 1 << "a";
970   innerList.append(QVariant(tuple));
971   tuple.clear();
972   tuple << 1 << "a";
973   innerList.append(QVariant(tuple));
974   tuple.clear();
975   tuple << 0 << "b";
976   innerList.append(QVariant(tuple));
977   tuple.clear();
978   tuple << 1 << "c";
979   innerList.append(QVariant(tuple));
980   tuple.clear();
981   list.append(QVariant(innerList));
982   innerList.clear();
983
984   tuple << 0 << "a";
985   innerList.append(QVariant(tuple));
986   tuple.clear();
987   tuple << 1 << "c";
988   innerList.append(QVariant(tuple));
989   tuple.clear();
990   tuple << 1 << "d";
991   innerList.append(QVariant(tuple));
992   tuple.clear();
993   tuple << 1 << "d";
994   innerList.append(QVariant(tuple));
995   tuple.clear();
996   tuple << 0 << "e";
997   innerList.append(QVariant(tuple));
998   tuple.clear();
999   list.append(QVariant(innerList));
1000   innerList.clear();
1001
1002   dict.insert("datalist", list);
1003   QTest::newRow("ifchanged08") << "{% for data in datalist %}{% for c,d in data %}{% if c %}{% ifchanged %}{{ d }}{% endifchanged %}{% endif %}{% endfor %}{% endfor %}" << dict << "accd" << NoError;
1004
1005 // Test one parameter given to ifchanged.
1006   dict.clear();
1007   dict.insert("num", QVariantList() << 1 << 2 << 3 );
1008   QTest::newRow("ifchanged-param01") << "{% for n in num %}{% ifchanged n %}..{% endifchanged %}{{ n }}{% endfor %}" << dict << "..1..2..3" << NoError;
1009
1010   dict.clear();
1011   dict.insert("num", QVariantList() << 1 << 2 << 3 );
1012   dict.insert("numx", QVariantList() << 5 << 6 << 7 );
1013   QTest::newRow("ifchanged-param02") << "{% for n in num %}{% for x in numx %}{% ifchanged n %}..{% endifchanged %}{{ x }}{% endfor %}{% endfor %}" << dict << "..567..567..567" << NoError;
1014
1015 // Test multiple parameters to ifchanged.
1016
1017   dict.clear();
1018   dict.insert("num", QVariantList() << 1 << 1 << 2 );
1019   dict.insert("numx", QVariantList() << 5 << 6 << 6 );
1020   QTest::newRow("ifchanged-param03") << "{% for n in num %}{{ n }}{% for x in numx %}{% ifchanged x n %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}" << dict << "156156256" << NoError;
1021
1022 // Test a date+hour like construct, where the hour of the last day
1023 // is the same but the date had changed, so print the hour anyway.
1024
1025   dict.clear();
1026   QVariantList days;
1027   QVariantMap day;
1028   day.insert("day", 1);
1029   day.insert("hours", QVariantList() << 1 << 2 << 3 );
1030   days << day;
1031   day.clear();
1032   day.insert("day", 2);
1033   day.insert("hours", QVariantList() << 3 );
1034   days << day;
1035   dict.insert("days", days );
1036   QTest::newRow("ifchanged-param04") << "{% for d in days %}{% ifchanged %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}" << dict << "112323" << NoError;
1037
1038
1039 // Logically the same as above, just written with explicit
1040 // ifchanged for the day.
1041
1042   // TODO: fix name conflict upstream
1043   QTest::newRow("ifchanged-param05") << "{% for d in days %}{% ifchanged d.day %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d.day h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}" << dict << "112323" << NoError;
1044
1045 // Test the else clause of ifchanged.
1046   dict.clear();
1047   dict.insert("ids", QVariantList() << 1 << 1 << 2 << 2 << 2 << 3 );
1048   QTest::newRow("ifchanged-else01") << "{% for id in ids %}{{ id }}{% ifchanged id %}-first{% else %}-other{% endifchanged %},{% endfor %}" << dict << "1-first,1-other,2-first,2-other,2-other,3-first," << NoError;
1049   QTest::newRow("ifchanged-else02") << "{% for id in ids %}{{ id }}-{% ifchanged id %}{% cycle red,blue %}{% else %}grey{% endifchanged %},{% endfor %}" << dict << "1-red,1-grey,2-blue,2-grey,2-grey,3-red," << NoError;
1050   QTest::newRow("ifchanged-else03") << "{% for id in ids %}{{ id }}{% ifchanged id %}-{% cycle red,blue %}{% else %}{% endifchanged %},{% endfor %}" << dict << "1-red,1,2-blue,2,2,3-red," << NoError;
1051
1052   dict.clear();
1053   dict.insert("ids", QVariantList() << 1 << 1 << 2 << 2 << 2 << 3 << 4 );
1054   QTest::newRow("ifchanged-else04") << "{% for id in ids %}{% ifchanged %}***{{ id }}*{% else %}...{% endifchanged %}{{ forloop.counter }}{% endfor %}" << dict << "***1*1...2***2*3...4...5***3*6***4*7" << NoError;
1055
1056 }
1057
1058
1059 QTEST_MAIN(TestDefaultTags)
1060 #include "testdefaulttags.moc"
1061
1062 #endif