qasphere-mcp
Version:
MCP server for QA Sphere integration
114 lines (113 loc) • 4.96 kB
JavaScript
import { describe, it, expect } from 'vitest';
import { JSONStringify } from './utils';
describe('JSONStringify', () => {
const baseObject = {
a: 1,
b: 2,
c: { a: 11, b: 22, d: { a: 111 } },
d: [{ a: 50, x: 100 }, { b: 60, a: 70 }],
e: null,
f: [1, 2, 3],
g: { a: 'keep_g' }
};
it('should return JSON string of object without changes when renameKeys is empty', () => {
const result = JSONStringify(baseObject, {});
expect(JSON.parse(result)).toEqual(baseObject);
});
it('should handle the first example: {a:z}', () => {
const o = { 'a': 1, 'b': 2, 'c': { 'a': 11, 'b': 22 } };
const renameMap = { a: 'z' };
const expected = { 'z': 1, 'b': 2, 'c': { 'a': 11, 'b': 22 } };
const result = JSONStringify(o, renameMap);
expect(JSON.parse(result)).toEqual(expected);
});
it('should handle the second example: {c:{a:z}}', () => {
const o = { 'a': 1, 'b': 2, 'c': { 'a': 11, 'b': 22 } };
const renameMap = { c: { a: 'z' } };
const expected = { 'a': 1, 'b': 2, 'c': { 'z': 11, 'b': 22 } };
const result = JSONStringify(o, renameMap);
expect(JSON.parse(result)).toEqual(expected);
});
it('should rename only specified top-level keys when using string values', () => {
const renameMap = { a: 'z', b: 'y' };
const expected = {
z: 1, // renamed
y: 2, // renamed
c: { a: 11, b: 22, d: { a: 111 } }, // nested a/b untouched
d: [{ a: 50, x: 100 }, { b: 60, a: 70 }], // nested a/b untouched
e: null,
f: [1, 2, 3],
g: { a: 'keep_g' } // nested a untouched
};
const result = JSONStringify(baseObject, renameMap);
expect(JSON.parse(result)).toEqual(expected);
});
it('should rename nested keys using nested rename map objects', () => {
const renameMap = { c: { a: 'z', d: { a: 'k' } }, g: { a: 'g_new' } };
const expected = {
a: 1,
b: 2,
c: { z: 11, b: 22, d: { k: 111 } }, // c.a renamed to z, c.d.a renamed to k
d: [{ a: 50, x: 100 }, { b: 60, a: 70 }], // d array untouched
e: null,
f: [1, 2, 3],
g: { g_new: 'keep_g' } // g.a renamed
};
const result = JSONStringify(baseObject, renameMap);
expect(JSON.parse(result)).toEqual(expected);
});
it('should rename keys deeply within arrays if a matching nested rule exists', () => {
// To rename 'a' inside the objects within the array 'd',
// the rename map needs to target 'a' at the level where it occurs.
const renameMap = { d: { a: 'z' } }; // This applies universally
const expected = {
a: 1,
b: 2,
c: { a: 11, b: 22, d: { a: 111 } },
d: [{ z: 50, x: 100 }, { b: 60, z: 70 }],
e: null,
f: [1, 2, 3],
g: { a: 'keep_g' }
};
const result = JSONStringify(baseObject, renameMap);
expect(JSON.parse(result)).toEqual(expected);
});
it('should handle mixed simple and nested renaming rules', () => {
const renameMap = { a: 'z', c: { b: 'y' } };
const expected = {
z: 1, // Renamed by top-level rule {a: 'z'}
b: 2,
c: { a: 11, y: 22, d: { a: 111 } }, // c.b renamed to y by nested rule, c.a and c.d.a untouched by *this* rule
d: [{ a: 50, x: 100 }, { b: 60, a: 70 }],
e: null,
f: [1, 2, 3],
g: { a: 'keep_g' }
};
const result = JSONStringify(baseObject, renameMap);
expect(JSON.parse(result)).toEqual(expected);
});
it('should handle empty objects', () => {
const renameMap = { a: 'z' };
expect(JSON.parse(JSONStringify({}, renameMap))).toEqual({});
});
it('should handle objects with null values', () => {
const obj = { a: 1, b: null };
const renameMap = { a: 'z' };
const expected = { z: 1, b: null };
expect(JSON.parse(JSONStringify(obj, renameMap))).toEqual(expected);
});
it('should handle arrays directly if passed', () => {
const arr = [{ a: 1 }, { a: 2 }];
const renameMap = { a: 'z' };
const expected = [{ z: 1 }, { z: 2 }];
expect(JSON.parse(JSONStringify(arr, renameMap))).toEqual(expected);
});
it('should handle non-string/object values in renameKeys gracefully (treat as no-op for that key)', () => {
// The type system prevents this, but testing javascript flexibility
const renameMap = { a: true, b: 'y' };
const obj = { a: 1, b: 2, c: 3 };
const expected = { a: 1, y: 2, c: 3 }; // 'a' is not renamed (invalid rule type), 'b' is
const result = JSONStringify(obj, renameMap);
expect(JSON.parse(result)).toEqual(expected);
});
});