From fcb930f0ddf2489fa74cd323f24398d7e9f7717f Mon Sep 17 00:00:00 2001 From: Harttle Date: Sun, 4 Jun 2023 13:32:17 +0800 Subject: [PATCH] fix: sample filter randomness and count=1 case --- CHANGELOG.md | 1 + src/filters/array.ts | 6 ++++-- test/integration/filters/array.spec.ts | 17 ++++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 584d00e558..3ca782300a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ ### Features * Add support for the Jekyll sample filter ([#612](https://github.com/harttle/liquidjs/issues/612)) ([ba8b842](https://github.com/harttle/liquidjs/commit/ba8b84245266589e43c0e70d99e12b981d349809)) +* Add support for the Jekyll push filter ([#611](https://github.com/harttle/liquidjs/issues/611)) * introduce a matrix with latest Ubuntu and macOS to test the build on macOS as well ([82ba548](https://github.com/harttle/liquidjs/commit/82ba54845f4cd4e1e7660c1557e3cfaa22d68924)), closes [#615](https://github.com/harttle/liquidjs/issues/615) * precise line/col for tokenization Error, [#613](https://github.com/harttle/liquidjs/issues/613) ([e347e60](https://github.com/harttle/liquidjs/commit/e347e603d76c039cec191d417deab34e7ef1f9a7)) diff --git a/src/filters/array.ts b/src/filters/array.ts index 6a6e35681d..d77f135eec 100644 --- a/src/filters/array.ts +++ b/src/filters/array.ts @@ -89,9 +89,11 @@ export function uniq (arr: T[]): T[] { }) } -export function sample (v: T[] | string, count: number | undefined = undefined): (T | string)[] { +export function sample (v: T[] | string, count = 1): T | string | (T | string)[] { v = toValue(v) if (isNil(v)) return [] if (!isArray(v)) v = stringify(v) - return [...v].sort(() => Math.random()).slice(0, count) + const shuffled = [...v].sort(() => Math.random() - 0.5) + if (count === 1) return shuffled[0] + return shuffled.slice(0, count) } diff --git a/test/integration/filters/array.spec.ts b/test/integration/filters/array.spec.ts index 3afc974db2..297c010402 100644 --- a/test/integration/filters/array.spec.ts +++ b/test/integration/filters/array.spec.ts @@ -1,6 +1,8 @@ import { test, render } from '../../stub/render' +import { Liquid } from '../../../src/liquid' describe('filters/array', function () { + const engine = new Liquid() describe('index', function () { it('should support index', function () { const src = '{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}' + @@ -97,6 +99,10 @@ describe('filters/array', function () { const scope = { val: ['hey'], arg: 'foo' } await test('{{ val | push: arg | join: "," }}', scope, 'hey,foo') }) + it('should not change original array', async () => { + const scope = { val: ['hey'], arg: 'foo' } + await test('{{ val | push: arg | join: "," }} {{ val | push: arg | join: "," }}', scope, 'hey,foo hey,foo') + }) it('should support undefined left value', async () => { const scope = { arg: 'foo' } await test('{{ notDefined | push: arg | join: "," }}', scope, 'foo') @@ -126,17 +132,18 @@ describe('filters/array', function () { }) }) describe('sample', function () { - it('should return full array sample', () => test( - '{{ "hello,world" | split: "," | sample | size }}', - '2' - )) + it('should return one item if count not specified', async () => { + const template = '{{ "hello,world" | split: "," | sample }}' + const result = await engine.parseAndRender(template) + expect(result).toMatch(/hello|world/) + }) it('should return full array sample even if excess count', () => test( '{{ "hello,world" | split: "," | sample: 10 | size }}', '2' )) it('should return partial array sample', () => test( '{{ "hello,world" | split: "," | sample: 1 | size }}', - '1' + '5' )) it('should sample nil value', () => test( '{{ nil | sample: 2 }}',