1<?php 2 3namespace Psr\Log\Test; 4 5use Psr\Log\AbstractLogger; 6 7/** 8 * Used for testing purposes. 9 * 10 * It records all records and gives you access to them for verification. 11 * 12 * @method bool hasEmergency($record) 13 * @method bool hasAlert($record) 14 * @method bool hasCritical($record) 15 * @method bool hasError($record) 16 * @method bool hasWarning($record) 17 * @method bool hasNotice($record) 18 * @method bool hasInfo($record) 19 * @method bool hasDebug($record) 20 * 21 * @method bool hasEmergencyRecords() 22 * @method bool hasAlertRecords() 23 * @method bool hasCriticalRecords() 24 * @method bool hasErrorRecords() 25 * @method bool hasWarningRecords() 26 * @method bool hasNoticeRecords() 27 * @method bool hasInfoRecords() 28 * @method bool hasDebugRecords() 29 * 30 * @method bool hasEmergencyThatContains($message) 31 * @method bool hasAlertThatContains($message) 32 * @method bool hasCriticalThatContains($message) 33 * @method bool hasErrorThatContains($message) 34 * @method bool hasWarningThatContains($message) 35 * @method bool hasNoticeThatContains($message) 36 * @method bool hasInfoThatContains($message) 37 * @method bool hasDebugThatContains($message) 38 * 39 * @method bool hasEmergencyThatMatches($message) 40 * @method bool hasAlertThatMatches($message) 41 * @method bool hasCriticalThatMatches($message) 42 * @method bool hasErrorThatMatches($message) 43 * @method bool hasWarningThatMatches($message) 44 * @method bool hasNoticeThatMatches($message) 45 * @method bool hasInfoThatMatches($message) 46 * @method bool hasDebugThatMatches($message) 47 * 48 * @method bool hasEmergencyThatPasses($message) 49 * @method bool hasAlertThatPasses($message) 50 * @method bool hasCriticalThatPasses($message) 51 * @method bool hasErrorThatPasses($message) 52 * @method bool hasWarningThatPasses($message) 53 * @method bool hasNoticeThatPasses($message) 54 * @method bool hasInfoThatPasses($message) 55 * @method bool hasDebugThatPasses($message) 56 */ 57class TestLogger extends AbstractLogger 58{ 59 /** 60 * @var array 61 */ 62 public $records = []; 63 64 public $recordsByLevel = []; 65 66 /** 67 * @inheritdoc 68 */ 69 public function log($level, $message, array $context = []) 70 { 71 $record = [ 72 'level' => $level, 73 'message' => $message, 74 'context' => $context, 75 ]; 76 77 $this->recordsByLevel[$record['level']][] = $record; 78 $this->records[] = $record; 79 } 80 81 public function hasRecords($level) 82 { 83 return isset($this->recordsByLevel[$level]); 84 } 85 86 public function hasRecord($record, $level) 87 { 88 if (is_string($record)) { 89 $record = ['message' => $record]; 90 } 91 return $this->hasRecordThatPasses(function ($rec) use ($record) { 92 if ($rec['message'] !== $record['message']) { 93 return false; 94 } 95 if (isset($record['context']) && $rec['context'] !== $record['context']) { 96 return false; 97 } 98 return true; 99 }, $level); 100 } 101 102 public function hasRecordThatContains($message, $level) 103 { 104 return $this->hasRecordThatPasses(function ($rec) use ($message) { 105 return strpos($rec['message'], $message) !== false; 106 }, $level); 107 } 108 109 public function hasRecordThatMatches($regex, $level) 110 { 111 return $this->hasRecordThatPasses(function ($rec) use ($regex) { 112 return preg_match($regex, $rec['message']) > 0; 113 }, $level); 114 } 115 116 public function hasRecordThatPasses(callable $predicate, $level) 117 { 118 if (!isset($this->recordsByLevel[$level])) { 119 return false; 120 } 121 foreach ($this->recordsByLevel[$level] as $i => $rec) { 122 if (call_user_func($predicate, $rec, $i)) { 123 return true; 124 } 125 } 126 return false; 127 } 128 129 public function __call($method, $args) 130 { 131 if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { 132 $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; 133 $level = strtolower($matches[2]); 134 if (method_exists($this, $genericMethod)) { 135 $args[] = $level; 136 return call_user_func_array([$this, $genericMethod], $args); 137 } 138 } 139 throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); 140 } 141 142 public function reset() 143 { 144 $this->records = []; 145 $this->recordsByLevel = []; 146 } 147} 148