eval-persistence.test.ts•4.06 kB
import { test, expect, describe } from './test-fixtures.js';
describe('Eval Persistence Integration Test', () => {
test('should persist variables across multiple eval calls', async ({ client }) => {
// First eval: set a variable
const result1 = await client.callTool({
name: 'eval',
arguments: {
function: '() => { vars.x = 42; return vars.x; }',
},
});
const content1 = result1.content as Array<{type: string, text: string}>;
expect(content1[0]?.text).toBe('$results[0] = // eval\n42');
// Second eval: use the variable (should persist)
const result2 = await client.callTool({
name: 'eval',
arguments: {
function: '() => vars.x + 8',
},
});
const content2 = result2.content as Array<{type: string, text: string}>;
expect(content2[0]?.text).toBe('$results[1] = // eval\n50');
// Third eval: modify the variable
const result3 = await client.callTool({
name: 'eval',
arguments: {
function: '() => { vars.x = vars.x + 8; return vars.x; }',
},
});
const content3 = result3.content as Array<{type: string, text: string}>;
expect(content3[0]?.text).toBe('$results[2] = // eval\n50');
// Fourth eval: multiply and verify persistence
const result4 = await client.callTool({
name: 'eval',
arguments: {
function: '() => { vars.x = vars.x * 2; return vars.x; }',
},
});
const content4 = result4.content as Array<{type: string, text: string}>;
expect(content4[0]?.text).toBe('$results[3] = // eval\n100');
});
test('should persist function definitions', async ({ client }) => {
// Define a function
const result1 = await client.callTool({
name: 'eval',
arguments: {
function: '() => { vars.add = function(a, b) { return a + b; }; }',
},
});
// Call the function
const result2 = await client.callTool({
name: 'eval',
arguments: {
function: '() => vars.add(10, 20)',
},
});
const content2 = result2.content as Array<{type: string, text: string}>;
expect(content2[0]?.text).toBe('$results[1] = // eval\n30');
// Redefine the function
const result3 = await client.callTool({
name: 'eval',
arguments: {
function: '() => { vars.add = function(a, b) { return a * b; }; }',
},
});
// Call the redefined function
const result4 = await client.callTool({
name: 'eval',
arguments: {
function: '() => vars.add(10, 20)',
},
});
const content4 = result4.content as Array<{type: string, text: string}>;
expect(content4[0]?.text).toBe('$results[3] = // eval\n200');
});
test('should persist objects and complex data structures', async ({ client }) => {
// Create an object
const result1 = await client.callTool({
name: 'eval',
arguments: {
function: '() => { vars.data = { count: 0, items: [] }; return vars.data.count; }',
},
});
const content1 = result1.content as Array<{type: string, text: string}>;
expect(content1[0]?.text).toBe('$results[0] = // eval\n0');
// Modify the object
const result2 = await client.callTool({
name: 'eval',
arguments: {
function: '() => { vars.data.count++; vars.data.items.push("hello"); return vars.data; }',
},
});
// With new format, object results are formatted after the $results assignment
const content2 = result2.content as Array<{type: string, text: string}>;
const dataStr = content2[0]?.text.split('\n').slice(1).join('\n') || '';
const data = JSON.parse(dataStr);
expect(data.count).toBe(1);
expect(data.items).toEqual(['hello']);
// Verify persistence
const result3 = await client.callTool({
name: 'eval',
arguments: {
function: '() => vars.data.items.length',
},
});
const content3 = result3.content as Array<{type: string, text: string}>;
expect(content3[0]?.text).toBe('$results[2] = // eval\n1');
});
});