mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-14 20:00:39 -07:00
fix: map filter allow nil results in strict mode, fixes #647
This commit is contained in:
@@ -76,11 +76,11 @@ export class Context {
|
||||
public getFromScope (scope: unknown, paths: PropertyKey[] | string): IterableIterator<unknown> {
|
||||
return toValueSync(this._getFromScope(scope, paths))
|
||||
}
|
||||
public * _getFromScope (scope: unknown, paths: PropertyKey[] | string): IterableIterator<unknown> {
|
||||
public * _getFromScope (scope: unknown, paths: PropertyKey[] | string, strictVariables = this.strictVariables): IterableIterator<unknown> {
|
||||
if (isString(paths)) paths = paths.split('.')
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
scope = yield readProperty(scope as object, paths[i], this.ownPropertyOnly)
|
||||
if (this.strictVariables && isUndefined(scope)) {
|
||||
if (strictVariables && isUndefined(scope)) {
|
||||
throw new InternalUndefinedVariableError((paths as string[]).slice(0, i + 1).join!('.'))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ export const size = (v: string | any[]) => (v && v.length) || 0
|
||||
export function * map (this: FilterImpl, arr: Scope[], property: string): IterableIterator<unknown> {
|
||||
const results = []
|
||||
for (const item of toArray(toValue(arr))) {
|
||||
results.push(yield this.context._getFromScope(item, stringify(property).split('.')))
|
||||
results.push(yield this.context._getFromScope(item, stringify(property), false))
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
@@ -31,7 +31,10 @@ describe('filter', function () {
|
||||
it('should render a simple filter', async function () {
|
||||
expect(await toPromise(new Filter('upcase', (x: string) => x.toUpperCase(), [], liquid).render('foo', ctx))).toBe('FOO')
|
||||
})
|
||||
|
||||
it('should reject promise when filter throws', async function () {
|
||||
const filter = new Filter('foo', function * () { throw new Error('intended') }, [], liquid)
|
||||
expect(toPromise(filter.render('foo', ctx))).rejects.toMatch('intended')
|
||||
})
|
||||
it('should render filters with argument', async function () {
|
||||
const two = new NumberToken('2', 0, 1, undefined)
|
||||
expect(await toPromise(new Filter('add', (a: number, b: number) => a + b, [two], liquid).render(3, ctx))).toBe(5)
|
||||
|
||||
@@ -27,6 +27,6 @@ export class Filter {
|
||||
if (isKeyValuePair(arg)) argv.push([arg[0], yield evalToken(arg[1], context)])
|
||||
else argv.push(yield evalToken(arg, context))
|
||||
}
|
||||
return this.handler.apply({ context, liquid: this.liquid }, [value, ...argv])
|
||||
return yield this.handler.apply({ context, liquid: this.liquid }, [value, ...argv])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,14 @@ describe('filters/array', function () {
|
||||
const post = { category: 'foo' }
|
||||
return test('{{post | map: "category"}}', { post }, 'foo')
|
||||
})
|
||||
it('should allow nil results in strictVariables mode', function () {
|
||||
const engine = new Liquid({ strictVariables: true })
|
||||
const ctx = {
|
||||
posts: [{ category: 'foo' }, { title: 'bar' }]
|
||||
}
|
||||
const result = engine.parseAndRenderSync('{{posts | map: "category" | json}}', ctx)
|
||||
expect(result).toEqual('["foo",null]')
|
||||
})
|
||||
it('should support nested property', function () {
|
||||
const tpl = '{{ arr | map: "name.first" | join }}'
|
||||
const a = { name: { first: 'Alice' } }
|
||||
|
||||
Reference in New Issue
Block a user