import { describe, it, expect } from 'vitest'; /** * Helper function that mimics the validation logic in ConfigTemplate.tsx * This is the improved version with comment support */ function validateJsonWithComments(value: string): { valid: boolean; error?: string } { try { if (!value.trim()) { return { valid: true }; } // Step 1: Remove /* */ multi-line comments let sanitized = value.replace(/\/\*[\s\S]*?\*\//g, ''); // Step 2: Process line by line to handle // comments outside quotes const lines = sanitized.split('\n'); const processedLines = lines.map(line => { let result = ''; let inQuote = false; let quoteChar = ''; for (let i = 0; i < line.length; i++) { const char = line[i]; const prevChar = i > 0 ? line[i - 1] : ''; // Check for quote start/end (not escaped) if ((char === '"' || char === "'") && prevChar !== '\\') { if (!inQuote) { inQuote = true; quoteChar = char; } else if (char === quoteChar) { inQuote = false; quoteChar = ''; } result += char; } // Check for // comment start (only outside quotes) else if (!inQuote && char === '/' && line[i + 1] === '/') { break; // Rest of line is comment } else { result += char; } } return result; }); sanitized = processedLines.join('\n'); // Step 3: Replace @placeholders@ with dummy values sanitized = sanitized.replace(/@[^@]+@/g, '1'); JSON.parse(sanitized); return { valid: true }; } catch (e) { return { valid: false, error: (e as Error).message }; } } describe('JSON Validation - Comment Support', () => { it('should remove single-line // comments outside quotes', () => { const json = `{ "key": "value" // this is a comment }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should preserve // inside quoted strings', () => { const json = `{ "url": "http://example.com/path", "description": "This // that // other" }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should preserve URLs with // in values', () => { const json = `{ "apiUrl": "http://localhost:8080/api", "cdn": "https://cdn.example.com/assets" }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should remove multi-line /* */ comments', () => { const json = `{ /* This is a multi-line comment */ "key": "value" }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should handle mixed comments and placeholders', () => { const json = `{ // Host configuration "host": "@host@", "port": @port@, // unquoted placeholder /* API settings */ "apiUrl": "http://@host@:@port@/api" // URL with placeholders }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should handle comment-only lines', () => { const json = `{ // Just a comment "key": "value" // Another comment }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should preserve // in string values with special characters', () => { const json = `{ "regex": "pattern // with slashes", "path": "C://Program Files//App", "comment": "text // more text // even more" }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should handle escaped quotes correctly', () => { const json = `{ "message": "He said \\"hello // world\\"" }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should reject invalid JSON with comments', () => { const json = `{ "key": "value" // missing comma "another": "key" }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(false); expect(result.error).toContain('Expected'); }); it('should handle empty template', () => { const result = validateJsonWithComments(''); expect(result.valid).toBe(true); }); it('should handle whitespace only', () => { const result = validateJsonWithComments(' \n\t '); expect(result.valid).toBe(true); }); }); describe('JSON Validation - Placeholder Support', () => { it('should validate quoted placeholders', () => { const json = `{ "Host": "@host@", "Port": "@port@" }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should validate unquoted placeholders', () => { const json = `{ "Host": "@host@", "Port": @port@ }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should validate placeholders in URLs', () => { const json = `{ "ApiUrl": "http://@host@:@port@/api/v1" }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); it('should validate complex template with comments and placeholders', () => { const json = `{ // Database config "db": { "host": "@db_host@", "port": @db_port@, "url": "jdbc:mysql://@db_host@:@db_port@/mydb" // connection string }, /* API settings */ "api": { "baseUrl": "https://@api_host@/v1", "timeout": @timeout@ } }`; const result = validateJsonWithComments(json); expect(result.valid).toBe(true); }); });