mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-27 23:07:12 +02:00
91 lines
2.5 KiB
TypeScript
91 lines
2.5 KiB
TypeScript
// @vitest-environment jsdom
|
|
|
|
import * as Helpers from './helpers';
|
|
import type { INodeExecutionData } from '../src/interfaces';
|
|
import { Workflow } from '../src/workflow';
|
|
|
|
// Feature-parity regressions for `$json` access across nested data shapes.
|
|
// This file lives in `packages/workflow/test/` so vitest runs it under both the
|
|
// `legacy-engine` and `vm-engine` projects (see vitest.config.ts). Any divergence
|
|
// between the two engines fails one project but not the other.
|
|
|
|
describe('Expression — nested $json shapes (engine parity)', () => {
|
|
const workflow = new Workflow({
|
|
id: '1',
|
|
nodes: [
|
|
{
|
|
name: 'node',
|
|
typeVersion: 1,
|
|
type: 'test.set',
|
|
id: 'uuid-1234',
|
|
position: [0, 0],
|
|
parameters: {},
|
|
},
|
|
],
|
|
connections: {},
|
|
active: false,
|
|
nodeTypes: Helpers.NodeTypes(),
|
|
});
|
|
const expression = workflow.expression;
|
|
|
|
beforeAll(async () => {
|
|
await expression.acquireIsolate();
|
|
});
|
|
afterAll(async () => {
|
|
await expression.releaseIsolate();
|
|
});
|
|
|
|
const evaluate = (value: string, json: unknown) => {
|
|
const data: INodeExecutionData[] = [{ json: json as INodeExecutionData['json'] }];
|
|
return expression.getParameterValue(value, null, 0, 0, 'node', data, 'manual', {});
|
|
};
|
|
|
|
it('round-trips a flat object via $json', () => {
|
|
expect(evaluate('={{ $json }}', { name: 'alice', age: 30 })).toEqual({
|
|
name: 'alice',
|
|
age: 30,
|
|
});
|
|
});
|
|
|
|
// N8N-9998 — under the VM engine, the lazy proxy used to wrap nested array
|
|
// values in an object-shaped proxy, so structured clone serialized them
|
|
// as `{}`. Legacy engine was always correct; this test pins the parity.
|
|
it('round-trips an array of arrays via $json', () => {
|
|
expect(evaluate('={{ $json }}', { demo: [[{ foo: 'bar' }], [{ bar: 'bas' }]] })).toEqual({
|
|
demo: [[{ foo: 'bar' }], [{ bar: 'bas' }]],
|
|
});
|
|
});
|
|
|
|
it('returns a nested array directly via $json path access', () => {
|
|
expect(
|
|
evaluate('={{ $json.demo[0] }}', { demo: [[{ foo: 'bar' }], [{ bar: 'bas' }]] }),
|
|
).toEqual([{ foo: 'bar' }]);
|
|
});
|
|
|
|
it('preserves three levels of array nesting', () => {
|
|
expect(evaluate('={{ $json }}', { a: [[[42]]] })).toEqual({ a: [[[42]]] });
|
|
});
|
|
|
|
it('preserves arrays of primitive arrays', () => {
|
|
expect(
|
|
evaluate('={{ $json }}', {
|
|
rows: [
|
|
[1, 2, 3],
|
|
[4, 5, 6],
|
|
],
|
|
}),
|
|
).toEqual({
|
|
rows: [
|
|
[1, 2, 3],
|
|
[4, 5, 6],
|
|
],
|
|
});
|
|
});
|
|
|
|
it('preserves mixed object/array siblings inside an array', () => {
|
|
expect(evaluate('={{ $json }}', { list: [[1, 2], { k: 'v' }] })).toEqual({
|
|
list: [[1, 2], { k: 'v' }],
|
|
});
|
|
});
|
|
});
|