Skip to content

Commit 459e5dc

Browse files
committed
fixes liquid tag normalisation + Liquid Tag test cases
1 parent 055e14d commit 459e5dc

File tree

4 files changed

+268
-31
lines changed

4 files changed

+268
-31
lines changed

src/lexers/markup.ts

+15-7
Original file line numberDiff line numberDiff line change
@@ -800,8 +800,8 @@ export function markup (input?: string) {
800800
if (lname.startsWith('end')) {
801801

802802
record.token = liner;
803-
record.types = 'liquid_end';
804-
record.lines = lines;
803+
record.types = lname === 'endcase' ? 'liquid_case_end' : 'liquid_end';
804+
record.lines = lines <= 1 ? 2 : lines;
805805

806806
push(record);
807807

@@ -2891,16 +2891,23 @@ export function markup (input?: string) {
28912891
}
28922892

28932893
} else if (
2894-
(u.ws(b[a + 1]) || u.is(b[a + 1], cc.LSB)) &&
2895-
u.ws(b[a]) &&
2896-
u.is(b[a - 1], cc.RSB)) {
2894+
(
2895+
tname !== 'liquid' &&
2896+
u.ws(b[a + 1]) &&
2897+
u.ws(b[a]) &&
2898+
u.is(b[a - 1], cc.RSB)
2899+
) || (
2900+
u.is(b[a], cc.WSP) &&
2901+
u.is(b[a + 1], cc.WSP)
2902+
)
2903+
) {
28972904

28982905
lexed.pop();
28992906

29002907
} else if (
29012908
lexed.length > 3 &&
29022909
u.is(b[a + 1], cc.NWL) &&
2903-
u.ns(b[a + 2])) {
2910+
u.not(b[a + 2], cc.WSP)) {
29042911

29052912
lexed.push(WSP);
29062913

@@ -2983,7 +2990,7 @@ export function markup (input?: string) {
29832990

29842991
lexed.push(WSP);
29852992

2986-
} else if (tname === 'if' || tname === 'unless' || tname === 'elsif') {
2993+
} else if (tname === 'if' || tname === 'unless' || tname === 'elsif' || tname === 'liquid') {
29872994

29882995
if ((
29892996
u.not(b[a], cc.WSP) ||
@@ -3016,6 +3023,7 @@ export function markup (input?: string) {
30163023
lexed.push(WSP);
30173024

30183025
}
3026+
30193027
}
30203028

30213029
}

tests/cases/liquid/liquid-tag.test.mjs

+245-11
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,227 @@ import test from 'ava';
22
import { liquid, forAssert, forSample } from '@liquify/ava/esthetic';
33
import esthetic from 'esthetic';
44

5-
test.skip('Liquid Tag: Normalising spacing of Liquid Tag internal expressions', t => {
5+
test('Liquid Tag - Structural tests and syntactical formations', t => {
66

77
forAssert(
88
[
99
[
10-
liquid`{% # Extraneous spacing between characters within a Liquid Tag %}
10+
liquid`{% # Capture Indentation %}
11+
12+
{% liquid
13+
capture foo
14+
echo 'string 1'
15+
endcapture
16+
17+
# comment
18+
capture foo
19+
echo 'string 1'
20+
endcapture
21+
%}
22+
23+
`,
24+
liquid`{% # Capture Indentation %}
25+
26+
{% liquid
27+
capture foo
28+
echo 'string 1'
29+
endcapture
30+
31+
# comment
32+
capture foo
33+
echo 'string 1'
34+
endcapture
35+
%}
36+
`
37+
],
38+
[
39+
liquid`{% # Filter ending assignments encapsulated within tag blocks %}
40+
41+
{% liquid
42+
43+
assign foo = object['prop'] | filter: 'foo'
44+
45+
if condition and assertion
46+
assign ENDING_RSB = object['prop'][0]
47+
elsif
48+
assign ENDING_WORD = object['prop'].value
49+
elsif
50+
assign ENDING_QUOTE = 'string'
51+
elsif
52+
assign ENDING_NUMBER = 1000
53+
else
54+
assign ENDING_NIL = nil
55+
endif
56+
57+
if product.selected_or_first_available_variant.featured_media
58+
assign seo_media = product.selected_or_first_available_variant.featured_media
59+
else
60+
assign seo_media = product.featured_media
61+
endif
62+
63+
assign x = product.selected_or_first_available_variant.quantity_price_breaks | sort: 'quantity' | reverse
64+
assign current_qty = cart_qty | plus: product.selected_or_first_available_variant.quantity_rule.min
65+
if cart_qty > 0
66+
assign current_qty_for_volume_pricing = cart_qty | plus: product.selected_or_first_available_variant.quantity_rule.increment
67+
endif
68+
%}
69+
70+
`,
71+
liquid`{% # Filter ending assignments encapsulated within tag blocks %}
72+
73+
{% liquid
74+
75+
assign foo = object['prop'] | filter: 'foo'
76+
77+
if condition and assertion
78+
assign ENDING_RSB = object['prop'][0]
79+
elsif
80+
assign ENDING_WORD = object['prop'].value
81+
elsif
82+
assign ENDING_QUOTE = 'string'
83+
elsif
84+
assign ENDING_NUMBER = 1000
85+
else
86+
assign ENDING_NIL = nil
87+
endif
88+
89+
if product.selected_or_first_available_variant.featured_media
90+
assign seo_media = product.selected_or_first_available_variant.featured_media
91+
else
92+
assign seo_media = product.featured_media
93+
endif
94+
95+
assign x = product.selected_or_first_available_variant.quantity_price_breaks | sort: 'quantity' | reverse
96+
assign current_qty = cart_qty | plus: product.selected_or_first_available_variant.quantity_rule.min
97+
if cart_qty > 0
98+
assign current_qty_for_volume_pricing = cart_qty | plus: product.selected_or_first_available_variant.quantity_rule.increment
99+
endif
100+
%}
101+
`
102+
],
103+
[
104+
liquid`{% # Forloop enders %}
105+
106+
{% liquid
107+
108+
for item in array limit: 200
109+
110+
echo item.prop | filter: 1000
111+
112+
for range in (1..1000)
113+
echo range
114+
endfor
115+
endfor
116+
117+
%}
118+
119+
`,
120+
liquid`{% # Forloop enders %}
121+
122+
{% liquid
123+
124+
for item in array limit: 200
125+
126+
echo item.prop | filter: 1000
11127
128+
for range in (1..1000)
129+
echo range
130+
endfor
131+
endfor
132+
%}
133+
`
134+
],
135+
[
136+
liquid`{% # Case Structures and deep nesting %}
137+
138+
{%- liquid
139+
140+
case section.settings.sort
141+
when 'products_high', 'products_low'
142+
assign collections = collections.vendors | sort: 'all_products_count'
143+
when 'date', 'date_reversed'
144+
assign collections = collections.vendors | sort: 'published_at'
145+
else
146+
case section.settings.sort
147+
when 'products_high', 'products_low'
148+
assign collections = collections.vendors | sort: 'all_products_count'
149+
when 'date', 'date_reversed'
150+
assign collections = collections.vendors | sort: 'published_at'
151+
endcase
152+
endcase
153+
154+
-%}
155+
`,
156+
liquid`{% # Case Structures and deep nesting %}
157+
158+
{%- liquid
159+
160+
case section.settings.sort
161+
when 'products_high', 'products_low'
162+
assign collections = collections.vendors | sort: 'all_products_count'
163+
when 'date', 'date_reversed'
164+
assign collections = collections.vendors | sort: 'published_at'
165+
else
166+
case section.settings.sort
167+
when 'products_high', 'products_low'
168+
assign collections = collections.vendors | sort: 'all_products_count'
169+
when 'date', 'date_reversed'
170+
assign collections = collections.vendors | sort: 'published_at'
171+
endcase
172+
endcase
173+
-%}
174+
`
175+
],
176+
[
177+
liquid`{% # Conditional Structures %}
178+
{% liquid
179+
assign rating_decimal = 0
180+
assign decimal = product.metafields.reviews.rating.value.rating | modulo: 1
181+
if decimal >= 0.3 and decimal <= 0.7
182+
assign rating_decimal = 0.5
183+
elsif decimal > 0.7
184+
assign rating_decimal = 1
185+
endif
186+
%}
187+
`,
188+
liquid`{% # Conditional Structures %}
189+
{% liquid
190+
assign rating_decimal = 0
191+
assign decimal = product.metafields.reviews.rating.value.rating | modulo: 1
192+
if decimal >= 0.3 and decimal <= 0.7
193+
assign rating_decimal = 0.5
194+
elsif decimal > 0.7
195+
assign rating_decimal = 1
196+
endif
197+
%}
198+
`
199+
]
200+
]
201+
)(function (source, expected) {
202+
203+
const actual = esthetic.format(source, {
204+
language: 'liquid',
205+
liquid: {
206+
dedentTagList: []
207+
},
208+
markup: {
209+
forceAttribute: 2,
210+
normalizeSpacing: true
211+
}
212+
});
213+
214+
// console.log(actual);
215+
t.deepEqual(actual, expected);
216+
217+
});
218+
});
12219

220+
test('Liquid Tag: Normalize spacing of Liquid Tag internal expressions', t => {
221+
222+
forAssert(
223+
[
224+
[
225+
liquid`{% # Extraneous spacing between characters within a Liquid Tag %}
13226
14227
{% liquid
15228
if x ==foo . property [ 0 ] . xxx and bar != baz or 5000< 2000
@@ -21,25 +234,46 @@ test.skip('Liquid Tag: Normalising spacing of Liquid Tag internal expressions',
21234
endif
22235
%}
23236
24-
{% if x==foo and bar != baz or 5000< 2000 %}
25-
{% endif %}
26-
27237
`,
28238
liquid`{% # Extraneous spacing between characters within a Liquid Tag %}
29239
30240
{% liquid
31-
32-
if x == foo.property[0].xx and bar != baz or 5000 < 2000
241+
if x == foo.property[0].xxx and bar != baz or 5000 < 2000
33242
unless y == x
34243
assign var = xxx | filter: ' preserve-string ' | filter: 100 | filter: true
244+
echo 'foo' | filter | filter: 'bar', 300 | append: 'from', 'to', something, 1000
245+
echo 'foo' | filter | filter: 'bar', 300 | append: 'from', 'to', something, 1000
35246
endunless
36247
endif
37248
%}
249+
`
250+
],
251+
[
252+
liquid`{% # Extraneous spacing between characters within a Liquid Tag %}
38253
39-
{% if x == foo and bar != baz or 5000 < 2000 %}
40-
{% endif %}
254+
{% liquid
41255
42-
`
256+
if x == foo.property[0].xx and bar != baz or 5000 < 2000
257+
unless y == x
258+
assign var = xxx | filter: ' preserve-string ' | filter: 100 | filter: true
259+
endunless
260+
endif
261+
%}
262+
263+
`,
264+
265+
liquid`{% # Extraneous spacing between characters within a Liquid Tag %}
266+
267+
{% liquid
268+
269+
if x == foo.property[0].xx and bar != baz or 5000 < 2000
270+
unless y == x
271+
assign var = xxx | filter: ' preserve-string ' | filter: 100 | filter: true
272+
endunless
273+
endif
274+
%}
275+
276+
`
43277
]
44278
]
45279
)(function (source, expected) {
@@ -58,7 +292,7 @@ test.skip('Liquid Tag: Normalising spacing of Liquid Tag internal expressions',
58292
});
59293
});
60294

61-
test('Structure Test: Indentation depth levels encapsulated by markup', t => {
295+
test('Liquid Tag: Indentation depth levels encapsulated by markup', t => {
62296

63297
forSample(
64298
[

tests/dev.test.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ dev(function (source) {
113113

114114
const output = esthetic.format(source, {
115115

116-
language: 'css',
116+
language: 'liquid',
117117
wrap: 0,
118118
indentSize: 2,
119119
liquid: {

tests/dev.txt

+7-12
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1+
{% liquid
12

2-
/* media query pseudo selector nesting */
33

4-
@media (prefers-reduced-motion: no-preference) {
4+
if product.tags contains "Women"
5+
assign model = shop.metafields.product.model.value["woman"]
6+
else
7+
assign model = shop.metafields.product.model.value["man"]
8+
endif
9+
%}
510

6-
7-
:root {
8-
scroll-behavior: smooth;
9-
}
10-
11-
::-webkit-search-decoration {
12-
-webkit-appearance: none;
13-
}
14-
15-
}

0 commit comments

Comments
 (0)