Skip to main content
Glama
multi-tool-validation.js11.7 kB
#!/usr/bin/env node /** * Multi-Tool Architecture Validation Tests * Tests each specialized tool in isolation to ensure proper functionality * @version 1.0.0 */ import { createLessonDataValidator } from '../src/tools/validate-lesson-data.js'; import { createComposerFormatter } from '../src/tools/format-for-composer.js'; // Test data samples const validLessonData = { metadata: { topic: "Sistema Solar - Exploração do Universo", duration: 50, learningObjectives: [ "Identificar os planetas do Sistema Solar", "Compreender as características dos planetas", "Conhecer curiosidades sobre astronomia" ], bnccAlignment: "EF06CI13, EF06CI14", subject: "Ciências", gradeLevel: "6º ano" }, widgets: [ { type: "head-1", content: { category: "Ciências - 6º ano", author_name: "Professor de Ciências", author_office: "Especialista em Astronomia" }, rationale: "Professional presentation for space science topic", educationalGoal: "Establish credibility and context" }, { type: "text-1", content: { text: "<h2>Bem-vindos ao Sistema Solar!</h2><p>Nosso sistema solar é formado pelo Sol e todos os objetos que orbitam ao seu redor, incluindo 8 planetas, luas, asteroides e cometas.</p>", title: "Introdução ao Sistema Solar" }, rationale: "Engaging introduction to capture student interest", educationalGoal: "Provide overview and context for the lesson" }, { type: "quiz-1", content: { title: "Quiz sobre Planetas", questions: [ { question: "Quantos planetas existem no Sistema Solar?", options: ["7", "8", "9", "10"], correct_option: 1, feedback: { correct: "Excelente! São 8 planetas desde 2006.", incorrect: "Tente novamente! Plutão foi reclassificado em 2006." } }, { question: "Qual é o maior planeta do Sistema Solar?", options: [ { text: "Terra", correct: false }, { text: "Júpiter", correct: true }, { text: "Saturno", correct: false }, { text: "Netuno", correct: false } ] } ], max_attempts: 2 }, rationale: "Assessment to validate understanding", educationalGoal: "Test knowledge of basic planetary facts" }, { type: "flashcards-1", content: { title: "Vocabulário Espacial", flashcards_items: [ { question: "O que é uma órbita?", answer: "O caminho que um objeto segue ao redor de outro no espaço" }, { question: "O que são asteroides?", answer: "Pequenos objetos rochosos que orbitam o Sol" } ] }, rationale: "Vocabulary reinforcement through active recall", educationalGoal: "Memorize key astronomical terms" } ], assessmentStrategy: "Quiz and flashcards provide formative assessment", widgetSelectionSummary: "Balanced approach with introduction, content, and assessment" }; const invalidLessonData = { metadata: { topic: "Too Short", // Should be 5-100 chars, this is too short duration: 200, // Should be 10-120 minutes learningObjectives: [] // Missing required content }, widgets: [ { type: "invalid-widget-type", // Invalid widget type content: { text: "Test" } }, { type: "quiz-1", content: { questions: [ { question: "Test?", // Too short (min 10 chars) options: ["A"], // Too few options (min 2) // Missing correct answer indication } ] } } ] }; class MultiToolValidator { constructor() { this.validator = createLessonDataValidator(); this.formatter = createComposerFormatter(); this.testResults = []; } async runAllTests() { console.error('\n=== MULTI-TOOL ARCHITECTURE VALIDATION ===\n'); // Test 1: Lesson Data Validator await this.testLessonDataValidator(); // Test 2: Composer Formatter await this.testComposerFormatter(); // Summary this.printSummary(); } async testLessonDataValidator() { console.error('🔍 Testing Lesson Data Validator...\n'); // Test 1.1: Valid lesson data try { console.error('Test 1.1: Valid lesson data validation'); const result = await this.validator.validateLessonData(validLessonData); if (result.success) { console.error('✅ PASS: Valid lesson data accepted'); console.error(` Widgets validated: ${result.data.widgetCount}`); console.error(` Validation summary: ${result.data.validationSummary}`); this.addTestResult('Validator - Valid Data', true); } else { console.error('❌ FAIL: Valid lesson data rejected'); console.error(' Errors:', result.error.details.slice(0, 3)); this.addTestResult('Validator - Valid Data', false); } } catch (error) { console.error('❌ FAIL: Validator threw exception:', error.message); this.addTestResult('Validator - Valid Data', false); } console.error(''); // Test 1.2: Invalid lesson data try { console.error('Test 1.2: Invalid lesson data validation'); const result = await this.validator.validateLessonData(invalidLessonData); if (!result.success && result.error.details.length > 0) { console.error('✅ PASS: Invalid lesson data properly rejected'); console.error(` Errors detected: ${result.error.details.length}`); console.error(' Sample errors:'); result.error.details.slice(0, 3).forEach(error => { console.error(` - ${error.type}: ${error.field} in ${error.location}`); }); this.addTestResult('Validator - Invalid Data', true); } else { console.error('❌ FAIL: Invalid lesson data incorrectly accepted'); this.addTestResult('Validator - Invalid Data', false); } } catch (error) { console.error('❌ FAIL: Validator threw exception:', error.message); this.addTestResult('Validator - Invalid Data', false); } console.error(''); // Test 1.3: Missing data try { console.error('Test 1.3: Missing lesson data'); const result = await this.validator.validateLessonData(null); if (!result.success) { console.error('✅ PASS: Missing data properly rejected'); this.addTestResult('Validator - Missing Data', true); } else { console.error('❌ FAIL: Missing data incorrectly accepted'); this.addTestResult('Validator - Missing Data', false); } } catch (error) { console.error('❌ FAIL: Validator threw exception:', error.message); this.addTestResult('Validator - Missing Data', false); } console.error(''); } async testComposerFormatter() { console.error('🎨 Testing Composer Formatter...\n'); // First validate the data for formatter input const validationResult = await this.validator.validateLessonData(validLessonData); if (!validationResult.success) { console.error('❌ SKIP: Cannot test formatter - validation failed'); this.addTestResult('Formatter - Valid Data', false); return; } const validatedData = validationResult.data.validatedLessonData; // Test 2.1: Valid data formatting try { console.error('Test 2.1: Valid data formatting'); const result = await this.formatter.formatForComposer(validatedData); if (result.success && result.data.composerJSON) { console.error('✅ PASS: Valid data formatted successfully'); console.error(` Widgets formatted: ${result.data.widgetCount}`); console.error(` Educational optimizations: ${result.data.educationalOptimizations.length}`); console.error(` Assets extracted: ${result.data.composerJSON.assets.length}`); // Validate composer JSON structure const composerJSON = result.data.composerJSON; if (composerJSON.uid && composerJSON.metadata && composerJSON.structure && composerJSON.assets) { console.error('✅ PASS: Composer JSON structure is valid'); this.addTestResult('Formatter - Valid Data', true); // Test specific widget formatting const hasHead1 = composerJSON.structure.some(w => w.type === 'head-1'); const hasQuiz = composerJSON.structure.some(w => w.type === 'quiz-1'); const hasFlashcards = composerJSON.structure.some(w => w.type === 'flashcards-1'); if (hasHead1 && hasQuiz && hasFlashcards) { console.error('✅ PASS: All widget types formatted correctly'); this.addTestResult('Formatter - Widget Types', true); } else { console.error('❌ FAIL: Some widget types missing or incorrectly formatted'); this.addTestResult('Formatter - Widget Types', false); } } else { console.error('❌ FAIL: Composer JSON structure incomplete'); this.addTestResult('Formatter - Valid Data', false); } } else { console.error('❌ FAIL: Valid data formatting failed'); console.error(' Error:', result.error?.message); this.addTestResult('Formatter - Valid Data', false); } } catch (error) { console.error('❌ FAIL: Formatter threw exception:', error.message); this.addTestResult('Formatter - Valid Data', false); } console.error(''); // Test 2.2: Missing data try { console.error('Test 2.2: Missing data formatting'); const result = await this.formatter.formatForComposer(null); if (!result.success) { console.error('✅ PASS: Missing data properly rejected'); this.addTestResult('Formatter - Missing Data', true); } else { console.error('❌ FAIL: Missing data incorrectly accepted'); this.addTestResult('Formatter - Missing Data', false); } } catch (error) { console.error('✅ PASS: Formatter properly threw exception for missing data'); this.addTestResult('Formatter - Missing Data', true); } console.error(''); } addTestResult(testName, passed) { this.testResults.push({ name: testName, passed }); } printSummary() { console.error('=== TEST SUMMARY ===\n'); const passed = this.testResults.filter(r => r.passed).length; const total = this.testResults.length; const percentage = Math.round((passed / total) * 100); console.error(`Total Tests: ${total}`); console.error(`Passed: ${passed}`); console.error(`Failed: ${total - passed}`); console.error(`Success Rate: ${percentage}%\n`); this.testResults.forEach(result => { const status = result.passed ? '✅' : '❌'; console.error(`${status} ${result.name}`); }); console.error(''); if (percentage >= 80) { console.error('🎉 OVERALL: Multi-tool architecture validation PASSED'); console.error(' Tools are ready for integration testing'); } else { console.error('⚠️ OVERALL: Multi-tool architecture validation FAILED'); console.error(' Review failed tests before proceeding'); } console.error(''); } } // Run validation tests const validator = new MultiToolValidator(); validator.runAllTests().catch(console.error);

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/rkm097git/euconquisto-composer-mcp-poc'

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