Skip to main content
Glama
json-operations.test.ts8.8 kB
import { JsonEditorMCPServerTestable } from './JsonEditorMCPServerTestable'; import { createTestFile, readTestFile } from './setup'; import { promises as fs } from 'fs'; import path from 'path'; describe('JSON Operations', () => { let server: JsonEditorMCPServerTestable; const testDir = path.join(__dirname, 'temp'); beforeEach(() => { server = new JsonEditorMCPServerTestable(); }); describe('getValueAtPath', () => { it('should read simple values', () => { const obj = { "key": "value" }; expect(server.getValueAtPath(obj, "key")).toBe("value"); }); it('should read nested values', () => { const obj = { "level1": { "level2": { "key": "value" } } }; expect(server.getValueAtPath(obj, "level1.level2.key")).toBe("value"); }); it('should read array values', () => { const obj = { "array": [1, 2, 3] }; expect(server.getValueAtPath(obj, "array")).toEqual([1, 2, 3]); }); it('should read object values', () => { const obj = { "nested": { "key": "value" } }; expect(server.getValueAtPath(obj, "nested")).toEqual({ "key": "value" }); }); it('should throw error for non-existent path', () => { const obj = { "key": "value" }; expect(() => server.getValueAtPath(obj, "nonexistent")).toThrow("Path nonexistent not found: nonexistent does not exist"); }); it('should throw error for invalid path', () => { const obj = { "key": "value" }; expect(() => server.getValueAtPath(obj, "key.nested")).toThrow("Path key.nested not found: nested is not an object"); }); it('should handle empty path', () => { const obj = { "key": "value" }; expect(() => server.getValueAtPath(obj, "")).toThrow(); }); }); describe('setValueAtPath', () => { it('should set simple values', () => { const obj: any = {}; server.setValueAtPath(obj, "key", "value"); expect(obj).toEqual({ "key": "value" }); }); it('should set nested values', () => { const obj: any = {}; server.setValueAtPath(obj, "level1.level2.key", "value"); expect(obj).toEqual({ "level1": { "level2": { "key": "value" } } }); }); it('should update existing values', () => { const obj: any = { "key": "oldValue" }; server.setValueAtPath(obj, "key", "newValue"); expect(obj).toEqual({ "key": "newValue" }); }); it('should update nested existing values', () => { const obj: any = { "level1": { "level2": { "key": "oldValue" } } }; server.setValueAtPath(obj, "level1.level2.key", "newValue"); expect(obj).toEqual({ "level1": { "level2": { "key": "newValue" } } }); }); it('should create intermediate objects', () => { const obj: any = {}; server.setValueAtPath(obj, "a.b.c.d", "value"); expect(obj).toEqual({ "a": { "b": { "c": { "d": "value" } } } }); }); it('should handle arrays', () => { const obj: any = {}; server.setValueAtPath(obj, "array", [1, 2, 3]); expect(obj).toEqual({ "array": [1, 2, 3] }); }); it('should handle objects', () => { const obj: any = {}; server.setValueAtPath(obj, "nested", { "key": "value" }); expect(obj).toEqual({ "nested": { "key": "value" } }); }); it('should handle null and undefined values', () => { const obj: any = {}; server.setValueAtPath(obj, "nullKey", null); server.setValueAtPath(obj, "undefinedKey", undefined); expect(obj).toEqual({ "nullKey": null, "undefinedKey": undefined }); }); it('should overwrite existing nested structures', () => { const obj: any = { "level1": { "level2": { "key": "value" } } }; server.setValueAtPath(obj, "level1", "string"); expect(obj).toEqual({ "level1": "string" }); }); }); describe('readJsonFile', () => { it('should read valid JSON file', async () => { const testData = { "key": "value", "nested": { "key": "value" } }; const filePath = await createTestFile('valid.json', testData); const result = await server.readJsonFile(filePath); expect(result).toEqual(testData); }); it('should return empty object for non-existent file', async () => { const result = await server.readJsonFile('nonexistent.json'); expect(result).toEqual({}); }); it('should throw error for invalid JSON', async () => { const filePath = path.join(testDir, 'invalid.json'); await fs.writeFile(filePath, 'invalid json content'); await expect(server.readJsonFile(filePath)).rejects.toThrow('Failed to read JSON file'); }); it('should handle empty file', async () => { const filePath = path.join(testDir, 'empty.json'); await fs.writeFile(filePath, ''); await expect(server.readJsonFile(filePath)).rejects.toThrow('Failed to read JSON file'); }); }); describe('deleteValueAtPath', () => { it('should delete simple values', () => { const obj: any = { "key": "value", "other": "otherValue" }; server.deleteValueAtPath(obj, "key"); expect(obj).toEqual({ "other": "otherValue" }); expect(obj.key).toBeUndefined(); }); it('should delete nested values', () => { const obj: any = { "level1": { "level2": { "key1": "value1", "key2": "value2" } } }; server.deleteValueAtPath(obj, "level1.level2.key1"); expect(obj.level1.level2).toEqual({ "key2": "value2" }); expect(obj.level1.level2.key1).toBeUndefined(); }); it('should delete top-level keys', () => { const obj: any = { "key1": "value1", "key2": "value2", "key3": "value3" }; server.deleteValueAtPath(obj, "key2"); expect(obj).toEqual({ "key1": "value1", "key3": "value3" }); }); it('should throw error for non-existent path', () => { const obj: any = { "key": "value" }; expect(() => server.deleteValueAtPath(obj, "nonexistent")).toThrow("Path nonexistent not found: nonexistent does not exist"); }); it('should throw error for non-existent nested path', () => { const obj: any = { "level1": { "level2": { "key": "value" } } }; expect(() => server.deleteValueAtPath(obj, "level1.level2.nonexistent")).toThrow("Path level1.level2.nonexistent not found: nonexistent does not exist"); }); it('should throw error when trying to delete from non-object', () => { const obj: any = { "key": "value" }; expect(() => server.deleteValueAtPath(obj, "key.nested")).toThrow("Path key.nested not found: cannot delete from non-object"); }); it('should handle deleting last key in nested object', () => { const obj: any = { "level1": { "level2": { "key": "value" } } }; server.deleteValueAtPath(obj, "level1.level2.key"); expect(obj.level1.level2).toEqual({}); }); }); describe('Integration tests', () => { it('should handle complex nested operations', () => { const obj: any = {}; // Set multiple nested values server.setValueAtPath(obj, "user.profile.name", "John Doe"); server.setValueAtPath(obj, "user.profile.age", 30); server.setValueAtPath(obj, "user.settings.theme", "dark"); server.setValueAtPath(obj, "user.settings.language", "en"); // Verify the structure expect(obj).toEqual({ "user": { "profile": { "name": "John Doe", "age": 30 }, "settings": { "theme": "dark", "language": "en" } } }); // Read values back expect(server.getValueAtPath(obj, "user.profile.name")).toBe("John Doe"); expect(server.getValueAtPath(obj, "user.profile.age")).toBe(30); expect(server.getValueAtPath(obj, "user.settings.theme")).toBe("dark"); expect(server.getValueAtPath(obj, "user.settings.language")).toBe("en"); }); it('should handle array operations', () => { const obj: any = {}; server.setValueAtPath(obj, "items", [1, 2, 3]); expect(server.getValueAtPath(obj, "items")).toEqual([1, 2, 3]); server.setValueAtPath(obj, "items", [4, 5, 6]); expect(server.getValueAtPath(obj, "items")).toEqual([4, 5, 6]); }); it('should handle boolean and number values', () => { const obj: any = {}; server.setValueAtPath(obj, "enabled", true); server.setValueAtPath(obj, "count", 42); server.setValueAtPath(obj, "price", 99.99); expect(server.getValueAtPath(obj, "enabled")).toBe(true); expect(server.getValueAtPath(obj, "count")).toBe(42); expect(server.getValueAtPath(obj, "price")).toBe(99.99); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/peternagy1332/json-editor-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server