use isTruthy for and/or operators, fixes #47

This commit is contained in:
harttle
2017-11-26 23:59:50 +08:00
parent d348edac14
commit 8efb41a631
5 changed files with 114 additions and 96 deletions
+5 -5
View File
@@ -1,4 +1,5 @@
var operators = { module.exports = function (isTruthy) {
return {
'==': (l, r) => l === r, '==': (l, r) => l === r,
'!=': (l, r) => l !== r, '!=': (l, r) => l !== r,
'>': (l, r) => l !== null && r !== null && l > r, '>': (l, r) => l !== null && r !== null && l > r,
@@ -10,8 +11,7 @@ var operators = {
if (typeof l.indexOf !== 'function') return false if (typeof l.indexOf !== 'function') return false
return l.indexOf(r) > -1 return l.indexOf(r) > -1
}, },
'and': (l, r) => l && r, 'and': (l, r) => isTruthy(l) && isTruthy(r),
'or': (l, r) => l || r 'or': (l, r) => isTruthy(l) || isTruthy(r)
}
} }
module.exports = operators
+1 -1
View File
@@ -1,4 +1,4 @@
const operators = require('./operators.js') const operators = require('./operators.js')(isTruthy)
const lexical = require('./lexical.js') const lexical = require('./lexical.js')
const assert = require('../src/util/assert.js') const assert = require('../src/util/assert.js')
+3 -7
View File
@@ -70,13 +70,9 @@ describe('liquid', function () {
it('should render template multiple times', function () { it('should render template multiple times', function () {
var template = engine.parse('{{obj}}') var template = engine.parse('{{obj}}')
return engine.render(template, ctx) return engine.render(template, ctx)
.then((result) => { .then(result => expect(result).to.equal('{"foo":"bar"}'))
expect(result).to.equal('{"foo":"bar"}') .then(() => engine.render(template, ctx))
return engine.render(template, ctx) .then((result) => expect(result).to.equal('{"foo":"bar"}'))
})
.then((result) => {
return expect(result).to.equal('{"foo":"bar"}')
})
}) })
it('should render filters', function () { it('should render filters', function () {
var template = engine.parse('<p>{{arr | join: "_"}}</p>') var template = engine.parse('<p>{{arr | join: "_"}}</p>')
+13 -3
View File
@@ -14,6 +14,7 @@ describe('expression', function () {
scope = Scope.factory({ scope = Scope.factory({
one: 1, one: 1,
two: 2, two: 2,
empty: '',
x: 'XXX', x: 'XXX',
y: undefined, y: undefined,
z: null z: null
@@ -73,11 +74,20 @@ describe('expression', function () {
expect(evalExp('"<=" == "<="', scope)).to.equal(true) expect(evalExp('"<=" == "<="', scope)).to.equal(true)
}) })
it('should eval complex expression', function () { describe('complex expression', function () {
expect(evalExp('1<2 and x contains "x"', scope)).to.equal(false) it('should support value or value', function () {
expect(evalExp('1<2 or x contains "x"', scope)).to.equal(true)
expect(evalExp('false or true', scope)).to.equal(true) expect(evalExp('false or true', scope)).to.equal(true)
}) })
it('should support < and contains', function () {
expect(evalExp('1<2 and x contains "x"', scope)).to.equal(false)
})
it('should support < or contains', function () {
expect(evalExp('1<2 or x contains "x"', scope)).to.equal(true)
})
it('should support value and !=', function () {
expect(evalExp('empty and empty != ""', scope)).to.equal(false)
})
})
it('should eval range expression', function () { it('should eval range expression', function () {
expect(evalExp('(2..4)', scope)).to.deep.equal([2, 3, 4]) expect(evalExp('(2..4)', scope)).to.deep.equal([2, 3, 4])
+47 -35
View File
@@ -17,11 +17,30 @@ describe('tags/if', function () {
return expect(liquid.parseAndRender(src, ctx)) return expect(liquid.parseAndRender(src, ctx))
.to.be.rejectedWith(/tag {% if false%} not closed/) .to.be.rejectedWith(/tag {% if false%} not closed/)
}) })
it('should support nested', function () {
var src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}'
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('')
})
describe('single value as condition', function () {
it('should support boolean', function () {
var src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}'
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('2')
})
it('should treat Array truthy', function () { it('should treat Array truthy', function () {
var src = '{%if emptyArray%}a{%endif%}' var src = '{%if emptyArray%}a{%endif%}'
return expect(liquid.parseAndRender(src, ctx)) return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('a') .to.eventually.equal('a')
}) })
it('should return true if empty string', function () {
var src = '{%if emptyString%}a{%endif%}'
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('a')
})
})
describe('expression as condition', function () {
it('should support ==', function () { it('should support ==', function () {
var src = '{% if 2==3 %}yes{%else%}no{%endif%}' var src = '{% if 2==3 %}yes{%else%}no{%endif%}'
return expect(liquid.parseAndRender(src, ctx)) return expect(liquid.parseAndRender(src, ctx))
@@ -37,67 +56,60 @@ describe('tags/if', function () {
return expect(liquid.parseAndRender(src, ctx)) return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('yes') .to.eventually.equal('yes')
}) })
it('should support boolean', function () { it('should support value and expression', function () {
var src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}' var src = `X{%if version and version != '' %}x{{version}}y{%endif%}Y`
var ctx = { 'version': '' }
return expect(liquid.parseAndRender(src, ctx)) return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('2') .to.eventually.equal('XY')
}) })
it('should support nested', function () {
var src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}'
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('')
}) })
it('should return true if empty string', function () { describe('comparasion to null', function () {
var src = '{%if emptyString%}a{%endif%}' it('should evaluate false for null < 10', function () {
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('a')
})
it('should return else when comparison on null 1', function () {
var src = '{% if null < 10 %}yes{% else %}no{% endif %}' var src = '{% if null < 10 %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx)) return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no') .to.eventually.equal('no')
}) })
it('should return else when comparison on null 2', function () { it('should evaluate false for null > 10', function () {
var src = '{% if null <= 10 %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no')
})
it('should return else when comparison on null 3', function () {
var src = '{% if null >= 10 %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no')
})
it('should return else when comparison on null 4', function () {
var src = '{% if null > 10 %}yes{% else %}no{% endif %}' var src = '{% if null > 10 %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx)) return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no') .to.eventually.equal('no')
}) })
it('should return else when comparison on null 5', function () { it('should evaluate false for null <= 10', function () {
var src = '{% if null <= 10 %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no')
})
it('should evaluate false for null >= 10', function () {
var src = '{% if null >= 10 %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no')
})
it('should evaluate false for 10 < null', function () {
var src = '{% if 10 < null %}yes{% else %}no{% endif %}' var src = '{% if 10 < null %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx)) return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no') .to.eventually.equal('no')
}) })
it('should return else when comparison on null 6', function () { it('should evaluate false for 10 > null', function () {
var src = '{% if 10 > null %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no')
})
it('should evaluate false for 10 <= null', function () {
var src = '{% if 10 <= null %}yes{% else %}no{% endif %}' var src = '{% if 10 <= null %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx)) return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no') .to.eventually.equal('no')
}) })
it('should return else when comparison on null 7', function () { it('should evaluate false for 10 >= null', function () {
var src = '{% if 10 >= null %}yes{% else %}no{% endif %}' var src = '{% if 10 >= null %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx)) return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no') .to.eventually.equal('no')
}) })
it('should return else when comparison on null 8', function () {
var src = '{% if 10 > null %}yes{% else %}no{% endif %}'
return expect(liquid.parseAndRender(src, ctx))
.to.eventually.equal('no')
}) })
}) })