n8n/packages/workflow/test/ExpressionExtensions/ArrayExtensions.test.ts
Milorad FIlipović 0cf45bc4c8
fix(core): Fix data transformation function that are reported not to work properly (#5338)
* 🔥 Remove test extensions
* 🚧 Add test description
* 📘 Expand types
*  Export extensions
*  Export collection
*  Mark all proxies
* ✏️ Rename for clarity
*  Export from barrel
*  Create datatype completions
*  Mount datatype completions
* 🧪 Adjust tests
*  Add `path` prop
* 🔥 Remove `()` from completion labels
*  Filter out completions for pseudo-proxies
* 🐛 Fix method error
*  Add metrics
* ✏️ Improve naming
*  Start completion on empty resolvable
*  Implement completion previews
*  Break out completion manager
*  Implement in expression editor modal
* ✏️ Improve naming
*  Filter out irrelevant completions
*  Add preview hint
* ✏️ Improve comments
* 🎨 Style preview hint
*  Expand `hasNoParams`
*  Add spacing for readability
*  Add error codes
* ✏️ Add comment
* 🐛 Fix Esc behavior
*  Parse Unicode
*  Throw on invalid `DateTime`
*  Fix second root completion detection
*  Switch message at completable prefix position
* 🐛 Fix function names for non-dev build
* 🐛 Fix `json` handling
* 🔥 Comment out previews
* ♻️ Apply feedback
* 🔥 Remove extensions
* 🚚 Rename extensions
*  Adjust some implementations
* 🔥 Remove dummy extensions
* 🐛 Fix object regex
* ♻️ Apply feedback
* ✏️ Fix typos
* ✏️ Add `fn is not a function` message
* 🔥 Remove check
*  Add `isNotEmpty` for objects
* 🚚 Rename `global` to `alpha`
* 🔥 Remove `encrypt`
*  Restore `is not a function` error
*  Support `week` on `extract()`
* 🧪 Fix tests
*  Add validation to some string extensions
*  Validate number arrays in some extensions
* 🧪 Fix tests
* ✏️ Improve error message
*  Revert extensions framework changes
* 🧹 Previews cleanup
*  Condense blank completions
*  Refactor dollar completions
*  Refactor non-dollar completions
*  Refactor Luxon completions
*  Refactor datatype completions
*  Use `DATETIMEUNIT_MAP`
* ✏️ Update test description
*  Revert "Use `DATETIMEUNIT_MAP`"
This reverts commit 472a77df5c.
* 🧪 Add tests
* ♻️ Restore generic extensions
* 🔥 Remove logs
* 🧪 Expand tests
*  Add `Math` completions
* ✏️ List breaking change
*  Add doc tooltips
* 🐛 Fix node selector regex
* 🐛 Fix `context` resolution
* 🐛 Allow dollar completions in args
*  Make numeric array methods context-dependent
* 📝 Adjust docs
* 🐛 Fix selector ref
*  Surface error for valid URL
* 🐛 Disallow whitespace in `isEmail` check
* 🧪 Fix test for `isUrl`
*  Add comma validator in `toFloat`
*  Add validation to `$jmespath()`
*  Revert valid URL error
*  Adjust `$jmespath()` validation
* 🧪 Adjust `isUrl` test
*  Remove `{}` and `[]` from compact
* ✏️ Update docs
* 🚚 Rename `stripTags` to `removeTags`
*  Do not inject whitespace inside resolvable
*  Make completions aware of `()`
* ✏️ Add note
*  Update sorting
*  Hide active node name from node selector
* 🔥 Remove `length()` and its aliases
*  Validate non-zero for `chunk`
* ✏️ Reword all error messages
* 🐛 Fix `$now` and `$today`
*  Simplify with `stripExcessParens`
*  Fold luxon into datatype
* 🧪 Clean up tests
* 🔥 Remove tests for removed methods
* 👕 Fix type
* ⬆️ Upgrade lang pack
*  Undo change to `vitest` command
* 🔥 Remove unused method
*  Separate `return` line
* ✏️ Improve description
* 🧪 Expand tests for initial-only completions
* 🧪 Add bracket-aware completions
*  Make check for `all()` stricter
* ✏️ Adjust explanatory comments
* 🔥 Remove unneded copy
* 🔥 Remove outdated comment
*  Make naming consistent
* ✏️ Update comments
*  Improve URL scheme check
* ✏️ Add comment
* 🚚 Move extension
* ✏️ Update `BREAKING-CHANGES.md`
* ✏️ Update upcoming version
* ✏️ Fix grammar
* ✏️ Shorten message
* 🐛 Fix `Esc` behavior
* 🐛 Fix `isNumeric`
*  Using UTC to handle-dates on back-end
*  Added more unit tests for date extensions
*  Not using `JSON.stringify` to render dates
*  Using `deep-equal` library instead of our `deepCompare` function
*  Adding more tests to array extensions
*  Fixing `inBetween` extension function
*  Added tests for `.inBetween()`
*  Updating `isEven` and `isOdd` to throw for floats
*  Updating `Array.merge()` so it works without arguments
* 🔀 Fixing leftover merge confilct
*  Updating `removeFieldsContaining` and `keepFieldsContaining` to throw on empty strings
*  Fixing `pluck()` so it returns only plucked values
* ⬆️ Updating pnpm lockfile
* 👕 Fixing lint errors
*  Using workflow timezone to display dates
* ✔️ Updating tests with workflow timezone
*  Not using system timezone when creating Luxon dates
*  Updating `merge()` and `pluck()` array functions
* 🔀 Sync with `master`: Removing code that was preserved during merge
*  Updating `.pluck()` to return full array if no arguments are passed
*  Updating `keepFieldsContaining` and `merge` object functions
*  Using week as default for `date.extract()`
*  Adding more test cases for DT functions
*  Removing `Object.merge` extension function. Adding missing `deep-equal` dependency
*  Handling `toDate` case when time component is not specified
*  Using workflow's timezone to render dates in output panel, updated unit tests after removing `Object.merge` function
*  Not parsing numbers as dates
* 👕 Fixing lint errors
*  Fixing a typo
*  Making date detection more strict so only stringified dates are getting converted
* 👌 Addressing PR feedback
* 🔥 Removing leftover comment
---------

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
2023-02-15 10:50:16 +01:00

239 lines
7 KiB
TypeScript

/**
* @jest-environment jsdom
*/
import { evaluate } from './Helpers';
describe('Data Transformation Functions', () => {
describe('Array Data Transformation Functions', () => {
test('.randomItem() should work correctly on an array', () => {
expect(evaluate('={{ [1,2,3].randomItem() }}')).not.toBeUndefined();
});
test('.isNotEmpty() should work correctly on an array', () => {
expect(evaluate('={{ [1,2,3, "imhere"].isNotEmpty() }}')).toEqual(true);
});
test('.pluck() should work correctly on an array', () => {
expect(
evaluate(`={{ [
{ value: 1, string: '1' },
{ value: 2, string: '2' },
{ value: 3, string: '3' },
{ value: 4, string: '4' },
{ value: 5, string: '5' },
{ value: 6, string: '6' },
{ value: { something: 'else' } }
].pluck("value") }}`),
).toEqual(
expect.arrayContaining([1, 2, 3, 4, 5, 6, { something: 'else' }]),
);
});
test('.pluck() should work correctly for multiple values', () => {
expect(
evaluate(`={{ [
{
firstName: 'John',
lastName: 'Doe',
phone: {
home: '111-222',
office: '333-444'
}
},
{
firstName: 'Jane',
lastName: 'Doe',
phone: {
office: '555-666'
}
}
].pluck("firstName", "lastName") }}`),
).toEqual(
expect.arrayContaining([["John", "Doe"],["Jane", "Doe"]]),
);
});
test('.pluck() should work return everything with no args', () => {
expect(
evaluate(`={{ [
{ value: 1, string: '1' },
{ value: 2, string: '2' },
{ value: 3, string: '3' },
{ value: 4, string: '4' },
{ value: 5, string: '5' },
{ value: 6, string: '6' },
{ value: { something: 'else' } }
].pluck() }}`),
).toEqual(
expect.arrayContaining([
{ value: 1, string: '1' },
{ value: 2, string: '2' },
{ value: 3, string: '3' },
{ value: 4, string: '4' },
{ value: 5, string: '5' },
{ value: 6, string: '6' },
{ value: { something: 'else' } }
]),
);
});
test('.unique() should work correctly on an array', () => {
expect(evaluate('={{ ["repeat","repeat","a","b","c"].unique() }}')).toEqual(
expect.arrayContaining(['repeat', 'repeat', 'a', 'b', 'c']),
);
});
test('.unique() should work on an arrays containing nulls, objects and arrays', () => {
expect(
evaluate(
'={{ [1, 2, 3, "as", {}, {}, 1, 2, [1,2], "[sad]", "[sad]", null].unique() }}',
),
).toEqual([1, 2, 3, "as", {}, [1,2], "[sad]", null]);
});
test('.isEmpty() should work correctly on an array', () => {
expect(evaluate('={{ [].isEmpty() }}')).toEqual(true);
});
test('.isEmpty() should work correctly on an array', () => {
expect(evaluate('={{ [1].isEmpty() }}')).toEqual(false);
});
test('.last() should work correctly on an array', () => {
expect(evaluate('={{ ["repeat","repeat","a","b","c"].last() }}')).toEqual('c');
});
test('.first() should work correctly on an array', () => {
expect(evaluate('={{ ["repeat","repeat","a","b","c"].first() }}')).toEqual('repeat');
});
test('.merge() should work correctly on an array', () => {
expect(
evaluate(
'={{ [{ test1: 1, test2: 2 }, { test1: 1, test3: 3 }].merge([{ test1: 2, test3: 3 }, { test4: 4 }]) }}',
),
).toEqual({"test1": 1, "test2": 2, "test3": 3, "test4": 4});
});
test('.merge() should work correctly without arguments', () => {
expect(
evaluate(
'={{ [{ a: 1, some: null }, { a: 2, c: "something" }, 2, "asds", { b: 23 }, null, [1, 2]].merge() }}',
),
).toEqual({"a": 1, "some": null, "c": "something", "b": 23});
});
test('.smartJoin() should work correctly on an array of objects', () => {
expect(
evaluate(
'={{ [{ name: "test1", value: "value1" }, { name: "test2", value: null }].smartJoin("name", "value") }}',
),
).toEqual({
test1: 'value1',
test2: null,
});
});
test('.renameKeys() should work correctly on an array of objects', () => {
expect(
evaluate(
'={{ [{ test1: 1, test2: 2 }, { test1: 1, test3: 3 }].renameKeys("test1", "rename1", "test3", "rename3") }}',
),
).toEqual([
{ rename1: 1, test2: 2 },
{ rename1: 1, rename3: 3 },
]);
});
test('.sum() should work on an array of numbers', () => {
expect(evaluate('={{ [1, 2, 3, 4, 5, 6].sum() }}')).toEqual(21);
expect(() => evaluate('={{ ["1", 2, 3, 4, 5, "bad"].sum() }}')).toThrow();
});
test('.average() should work on an array of numbers', () => {
expect(evaluate('={{ [1, 2, 3, 4, 5, 6].average() }}')).toEqual(3.5);
expect(() => evaluate('={{ ["1", 2, 3, 4, 5, "bad"].average() }}')).toThrow();
});
test('.min() should work on an array of numbers', () => {
expect(evaluate('={{ [1, 2, 3, 4, 5, 6].min() }}')).toEqual(1);
expect(() => evaluate('={{ ["1", 2, 3, 4, 5, "bad"].min() }}')).toThrow();
});
test('.max() should work on an array of numbers', () => {
expect(evaluate('={{ [1, 2, 3, 4, 5, 6].max() }}')).toEqual(6);
expect(() => evaluate('={{ ["1", 2, 3, 4, 5, "bad"].max() }}')).toThrow();
});
test('.union() should work on an array of objects', () => {
expect(
evaluate(
'={{ [{ test1: 1 }, { test2: 2 }].union([{ test1: 1, test3: 3 }, { test2: 2 }, { test4: 4 }]) }}',
),
).toEqual([{ test1: 1 }, { test2: 2 }, { test1: 1, test3: 3 }, { test4: 4 }]);
});
test('.union() should work on an arrays containing nulls, objects and arrays', () => {
expect(
evaluate(
'={{ [1, 2, "dd", {}, null].union([1, {}, null, 3]) }}',
),
).toEqual([1, 2, "dd", {}, null, 3]);
});
test('.intersection() should work on an array of objects', () => {
expect(
evaluate(
'={{ [{ test1: 1 }, { test2: 2 }].intersection([{ test1: 1, test3: 3 }, { test2: 2 }, { test4: 4 }]) }}',
),
).toEqual([{ test2: 2 }]);
});
test('.intersection() should work on an arrays containing nulls, objects and arrays', () => {
expect(
evaluate(
'={{ [1, 2, "dd", {}, null].intersection([1, {}, null]) }}',
),
).toEqual([1, {}, null]);
});
test('.difference() should work on an array of objects', () => {
expect(
evaluate(
'={{ [{ test1: 1 }, { test2: 2 }].difference([{ test1: 1, test3: 3 }, { test2: 2 }, { test4: 4 }]) }}',
),
).toEqual([{ test1: 1 }]);
expect(
evaluate('={{ [{ test1: 1 }, { test2: 2 }].difference([{ test1: 1 }, { test2: 2 }]) }}'),
).toEqual([]);
});
test('.difference() should work on an arrays containing nulls, objects and arrays', () => {
expect(
evaluate(
'={{ [1, 2, "dd", {}, null, ["a", 1]].difference([1, {}, null, ["a", 1]]) }}',
),
).toEqual([2, "dd"]);
});
test('.compact() should work on an array', () => {
expect(
evaluate(
'={{ [{ test1: 1, test2: undefined, test3: null }, null, undefined, 1, 2, 0, { test: "asdf" }].compact() }}',
),
).toEqual([{ test1: 1 }, 1, 2, 0, { test: 'asdf' }]);
});
test('.chunk() should work on an array', () => {
expect(evaluate('={{ numberList(1, 20).chunk(5) }}')).toEqual([
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
]);
});
});
});