update
This commit is contained in:
@ -0,0 +1,168 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import { promises as fs } from 'fs';
|
||||
import * as path from 'path';
|
||||
import { CorpusLoader } from '../../helpers/corpus.loader.js';
|
||||
import { PerformanceTracker } from '../../helpers/performance.tracker.js';
|
||||
|
||||
tap.test('FD-05: XRechnung Format Detection - should correctly identify XRechnung invoices', async () => {
|
||||
// Get potential XRechnung test files from UBL corpus
|
||||
const ublFiles = await CorpusLoader.getFiles('UBL_XMLRECHNUNG');
|
||||
const en16931UblFiles = await CorpusLoader.getFiles('EN16931_UBL_EXAMPLES');
|
||||
|
||||
// Filter for files that might be XRechnung (look for specific keywords)
|
||||
const allFiles = [...ublFiles, ...en16931UblFiles];
|
||||
const xrechnungFiles = allFiles.filter(f =>
|
||||
path.basename(f).toLowerCase().includes('xrechnung') ||
|
||||
path.basename(f).toLowerCase().includes('xr_') ||
|
||||
path.basename(f).toLowerCase().includes('de_')
|
||||
);
|
||||
|
||||
console.log(`Testing ${xrechnungFiles.length} potential XRechnung files`);
|
||||
|
||||
let successCount = 0;
|
||||
let failureCount = 0;
|
||||
const failures: { file: string; error: string }[] = [];
|
||||
|
||||
// Import the format detector
|
||||
const { FormatDetector } = await import('../../../ts/formats/utils/format.detector.js');
|
||||
|
||||
for (const filePath of xrechnungFiles.slice(0, 10)) { // Limit to first 10 for testing
|
||||
try {
|
||||
// Read XML content
|
||||
const xmlContent = await fs.readFile(filePath, 'utf-8');
|
||||
|
||||
// Track performance of format detection
|
||||
const { result: format } = await PerformanceTracker.track(
|
||||
'xrechnung-format-detection',
|
||||
async () => {
|
||||
return FormatDetector.detectFormat(xmlContent);
|
||||
},
|
||||
{ file: path.basename(filePath) }
|
||||
);
|
||||
|
||||
// Verify it's detected as XRechnung or UBL
|
||||
if (format.toString().toLowerCase().includes('xrechnung') ||
|
||||
format.toString().toLowerCase().includes('ubl')) {
|
||||
successCount++;
|
||||
} else {
|
||||
failureCount++;
|
||||
failures.push({
|
||||
file: path.basename(filePath),
|
||||
error: `Detected as ${format} instead of XRechnung/UBL`
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
failureCount++;
|
||||
failures.push({
|
||||
file: path.basename(filePath),
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Report results
|
||||
const totalTested = Math.min(xrechnungFiles.length, 10);
|
||||
console.log(`\nXRechnung Format Detection Results:`);
|
||||
console.log(`✓ Success: ${successCount}/${totalTested} (${(successCount/totalTested*100).toFixed(1)}%)`);
|
||||
console.log(`✗ Failed: ${failureCount}/${totalTested} (${(failureCount/totalTested*100).toFixed(1)}%)`);
|
||||
|
||||
if (failures.length > 0) {
|
||||
console.log(`\nFailures:`);
|
||||
failures.forEach(f => console.log(` - ${f.file}: ${f.error}`));
|
||||
}
|
||||
|
||||
// Performance summary
|
||||
const perfSummary = await PerformanceTracker.getSummary('xrechnung-format-detection');
|
||||
if (perfSummary) {
|
||||
console.log(`\nPerformance Summary:`);
|
||||
console.log(` Average: ${perfSummary.average.toFixed(2)}ms`);
|
||||
console.log(` Min: ${perfSummary.min.toFixed(2)}ms`);
|
||||
console.log(` Max: ${perfSummary.max.toFixed(2)}ms`);
|
||||
console.log(` P95: ${perfSummary.p95.toFixed(2)}ms`);
|
||||
}
|
||||
|
||||
// Expect reasonable success rate
|
||||
expect(successCount / totalTested).toBeGreaterThan(0.6);
|
||||
});
|
||||
|
||||
tap.test('FD-05: XRechnung CustomizationID Detection - should detect XRechnung by CustomizationID', async () => {
|
||||
const xrechnungCustomizations = [
|
||||
'urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_3.0',
|
||||
'urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.3',
|
||||
'urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.2'
|
||||
];
|
||||
|
||||
const { FormatDetector } = await import('../../../ts/formats/utils/format.detector.js');
|
||||
|
||||
for (const customization of xrechnungCustomizations) {
|
||||
const testXml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
|
||||
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
|
||||
<cbc:CustomizationID>${customization}</cbc:CustomizationID>
|
||||
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
|
||||
<cbc:ID>XR-001</cbc:ID>
|
||||
</Invoice>`;
|
||||
|
||||
const { result: format } = await PerformanceTracker.track(
|
||||
'xrechnung-customization-detection',
|
||||
async () => FormatDetector.detectFormat(testXml)
|
||||
);
|
||||
|
||||
console.log(`Customization ${customization.split(':').pop()}: Detected as ${format}`);
|
||||
|
||||
// Should detect as XRechnung or UBL
|
||||
const isXRechnungDetected = format.toString().toLowerCase().includes('xrechnung') ||
|
||||
format.toString().toLowerCase().includes('ubl');
|
||||
expect(isXRechnungDetected).toEqual(true);
|
||||
}
|
||||
});
|
||||
|
||||
tap.test('FD-05: XRechnung vs UBL Distinction - should distinguish XRechnung from generic UBL', async () => {
|
||||
const testCases = [
|
||||
{
|
||||
name: 'XRechnung Invoice',
|
||||
xml: `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
|
||||
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
|
||||
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_3.0</cbc:CustomizationID>
|
||||
<cbc:ID>XR-001</cbc:ID>
|
||||
</Invoice>`,
|
||||
shouldBeXRechnung: true
|
||||
},
|
||||
{
|
||||
name: 'Generic UBL Invoice',
|
||||
xml: `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
|
||||
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
|
||||
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
|
||||
<cbc:ID>UBL-001</cbc:ID>
|
||||
</Invoice>`,
|
||||
shouldBeXRechnung: false
|
||||
}
|
||||
];
|
||||
|
||||
const { FormatDetector } = await import('../../../ts/formats/utils/format.detector.js');
|
||||
|
||||
for (const testCase of testCases) {
|
||||
const { result: format } = await PerformanceTracker.track(
|
||||
'xrechnung-ubl-distinction',
|
||||
async () => FormatDetector.detectFormat(testCase.xml)
|
||||
);
|
||||
|
||||
console.log(`${testCase.name}: Detected as ${format}`);
|
||||
|
||||
const formatStr = format.toString().toLowerCase();
|
||||
const isXRechnung = formatStr.includes('xrechnung');
|
||||
|
||||
if (testCase.shouldBeXRechnung) {
|
||||
// Should be detected as XRechnung specifically
|
||||
expect(isXRechnung).toEqual(true);
|
||||
} else {
|
||||
// Can be UBL or XRechnung (since XRechnung is UBL-based)
|
||||
const isUBLFamily = formatStr.includes('ubl') || formatStr.includes('xrechnung');
|
||||
expect(isUBLFamily).toEqual(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tap.start();
|
Reference in New Issue
Block a user