import { expect, tap } from '@git.zone/tstest/tapbundle'; import * as devicemanager from '../ts/index.js'; // Test imports tap.test('should export DeviceManager', async () => { expect(devicemanager.DeviceManager).toBeDefined(); expect(typeof devicemanager.DeviceManager).toEqual('function'); }); tap.test('should export Scanner', async () => { expect(devicemanager.Scanner).toBeDefined(); expect(typeof devicemanager.Scanner).toEqual('function'); }); tap.test('should export Printer', async () => { expect(devicemanager.Printer).toBeDefined(); expect(typeof devicemanager.Printer).toEqual('function'); }); tap.test('should export protocol implementations', async () => { expect(devicemanager.EsclProtocol).toBeDefined(); expect(devicemanager.SaneProtocol).toBeDefined(); expect(devicemanager.IppProtocol).toBeDefined(); }); tap.test('should export retry helpers', async () => { expect(devicemanager.withRetry).toBeDefined(); expect(devicemanager.createRetryable).toBeDefined(); expect(devicemanager.defaultRetryOptions).toBeDefined(); }); // Test DeviceManager creation tap.test('should create DeviceManager instance', async () => { const dm = new devicemanager.DeviceManager({ autoDiscovery: false, }); expect(dm).toBeInstanceOf(devicemanager.DeviceManager); expect(dm.isDiscovering).toEqual(false); expect(dm.getScanners()).toEqual([]); expect(dm.getPrinters()).toEqual([]); }); // Test retry helper tap.test('withRetry should succeed on first try', async () => { let callCount = 0; const result = await devicemanager.withRetry(async () => { callCount++; return 'success'; }); expect(result).toEqual('success'); expect(callCount).toEqual(1); }); tap.test('withRetry should retry on failure', async () => { let callCount = 0; const result = await devicemanager.withRetry( async () => { callCount++; if (callCount < 3) { throw new Error('Temporary failure'); } return 'success after retries'; }, { maxRetries: 5, baseDelay: 10, maxDelay: 100 } ); expect(result).toEqual('success after retries'); expect(callCount).toEqual(3); }); tap.test('withRetry should throw after max retries', async () => { let callCount = 0; let error: Error | null = null; try { await devicemanager.withRetry( async () => { callCount++; throw new Error('Persistent failure'); }, { maxRetries: 2, baseDelay: 10, maxDelay: 100 } ); } catch (e) { error = e as Error; } expect(error).not.toBeNull(); expect(error?.message).toEqual('Persistent failure'); expect(callCount).toEqual(3); // Initial + 2 retries }); // Test discovery (non-blocking) tap.test('should start and stop discovery', async () => { const dm = new devicemanager.DeviceManager(); // Track events let discoveryStarted = false; let discoveryStopped = false; dm.on('discovery:started', () => { discoveryStarted = true; }); dm.on('discovery:stopped', () => { discoveryStopped = true; }); await dm.startDiscovery(); expect(dm.isDiscovering).toEqual(true); expect(discoveryStarted).toEqual(true); // Wait a bit for potential device discovery await new Promise((resolve) => setTimeout(resolve, 2000)); // Log discovered devices const scanners = dm.getScanners(); const printers = dm.getPrinters(); console.log(`Discovered ${scanners.length} scanner(s) and ${printers.length} printer(s)`); for (const scanner of scanners) { console.log(` Scanner: ${scanner.name} (${scanner.address}:${scanner.port}) - ${scanner.protocol}`); } for (const printer of printers) { console.log(` Printer: ${printer.name} (${printer.address}:${printer.port})`); } await dm.stopDiscovery(); expect(dm.isDiscovering).toEqual(false); expect(discoveryStopped).toEqual(true); await dm.shutdown(); }); // Test Scanner creation from discovery info tap.test('should create Scanner from discovery info', async () => { const scanner = devicemanager.Scanner.fromDiscovery({ id: 'test:scanner:1', name: 'Test Scanner', address: '192.168.1.100', port: 443, protocol: 'escl', txtRecords: { 'ty': 'HP LaserJet MFP', 'pdl': 'image/jpeg,application/pdf', 'cs': 'color,grayscale', 'is': 'platen,adf', }, }); expect(scanner.name).toEqual('Test Scanner'); expect(scanner.address).toEqual('192.168.1.100'); expect(scanner.port).toEqual(443); expect(scanner.protocol).toEqual('escl'); expect(scanner.supportedFormats).toContain('jpeg'); expect(scanner.supportedFormats).toContain('pdf'); expect(scanner.supportedColorModes).toContain('color'); expect(scanner.supportedColorModes).toContain('grayscale'); expect(scanner.supportedSources).toContain('flatbed'); expect(scanner.supportedSources).toContain('adf'); expect(scanner.hasAdf).toEqual(true); }); // Test Printer creation from discovery info tap.test('should create Printer from discovery info', async () => { const printer = devicemanager.Printer.fromDiscovery({ id: 'test:printer:1', name: 'Test Printer', address: '192.168.1.101', port: 631, txtRecords: { 'ty': 'Brother HL-L2350DW', 'rp': 'ipp/print', 'Color': 'T', 'Duplex': 'T', }, }); expect(printer.name).toEqual('Test Printer'); expect(printer.address).toEqual('192.168.1.101'); expect(printer.port).toEqual(631); expect(printer.supportsColor).toEqual(true); expect(printer.supportsDuplex).toEqual(true); expect(printer.uri).toContain('ipp://'); }); export default tap.start();