Skip to content

Commit

Permalink
fix: enumerate Promises (e.g. in for & tablerow) (#237)
Browse files Browse the repository at this point in the history
* fix: enumerate Promise<array> (e.g. in {% for ... %})

Previously, a Promise of an array was not being enumerated in
{% for %}, for example. This is misleading since the library
handles promises elsewhere (e.g. if you {% assign x = promiseArray %}
and then {% for v in x %}, it worked just fine.

This PR makes Promises of arrays handled by changing toEnumerable
to handle then-ables. This affects other iterators, too, e.g. tablerow,
so I put in a test for that as well.
  • Loading branch information
tejasmanohar authored Jun 28, 2020
1 parent 11ffd65 commit 941dd66
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/builtin/tags/for.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default {
},
render: function * (ctx: Context, emitter: Emitter) {
const r = this.liquid.renderer
let collection = toEnumerable(evalToken(this.collection, ctx))
let collection = toEnumerable(yield evalToken(this.collection, ctx))

if (!collection.length) {
yield r.renderTemplates(this.elseTemplates, ctx, emitter)
Expand Down
2 changes: 1 addition & 1 deletion src/builtin/tags/tablerow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default {
},

render: function * (ctx: Context, emitter: Emitter) {
let collection = toEnumerable(evalToken(this.collection, ctx))
let collection = toEnumerable(yield evalToken(this.collection, ctx))
const hash = yield this.hash.render(ctx)
const offset = hash.offset || 0
const limit = (hash.limit === undefined) ? collection.length : hash.limit
Expand Down
8 changes: 8 additions & 0 deletions test/integration/builtin/tags/for.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,23 @@ describe('tags/for', function () {
nullProtoObj: Object.create(null),
obj: { foo: 'bar', coo: 'haa' },
alpha: ['a', 'b', 'c'],
promiseArray: Promise.resolve(['a', 'b', 'c']),
emptyArray: []
}
})

it('should support array', async function () {
const src = '{%for c in alpha%}{{c}}{%endfor%}'
const html = await liquid.parseAndRender(src, scope)
return expect(html).to.equal('abc')
})

it('should support promise of array', async function () {
const src = '{%for c in promiseArray%}{{c}}{%endfor%}'
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, scope)
Expand Down
10 changes: 10 additions & 0 deletions test/integration/builtin/tags/tablerow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ describe('tags/tablerow', function () {
return expect(html).to.equal(dst)
})

it('should support promises', async function () {
const src = '{% tablerow i in promiseNumbers %}{{ i }}{% endtablerow %}'
const ctx = {
promiseNumbers: Promise.resolve([1,2,3])
}
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
const html = await liquid.parseAndRender(src, ctx)
return expect(html).to.equal(dst)
})

it('should support cols', async function () {
const src = '{% tablerow i in alpha cols:2 %}{{ i }}{% endtablerow %}'
const ctx = {
Expand Down

0 comments on commit 941dd66

Please sign in to comment.