import { describe, it, expect, beforeEach } from '@jest/globals';
import { TypeConversionTool } from '../../src/tools/conversion.js';
describe('TypeConversionTool', () => {
let tool: TypeConversionTool;
beforeEach(() => {
tool = new TypeConversionTool();
});
describe('Tool Definition', () => {
it('should have correct name', () => {
expect(tool.name).toBe('typeconversion');
});
it('should have description', () => {
expect(tool.description).toBeTruthy();
expect(tool.description.length).toBeGreaterThan(0);
});
it('should have schema', () => {
expect(tool.schema).toBeDefined();
});
});
describe('JSON Conversions', () => {
const jsonData = '{"name": "John", "age": 30, "city": "New York"}';
it('should convert JSON to YAML', async () => {
const result = await tool.run({
input: jsonData,
fromFormat: 'json',
toFormat: 'yaml',
});
expect(result.content[0].text).toContain('name: John');
expect(result.content[0].text).toContain('age: 30');
expect(result.content[0].text).toContain('city: New York');
});
it('should convert JSON to XML', async () => {
const result = await tool.run({
input: jsonData,
fromFormat: 'json',
toFormat: 'xml',
});
expect(result.content[0].text).toContain('<name>John</name>');
expect(result.content[0].text).toContain('<age>30</age>');
expect(result.content[0].text).toContain('<city>New York</city>');
});
it('should convert JSON to CSV', async () => {
const arrayJson = '[{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]';
const result = await tool.run({
input: arrayJson,
fromFormat: 'json',
toFormat: 'csv',
});
expect(result.content[0].text).toContain('name,age');
expect(result.content[0].text).toContain('John,30');
expect(result.content[0].text).toContain('Jane,25');
});
it('should convert JSON to TOML', async () => {
const result = await tool.run({
input: jsonData,
fromFormat: 'json',
toFormat: 'toml',
});
expect(result.content[0].text).toContain('name = "John"');
expect(result.content[0].text).toContain('age = 30');
expect(result.content[0].text).toContain('city = "New York"');
});
});
describe('YAML Conversions', () => {
const yamlData = 'name: John\nage: 30\ncity: New York';
it('should convert YAML to JSON', async () => {
const result = await tool.run({
input: yamlData,
fromFormat: 'yaml',
toFormat: 'json',
});
const parsed = JSON.parse(result.content[0].text);
expect(parsed.name).toBe('John');
expect(parsed.age).toBe(30);
expect(parsed.city).toBe('New York');
});
it('should convert YAML to XML', async () => {
const result = await tool.run({
input: yamlData,
fromFormat: 'yaml',
toFormat: 'xml',
});
expect(result.content[0].text).toContain('<name>John</name>');
expect(result.content[0].text).toContain('<age>30</age>');
});
});
describe('CSV Conversions', () => {
const csvData = 'name,age\nJohn,30\nJane,25';
it('should convert CSV to JSON', async () => {
const result = await tool.run({
input: csvData,
fromFormat: 'csv',
toFormat: 'json',
});
const parsed = JSON.parse(result.content[0].text);
expect(Array.isArray(parsed)).toBe(true);
expect(parsed[0].name).toBe('John');
expect(parsed[0].age).toBe('30');
});
it('should convert CSV to YAML', async () => {
const result = await tool.run({
input: csvData,
fromFormat: 'csv',
toFormat: 'yaml',
});
expect(result.content[0].text).toContain('name: John');
expect(result.content[0].text).toContain('age: \'30\'');
});
it('should handle CSV without headers', async () => {
const result = await tool.run({
input: csvData,
fromFormat: 'csv',
toFormat: 'json',
options: { csvHeaders: false },
});
expect(result.content[0].text).toBeTruthy();
});
it('should handle custom CSV delimiter', async () => {
const tsvData = 'name\tage\nJohn\t30';
const result = await tool.run({
input: tsvData,
fromFormat: 'csv',
toFormat: 'json',
options: { csvDelimiter: '\t' },
});
const parsed = JSON.parse(result.content[0].text);
expect(parsed[0].name).toBe('John');
});
});
describe('XML Conversions', () => {
const xmlData = '<root><name>John</name><age>30</age></root>';
it('should convert XML to JSON', async () => {
const result = await tool.run({
input: xmlData,
fromFormat: 'xml',
toFormat: 'json',
});
const parsed = JSON.parse(result.content[0].text);
expect(parsed.name).toBe('John');
expect(parsed.age).toBe('30');
});
it('should convert XML to YAML', async () => {
const result = await tool.run({
input: xmlData,
fromFormat: 'xml',
toFormat: 'yaml',
});
expect(result.content[0].text).toContain('name: John');
});
});
describe('TOML Conversions', () => {
const tomlData = 'name = "John"\nage = 30';
it('should convert TOML to JSON', async () => {
const result = await tool.run({
input: tomlData,
fromFormat: 'toml',
toFormat: 'json',
});
const parsed = JSON.parse(result.content[0].text);
expect(parsed.name).toBe('John');
expect(parsed.age).toBe(30);
});
it('should convert TOML to YAML', async () => {
const result = await tool.run({
input: tomlData,
fromFormat: 'toml',
toFormat: 'yaml',
});
expect(result.content[0].text).toContain('name: John');
});
});
describe('Formatting Options', () => {
const jsonData = '{"name": "John", "age": 30}';
it('should pretty print by default', async () => {
const result = await tool.run({
input: jsonData,
fromFormat: 'json',
toFormat: 'json',
});
expect(result.content[0].text).toContain('\n');
expect(result.content[0].text).toContain(' ');
});
it('should minify when pretty is false', async () => {
const result = await tool.run({
input: jsonData,
fromFormat: 'json',
toFormat: 'json',
options: { pretty: false },
});
expect(result.content[0].text).not.toContain('\n ');
});
it('should respect custom indentation', async () => {
const result = await tool.run({
input: jsonData,
fromFormat: 'json',
toFormat: 'json',
options: { pretty: true, indent: 4 },
});
expect(result.content[0].text).toContain(' ');
});
});
describe('Error Handling', () => {
it('should handle invalid JSON', async () => {
const result = await tool.run({
input: '{invalid json}',
fromFormat: 'json',
toFormat: 'yaml',
});
expect(result.isError).toBe(true);
expect(result.content[0].text).toContain('Error');
});
it('should handle invalid XML', async () => {
const result = await tool.run({
input: '<invalid><xml>',
fromFormat: 'xml',
toFormat: 'json',
});
expect(result.isError).toBe(true);
});
it('should handle invalid YAML', async () => {
const result = await tool.run({
input: 'invalid:\n - yaml\n - structure',
fromFormat: 'yaml',
toFormat: 'json',
});
expect(result.isError).toBe(true);
});
it('should handle TOML with array at root', async () => {
const result = await tool.run({
input: '["item1", "item2"]',
fromFormat: 'json',
toFormat: 'toml',
});
expect(result.isError).toBe(true);
expect(result.content[0].text).toContain('object at the root level');
});
it('should validate required parameters', async () => {
const result = await tool.run({
input: '',
fromFormat: 'json',
toFormat: 'yaml',
});
expect(result.isError).toBe(true);
});
});
describe('Edge Cases', () => {
it('should handle empty CSV', async () => {
const result = await tool.run({
input: '',
fromFormat: 'csv',
toFormat: 'json',
});
// Should handle gracefully
expect(result).toBeDefined();
});
it('should handle nested structures', async () => {
const nestedJson = '{"user": {"name": "John", "address": {"city": "NYC"}}}';
const result = await tool.run({
input: nestedJson,
fromFormat: 'json',
toFormat: 'yaml',
});
expect(result.content[0].text).toContain('user:');
expect(result.content[0].text).toContain('address:');
});
it('should handle special characters', async () => {
const specialJson = '{"text": "Hello \\"World\\"", "emoji": "🚀"}';
const result = await tool.run({
input: specialJson,
fromFormat: 'json',
toFormat: 'yaml',
});
expect(result.isError).toBe(false);
});
});
});