feature: variable lookup respects to to_liquid, #81

This commit is contained in:
harttle
2018-08-14 00:11:50 +08:00
committed by Jun Yang
parent ea38a9e1f5
commit 5b43520d78
4 changed files with 35 additions and 22 deletions
+9 -4
View File
@@ -58,12 +58,17 @@ var Scope = {
}, },
readProperty: function (obj, key) { readProperty: function (obj, key) {
let val let val
if (key === 'size' && (_.isArray(obj) || _.isString(obj))) { if (_.isNil(obj)) {
val = obj.length
} else if (_.isNil(obj)) {
val = undefined val = undefined
} else { } else {
val = obj[key] if (typeof obj.to_liquid === 'function') {
obj = obj.to_liquid()
}
if (key === 'size' && (_.isArray(obj) || _.isString(obj))) {
val = obj.length
} else {
val = obj[key]
}
} }
if (_.isNil(val) && this.opts.strict_variables) { if (_.isNil(val) && this.opts.strict_variables) {
throw new TypeError(`undefined variable: ${key}`) throw new TypeError(`undefined variable: ${key}`)
+4 -3
View File
@@ -1,3 +1,4 @@
'use strict'
const toStr = Object.prototype.toString const toStr = Object.prototype.toString
/* /*
@@ -10,12 +11,12 @@ function isString (value) {
} }
function stringify (value) { function stringify (value) {
if (value && typeof value.to_liquid === 'function') {
return stringify(value.to_liquid())
}
if (isString(value)) { if (isString(value)) {
return value return value
} }
if (value && typeof value.to_liquid === 'function') {
return value.to_liquid()
}
let cache = [] let cache = []
return JSON.stringify(value, (key, value) => { return JSON.stringify(value, (key, value) => {
+14 -15
View File
@@ -1,3 +1,4 @@
'use strict'
const chai = require('chai') const chai = require('chai')
const chaiAsPromised = require('chai-as-promised') const chaiAsPromised = require('chai-as-promised')
const expect = chai.expect const expect = chai.expect
@@ -42,7 +43,6 @@ describe('render', function () {
let tpl = Template.parseValue('bar') let tpl = Template.parseValue('bar')
return expect(render.renderValue(tpl, scope)).to.eventually.equal('custom') return expect(render.renderValue(tpl, scope)).to.eventually.equal('custom')
}) })
it('should stringify objects', function () { it('should stringify objects', function () {
let scope = Scope.factory({ let scope = Scope.factory({
foo: { obj: { arr: ['a', 2] } } foo: { obj: { arr: ['a', 2] } }
@@ -65,20 +65,6 @@ describe('render', function () {
}) })
}) })
it('should eval filter with correct arguments', function () {
let date = sinon.stub().returns('y')
let time = sinon.spy()
filter.register('date', date)
filter.register('time', time)
let tpl = Template.parseValue('foo.bar | date: "b" | time:2')
let scope = Scope.factory({
foo: {bar: 'bar'}
})
render.evalValue(tpl, scope)
expect(date).to.have.been.calledWith('bar', 'b')
expect(time).to.have.been.calledWith('y', 2)
})
describe('.evalValue()', function () { describe('.evalValue()', function () {
it('should throw when scope undefined', function () { it('should throw when scope undefined', function () {
expect(function () { expect(function () {
@@ -99,5 +85,18 @@ describe('render', function () {
let tpl = Template.parseValue('"x" | arr') let tpl = Template.parseValue('"x" | arr')
expect(render.evalValue(tpl, Scope.factory())).to.deep.equal([1]) expect(render.evalValue(tpl, Scope.factory())).to.deep.equal([1])
}) })
it('should eval filter with correct arguments', function () {
let date = sinon.stub().returns('y')
let time = sinon.spy()
filter.register('date', date)
filter.register('time', time)
let tpl = Template.parseValue('foo.bar | date: "b" | time:2')
let scope = Scope.factory({
foo: {bar: 'bar'}
})
render.evalValue(tpl, scope)
expect(date).to.have.been.calledWith('bar', 'b')
expect(time).to.have.been.calledWith('y', 2)
})
}) })
}) })
+8
View File
@@ -88,6 +88,14 @@ describe('scope', function () {
}).to.throw(/unbalanced '/) }).to.throw(/unbalanced '/)
}) })
it('should respect to to_liquid', function () {
let scope = Scope.factory({foo: {
to_liquid: () => ({bar: 'BAR'}),
bar: 'bar'
}})
expect(scope.get('foo.bar')).to.equal('BAR')
})
it('should access child property via dot syntax', function () { it('should access child property via dot syntax', function () {
expect(scope.get('bar.zoo')).to.equal('coo') expect(scope.get('bar.zoo')).to.equal('coo')
expect(scope.get('bar.arr')).to.deep.equal(['a', 'b']) expect(scope.get('bar.arr')).to.deep.equal(['a', 'b'])