capturedRecords = []; // Mock Handler der alle Records captured $mockHandler = $this->createMock(LogHandler::class); $mockHandler->method('isHandling')->willReturn(true); $mockHandler->method('handle')->willReturnCallback(function (LogRecord $record) { $this->capturedRecords[] = $record; }); $this->logger = new DefaultLogger( minLevel: LogLevel::DEBUG, handlers: [$mockHandler], processorManager: new ProcessorManager() ); } public function test_logger_has_all_channel_loggers(): void { $channelLogger = $this->logger->channel(LogChannel::SECURITY); expect($channelLogger)->toBeInstanceOf(Logger::class); expect($channelLogger)->toBeInstanceOf(HasChannel::class); expect($this->logger->channel(LogChannel::CACHE))->toBeInstanceOf(Logger::class); expect($this->logger->channel(LogChannel::DATABASE))->toBeInstanceOf(Logger::class); expect($this->logger->channel(LogChannel::FRAMEWORK))->toBeInstanceOf(Logger::class); expect($this->logger->channel(LogChannel::ERROR))->toBeInstanceOf(Logger::class); } public function test_channel_loggers_have_correct_channels(): void { expect($this->logger->channel(LogChannel::SECURITY)->channel)->toBe(LogChannel::SECURITY); expect($this->logger->channel(LogChannel::CACHE)->channel)->toBe(LogChannel::CACHE); expect($this->logger->channel(LogChannel::DATABASE)->channel)->toBe(LogChannel::DATABASE); expect($this->logger->channel(LogChannel::FRAMEWORK)->channel)->toBe(LogChannel::FRAMEWORK); expect($this->logger->channel(LogChannel::ERROR)->channel)->toBe(LogChannel::ERROR); } public function test_log_to_channel_creates_record_with_channel(): void { $this->logger->logToChannel(LogChannel::SECURITY, LogLevel::WARNING, 'Test message', LogContext::withData(['key' => 'value'])); expect($this->capturedRecords)->toHaveCount(1); $record = $this->capturedRecords[0]; expect($record->getChannel())->toBe('security'); expect($record->getMessage())->toBe('Test message'); expect($record->getLevel())->toBe(LogLevel::WARNING); expect($record->getContext())->toMatchArray(['key' => 'value']); } public function test_channel_logger_creates_records_with_correct_channel(): void { $this->logger->channel(LogChannel::SECURITY)->error('Security alert', LogContext::withData(['ip' => '192.168.1.1'])); expect($this->capturedRecords)->toHaveCount(1); $record = $this->capturedRecords[0]; expect($record->getChannel())->toBe('security'); expect($record->getMessage())->toBe('Security alert'); expect($record->getLevel())->toBe(LogLevel::ERROR); expect($record->getContext())->toBe(['ip' => '192.168.1.1']); } public function test_different_channels_create_different_records(): void { $this->logger->channel(LogChannel::SECURITY)->warning('Security warning'); $this->logger->channel(LogChannel::CACHE)->debug('Cache debug'); $this->logger->channel(LogChannel::DATABASE)->error('DB error'); expect($this->capturedRecords)->toHaveCount(3); expect($this->capturedRecords[0]->getChannel())->toBe('security'); expect($this->capturedRecords[0]->getLevel())->toBe(LogLevel::WARNING); expect($this->capturedRecords[1]->getChannel())->toBe('cache'); expect($this->capturedRecords[1]->getLevel())->toBe(LogLevel::DEBUG); expect($this->capturedRecords[2]->getChannel())->toBe('database'); expect($this->capturedRecords[2]->getLevel())->toBe(LogLevel::ERROR); } public function test_standard_logging_still_works(): void { $this->logger->info('Standard log message'); expect($this->capturedRecords)->toHaveCount(1); $record = $this->capturedRecords[0]; expect($record->getChannel())->toBeNull(); // Standard logs haben keinen Channel expect($record->getMessage())->toBe('Standard log message'); expect($record->getLevel())->toBe(LogLevel::INFO); } public function test_log_to_channel_respects_min_level(): void { // Logger mit höherem Min-Level erstellen $logger = new DefaultLogger(minLevel: LogLevel::ERROR); // Debug-Level sollte ignoriert werden $logger->logToChannel(LogChannel::SECURITY, LogLevel::DEBUG, 'Debug message'); // Keine Records sollten erstellt werden, da kein Handler gesetzt ist // aber der Level-Check sollte funktionieren expect(true)->toBeTrue(); // Test dass keine Exception geworfen wird } public function test_log_to_channel_with_empty_context(): void { $this->logger->logToChannel(LogChannel::FRAMEWORK, LogLevel::INFO, 'Framework message'); expect($this->capturedRecords)->toHaveCount(1); $record = $this->capturedRecords[0]; expect($record->getChannel())->toBe('framework'); expect($record->getContext())->toBe([]); } public function test_mixed_logging_works_correctly(): void { // Mix aus Standard- und Channel-Logging $this->logger->info('Standard info'); $this->logger->channel(LogChannel::SECURITY)->warning('Security warning'); $this->logger->error('Standard error'); $this->logger->channel(LogChannel::CACHE)->debug('Cache debug'); expect($this->capturedRecords)->toHaveCount(4); // Standard logs haben keinen Channel expect($this->capturedRecords[0]->getChannel())->toBeNull(); expect($this->capturedRecords[2]->getChannel())->toBeNull(); // Channel logs haben korrekte Channels expect($this->capturedRecords[1]->getChannel())->toBe('security'); expect($this->capturedRecords[3]->getChannel())->toBe('cache'); } }