bzikarsky /
gelf-php
| 1 | <?php |
||||||
| 2 | declare(strict_types=1); |
||||||
| 3 | |||||||
| 4 | /* |
||||||
| 5 | * This file is part of the php-gelf package. |
||||||
| 6 | * |
||||||
| 7 | * (c) Benjamin Zikarsky <http://benjamin-zikarsky.de> |
||||||
| 8 | * |
||||||
| 9 | * For the full copyright and license information, please view the LICENSE |
||||||
| 10 | * file that was distributed with this source code. |
||||||
| 11 | */ |
||||||
| 12 | |||||||
| 13 | namespace Gelf\Test; |
||||||
| 14 | |||||||
| 15 | use Gelf\Logger; |
||||||
| 16 | use Gelf\MessageInterface; |
||||||
| 17 | use Gelf\PublisherInterface; |
||||||
| 18 | use PHPUnit\Framework\MockObject\MockObject; |
||||||
| 19 | use PHPUnit\Framework\TestCase; |
||||||
| 20 | use Psr\Log\LogLevel; |
||||||
| 21 | use Exception; |
||||||
| 22 | use Closure; |
||||||
| 23 | use Stringable; |
||||||
| 24 | |||||||
| 25 | class LoggerTest extends TestCase |
||||||
| 26 | { |
||||||
| 27 | private MockObject|PublisherInterface $publisher; |
||||||
| 28 | private Logger $logger; |
||||||
| 29 | |||||||
| 30 | public function setUp(): void |
||||||
| 31 | { |
||||||
| 32 | $this->publisher = $this->createMock(PublisherInterface::class); |
||||||
| 33 | $this->logger = new Logger($this->publisher); |
||||||
| 34 | } |
||||||
| 35 | |||||||
| 36 | public function testPublisher(): void |
||||||
| 37 | { |
||||||
| 38 | self::assertEquals($this->publisher, $this->logger->getPublisher()); |
||||||
| 39 | |||||||
| 40 | $newPublisher = $this->createMock(PublisherInterface::class); |
||||||
| 41 | $this->logger->setPublisher($newPublisher); |
||||||
| 42 | self::assertEquals($newPublisher, $this->logger->getPublisher()); |
||||||
| 43 | } |
||||||
| 44 | |||||||
| 45 | public function testSimpleLog(): void |
||||||
| 46 | { |
||||||
| 47 | $this->validatePublish( |
||||||
| 48 | function (MessageInterface $message) { |
||||||
| 49 | self::assertEquals("test", $message->getShortMessage()); |
||||||
| 50 | self::assertEquals(LogLevel::ALERT, $message->getLevel()); |
||||||
| 51 | } |
||||||
| 52 | ); |
||||||
| 53 | |||||||
| 54 | $this->logger->log(LogLevel::ALERT, "test"); |
||||||
| 55 | } |
||||||
| 56 | |||||||
| 57 | public function testLogContext(): void |
||||||
| 58 | { |
||||||
| 59 | $additional = ['test' => 'bar', 'abc' => 'buz']; |
||||||
| 60 | $this->validatePublish( |
||||||
| 61 | function (MessageInterface $message) use ($additional) { |
||||||
| 62 | self::assertEquals("foo bar", $message->getShortMessage()); |
||||||
| 63 | self::assertEquals($additional, $message->getAllAdditionals()); |
||||||
| 64 | } |
||||||
| 65 | ); |
||||||
| 66 | |||||||
| 67 | $this->logger->log(LogLevel::NOTICE, "foo {test}", $additional); |
||||||
| 68 | } |
||||||
| 69 | |||||||
| 70 | /** |
||||||
| 71 | * @see https://github.com/bzikarsky/gelf-php/issues/50 |
||||||
| 72 | * @dataProvider providerLogContextWithStructuralValues |
||||||
| 73 | */ |
||||||
| 74 | public function testLogContextWithStructuralValues(mixed $contextValue, mixed $expected): void |
||||||
| 75 | { |
||||||
| 76 | $additional = ['context' => $contextValue]; |
||||||
| 77 | $this->validatePublish( |
||||||
| 78 | function (MessageInterface $message) use ($expected) { |
||||||
| 79 | // Use Message::toArray() as it filters invalid values |
||||||
| 80 | $final = $message->toArray(); |
||||||
| 81 | if (!isset($final['_context'])) { |
||||||
| 82 | self::fail("Expected context key missing"); |
||||||
| 83 | } |
||||||
| 84 | $actual = $final['_context']; |
||||||
| 85 | // Only scalar values are allowed, with exception of boolean |
||||||
| 86 | self::assertTrue( |
||||||
| 87 | is_scalar($actual) && !is_bool($actual), |
||||||
| 88 | 'Unexpected context value of type: ' . gettype($actual) |
||||||
| 89 | ); |
||||||
| 90 | self::assertSame($expected, $actual); |
||||||
| 91 | } |
||||||
| 92 | ); |
||||||
| 93 | |||||||
| 94 | // Log message length must exceed longest context key length + 2 |
||||||
| 95 | // to cause strtr() in Logger::interpolate() to throw notices for nested arrays |
||||||
| 96 | $this->logger->log(LogLevel::NOTICE, 'test message', $additional); |
||||||
| 97 | } |
||||||
| 98 | |||||||
| 99 | public static function providerLogContextWithStructuralValues(): array |
||||||
| 100 | { |
||||||
| 101 | $stdClass = new \stdClass(); |
||||||
| 102 | $stdClass->prop1 = 'val1'; |
||||||
| 103 | |||||||
| 104 | $toString = new class implements Stringable { |
||||||
| 105 | public function __toString(): string |
||||||
| 106 | { |
||||||
| 107 | return 'toString'; |
||||||
| 108 | } |
||||||
| 109 | }; |
||||||
| 110 | |||||||
| 111 | return [ |
||||||
| 112 | 'array' => [['bar' => 'buz'], '{"bar":"buz"}'], |
||||||
| 113 | 'boolTrue' => [true, 'true'], |
||||||
| 114 | 'boolFalse' => [false, 'false'], |
||||||
| 115 | 'integer' => [123, 123], |
||||||
| 116 | 'float' => [123.456, 123.456], |
||||||
| 117 | 'object' => [$stdClass, '[object (stdClass)]'], |
||||||
| 118 | 'toString' => [$toString, 'toString'], |
||||||
| 119 | 'resource' => [fopen('php://memory', 'r'), '[resource]'], |
||||||
| 120 | 'null' => [null, 'NULL'] |
||||||
| 121 | ]; |
||||||
| 122 | } |
||||||
| 123 | |||||||
| 124 | public function testLogException(): void |
||||||
| 125 | { |
||||||
| 126 | // offset is the line-distance to the throw statement! |
||||||
| 127 | $line = __LINE__ + 3; |
||||||
| 128 | |||||||
| 129 | try { |
||||||
| 130 | throw new Exception("test-message", 123); |
||||||
| 131 | } catch (Exception $e) { |
||||||
| 132 | $this->validatePublish( |
||||||
| 133 | function (MessageInterface $message) use ($e, $line) { |
||||||
| 134 | self::assertStringContainsString( |
||||||
| 135 | $e->getMessage(), |
||||||
| 136 | $message->getFullMessage() |
||||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||||
| 137 | ); |
||||||
| 138 | self::assertStringContainsString( |
||||||
| 139 | get_class($e), |
||||||
| 140 | $message->getFullMessage() |
||||||
| 141 | ); |
||||||
| 142 | self::assertEquals($line, $message->getAdditional('line')); |
||||||
| 143 | self::assertEquals(__FILE__, $message->getAdditional('file')); |
||||||
| 144 | } |
||||||
| 145 | ); |
||||||
| 146 | |||||||
| 147 | $this->logger->log( |
||||||
| 148 | LogLevel::ALERT, |
||||||
| 149 | $e->getMessage(), |
||||||
| 150 | context: ['exception' => $e] |
||||||
| 151 | ); |
||||||
| 152 | } |
||||||
| 153 | } |
||||||
| 154 | |||||||
| 155 | // @see https://github.com/bzikarsky/gelf-php/issues/9 |
||||||
| 156 | public function testStringZeroMessage(): void |
||||||
| 157 | { |
||||||
| 158 | $this->validatePublish( |
||||||
| 159 | function (MessageInterface $message) { |
||||||
| 160 | self::assertEquals("0", $message->getShortMessage()); |
||||||
| 161 | } |
||||||
| 162 | ); |
||||||
| 163 | |||||||
| 164 | $this->logger->info('0'); |
||||||
| 165 | } |
||||||
| 166 | |||||||
| 167 | private function validatePublish(Closure $validator): void |
||||||
| 168 | { |
||||||
| 169 | $this->publisher->expects($this->once())->method('publish')->will( |
||||||
|
0 ignored issues
–
show
The method
expects() does not exist on Gelf\PublisherInterface.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. Loading history...
|
|||||||
| 170 | $this->returnCallback($validator) |
||||||
| 171 | ); |
||||||
| 172 | } |
||||||
| 173 | |||||||
| 174 | public function testDefaultContext(): void |
||||||
| 175 | { |
||||||
| 176 | $this->logger->setDefaultContext(['defaultFoo' => 'bar', 'defaultBar' => 'foo']); |
||||||
| 177 | $this->validatePublish( |
||||||
| 178 | function (MessageInterface $message) { |
||||||
| 179 | self::assertEquals("bar", $message->getAdditional('defaultFoo')); |
||||||
| 180 | self::assertEquals("baz", $message->getAdditional('defaultBar')); |
||||||
| 181 | } |
||||||
| 182 | ); |
||||||
| 183 | |||||||
| 184 | $this->logger->log(5, 'test', [ |
||||||
| 185 | 'defaultBar' => 'baz' |
||||||
| 186 | ]); |
||||||
| 187 | } |
||||||
| 188 | } |
||||||
| 189 |