feat(tests): fully implemented test suite
This commit is contained in:
@ -0,0 +1,147 @@
|
||||
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
||||
import { EInvoice } from '../../../ts/index.js';
|
||||
import { InvoiceFormat, ValidationLevel } from '../../../ts/interfaces/common.js';
|
||||
import { CorpusLoader, PerformanceTracker } from '../../helpers/test-utils.js';
|
||||
|
||||
/**
|
||||
* Test ID: CORP-01
|
||||
* Test Description: XML-Rechnung Corpus Processing
|
||||
* Priority: High
|
||||
*
|
||||
* This test validates processing of all XML-Rechnung format files (both CII and UBL)
|
||||
* from the test corpus to ensure real-world compatibility.
|
||||
*/
|
||||
|
||||
tap.test('CORP-01: XML-Rechnung Corpus Processing - should process all XML-Rechnung files', async (t) => {
|
||||
// Load XML-Rechnung test files
|
||||
const ciiFiles = await CorpusLoader.loadCategory('XML_RECHNUNG_CII');
|
||||
const ublFiles = await CorpusLoader.loadCategory('XML_RECHNUNG_UBL');
|
||||
|
||||
const allFiles = [...ciiFiles, ...ublFiles];
|
||||
|
||||
console.log(`Testing ${allFiles.length} XML-Rechnung files`);
|
||||
console.log(` CII files: ${ciiFiles.length}`);
|
||||
console.log(` UBL files: ${ublFiles.length}`);
|
||||
|
||||
const results = {
|
||||
total: allFiles.length,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
parseErrors: 0,
|
||||
validationErrors: 0,
|
||||
conversionErrors: 0,
|
||||
processingTimes: [] as number[]
|
||||
};
|
||||
|
||||
const failures: Array<{
|
||||
file: string;
|
||||
error: string;
|
||||
stage: 'parse' | 'validate' | 'convert';
|
||||
}> = [];
|
||||
|
||||
for (const file of allFiles) {
|
||||
try {
|
||||
const xmlBuffer = await CorpusLoader.loadFile(file.path);
|
||||
const xmlString = xmlBuffer.toString('utf-8');
|
||||
|
||||
// Track performance
|
||||
const { result: invoice, metric } = await PerformanceTracker.track(
|
||||
'xml-rechnung-processing',
|
||||
async () => {
|
||||
const einvoice = new EInvoice();
|
||||
await einvoice.fromXmlString(xmlString);
|
||||
return einvoice;
|
||||
},
|
||||
{ file: file.path, size: file.size }
|
||||
);
|
||||
|
||||
results.processingTimes.push(metric.duration);
|
||||
|
||||
// Validate the parsed invoice
|
||||
try {
|
||||
const validationResult = await invoice.validate(ValidationLevel.EXTENDED);
|
||||
|
||||
if (validationResult.valid) {
|
||||
results.successful++;
|
||||
t.pass(`✓ ${file.path}: Successfully processed and validated`);
|
||||
} else {
|
||||
results.validationErrors++;
|
||||
failures.push({
|
||||
file: file.path,
|
||||
error: `Validation failed: ${validationResult.errors?.[0]?.message || 'Unknown error'}`,
|
||||
stage: 'validate'
|
||||
});
|
||||
t.fail(`✗ ${file.path}: Validation failed`);
|
||||
}
|
||||
} catch (validationError: any) {
|
||||
results.validationErrors++;
|
||||
failures.push({
|
||||
file: file.path,
|
||||
error: validationError.message,
|
||||
stage: 'validate'
|
||||
});
|
||||
}
|
||||
|
||||
// Test format conversion
|
||||
try {
|
||||
const targetFormat = file.path.includes('.cii.') ? 'ubl' : 'cii';
|
||||
const converted = await invoice.toXmlString(targetFormat as any);
|
||||
|
||||
if (converted) {
|
||||
t.pass(`✓ ${file.path}: Successfully converted to ${targetFormat}`);
|
||||
}
|
||||
} catch (conversionError: any) {
|
||||
results.conversionErrors++;
|
||||
failures.push({
|
||||
file: file.path,
|
||||
error: conversionError.message,
|
||||
stage: 'convert'
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error: any) {
|
||||
results.failed++;
|
||||
results.parseErrors++;
|
||||
failures.push({
|
||||
file: file.path,
|
||||
error: error.message,
|
||||
stage: 'parse'
|
||||
});
|
||||
t.fail(`✗ ${file.path}: Failed to parse`);
|
||||
}
|
||||
}
|
||||
|
||||
// Summary report
|
||||
console.log('\n=== XML-Rechnung Corpus Processing Summary ===');
|
||||
console.log(`Total files: ${results.total}`);
|
||||
console.log(`Successful: ${results.successful} (${(results.successful/results.total*100).toFixed(1)}%)`);
|
||||
console.log(`Failed: ${results.failed}`);
|
||||
console.log(` - Parse errors: ${results.parseErrors}`);
|
||||
console.log(` - Validation errors: ${results.validationErrors}`);
|
||||
console.log(` - Conversion errors: ${results.conversionErrors}`);
|
||||
|
||||
if (failures.length > 0) {
|
||||
console.log('\nFailure Details (first 10):');
|
||||
failures.slice(0, 10).forEach(f => {
|
||||
console.log(` ${f.file} [${f.stage}]: ${f.error}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Performance metrics
|
||||
if (results.processingTimes.length > 0) {
|
||||
const avgTime = results.processingTimes.reduce((a, b) => a + b, 0) / results.processingTimes.length;
|
||||
const maxTime = Math.max(...results.processingTimes);
|
||||
const minTime = Math.min(...results.processingTimes);
|
||||
|
||||
console.log('\nPerformance Metrics:');
|
||||
console.log(` Average processing time: ${avgTime.toFixed(2)}ms`);
|
||||
console.log(` Min time: ${minTime.toFixed(2)}ms`);
|
||||
console.log(` Max time: ${maxTime.toFixed(2)}ms`);
|
||||
}
|
||||
|
||||
// Success criteria: at least 90% should pass
|
||||
const successRate = results.successful / results.total;
|
||||
expect(successRate).toBeGreaterThan(0.9);
|
||||
});
|
||||
|
||||
tap.start();
|
Reference in New Issue
Block a user