n8n/packages/workflow/test/expression-vm-dispatch.test.ts
Mike Repeć e383f0f903
chore(core): Backport expression isolation phases 4A–8 to 1.x (no-changelog)
Completes the CAT-2844 backport of Expression Isolation to 1.x. Phases 1–3
landed via #31186/#31383/#31384; this squashes the remaining phases (whose
per-phase PRs #31385/#31387/#31388/#31389/#31390/#31474 were merged into the
stacked branches rather than 1.x):

- 4A — dispatch Expression.evaluate() to the VM evaluator (#31385)
- 4B — init/dispose VM engine in cli base command (#31387)
- 4C — acquire/release isolate at production callsites (#31388)
- 5  — ExpressionObservabilityProvider (#31389)
- 7  — workflow engine-parity test workspace (#31390)
- 8  — rebuild isolated-vm in Docker image for musl libc (#31474)
- test: make 1.x jmespath/array-proxy tests engine-aware

Engine remains opt-in via N8N_EXPRESSION_ENGINE=vm (default legacy); v1
behaviour unchanged unless enabled.

Refs https://linear.app/n8n/issue/CAT-2844
2026-06-02 12:07:42 +02:00

73 lines
1.6 KiB
TypeScript

import { afterAll, beforeAll, beforeEach, afterEach, describe, expect, test } from 'vitest';
import { Expression } from '../src/expression';
import { Workflow } from '../src/workflow';
import * as Helpers from './helpers';
describe('Expression VM engine dispatch', () => {
let workflow: Workflow;
beforeAll(async () => {
await Expression.initExpressionEngine({
engine: 'vm',
bridgeTimeout: 5000,
bridgeMemoryLimit: 128,
poolSize: 1,
maxCodeCacheSize: 64,
});
const nodeTypes = Helpers.NodeTypes();
workflow = new Workflow({
nodes: [
{
name: 'node',
typeVersion: 1,
type: 'test.set',
id: 'uuid-1',
parameters: {},
position: [0, 0],
},
],
connections: {},
active: false,
nodeTypes,
});
});
afterAll(async () => {
await Expression.disposeExpressionEngine();
});
beforeEach(async () => {
await workflow.expression.acquireIsolate();
});
afterEach(async () => {
await workflow.expression.releaseIsolate();
});
test('reports vm as active implementation while engine is set', () => {
expect(Expression.getActiveImplementation()).toBe('vm');
});
test('evaluates a simple expression through the VM engine', () => {
const result = workflow.expression.getSimpleParameterValue(
workflow.nodes.node,
'={{ 7 * 6 }}',
'manual',
{},
);
expect(result).toBe(42);
});
test('evaluates string concatenation through the VM engine', () => {
const result = workflow.expression.getSimpleParameterValue(
workflow.nodes.node,
'={{ "hello " + "world" }}',
'manual',
{},
);
expect(result).toBe('hello world');
});
});