mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-17 05:10:40 -07:00
fix: inconsistent continue behaviour, fixes #779
This commit is contained in:
@@ -25,6 +25,8 @@ export class Context {
|
|||||||
*/
|
*/
|
||||||
public globals: Scope
|
public globals: Scope
|
||||||
public sync: boolean
|
public sync: boolean
|
||||||
|
public breakCalled = false
|
||||||
|
public continueCalled = false
|
||||||
/**
|
/**
|
||||||
* The normalized liquid options object
|
* The normalized liquid options object
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export class Render {
|
|||||||
const html = yield tpl.render(ctx, emitter)
|
const html = yield tpl.render(ctx, emitter)
|
||||||
// if not, it'll return an `html`, write to the emitter for it
|
// if not, it'll return an `html`, write to the emitter for it
|
||||||
html && emitter.write(html)
|
html && emitter.write(html)
|
||||||
if (emitter['break'] || emitter['continue']) break
|
if (ctx.breakCalled || ctx.continueCalled) break
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const err = LiquidError.is(e) ? e : new RenderError(e as Error, tpl)
|
const err = LiquidError.is(e) ? e : new RenderError(e as Error, tpl)
|
||||||
if (ctx.opts.catchAllErrors) errors.push(err)
|
if (ctx.opts.catchAllErrors) errors.push(err)
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
import { Context, Emitter, Tag } from '..'
|
import { Context, Emitter, Tag } from '..'
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
render (ctx: Context, emitter: Emitter) {
|
render (ctx: Context, _emitter: Emitter) {
|
||||||
emitter['break'] = true
|
ctx.breakCalled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Tag, Emitter, Context } from '..'
|
import { Tag, Emitter, Context } from '..'
|
||||||
|
|
||||||
export default class extends Tag {
|
export default class extends Tag {
|
||||||
render (ctx: Context, emitter: Emitter) {
|
render (ctx: Context, _emitter: Emitter) {
|
||||||
emitter['continue'] = true
|
ctx.continueCalled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-5
@@ -68,12 +68,9 @@ export default class extends Tag {
|
|||||||
ctx.push(scope)
|
ctx.push(scope)
|
||||||
for (const item of collection) {
|
for (const item of collection) {
|
||||||
scope[this.variable] = item
|
scope[this.variable] = item
|
||||||
|
ctx.continueCalled = ctx.breakCalled = false
|
||||||
yield r.renderTemplates(this.templates, ctx, emitter)
|
yield r.renderTemplates(this.templates, ctx, emitter)
|
||||||
if (emitter['break']) {
|
if (ctx.breakCalled) break
|
||||||
emitter['break'] = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
emitter['continue'] = false
|
|
||||||
scope.forloop.next()
|
scope.forloop.next()
|
||||||
}
|
}
|
||||||
ctx.pop()
|
ctx.pop()
|
||||||
|
|||||||
@@ -525,8 +525,10 @@ describe('Issues', function () {
|
|||||||
expect(result).toEqual('\n[2,12] foo')
|
expect(result).toEqual('\n[2,12] foo')
|
||||||
})
|
})
|
||||||
it("memoryLimit doesn't work in for tag #776", () => {
|
it("memoryLimit doesn't work in for tag #776", () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid({
|
||||||
|
memoryLimit: 1e5
|
||||||
|
})
|
||||||
const tpl = `{% for i in (1..1000000000) %} {{'a'}} {% endfor %}`
|
const tpl = `{% for i in (1..1000000000) %} {{'a'}} {% endfor %}`
|
||||||
expect(() => engine.parseAndRenderSync(tpl)).toThrow(/memory out/)
|
expect(() => engine.parseAndRenderSync(tpl)).toThrow('memory alloc limit exceeded, line:1, col:1')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { Drop } from '../../../src/drop/drop'
|
import { Drop } from '../../../src/drop/drop'
|
||||||
import { Scope } from '../../../src/context/scope'
|
import { Scope } from '../../../src/context/scope'
|
||||||
|
import { mock, restore } from '../../stub/mockfs'
|
||||||
|
|
||||||
describe('tags/for', function () {
|
describe('tags/for', function () {
|
||||||
let liquid: Liquid, scope: Scope
|
let liquid: Liquid, scope: Scope
|
||||||
@@ -139,6 +140,7 @@ describe('tags/for', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('continue', function () {
|
describe('continue', function () {
|
||||||
|
afterEach(restore)
|
||||||
it('should support for with continue', async function () {
|
it('should support for with continue', async function () {
|
||||||
const src = '{% for i in (1..5) %}' +
|
const src = '{% for i in (1..5) %}' +
|
||||||
'{% if i == 4 %}continue{% continue %}{% endif %}{{i}}' +
|
'{% if i == 4 %}continue{% continue %}{% endif %}{{i}}' +
|
||||||
@@ -154,6 +156,28 @@ describe('tags/for', function () {
|
|||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).toBe('123continue5')
|
return expect(html).toBe('123continue5')
|
||||||
})
|
})
|
||||||
|
it('should skip snippet for rendered continue', async function () {
|
||||||
|
mock({
|
||||||
|
'snippet.liquid': ' before{% continue %}skipped'
|
||||||
|
})
|
||||||
|
const src = '{% for i in (1..2) %}' +
|
||||||
|
'{% render "snippet.liquid" %}' +
|
||||||
|
' after' +
|
||||||
|
'{% endfor %}'
|
||||||
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
|
return expect(html).toBe(' before after before after')
|
||||||
|
})
|
||||||
|
it('should skip `for` body for included continue', async function () {
|
||||||
|
mock({
|
||||||
|
'snippet.liquid': ' before{% continue %}skipped'
|
||||||
|
})
|
||||||
|
const src = '{% for i in (1..2) %}' +
|
||||||
|
'{% include "snippet.liquid" %}' +
|
||||||
|
' after' +
|
||||||
|
'{% endfor %}'
|
||||||
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
|
return expect(html).toBe(' before before')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
describe('break', function () {
|
describe('break', function () {
|
||||||
it('should support break', async function () {
|
it('should support break', async function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user