fix(compliance): improve compliance

This commit is contained in:
2025-05-30 04:29:13 +00:00
parent 960bbc2208
commit 0ba55dcb60
14 changed files with 1270 additions and 1095 deletions

View File

@ -1,8 +1,8 @@
import { tap, expect } from '@git.zone/tstest/tapbundle';
import * as plugins from '../../../ts/plugins.ts';
import { EInvoice } from '../../../ts/classes.xinvoice.ts';
import { CorpusLoader } from '../../helpers/corpus.loader.ts';
import { PerformanceTracker } from '../../helpers/performance.tracker.ts';
import * as plugins from '../../../ts/plugins.js';
import { EInvoice } from '../../../ts/index.js';
import { CorpusLoader } from '../../helpers/corpus.loader.js';
import { PerformanceTracker } from '../../helpers/performance.tracker.js';
const testTimeout = 300000; // 5 minutes timeout for corpus processing
@ -76,9 +76,9 @@ tap.test('VAL-13: Error Reporting - Error Message Quality', async (tools) => {
// Expect validation to fail
if (validationResult && validationResult.valid) {
tools.log(`⚠ Expected validation to fail for ${testCase.name} but it passed`);
console.log(`⚠ Expected validation to fail for ${testCase.name} but it passed`);
} else {
tools.log(`${testCase.name}: Validation correctly failed`);
console.log(`${testCase.name}: Validation correctly failed`);
// Check error quality if errors are available
if (validationResult?.errors && validationResult.errors.length > 0) {
@ -89,14 +89,14 @@ tap.test('VAL-13: Error Reporting - Error Message Quality', async (tools) => {
expect(error.message).toBeTruthy();
expect(error.message.length).toBeGreaterThan(10); // Should be descriptive
tools.log(` Error: ${error.message}`);
console.log(` Error: ${error.message}`);
// Check if error message contains relevant context
if (testCase.expectedFieldName) {
const containsFieldName = error.message.toLowerCase().includes(testCase.expectedFieldName.toLowerCase()) ||
error.path?.includes(testCase.expectedFieldName);
if (containsFieldName) {
tools.log(` ✓ Error message includes field name: ${testCase.expectedFieldName}`);
console.log(` ✓ Error message includes field name: ${testCase.expectedFieldName}`);
}
}
}
@ -105,14 +105,14 @@ tap.test('VAL-13: Error Reporting - Error Message Quality', async (tools) => {
} catch (parseError) {
// Parse errors are also valid for testing error reporting
tools.log(`${testCase.name}: Parse error caught: ${parseError.message}`);
console.log(`${testCase.name}: Parse error caught: ${parseError.message}`);
expect(parseError.message).toBeTruthy();
expect(parseError.message.length).toBeGreaterThan(5);
}
}
const duration = Date.now() - startTime;
PerformanceTracker.recordMetric('error-reporting-message-quality', duration);
// PerformanceTracker.recordMetric('error-reporting-message-quality', duration);
});
tap.test('VAL-13: Error Reporting - Error Code Classification', async (tools) => {
@ -175,7 +175,7 @@ tap.test('VAL-13: Error Reporting - Error Code Classification', async (tools) =>
} catch (parseError) {
// Handle syntax errors at parse level
if (test.expectedCategory === 'syntax') {
tools.log(`${test.name}: Syntax error correctly detected at parse time`);
console.log(`${test.name}: Syntax error correctly detected at parse time`);
expect(parseError.message).toBeTruthy();
continue;
} else {
@ -187,41 +187,41 @@ tap.test('VAL-13: Error Reporting - Error Code Classification', async (tools) =>
const validationResult = await invoice.validate();
if (validationResult && !validationResult.valid && validationResult.errors) {
tools.log(`${test.name}: Validation errors detected`);
console.log(`${test.name}: Validation errors detected`);
for (const error of validationResult.errors) {
tools.log(` Error: ${error.message}`);
console.log(` Error: ${error.message}`);
// Check error classification properties
if (error.code) {
tools.log(` Code: ${error.code}`);
console.log(` Code: ${error.code}`);
}
if (error.severity) {
tools.log(` Severity: ${error.severity}`);
console.log(` Severity: ${error.severity}`);
expect(['error', 'warning', 'info']).toContain(error.severity);
}
if (error.category) {
tools.log(` Category: ${error.category}`);
console.log(` Category: ${error.category}`);
}
if (error.path) {
tools.log(` Path: ${error.path}`);
console.log(` Path: ${error.path}`);
}
}
} else if (test.expectedCategory !== 'format') {
tools.log(`⚠ Expected validation errors for ${test.name} but validation passed`);
console.log(`⚠ Expected validation errors for ${test.name} but validation passed`);
}
}
} catch (error) {
tools.log(`Error processing ${test.name}: ${error.message}`);
console.log(`Error processing ${test.name}: ${error.message}`);
}
}
const duration = Date.now() - startTime;
PerformanceTracker.recordMetric('error-reporting-classification', duration);
// PerformanceTracker.recordMetric('error-reporting-classification', duration);
});
tap.test('VAL-13: Error Reporting - Error Context and Location', async (tools) => {
@ -262,49 +262,49 @@ tap.test('VAL-13: Error Reporting - Error Context and Location', async (tools) =
const validationResult = await invoice.validate();
if (validationResult && !validationResult.valid && validationResult.errors) {
tools.log(`Error context testing - found ${validationResult.errors.length} errors:`);
console.log(`Error context testing - found ${validationResult.errors.length} errors:`);
for (const error of validationResult.errors) {
tools.log(`\nError: ${error.message}`);
console.log(`\nError: ${error.message}`);
// Check for location information
if (error.path) {
tools.log(` XPath/Path: ${error.path}`);
console.log(` XPath/Path: ${error.path}`);
expect(error.path).toBeTruthy();
}
if (error.lineNumber) {
tools.log(` Line: ${error.lineNumber}`);
console.log(` Line: ${error.lineNumber}`);
expect(error.lineNumber).toBeGreaterThan(0);
}
if (error.columnNumber) {
tools.log(` Column: ${error.columnNumber}`);
console.log(` Column: ${error.columnNumber}`);
expect(error.columnNumber).toBeGreaterThan(0);
}
// Check for additional context
if (error.context) {
tools.log(` Context: ${JSON.stringify(error.context)}`);
console.log(` Context: ${JSON.stringify(error.context)}`);
}
if (error.element) {
tools.log(` Element: ${error.element}`);
console.log(` Element: ${error.element}`);
}
}
tools.log(`✓ Error context information available`);
console.log(`✓ Error context information available`);
} else {
tools.log(`⚠ Expected validation errors but validation passed`);
console.log(`⚠ Expected validation errors but validation passed`);
}
}
} catch (error) {
tools.log(`Context test failed: ${error.message}`);
console.log(`Context test failed: ${error.message}`);
}
const duration = Date.now() - startTime;
PerformanceTracker.recordMetric('error-reporting-context', duration);
// PerformanceTracker.recordMetric('error-reporting-context', duration);
});
tap.test('VAL-13: Error Reporting - Error Aggregation and Summarization', async (tools) => {
@ -350,7 +350,7 @@ tap.test('VAL-13: Error Reporting - Error Aggregation and Summarization', async
if (validationResult && !validationResult.valid && validationResult.errors) {
const errors = validationResult.errors;
tools.log(`Error aggregation test - found ${errors.length} errors:`);
console.log(`Error aggregation test - found ${errors.length} errors:`);
// Group errors by category
const errorsByCategory = {};
@ -365,24 +365,24 @@ tap.test('VAL-13: Error Reporting - Error Aggregation and Summarization', async
const severity = error.severity || 'error';
errorsBySeverity[severity] = (errorsBySeverity[severity] || 0) + 1;
tools.log(` - ${error.message}`);
console.log(` - ${error.message}`);
if (error.path) {
tools.log(` Path: ${error.path}`);
console.log(` Path: ${error.path}`);
}
}
// Display error summary
tools.log(`\nError Summary:`);
tools.log(` Total errors: ${errors.length}`);
console.log(`\nError Summary:`);
console.log(` Total errors: ${errors.length}`);
tools.log(` By category:`);
console.log(` By category:`);
for (const [category, count] of Object.entries(errorsByCategory)) {
tools.log(` ${category}: ${count}`);
console.log(` ${category}: ${count}`);
}
tools.log(` By severity:`);
console.log(` By severity:`);
for (const [severity, count] of Object.entries(errorsBySeverity)) {
tools.log(` ${severity}: ${count}`);
console.log(` ${severity}: ${count}`);
}
// Expect multiple errors to be found
@ -394,16 +394,16 @@ tap.test('VAL-13: Error Reporting - Error Aggregation and Summarization', async
expect(typeof error.message).toBe('string');
}
tools.log(`✓ Error aggregation and categorization working`);
console.log(`✓ Error aggregation and categorization working`);
}
}
} catch (error) {
tools.log(`Error aggregation test failed: ${error.message}`);
console.log(`Error aggregation test failed: ${error.message}`);
}
const duration = Date.now() - startTime;
PerformanceTracker.recordMetric('error-reporting-aggregation', duration);
// PerformanceTracker.recordMetric('error-reporting-aggregation', duration);
});
tap.test('VAL-13: Error Reporting - Localized Error Messages', async (tools) => {
@ -427,9 +427,9 @@ tap.test('VAL-13: Error Reporting - Localized Error Messages', async (tools) =>
// Set locale if the API supports it
if (typeof invoice.setLocale === 'function') {
invoice.setLocale(locale);
tools.log(`Testing error messages in locale: ${locale}`);
console.log(`Testing error messages in locale: ${locale}`);
} else {
tools.log(`Locale setting not supported, testing default messages`);
console.log(`Locale setting not supported, testing default messages`);
}
const parseResult = await invoice.fromXmlString(localizationTestXml);
@ -439,7 +439,7 @@ tap.test('VAL-13: Error Reporting - Localized Error Messages', async (tools) =>
if (validationResult && !validationResult.valid && validationResult.errors) {
for (const error of validationResult.errors) {
tools.log(` ${locale}: ${error.message}`);
console.log(` ${locale}: ${error.message}`);
// Check that error message is not empty and reasonably descriptive
expect(error.message).toBeTruthy();
@ -447,21 +447,21 @@ tap.test('VAL-13: Error Reporting - Localized Error Messages', async (tools) =>
// Check for locale-specific characteristics (if implemented)
if (locale === 'de' && error.message.includes('ungültig')) {
tools.log(` ✓ German localization detected`);
console.log(` ✓ German localization detected`);
} else if (locale === 'fr' && error.message.includes('invalide')) {
tools.log(` ✓ French localization detected`);
console.log(` ✓ French localization detected`);
}
}
}
}
} catch (error) {
tools.log(`Localization test failed for ${locale}: ${error.message}`);
console.log(`Localization test failed for ${locale}: ${error.message}`);
}
}
const duration = Date.now() - startTime;
PerformanceTracker.recordMetric('error-reporting-localization', duration);
// PerformanceTracker.recordMetric('error-reporting-localization', duration);
});
tap.test('VAL-13: Error Reporting - Corpus Error Analysis', { timeout: testTimeout }, async (tools) => {
@ -517,33 +517,33 @@ tap.test('VAL-13: Error Reporting - Corpus Error Analysis', { timeout: testTimeo
} catch (error) {
errorStatistics.filesWithErrors++;
errorStatistics.totalErrors++;
tools.log(`Parse error in ${plugins.path.basename(filePath)}: ${error.message}`);
console.log(`Parse error in ${plugins.path.basename(filePath)}: ${error.message}`);
}
}
} catch (error) {
tools.log(`Failed to process category ${category}: ${error.message}`);
console.log(`Failed to process category ${category}: ${error.message}`);
}
}
// Display error analysis results
tools.log(`\n=== Corpus Error Analysis ===`);
tools.log(`Total files analyzed: ${errorStatistics.totalFiles}`);
tools.log(`Files with errors: ${errorStatistics.filesWithErrors} (${(errorStatistics.filesWithErrors / errorStatistics.totalFiles * 100).toFixed(1)}%)`);
tools.log(`Total errors found: ${errorStatistics.totalErrors}`);
tools.log(`Average errors per file: ${(errorStatistics.totalErrors / errorStatistics.totalFiles).toFixed(1)}`);
console.log(`\n=== Corpus Error Analysis ===`);
console.log(`Total files analyzed: ${errorStatistics.totalFiles}`);
console.log(`Files with errors: ${errorStatistics.filesWithErrors} (${(errorStatistics.filesWithErrors / errorStatistics.totalFiles * 100).toFixed(1)}%)`);
console.log(`Total errors found: ${errorStatistics.totalErrors}`);
console.log(`Average errors per file: ${(errorStatistics.totalErrors / errorStatistics.totalFiles).toFixed(1)}`);
if (Object.keys(errorStatistics.errorsByCategory).length > 0) {
tools.log(`\nErrors by category:`);
console.log(`\nErrors by category:`);
for (const [category, count] of Object.entries(errorStatistics.errorsByCategory)) {
tools.log(` ${category}: ${count}`);
console.log(` ${category}: ${count}`);
}
}
if (Object.keys(errorStatistics.errorsBySeverity).length > 0) {
tools.log(`\nErrors by severity:`);
console.log(`\nErrors by severity:`);
for (const [severity, count] of Object.entries(errorStatistics.errorsBySeverity)) {
tools.log(` ${severity}: ${count}`);
console.log(` ${severity}: ${count}`);
}
}
@ -553,9 +553,9 @@ tap.test('VAL-13: Error Reporting - Corpus Error Analysis', { timeout: testTimeo
.slice(0, 5);
if (commonErrors.length > 0) {
tools.log(`\nMost common errors:`);
console.log(`\nMost common errors:`);
for (const [errorKey, count] of commonErrors) {
tools.log(` ${count}x: ${errorKey}`);
console.log(` ${count}x: ${errorKey}`);
}
}
@ -563,15 +563,15 @@ tap.test('VAL-13: Error Reporting - Corpus Error Analysis', { timeout: testTimeo
expect(errorStatistics.totalFiles).toBeGreaterThan(0);
} catch (error) {
tools.log(`Corpus error analysis failed: ${error.message}`);
console.log(`Corpus error analysis failed: ${error.message}`);
throw error;
}
const totalDuration = Date.now() - startTime;
PerformanceTracker.recordMetric('error-reporting-corpus', totalDuration);
// PerformanceTracker.recordMetric('error-reporting-corpus', totalDuration);
expect(totalDuration).toBeLessThan(120000); // 2 minutes max
tools.log(`Error analysis completed in ${totalDuration}ms`);
console.log(`Error analysis completed in ${totalDuration}ms`);
});
tap.test('VAL-13: Performance Summary', async (tools) => {
@ -584,15 +584,21 @@ tap.test('VAL-13: Performance Summary', async (tools) => {
'error-reporting-corpus'
];
tools.log(`\n=== Error Reporting Performance Summary ===`);
console.log(`\n=== Error Reporting Performance Summary ===`);
for (const operation of operations) {
const summary = await PerformanceTracker.getSummary(operation);
if (summary) {
tools.log(`${operation}:`);
tools.log(` avg=${summary.average}ms, min=${summary.min}ms, max=${summary.max}ms, p95=${summary.p95}ms`);
console.log(`${operation}:`);
console.log(` avg=${summary.average}ms, min=${summary.min}ms, max=${summary.max}ms, p95=${summary.p95}ms`);
}
}
tools.log(`\nError reporting testing completed successfully.`);
});
console.log(`\nError reporting testing completed successfully.`);
});
// Start the test
tap.start();
// Export for test runner compatibility
export default tap;