createMock(LogHandler::class); $handler = new BufferedLogHandler($inner, bufferSize: 3); // First 2 logs should be buffered $inner->expects($this->never())->method('handle'); $handler->handle($this->createLogRecord('log 1')); $handler->handle($this->createLogRecord('log 2')); $this->assertEquals(2, $handler->getBufferSize()); } public function test_flushes_when_buffer_full(): void { $inner = $this->createMock(LogHandler::class); $handler = new BufferedLogHandler($inner, bufferSize: 2); $inner->expects($this->exactly(2))->method('handle'); $handler->handle($this->createLogRecord('log 1')); $handler->handle($this->createLogRecord('log 2')); $this->assertEquals(0, $handler->getBufferSize()); } public function test_flushes_immediately_on_error(): void { $inner = $this->createMock(LogHandler::class); $handler = new BufferedLogHandler( $inner, bufferSize: 100, flushOnError: true ); // INFO log should be buffered $handler->handle($this->createLogRecord('info', LogLevel::INFO)); $this->assertEquals(1, $handler->getBufferSize()); // ERROR should trigger immediate flush $inner->expects($this->exactly(2))->method('handle'); $handler->handle($this->createLogRecord('error', LogLevel::ERROR)); $this->assertEquals(0, $handler->getBufferSize()); } public function test_flushes_on_destruct(): void { $inner = $this->createMock(LogHandler::class); $inner->expects($this->once())->method('handle'); $handler = new BufferedLogHandler($inner, bufferSize: 100); $handler->handle($this->createLogRecord()); // Destructor should flush unset($handler); } public function test_manual_flush(): void { $inner = $this->createMock(LogHandler::class); $handler = new BufferedLogHandler($inner, bufferSize: 100); $handler->handle($this->createLogRecord('log 1')); $handler->handle($this->createLogRecord('log 2')); $this->assertEquals(2, $handler->getBufferSize()); $inner->expects($this->exactly(2))->method('handle'); $handler->flush(); $this->assertTrue($handler->isEmpty()); } private function createLogRecord( string $message = 'test', LogLevel $level = LogLevel::INFO ): LogRecord { return new LogRecord( level: $level, message: $message, channel: 'test', context: LogContext::empty(), timestamp: new \DateTimeImmutable() ); } }