1<?php 2 3namespace Psr\Log\Test; 4 5use Psr\Log\LoggerInterface; 6use Psr\Log\LogLevel; 7use PHPUnit\Framework\TestCase; 8 9/** 10 * Provides a base test class for ensuring compliance with the LoggerInterface. 11 * 12 * Implementors can extend the class and implement abstract methods to run this 13 * as part of their test suite. 14 */ 15abstract class LoggerInterfaceTest extends TestCase 16{ 17 /** 18 * @return LoggerInterface 19 */ 20 abstract public function getLogger(); 21 22 /** 23 * This must return the log messages in order. 24 * 25 * The simple formatting of the messages is: "<LOG LEVEL> <MESSAGE>". 26 * 27 * Example ->error('Foo') would yield "error Foo". 28 * 29 * @return string[] 30 */ 31 abstract public function getLogs(); 32 33 public function testImplements() 34 { 35 $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); 36 } 37 38 /** 39 * @dataProvider provideLevelsAndMessages 40 */ 41 public function testLogsAtAllLevels($level, $message) 42 { 43 $logger = $this->getLogger(); 44 $logger->{$level}($message, array('user' => 'Bob')); 45 $logger->log($level, $message, array('user' => 'Bob')); 46 47 $expected = array( 48 $level.' message of level '.$level.' with context: Bob', 49 $level.' message of level '.$level.' with context: Bob', 50 ); 51 $this->assertEquals($expected, $this->getLogs()); 52 } 53 54 public function provideLevelsAndMessages() 55 { 56 return array( 57 LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), 58 LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), 59 LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), 60 LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), 61 LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), 62 LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), 63 LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), 64 LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), 65 ); 66 } 67 68 /** 69 * @expectedException \Psr\Log\InvalidArgumentException 70 */ 71 public function testThrowsOnInvalidLevel() 72 { 73 $logger = $this->getLogger(); 74 $logger->log('invalid level', 'Foo'); 75 } 76 77 public function testContextReplacement() 78 { 79 $logger = $this->getLogger(); 80 $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); 81 82 $expected = array('info {Message {nothing} Bob Bar a}'); 83 $this->assertEquals($expected, $this->getLogs()); 84 } 85 86 public function testObjectCastToString() 87 { 88 if (method_exists($this, 'createPartialMock')) { 89 $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString')); 90 } else { 91 $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); 92 } 93 $dummy->expects($this->once()) 94 ->method('__toString') 95 ->will($this->returnValue('DUMMY')); 96 97 $this->getLogger()->warning($dummy); 98 99 $expected = array('warning DUMMY'); 100 $this->assertEquals($expected, $this->getLogs()); 101 } 102 103 public function testContextCanContainAnything() 104 { 105 $closed = fopen('php://memory', 'r'); 106 fclose($closed); 107 108 $context = array( 109 'bool' => true, 110 'null' => null, 111 'string' => 'Foo', 112 'int' => 0, 113 'float' => 0.5, 114 'nested' => array('with object' => new DummyTest), 115 'object' => new \DateTime, 116 'resource' => fopen('php://memory', 'r'), 117 'closed' => $closed, 118 ); 119 120 $this->getLogger()->warning('Crazy context data', $context); 121 122 $expected = array('warning Crazy context data'); 123 $this->assertEquals($expected, $this->getLogs()); 124 } 125 126 public function testContextExceptionKeyCanBeExceptionOrOtherValues() 127 { 128 $logger = $this->getLogger(); 129 $logger->warning('Random message', array('exception' => 'oops')); 130 $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); 131 132 $expected = array( 133 'warning Random message', 134 'critical Uncaught Exception!' 135 ); 136 $this->assertEquals($expected, $this->getLogs()); 137 } 138} 139