mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-16 21:00:40 -07:00
feat: add find_index, has, and reject filters (#799)
* feat: add find_index, has, and reject filters * Minor tweaks * Change semantics of jekyllStyle, add more tests * Some docs improvements
This commit is contained in:
@@ -417,6 +417,32 @@ describe('filters/array', function () {
|
||||
- Boring sneakers
|
||||
`)
|
||||
})
|
||||
it('should support filter with undefined target', function () {
|
||||
return test(`{% assign typed_products = products | where: "type", notdefined %}
|
||||
Typed products:
|
||||
{% for product in typed_products -%}
|
||||
- {{ product.title }}
|
||||
{% endfor %}`, { products }, `
|
||||
Typed products:
|
||||
- Vacuum
|
||||
- Spatula
|
||||
- Television
|
||||
- Garlic press
|
||||
`)
|
||||
})
|
||||
it('should support no target', function () {
|
||||
return test(`{% assign typed_products = products | where: "type" %}
|
||||
Typed products:
|
||||
{% for product in typed_products -%}
|
||||
- {{ product.title }}
|
||||
{% endfor %}`, { products }, `
|
||||
Typed products:
|
||||
- Vacuum
|
||||
- Spatula
|
||||
- Television
|
||||
- Garlic press
|
||||
`)
|
||||
})
|
||||
it('should support nested property', async function () {
|
||||
const authors = [
|
||||
{ name: 'Alice', books: { year: 2019 } },
|
||||
@@ -491,7 +517,7 @@ describe('filters/array', function () {
|
||||
await test('{{objs | where: "foo", "FOO" | json}}', scope, '[]')
|
||||
})
|
||||
describe('jekyll style', () => {
|
||||
it('should not match string with array', async () => {
|
||||
it('should filter arrays by inclusion', async () => {
|
||||
const scope = { objs: [{ foo: ['FOO', 'bar'] }] }
|
||||
await test('{{objs | where: "foo", "FOO" | json}}', scope, '[{"foo":["FOO","bar"]}]', { jekyllWhere: true })
|
||||
})
|
||||
@@ -499,6 +525,14 @@ describe('filters/array', function () {
|
||||
const scope = { pages: [{ tags: ['FOO'] }, { tags: [] }, { title: 'foo' }] }
|
||||
await test('{{pages | where: "tags", empty | json}}', scope, '[{"tags":[]}]', { jekyllWhere: true })
|
||||
})
|
||||
it('should filter by undefined when target is omitted', async () => {
|
||||
await test('{{products | where: "type" | map: "title" | join: ","}}', { products },
|
||||
'Coffee mug,Limited edition sneakers,Boring sneakers', { jekyllWhere: true })
|
||||
})
|
||||
it('should filter plainly when target is undefined', async () => {
|
||||
await test('{{products | where: "type", notdefined | map: "title" | join: ","}}', { products },
|
||||
'Coffee mug,Limited edition sneakers,Boring sneakers', { jekyllWhere: true })
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('where_exp', function () {
|
||||
@@ -537,6 +571,89 @@ describe('filters/array', function () {
|
||||
return test(tpl, scope, html)
|
||||
})
|
||||
})
|
||||
describe('reject', function () {
|
||||
const 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 }
|
||||
]
|
||||
it('should support reject by property value', function () {
|
||||
return test(`{% assign kitchen_products = products | reject: "type", "kitchen" %}
|
||||
Kitchen products:
|
||||
{% for product in kitchen_products -%}
|
||||
- {{ product.title }}
|
||||
{% endfor %}`, { products }, `
|
||||
Kitchen products:
|
||||
- Vacuum
|
||||
- Television
|
||||
- Coffee mug
|
||||
- Limited edition sneakers
|
||||
- Boring sneakers
|
||||
`)
|
||||
})
|
||||
it('should support reject truthy property', function () {
|
||||
return test(`{% assign unavailable_products = products | reject: "available" %}
|
||||
Unavailable products:
|
||||
{% for product in unavailable_products -%}
|
||||
- {{ product.title }}
|
||||
{% endfor %}`, { products }, `
|
||||
Unavailable products:
|
||||
- Vacuum
|
||||
- Spatula
|
||||
- Television
|
||||
- Garlic press
|
||||
- Limited edition sneakers
|
||||
`)
|
||||
})
|
||||
it('should support reject by string property', function () {
|
||||
return test(`{% assign untyped_products = products | reject: "type" %}
|
||||
Untyped products:
|
||||
{% for product in untyped_products -%}
|
||||
- {{ product.title }}
|
||||
{% endfor %}`, { products }, `
|
||||
Untyped products:
|
||||
- Coffee mug
|
||||
- Limited edition sneakers
|
||||
- Boring sneakers
|
||||
`)
|
||||
})
|
||||
describe('jekyll style', () => {
|
||||
it('should filter arrays by exclusion', async () => {
|
||||
const scope = { objs: [{ foo: ['FOO', 'bar'] }, { foo: ['bar', 'baz'] }, { foo: ['FOO'] }] }
|
||||
await test('{{objs | reject: "foo", "FOO" | json}}', scope, '[{"foo":["bar","baz"]}]', { jekyllWhere: true })
|
||||
})
|
||||
it('should filter by undefined when target is omitted', async () => {
|
||||
await test('{{products | reject: "type" | map: "title" | join: ","}}', { products },
|
||||
'Vacuum,Spatula,Television,Garlic press', { jekyllWhere: true })
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('reject_exp', function () {
|
||||
const 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 }
|
||||
]
|
||||
it('should support reject by exp', function () {
|
||||
return test(`{% assign kitchen_products = products | reject_exp: "item", "item.type != 'kitchen'" %}
|
||||
Kitchen products:
|
||||
{% for product in kitchen_products -%}
|
||||
- {{ product.title }}
|
||||
{% endfor %}`, { products }, `
|
||||
Kitchen products:
|
||||
- Spatula
|
||||
- Garlic press
|
||||
`)
|
||||
})
|
||||
})
|
||||
describe('group_by', function () {
|
||||
const members = [
|
||||
{ graduation_year: 2003, name: 'Jay' },
|
||||
@@ -616,12 +733,76 @@ describe('filters/array', function () {
|
||||
JSON.stringify(expected))
|
||||
})
|
||||
})
|
||||
describe('find', function () {
|
||||
describe('has', function () {
|
||||
const members = [
|
||||
{ graduation_year: 2013, name: 'Jay' },
|
||||
{ graduation_year: 2014, name: 'John' },
|
||||
{ graduation_year: 2014, name: 'Jack', age: 13 }
|
||||
]
|
||||
it('should support has with no value', function () {
|
||||
return test(
|
||||
`{{ members | has: "age" | json }}, {{ members | has: "height" | json }}`,
|
||||
{ members },
|
||||
`true, false`)
|
||||
})
|
||||
it('should support has by property', function () {
|
||||
return test(
|
||||
`{{ members | has: "graduation_year", 2014 | json }}`,
|
||||
{ members },
|
||||
`true`)
|
||||
})
|
||||
it('should return false if not found', function () {
|
||||
return test(
|
||||
`{{ members | has: "graduation_year", 2018 | json }}`,
|
||||
{ members },
|
||||
`false`)
|
||||
})
|
||||
describe('jekyll style', () => {
|
||||
it('should select array by inclusion', async () => {
|
||||
const scope = { objs: [{ foo: ['FOO', 'bar'] }] }
|
||||
await test('{{objs | has: "foo", "FOO" | json}}', scope, 'true', { jekyllWhere: true })
|
||||
})
|
||||
it('should support empty as target', async () => {
|
||||
const scope = { pages: [{ tags: ['FOO'] }, { tags: [] }, { title: 'foo' }] }
|
||||
await test('{{pages | has: "tags", empty | json}}', scope, 'true', { jekyllWhere: true })
|
||||
})
|
||||
it('should search plainly when target is undefined', async () => {
|
||||
await test('{{members | has: "age", notdefined}}', { members }, 'true', { jekyllWhere: true })
|
||||
await test('{{members | has: "name", notdefined}}', { members }, 'false', { jekyllWhere: true })
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('has_exp', function () {
|
||||
const members = [
|
||||
{ graduation_year: 2013, name: 'Jay' },
|
||||
{ graduation_year: 2014, name: 'John' },
|
||||
{ graduation_year: 2014, name: 'Jack' }
|
||||
]
|
||||
it('should support has by expression', function () {
|
||||
return test(
|
||||
`{{ members | has_exp: "item", "item.graduation_year == 2014" | json }}`,
|
||||
{ members },
|
||||
`true`)
|
||||
})
|
||||
it('should return false if not found', function () {
|
||||
return test(
|
||||
`{{ members | has_exp: "item", "item.graduation_year == 2018" | json }}`,
|
||||
{ members },
|
||||
`false`)
|
||||
})
|
||||
})
|
||||
describe('find', function () {
|
||||
const members = [
|
||||
{ graduation_year: 2013, name: 'Jay' },
|
||||
{ graduation_year: 2014, name: 'John' },
|
||||
{ graduation_year: 2014, name: 'Jack', age: 13 }
|
||||
]
|
||||
it('should support find with no value', function () {
|
||||
return test(
|
||||
`{{ members | find: "age" | json }}`,
|
||||
{ members },
|
||||
`{"graduation_year":2014,"name":"Jack","age":13}`)
|
||||
})
|
||||
it('should support find by property', function () {
|
||||
return test(
|
||||
`{{ members | find: "graduation_year", 2014 | json }}`,
|
||||
@@ -634,6 +815,24 @@ describe('filters/array', function () {
|
||||
{ members },
|
||||
``)
|
||||
})
|
||||
describe('jekyll style', () => {
|
||||
it('should select array by inclusion', async () => {
|
||||
const scope = { objs: [{ foo: ['FOO', 'bar'] }] }
|
||||
await test('{{objs | find: "foo", "FOO" | json}}', scope, '{"foo":["FOO","bar"]}', { jekyllWhere: true })
|
||||
})
|
||||
it('should support empty as target', async () => {
|
||||
const scope = { pages: [{ tags: ['FOO'] }, { tags: [] }, { title: 'foo' }] }
|
||||
await test('{{pages | find: "tags", empty | json}}', scope, '{"tags":[]}', { jekyllWhere: true })
|
||||
})
|
||||
it('should search plainly when target is undefined', async () => {
|
||||
await test(
|
||||
'{{members | find: "age", notdefined | json}}',
|
||||
{ members },
|
||||
'{"graduation_year":2013,"name":"Jay"}',
|
||||
{ jekyllWhere: true })
|
||||
await test('{{members | find: "name", notdefined | json}}', { members }, '', { jekyllWhere: true })
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('find_exp', function () {
|
||||
const members = [
|
||||
@@ -654,4 +853,62 @@ describe('filters/array', function () {
|
||||
``)
|
||||
})
|
||||
})
|
||||
describe('find_index', function () {
|
||||
const members = [
|
||||
{ graduation_year: 2013, name: 'Jay' },
|
||||
{ graduation_year: 2014, name: 'John' },
|
||||
{ graduation_year: 2014, name: 'Jack', age: 13 }
|
||||
]
|
||||
it('should support find_index with no value', function () {
|
||||
return test(
|
||||
`{{ members | find_index: "age" | json }}`,
|
||||
{ members },
|
||||
`2`)
|
||||
})
|
||||
it('should support find_index by property', function () {
|
||||
return test(
|
||||
`{{ members | find_index: "graduation_year", 2014 | json }}`,
|
||||
{ members },
|
||||
`1`)
|
||||
})
|
||||
it('should render none if not found', function () {
|
||||
return test(
|
||||
`{{ members | find_index: "graduation_year", 2018 | json }}`,
|
||||
{ members },
|
||||
``)
|
||||
})
|
||||
describe('jekyll style', () => {
|
||||
it('should select array by inclusion', async () => {
|
||||
const scope = { objs: [{ foo: ['FOO', 'bar'] }] }
|
||||
await test('{{objs | find_index: "foo", "FOO" | json}}', scope, '0', { jekyllWhere: true })
|
||||
})
|
||||
it('should support empty as target', async () => {
|
||||
const scope = { pages: [{ tags: ['FOO'] }, { tags: [] }, { title: 'foo' }] }
|
||||
await test('{{pages | find_index: "tags", empty | json}}', scope, '1', { jekyllWhere: true })
|
||||
})
|
||||
it('should search plainly when target is undefined', async () => {
|
||||
await test('{{members | find_index: "age", notdefined | json}}', { members }, '0', { jekyllWhere: true })
|
||||
await test('{{members | find_index: "name", notdefined | json}}', { members }, '', { jekyllWhere: true })
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('find_index_exp', function () {
|
||||
const members = [
|
||||
{ graduation_year: 2013, name: 'Jay' },
|
||||
{ graduation_year: 2014, name: 'John' },
|
||||
{ graduation_year: 2014, name: 'Jack' }
|
||||
]
|
||||
it('should support find_index by expression', function () {
|
||||
return test(
|
||||
`{{ members | find_index_exp: "item", "item.graduation_year == 2014" | json }}`,
|
||||
{ members },
|
||||
`1`)
|
||||
})
|
||||
it('should render none if not found', function () {
|
||||
return test(
|
||||
`{{ members | find_index_exp: "item", "item.graduation_year == 2018" | json }}`,
|
||||
{ members },
|
||||
``)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user