mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-16 12:50:38 -07:00
feat: renderSync, parseAndRenderSync and renderFileSync, see #48
This commit is contained in:
@@ -81,4 +81,9 @@ describe('tags/assign', function () {
|
||||
return expect(html).to.equal('12 2')
|
||||
})
|
||||
})
|
||||
it('should support sync', function () {
|
||||
const src = '{% assign foo="bar" %}{{foo}}'
|
||||
const html = liquid.parseAndRenderSync(src)
|
||||
return expect(html).to.equal('bar')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -32,4 +32,9 @@ describe('tags/capture', function () {
|
||||
return expect(liquid.parseAndRender(src))
|
||||
.to.be.rejectedWith(/tag .* not closed/)
|
||||
})
|
||||
it('should support sync', function () {
|
||||
const src = '{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}'
|
||||
const html = liquid.parseAndRenderSync(src)
|
||||
return expect(html).to.equal('A')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -48,4 +48,20 @@ describe('tags/case', function () {
|
||||
const html = await liquid.parseAndRender(src)
|
||||
return expect(html).to.equal('d')
|
||||
})
|
||||
describe('sync support', function () {
|
||||
it('should hit the specified case', function () {
|
||||
const src = '{% case "foo"%}' +
|
||||
'{% when "foo" %}foo{% when "bar"%}bar' +
|
||||
'{%endcase%}'
|
||||
const html = liquid.parseAndRenderSync(src)
|
||||
return expect(html).to.equal('foo')
|
||||
})
|
||||
it('should support else branch', function () {
|
||||
const src = '{% case "a" %}' +
|
||||
'{% when "b" %}b{% when "c"%}c{%else %}d' +
|
||||
'{%endcase%}'
|
||||
const html = liquid.parseAndRenderSync(src)
|
||||
return expect(html).to.equal('d')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -31,4 +31,11 @@ describe('tags/comment', function () {
|
||||
const html = await liquid.parseAndRender(src)
|
||||
return expect(html).to.equal('')
|
||||
})
|
||||
describe('sync support', function () {
|
||||
it('should ignore plain string', function () {
|
||||
const src = 'My name is {% comment %}super{% endcomment %} Shopify.'
|
||||
const html = liquid.parseAndRenderSync(src)
|
||||
return expect(html).to.equal('My name is Shopify.')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -35,4 +35,9 @@ describe('tags/cycle', function () {
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
return expect(html).to.equal('121')
|
||||
})
|
||||
it('should support sync', function () {
|
||||
const src = "{% cycle '1', '2', '3' %}"
|
||||
const html = liquid.parseAndRenderSync(src + src + src + src)
|
||||
return expect(html).to.equal('1231')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -6,13 +6,13 @@ import { Scope } from '../../../../src/context/scope'
|
||||
use(chaiAsPromised)
|
||||
|
||||
describe('tags/for', function () {
|
||||
let liquid: Liquid, ctx: Scope
|
||||
let liquid: Liquid, scope: Scope
|
||||
before(function () {
|
||||
liquid = new Liquid()
|
||||
liquid.registerTag('throwingTag', {
|
||||
render: function () { throw new Error('intended render error') }
|
||||
})
|
||||
ctx = {
|
||||
scope = {
|
||||
one: 1,
|
||||
// eslint-disable-next-line
|
||||
strObj: new String(''),
|
||||
@@ -25,30 +25,30 @@ describe('tags/for', function () {
|
||||
})
|
||||
it('should support array', async function () {
|
||||
const src = '{%for c in alpha%}{{c}}{%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('abc')
|
||||
})
|
||||
|
||||
it('should support object', async function () {
|
||||
const src = '{%for item in obj%}{{item[0]}},{{item[1]}}-{%else%}b{%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('foo,bar-coo,haa-')
|
||||
})
|
||||
it('should output forloop', async function () {
|
||||
const src = '{%for i in (1..1)%}{{forloop}}{%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('{"i":0,"length":1}')
|
||||
})
|
||||
describe('illegal', function () {
|
||||
it('should reject when for not closed', function () {
|
||||
const src = '{%for c in alpha%}{{c}}'
|
||||
return expect(liquid.parseAndRender(src, ctx))
|
||||
return expect(liquid.parseAndRender(src, scope))
|
||||
.to.be.rejectedWith(/tag .* not closed/)
|
||||
})
|
||||
|
||||
it('should reject when inner templates rejected', function () {
|
||||
const src = '{%for c in alpha%}{%throwingTag%}{%endfor%}'
|
||||
return expect(liquid.parseAndRender(src, ctx))
|
||||
return expect(liquid.parseAndRender(src, scope))
|
||||
.to.be.rejectedWith(/intended render error/)
|
||||
})
|
||||
})
|
||||
@@ -56,38 +56,38 @@ describe('tags/for', function () {
|
||||
describe('else', function () {
|
||||
it('should goto else for empty array', async function () {
|
||||
const src = '{%for c in emptyArray%}a{%else%}b{%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('b')
|
||||
})
|
||||
|
||||
it('should treat non-empty string as one single element', async function () {
|
||||
const src = '{%for c in "abc"%}x{{c}}{%else%}y{%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('xabc')
|
||||
})
|
||||
|
||||
it('should goto else for empty string', async function () {
|
||||
const src = '{%for c in ""%}a{%else%}b{%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('b')
|
||||
})
|
||||
|
||||
it('should goto else for empty string object', async function () {
|
||||
// it should be false although `new String` is none-conform
|
||||
const src = '{%for c in strObj%}a{%else%}b{%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('b')
|
||||
})
|
||||
|
||||
it('should goto else for empty object', async function () {
|
||||
const src = '{%for c in emptyObj%}a{%else%}b{%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('b')
|
||||
})
|
||||
|
||||
it('should goto else for null-prototyped object', async function () {
|
||||
const src = '{%for c in nullProtoObj%}a{%else%}b{%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('b')
|
||||
})
|
||||
})
|
||||
@@ -102,7 +102,7 @@ describe('tags/for', function () {
|
||||
const dst = 'true.1.0.false.3.3.2a\n' +
|
||||
'false.2.1.false.3.2.1b\n' +
|
||||
'false.3.2.true.3.1.0c\n'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal(dst)
|
||||
})
|
||||
|
||||
@@ -111,7 +111,7 @@ describe('tags/for', function () {
|
||||
const src = '{% for i in (1..5) %}' +
|
||||
'{% if i == 4 %}continue{% continue %}{% endif %}{{i}}' +
|
||||
'{% endfor %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('123continue5')
|
||||
})
|
||||
it('should output contents before continue', async function () {
|
||||
@@ -119,7 +119,7 @@ describe('tags/for', function () {
|
||||
'{% if i == 4 %}continue{% continue %}{% endif %}' +
|
||||
'{{ i }}' +
|
||||
'{% endfor %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('123continue5')
|
||||
})
|
||||
})
|
||||
@@ -129,7 +129,7 @@ describe('tags/for', function () {
|
||||
'{% if i == 4 %}{% break %}{% endif %}' +
|
||||
'{{ i }}' +
|
||||
'{% endfor %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('123')
|
||||
})
|
||||
it('should output contents before break', async function () {
|
||||
@@ -137,7 +137,7 @@ describe('tags/for', function () {
|
||||
'{% if i == 4 %}breaking{% break %}{% endif %}' +
|
||||
'{{ i }}' +
|
||||
'{% endfor %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('123breaking')
|
||||
})
|
||||
})
|
||||
@@ -145,22 +145,22 @@ describe('tags/for', function () {
|
||||
describe('limit', function () {
|
||||
it('should support for with limit', async function () {
|
||||
const src = '{% for i in (1..5) limit:2 %}{{ i }}{% endfor %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('12')
|
||||
})
|
||||
it('should set forloop.last properly', async function () {
|
||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.last}} {%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('false true ')
|
||||
})
|
||||
it('should set forloop.first properly', async function () {
|
||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.first}} {%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('true false ')
|
||||
})
|
||||
it('should set forloop.length properly', function () {
|
||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.length}} {%endfor%}'
|
||||
return expect(liquid.parseAndRender(src, ctx))
|
||||
return expect(liquid.parseAndRender(src, scope))
|
||||
.to.eventually.equal('2 2 ')
|
||||
})
|
||||
})
|
||||
@@ -168,27 +168,27 @@ describe('tags/for', function () {
|
||||
describe('offset', function () {
|
||||
it('should support offset with limit', async function () {
|
||||
const src = '{% for i in (1..10) limit:2 offset:5%}{{ i }}{% endfor %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('67')
|
||||
})
|
||||
it('should set index properly', async function () {
|
||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index}} {%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('1 2 ')
|
||||
})
|
||||
it('should set index0 properly', async function () {
|
||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index0}} {%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('0 1 ')
|
||||
})
|
||||
it('should set rindex properly', async function () {
|
||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex}} {%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('2 1 ')
|
||||
})
|
||||
it('should set rindex0 properly', async function () {
|
||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex0}} {%endfor%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('1 0 ')
|
||||
})
|
||||
})
|
||||
@@ -196,20 +196,47 @@ describe('tags/for', function () {
|
||||
describe('reverse', function () {
|
||||
it('should support for reversed in the last position', async function () {
|
||||
const src = '{% for i in (1..5) limit:2 reversed %}{{ i }}{% endfor %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('21')
|
||||
})
|
||||
|
||||
it('should support for reversed in the first position', async function () {
|
||||
const src = '{% for i in (1..5) reversed limit:2 %}{{ i }}{% endfor %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('21')
|
||||
})
|
||||
|
||||
it('should support for reversed in the middle position', async function () {
|
||||
const src = '{% for i in (1..5) offset:2 reversed limit:4 %}{{ i }}{% endfor %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src)
|
||||
return expect(html).to.equal('543')
|
||||
})
|
||||
})
|
||||
describe('sync', function () {
|
||||
it('should support sync', function () {
|
||||
const src = '{% for i in (1..5) %}{{i}}{%endfor%}'
|
||||
const html = liquid.parseAndRenderSync(src)
|
||||
return expect(html).to.equal('12345')
|
||||
})
|
||||
it('should output contents before break', function () {
|
||||
const src = '{% for i in (1..5) %}' +
|
||||
'{% if i == 4 %}breaking{% break %}{% endif %}' +
|
||||
'{{ i }}' +
|
||||
'{% endfor %}'
|
||||
const html = liquid.parseAndRenderSync(src, scope)
|
||||
return expect(html).to.equal('123breaking')
|
||||
})
|
||||
it('should support for with continue', function () {
|
||||
const src = '{% for i in (1..5) %}' +
|
||||
'{% if i == 4 %}continue{% continue %}{% endif %}{{i}}' +
|
||||
'{% endfor %}'
|
||||
const html = liquid.parseAndRenderSync(src, scope)
|
||||
return expect(html).to.equal('123continue5')
|
||||
})
|
||||
it('should goto else for empty array', async function () {
|
||||
const src = '{%for c in emptyArray%}a{%else%}b{%endfor%}'
|
||||
const html = await liquid.parseAndRenderSync(src, scope)
|
||||
return expect(html).to.equal('b')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@ import { expect } from 'chai'
|
||||
|
||||
describe('tags/if', function () {
|
||||
const liquid = new Liquid()
|
||||
const ctx = {
|
||||
const scope = {
|
||||
one: 1,
|
||||
two: 2,
|
||||
emptyString: '',
|
||||
@@ -12,52 +12,52 @@ describe('tags/if', function () {
|
||||
|
||||
it('should throw if not closed', function () {
|
||||
const src = '{% if false%}yes'
|
||||
return expect(liquid.parseAndRender(src, ctx))
|
||||
return expect(liquid.parseAndRender(src, scope))
|
||||
.to.be.rejectedWith(/tag {% if false%} not closed/)
|
||||
})
|
||||
it('should support nested', async function () {
|
||||
const src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('')
|
||||
})
|
||||
|
||||
describe('single value as condition', function () {
|
||||
it('should support boolean', async function () {
|
||||
const src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('2')
|
||||
})
|
||||
it('should treat Array truthy', async function () {
|
||||
const src = '{%if emptyArray%}a{%endif%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('a')
|
||||
})
|
||||
it('should return true if empty string', async function () {
|
||||
const src = '{%if emptyString%}a{%endif%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('a')
|
||||
})
|
||||
})
|
||||
describe('expression as condition', function () {
|
||||
it('should support ==', async function () {
|
||||
const src = '{% if 2 == 3 %}yes{%else%}no{%endif%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('no')
|
||||
})
|
||||
it('should support >=', async function () {
|
||||
const src = '{% if 1 >= 2 and one<two %}a{%endif%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('')
|
||||
})
|
||||
it('should support !=', async function () {
|
||||
const src = '{% if one != two %}yes{%else%}no{%endif%}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('yes')
|
||||
})
|
||||
it('should support value and expression', async function () {
|
||||
const src = `X{%if version and version != '' %}x{{version}}y{%endif%}Y`
|
||||
const ctx = { 'version': '' }
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const scope = { 'version': '' }
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('XY')
|
||||
})
|
||||
it('should evaluate right to left', async function () {
|
||||
@@ -69,50 +69,55 @@ describe('tags/if', function () {
|
||||
describe('comparasion to null', function () {
|
||||
it('should evaluate false for null < 10', async function () {
|
||||
const src = '{% if null < 10 %}yes{% else %}no{% endif %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('no')
|
||||
})
|
||||
|
||||
it('should evaluate false for null > 10', async function () {
|
||||
const src = '{% if null > 10 %}yes{% else %}no{% endif %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('no')
|
||||
})
|
||||
|
||||
it('should evaluate false for null <= 10', async function () {
|
||||
const src = '{% if null <= 10 %}yes{% else %}no{% endif %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('no')
|
||||
})
|
||||
|
||||
it('should evaluate false for null >= 10', async function () {
|
||||
const src = '{% if null >= 10 %}yes{% else %}no{% endif %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('no')
|
||||
})
|
||||
|
||||
it('should evaluate false for 10 < null', async function () {
|
||||
const src = '{% if 10 < null %}yes{% else %}no{% endif %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('no')
|
||||
})
|
||||
|
||||
it('should evaluate false for 10 > null', async function () {
|
||||
const src = '{% if 10 > null %}yes{% else %}no{% endif %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('no')
|
||||
})
|
||||
|
||||
it('should evaluate false for 10 <= null', async function () {
|
||||
const src = '{% if 10 <= null %}yes{% else %}no{% endif %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('no')
|
||||
})
|
||||
|
||||
it('should evaluate false for 10 >= null', async function () {
|
||||
const src = '{% if 10 >= null %}yes{% else %}no{% endif %}'
|
||||
const html = await liquid.parseAndRender(src, ctx)
|
||||
const html = await liquid.parseAndRender(src, scope)
|
||||
return expect(html).to.equal('no')
|
||||
})
|
||||
})
|
||||
it('should support sync', function () {
|
||||
const src = '{%if true%}true{%else%}false{%endif%}'
|
||||
const html = liquid.parseAndRenderSync(src, scope)
|
||||
return expect(html).to.equal('true')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -171,4 +171,39 @@ describe('tags/include', function () {
|
||||
return expect(html).to.equal('Xchild with redY')
|
||||
})
|
||||
})
|
||||
describe('sync support', function () {
|
||||
it('should support quoted string', function () {
|
||||
mock({
|
||||
'/current.html': 'bar{% include "bar/foo.html" %}bar',
|
||||
'/bar/foo.html': 'foo'
|
||||
})
|
||||
const html = liquid.renderFileSync('/current.html')
|
||||
return expect(html).to.equal('barfoobar')
|
||||
})
|
||||
it('should support template string', function () {
|
||||
mock({
|
||||
'/current.html': 'bar{% include name" %}bar',
|
||||
'/bar/foo.html': 'foo'
|
||||
})
|
||||
const html = liquid.renderFileSync('/current.html', { name: '/bar/foo.html' })
|
||||
return expect(html).to.equal('barfoobar')
|
||||
})
|
||||
it('should support include: with', function () {
|
||||
mock({
|
||||
'/with.html': '{% include "color" with "red", shape: "rect" %}',
|
||||
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
||||
})
|
||||
const html = liquid.renderFileSync('with.html')
|
||||
return expect(html).to.equal('color:red, shape:rect')
|
||||
})
|
||||
it('should support filename with extention', function () {
|
||||
mock({
|
||||
'/parent.html': 'X{% include child.html color:"red" %}Y',
|
||||
'/child.html': 'child with {{color}}'
|
||||
})
|
||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||
const html = staticLiquid.renderFileSync('parent.html')
|
||||
return expect(html).to.equal('Xchild with redY')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -133,4 +133,13 @@ describe('tags/layout', function () {
|
||||
return expect(html).to.equal('blackA')
|
||||
})
|
||||
})
|
||||
it('should support sync', function () {
|
||||
mock({
|
||||
'/grand.html': 'X{%block a%}G{%endblock%}Y',
|
||||
'/parent.html': '{%layout "grand" %}{%block a%}P{%endblock%}',
|
||||
'/main.html': '{%layout "parent"%}{%block a%}A{%endblock%}'
|
||||
})
|
||||
const html = liquid.renderFileSync('/main.html')
|
||||
return expect(html).to.equal('XAY')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,20 +3,24 @@ import { expect } from 'chai'
|
||||
|
||||
describe('tags/raw', function () {
|
||||
const liquid = new Liquid()
|
||||
it('should support raw 1', async function () {
|
||||
it('should throw when not closed', async function () {
|
||||
const p = liquid.parseAndRender('{% raw%}')
|
||||
return expect(p).be.rejectedWith(/{% raw%} not closed/)
|
||||
})
|
||||
it('should support raw 2', async function () {
|
||||
it('should output filters as it is', async function () {
|
||||
const src = '{% raw %}{{ 5 | plus: 6 }}{% endraw %} is equal to 11.'
|
||||
const dst = '{{ 5 | plus: 6 }} is equal to 11.'
|
||||
const html = await liquid.parseAndRender(src)
|
||||
return expect(html).to.equal(dst)
|
||||
})
|
||||
it('should support raw 3', async function () {
|
||||
it('should preserve blank characters', async function () {
|
||||
const src = '{% raw %}\n{{ foo}} \n{% endraw %}'
|
||||
const dst = '\n{{ foo}} \n'
|
||||
const html = await liquid.parseAndRender(src)
|
||||
return expect(html).to.equal(dst)
|
||||
})
|
||||
it('should support sync', function () {
|
||||
const html = liquid.parseAndRenderSync('{% raw %}{{foo}}{% endraw %}')
|
||||
return expect(html).to.equal('{{foo}}')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -107,4 +107,18 @@ describe('tags/tablerow', function () {
|
||||
return expect(html).to.equal(dst)
|
||||
})
|
||||
})
|
||||
describe('sync support', function () {
|
||||
it('should support tablerow', function () {
|
||||
const src = '{% tablerow i in (1..3)%}{{ i }}{% endtablerow %}'
|
||||
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
||||
const html = liquid.parseAndRenderSync(src)
|
||||
expect(html).to.equal(dst)
|
||||
})
|
||||
it('should support empty tablerow', function () {
|
||||
const src = '{% tablerow i in "" cols:2 %}{{ i }}{% endtablerow %}'
|
||||
const dst = ''
|
||||
const html = liquid.parseAndRenderSync(src)
|
||||
return expect(html).to.equal(dst)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -34,4 +34,16 @@ describe('tags/unless', function () {
|
||||
const html = await liquid.parseAndRender(src)
|
||||
return expect(html).to.equal('')
|
||||
})
|
||||
describe('sync support', function () {
|
||||
it('should render else when predicate yields true', function () {
|
||||
const src = '{% unless 0 %}yes{%else%}no{%endunless%}'
|
||||
const html = liquid.parseAndRenderSync(src)
|
||||
expect(html).to.equal('no')
|
||||
})
|
||||
it('should render unless when predicate yields false', function () {
|
||||
const src = '{% unless false %}yes{%else%}no{%endunless%}'
|
||||
const html = liquid.parseAndRenderSync(src)
|
||||
expect(html).to.equal('yes')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -49,6 +49,10 @@ describe('drop/drop', function () {
|
||||
const html = await liquid.parseAndRender(`{{obj.name}}`, { obj: new PromiseDrop() })
|
||||
expect(html).to.equal('NAME')
|
||||
})
|
||||
it('should resolve before calling filters', async function () {
|
||||
const html = await liquid.parseAndRender(`{{obj.name | downcase}}`, { obj: new PromiseDrop() })
|
||||
expect(html).to.equal('name')
|
||||
})
|
||||
it('should support promise returned by liquidMethodMissing', async function () {
|
||||
const html = await liquid.parseAndRender(`{{obj.foo}}`, { obj: new PromiseDrop() })
|
||||
expect(html).to.equal('FOO')
|
||||
|
||||
@@ -3,36 +3,87 @@ import { Liquid } from '../../../src/liquid'
|
||||
import { mock, restore } from '../../stub/mockfs'
|
||||
|
||||
describe('LiquidOptions#cache', function () {
|
||||
let engine: Liquid
|
||||
beforeEach(function () {
|
||||
engine = new Liquid({
|
||||
root: '/root/',
|
||||
extname: '.html'
|
||||
})
|
||||
mock({ '/root/files/foo.html': 'foo' })
|
||||
})
|
||||
afterEach(restore)
|
||||
it('should be disabled by default', function () {
|
||||
return engine.renderFile('files/foo')
|
||||
.then(x => expect(x).to.equal('foo'))
|
||||
.then(() => mock({
|
||||
'/root/files/foo.html': 'bar'
|
||||
}))
|
||||
.then(() => engine.renderFile('files/foo'))
|
||||
.then(x => expect(x).to.equal('bar'))
|
||||
})
|
||||
it('should respect cache=true option', function () {
|
||||
engine = new Liquid({
|
||||
root: '/root/',
|
||||
extname: '.html',
|
||||
cache: true
|
||||
|
||||
describe('#renderFile', function () {
|
||||
it('should be disabled by default', async function () {
|
||||
const engine = new Liquid({
|
||||
root: '/root/',
|
||||
extname: '.html'
|
||||
})
|
||||
mock({ '/root/files/foo.html': 'foo' })
|
||||
const x = await engine.renderFile('files/foo')
|
||||
expect(x).to.equal('foo')
|
||||
mock({ '/root/files/foo.html': 'bar' })
|
||||
const y = await engine.renderFile('files/foo')
|
||||
expect(y).to.equal('bar')
|
||||
})
|
||||
it('should respect cache=true option', async function () {
|
||||
const engine = new Liquid({
|
||||
root: '/root/',
|
||||
extname: '.html',
|
||||
cache: true
|
||||
})
|
||||
mock({ '/root/files/foo.html': 'foo' })
|
||||
const x = await engine.renderFile('files/foo')
|
||||
expect(x).to.equal('foo')
|
||||
mock({ '/root/files/foo.html': 'bar' })
|
||||
const y = await engine.renderFile('files/foo')
|
||||
expect(y).to.equal('foo')
|
||||
})
|
||||
it('should not cache not exist file', async function () {
|
||||
const engine = new Liquid({
|
||||
root: '/root/',
|
||||
extname: '.html',
|
||||
cache: true
|
||||
})
|
||||
try { await engine.renderFile('foo') } catch (err) {}
|
||||
|
||||
mock({ '/root/foo.html': 'foo' })
|
||||
const y = await engine.renderFile('foo')
|
||||
expect(y).to.equal('foo')
|
||||
})
|
||||
})
|
||||
|
||||
describe('#renderFileSync', function () {
|
||||
it('should be disabled by default', function () {
|
||||
const engine = new Liquid({
|
||||
root: '/root/',
|
||||
extname: '.html'
|
||||
})
|
||||
mock({ '/root/foo.html': 'foo' })
|
||||
const x = engine.renderFileSync('foo')
|
||||
expect(x).to.equal('foo')
|
||||
|
||||
mock({ '/root/foo.html': 'bar' })
|
||||
const y = engine.renderFileSync('foo')
|
||||
expect(y).to.equal('bar')
|
||||
})
|
||||
it('should respect cache=true option', function () {
|
||||
const engine = new Liquid({
|
||||
root: '/root/',
|
||||
extname: '.html',
|
||||
cache: true
|
||||
})
|
||||
mock({ '/root/foo.html': 'foo' })
|
||||
const x = engine.renderFileSync('foo')
|
||||
expect(x).to.equal('foo')
|
||||
|
||||
mock({ '/root/foo.html': 'bar' })
|
||||
const y = engine.renderFileSync('foo')
|
||||
expect(y).to.equal('foo')
|
||||
})
|
||||
it('should not cache not exist file', async function () {
|
||||
const engine = new Liquid({
|
||||
root: '/root/',
|
||||
extname: '.html',
|
||||
cache: true
|
||||
})
|
||||
try { engine.renderFileSync('foo') } catch (err) {}
|
||||
|
||||
mock({ '/root/foo.html': 'foo' })
|
||||
const y = await engine.renderFile('foo')
|
||||
expect(y).to.equal('foo')
|
||||
})
|
||||
return engine.renderFile('files/foo')
|
||||
.then(x => expect(x).to.equal('foo'))
|
||||
.then(() => mock({
|
||||
'/root/files/foo.html': 'bar'
|
||||
}))
|
||||
.then(() => engine.renderFile('files/foo'))
|
||||
.then(x => expect(x).to.equal('foo'))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -53,14 +53,14 @@ describe('Liquid', function () {
|
||||
})
|
||||
after(restore)
|
||||
it('should render single template', function (done) {
|
||||
render.call({ root: '.' }, 'foo', null as any, (err: Error | null, result: string | undefined) => {
|
||||
render.call({ root: '/root' }, 'foo', null as any, (err: Error | null, result: string | undefined) => {
|
||||
if (err) return done(err)
|
||||
expect(result).to.equal('foo')
|
||||
done()
|
||||
})
|
||||
})
|
||||
it('should render single template with Array-typed root', function (done) {
|
||||
render.call({ root: ['.'] }, 'foo', null as any, (err: Error | null, result: string | undefined) => {
|
||||
render.call({ root: ['/root'] }, 'foo', null as any, (err: Error | null, result: string | undefined) => {
|
||||
if (err) return done(err)
|
||||
expect(result).to.equal('foo')
|
||||
done()
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
import { test, liquid } from '../../stub/render'
|
||||
import { expect } from 'chai'
|
||||
import { Liquid } from '../../../src/liquid'
|
||||
|
||||
describe('liquid#registerFilter()', function () {
|
||||
const liquid = new Liquid()
|
||||
|
||||
describe('object arguments', function () {
|
||||
liquid.registerFilter('obj_test', function () {
|
||||
return JSON.stringify(arguments)
|
||||
liquid.registerFilter('obj_test', function (...args) {
|
||||
return JSON.stringify(args)
|
||||
})
|
||||
it('should support object', async () => {
|
||||
const src = `{{ "a" | obj_test: k1: "v1", k2: foo }}`,
|
||||
const dst = '["a",["k1","v1"],["k2","bar"]]'
|
||||
const html = await liquid.parseAndRender(src, { foo: 'bar' })
|
||||
return expect(html).to.equal(dst)
|
||||
})
|
||||
it('should support mixed object', async () => {
|
||||
const src = `{{ "a" | obj_test: "something", k1: "v1", k2: foo }}`,
|
||||
const dst = '["a","something",["k1","v1"],["k2","bar"]]'
|
||||
const html = await liquid.parseAndRender(src, { foo: 'bar' })
|
||||
return expect(html).to.equal(dst)
|
||||
})
|
||||
it('should support object', () => test(
|
||||
`{{ "a" | obj_test: k1: "v1", k2: foo }}`,
|
||||
'{"0":"a","1":["k1","v1"],"2":["k2","bar"]}'
|
||||
))
|
||||
it('should support mixed object', () => test(
|
||||
`{{ "a" | obj_test: "something", k1: "v1", k2: foo }}`,
|
||||
'{"0":"a","1":"something","2":["k1","v1"],"3":["k2","bar"]}'
|
||||
))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { expect } from 'chai'
|
||||
import { RenderError } from '../../../src/util/error'
|
||||
import { Liquid } from '../../../src/liquid'
|
||||
import * as path from 'path'
|
||||
import { mock, restore } from '../../stub/mockfs'
|
||||
@@ -264,4 +265,46 @@ describe('error', function () {
|
||||
expect(err.stack).to.match(/at .*:\d+:\d+\)/)
|
||||
})
|
||||
})
|
||||
describe('sync support', function () {
|
||||
let engine
|
||||
beforeEach(function () {
|
||||
engine = new Liquid({
|
||||
root: '/'
|
||||
})
|
||||
engine.registerTag('throwingTag', {
|
||||
render: function () {
|
||||
throw new Error('intended render error')
|
||||
}
|
||||
})
|
||||
})
|
||||
it('should throw RenderError when tag throws', function () {
|
||||
const src = '{%throwingTag%}'
|
||||
expect(() => engine.parseAndRenderSync(src))
|
||||
.to.throw(RenderError, /intended render error/)
|
||||
})
|
||||
it('should contain original error info for {% include %}', function () {
|
||||
const origin = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th']
|
||||
mock({
|
||||
'/throwing-tag.html': origin.join('\n')
|
||||
})
|
||||
const html = '{%include "throwing-tag.html"%}'
|
||||
const message = [
|
||||
' 2| 2nd',
|
||||
' 3| 3rd',
|
||||
'>> 4| X{%throwingTag%} Y',
|
||||
' 5| 5th',
|
||||
' 6| 6th',
|
||||
' 7| 7th',
|
||||
'RenderError'
|
||||
]
|
||||
try {
|
||||
engine.parseAndRenderSync(html)
|
||||
throw new Error('expected throw')
|
||||
} catch (err) {
|
||||
expect(err.message).to.equal(`intended render error, file:${path.resolve('/throwing-tag.html')}, line:4, col:2`)
|
||||
expect(err.stack).to.contain(message.join('\n'))
|
||||
expect(err.name).to.equal('RenderError')
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user