From 95663d1d57251b926f5db2a89647162063a1935d Mon Sep 17 00:00:00 2001 From: Machiel Date: Tue, 25 Jun 2024 16:13:25 +0200 Subject: [PATCH] feat: Add unique filter to nunjucks. --- .changeset/great-elephants-flash.md | 5 ++ packages/utils/nunjucks/src/index.js | 2 + packages/utils/nunjucks/src/uniqueFilter.js | 26 +++++++ .../utils/nunjucks/src/uniqueFilter.test.js | 68 +++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 .changeset/great-elephants-flash.md create mode 100644 packages/utils/nunjucks/src/uniqueFilter.js create mode 100644 packages/utils/nunjucks/src/uniqueFilter.test.js diff --git a/.changeset/great-elephants-flash.md b/.changeset/great-elephants-flash.md new file mode 100644 index 000000000..3ea7dde99 --- /dev/null +++ b/.changeset/great-elephants-flash.md @@ -0,0 +1,5 @@ +--- +'@lowdefy/nunjucks': minor +--- + +Add 'unique' filter to \_nunjucks. diff --git a/packages/utils/nunjucks/src/index.js b/packages/utils/nunjucks/src/index.js index 2d511ec30..100601a16 100644 --- a/packages/utils/nunjucks/src/index.js +++ b/packages/utils/nunjucks/src/index.js @@ -17,11 +17,13 @@ import nunjucks from 'nunjucks'; import { type } from '@lowdefy/helpers'; import dateFilter from './dateFilter.js'; +import uniqueFilter from './uniqueFilter.js'; // dateFilter.setDefaultFormat('YYYY-MM-DD'); export const nunjucksEnv = new nunjucks.Environment(); nunjucksEnv.addFilter('date', dateFilter); +nunjucksEnv.addFilter('unique', uniqueFilter); const nunjucksTemplates = {}; // slow diff --git a/packages/utils/nunjucks/src/uniqueFilter.js b/packages/utils/nunjucks/src/uniqueFilter.js new file mode 100644 index 000000000..c825cc508 --- /dev/null +++ b/packages/utils/nunjucks/src/uniqueFilter.js @@ -0,0 +1,26 @@ +/* + Copyright 2020-2024 Lowdefy, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import { type } from '@lowdefy/helpers'; + +const uniqueFilter = (arr) => { + if (!type.isArray(arr)) { + return arr; + } + return Array.from(new Set(arr)); +}; + +export default uniqueFilter; diff --git a/packages/utils/nunjucks/src/uniqueFilter.test.js b/packages/utils/nunjucks/src/uniqueFilter.test.js new file mode 100644 index 000000000..4dadc9af8 --- /dev/null +++ b/packages/utils/nunjucks/src/uniqueFilter.test.js @@ -0,0 +1,68 @@ +/* + Copyright 2020-2024 Lowdefy, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import nunjucks from 'nunjucks'; +import uniqueFilter from './uniqueFilter.js'; + +export const nunjucksEnv = new nunjucks.Environment(); +nunjucksEnv.addFilter('unique', uniqueFilter); + +describe('uniqueFilter', () => { + test('should return unique values from an array of primitives', () => { + const input = [1, 2, 2, 3, 4, 4, 4, 5]; + const output = uniqueFilter(input); + expect(output).toEqual([1, 2, 3, 4, 5]); + }); + + test('should return unique values from an array of strings', () => { + const input = ['a', 'b', 'b', 'c', 'a']; + const output = uniqueFilter(input); + expect(output).toEqual(['a', 'b', 'c']); + }); + + test('should return the same array when all values are unique', () => { + const input = [1, 2, 3, 4, 5]; + const output = uniqueFilter(input); + expect(output).toEqual([1, 2, 3, 4, 5]); + }); + + test('should return an empty array when input is an empty array', () => { + const input = []; + const output = uniqueFilter(input); + expect(output).toEqual([]); + }); + + test('should return the input when input is not an array', () => { + expect(uniqueFilter(123)).toBe(123); + expect(uniqueFilter('abc')).toBe('abc'); + expect(uniqueFilter({ a: 1 })).toEqual({ a: 1 }); + expect(uniqueFilter(null)).toBe(null); + expect(uniqueFilter(undefined)).toBe(undefined); + }); + + test('should handle an array with mixed types', () => { + const input = [1, '1', 1, 'a', 'a', {}, {}, []]; + const output = uniqueFilter(input); + expect(output).toEqual([1, '1', 'a', input[5], input[6], input[7]]); + }); + + test('should install unique filter in nunjucks and return unique values', () => { + const templateString = '{{ value | unique | dump }}'; + const input = [1, 2, 2, 3, 4, 4, 4, 5]; + const output = nunjucksEnv.renderString(templateString, { value: input }); + expect(output).toBe('[1,2,3,4,5]'); + }); +});