@@ -2,25 +2,25 @@ import { TopLevelToken, TagToken, Tokenizer, Context, Liquid, Drop, toValueSync
2
2
const LiquidUMD = require ( '../../dist/liquid.browser.umd.js' ) . Liquid
3
3
4
4
describe ( 'Issues' , function ( ) {
5
- it ( '#221 unicode blanks are not properly treated' , async ( ) => {
5
+ it ( 'unicode blanks are not properly treated #221 ' , async ( ) => {
6
6
const engine = new Liquid ( { strictVariables : true , strictFilters : true } )
7
7
const html = engine . parseAndRenderSync ( '{{huh | truncate: 11}}' , { huh : 'fdsafdsafdsafdsaaaaa' } )
8
8
expect ( html ) . toBe ( 'fdsafdsa...' )
9
9
} )
10
- it ( '#252 "Not valid identifier" error for a quotes-containing identifier' , async ( ) => {
10
+ it ( '"Not valid identifier" error for a quotes-containing identifier #252 ' , async ( ) => {
11
11
const template = `{% capture "form_classes" -%}
12
12
foo
13
13
{%- endcapture %}{{form_classes}}`
14
14
const engine = new Liquid ( )
15
15
const html = await engine . parseAndRender ( template )
16
16
expect ( html ) . toBe ( 'foo' )
17
17
} )
18
- it ( '#259 complex property access with braces is not supported' , async ( ) => {
18
+ it ( 'complex property access with braces is not supported #259 ' , async ( ) => {
19
19
const engine = new Liquid ( )
20
20
const html = engine . parseAndRenderSync ( '{{ ["complex key"] }}' , { 'complex key' : 'foo' } )
21
21
expect ( html ) . toBe ( 'foo' )
22
22
} )
23
- it ( '#243 Potential for ReDoS through string replace function' , async ( ) => {
23
+ it ( 'Potential for ReDoS through string replace function #243 ' , async ( ) => {
24
24
const engine = new Liquid ( )
25
25
const INPUT = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!'
26
26
const BROKEN_REGEX = / ( [ a - z ] + ) + $ /
@@ -33,13 +33,13 @@ describe('Issues', function () {
33
33
// should stringify the regexp rather than execute it
34
34
expect ( html ) . toBe ( INPUT )
35
35
} )
36
- it ( '#263 raw/endraw block not ignoring {% characters' , ( ) => {
36
+ it ( 'raw/endraw block not ignoring {% characters #263 ' , ( ) => {
37
37
const template = `{% raw %}This is a code snippet showing how {% breaks the raw block.{% endraw %}`
38
38
const engine = new Liquid ( )
39
39
const html = engine . parseAndRenderSync ( template )
40
40
expect ( html ) . toBe ( 'This is a code snippet showing how {% breaks the raw block.' )
41
41
} )
42
- it ( '#268 elsif is not supported for unless' , ( ) => {
42
+ it ( 'elsif is not supported for unless #268 ' , ( ) => {
43
43
const template = `{%- unless condition1 -%}
44
44
<div>X</div>
45
45
{%- elsif condition2 -%}
@@ -51,7 +51,7 @@ describe('Issues', function () {
51
51
const html = engine . parseAndRenderSync ( template , { condition1 : true , condition2 : true } )
52
52
expect ( html ) . toBe ( '<div>Y</div>' )
53
53
} )
54
- it ( '#277 Passing liquid in FilterImpl' , ( ) => {
54
+ it ( 'Passing liquid in FilterImpl #277 ' , ( ) => {
55
55
const engine = new Liquid ( )
56
56
engine . registerFilter ( 'render' , function ( this : any , template : string , name : string ) {
57
57
return this . liquid . parseAndRenderSync ( decodeURIComponent ( template ) , { name } )
@@ -62,55 +62,55 @@ describe('Issues', function () {
62
62
)
63
63
expect ( html ) . toBe ( 'hello foo' )
64
64
} )
65
- it ( '#288 Unexpected behavior when string literals contain }}' , async ( ) => {
65
+ it ( 'Unexpected behavior when string literals contain }} #288 ' , async ( ) => {
66
66
const engine = new Liquid ( )
67
67
const html = await engine . parseAndRender ( `{{ '{{' }}{{ '}}' }}` )
68
68
expect ( html ) . toBe ( '{{}}' )
69
69
} )
70
- it ( '#222 Support function calls' , async ( ) => {
70
+ it ( 'Support function calls #222 ' , async ( ) => {
71
71
const engine = new Liquid ( )
72
72
const html = await engine . parseAndRender (
73
73
`{{ obj.property }}` ,
74
74
{ obj : { property : ( ) => 'BAR' } }
75
75
)
76
76
expect ( html ) . toBe ( 'BAR' )
77
77
} )
78
- it ( '#313 lenientIf not working as expected in umd' , async ( ) => {
78
+ it ( 'lenientIf not working as expected in umd #313 ' , async ( ) => {
79
79
const engine = new LiquidUMD ( {
80
80
strictVariables : true ,
81
81
lenientIf : true
82
82
} )
83
83
const html = await engine . parseAndRender ( `{{ name | default: "default name" }}` )
84
84
expect ( html ) . toBe ( 'default name' )
85
85
} )
86
- it ( '#321 comparison for empty/nil' , async ( ) => {
86
+ it ( 'comparison for empty/nil #321 ' , async ( ) => {
87
87
const engine = new Liquid ( )
88
88
const html = await engine . parseAndRender (
89
89
'{% if empty == nil %}true{%else%}false{%endif%}' +
90
90
'{% if nil == empty %}true{%else%}false{%endif%}'
91
91
)
92
92
expect ( html ) . toBe ( 'falsefalse' )
93
93
} )
94
- it ( '#320 newline_to_br filter should output <br /> instead of <br/>' , async ( ) => {
94
+ it ( 'newline_to_br filter should output <br /> instead of <br/> #320 ' , async ( ) => {
95
95
const engine = new Liquid ( )
96
96
const html = await engine . parseAndRender (
97
97
`{{ 'a \n b \n c' | newline_to_br | split: '<br />' }}`
98
98
)
99
99
expect ( html ) . toBe ( 'a \n b \n c' )
100
100
} )
101
- it ( '#342 New lines in logical operator' , async ( ) => {
101
+ it ( 'New lines in logical operator #342 ' , async ( ) => {
102
102
const engine = new Liquid ( )
103
103
const tpl = `{%\r\nif\r\ntrue\r\nor\r\nfalse\r\n%}\r\ntrue\r\n{%\r\nendif\r\n%}`
104
104
const html = await engine . parseAndRender ( tpl )
105
105
expect ( html ) . toBe ( '\r\ntrue\r\n' )
106
106
} )
107
- it ( '#401 Timezone Offset Issue' , async ( ) => {
107
+ it ( 'Timezone Offset Issue #401 ' , async ( ) => {
108
108
const engine = new Liquid ( { timezoneOffset : - 600 } )
109
109
const tpl = engine . parse ( '{{ date | date: "%Y-%m-%d %H:%M %p %z" }}' )
110
110
const html = await engine . render ( tpl , { date : '2021-10-06T15:31:00+08:00' } )
111
111
expect ( html ) . toBe ( '2021-10-06 17:31 PM +1000' )
112
112
} )
113
- it ( '#412 Pass root as it is to `resolve`' , async ( ) => {
113
+ it ( 'Pass root as it is to `resolve` #412 ' , async ( ) => {
114
114
const engine = new Liquid ( {
115
115
root : '/tmp' ,
116
116
relativeReference : false ,
@@ -126,7 +126,7 @@ describe('Issues', function () {
126
126
const html = await engine . renderSync ( tpl )
127
127
expect ( html ) . toBe ( '/tmp/foo.liquid' )
128
128
} )
129
- it ( '#416 Templates imported by {% render %} not cached for concurrent async render' , async ( ) => {
129
+ it ( 'Templates imported by {% render %} not cached for concurrent async render #416 ' , async ( ) => {
130
130
const readFile = jest . fn ( ( ) => Promise . resolve ( 'HELLO' ) )
131
131
const exists = jest . fn ( ( ) => 'HELLO' )
132
132
const engine = new Liquid ( {
@@ -148,15 +148,15 @@ describe('Issues', function () {
148
148
expect ( exists ) . toHaveBeenCalledTimes ( 1 )
149
149
expect ( readFile ) . toHaveBeenCalledTimes ( 1 )
150
150
} )
151
- it ( '#431 Error when using Date timezoneOffset in 9.28.5' , ( ) => {
151
+ it ( 'Error when using Date timezoneOffset in 9.28.5 #431 ' , ( ) => {
152
152
const engine = new Liquid ( {
153
153
timezoneOffset : 0 ,
154
154
preserveTimezones : true
155
155
} )
156
156
const tpl = engine . parse ( 'Welcome to {{ now | date: "%Y-%m-%d" }}' )
157
157
return expect ( engine . render ( tpl , { now : new Date ( '2019-02-01T00:00:00.000Z' ) } ) ) . resolves . toBe ( 'Welcome to 2019-02-01' )
158
158
} )
159
- it ( '#433 Support Jekyll-like includes' , async ( ) => {
159
+ it ( 'Support Jekyll-like includes #433 ' , async ( ) => {
160
160
const engine = new Liquid ( {
161
161
dynamicPartials : false ,
162
162
relativeReference : false ,
@@ -173,7 +173,7 @@ describe('Issues', function () {
173
173
const html = await engine . render ( tpl , { my_variable : 'foo' } )
174
174
expect ( html ) . toBe ( 'CONTENT for /tmp/prefix/foo-bar/suffix' )
175
175
} )
176
- it ( '#428 Implement liquid/echo tags' , ( ) => {
176
+ it ( 'Implement liquid/echo tags #428 ' , ( ) => {
177
177
const template = `{%- liquid
178
178
for value in array
179
179
assign double_value = value | times: 2
@@ -190,25 +190,25 @@ describe('Issues', function () {
190
190
const html = engine . parseAndRenderSync ( template , { array : [ 1 , 2 , 3 ] } )
191
191
expect ( html ) . toBe ( '4#8#12#6' )
192
192
} )
193
- it ( '#454 leaking JS prototype getter functions in evaluation' , async ( ) => {
193
+ it ( 'leaking JS prototype getter functions in evaluation #454 ' , async ( ) => {
194
194
const engine = new Liquid ( { ownPropertyOnly : true } )
195
195
const html = engine . parseAndRenderSync ( '{{foo | size}}-{{bar.coo}}' , { foo : 'foo' , bar : Object . create ( { coo : 'COO' } ) } )
196
196
expect ( html ) . toBe ( '3-' )
197
197
} )
198
- it ( '#465 Liquidjs divided_by not compatible with Ruby/Shopify Liquid' , ( ) => {
198
+ it ( 'Liquidjs divided_by not compatible with Ruby/Shopify Liquid #465 ' , ( ) => {
199
199
const engine = new Liquid ( { ownPropertyOnly : true } )
200
200
const html = engine . parseAndRenderSync ( '{{ 5 | divided_by: 3, true }}' )
201
201
expect ( html ) . toBe ( '1' )
202
202
} )
203
- it ( '#479 url_encode throws on undefined value' , async ( ) => {
203
+ it ( 'url_encode throws on undefined value #479 ' , async ( ) => {
204
204
const engine = new Liquid ( {
205
205
strictVariables : false
206
206
} )
207
207
const tpl = engine . parse ( '{{ v | url_encode }}' )
208
208
const html = await engine . render ( tpl , { v : undefined } )
209
209
expect ( html ) . toBe ( '' )
210
210
} )
211
- it ( '#481 filters that should not throw' , async ( ) => {
211
+ it ( 'filters that should not throw #481 ' , async ( ) => {
212
212
const engine = new Liquid ( )
213
213
const tpl = engine . parse ( `
214
214
{{ foo | join }}
@@ -223,17 +223,17 @@ describe('Issues', function () {
223
223
const html = await engine . render ( tpl , { foo : undefined } )
224
224
expect ( html . trim ( ) ) . toBe ( '[]' )
225
225
} )
226
- it ( '#481 concat should always return an array' , async ( ) => {
226
+ it ( 'concat should always return an array #481 ' , async ( ) => {
227
227
const engine = new Liquid ( )
228
228
const html = await engine . parseAndRender ( `{{ foo | concat | json }}` )
229
229
expect ( html ) . toBe ( '[]' )
230
230
} )
231
- it ( '#486 Access array items from the right with negative indexes' , async ( ) => {
231
+ it ( 'Access array items from the right with negative indexes #486 ' , async ( ) => {
232
232
const engine = new Liquid ( )
233
233
const html = await engine . parseAndRender ( `{% assign a = "x,y,z" | split: ',' -%}{{ a[-1] }} {{ a[-3] }} {{ a[-8] }}` )
234
234
expect ( html ) . toBe ( 'z x ' )
235
235
} )
236
- it ( '#492 contains operator does not support Drop' , async ( ) => {
236
+ it ( 'contains operator does not support Drop #492 ' , async ( ) => {
237
237
class TemplateDrop extends Drop {
238
238
valueOf ( ) { return 'product' }
239
239
}
@@ -242,44 +242,44 @@ describe('Issues', function () {
242
242
const html = await engine . parseAndRender ( `{% if template contains "product" %}contains{%endif%}` , ctx )
243
243
expect ( html ) . toBe ( 'contains' )
244
244
} )
245
- it ( '#513 should support large number of templates [async]' , async ( ) => {
245
+ it ( 'should support large number of templates [async] #513 ' , async ( ) => {
246
246
const engine = new Liquid ( )
247
247
const html = await engine . parseAndRender ( `{% for i in (1..10000) %}{{ i }}{% endfor %}` )
248
248
expect ( html ) . toHaveLength ( 38894 )
249
249
} )
250
- it ( '#513 should support large number of templates [sync]' , ( ) => {
250
+ it ( 'should support large number of templates [sync] #513 ' , ( ) => {
251
251
const engine = new Liquid ( )
252
252
const html = engine . parseAndRenderSync ( `{% for i in (1..10000) %}{{ i }}{% endfor %}` )
253
253
expect ( html ) . toHaveLength ( 38894 )
254
254
} )
255
- it ( '#519 should throw parse error for invalid assign expression' , ( ) => {
255
+ it ( 'should throw parse error for invalid assign expression #519 ' , ( ) => {
256
256
const engine = new Liquid ( )
257
257
expect ( ( ) => engine . parse ( '{% assign headshot = https://testurl.com/not_enclosed_in_quotes.jpg %}' ) ) . toThrow ( / e x p e c t e d " | " b e f o r e f i l t e r , l i n e : 1 , c o l : 2 7 / )
258
258
} )
259
- it ( '#527 export Liquid Expression' , ( ) => {
259
+ it ( 'export Liquid Expression #527 ' , ( ) => {
260
260
const tokenizer = new Tokenizer ( 'a > b' )
261
261
const expression = tokenizer . readExpression ( )
262
262
const result = toValueSync ( expression . evaluate ( new Context ( { a : 1 , b : 2 } ) ) )
263
263
expect ( result ) . toBe ( false )
264
264
} )
265
- it ( '#527 export Liquid Expression (evalValue)' , async ( ) => {
265
+ it ( 'export Liquid Expression (evalValue) #527 ' , async ( ) => {
266
266
const liquid = new Liquid ( )
267
267
const result = await liquid . evalValue ( 'a > b' , { a : 1 , b : 2 } )
268
268
expect ( result ) . toBe ( false )
269
269
} )
270
- it ( '#527 export Liquid Expression (evalValueSync)' , async ( ) => {
270
+ it ( 'export Liquid Expression (evalValueSync) #527 ' , async ( ) => {
271
271
const liquid = new Liquid ( )
272
272
const result = liquid . evalValueSync ( 'a > b' , { a : 1 , b : 2 } )
273
273
expect ( result ) . toBe ( false )
274
274
} )
275
- it ( '#276 Promise support in expressions' , async ( ) => {
275
+ it ( 'Promise support in expressions #276 ' , async ( ) => {
276
276
const liquid = new Liquid ( )
277
277
const tpl = '{%if name == "alice" %}true{%endif%}'
278
278
const ctx = { name : Promise . resolve ( 'alice' ) }
279
279
const html = await liquid . parseAndRender ( tpl , ctx )
280
280
expect ( html ) . toBe ( 'true' )
281
281
} )
282
- it ( '#533 Nested Promise support for scope object' , async ( ) => {
282
+ it ( 'Nested Promise support for scope object #533 ' , async ( ) => {
283
283
const liquid = new Liquid ( )
284
284
const context = {
285
285
a : 1 ,
@@ -325,7 +325,7 @@ describe('Issues', function () {
325
325
expect ( await liquid . parseAndRender ( '{{i.i}}' , context ) ) . toBe ( '1' )
326
326
expect ( await liquid . parseAndRender ( '{{j.j}}' , context ) ) . toBe ( '1' )
327
327
} )
328
- it ( '#559 Case/When should evaluate multiple When statements' , async ( ) => {
328
+ it ( 'Case/When should evaluate multiple When statements #559 ' , async ( ) => {
329
329
const liquid = new Liquid ( )
330
330
const tpl = `
331
331
{% assign tag = 'Love' %}
@@ -342,7 +342,7 @@ describe('Issues', function () {
342
342
const html = await liquid . parseAndRender ( tpl )
343
343
expect ( html ) . toMatch ( / ^ \s * T h i s i s a l o v e o r l u c k p o t i o n .\s + T h i s i s a s t r e n g t h o r h e a l t h o r l o v e p o t i o n .\s * $ / )
344
344
} )
345
- it ( '#570 tag registration compatible to v9' , async ( ) => {
345
+ it ( 'tag registration compatible to v9 #570 ' , async ( ) => {
346
346
const liquid = new Liquid ( )
347
347
liquid . registerTag ( 'metadata_file' , {
348
348
parse ( tagToken : TagToken , remainTokens : TopLevelToken [ ] ) {
@@ -358,7 +358,7 @@ describe('Issues', function () {
358
358
const html = await liquid . parseAndRender ( tpl , ctx )
359
359
expect ( html ) . toBe ( 'FOO' )
360
360
} )
361
- it ( '#573 date filter should return parsed input when no format is provided' , async ( ) => {
361
+ it ( 'date filter should return parsed input when no format is provided #573 ' , async ( ) => {
362
362
const liquid = new Liquid ( )
363
363
liquid . registerTag ( 'metadata_file' , {
364
364
parse ( tagToken : TagToken , remainTokens : TopLevelToken [ ] ) {
@@ -374,7 +374,7 @@ describe('Issues', function () {
374
374
// sample: Thursday, February 2, 2023 at 6:25 pm +0000
375
375
expect ( html ) . toMatch ( / \w + , \w + \d + , \d \d \d \d a t \d + : \d \d [ a p ] m [ - + ] \d \d \d \d / )
376
376
} )
377
- it ( '#575 Add support for Not operator' , async ( ) => {
377
+ it ( 'Add support for Not operator #575 ' , async ( ) => {
378
378
const liquid = new Liquid ( )
379
379
const tpl = `
380
380
{% if link and not button %}
@@ -386,7 +386,7 @@ describe('Issues', function () {
386
386
const html = await liquid . parseAndRender ( tpl , ctx )
387
387
expect ( html . trim ( ) ) . toBe ( '<a href="https://example.com">Lot more code here</a>' )
388
388
} )
389
- it ( '#70 strip multiline content of <style>' , async ( ) => {
389
+ it ( 'strip multiline content of <style> #70 ' , async ( ) => {
390
390
const str = `
391
391
<style type="text/css">
392
392
.test-one-line {display: none;}
@@ -396,7 +396,7 @@ describe('Issues', function () {
396
396
const html = await engine . parseAndRender ( template , { str } )
397
397
expect ( html ) . toMatch ( / ^ \s * $ / )
398
398
} )
399
- it ( '#589 Arrays should compare values' , async ( ) => {
399
+ it ( 'Arrays should compare values #589 ' , async ( ) => {
400
400
const engine = new Liquid ( )
401
401
const template = `
402
402
{% assign people1 = "alice, bob, carol" | split: ", " -%}
@@ -406,7 +406,7 @@ describe('Issues', function () {
406
406
const html = await engine . parseAndRender ( template )
407
407
expect ( html ) . toContain ( 'true' )
408
408
} )
409
- it ( '#604 date filter appears to add DST correction to UTC dates' , ( ) => {
409
+ it ( 'date filter appears to add DST correction to UTC dates #604 ' , ( ) => {
410
410
const engine = new Liquid ( {
411
411
timezoneOffset : 'Etc/GMT'
412
412
} )
@@ -426,12 +426,12 @@ describe('Issues', function () {
426
426
'2023-01-05T12:00:00+0000'
427
427
expect ( html ) . toEqual ( expected )
428
428
} )
429
- it ( '#610 should throw missing ":" after filter name' , ( ) => {
429
+ it ( 'should throw missing ":" after filter name #610 ' , ( ) => {
430
430
const engine = new Liquid ( )
431
431
const fn = ( ) => engine . parseAndRenderSync ( "{%- assign module = '' | split '' -%}" )
432
432
expect ( fn ) . toThrow ( / e x p e c t e d " : " a f t e r f i l t e r n a m e / )
433
433
} )
434
- it ( '#628 Single or double quote breaks comments' , ( ) => {
434
+ it ( 'Single or double quote breaks comments #628 ' , ( ) => {
435
435
const template = `{%- liquid
436
436
# Show a message that's customized to the product type
437
437
@@ -454,7 +454,7 @@ describe('Issues', function () {
454
454
const result = engine . parseAndRenderSync ( template , { product } )
455
455
expect ( result ) . toEqual ( 'This is a love potion!' )
456
456
} )
457
- it ( '#643 Error When Accessing Subproperty of Bracketed Reference' , ( ) => {
457
+ it ( 'Error When Accessing Subproperty of Bracketed Reference #643 ' , ( ) => {
458
458
const engine = new Liquid ( )
459
459
const tpl = '{{ ["Key String with Spaces"].subpropertyKey }}'
460
460
const ctx = {
@@ -464,20 +464,20 @@ describe('Issues', function () {
464
464
}
465
465
expect ( engine . parseAndRenderSync ( tpl , ctx ) ) . toEqual ( 'FOO' )
466
466
} )
467
- it ( '#655 Error in the tokenization process due to an invalid value expression' , ( ) => {
467
+ it ( 'Error in the tokenization process due to an invalid value expression #655 ' , ( ) => {
468
468
const engine = new Liquid ( )
469
469
const result = engine . parseAndRenderSync ( '{{ÜLKE}}' , { ÜLKE : 'Türkiye' } )
470
470
expect ( result ) . toEqual ( 'Türkiye' )
471
471
} )
472
- it ( '#670 Should not render anything after an else branch' , ( ) => {
472
+ it ( 'Should not render anything after an else branch #670 ' , ( ) => {
473
473
const engine = new Liquid ( )
474
474
expect ( ( ) => engine . parseAndRenderSync ( '{% assign value = "this" %}{% if false %}{% else %}{% else %}{% endif %}' ) ) . toThrow ( 'duplicated else' )
475
475
} )
476
- it ( '#672 Should not render an elseif after an else branch' , ( ) => {
476
+ it ( 'Should not render an elseif after an else branch #672 ' , ( ) => {
477
477
const engine = new Liquid ( )
478
478
expect ( ( ) => engine . parseAndRenderSync ( '{% if false %}{% else %}{% elsif true %}{% endif %}' ) ) . toThrow ( 'unexpected elsif after else' )
479
479
} )
480
- it ( '#675 10.10.1 Operator: contains regression' , ( ) => {
480
+ it ( '10.10.1 Operator: contains regression #675 ' , ( ) => {
481
481
const engine = new Liquid ( )
482
482
class StrictStringForLiquid {
483
483
constructor ( private value : string ) { }
@@ -491,4 +491,8 @@ describe('Issues', function () {
491
491
} )
492
492
expect ( result ) . toEqual ( 'true' )
493
493
} )
494
+ it ( 'parse length limit exceeded on versions >= 10.15.0 #726' , ( ) => {
495
+ const liquid = new Liquid ( )
496
+ expect ( ( ) => liquid . parse ( { } as any ) ) . not . toThrow ( )
497
+ } )
494
498
} )
0 commit comments