QVariantMap -> QVariantHash. KDevelop rocks.
[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 = new Template(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   QVariantHash hash;
490   hash.insert("one", 1);
491   hash.insert("two", 2);
492   dict.insert("items", hash);
493   QTest::newRow("for-tag-unpack-dict01") << "{% for key,value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
494
495   QTest::newRow("for-tag-unpack-dict03") << "{% for key, value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
496   QTest::newRow("for-tag-unpack-dict04") << "{% for key , value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
497   QTest::newRow("for-tag-unpack-dict05") << "{% for key ,value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
498   QTest::newRow("for-tag-unpack-dict06") << "{% for key value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
499   QTest::newRow("for-tag-unpack-dict07") << "{% for key,,value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
500   QTest::newRow("for-tag-unpack-dict08") << "{% 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-unpack-dict09") << "{% for val in items %}{{ val.0 }}:{{ val.1 }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
504
505   dict.clear();
506   list.clear();
507   QVariantList innerList;
508   innerList << "one" << 1;
509   list.append(QVariant(innerList));
510   innerList.clear();
511   innerList << "two" << 2;
512   list.append(QVariant(innerList));
513   dict.insert("items", list);
514   QTest::newRow("for-tag-unpack01") << "{% for key,value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
515
516   QTest::newRow("for-tag-unpack03") << "{% for key, value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
517   QTest::newRow("for-tag-unpack04") << "{% for key , value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
518   QTest::newRow("for-tag-unpack05") << "{% for key ,value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
519   QTest::newRow("for-tag-unpack06") << "{% for key value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
520   QTest::newRow("for-tag-unpack07") << "{% for key,,value in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
521   QTest::newRow("for-tag-unpack08") << "{% for key,value, in items %}{{ key }}:{{ value }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
522
523   // Ensure that a single loopvar doesn't truncate the list in val.
524   QTest::newRow("for-tag-unpack09") << "{% for val in items %}{{ val.0 }}:{{ val.1 }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
525
526 // Otherwise, silently truncate if the length of loopvars differs to the length of each set of items.
527
528   dict.clear();
529   list.clear();
530   innerList.clear();
531   innerList << "one" << 1 << "carrot";
532   list.append(QVariant(innerList));
533   innerList.clear();
534   innerList << "two" << 2 << "orange";
535   list.append(QVariant(innerList));
536   dict.insert("items", list);
537
538   QTest::newRow("for-tag-unpack10") << "{% for x,y in items %}{{ x }}:{{ y }}/{% endfor %}" << dict << "one:1/two:2/" << NoError;
539
540   dict.clear();
541   list.clear();
542   innerList.clear();
543   innerList << "one" << 1;
544   list.append(QVariant(innerList));
545   innerList.clear();
546   innerList << "two" << 2;
547   list.append(QVariant(innerList));
548   dict.insert("items", list);
549
550   QTest::newRow("for-tag-unpack11") << "{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}" << dict << "one:1,/two:2,/" << NoError;
551
552   dict.clear();
553   list.clear();
554   innerList.clear();
555   innerList << "one" << 1 << "carrot";
556   list.append(QVariant(innerList));
557   innerList.clear();
558   innerList << "two" << 2;
559   list.append(QVariant(innerList));
560   dict.insert("items", list);
561
562   QTest::newRow("for-tag-unpack12") << "{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}" << dict << "one:1,carrot/two:2,/" << NoError;
563
564   dict.clear();
565   list.clear();
566   innerList.clear();
567   innerList << "one" << 1 << "carrot";
568   list.append(QVariant(innerList));
569   innerList.clear();
570   innerList << "two" << 2 << "cheese";
571   list.append(QVariant(innerList));
572
573   dict.insert("items", list);
574
575   QTest::newRow("for-tag-unpack13") << "{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}" << dict << "one:1,carrot/two:2,cheese/" << NoError;
576
577 // Empty tag:
578
579   dict.clear();
580   dict.insert("values", QVariantList() << 1 << 2 << 3 );
581   QTest::newRow("for-tag-empty01") << "{% for val in values %}{{ val }}{% empty %}empty text{% endfor %}" << dict << "123" << NoError;
582
583   dict.clear();
584   dict.insert("values", QVariantList());
585   QTest::newRow("for-tag-empty02") << "{% for val in values %}{{ val }}{% empty %}values array empty{% endfor %}" << dict << "values array empty" << NoError;
586
587   dict.clear();
588   QTest::newRow("for-tag-empty03") << "{% for val in values %}{{ val }}{% empty %}values array not found{% endfor %}" << dict << "values array not found" << NoError;
589
590 }
591
592 void TestDefaultTags::testIfEqualTag_data()
593 {
594   QTest::addColumn<QString>("input");
595   QTest::addColumn<Dict>("dict");
596   QTest::addColumn<QString>("output");
597   QTest::addColumn<Grantlee::Error>("error");
598
599   Dict dict;
600
601   dict.insert("a", 1);
602   dict.insert("b", 2);
603
604   QTest::newRow("ifequal01") << "{% ifequal a b %}yes{% endifequal %}" << dict << "" << NoError;
605   QTest::newRow("ifequal03") << "{% ifequal a b %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
606
607   dict.clear();
608   dict.insert("a", 1);
609   dict.insert("b", 1);
610
611   QTest::newRow("ifequal02") << "{% ifequal a b %}yes{% endifequal %}" << dict << "yes" << NoError;
612   QTest::newRow("ifequal04") << "{% ifequal a b %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
613
614   dict.clear();
615   dict.insert("a", "test");
616
617   QTest::newRow("ifequal05") << "{% ifequal a 'test' %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
618
619   dict.clear();
620   dict.insert("a", "no");
621
622   QTest::newRow("ifequal06") << "{% ifequal a 'test' %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
623
624   dict.clear();
625   dict.insert("a", "test");
626
627   QTest::newRow("ifequal07") << "{% ifequal a \"test\" %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
628
629   dict.clear();
630   dict.insert("a", "no");
631
632   QTest::newRow("ifequal08") << "{% ifequal a \"test\" %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
633
634   dict.clear();
635
636   QTest::newRow("ifequal09") << "{% ifequal a \"test\" %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
637
638   QTest::newRow("ifequal10") << "{% ifequal a b %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
639
640
641   QTest::newRow("ifequal-split01") << "{% ifequal a \"test man\" %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
642
643   dict.insert("a", "foo");
644   QTest::newRow("ifequal-split01") << "{% ifequal a \"test man\" %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
645   QTest::newRow("ifequal-split02") << "{% ifequal a \"test man\" %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
646
647   dict.clear();
648   dict.insert("a", "test man");
649   QTest::newRow("ifequal-split03") << "{% ifequal a \"test man\" %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
650   QTest::newRow("ifequal-split04") << "{% ifequal a 'test man' %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
651
652   dict.clear();
653   dict.insert("a", "");
654   QTest::newRow("ifequal-split05") << "{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
655
656   dict.clear();
657   dict.insert("a", "i \"love\" you");
658   QTest::newRow("ifequal-split06") << "{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
659
660   dict.clear();
661   dict.insert("a", "i love you");
662   QTest::newRow("ifequal-split07") << "{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
663
664   dict.clear();
665   dict.insert("a", "I'm happy");
666   QTest::newRow("ifequal-split08") << "{% ifequal a 'I\\'m happy' %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
667
668   dict.clear();
669   dict.insert("a", "slash\\man");
670   QTest::newRow("ifequal-split09") << "{% ifequal a 'slash\\man' %}yes{% else %}no{% endifequal %}" << dict << "yes" << NoError;
671
672   dict.clear();
673   dict.insert("a", "slashman");
674   QTest::newRow("ifequal-split10") << "{% ifequal a 'slash\\man' %}yes{% else %}no{% endifequal %}" << dict << "no" << NoError;
675 // NUMERIC RESOLUTION
676
677   dict.clear();
678   dict.insert("x", "5");
679
680   QTest::newRow("ifequal-numeric01") << "{% ifequal x 5 %}yes{% endifequal %}" << dict << "" << NoError;
681
682   dict.clear();
683   dict.insert("x", 5);
684   QTest::newRow("ifequal-numeric02") << "{% ifequal x 5 %}yes{% endifequal %}" << dict << "yes" << NoError;
685
686   dict.clear();
687   dict.insert("x", 5.2);
688   QTest::newRow("ifequal-numeric03") << "{% ifequal x 5 %}yes{% endifequal %}" << dict << "" << NoError;
689   QTest::newRow("ifequal-numeric04") << "{% ifequal x 5.2 %}yes{% endifequal %}" << dict << "yes" << NoError;
690
691   dict.clear();
692   dict.insert("x", .2);
693
694   QTest::newRow("ifequal-numeric05") << "{% ifequal x 0.2 %}yes{% endifequal %}" << dict << "yes" << NoError;
695   QTest::newRow("ifequal-numeric06") << "{% ifequal x .2 %}yes{% endifequal %}" << dict << "yes" << NoError;
696
697   dict.clear();
698   dict.insert("x", 2);
699
700   QTest::newRow("ifequal-numeric07") << "{% ifequal x 2. %}yes{% endifequal %}" << dict << "" << NoError;
701
702   dict.clear();
703   dict.insert("x", 5);
704   QTest::newRow("ifequal-numeric08") << "{% ifequal x \"5\" %}yes{% endifequal %}" << dict << "" << NoError;
705
706   dict.clear();
707   dict.insert("x", "5");
708   QTest::newRow("ifequal-numeric09") << "{% ifequal x \"5\" %}yes{% endifequal %}" << dict << "yes" << NoError;
709
710   dict.clear();
711   dict.insert("x", -5);
712   QTest::newRow("ifequal-numeric10") << "{% ifequal x -5 %}yes{% endifequal %}" << dict << "yes" << NoError;
713
714   dict.clear();
715   dict.insert("x", -5.2);
716   QTest::newRow("ifequal-numeric11") << "{% ifequal x -5.2 %}yes{% endifequal %}" << dict << "yes" << NoError;
717
718   dict.clear();
719   dict.insert("x", 5);
720   QTest::newRow("ifequal-numeric12") << "{% ifequal x +5 %}yes{% endifequal %}" << dict << "yes" << NoError;
721
722
723   // FILTER EXPRESSIONS AS ARGUMENTS
724
725   dict.clear();
726   dict.insert("a", "a");
727   QTest::newRow("ifequal-filter01") << "{% ifequal a|upper \"A\" %}x{% endifequal %}" << dict << "x" << NoError;
728
729   QTest::newRow("ifequal-filter02") << "{% ifequal \"A\" a|upper %}x{% endifequal %}" << dict << "x" << NoError;
730
731   dict.clear();
732   dict.insert("a", "x");
733   dict.insert("b", "X");
734
735   QTest::newRow("ifequal-filter03") << "{% ifequal a|upper b|upper %}x{% endifequal %}" << dict << "x" << NoError;
736
737   dict.clear();
738   dict.insert("x", "aaa");
739
740   QTest::newRow("ifequal-filter04") << "{% ifequal x|slice:\"1\" \"a\" %}x{% endifequal %}" << dict << "x" << NoError;
741
742   dict.clear();
743   dict.insert("x", "aaa");
744
745   QTest::newRow("ifequal-filter05") << "{% ifequal x|slice:\"1\"|upper \"A\" %}x{% endifequal %}" << dict << "x" << NoError;
746
747 }
748
749 void TestDefaultTags::testIfNotEqualTag_data()
750 {
751   QTest::addColumn<QString>("input");
752   QTest::addColumn<Dict>("dict");
753   QTest::addColumn<QString>("output");
754   QTest::addColumn<Grantlee::Error>("error");
755
756   Dict dict;
757
758   dict.insert("a", 1);
759   dict.insert("b", 2);
760
761   QTest::newRow("ifnotequal01") << "{% ifnotequal a b %}yes{% endifnotequal %}" << dict << "yes" << NoError;
762   QTest::newRow("ifnotequal03") << "{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}" << dict << "yes" << NoError;
763
764   dict.clear();
765   dict.insert("a", 1);
766   dict.insert("b", 1);
767
768   QTest::newRow("ifnotequal02") << "{% ifnotequal a b %}yes{% endifnotequal %}" << dict << "" << NoError;
769   QTest::newRow("ifnotequal04") << "{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}" << dict << "no" << NoError;
770
771 }
772
773 void TestDefaultTags::testTemplateTagTag_data()
774 {
775   QTest::addColumn<QString>("input");
776   QTest::addColumn<Dict>("dict");
777   QTest::addColumn<QString>("output");
778   QTest::addColumn<Grantlee::Error>("error");
779
780   Dict dict;
781
782   QTest::newRow("templatetag01") << "{% templatetag openblock %}" << dict << "{%" << NoError;
783   QTest::newRow("templatetag02") << "{% templatetag closeblock %}" << dict << "%}" << NoError;
784   QTest::newRow("templatetag03") << "{% templatetag openvariable %}" << dict << "{{" << NoError;
785   QTest::newRow("templatetag04") << "{% templatetag closevariable %}" << dict << "}}" << NoError;
786   QTest::newRow("templatetag05") << "{% templatetag %}" << dict << "" << TagSyntaxError;
787   QTest::newRow("templatetag06") << "{% templatetag foo %}" << dict << "" << TagSyntaxError;
788   QTest::newRow("templatetag07") << "{% templatetag openbrace %}" << dict << "{" << NoError;
789   QTest::newRow("templatetag08") << "{% templatetag closebrace %}" << dict << "}" << NoError;
790   QTest::newRow("templatetag09") << "{% templatetag openbrace %}{% templatetag openbrace %}" << dict << "{{" << NoError;
791   QTest::newRow("templatetag10") << "{% templatetag closebrace %}{% templatetag closebrace %}" << dict << "}}" << NoError;
792   QTest::newRow("templatetag11") << "{% templatetag opencomment %}" << dict << "{#" << NoError;
793   QTest::newRow("templatetag12") << "{% templatetag closecomment %}" << dict << "#}" << NoError;
794
795 }
796
797 void TestDefaultTags::testWithTag_data()
798 {
799   QTest::addColumn<QString>("input");
800   QTest::addColumn<Dict>("dict");
801   QTest::addColumn<QString>("output");
802   QTest::addColumn<Grantlee::Error>("error");
803
804   Dict dict;
805
806   QVariantHash hash;
807   hash.insert("key", 50);
808   dict.insert("dict", hash);
809   QTest::newRow("with01") << "{% with dict.key as key %}{{ key }}{% endwith %}" << dict << "50" << NoError;
810   QTest::newRow("with02")
811         << "{{ key }}{% with dict.key as key %}{{ key }}-{{ dict.key }}-{{ key }}{% endwith %}{{ key }}"
812         << dict << "50-50-50" << NoError;
813   QTest::newRow("with03") << "{% with dict.key xx key %}{{ key }}{% endwith %}" << dict << "" << TagSyntaxError;
814   QTest::newRow("with04") << "{% with dict.key as %}{{ key }}{% endwith %}" << dict << "" << TagSyntaxError;
815 }
816
817 void TestDefaultTags::testCycleTag_data()
818 {
819   QTest::addColumn<QString>("input");
820   QTest::addColumn<Dict>("dict");
821   QTest::addColumn<QString>("output");
822   QTest::addColumn<Grantlee::Error>("error");
823
824   Dict dict;
825
826   QTest::newRow("cycle01") << "{% cycle a %}" << dict << "" << TagSyntaxError;
827   QTest::newRow("cycle02") << "{% cycle a,b,c as abc %}{% cycle abc %}" << dict << "ab" << NoError;
828   QTest::newRow("cycle03") << "{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}" << dict << "abc" << NoError;
829   QTest::newRow("cycle04") << "{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}" << dict << "abca" << NoError;
830   QTest::newRow("cycle05") << "{% cycle a %}" << dict << "" << TagSyntaxError;
831   // TODO: This is the same as cycle01. Remove.
832   QTest::newRow("cycle06") << "{% cycle a %}" << dict << "" << TagSyntaxError;
833   QTest::newRow("cycle07") << "{% cycle a,b,c as foo %}{% cycle bar %}" << dict << "" << TagSyntaxError;
834   QTest::newRow("cycle08") << "{% cycle a,b,c as foo %}{% cycle foo %}{{ foo }}{{ foo }}{% cycle foo %}{{ foo }}" << dict << "abbbcc" << NoError;
835
836   dict.insert("test", QVariantList() << 0 << 1 << 2 << 3 << 4);
837   QTest::newRow("cycle09") << "{% for i in test %}{% cycle a,b %}{{ i }},{% endfor %}" << dict << "a0,b1,a2,b3,a4," << NoError;
838
839   dict.clear();
840   QTest::newRow("cycle10") << "{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}" << dict << "ab" << NoError;
841   QTest::newRow("cycle11") << "{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}" << dict << "abc" << NoError;
842   QTest::newRow("cycle12") << "{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}" << dict << "abca" << NoError;
843
844   dict.insert("test", QVariantList() << 0 << 1 << 2 << 3 << 4);
845   QTest::newRow("cycle13") << "{% for i in test %}{% cycle 'a' 'b' %}{{ i }},{% endfor %}" << dict << "a0,b1,a2,b3,a4," << NoError;
846
847   dict.clear();
848   dict.insert("one", "1");
849   dict.insert("two", "2");
850   QTest::newRow("cycle14") << "{% cycle one two as foo %}{% cycle foo %}" << dict << "12" << NoError;
851
852   dict.clear();
853   dict.insert("test", QVariantList() << 0 << 1 << 2 << 3 << 4);
854   dict.insert("aye", "a");
855   dict.insert("bee", "b");
856   QTest::newRow("cycle15") << "{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}" << dict << "a0,b1,a2,b3,a4," << NoError;
857
858   dict.clear();
859   dict.insert("one", "A");
860   dict.insert("two", "2");
861   QTest::newRow("cycle16") << "{% cycle one|lower two as foo %}{% cycle foo %}" << dict << "a2" << NoError;
862 }
863
864 void TestDefaultTags::testWidthRatioTag_data()
865 {
866   QTest::addColumn<QString>("input");
867   QTest::addColumn<Dict>("dict");
868   QTest::addColumn<QString>("output");
869   QTest::addColumn<Grantlee::Error>("error");
870
871   Dict dict;
872
873   dict.insert("a", 50);
874   dict.insert("b", 100);
875   QTest::newRow("widthratio01") << "{% widthratio a b 0 %}" << dict << "0" << NoError;
876
877   dict.clear();
878   dict.insert("a", 0);
879   dict.insert("b", 0);
880   QTest::newRow("widthratio02") << "{% widthratio a b 0 %}" << dict << "" << NoError;
881
882   dict.clear();
883   dict.insert("a", 0);
884   dict.insert("b", 100);
885   QTest::newRow("widthratio03") << "{% widthratio a b 100 %}" << dict << "0" << NoError;
886
887   dict.clear();
888   dict.insert("a", 50);
889   dict.insert("b", 100);
890   QTest::newRow("widthratio04") << "{% widthratio a b 100 %}" << dict << "50" << NoError;
891
892   dict.clear();
893   dict.insert("a", 100);
894   dict.insert("b", 100);
895   QTest::newRow("widthratio05") << "{% widthratio a b 100 %}" << dict << "100" << NoError;
896
897   dict.clear();
898   dict.insert("a", 50);
899   dict.insert("b", 80);
900   QTest::newRow("widthratio06") << "{% widthratio a b 100 %}" << dict << "63" << NoError;
901
902   dict.clear();
903   dict.insert("a", 50);
904   dict.insert("b", 70);
905   QTest::newRow("widthratio07") << "{% widthratio a b 100 %}" << dict << "71" << NoError;
906
907   dict.clear();
908 // Raise exception if we don't have 3 args, last one an integer
909   QTest::newRow("widthratio08") << "{% widthratio %}" << dict << "" << TagSyntaxError;
910
911   dict.clear();
912   QTest::newRow("widthratio09") << "{% widthratio a b %}" << dict << "" << TagSyntaxError;
913
914   dict.clear();
915   dict.insert("a", 50);
916   dict.insert("b", 100);
917   QTest::newRow("widthratio10") << "{% widthratio a b 100.0 %}" << dict << "50" << NoError;
918
919   dict.clear();
920   dict.insert("a", 50);
921   dict.insert("b", 100);
922   dict.insert("c", 100);
923   QTest::newRow("widthratio11") << "{% widthratio a b c %}" << dict << "50" << NoError;
924
925 }
926
927
928 void TestDefaultTags::testFilterTag_data()
929 {
930   QTest::addColumn<QString>("input");
931   QTest::addColumn<Dict>("dict");
932   QTest::addColumn<QString>("output");
933   QTest::addColumn<Grantlee::Error>("error");
934
935   Dict dict;
936
937   QTest::newRow("filter01") << "{% filter upper %}{% endfilter %}" << dict << "" << NoError;
938   QTest::newRow("filter02") << "{% filter upper %}django{% endfilter %}" << dict << "DJANGO" << NoError;
939   QTest::newRow("filter03") << "{% filter upper|lower %}django{% endfilter %}" << dict << "django" << NoError;
940
941   dict.insert("remove", "spam");
942   QTest::newRow("filter04") << "{% filter cut:remove %}djangospam{% endfilter %}" << dict << "django" << NoError;
943
944 }
945
946 void TestDefaultTags::testNowTag_data()
947 {
948   QTest::addColumn<QString>("input");
949   QTest::addColumn<Dict>("dict");
950   QTest::addColumn<QString>("output");
951   QTest::addColumn<Grantlee::Error>("error");
952
953   Dict dict;
954
955   QDate today = QDateTime::currentDateTime().date();
956
957   QTest::newRow("now01") << "{% now \"d M yyyy\"%}" << dict << (QString::number(today.day()) + " " +  QString::number(today.month()) + " " + QString::number(today.year())) << NoError;
958
959
960 }
961
962 void TestDefaultTags::testSpacelessTag_data()
963 {
964   QTest::addColumn<QString>("input");
965   QTest::addColumn<Dict>("dict");
966   QTest::addColumn<QString>("output");
967   QTest::addColumn<Grantlee::Error>("error");
968
969   Dict dict;
970
971   QTest::newRow("spaceless01") << "{% spaceless %} <b>    <i> text </i>    </b> {% endspaceless %}" << dict << "<b><i> text </i></b>" << NoError;
972   QTest::newRow("spaceless02") << "{% spaceless %} <b> \n <i> text </i> \n </b> {% endspaceless %}" << dict << "<b><i> text </i></b>" << NoError;
973   QTest::newRow("spaceless03") << "{% spaceless %}<b><i>text</i></b>{% endspaceless %}" << dict << "<b><i>text</i></b>" << NoError;
974
975 }
976
977 void TestDefaultTags::testRegroupTag_data()
978 {
979   QTest::addColumn<QString>("input");
980   QTest::addColumn<Dict>("dict");
981   QTest::addColumn<QString>("output");
982   QTest::addColumn<Grantlee::Error>("error");
983
984   Dict dict;
985
986   QVariantList list;
987   QVariantHash hash;
988
989   hash.insert("foo", "c");
990   hash.insert("bar", 1);
991   list.append(hash);
992
993   hash.clear();
994   hash.insert("foo", "d");
995   hash.insert("bar", 1);
996   list.append(hash);
997
998   hash.clear();
999   hash.insert("foo", "a");
1000   hash.insert("bar", 2);
1001   list.append(hash);
1002
1003   hash.clear();
1004   hash.insert("foo", "b");
1005   hash.insert("bar", 2);
1006   list.append(hash);
1007
1008   hash.clear();
1009   hash.insert("foo", "x");
1010   hash.insert("bar", 3);
1011   list.append(hash);
1012
1013   dict.insert("data", list);
1014
1015   QTest::newRow("regroup01") << "{% regroup data by bar as grouped %}"
1016                                   "{% for group in grouped %}"
1017                                     "{{ group.grouper }}:"
1018                                     "{% for item in group.list %}"
1019                                       "{{ item.foo }}"
1020                                     "{% endfor %},"
1021                                   "{% endfor %}" << dict << "1:cd,2:ab,3:x," << NoError;
1022
1023 }
1024
1025 void TestDefaultTags::testIfChangedTag_data()
1026 {
1027   QTest::addColumn<QString>("input");
1028   QTest::addColumn<Dict>("dict");
1029   QTest::addColumn<QString>("output");
1030   QTest::addColumn<Grantlee::Error>("error");
1031
1032   Dict dict;
1033
1034   dict.insert("num", QVariantList() << 1 << 2 << 3 );
1035   QTest::newRow("ifchanged01") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}" << dict << "123" << NoError;
1036
1037   dict.clear();
1038   dict.insert("num", QVariantList() << 1 << 1 << 3 );
1039   QTest::newRow("ifchanged02") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}" << dict << "13" << NoError;
1040
1041   dict.clear();
1042   dict.insert("num", QVariantList() << 1 << 1 << 1 );
1043   QTest::newRow("ifchanged03") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}" << dict << "1" << NoError;
1044
1045   dict.clear();
1046   dict.insert("num", QVariantList() << 1 << 2 << 3 );
1047   dict.insert("numx", QVariantList() << 2 << 2 << 2 );
1048   QTest::newRow("ifchanged04") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}" << dict << "122232" << NoError;
1049
1050   dict.clear();
1051   dict.insert("num", QVariantList() << 1 << 1 << 1 );
1052   dict.insert("numx", QVariantList() << 1 << 2 << 3 );
1053   QTest::newRow("ifchanged05") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}" << dict << "1123123123" << NoError;
1054
1055   dict.clear();
1056   dict.insert("num", QVariantList() << 1 << 1 << 1 );
1057   dict.insert("numx", QVariantList() << 2 << 2 << 2 );
1058   QTest::newRow("ifchanged06") << "{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}" << dict << "1222" << NoError;
1059
1060   dict.clear();
1061   dict.insert("num", QVariantList() << 1 << 1 << 1 );
1062   dict.insert("numx", QVariantList() << 2 << 2 << 2 );
1063   dict.insert("numy", QVariantList() << 3 << 3 << 3 );
1064   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;
1065
1066   // datalist': [[(1, 'a'), (1, 'a'), (0, 'b'), (1, 'c')], [(0, 'a'), (1, 'c'), (1, 'd'), (1, 'd'), (0, 'e')]]}
1067   dict.clear();
1068   QVariantList list;
1069   QVariantList innerList;
1070   QVariantList tuple;
1071   tuple << 1 << "a";
1072   innerList.append(QVariant(tuple));
1073   tuple.clear();
1074   tuple << 1 << "a";
1075   innerList.append(QVariant(tuple));
1076   tuple.clear();
1077   tuple << 0 << "b";
1078   innerList.append(QVariant(tuple));
1079   tuple.clear();
1080   tuple << 1 << "c";
1081   innerList.append(QVariant(tuple));
1082   tuple.clear();
1083   list.append(QVariant(innerList));
1084   innerList.clear();
1085
1086   tuple << 0 << "a";
1087   innerList.append(QVariant(tuple));
1088   tuple.clear();
1089   tuple << 1 << "c";
1090   innerList.append(QVariant(tuple));
1091   tuple.clear();
1092   tuple << 1 << "d";
1093   innerList.append(QVariant(tuple));
1094   tuple.clear();
1095   tuple << 1 << "d";
1096   innerList.append(QVariant(tuple));
1097   tuple.clear();
1098   tuple << 0 << "e";
1099   innerList.append(QVariant(tuple));
1100   tuple.clear();
1101   list.append(QVariant(innerList));
1102   innerList.clear();
1103
1104   dict.insert("datalist", list);
1105   QTest::newRow("ifchanged08") << "{% for data in datalist %}{% for c,d in data %}{% if c %}{% ifchanged %}{{ d }}{% endifchanged %}{% endif %}{% endfor %}{% endfor %}" << dict << "accd" << NoError;
1106
1107 // Test one parameter given to ifchanged.
1108   dict.clear();
1109   dict.insert("num", QVariantList() << 1 << 2 << 3 );
1110   QTest::newRow("ifchanged-param01") << "{% for n in num %}{% ifchanged n %}..{% endifchanged %}{{ n }}{% endfor %}" << dict << "..1..2..3" << NoError;
1111
1112   dict.clear();
1113   dict.insert("num", QVariantList() << 1 << 2 << 3 );
1114   dict.insert("numx", QVariantList() << 5 << 6 << 7 );
1115   QTest::newRow("ifchanged-param02") << "{% for n in num %}{% for x in numx %}{% ifchanged n %}..{% endifchanged %}{{ x }}{% endfor %}{% endfor %}" << dict << "..567..567..567" << NoError;
1116
1117 // Test multiple parameters to ifchanged.
1118
1119   dict.clear();
1120   dict.insert("num", QVariantList() << 1 << 1 << 2 );
1121   dict.insert("numx", QVariantList() << 5 << 6 << 6 );
1122   QTest::newRow("ifchanged-param03") << "{% for n in num %}{{ n }}{% for x in numx %}{% ifchanged x n %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}" << dict << "156156256" << NoError;
1123
1124 // Test a date+hour like construct, where the hour of the last day
1125 // is the same but the date had changed, so print the hour anyway.
1126
1127   dict.clear();
1128   QVariantList days;
1129   QVariantHash hash;
1130   hash.insert("day", 1);
1131   hash.insert("hours", QVariantList() << 1 << 2 << 3 );
1132   days << hash;
1133   hash.clear();
1134   hash.insert("day", 2);
1135   hash.insert("hours", QVariantList() << 3 );
1136   days << hash;
1137   dict.insert("days", days );
1138   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;
1139
1140
1141 // Logically the same as above, just written with explicit
1142 // ifchanged for the day.
1143
1144   // TODO: fix name conflict upstream
1145   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;
1146
1147 // Test the else clause of ifchanged.
1148   dict.clear();
1149   dict.insert("ids", QVariantList() << 1 << 1 << 2 << 2 << 2 << 3 );
1150   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;
1151   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;
1152   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;
1153
1154   dict.clear();
1155   dict.insert("ids", QVariantList() << 1 << 1 << 2 << 2 << 2 << 3 << 4 );
1156   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;
1157
1158 }
1159
1160
1161 QTEST_MAIN(TestDefaultTags)
1162 #include "testdefaulttags.moc"
1163
1164 #endif