python-liquid 2.0.0__py3-none-any.whl → 2.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. liquid/__init__.py +1 -1
  2. liquid/builtin/expressions/loop.py +2 -5
  3. liquid/builtin/loaders/mixins.py +1 -2
  4. liquid/extra/tags/macro_tag.py +2 -0
  5. liquid/messages.py +1 -1
  6. liquid/static_analysis.py +16 -10
  7. {python_liquid-2.0.0.dist-info → python_liquid-2.0.2.dist-info}/METADATA +6 -9
  8. python_liquid-2.0.2.dist-info/RECORD +95 -0
  9. liquid/golden/__init__.py +0 -173
  10. liquid/golden/abs_filter.py +0 -73
  11. liquid/golden/append_filter.py +0 -43
  12. liquid/golden/assign_tag.py +0 -45
  13. liquid/golden/at_least_filter.py +0 -78
  14. liquid/golden/at_most_filter.py +0 -68
  15. liquid/golden/base64_decode_filter.py +0 -43
  16. liquid/golden/base64_encode_filter.py +0 -42
  17. liquid/golden/base64_url_safe_decode_filter.py +0 -43
  18. liquid/golden/base64_url_safe_encode_filter.py +0 -42
  19. liquid/golden/capitalize_filter.py +0 -27
  20. liquid/golden/capture_tag.py +0 -39
  21. liquid/golden/case.py +0 -28
  22. liquid/golden/case_tag.py +0 -226
  23. liquid/golden/ceil_filter.py +0 -63
  24. liquid/golden/comment_tag.py +0 -119
  25. liquid/golden/compact_filter.py +0 -54
  26. liquid/golden/concat_filter.py +0 -63
  27. liquid/golden/cycle_tag.py +0 -114
  28. liquid/golden/date_filter.py +0 -63
  29. liquid/golden/decrement_tag.py +0 -16
  30. liquid/golden/default_filter.py +0 -112
  31. liquid/golden/divided_by_filter.py +0 -101
  32. liquid/golden/doc_tag.py +0 -61
  33. liquid/golden/downcase_filter.py +0 -27
  34. liquid/golden/echo_tag.py +0 -116
  35. liquid/golden/escape_filter.py +0 -27
  36. liquid/golden/escape_once_filter.py +0 -32
  37. liquid/golden/find_filter.py +0 -90
  38. liquid/golden/find_index_filter.py +0 -96
  39. liquid/golden/first_filter.py +0 -51
  40. liquid/golden/floor_filter.py +0 -63
  41. liquid/golden/for_tag.py +0 -642
  42. liquid/golden/has_filter.py +0 -139
  43. liquid/golden/identifiers.py +0 -249
  44. liquid/golden/if_tag.py +0 -531
  45. liquid/golden/ifchanged_tag.py +0 -46
  46. liquid/golden/illegal.py +0 -34
  47. liquid/golden/include_tag.py +0 -196
  48. liquid/golden/increment_tag.py +0 -48
  49. liquid/golden/inline_comment_tag.py +0 -127
  50. liquid/golden/join_filter.py +0 -69
  51. liquid/golden/last_filter.py +0 -51
  52. liquid/golden/liquid_tag.py +0 -215
  53. liquid/golden/lstrip_filter.py +0 -37
  54. liquid/golden/map_filter.py +0 -50
  55. liquid/golden/minus_filter.py +0 -58
  56. liquid/golden/modulo_filter.py +0 -60
  57. liquid/golden/newline_to_br_filter.py +0 -37
  58. liquid/golden/not_liquid.py +0 -16
  59. liquid/golden/output_statement.py +0 -295
  60. liquid/golden/plus_filter.py +0 -63
  61. liquid/golden/prepend_filter.py +0 -43
  62. liquid/golden/range_objects.py +0 -79
  63. liquid/golden/raw_tag.py +0 -31
  64. liquid/golden/reject_filter.py +0 -268
  65. liquid/golden/remove_filter.py +0 -45
  66. liquid/golden/remove_first_filter.py +0 -46
  67. liquid/golden/remove_last_filter.py +0 -46
  68. liquid/golden/render_tag.py +0 -210
  69. liquid/golden/replace_filter.py +0 -65
  70. liquid/golden/replace_first_filter.py +0 -59
  71. liquid/golden/replace_last_filter.py +0 -60
  72. liquid/golden/reverse_filter.py +0 -42
  73. liquid/golden/round_filter.py +0 -87
  74. liquid/golden/rstrip_filter.py +0 -37
  75. liquid/golden/size_filter.py +0 -42
  76. liquid/golden/slice_filter.py +0 -119
  77. liquid/golden/sort_filter.py +0 -86
  78. liquid/golden/sort_natural_filter.py +0 -105
  79. liquid/golden/special.py +0 -91
  80. liquid/golden/split_filter.py +0 -128
  81. liquid/golden/strip_filter.py +0 -37
  82. liquid/golden/strip_html_filter.py +0 -74
  83. liquid/golden/strip_newlines_filter.py +0 -37
  84. liquid/golden/sum_filter.py +0 -97
  85. liquid/golden/tablerow_tag.py +0 -399
  86. liquid/golden/times_filter.py +0 -53
  87. liquid/golden/truncate_filter.py +0 -61
  88. liquid/golden/truncatewords_filter.py +0 -94
  89. liquid/golden/uniq_filter.py +0 -87
  90. liquid/golden/unless_tag.py +0 -101
  91. liquid/golden/upcase_filter.py +0 -27
  92. liquid/golden/url_decode_filter.py +0 -27
  93. liquid/golden/url_encode_filter.py +0 -27
  94. liquid/golden/where_filter.py +0 -122
  95. liquid/golden/whitespace_control.py +0 -281
  96. python_liquid-2.0.0.dist-info/RECORD +0 -182
  97. {python_liquid-2.0.0.dist-info → python_liquid-2.0.2.dist-info}/WHEEL +0 -0
  98. {python_liquid-2.0.0.dist-info → python_liquid-2.0.2.dist-info}/licenses/LICENSE +0 -0
