Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
   1  <?php
   2  
   3  namespace Psr\Log\Test;
   4  
   5  use Psr\Log\LoggerInterface;
   6  use Psr\Log\LogLevel;
   7  use 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   */
  15  abstract 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  }