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