Skip to content

Commit 493acde

Browse files
committed
feat: size, first, last support arraylike objects, #781
1 parent bb08cfa commit 493acde

File tree

3 files changed

+10
-12
lines changed

3 files changed

+10
-12
lines changed

src/filters/array.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { toArray, argumentsToValue, toValue, stringify, caseInsensitiveCompare, isArray, isNil, last as arrayLast } from '../util'
1+
import { toArray, argumentsToValue, toValue, stringify, caseInsensitiveCompare, isArray, isNil, last as arrayLast, isArrayLike } from '../util'
22
import { arrayIncludes, equals, evalToken, isTruthy } from '../render'
33
import { Value, FilterImpl } from '../template'
44
import { Tokenizer } from '../parser'
@@ -12,8 +12,8 @@ export const join = argumentsToValue(function (this: FilterImpl, v: any[], arg:
1212
this.context.memoryLimit.use(complexity)
1313
return array.join(sep)
1414
})
15-
export const last = argumentsToValue((v: any) => isArray(v) ? arrayLast(v) : '')
16-
export const first = argumentsToValue((v: any) => isArray(v) ? v[0] : '')
15+
export const last = argumentsToValue((v: any) => isArrayLike(v) ? arrayLast(v) : '')
16+
export const first = argumentsToValue((v: any) => isArrayLike(v) ? v[0] : '')
1717
export const reverse = argumentsToValue(function (this: FilterImpl, v: any[]) {
1818
const array = toArray(v)
1919
this.context.memoryLimit.use(array.length)

src/util/underscore.ts

+4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ export function isArray (value: any): value is any[] {
9393
return toString.call(value) === '[object Array]'
9494
}
9595

96+
export function isArrayLike (value: any): value is any[] {
97+
return value && isNumber(value.length)
98+
}
99+
96100
export function isIterable (value: any): value is Iterable<any> {
97101
return isObject(value) && Symbol.iterator in value
98102
}

test/integration/filters/array.spec.ts

+3-9
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,6 @@ describe('filters/array', function () {
2727
return expect(render(src)).rejects.toThrow('expected ":" after filter name, line:1, col:83')
2828
})
2929
})
30-
describe('last', () => {
31-
it('should support last', function () {
32-
const src = '{{ arr | last }}'
33-
const scope = { arr: ['zebra', 'octopus', 'giraffe', 'tiger'] }
34-
return test(src, scope, 'tiger')
35-
})
36-
})
3730
describe('split', () => {
3831
it('should support split', function () {
3932
const src = '{% assign my_array = "zebra, octopus, giraffe, tiger" | split: ", " %}' +
@@ -263,6 +256,7 @@ describe('filters/array', function () {
263256
it('should return 0 for false', () => test('{{ false | size }}', '0'))
264257
it('should return 0 for nil', () => test('{{ nil | size }}', '0'))
265258
it('should return 0 for undefined', () => test('{{ foo | size }}', '0'))
259+
it('should work for string', () => test('{{ "foo" | size }}', {}, '3'))
266260
})
267261
describe('first', function () {
268262
it('should support first', () => test(
@@ -273,7 +267,7 @@ describe('filters/array', function () {
273267
it('should return empty for nil', () => test('{{nil | first}}', ''))
274268
it('should return empty for undefined', () => test('{{foo | first}}', ''))
275269
it('should return empty for false', () => test('{{false | first}}', ''))
276-
it('should return empty for string', () => test('{{"zebra" | first}}', ''))
270+
it('should work for string', () => test('{{ "foo" | first }}', 'f'))
277271
})
278272
describe('last', function () {
279273
it('should support last', () => test(
@@ -284,7 +278,7 @@ describe('filters/array', function () {
284278
it('should return empty for nil', () => test('{{nil | last}}', ''))
285279
it('should return empty for undefined', () => test('{{foo | last}}', ''))
286280
it('should return empty for false', () => test('{{false | last}}', ''))
287-
it('should return empty for string', () => test('{{"zebra" | last}}', ''))
281+
it('should work for string', () => test('{{ "foo" | last }}', {}, 'o'))
288282
})
289283
describe('slice', function () {
290284
it('should slice first char by 0', () => test('{{ "Liquid" | slice: 0 }}', 'L'))

0 commit comments

Comments
 (0)