UNPKG

onix-parser

Version:

Parse ONIX 3.0 XML files and extract structured product data for publishing and digital books

260 lines (212 loc) โ€ข 7.35 kB
const fs = require('fs') const path = require('path') const onix = require('./onix') /** * Enhanced test suite for ONIX parser */ class OnixTester { constructor() { this.results = { passed: 0, failed: 0, total: 0, errors: [] } this.outputDir = './test-results' this.ensureOutputDir() } ensureOutputDir() { if (!fs.existsSync(this.outputDir)) { fs.mkdirSync(this.outputDir, { recursive: true }) } } async runAllTests() { console.log('๐Ÿš€ Starting ONIX Parser Test Suite') console.log('='.repeat(50)) // Test individual files await this.testIndividualFiles() // Test edge cases await this.testEdgeCases() // Test performance await this.testPerformance() this.printSummary() } async testIndividualFiles() { console.log('\n๐Ÿ“ Testing Individual ONIX Files') console.log('-'.repeat(30)) const testFiles = this.getTestFiles() for (const file of testFiles) { await this.testSingleFile(file) } } async testSingleFile(filename) { const filePath = `./files/${filename}` const testName = filename.replace('.xml', '') try { console.log(`Testing ${filename}...`) const startTime = Date.now() const result = await onix(filePath) const duration = Date.now() - startTime if (result.status) { console.log(` โœ… ${testName} - Parsed successfully (${duration}ms)`) console.log(` Title: ${result.data.title?.titleText || 'N/A'}`) console.log(` ISBN: ${result.data.iSNB13 || 'N/A'}`) console.log(` Format: ${result.data.productFormDetail?.detail || 'N/A'}`) console.log(` Price: ${result.data.priceBRL || 'N/A'} BRL`) // Save successful results const outputFile = path.join(this.outputDir, `${testName}.json`) fs.writeFileSync(outputFile, JSON.stringify(result, null, 2)) this.results.passed++ } else { console.log(` โŒ ${testName} - Failed`) console.log(` Errors: ${result.message.join(', ')}`) // Save failed results for analysis const errorFile = path.join(this.outputDir, `${testName}-error.json`) fs.writeFileSync(errorFile, JSON.stringify(result, null, 2)) this.results.failed++ this.results.errors.push({ file: filename, errors: result.message }) } this.results.total++ } catch (error) { console.log(` ๐Ÿ’ฅ ${testName} - Exception: ${error.message}`) this.results.failed++ this.results.total++ this.results.errors.push({ file: filename, errors: [error.message] }) } } async testEdgeCases() { console.log('\n๐Ÿงช Testing Edge Cases') console.log('-'.repeat(20)) const edgeCases = [ { name: 'Non-existent file', test: () => onix('./files/non-existent.xml') }, { name: 'Invalid file path', test: () => onix(null) }, { name: 'Empty string path', test: () => onix('') }, { name: 'Invalid path type', test: () => onix(123) } ] for (const testCase of edgeCases) { try { console.log(`Testing ${testCase.name}...`) const result = await testCase.test() if (!result.status) { console.log(` โœ… ${testCase.name} - Correctly handled with error: ${result.message[0]}`) } else { console.log(` โŒ ${testCase.name} - Should have failed but didn't`) } } catch (error) { console.log(` โœ… ${testCase.name} - Correctly threw exception: ${error.message}`) } } } async testPerformance() { console.log('\nโšก Performance Tests') console.log('-'.repeat(18)) const testFiles = this.getTestFiles().slice(0, 5) // Test with first 5 files const times = [] for (const file of testFiles) { const filePath = `./files/${file}` if (!fs.existsSync(filePath)) continue const startTime = Date.now() await onix(filePath) const duration = Date.now() - startTime times.push(duration) console.log(` ๐Ÿ“Š ${file}: ${duration}ms`) } if (times.length > 0) { const avgTime = times.reduce((a, b) => a + b, 0) / times.length const maxTime = Math.max(...times) const minTime = Math.min(...times) console.log(`\n Average: ${avgTime.toFixed(1)}ms`) console.log(` Min: ${minTime}ms, Max: ${maxTime}ms`) } } getTestFiles() { const filesDir = './files' if (!fs.existsSync(filesDir)) { console.log('โš ๏ธ Files directory not found') return [] } return fs.readdirSync(filesDir) .filter(file => file.endsWith('.xml')) .sort() } printSummary() { console.log('\n' + '='.repeat(50)) console.log('๐Ÿ“Š TEST SUMMARY') console.log('='.repeat(50)) console.log(`Total tests: ${this.results.total}`) console.log(`Passed: ${this.results.passed} โœ…`) console.log(`Failed: ${this.results.failed} โŒ`) if (this.results.total > 0) { const successRate = ((this.results.passed / this.results.total) * 100).toFixed(1) console.log(`Success rate: ${successRate}%`) } if (this.results.errors.length > 0) { console.log('\nโŒ FAILED TESTS:') this.results.errors.forEach(error => { console.log(` ${error.file}: ${error.errors.join(', ')}`) }) } console.log(`\n๐Ÿ“ Results saved to: ${this.outputDir}`) console.log('='.repeat(50)) } // Generate a test report generateReport() { const report = { timestamp: new Date().toISOString(), summary: this.results, details: { totalFiles: this.getTestFiles().length, outputDirectory: this.outputDir } } const reportFile = path.join(this.outputDir, 'test-report.json') fs.writeFileSync(reportFile, JSON.stringify(report, null, 2)) console.log(`๐Ÿ“„ Detailed report saved to: ${reportFile}`) } } // Quick test function for individual files async function quickTest(filename) { console.log(`๐Ÿ” Quick test for ${filename}`) const result = await onix(`./files/${filename}`) if (result.status) { console.log('โœ… Success!') console.log('๐Ÿ“– Title:', result.data.title?.titleText) console.log('๐Ÿ“š ISBN:', result.data.iSNB13) console.log('๐Ÿ’ฐ Price:', result.data.priceBRL, 'BRL') } else { console.log('โŒ Failed:', result.message.join(', ')) } return result } // Run tests based on command line arguments or run all async function main() { const args = process.argv.slice(2) if (args.length > 0) { // Test specific file const filename = args[0].endsWith('.xml') ? args[0] : `${args[0]}.xml` await quickTest(filename) } else { // Run full test suite const tester = new OnixTester() await tester.runAllTests() tester.generateReport() } } // Export for use in other files module.exports = { OnixTester, quickTest } // Run if called directly if (require.main === module) { main().catch(console.error) }