multi-tool-validation.js•11.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);