import { tap, expect } from '@push.rocks/tapbundle'; import * as fs from 'fs/promises'; import * as path from 'path'; import { execSync } from 'child_process'; // Master test for corpus testing tap.test('Run all corpus tests', async () => { console.log('Running all corpus tests...'); // Create output directory const testDir = path.join(process.cwd(), 'test', 'output'); await fs.mkdir(testDir, { recursive: true }); // Run each test file and collect results const testFiles = [ 'test.zugferd-corpus.ts', 'test.xml-rechnung-corpus.ts', 'test.other-formats-corpus.ts', 'test.validation-corpus.ts', 'test.circular-corpus.ts' ]; const results: Record = {}; for (const testFile of testFiles) { console.log(`Running ${testFile}...`); try { // Run the test execSync(`tsx test/${testFile}`, { stdio: 'inherit' }); // Read the results const resultFile = testFile.replace('.ts', '-results.json'); const resultPath = path.join(testDir, resultFile); if (await fileExists(resultPath)) { const resultContent = await fs.readFile(resultPath, 'utf8'); results[testFile] = JSON.parse(resultContent); } else { results[testFile] = { error: 'No results file found' }; } } catch (error) { console.error(`Error running ${testFile}:`, error); results[testFile] = { error: error.message }; } } // Save the combined results await fs.writeFile( path.join(testDir, 'corpus-master-results.json'), JSON.stringify(results, null, 2) ); // Generate a summary report const summary = generateSummary(results); await fs.writeFile( path.join(testDir, 'corpus-summary.md'), summary ); console.log('All corpus tests completed.'); }); /** * Generates a summary report from the test results * @param results Test results * @returns Summary report in Markdown format */ function generateSummary(results: Record): string { let summary = '# XInvoice Corpus Testing Summary\n\n'; // Add date and time summary += `Generated on: ${new Date().toISOString()}\n\n`; // Add overall summary summary += '## Overall Summary\n\n'; summary += '| Test | Success Rate | Files Tested |\n'; summary += '|------|--------------|-------------|\n'; for (const [testFile, result] of Object.entries(results)) { if (result.error) { summary += `| ${testFile} | Error: ${result.error} | N/A |\n`; continue; } let successRate = 'N/A'; let filesTested = 'N/A'; if (testFile === 'test.zugferd-corpus.ts') { const rate = result.totalCorrectSuccessRate * 100; successRate = `${rate.toFixed(2)}%`; const v1Correct = result.zugferdV1Correct?.success + result.zugferdV1Correct?.fail || 0; const v1Fail = result.zugferdV1Fail?.success + result.zugferdV1Fail?.fail || 0; const v2Correct = result.zugferdV2Correct?.success + result.zugferdV2Correct?.fail || 0; const v2Fail = result.zugferdV2Fail?.success + result.zugferdV2Fail?.fail || 0; filesTested = `${v1Correct + v1Fail + v2Correct + v2Fail}`; } else if (testFile === 'test.xml-rechnung-corpus.ts') { const rate = result.totalSuccessRate * 100; successRate = `${rate.toFixed(2)}%`; const cii = result.cii?.success + result.cii?.fail || 0; const ubl = result.ubl?.success + result.ubl?.fail || 0; const fx = result.fx?.success + result.fx?.fail || 0; filesTested = `${cii + ubl + fx}`; } else if (testFile === 'test.other-formats-corpus.ts') { const rate = result.totalSuccessRate * 100; successRate = `${rate.toFixed(2)}%`; const peppol = result.peppol?.success + result.peppol?.fail || 0; const fatturapa = result.fatturapa?.success + result.fatturapa?.fail || 0; filesTested = `${peppol + fatturapa}`; } else if (testFile === 'test.validation-corpus.ts') { const rate = result.totalCorrectSuccessRate * 100; successRate = `${rate.toFixed(2)}%`; const zugferdV2Correct = result.zugferdV2Correct?.success + result.zugferdV2Correct?.fail || 0; const zugferdV2Fail = result.zugferdV2Fail?.success + result.zugferdV2Fail?.fail || 0; const cii = result.cii?.success + result.cii?.fail || 0; const ubl = result.ubl?.success + result.ubl?.fail || 0; filesTested = `${zugferdV2Correct + zugferdV2Fail + cii + ubl}`; } else if (testFile === 'test.circular-corpus.ts') { const rate = result.totalSuccessRate * 100; successRate = `${rate.toFixed(2)}%`; const cii = result.cii?.success + result.cii?.fail || 0; const ubl = result.ubl?.success + result.ubl?.fail || 0; filesTested = `${cii + ubl}`; } summary += `| ${testFile} | ${successRate} | ${filesTested} |\n`; } // Add detailed results for each test for (const [testFile, result] of Object.entries(results)) { if (result.error) { continue; } summary += `\n## ${testFile}\n\n`; if (testFile === 'test.zugferd-corpus.ts') { summary += '### ZUGFeRD v1 Correct Files\n\n'; summary += `Success: ${result.zugferdV1Correct?.success || 0}, Fail: ${result.zugferdV1Correct?.fail || 0}\n\n`; summary += '### ZUGFeRD v1 Fail Files\n\n'; summary += `Success: ${result.zugferdV1Fail?.success || 0}, Fail: ${result.zugferdV1Fail?.fail || 0}\n\n`; summary += '### ZUGFeRD v2 Correct Files\n\n'; summary += `Success: ${result.zugferdV2Correct?.success || 0}, Fail: ${result.zugferdV2Correct?.fail || 0}\n\n`; summary += '### ZUGFeRD v2 Fail Files\n\n'; summary += `Success: ${result.zugferdV2Fail?.success || 0}, Fail: ${result.zugferdV2Fail?.fail || 0}\n\n`; } else if (testFile === 'test.xml-rechnung-corpus.ts') { summary += '### CII Files\n\n'; summary += `Success: ${result.cii?.success || 0}, Fail: ${result.cii?.fail || 0}\n\n`; summary += '### UBL Files\n\n'; summary += `Success: ${result.ubl?.success || 0}, Fail: ${result.ubl?.fail || 0}\n\n`; summary += '### FX Files\n\n'; summary += `Success: ${result.fx?.success || 0}, Fail: ${result.fx?.fail || 0}\n\n`; } else if (testFile === 'test.other-formats-corpus.ts') { summary += '### PEPPOL Files\n\n'; summary += `Success: ${result.peppol?.success || 0}, Fail: ${result.peppol?.fail || 0}\n\n`; summary += '### fatturaPA Files\n\n'; summary += `Success: ${result.fatturapa?.success || 0}, Fail: ${result.fatturapa?.fail || 0}\n\n`; } else if (testFile === 'test.validation-corpus.ts') { summary += '### ZUGFeRD v2 Correct Files Validation\n\n'; summary += `Success: ${result.zugferdV2Correct?.success || 0}, Fail: ${result.zugferdV2Correct?.fail || 0}\n\n`; summary += '### ZUGFeRD v2 Fail Files Validation\n\n'; summary += `Success: ${result.zugferdV2Fail?.success || 0}, Fail: ${result.zugferdV2Fail?.fail || 0}\n\n`; summary += '### CII Files Validation\n\n'; summary += `Success: ${result.cii?.success || 0}, Fail: ${result.cii?.fail || 0}\n\n`; summary += '### UBL Files Validation\n\n'; summary += `Success: ${result.ubl?.success || 0}, Fail: ${result.ubl?.fail || 0}\n\n`; } else if (testFile === 'test.circular-corpus.ts') { summary += '### CII Files Circular Testing\n\n'; summary += `Success: ${result.cii?.success || 0}, Fail: ${result.cii?.fail || 0}\n\n`; summary += '### UBL Files Circular Testing\n\n'; summary += `Success: ${result.ubl?.success || 0}, Fail: ${result.ubl?.fail || 0}\n\n`; } } return summary; } /** * Checks if a file exists * @param filePath Path to the file * @returns True if the file exists */ async function fileExists(filePath: string): Promise { try { await fs.access(filePath); return true; } catch { return false; } } // Run the tests tap.start();