2025-05-25 19:45:37 +00:00
import { tap , expect } from '@git.zone/tstest/tapbundle' ;
2025-05-30 04:29:13 +00:00
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' ;
2025-05-25 19:45:37 +00:00
const testTimeout = 300000 ; // 5 minutes timeout for corpus processing
// VAL-13: Validation Error Reporting
// Tests validation error reporting functionality including error messages,
// error codes, error context, and error aggregation
tap . test ( 'VAL-13: Error Reporting - Error Message Quality' , async ( tools ) = > {
const startTime = Date . now ( ) ;
// Test validation errors with clear, actionable messages
const errorTestCases = [
{
name : 'Missing Required Field' ,
xml : ` <?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<IssueDate>2024-01-01</IssueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
</Invoice> ` ,
expectedErrorType : 'missing-required-field' ,
expectedFieldName : 'ID'
} ,
{
name : 'Invalid Date Format' ,
xml : ` <?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<ID>TEST-001</ID>
<IssueDate>31-01-2024</IssueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
</Invoice> ` ,
expectedErrorType : 'invalid-date-format' ,
expectedFieldName : 'IssueDate'
} ,
{
name : 'Invalid Currency Code' ,
xml : ` <?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<ID>TEST-001</ID>
<IssueDate>2024-01-01</IssueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
<DocumentCurrencyCode>INVALID</DocumentCurrencyCode>
</Invoice> ` ,
expectedErrorType : 'invalid-currency-code' ,
expectedFieldName : 'DocumentCurrencyCode'
} ,
{
name : 'Invalid Numeric Value' ,
xml : ` <?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<ID>TEST-001</ID>
<IssueDate>2024-01-01</IssueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
<LegalMonetaryTotal>
<PayableAmount currencyID="EUR">NOT_A_NUMBER</PayableAmount>
</LegalMonetaryTotal>
</Invoice> ` ,
expectedErrorType : 'invalid-numeric-value' ,
expectedFieldName : 'PayableAmount'
}
] ;
for ( const testCase of errorTestCases ) {
try {
const invoice = new EInvoice ( ) ;
const parseResult = await invoice . fromXmlString ( testCase . xml ) ;
let validationResult ;
if ( parseResult ) {
validationResult = await invoice . validate ( ) ;
}
// Expect validation to fail
if ( validationResult && validationResult . valid ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ⚠ Expected validation to fail for ${ testCase . name } but it passed ` ) ;
2025-05-25 19:45:37 +00:00
} else {
2025-05-30 04:29:13 +00:00
console . log ( ` ✓ ${ testCase . name } : Validation correctly failed ` ) ;
2025-05-25 19:45:37 +00:00
// Check error quality if errors are available
if ( validationResult ? . errors && validationResult . errors . length > 0 ) {
const errors = validationResult . errors ;
// Check for descriptive error messages
for ( const error of errors ) {
expect ( error . message ) . toBeTruthy ( ) ;
expect ( error . message . length ) . toBeGreaterThan ( 10 ) ; // Should be descriptive
2025-05-30 04:29:13 +00:00
console . log ( ` Error: ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
// 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 ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ✓ Error message includes field name: ${ testCase . expectedFieldName } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
}
}
}
} catch ( parseError ) {
// Parse errors are also valid for testing error reporting
2025-05-30 04:29:13 +00:00
console . log ( ` ✓ ${ testCase . name } : Parse error caught: ${ parseError . message } ` ) ;
2025-05-25 19:45:37 +00:00
expect ( parseError . message ) . toBeTruthy ( ) ;
expect ( parseError . message . length ) . toBeGreaterThan ( 5 ) ;
}
}
const duration = Date . now ( ) - startTime ;
2025-05-30 04:29:13 +00:00
// PerformanceTracker.recordMetric('error-reporting-message-quality', duration);
2025-05-25 19:45:37 +00:00
} ) ;
tap . test ( 'VAL-13: Error Reporting - Error Code Classification' , async ( tools ) = > {
const startTime = Date . now ( ) ;
// Test error classification and categorization
const errorClassificationTests = [
{
name : 'Syntax Error' ,
xml : ` <?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<ID>TEST-001</ID>
<IssueDate>2024-01-01</IssueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
<UnclosedTag>
</Invoice> ` ,
expectedCategory : 'syntax' ,
expectedSeverity : 'error'
} ,
{
name : 'Business Rule Violation' ,
xml : ` <?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<ID>TEST-001</ID>
<IssueDate>2024-01-01</IssueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
<TaxTotal>
<TaxAmount currencyID="EUR">20.00</TaxAmount>
<TaxSubtotal>
<TaxableAmount currencyID="EUR">100.00</TaxableAmount>
<TaxAmount currencyID="EUR">19.00</TaxAmount>
<TaxCategory><Percent>19.00</Percent></TaxCategory>
</TaxSubtotal>
</TaxTotal>
</Invoice> ` ,
expectedCategory : 'business-rule' ,
expectedSeverity : 'error'
} ,
{
name : 'Format Warning' ,
xml : ` <?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<ID>TEST-001</ID>
<IssueDate>2024-01-01</IssueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
<Note>This is a very long note that exceeds recommended character limits for invoice notes and should trigger a warning about readability and processing efficiency in some systems</Note>
</Invoice> ` ,
expectedCategory : 'format' ,
expectedSeverity : 'warning'
}
] ;
for ( const test of errorClassificationTests ) {
try {
const invoice = new EInvoice ( ) ;
let parseResult ;
try {
parseResult = await invoice . fromXmlString ( test . xml ) ;
} catch ( parseError ) {
// Handle syntax errors at parse level
if ( test . expectedCategory === 'syntax' ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ✓ ${ test . name } : Syntax error correctly detected at parse time ` ) ;
2025-05-25 19:45:37 +00:00
expect ( parseError . message ) . toBeTruthy ( ) ;
continue ;
} else {
throw parseError ;
}
}
if ( parseResult ) {
const validationResult = await invoice . validate ( ) ;
if ( validationResult && ! validationResult . valid && validationResult . errors ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ✓ ${ test . name } : Validation errors detected ` ) ;
2025-05-25 19:45:37 +00:00
for ( const error of validationResult . errors ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Error: ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
// Check error classification properties
if ( error . code ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Code: ${ error . code } ` ) ;
2025-05-25 19:45:37 +00:00
}
if ( error . severity ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Severity: ${ error . severity } ` ) ;
2025-05-25 19:45:37 +00:00
expect ( [ 'error' , 'warning' , 'info' ] ) . toContain ( error . severity ) ;
}
if ( error . category ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Category: ${ error . category } ` ) ;
2025-05-25 19:45:37 +00:00
}
if ( error . path ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Path: ${ error . path } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
} else if ( test . expectedCategory !== 'format' ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ⚠ Expected validation errors for ${ test . name } but validation passed ` ) ;
2025-05-25 19:45:37 +00:00
}
}
} catch ( error ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Error processing ${ test . name } : ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
const duration = Date . now ( ) - startTime ;
2025-05-30 04:29:13 +00:00
// PerformanceTracker.recordMetric('error-reporting-classification', duration);
2025-05-25 19:45:37 +00:00
} ) ;
tap . test ( 'VAL-13: Error Reporting - Error Context and Location' , async ( tools ) = > {
const startTime = Date . now ( ) ;
// Test error context information (line numbers, XPath, etc.)
const contextTestXml = ` <?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<ID>CONTEXT-TEST-001</ID>
<IssueDate>2024-01-01</IssueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
<DocumentCurrencyCode>EUR</DocumentCurrencyCode>
<AccountingSupplierParty>
<Party>
<PartyName>
<Name></Name>
</PartyName>
<PostalAddress>
<StreetName>Test Street</StreetName>
<CityName></CityName>
<PostalZone>12345</PostalZone>
<Country>
<IdentificationCode>DE</IdentificationCode>
</Country>
</PostalAddress>
</Party>
</AccountingSupplierParty>
<LegalMonetaryTotal>
<PayableAmount currencyID="EUR">INVALID_AMOUNT</PayableAmount>
</LegalMonetaryTotal>
</Invoice> ` ;
try {
const invoice = new EInvoice ( ) ;
const parseResult = await invoice . fromXmlString ( contextTestXml ) ;
if ( parseResult ) {
const validationResult = await invoice . validate ( ) ;
if ( validationResult && ! validationResult . valid && validationResult . errors ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Error context testing - found ${ validationResult . errors . length } errors: ` ) ;
2025-05-25 19:45:37 +00:00
for ( const error of validationResult . errors ) {
2025-05-30 04:29:13 +00:00
console . log ( ` \ nError: ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
// Check for location information
if ( error . path ) {
2025-05-30 04:29:13 +00:00
console . log ( ` XPath/Path: ${ error . path } ` ) ;
2025-05-25 19:45:37 +00:00
expect ( error . path ) . toBeTruthy ( ) ;
}
if ( error . lineNumber ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Line: ${ error . lineNumber } ` ) ;
2025-05-25 19:45:37 +00:00
expect ( error . lineNumber ) . toBeGreaterThan ( 0 ) ;
}
if ( error . columnNumber ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Column: ${ error . columnNumber } ` ) ;
2025-05-25 19:45:37 +00:00
expect ( error . columnNumber ) . toBeGreaterThan ( 0 ) ;
}
// Check for additional context
if ( error . context ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Context: ${ JSON . stringify ( error . context ) } ` ) ;
2025-05-25 19:45:37 +00:00
}
if ( error . element ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Element: ${ error . element } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
2025-05-30 04:29:13 +00:00
console . log ( ` ✓ Error context information available ` ) ;
2025-05-25 19:45:37 +00:00
} else {
2025-05-30 04:29:13 +00:00
console . log ( ` ⚠ Expected validation errors but validation passed ` ) ;
2025-05-25 19:45:37 +00:00
}
}
} catch ( error ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Context test failed: ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
}
const duration = Date . now ( ) - startTime ;
2025-05-30 04:29:13 +00:00
// PerformanceTracker.recordMetric('error-reporting-context', duration);
2025-05-25 19:45:37 +00:00
} ) ;
tap . test ( 'VAL-13: Error Reporting - Error Aggregation and Summarization' , async ( tools ) = > {
const startTime = Date . now ( ) ;
// Test error aggregation for multiple issues
const multiErrorXml = ` <?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<ID></ID>
<IssueDate>invalid-date</IssueDate>
<InvoiceTypeCode>999</InvoiceTypeCode>
<DocumentCurrencyCode>INVALID</DocumentCurrencyCode>
<AccountingSupplierParty>
<Party>
<PartyName>
<Name></Name>
</PartyName>
</Party>
</AccountingSupplierParty>
<AccountingCustomerParty>
<Party>
<PartyName>
<Name></Name>
</PartyName>
</Party>
</AccountingCustomerParty>
<InvoiceLine>
<ID></ID>
<InvoicedQuantity unitCode="">0</InvoicedQuantity>
<LineExtensionAmount currencyID="EUR">invalid-amount</LineExtensionAmount>
</InvoiceLine>
<LegalMonetaryTotal>
<PayableAmount currencyID="EUR">another-invalid-amount</PayableAmount>
</LegalMonetaryTotal>
</Invoice> ` ;
try {
const invoice = new EInvoice ( ) ;
const parseResult = await invoice . fromXmlString ( multiErrorXml ) ;
if ( parseResult ) {
const validationResult = await invoice . validate ( ) ;
if ( validationResult && ! validationResult . valid && validationResult . errors ) {
const errors = validationResult . errors ;
2025-05-30 04:29:13 +00:00
console . log ( ` Error aggregation test - found ${ errors . length } errors: ` ) ;
2025-05-25 19:45:37 +00:00
// Group errors by category
const errorsByCategory = { } ;
const errorsBySeverity = { } ;
for ( const error of errors ) {
// Count by category
const category = error . category || 'unknown' ;
errorsByCategory [ category ] = ( errorsByCategory [ category ] || 0 ) + 1 ;
// Count by severity
const severity = error . severity || 'error' ;
errorsBySeverity [ severity ] = ( errorsBySeverity [ severity ] || 0 ) + 1 ;
2025-05-30 04:29:13 +00:00
console . log ( ` - ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
if ( error . path ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Path: ${ error . path } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
// Display error summary
2025-05-30 04:29:13 +00:00
console . log ( ` \ nError Summary: ` ) ;
console . log ( ` Total errors: ${ errors . length } ` ) ;
2025-05-25 19:45:37 +00:00
2025-05-30 04:29:13 +00:00
console . log ( ` By category: ` ) ;
2025-05-25 19:45:37 +00:00
for ( const [ category , count ] of Object . entries ( errorsByCategory ) ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ${ category } : ${ count } ` ) ;
2025-05-25 19:45:37 +00:00
}
2025-05-30 04:29:13 +00:00
console . log ( ` By severity: ` ) ;
2025-05-25 19:45:37 +00:00
for ( const [ severity , count ] of Object . entries ( errorsBySeverity ) ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ${ severity } : ${ count } ` ) ;
2025-05-25 19:45:37 +00:00
}
// Expect multiple errors to be found
expect ( errors . length ) . toBeGreaterThan ( 3 ) ;
// Check that errors are properly structured
for ( const error of errors ) {
expect ( error . message ) . toBeTruthy ( ) ;
expect ( typeof error . message ) . toBe ( 'string' ) ;
}
2025-05-30 04:29:13 +00:00
console . log ( ` ✓ Error aggregation and categorization working ` ) ;
2025-05-25 19:45:37 +00:00
}
}
} catch ( error ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Error aggregation test failed: ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
}
const duration = Date . now ( ) - startTime ;
2025-05-30 04:29:13 +00:00
// PerformanceTracker.recordMetric('error-reporting-aggregation', duration);
2025-05-25 19:45:37 +00:00
} ) ;
tap . test ( 'VAL-13: Error Reporting - Localized Error Messages' , async ( tools ) = > {
const startTime = Date . now ( ) ;
// Test error message localization (if supported)
const localizationTestXml = ` <?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<ID>LOC-TEST-001</ID>
<IssueDate>2024-01-01</IssueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
<DocumentCurrencyCode>INVALID</DocumentCurrencyCode>
</Invoice> ` ;
const locales = [ 'en' , 'de' , 'fr' ] ;
for ( const locale of locales ) {
try {
const invoice = new EInvoice ( ) ;
// Set locale if the API supports it
if ( typeof invoice . setLocale === 'function' ) {
invoice . setLocale ( locale ) ;
2025-05-30 04:29:13 +00:00
console . log ( ` Testing error messages in locale: ${ locale } ` ) ;
2025-05-25 19:45:37 +00:00
} else {
2025-05-30 04:29:13 +00:00
console . log ( ` Locale setting not supported, testing default messages ` ) ;
2025-05-25 19:45:37 +00:00
}
const parseResult = await invoice . fromXmlString ( localizationTestXml ) ;
if ( parseResult ) {
const validationResult = await invoice . validate ( ) ;
if ( validationResult && ! validationResult . valid && validationResult . errors ) {
for ( const error of validationResult . errors ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ${ locale } : ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
// Check that error message is not empty and reasonably descriptive
expect ( error . message ) . toBeTruthy ( ) ;
expect ( error . message . length ) . toBeGreaterThan ( 5 ) ;
// Check for locale-specific characteristics (if implemented)
if ( locale === 'de' && error . message . includes ( 'ungültig' ) ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ✓ German localization detected ` ) ;
2025-05-25 19:45:37 +00:00
} else if ( locale === 'fr' && error . message . includes ( 'invalide' ) ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ✓ French localization detected ` ) ;
2025-05-25 19:45:37 +00:00
}
}
}
}
} catch ( error ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Localization test failed for ${ locale } : ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
const duration = Date . now ( ) - startTime ;
2025-05-30 04:29:13 +00:00
// PerformanceTracker.recordMetric('error-reporting-localization', duration);
2025-05-25 19:45:37 +00:00
} ) ;
tap . test ( 'VAL-13: Error Reporting - Corpus Error Analysis' , { timeout : testTimeout } , async ( tools ) = > {
const startTime = Date . now ( ) ;
const errorStatistics = {
totalFiles : 0 ,
filesWithErrors : 0 ,
totalErrors : 0 ,
errorsByCategory : { } ,
errorsBySeverity : { } ,
mostCommonErrors : { }
} ;
try {
// Analyze errors across corpus files
const categories = [ 'UBL_XML_RECHNUNG' , 'CII_XML_RECHNUNG' ] ;
for ( const category of categories ) {
try {
const files = await CorpusLoader . getFiles ( category ) ;
for ( const filePath of files . slice ( 0 , 8 ) ) { // Process first 8 files per category
errorStatistics . totalFiles ++ ;
try {
const invoice = new EInvoice ( ) ;
const parseResult = await invoice . fromFile ( filePath ) ;
if ( parseResult ) {
const validationResult = await invoice . validate ( ) ;
if ( validationResult && ! validationResult . valid && validationResult . errors ) {
errorStatistics . filesWithErrors ++ ;
errorStatistics . totalErrors += validationResult . errors . length ;
for ( const error of validationResult . errors ) {
// Count by category
const category = error . category || 'unknown' ;
errorStatistics . errorsByCategory [ category ] = ( errorStatistics . errorsByCategory [ category ] || 0 ) + 1 ;
// Count by severity
const severity = error . severity || 'error' ;
errorStatistics . errorsBySeverity [ severity ] = ( errorStatistics . errorsBySeverity [ severity ] || 0 ) + 1 ;
// Track common error patterns
const errorKey = error . code || error . message . substring ( 0 , 50 ) ;
errorStatistics . mostCommonErrors [ errorKey ] = ( errorStatistics . mostCommonErrors [ errorKey ] || 0 ) + 1 ;
}
}
}
} catch ( error ) {
errorStatistics . filesWithErrors ++ ;
errorStatistics . totalErrors ++ ;
2025-05-30 04:29:13 +00:00
console . log ( ` Parse error in ${ plugins . path . basename ( filePath ) } : ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
} catch ( error ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Failed to process category ${ category } : ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
// Display error analysis results
2025-05-30 04:29:13 +00:00
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 ) } ` ) ;
2025-05-25 19:45:37 +00:00
if ( Object . keys ( errorStatistics . errorsByCategory ) . length > 0 ) {
2025-05-30 04:29:13 +00:00
console . log ( ` \ nErrors by category: ` ) ;
2025-05-25 19:45:37 +00:00
for ( const [ category , count ] of Object . entries ( errorStatistics . errorsByCategory ) ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ${ category } : ${ count } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
if ( Object . keys ( errorStatistics . errorsBySeverity ) . length > 0 ) {
2025-05-30 04:29:13 +00:00
console . log ( ` \ nErrors by severity: ` ) ;
2025-05-25 19:45:37 +00:00
for ( const [ severity , count ] of Object . entries ( errorStatistics . errorsBySeverity ) ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ${ severity } : ${ count } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
// Show most common errors
const commonErrors = Object . entries ( errorStatistics . mostCommonErrors )
. sort ( ( [ , a ] , [ , b ] ) = > b - a )
. slice ( 0 , 5 ) ;
if ( commonErrors . length > 0 ) {
2025-05-30 04:29:13 +00:00
console . log ( ` \ nMost common errors: ` ) ;
2025-05-25 19:45:37 +00:00
for ( const [ errorKey , count ] of commonErrors ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ${ count } x: ${ errorKey } ` ) ;
2025-05-25 19:45:37 +00:00
}
}
// Error analysis should complete successfully
expect ( errorStatistics . totalFiles ) . toBeGreaterThan ( 0 ) ;
} catch ( error ) {
2025-05-30 04:29:13 +00:00
console . log ( ` Corpus error analysis failed: ${ error . message } ` ) ;
2025-05-25 19:45:37 +00:00
throw error ;
}
const totalDuration = Date . now ( ) - startTime ;
2025-05-30 04:29:13 +00:00
// PerformanceTracker.recordMetric('error-reporting-corpus', totalDuration);
2025-05-25 19:45:37 +00:00
expect ( totalDuration ) . toBeLessThan ( 120000 ) ; // 2 minutes max
2025-05-30 04:29:13 +00:00
console . log ( ` Error analysis completed in ${ totalDuration } ms ` ) ;
2025-05-25 19:45:37 +00:00
} ) ;
tap . test ( 'VAL-13: Performance Summary' , async ( tools ) = > {
const operations = [
'error-reporting-message-quality' ,
'error-reporting-classification' ,
'error-reporting-context' ,
'error-reporting-aggregation' ,
'error-reporting-localization' ,
'error-reporting-corpus'
] ;
2025-05-30 04:29:13 +00:00
console . log ( ` \ n=== Error Reporting Performance Summary === ` ) ;
2025-05-25 19:45:37 +00:00
for ( const operation of operations ) {
const summary = await PerformanceTracker . getSummary ( operation ) ;
if ( summary ) {
2025-05-30 04:29:13 +00:00
console . log ( ` ${ operation } : ` ) ;
console . log ( ` avg= ${ summary . average } ms, min= ${ summary . min } ms, max= ${ summary . max } ms, p95= ${ summary . p95 } ms ` ) ;
2025-05-25 19:45:37 +00:00
}
}
2025-05-30 04:29:13 +00:00
console . log ( ` \ nError reporting testing completed successfully. ` ) ;
} ) ;
// Start the test
tap . start ( ) ;
// Export for test runner compatibility
export default tap ;