From daa0b574fcb72757fd25efe5399ff438a2cae790 Mon Sep 17 00:00:00 2001 From: Jun Yang Date: Tue, 2 Apr 2019 00:27:42 +0800 Subject: [PATCH] feat: where filter, working on #118 doc: https://shopify.github.io/liquid/filters/where/ ruby impl: https://github.com/Shopify/liquid/blob/14cd011cb5eef042af192ad5294c8f0e1ae89f06/lib/liquid/standardfilters.rb --- src/builtin/filters/array.ts | 4 ++++ test/integration/builtin/filters/array.ts | 24 +++++++++++++++++++++++ test/stub/render.ts | 11 ++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/builtin/filters/array.ts b/src/builtin/filters/array.ts index ab0a04be6..05749cb5e 100644 --- a/src/builtin/filters/array.ts +++ b/src/builtin/filters/array.ts @@ -1,4 +1,5 @@ import { last } from '../../util/underscore' +import { isTruthy } from '../../render/syntax' export default { 'join': (v: any[], arg: string) => v.join(arg === undefined ? ' ' : arg), @@ -20,5 +21,8 @@ export default { u[String(val)] = true return true }) + }, + 'where': function (arr: T[], property: string, value?: any): T[] { + return arr.filter(obj => value === undefined ? isTruthy(obj[property]) : obj[property] === value) } } diff --git a/test/integration/builtin/filters/array.ts b/test/integration/builtin/filters/array.ts index cb8e7bc81..cc10f8c14 100644 --- a/test/integration/builtin/filters/array.ts +++ b/test/integration/builtin/filters/array.ts @@ -64,4 +64,28 @@ describe('filters/array', function () { return test('{{"" | uniq | join: ","}}', '') }) }) + describe('where', function () { + it('should support filter by property value', function () { + return test(`{% assign kitchen_products = products | where: "type", "kitchen" %} +Kitchen products: +{% for product in kitchen_products -%} +- {{ product.title }} +{% endfor %}`, ` +Kitchen products: +- Spatula +- Garlic press +`) + }) + it('should support filter truthy property', function () { + return test(`{% assign available_products = products | where: "available" %} +Available products: +{% for product in available_products -%} +- {{ product.title }} +{% endfor %}`, ` +Available products: +- Coffee mug +- Boring sneakers +`) + }) + }) }) diff --git a/test/stub/render.ts b/test/stub/render.ts index 1b72f110b..8872f6bd2 100644 --- a/test/stub/render.ts +++ b/test/stub/render.ts @@ -9,7 +9,16 @@ export const ctx = { arr: [-2, 'a'], obj: { foo: 'bar' }, func: function () {}, - posts: [{ category: 'foo' }, { category: 'bar' }] + posts: [{ category: 'foo' }, { category: 'bar' }], + products: [ + {title: 'Vacuum', type: 'living room'}, + {title: 'Spatula', type: 'kitchen'}, + {title: 'Television', type: 'living room'}, + {title: 'Garlic press', type: 'kitchen'}, + {title: 'Coffee mug', available: true}, + {title: 'Limited edition sneakers', available: false}, + {title: 'Boring sneakers', available: true} + ] } export async function test (src: string, dst: string) {