1 module tests.statements.for_;
2 
3 private
4 {
5     import tests.asserts;
6 }
7 
8 
9 private struct Dummy
10 {
11     int    num;
12     string str;
13     long[] list;
14 }
15 
16 private immutable long[] list = [1, 2, 3, 4, 5];
17 private auto dict = immutable(Dummy)(1, "str", list);
18 
19 
20 unittest
21 {
22     // Iterate through inline list
23     assertRender(`{% for val in [1,2,3] %}{{val}}{% endfor %}`, "123");
24 
25     // Iterate through inline tuple
26     assertRender(`{% for val in (1,2,3) %}{{val}}{% endfor %}`, "123");
27 
28     // Iterate through inline dict
29     assertRender(
30             `{% for key, val in {a:1, b:2} %}` ~
31             `{{1}}` ~ // Can't check key-val because of an implicit iterating dict order
32             `{% endfor %}`,
33             "11"
34         );
35 }
36 
37 unittest
38 {
39     // Filtering iterated obj
40     assertRender(
41             `{% for i in [1,2,3,4,5] if i % 2 == 1 %}` ~
42                 `{{i}}` ~
43             `{% endfor %}`,
44             "135");
45 
46     // Else block
47     assertRender(
48             `{% for i in [] %}` ~
49                 `{{i}}` ~
50             `{% else %}` ~
51                 `not iterated` ~
52             `{% endfor %}`,
53             "not iterated");
54 
55     assertRender(
56             `{% for i in [1,2,3,4,5] if i > 5 %}` ~
57                 `{{i}}` ~
58             `{% else %}` ~
59                 `else` ~
60             `{% endfor %}`,
61             "else");
62 }
63 
64 unittest
65 {
66     // Recursive iterating
67     assertRender(
68             `{% for i in [1,2,[3,4,[5,6]],7,[8], 9] recursive %}` ~
69                 `{{i if i not is list else loop(i) }}` ~
70             `{% endfor %}`,
71             "123456789");
72 
73     // Recursive iterating with filter
74     assertRender(
75             `{% for i in [1,2,[3,4,[5,6]],7,[8], 9] 
76                                         if i not is number or i % 2 recursive %}` ~
77                 `{{i if i not is list else loop(i) }}` ~
78             `{% endfor %}`,
79             "13579");
80 }
81 
82 unittest
83 {
84     // Check loop.length, loop.index/0, loop.depth/0, loop.revindex/0, loop.first/last
85     assertRender(
86             `{% for i in [1,2,[3,4,[5,6]],7,8,[9]] 
87                                         if i not is number or i % 2 recursive %}` ~
88                 `{% if i is list%}` ~
89                     `{{loop(i)}}` ~
90                 `{% else %}` ~
91                     `{{loop.length}},` ~
92                     `{{loop.index}},{{loop.index0}},` ~
93                     `{{loop.depth}},{{loop.depth0}},` ~
94                     `{{loop.revindex}},{{loop.revindex0}},` ~
95                     `{{loop.first}},{{loop.last}}` ~
96                 `{% endif %}` ~
97             `{% endfor %}`,
98 
99             "4,1,0,1,0,4,3,true,false" ~
100             "2,1,0,2,1,2,1,true,false" ~
101             "1,1,0,3,2,1,0,true,true" ~
102             "4,3,2,1,0,2,1,false,false" ~
103             "1,1,0,2,1,1,0,true,true"
104         );
105 
106     // Check loop.previtem, loop.nextitem
107     assertRender(
108             `{% for i in [1,2,[3,4,[5,6]],7,8,[9]] 
109                                         if i not is number or i % 2 recursive %}` ~
110                 `{% if i is list%}` ~
111                     `{{loop(i)}}` ~
112                 `{% else %}` ~
113                     `curr: '{{i}}', prev: '{{loop.previtem}}', next: '{{loop.nextitem}}'` ~
114                 `{% endif %}` ~
115             `{% endfor %}`,
116 
117             "curr: '1', prev: '', next: '[3, 4, [5, 6]]'" ~
118             "curr: '3', prev: '', next: '[5, 6]'" ~
119             "curr: '5', prev: '', next: ''" ~
120             "curr: '7', prev: '[3, 4, [5, 6]]', next: '[9]'" ~
121             "curr: '9', prev: '', next: ''"
122         );
123 
124     // Check loop.cycle, loop.changed
125     assertRender(
126             `{% for i in [1,2,3,3,4,4,5,6,7] %}` ~
127                 `{{loop.cycle(1,2)}},{{loop.cycle(1,2,3)}},{{loop.changed(i)}}` ~
128             `{% endfor %}`,
129 
130             "1,1,true" ~
131             "2,2,true" ~
132             "1,3,true" ~
133             "2,1,false" ~
134             "1,2,true" ~
135             "2,3,false" ~
136             "1,1,true" ~
137             "2,2,true" ~
138             "1,3,true"
139         );
140 }