Skip to content

Commit d17813e

Browse files
committed
fix: case should render multiple when statements
1 parent 46ffe03 commit d17813e

File tree

3 files changed

+45
-14
lines changed

3 files changed

+45
-14
lines changed

src/tags/case.ts

+20-14
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ValueToken, Liquid, Tokenizer, toValue, evalToken, Value, Emitter, TagT
22

33
export default class extends Tag {
44
value: Value
5-
branches: { value?: ValueToken, templates: Template[] }[] = []
5+
branches: { values: ValueToken[], templates: Template[] }[] = []
66
elseTemplates: Template[] = []
77
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
88
super(tagToken, remainTokens, liquid)
@@ -15,15 +15,15 @@ export default class extends Tag {
1515
p = []
1616

1717
const tokenizer = new Tokenizer(token.args, this.liquid.options.operators)
18-
18+
const values: ValueToken[] = []
1919
while (!tokenizer.end()) {
20-
const value = tokenizer.readValue()
21-
this.branches.push({
22-
value: value,
23-
templates: p
24-
})
20+
values.push(tokenizer.readValueOrThrow())
2521
tokenizer.readTo(',')
2622
}
23+
this.branches.push({
24+
values,
25+
templates: p
26+
})
2727
})
2828
.on('tag:else', () => (p = this.elseTemplates))
2929
.on('tag:endcase', () => stream.stop())
@@ -35,16 +35,22 @@ export default class extends Tag {
3535
stream.start()
3636
}
3737

38-
* render (ctx: Context, emitter: Emitter): Generator<unknown, unknown, unknown> {
38+
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, unknown> {
3939
const r = this.liquid.renderer
40-
const value = toValue(yield this.value.value(ctx, ctx.opts.lenientIf))
40+
const target = toValue(yield this.value.value(ctx, ctx.opts.lenientIf))
41+
let branchHit = false
4142
for (const branch of this.branches) {
42-
const target = yield evalToken(branch.value, ctx, ctx.opts.lenientIf)
43-
if (target === value) {
44-
yield r.renderTemplates(branch.templates, ctx, emitter)
45-
return
43+
for (const valueToken of branch.values) {
44+
const value = yield evalToken(valueToken, ctx, ctx.opts.lenientIf)
45+
if (target === value) {
46+
yield r.renderTemplates(branch.templates, ctx, emitter)
47+
branchHit = true
48+
break
49+
}
4650
}
4751
}
48-
yield r.renderTemplates(this.elseTemplates, ctx, emitter)
52+
if (!branchHit) {
53+
yield r.renderTemplates(this.elseTemplates, ctx, emitter)
54+
}
4955
}
5056
}

test/e2e/issues.ts

+17
Original file line numberDiff line numberDiff line change
@@ -329,4 +329,21 @@ describe('Issues', function () {
329329
expect(await liquid.parseAndRender('{{i.i}}', context)).to.equal('1')
330330
expect(await liquid.parseAndRender('{{j.j}}', context)).to.equal('1')
331331
})
332+
it('#559 Case/When should evaluate multiple When statements', async () => {
333+
const liquid = new Liquid()
334+
const tpl = `
335+
{% assign tag = 'Love' %}
336+
337+
{% case tag %}
338+
{% when 'Love' or 'Luck' %}
339+
This is a love or luck potion.
340+
{% when 'Strength','Health', 'Love' %}
341+
This is a strength or health or love potion.
342+
{% else %}
343+
This is a potion.
344+
{% endcase %}
345+
`
346+
const html = await liquid.parseAndRender(tpl)
347+
expect(html).to.match(/^\s*This is a love or luck potion.\s+This is a strength or health or love potion.\s*$/)
348+
})
332349
})

test/integration/tags/case.ts

+8
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,12 @@ describe('tags/case', function () {
7171
const html = await liquid.parseAndRender(src)
7272
return expect(html).to.equal('foo')
7373
})
74+
it('should render multiple matching branches', async function () {
75+
const src = '{% case "b" %}' +
76+
'{% when "a", "b" %}first' +
77+
'{% when "b" %}second' +
78+
'{%endcase%}'
79+
const html = await liquid.parseAndRender(src)
80+
return expect(html).to.equal('firstsecond')
81+
})
7482
})

0 commit comments

Comments
 (0)