Skip to main content
Glama
validate-endpoints.js10.3 kB
#!/usr/bin/env node /** * Validation Endpoints Test Suite * Tests all validation endpoints with various diagram types * Author: Gregorio Elias Roecker Momm */ const http = require('http'); const fs = require('fs'); const path = require('path'); const API_HOST = process.env.API_HOST || 'localhost'; const API_PORT = process.env.API_PORT || 8000; const API_BASE = `http://${API_HOST}:${API_PORT}/api/v1`; const COLORS = { RED: '\x1b[31m', GREEN: '\x1b[32m', YELLOW: '\x1b[33m', BLUE: '\x1b[34m', NC: '\x1b[0m' }; function log(message, color = COLORS.NC) { console.log(`${color}${message}${COLORS.NC}`); } /** * Test cases for all 26 Mermaid diagram types */ const testCases = [ { name: 'Flowchart', type: 'flowchart', content: `flowchart TD A[Start] --> B{Decision} B -->|Yes| C[Process] B -->|No| D[End]` }, { name: 'Sequence Diagram', type: 'sequenceDiagram', content: `sequenceDiagram Alice->>Bob: Hello Bob Bob-->>Alice: Hi Alice` }, { name: 'Class Diagram', type: 'classDiagram', content: `classDiagram class Animal { +String name +int age +makeSound() }` }, { name: 'State Diagram', type: 'stateDiagram-v2', content: `stateDiagram-v2 [*] --> Idle Idle --> Working Working --> [*]` }, { name: 'Entity Relationship', type: 'erDiagram', content: `erDiagram CUSTOMER ||--o{ ORDER : places ORDER ||--|{ LINE-ITEM : contains` }, { name: 'Gantt Chart', type: 'gantt', content: `gantt title Project Schedule section Planning Research :a1, 2024-01-01, 30d` }, { name: 'User Journey', type: 'journey', content: `journey title My working day section Go to work Make tea: 5: Me` }, { name: 'Git Graph', type: 'gitGraph', content: `gitGraph commit branch develop commit checkout main merge develop` }, { name: 'Pie Chart', type: 'pie', content: `pie title Pets adopted "Dogs" : 386 "Cats" : 85 "Rats" : 15` }, { name: 'Quadrant Chart', type: 'quadrantChart', content: `quadrantChart title Reach and engagement x-axis Low Reach --> High Reach y-axis Low Engagement --> High Engagement quadrant-1 We should expand quadrant-2 Need to promote quadrant-3 Re-evaluate quadrant-4 May be improved Campaign A: [0.3, 0.6]` }, { name: 'Requirement Diagram', type: 'requirementDiagram', content: `requirementDiagram requirement test_req { id: 1 text: the test text risk: high verifymethod: test }` }, { name: 'Mind Map', type: 'mindmap', content: `mindmap root((mindmap)) Origins Long history Research On effectiveness Tools pen and paper apps` }, { name: 'Timeline', type: 'timeline', content: `timeline title Timeline of Events 2020 : Event 1 2021 : Event 2 2022 : Event 3` }, { name: 'ZenUML', type: 'zenuml', content: `zenuml Alice->Bob: Hello Bob Bob->Alice: Hi Alice` }, { name: 'Sankey', type: 'sankey-beta', content: `sankey-beta Coal,Electricity,10 Solar,Electricity,5` }, { name: 'XY Chart', type: 'xychart-beta', content: `xychart-beta title "Sales Revenue" x-axis [jan, feb, mar] y-axis "Revenue" 0 --> 10000 bar [5000, 6000, 7500]` }, { name: 'Block Diagram', type: 'block-beta', content: `block-beta columns 2 A B C` }, { name: 'Packet Diagram', type: 'packet-beta', content: `packet-beta 0-7: Header 8-15: Length 16-31: Data` }, { name: 'Architecture', type: 'architecture-beta', content: `architecture-beta group api(server)[API] group database[Database] api --> database` }, { name: 'Kanban', type: 'kanban', content: `kanban Todo Task 1 In Progress Task 2 Done Task 3` }, { name: 'C4 Context', type: 'C4Context', content: `C4Context title System Context Person(customer, "Customer", "A user of the system") System(banking_system, "Banking System", "Handles transactions") Rel(customer, banking_system, "Uses")` }, { name: 'Graph', type: 'graph', content: `graph TD A --> B B --> C` }, { name: 'Info', type: 'info', content: `info` }, { name: 'Radar Chart', type: 'radar', content: `radar title Skills "Skill A", 80 "Skill B", 60 "Skill C", 70` }, { name: 'Tree Map', type: 'treemap', content: `treemap-beta Root Branch1 Leaf1 Leaf2 Branch2 Leaf3` }, { name: 'Example Diagram', type: 'exampleDiagram', content: `example-diagram showInfo` } ]; /** * Make HTTP request */ function makeRequest(options, data) { return new Promise((resolve, reject) => { const req = http.request(options, (res) => { let body = ''; res.on('data', chunk => body += chunk); res.on('end', () => { try { const response = { statusCode: res.statusCode, headers: res.headers, body: body ? JSON.parse(body) : null }; resolve(response); } catch (error) { reject(new Error(`Failed to parse response: ${error.message}`)); } }); }); req.on('error', reject); if (data) { req.write(JSON.stringify(data)); } req.end(); }); } /** * Test single validation */ async function testSingleValidation(diagram) { const options = { hostname: API_HOST, port: API_PORT, path: '/api/v1/validate', method: 'POST', headers: { 'Content-Type': 'application/json' } }; const data = { diagrams: [{ content: diagram.content, type: diagram.type }], options: {} }; try { const response = await makeRequest(options, data); return { name: diagram.name, type: diagram.type, success: response.statusCode === 200 && response.body.validDiagrams === 1, statusCode: response.statusCode, valid: response.body?.results?.[0]?.valid, errors: response.body?.results?.[0]?.errors || [], processingTime: response.body?.processingTime }; } catch (error) { return { name: diagram.name, type: diagram.type, success: false, error: error.message }; } } /** * Test batch validation */ async function testBatchValidation() { log('\n=== Testing Batch Validation ===', COLORS.BLUE); const options = { hostname: API_HOST, port: API_PORT, path: '/api/v1/validate', method: 'POST', headers: { 'Content-Type': 'application/json' } }; const data = { diagrams: testCases.slice(0, 5).map(tc => ({ content: tc.content, type: tc.type })), options: {} }; try { const response = await makeRequest(options, data); if (response.statusCode === 200) { log(` ✓ Batch validation successful: ${response.body.validDiagrams}/${response.body.totalDiagrams} valid`, COLORS.GREEN); } else { log(` ✗ Batch validation failed with status ${response.statusCode}`, COLORS.RED); } } catch (error) { log(` ✗ Batch validation error: ${error.message}`, COLORS.RED); } } /** * Test health endpoint */ async function testHealthEndpoint() { log('\n=== Testing Health Endpoint ===', COLORS.BLUE); const options = { hostname: API_HOST, port: API_PORT, path: '/api/v1/health', method: 'GET' }; try { const response = await makeRequest(options); if (response.statusCode === 200 && (response.body.status === 'healthy' || response.body.status === 'degraded')) { log(` ✓ Health check passed (status: ${response.body.status})`, response.body.status === 'healthy' ? COLORS.GREEN : COLORS.YELLOW); return true; } else { log(` ✗ Health check failed: ${response.body?.status}`, COLORS.RED); return false; } } catch (error) { log(` ✗ Health check error: ${error.message}`, COLORS.RED); return false; } } /** * Main test runner */ async function main() { log('Validation Endpoints Test Suite', COLORS.BLUE); log('================================\n', COLORS.BLUE); // Check health first const healthy = await testHealthEndpoint(); if (!healthy) { log('\nServer is not healthy, exiting...', COLORS.RED); process.exit(1); } // Test individual validations log('\n=== Testing Individual Validations ===', COLORS.BLUE); const results = []; let successCount = 0; let failureCount = 0; for (const testCase of testCases) { process.stdout.write(`Testing ${testCase.name}... `); const result = await testSingleValidation(testCase); results.push(result); if (result.success) { log('✓', COLORS.GREEN); successCount++; } else { log(`✗ (${result.error || `Invalid: ${result.errors?.join(', ')}`})`, COLORS.RED); failureCount++; } } // Test batch validation await testBatchValidation(); // Summary log('\n=== Test Summary ===', COLORS.BLUE); log(`Total tests: ${testCases.length}`, COLORS.BLUE); log(`Passed: ${successCount}`, COLORS.GREEN); log(`Failed: ${failureCount}`, failureCount > 0 ? COLORS.RED : COLORS.GREEN); // Performance stats const avgTime = results .filter(r => r.processingTime) .reduce((sum, r) => sum + r.processingTime, 0) / results.length; log(`Average processing time: ${avgTime.toFixed(2)}ms`, COLORS.BLUE); // Exit code process.exit(failureCount > 0 ? 1 : 0); } // Run tests if (require.main === module) { main().catch(error => { log(`Fatal error: ${error.message}`, COLORS.RED); process.exit(1); }); } module.exports = { testSingleValidation, testBatchValidation, testHealthEndpoint };

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/ai-of-mine/fast-mermaid-validator-mcp'

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