liquid/golden/for_tag.py DELETED
@@ -1,642 +0,0 @@
1
- """Golden tests cases for testing liquid's `for` tag."""
2
-
3
- from liquid.golden.case import Case
4
-
5
- cases = [
6
- Case(
7
- description="simple range loop",
8
- template=r"{% for i in (0..3) %}{{ i }} {% endfor %}",
9
- expect="0 1 2 3 ",
10
- ),
11
- Case(
12
- description="range loop using identifier",
13
- template=(
14
- r"{% for i in (0..product.end_range) %}"
15
- r"{{ i }} - {{ product.tags[i] }} "
16
- r"{% endfor %}"
17
- ),
18
- expect="0 - sports 1 - garden ",
19
- globals={"product": {"tags": ["sports", "garden"], "end_range": 1}},
20
- ),
21
- Case(
22
- description="simple array loop",
23
- template=r"{% for tag in product.tags %}{{ tag }} {% endfor %}",
24
- expect="sports garden ",
25
- globals={"product": {"tags": ["sports", "garden"]}},
26
- ),
27
- Case(
28
- description="loop over an array in reverse",
29
- template=r"{% for tag in product.tags reversed %}{{ tag }} {% endfor %}",
30
- expect="garden sports ",
31
- globals={"product": {"tags": ["sports", "garden"]}},
32
- ),
33
- Case(
34
- description="simple hash loop",
35
- template=r"{% for c in collection %}{{ c[0] }} {{ c[1] }} {% endfor %}",
36
- expect="title foo description bar ",
37
- globals={"collection": {"title": "foo", "description": "bar"}},
38
- ),
39
- Case(
40
- description="empty array with default",
41
- template=(
42
- r"{% for img in emptythings.array %}"
43
- r"{{ img.url }} "
44
- r"{% else %}"
45
- r"no images"
46
- r"{% endfor %}"
47
- ),
48
- expect="no images",
49
- globals={"emptythings": {"array": [], "map": {}, "string": ""}},
50
- ),
51
- Case(
52
- description="break",
53
- template=(
54
- r"{% for tag in product.tags %}"
55
- r"{% if tag == 'sports' %}"
56
- r"{% break %}"
57
- r"{% else %}"
58
- r"{{ tag }} "
59
- r"{% endif %}"
60
- r"{% else %}"
61
- r"no images"
62
- r"{% endfor %}"
63
- ),
64
- expect="",
65
- globals={"product": {"tags": ["sports", "garden"]}},
66
- ),
67
- Case(
68
- description="continue",
69
- template=(
70
- r"{% for tag in product.tags %}"
71
- r"{% if tag == 'sports' %}"
72
- r"{% continue %}"
73
- r"{% else %}"
74
- r"{{ tag }} "
75
- r"{% endif %}"
76
- r"{% else %}"
77
- r"no images"
78
- r"{% endfor %}"
79
- ),
80
- expect="garden ",
81
- globals={"product": {"tags": ["sports", "garden"]}},
82
- ),
83
- Case(
84
- description="limit",
85
- template=r"{% for tag in product.tags limit:1 %}{{ tag }} {% endfor %}",
86
- expect="sports ",
87
- globals={"product": {"tags": ["sports", "garden"]}},
88
- ),
89
- Case(
90
- description="offset",
91
- template=r"{% for tag in product.tags offset:1 %}{{ tag }} {% endfor %}",
92
- expect="garden ",
93
- globals={"product": {"tags": ["sports", "garden"]}},
94
- ),
95
- Case(
96
- description="forloop length",
97
- template=r"{% for tag in product.tags %}{{ forloop.length }} {% endfor %}",
98
- expect="2 2 ",
99
- globals={"product": {"tags": ["sports", "garden"]}},
100
- ),
101
- Case(
102
- description="forloop length with limit",
103
- template=r"{% for tag in tags limit:3 %}{{ forloop.length }} {% endfor %}",
104
- expect="3 3 3 ",
105
- globals={
106
- "tags": [
107
- "sports",
108
- "garden",
109
- "home",
110
- "diy",
111
- "motoring",
112
- "fashion",
113
- ]
114
- },
115
- ),
116
- Case(
117
- description="forloop length with offset",
118
- template=r"{% for tag in tags offset:3 %}{{ forloop.length }} {% endfor %}",
119
- expect="3 3 3 ",
120
- globals={
121
- "tags": [
122
- "sports",
123
- "garden",
124
- "home",
125
- "diy",
126
- "motoring",
127
- "fashion",
128
- ]
129
- },
130
- ),
131
- Case(
132
- description="forloop goes out of scope",
133
- template=(
134
- r"{% for tag in product.tags %}"
135
- r"{{ forloop.length }} "
136
- r"{% endfor %}"
137
- r"{{ forloop.length }}"
138
- ),
139
- expect="2 2 ",
140
- globals={"product": {"tags": ["sports", "garden"]}},
141
- ),
142
- Case(
143
- description="forloop.first",
144
- template=r"{% for tag in product.tags %}{{ forloop.first }} {% endfor %}",
145
- expect="true false ",
146
- globals={"product": {"tags": ["sports", "garden"]}},
147
- ),
148
- Case(
149
- description="forloop.last",
150
- template=r"{% for tag in product.tags %}{{ forloop.last }} {% endfor %}",
151
- expect="false true ",
152
- globals={"product": {"tags": ["sports", "garden"]}},
153
- ),
154
- Case(
155
- description="forloop.index",
156
- template=r"{% for tag in product.tags %}{{ forloop.index }} {% endfor %}",
157
- expect="1 2 ",
158
- globals={"product": {"tags": ["sports", "garden"]}},
159
- ),
160
- Case(
161
- description="forloop.index0",
162
- template=r"{% for tag in product.tags %}{{ forloop.index0 }} {% endfor %}",
163
- expect="0 1 ",
164
- globals={"product": {"tags": ["sports", "garden"]}},
165
- ),
166
- Case(
167
- description="forloop.rindex",
168
- template=r"{% for tag in product.tags %}{{ forloop.rindex }} {% endfor %}",
169
- expect="2 1 ",
170
- globals={"product": {"tags": ["sports", "garden"]}},
171
- ),
172
- Case(
173
- description="forloop.rindex0",
174
- template=r"{% for tag in product.tags %}{{ forloop.rindex0 }} {% endfor %}",
175
- expect="1 0 ",
176
- globals={"product": {"tags": ["sports", "garden"]}},
177
- ),
178
- Case(
179
- description="forloop name",
180
- template=r"{% for tag in product.tags limit:1 %}{{ forloop.name }}{% endfor %}",
181
- expect="tag-product.tags",
182
- globals={"product": {"tags": ["sports", "garden"]}},
183
- ),
184
- Case(
185
- description="forloop name of a range",
186
- template=r"{% for i in (1..3) limit:1 %}{{ forloop.name }}{% endfor %}",
187
- expect="i-(1..3)",
188
- globals={},
189
- ),
190
- Case(
191
- description="forloop no such attribute",
192
- template=r"{% for tag in product.tags %}{{ forloop.nosuchthing }}{% endfor %}",
193
- expect="",
194
- globals={"product": {"tags": ["sports", "garden"]}},
195
- ),
196
- Case(
197
- description="iterate an empty array",
198
- template=r"{% for item in emptythings.array %}{{ item }}{% endfor %}",
199
- expect="",
200
- globals={"emptythings": {"array": [], "map": {}, "string": ""}},
201
- ),
202
- Case(
203
- description="iterate an empty array with default",
204
- template=(
205
- r"{% for item in emptythings.array %}"
206
- r"{{ item }}{% else %}foo"
207
- r"{% endfor %}"
208
- ),
209
- expect="foo",
210
- globals={"emptythings": {"array": [], "map": {}, "string": ""}},
211
- ),
212
- Case(
213
- description="lookup a filter from an outer context",
214
- template=r"{% for tag in product.tags %}{{ tag | upcase }} {% endfor %}",
215
- expect="SPORTS GARDEN ",
216
- globals={"product": {"tags": ["sports", "garden"]}},
217
- ),
218
- Case(
219
- description="assign inside loop",
220
- template=(
221
- r"{% for tag in product.tags %}"
222
- r"{% assign x = tag %}"
223
- r"{% endfor %}"
224
- r"{{ x }}"
225
- ),
226
- expect="garden",
227
- globals={"product": {"tags": ["sports", "garden"]}},
228
- ),
229
- Case(
230
- description="blank empty loops",
231
- template=r"{% for i in (0..10) %} {% endfor %}",
232
- expect="",
233
- ),
234
- Case(
235
- description=(
236
- "loop over nested and chained object from context "
237
- "with trailing identifier"
238
- ),
239
- template=(
240
- r"{% for link in linklists[section.settings.menu].links %}"
241
- r"{{ link }} "
242
- r"{% endfor %}"
243
- ),
244
- expect="1 2 ",
245
- globals={
246
- "linklists": {"main": {"links": ["1", "2"]}},
247
- "section": {"settings": {"menu": "main"}},
248
- },
249
- ),
250
- Case(
251
- description="loop over undefined",
252
- template=r"{% for tag in nosuchthing %}{{ tag }}{% endfor %}",
253
- expect="",
254
- globals={},
255
- ),
256
- Case(
257
- description="continue a loop",
258
- template=(
259
- r"{% for item in array limit: 3 %}"
260
- r"a{{ item }} "
261
- r"{% endfor %}"
262
- r"{% for item in array offset: continue %}"
263
- r"b{{ item }} "
264
- r"{% endfor %}"
265
- ),
266
- expect="a1 a2 a3 b4 b5 b6 ",
267
- globals={"array": [1, 2, 3, 4, 5, 6]},
268
- ),
269
- Case(
270
- description="continue a loop over an assigned range",
271
- template=(
272
- r"{% assign nums = (1..5) %}"
273
- r"{% for item in nums limit: 3 %}"
274
- r"a{{ item }} "
275
- r"{% endfor %}"
276
- r"{% for item in nums offset: continue %}"
277
- r"b{{ item }} "
278
- r"{% endfor %}"
279
- ),
280
- expect="a1 a2 a3 b4 b5 ",
281
- ),
282
- Case(
283
- description="continue a loop over a changing array",
284
- template=(
285
- r"{% assign foo = '1,2,3,4,5,6' | split: ',' %}"
286
- r"{% for item in foo limit: 3 %}"
287
- r"{{ item }} "
288
- r"{% endfor %}"
289
- r"{% assign foo = 'u,v,w,x,y,z' | split: ',' %}"
290
- r"{% for item in foo offset: continue %}"
291
- r"{{ item }} "
292
- r"{% endfor %}"
293
- ),
294
- expect="1 2 3 x y z ",
295
- globals={},
296
- ),
297
- Case(
298
- description="continue with changing loop var",
299
- template=(
300
- r"{% for foo in array limit: 3 %}"
301
- r"{{ foo }} "
302
- r"{% endfor %}"
303
- r"{% for bar in array offset: continue %}"
304
- r"{{ bar }} "
305
- r"{% endfor %}"
306
- ),
307
- expect="1 2 3 1 2 3 4 5 6 ",
308
- globals={"array": [1, 2, 3, 4, 5, 6]},
309
- ),
310
- Case(
311
- description="nothing to continue from",
312
- template=(
313
- r"{% for item in array %}"
314
- r"a{{ item }} "
315
- r"{% endfor %}"
316
- r"{% for item in array offset: continue %}"
317
- r"b{{ item }} "
318
- r"{% endfor %}"
319
- ),
320
- expect="a1 a2 a3 a4 a5 a6 ",
321
- globals={"array": [1, 2, 3, 4, 5, 6]},
322
- ),
323
- Case(
324
- description="offset continue without preceding loop",
325
- template=r"{% for item in array offset: continue %}{{ item }} {% endfor %}",
326
- expect="1 2 3 4 5 6 ",
327
- globals={"array": [1, 2, 3, 4, 5, 6]},
328
- ),
329
- Case(
330
- description="continue from a limit that is greater than length",
331
- template=(
332
- r"{% for item in array limit: 99 %}"
333
- r"a{{ item }} "
334
- r"{% endfor %}"
335
- r"{% for item in array offset: continue %}"
336
- r"b{{ item }} "
337
- r"{% endfor %}"
338
- ),
339
- expect="a1 a2 a3 a4 a5 a6 ",
340
- globals={"array": [1, 2, 3, 4, 5, 6]},
341
- ),
342
- Case(
343
- description="continue from a range expression",
344
- template=(
345
- r"{% for item in (1..6) limit: 3 %}"
346
- r"a{{ item }} "
347
- r"{% endfor %}"
348
- r"{% for item in (1..6) offset: continue %}"
349
- r"b{{ item }} "
350
- r"{% endfor %}"
351
- ),
352
- expect="a1 a2 a3 b4 b5 b6 ",
353
- globals={"array": [1, 2, 3, 4, 5, 6]},
354
- ),
355
- Case(
356
- description="offset continue twice with limit",
357
- template=(
358
- r"{% for item in (1..6) limit: 2 %}"
359
- r"a{{ item }} "
360
- r"{% endfor %}"
361
- r"{% for item in (1..6) limit: 2 offset: continue %}"
362
- r"b{{ item }} "
363
- r"{% endfor %}"
364
- r"{% for item in (1..6) offset: continue %}"
365
- r"c{{ item }} "
366
- r"{% endfor %}"
367
- ),
368
- expect="a1 a2 b3 b4 c5 c6 ",
369
- ),
370
- Case(
371
- description="offset continue twice with changing limit",
372
- template=(
373
- r"{% for item in (1..6) limit: 2 %}"
374
- r"a{{ item }} "
375
- r"{% endfor %}"
376
- r"{% for item in (1..6) limit: 3 offset: continue %}"
377
- r"b{{ item }} "
378
- r"{% endfor %}"
379
- r"{% for item in (1..6) offset: continue %}"
380
- r"c{{ item }} "
381
- r"{% endfor %}"
382
- ),
383
- expect="a1 a2 b3 b4 b5 c6 ",
384
- ),
385
- Case(
386
- description="offset continue twice with no second limit",
387
- template=(
388
- r"{% for item in (1..6) limit: 2 %}"
389
- r"a{{ item }} "
390
- r"{% endfor %}"
391
- r"{% for item in (1..6) offset: continue %}"
392
- r"b{{ item }} "
393
- r"{% endfor %}"
394
- r"{% for item in (1..6) offset: continue %}"
395
- r"c{{ item }} "
396
- r"{% endfor %}"
397
- ),
398
- expect="a1 a2 b3 b4 b5 b6 ",
399
- ),
400
- Case(
401
- description="offset continue from a broken loop",
402
- template=(
403
- r"{% for item in (1..6) limit: 4 %}"
404
- r"{% if item == 3 %}{% break %}{% endif %}"
405
- r"a{{ item }} "
406
- r"{% endfor %}"
407
- r"{% for item in (1..6) offset: continue %}"
408
- r"b{{ item }} "
409
- r"{% endfor %}"
410
- ),
411
- expect="a1 a2 b5 b6 ",
412
- ),
413
- Case(
414
- description="offset continue from a broken loop with preceding limit",
415
- template=(
416
- r"{% for item in (1..6) limit: 3 %}"
417
- r"a{{ item }} "
418
- r"{% endfor %}"
419
- r"{% for item in (1..6) %}"
420
- r"{% if item == 3 %}{% break %}{% endif %}"
421
- r"b{{ item }} "
422
- r"{% endfor %}"
423
- r"{% for item in (1..6) offset: continue %}"
424
- r"c{{ item }} "
425
- r"{% endfor %}"
426
- ),
427
- expect="a1 a2 a3 b1 b2 ",
428
- ),
429
- Case(
430
- description="offset continue forloop length",
431
- template=(
432
- r"{% for item in (1..6) limit: 2 %}"
433
- r"a{{ item }} - {{ forloop.length }}, "
434
- r"{% endfor %}"
435
- r"{% for item in (1..6) offset: continue %}"
436
- r"b{{ item }} - {{ forloop.length }}, "
437
- r"{% endfor %}"
438
- ),
439
- expect="a1 - 2, a2 - 2, b3 - 4, b4 - 4, b5 - 4, b6 - 4, ",
440
- ),
441
- Case(
442
- description="parentloop is normally undefined",
443
- template=(r"{% for i in (1..2)%}{{ forloop.parentloop.index }}{% endfor %}"),
444
- expect="",
445
- globals={},
446
- ),
447
- Case(
448
- description="access parentloop",
449
- template=(
450
- r"{% for i in (1..2)%}"
451
- r"{% for j in (1..2) %}"
452
- r"{{ i }} {{j}} {{ forloop.parentloop.index }} {{ forloop.index }} "
453
- r"{% endfor %}"
454
- r"{% endfor %}"
455
- ),
456
- expect="1 1 1 1 1 2 1 2 2 1 2 1 2 2 2 2 ",
457
- globals={},
458
- ),
459
- Case(
460
- description="parentloop goes out of scope",
461
- template=(
462
- r"{% for i in (1..2)%}"
463
- r"{% for j in (1..2) %}"
464
- r"{{ i }} {{ j }} "
465
- r"{% endfor %}"
466
- r"{{ forloop.parentloop.index }}"
467
- r"{% endfor %}"
468
- ),
469
- expect="1 1 1 2 2 1 2 2 ",
470
- globals={},
471
- ),
472
- Case(
473
- description="parent's parentloop",
474
- template=(
475
- r"{% for i in (1..2) %}"
476
- r"{% for j in (1..2) %}"
477
- r"{% for k in (1..2) %}"
478
- r"i={{ forloop.parentloop.parentloop.index }} "
479
- r"j={{ forloop.parentloop.index }} "
480
- r"k={{ forloop.index }} "
481
- r"{% endfor %}"
482
- r"{% endfor %}"
483
- r"{% endfor %}"
484
- ),
485
- expect=(
486
- "i=1 j=1 k=1 i=1 j=1 k=2 "
487
- "i=1 j=2 k=1 i=1 j=2 k=2 "
488
- "i=2 j=1 k=1 i=2 j=1 k=2 "
489
- "i=2 j=2 k=1 i=2 j=2 k=2 "
490
- ),
491
- globals={},
492
- ),
493
- Case(
494
- description="loop over an existing range object",
495
- template=(
496
- r"{% assign foo = (1..3) %}"
497
- r"{{ foo | join: '#' }}"
498
- r"{% for i in foo %}"
499
- r"{{ i }}"
500
- r"{% endfor %}"
501
- r"{% for i in foo %}"
502
- r"{{ i }}"
503
- r"{% endfor %}"
504
- ),
505
- expect="1#2#3123123",
506
- globals={},
507
- ),
508
- Case(
509
- description="loop over range with float start",
510
- template=r"{% assign x = (2.4..5) %}{% for i in x %}{{ i }}{% endfor %}",
511
- expect="2345",
512
- globals={},
513
- ),
514
- Case(
515
- description="share outer scope",
516
- template=(
517
- r"{% assign foo = 'hello' %}"
518
- r"{% for x in (1..3) %}"
519
- r"{% assign foo = x %}"
520
- r"{% endfor %}"
521
- r"{{ foo }}"
522
- ),
523
- expect="3",
524
- globals={},
525
- ),
526
- Case(
527
- description="offset and limit",
528
- template=r"{% for tag in tags limit: 3 offset: 1 %}{{ tag }} {% endfor %}",
529
- expect="garden home diy ",
530
- globals={"tags": ["sports", "garden", "home", "diy", "motoring", "fashion"]},
531
- ),
532
- Case(
533
- description="first and last with an offset and limit",
534
- template=(
535
- r"{% for tag in tags limit: 2 offset: 1 %}"
536
- r"{{ tag }} {{ forloop.first }} {{ forloop.last }} "
537
- r"{% endfor %}"
538
- ),
539
- expect="garden true false home false true ",
540
- globals={"tags": ["sports", "garden", "home", "diy", "motoring", "fashion"]},
541
- ),
542
- Case(
543
- description="first and last with offset continue",
544
- template=(
545
- r"{% for tag in product.tags limit: 1 %}"
546
- r"{% endfor %}"
547
- r"{% for tag in product.tags offset: continue %}"
548
- r"{{ forloop.first }} {{ forloop.last }} "
549
- r"{% endfor %}"
550
- ),
551
- expect="true false false false false false false false false true ",
552
- globals={
553
- "product": {
554
- "tags": ["sports", "garden", "home", "diy", "motoring", "fashion"]
555
- }
556
- },
557
- ),
558
- Case(
559
- description="range start and stop are the same",
560
- template=r"{% for i in (1..1) %}{{ i }} {% endfor %}",
561
- expect="1 ",
562
- ),
563
- Case(
564
- description="range start and stop are zero",
565
- template=r"{% for i in (0..0) %}{{ i }} {% endfor %}",
566
- expect="0 ",
567
- ),
568
- # Case(
569
- # description="limit is a float",
570
- # template=r"{% for i in (1..4) limit: 2.6 %}{{ i }} {% endfor %}",
571
- # expect="",
572
- # error=True,
573
- # ),
574
- # Case(
575
- # description="offset is a float",
576
- # template=r"{% for i in (1..4) offset: 2.6 %}{{ i }} {% endfor %}",
577
- # expect="",
578
- # error=True,
579
- # ),
580
- Case(
581
- description="limit is a string",
582
- template=r"{% for i in (1..4) limit: '2' %}{{ i }} {% endfor %}",
583
- expect="1 2 ",
584
- ),
585
- Case(
586
- description="offset is a string",
587
- template=r"{% for i in (1..4) offset: '2' %}{{ i }} {% endfor %}",
588
- expect="3 4 ",
589
- ),
590
- Case(
591
- description="limit is a non-number string",
592
- template=r"{% for i in (1..4) limit: 'foo' %}{{ i }} {% endfor %}",
593
- expect="",
594
- error=True,
595
- ),
596
- Case(
597
- description="offset is a non-number string",
598
- template=r"{% for i in (1..4) offset: 'foo' %}{{ i }} {% endfor %}",
599
- expect="",
600
- error=True,
601
- ),
602
- Case(
603
- description="limit is not a string or number",
604
- template=r"{% for i in (1..4) limit: foo %}{{ i }} {% endfor %}",
605
- expect="",
606
- globals={"foo": [1, 2, 3]},
607
- error=True,
608
- ),
609
- Case(
610
- description="offset is not a string or number",
611
- template=r"{% for i in (1..4) offset: foo %}{{ i }} {% endfor %}",
612
- expect="",
613
- globals={"foo": [1, 2, 3]},
614
- error=True,
615
- ),
616
- Case(
617
- description="comma separated arguments",
618
- template=r"{% for i in (1..6), limit: 4, offset: 2 %}{{ i }} {% endfor %}",
619
- expect="3 4 5 6 ",
620
- globals={},
621
- ),
622
- Case(
623
- description="some comma separated arguments",
624
- template=r"{% for i in (1..6) limit: 4, offset: 2, %}{{ i }} {% endfor %}",
625
- expect="3 4 5 6 ",
626
- globals={},
627
- ),
628
- Case(
629
- description="loop over a string literal",
630
- template=r"{% for i in 'hello' %}{{ i }} {% endfor %}",
631
- expect="hello ",
632
- globals={},
633
- future=True,
634
- ),
635
- Case(
636
- description="loop over a string variable",
637
- template=r"{% for i in foo %}{{ i }} {% endfor %}",
638
- expect="hello ",
639
- globals={"foo": "hello"},
640
- future=True,
641
- ),
642
- ]