@@ -2,25 +2,25 @@ import { TopLevelToken, TagToken, Tokenizer, Context, Liquid, Drop, toValueSync
22const LiquidUMD = require ( '../../dist/liquid.browser.umd.js' ) . Liquid
33
44describe ( 'Issues' , function ( ) {
5- it ( '#221 unicode blanks are not properly treated' , async ( ) => {
5+ it ( 'unicode blanks are not properly treated #221 ' , async ( ) => {
66 const engine = new Liquid ( { strictVariables : true , strictFilters : true } )
77 const html = engine . parseAndRenderSync ( '{{huh | truncate: 11}}' , { huh : 'fdsafdsafdsafdsaaaaa' } )
88 expect ( html ) . toBe ( 'fdsafdsa...' )
99 } )
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 ( ) => {
1111 const template = `{% capture "form_classes" -%}
1212 foo
1313 {%- endcapture %}{{form_classes}}`
1414 const engine = new Liquid ( )
1515 const html = await engine . parseAndRender ( template )
1616 expect ( html ) . toBe ( 'foo' )
1717 } )
18- it ( '#259 complex property access with braces is not supported' , async ( ) => {
18+ it ( 'complex property access with braces is not supported #259 ' , async ( ) => {
1919 const engine = new Liquid ( )
2020 const html = engine . parseAndRenderSync ( '{{ ["complex key"] }}' , { 'complex key' : 'foo' } )
2121 expect ( html ) . toBe ( 'foo' )
2222 } )
23- it ( '#243 Potential for ReDoS through string replace function' , async ( ) => {
23+ it ( 'Potential for ReDoS through string replace function #243 ' , async ( ) => {
2424 const engine = new Liquid ( )
2525 const INPUT = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!'
2626 const BROKEN_REGEX = / ( [ a - z ] + ) + $ /
@@ -33,13 +33,13 @@ describe('Issues', function () {
3333 // should stringify the regexp rather than execute it
3434 expect ( html ) . toBe ( INPUT )
3535 } )
36- it ( '#263 raw/endraw block not ignoring {% characters' , ( ) => {
36+ it ( 'raw/endraw block not ignoring {% characters #263 ' , ( ) => {
3737 const template = `{% raw %}This is a code snippet showing how {% breaks the raw block.{% endraw %}`
3838 const engine = new Liquid ( )
3939 const html = engine . parseAndRenderSync ( template )
4040 expect ( html ) . toBe ( 'This is a code snippet showing how {% breaks the raw block.' )
4141 } )
42- it ( '#268 elsif is not supported for unless' , ( ) => {
42+ it ( 'elsif is not supported for unless #268 ' , ( ) => {
4343 const template = `{%- unless condition1 -%}
4444 <div>X</div>
4545 {%- elsif condition2 -%}
@@ -51,7 +51,7 @@ describe('Issues', function () {
5151 const html = engine . parseAndRenderSync ( template , { condition1 : true , condition2 : true } )
5252 expect ( html ) . toBe ( '<div>Y</div>' )
5353 } )
54- it ( '#277 Passing liquid in FilterImpl' , ( ) => {
54+ it ( 'Passing liquid in FilterImpl #277 ' , ( ) => {
5555 const engine = new Liquid ( )
5656 engine . registerFilter ( 'render' , function ( this : any , template : string , name : string ) {
5757 return this . liquid . parseAndRenderSync ( decodeURIComponent ( template ) , { name } )
@@ -62,55 +62,55 @@ describe('Issues', function () {
6262 )
6363 expect ( html ) . toBe ( 'hello foo' )
6464 } )
65- it ( '#288 Unexpected behavior when string literals contain }}' , async ( ) => {
65+ it ( 'Unexpected behavior when string literals contain }} #288 ' , async ( ) => {
6666 const engine = new Liquid ( )
6767 const html = await engine . parseAndRender ( `{{ '{{' }}{{ '}}' }}` )
6868 expect ( html ) . toBe ( '{{}}' )
6969 } )
70- it ( '#222 Support function calls' , async ( ) => {
70+ it ( 'Support function calls #222 ' , async ( ) => {
7171 const engine = new Liquid ( )
7272 const html = await engine . parseAndRender (
7373 `{{ obj.property }}` ,
7474 { obj : { property : ( ) => 'BAR' } }
7575 )
7676 expect ( html ) . toBe ( 'BAR' )
7777 } )
78- it ( '#313 lenientIf not working as expected in umd' , async ( ) => {
78+ it ( 'lenientIf not working as expected in umd #313 ' , async ( ) => {
7979 const engine = new LiquidUMD ( {
8080 strictVariables : true ,
8181 lenientIf : true
8282 } )
8383 const html = await engine . parseAndRender ( `{{ name | default: "default name" }}` )
8484 expect ( html ) . toBe ( 'default name' )
8585 } )
86- it ( '#321 comparison for empty/nil' , async ( ) => {
86+ it ( 'comparison for empty/nil #321 ' , async ( ) => {
8787 const engine = new Liquid ( )
8888 const html = await engine . parseAndRender (
8989 '{% if empty == nil %}true{%else%}false{%endif%}' +
9090 '{% if nil == empty %}true{%else%}false{%endif%}'
9191 )
9292 expect ( html ) . toBe ( 'falsefalse' )
9393 } )
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 ( ) => {
9595 const engine = new Liquid ( )
9696 const html = await engine . parseAndRender (
9797 `{{ 'a \n b \n c' | newline_to_br | split: '<br />' }}`
9898 )
9999 expect ( html ) . toBe ( 'a \n b \n c' )
100100 } )
101- it ( '#342 New lines in logical operator' , async ( ) => {
101+ it ( 'New lines in logical operator #342 ' , async ( ) => {
102102 const engine = new Liquid ( )
103103 const tpl = `{%\r\nif\r\ntrue\r\nor\r\nfalse\r\n%}\r\ntrue\r\n{%\r\nendif\r\n%}`
104104 const html = await engine . parseAndRender ( tpl )
105105 expect ( html ) . toBe ( '\r\ntrue\r\n' )
106106 } )
107- it ( '#401 Timezone Offset Issue' , async ( ) => {
107+ it ( 'Timezone Offset Issue #401 ' , async ( ) => {
108108 const engine = new Liquid ( { timezoneOffset : - 600 } )
109109 const tpl = engine . parse ( '{{ date | date: "%Y-%m-%d %H:%M %p %z" }}' )
110110 const html = await engine . render ( tpl , { date : '2021-10-06T15:31:00+08:00' } )
111111 expect ( html ) . toBe ( '2021-10-06 17:31 PM +1000' )
112112 } )
113- it ( '#412 Pass root as it is to `resolve`' , async ( ) => {
113+ it ( 'Pass root as it is to `resolve` #412 ' , async ( ) => {
114114 const engine = new Liquid ( {
115115 root : '/tmp' ,
116116 relativeReference : false ,
@@ -126,7 +126,7 @@ describe('Issues', function () {
126126 const html = await engine . renderSync ( tpl )
127127 expect ( html ) . toBe ( '/tmp/foo.liquid' )
128128 } )
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 ( ) => {
130130 const readFile = jest . fn ( ( ) => Promise . resolve ( 'HELLO' ) )
131131 const exists = jest . fn ( ( ) => 'HELLO' )
132132 const engine = new Liquid ( {
@@ -148,15 +148,15 @@ describe('Issues', function () {
148148 expect ( exists ) . toHaveBeenCalledTimes ( 1 )
149149 expect ( readFile ) . toHaveBeenCalledTimes ( 1 )
150150 } )
151- it ( '#431 Error when using Date timezoneOffset in 9.28.5' , ( ) => {
151+ it ( 'Error when using Date timezoneOffset in 9.28.5 #431 ' , ( ) => {
152152 const engine = new Liquid ( {
153153 timezoneOffset : 0 ,
154154 preserveTimezones : true
155155 } )
156156 const tpl = engine . parse ( 'Welcome to {{ now | date: "%Y-%m-%d" }}' )
157157 return expect ( engine . render ( tpl , { now : new Date ( '2019-02-01T00:00:00.000Z' ) } ) ) . resolves . toBe ( 'Welcome to 2019-02-01' )
158158 } )
159- it ( '#433 Support Jekyll-like includes' , async ( ) => {
159+ it ( 'Support Jekyll-like includes #433 ' , async ( ) => {
160160 const engine = new Liquid ( {
161161 dynamicPartials : false ,
162162 relativeReference : false ,
@@ -173,7 +173,7 @@ describe('Issues', function () {
173173 const html = await engine . render ( tpl , { my_variable : 'foo' } )
174174 expect ( html ) . toBe ( 'CONTENT for /tmp/prefix/foo-bar/suffix' )
175175 } )
176- it ( '#428 Implement liquid/echo tags' , ( ) => {
176+ it ( 'Implement liquid/echo tags #428 ' , ( ) => {
177177 const template = `{%- liquid
178178 for value in array
179179 assign double_value = value | times: 2
@@ -190,25 +190,25 @@ describe('Issues', function () {
190190 const html = engine . parseAndRenderSync ( template , { array : [ 1 , 2 , 3 ] } )
191191 expect ( html ) . toBe ( '4#8#12#6' )
192192 } )
193- it ( '#454 leaking JS prototype getter functions in evaluation' , async ( ) => {
193+ it ( 'leaking JS prototype getter functions in evaluation #454 ' , async ( ) => {
194194 const engine = new Liquid ( { ownPropertyOnly : true } )
195195 const html = engine . parseAndRenderSync ( '{{foo | size}}-{{bar.coo}}' , { foo : 'foo' , bar : Object . create ( { coo : 'COO' } ) } )
196196 expect ( html ) . toBe ( '3-' )
197197 } )
198- it ( '#465 Liquidjs divided_by not compatible with Ruby/Shopify Liquid' , ( ) => {
198+ it ( 'Liquidjs divided_by not compatible with Ruby/Shopify Liquid #465 ' , ( ) => {
199199 const engine = new Liquid ( { ownPropertyOnly : true } )
200200 const html = engine . parseAndRenderSync ( '{{ 5 | divided_by: 3, true }}' )
201201 expect ( html ) . toBe ( '1' )
202202 } )
203- it ( '#479 url_encode throws on undefined value' , async ( ) => {
203+ it ( 'url_encode throws on undefined value #479 ' , async ( ) => {
204204 const engine = new Liquid ( {
205205 strictVariables : false
206206 } )
207207 const tpl = engine . parse ( '{{ v | url_encode }}' )
208208 const html = await engine . render ( tpl , { v : undefined } )
209209 expect ( html ) . toBe ( '' )
210210 } )
211- it ( '#481 filters that should not throw' , async ( ) => {
211+ it ( 'filters that should not throw #481 ' , async ( ) => {
212212 const engine = new Liquid ( )
213213 const tpl = engine . parse ( `
214214 {{ foo | join }}
@@ -223,17 +223,17 @@ describe('Issues', function () {
223223 const html = await engine . render ( tpl , { foo : undefined } )
224224 expect ( html . trim ( ) ) . toBe ( '[]' )
225225 } )
226- it ( '#481 concat should always return an array' , async ( ) => {
226+ it ( 'concat should always return an array #481 ' , async ( ) => {
227227 const engine = new Liquid ( )
228228 const html = await engine . parseAndRender ( `{{ foo | concat | json }}` )
229229 expect ( html ) . toBe ( '[]' )
230230 } )
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 ( ) => {
232232 const engine = new Liquid ( )
233233 const html = await engine . parseAndRender ( `{% assign a = "x,y,z" | split: ',' -%}{{ a[-1] }} {{ a[-3] }} {{ a[-8] }}` )
234234 expect ( html ) . toBe ( 'z x ' )
235235 } )
236- it ( '#492 contains operator does not support Drop' , async ( ) => {
236+ it ( 'contains operator does not support Drop #492 ' , async ( ) => {
237237 class TemplateDrop extends Drop {
238238 valueOf ( ) { return 'product' }
239239 }
@@ -242,44 +242,44 @@ describe('Issues', function () {
242242 const html = await engine . parseAndRender ( `{% if template contains "product" %}contains{%endif%}` , ctx )
243243 expect ( html ) . toBe ( 'contains' )
244244 } )
245- it ( '#513 should support large number of templates [async]' , async ( ) => {
245+ it ( 'should support large number of templates [async] #513 ' , async ( ) => {
246246 const engine = new Liquid ( )
247247 const html = await engine . parseAndRender ( `{% for i in (1..10000) %}{{ i }}{% endfor %}` )
248248 expect ( html ) . toHaveLength ( 38894 )
249249 } )
250- it ( '#513 should support large number of templates [sync]' , ( ) => {
250+ it ( 'should support large number of templates [sync] #513 ' , ( ) => {
251251 const engine = new Liquid ( )
252252 const html = engine . parseAndRenderSync ( `{% for i in (1..10000) %}{{ i }}{% endfor %}` )
253253 expect ( html ) . toHaveLength ( 38894 )
254254 } )
255- it ( '#519 should throw parse error for invalid assign expression' , ( ) => {
255+ it ( 'should throw parse error for invalid assign expression #519 ' , ( ) => {
256256 const engine = new Liquid ( )
257257 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 / )
258258 } )
259- it ( '#527 export Liquid Expression' , ( ) => {
259+ it ( 'export Liquid Expression #527 ' , ( ) => {
260260 const tokenizer = new Tokenizer ( 'a > b' )
261261 const expression = tokenizer . readExpression ( )
262262 const result = toValueSync ( expression . evaluate ( new Context ( { a : 1 , b : 2 } ) ) )
263263 expect ( result ) . toBe ( false )
264264 } )
265- it ( '#527 export Liquid Expression (evalValue)' , async ( ) => {
265+ it ( 'export Liquid Expression (evalValue) #527 ' , async ( ) => {
266266 const liquid = new Liquid ( )
267267 const result = await liquid . evalValue ( 'a > b' , { a : 1 , b : 2 } )
268268 expect ( result ) . toBe ( false )
269269 } )
270- it ( '#527 export Liquid Expression (evalValueSync)' , async ( ) => {
270+ it ( 'export Liquid Expression (evalValueSync) #527 ' , async ( ) => {
271271 const liquid = new Liquid ( )
272272 const result = liquid . evalValueSync ( 'a > b' , { a : 1 , b : 2 } )
273273 expect ( result ) . toBe ( false )
274274 } )
275- it ( '#276 Promise support in expressions' , async ( ) => {
275+ it ( 'Promise support in expressions #276 ' , async ( ) => {
276276 const liquid = new Liquid ( )
277277 const tpl = '{%if name == "alice" %}true{%endif%}'
278278 const ctx = { name : Promise . resolve ( 'alice' ) }
279279 const html = await liquid . parseAndRender ( tpl , ctx )
280280 expect ( html ) . toBe ( 'true' )
281281 } )
282- it ( '#533 Nested Promise support for scope object' , async ( ) => {
282+ it ( 'Nested Promise support for scope object #533 ' , async ( ) => {
283283 const liquid = new Liquid ( )
284284 const context = {
285285 a : 1 ,
@@ -325,7 +325,7 @@ describe('Issues', function () {
325325 expect ( await liquid . parseAndRender ( '{{i.i}}' , context ) ) . toBe ( '1' )
326326 expect ( await liquid . parseAndRender ( '{{j.j}}' , context ) ) . toBe ( '1' )
327327 } )
328- it ( '#559 Case/When should evaluate multiple When statements' , async ( ) => {
328+ it ( 'Case/When should evaluate multiple When statements #559 ' , async ( ) => {
329329 const liquid = new Liquid ( )
330330 const tpl = `
331331 {% assign tag = 'Love' %}
@@ -342,7 +342,7 @@ describe('Issues', function () {
342342 const html = await liquid . parseAndRender ( tpl )
343343 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 * $ / )
344344 } )
345- it ( '#570 tag registration compatible to v9' , async ( ) => {
345+ it ( 'tag registration compatible to v9 #570 ' , async ( ) => {
346346 const liquid = new Liquid ( )
347347 liquid . registerTag ( 'metadata_file' , {
348348 parse ( tagToken : TagToken , remainTokens : TopLevelToken [ ] ) {
@@ -358,7 +358,7 @@ describe('Issues', function () {
358358 const html = await liquid . parseAndRender ( tpl , ctx )
359359 expect ( html ) . toBe ( 'FOO' )
360360 } )
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 ( ) => {
362362 const liquid = new Liquid ( )
363363 liquid . registerTag ( 'metadata_file' , {
364364 parse ( tagToken : TagToken , remainTokens : TopLevelToken [ ] ) {
@@ -374,7 +374,7 @@ describe('Issues', function () {
374374 // sample: Thursday, February 2, 2023 at 6:25 pm +0000
375375 expect ( html ) . toMatch ( / \w + , \w + \d + , \d \d \d \d a t \d + : \d \d [ a p ] m [ - + ] \d \d \d \d / )
376376 } )
377- it ( '#575 Add support for Not operator' , async ( ) => {
377+ it ( 'Add support for Not operator #575 ' , async ( ) => {
378378 const liquid = new Liquid ( )
379379 const tpl = `
380380 {% if link and not button %}
@@ -386,7 +386,7 @@ describe('Issues', function () {
386386 const html = await liquid . parseAndRender ( tpl , ctx )
387387 expect ( html . trim ( ) ) . toBe ( '<a href="https://example.com">Lot more code here</a>' )
388388 } )
389- it ( '#70 strip multiline content of <style>' , async ( ) => {
389+ it ( 'strip multiline content of <style> #70 ' , async ( ) => {
390390 const str = `
391391 <style type="text/css">
392392 .test-one-line {display: none;}
@@ -396,7 +396,7 @@ describe('Issues', function () {
396396 const html = await engine . parseAndRender ( template , { str } )
397397 expect ( html ) . toMatch ( / ^ \s * $ / )
398398 } )
399- it ( '#589 Arrays should compare values' , async ( ) => {
399+ it ( 'Arrays should compare values #589 ' , async ( ) => {
400400 const engine = new Liquid ( )
401401 const template = `
402402 {% assign people1 = "alice, bob, carol" | split: ", " -%}
@@ -406,7 +406,7 @@ describe('Issues', function () {
406406 const html = await engine . parseAndRender ( template )
407407 expect ( html ) . toContain ( 'true' )
408408 } )
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 ' , ( ) => {
410410 const engine = new Liquid ( {
411411 timezoneOffset : 'Etc/GMT'
412412 } )
@@ -426,12 +426,12 @@ describe('Issues', function () {
426426 '2023-01-05T12:00:00+0000'
427427 expect ( html ) . toEqual ( expected )
428428 } )
429- it ( '#610 should throw missing ":" after filter name' , ( ) => {
429+ it ( 'should throw missing ":" after filter name #610 ' , ( ) => {
430430 const engine = new Liquid ( )
431431 const fn = ( ) => engine . parseAndRenderSync ( "{%- assign module = '' | split '' -%}" )
432432 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 / )
433433 } )
434- it ( '#628 Single or double quote breaks comments' , ( ) => {
434+ it ( 'Single or double quote breaks comments #628 ' , ( ) => {
435435 const template = `{%- liquid
436436 # Show a message that's customized to the product type
437437
@@ -454,7 +454,7 @@ describe('Issues', function () {
454454 const result = engine . parseAndRenderSync ( template , { product } )
455455 expect ( result ) . toEqual ( 'This is a love potion!' )
456456 } )
457- it ( '#643 Error When Accessing Subproperty of Bracketed Reference' , ( ) => {
457+ it ( 'Error When Accessing Subproperty of Bracketed Reference #643 ' , ( ) => {
458458 const engine = new Liquid ( )
459459 const tpl = '{{ ["Key String with Spaces"].subpropertyKey }}'
460460 const ctx = {
@@ -464,20 +464,20 @@ describe('Issues', function () {
464464 }
465465 expect ( engine . parseAndRenderSync ( tpl , ctx ) ) . toEqual ( 'FOO' )
466466 } )
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 ' , ( ) => {
468468 const engine = new Liquid ( )
469469 const result = engine . parseAndRenderSync ( '{{ÜLKE}}' , { ÜLKE : 'Türkiye' } )
470470 expect ( result ) . toEqual ( 'Türkiye' )
471471 } )
472- it ( '#670 Should not render anything after an else branch' , ( ) => {
472+ it ( 'Should not render anything after an else branch #670 ' , ( ) => {
473473 const engine = new Liquid ( )
474474 expect ( ( ) => engine . parseAndRenderSync ( '{% assign value = "this" %}{% if false %}{% else %}{% else %}{% endif %}' ) ) . toThrow ( 'duplicated else' )
475475 } )
476- it ( '#672 Should not render an elseif after an else branch' , ( ) => {
476+ it ( 'Should not render an elseif after an else branch #672 ' , ( ) => {
477477 const engine = new Liquid ( )
478478 expect ( ( ) => engine . parseAndRenderSync ( '{% if false %}{% else %}{% elsif true %}{% endif %}' ) ) . toThrow ( 'unexpected elsif after else' )
479479 } )
480- it ( '#675 10.10.1 Operator: contains regression' , ( ) => {
480+ it ( '10.10.1 Operator: contains regression #675 ' , ( ) => {
481481 const engine = new Liquid ( )
482482 class StrictStringForLiquid {
483483 constructor ( private value : string ) { }
@@ -491,4 +491,8 @@ describe('Issues', function () {
491491 } )
492492 expect ( result ) . toEqual ( 'true' )
493493 } )
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+ } )
494498} )
0 commit comments