ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
NormalizerFormatterTest.php
Go to the documentation of this file.
1<?php
2
3/*
4 * This file is part of the Monolog package.
5 *
6 * (c) Jordi Boggiano <j.boggiano@seld.be>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Monolog\Formatter;
13
18{
19 public function testFormat()
20 {
21 $formatter = new NormalizerFormatter('Y-m-d');
22 $formatted = $formatter->format(array(
23 'level_name' => 'ERROR',
24 'channel' => 'meh',
25 'message' => 'foo',
26 'datetime' => new \DateTime,
27 'extra' => array('foo' => new TestFooNorm, 'bar' => new TestBarNorm, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
28 'context' => array(
29 'foo' => 'bar',
30 'baz' => 'qux',
31 'inf' => INF,
32 '-inf' => -INF,
33 'nan' => acos(4),
34 ),
35 ));
36
37 $this->assertEquals(array(
38 'level_name' => 'ERROR',
39 'channel' => 'meh',
40 'message' => 'foo',
41 'datetime' => date('Y-m-d'),
42 'extra' => array(
43 'foo' => '[object] (Monolog\\Formatter\\TestFooNorm: {"foo":"foo"})',
44 'bar' => '[object] (Monolog\\Formatter\\TestBarNorm: bar)',
45 'baz' => array(),
46 'res' => '[resource]',
47 ),
48 'context' => array(
49 'foo' => 'bar',
50 'baz' => 'qux',
51 'inf' => 'INF',
52 '-inf' => '-INF',
53 'nan' => 'NaN',
54 )
55 ), $formatted);
56 }
57
58 public function testFormatExceptions()
59 {
60 $formatter = new NormalizerFormatter('Y-m-d');
61 $e = new \LogicException('bar');
62 $e2 = new \RuntimeException('foo', 0, $e);
63 $formatted = $formatter->format(array(
64 'exception' => $e2,
65 ));
66
67 $this->assertGreaterThan(5, count($formatted['exception']['trace']));
68 $this->assertTrue(isset($formatted['exception']['previous']));
69 unset($formatted['exception']['trace'], $formatted['exception']['previous']);
70
71 $this->assertEquals(array(
72 'exception' => array(
73 'class' => get_class($e2),
74 'message' => $e2->getMessage(),
75 'code' => $e2->getCode(),
76 'file' => $e2->getFile().':'.$e2->getLine(),
77 )
78 ), $formatted);
79 }
80
81 public function testBatchFormat()
82 {
83 $formatter = new NormalizerFormatter('Y-m-d');
84 $formatted = $formatter->formatBatch(array(
85 array(
86 'level_name' => 'CRITICAL',
87 'channel' => 'test',
88 'message' => 'bar',
89 'context' => array(),
90 'datetime' => new \DateTime,
91 'extra' => array(),
92 ),
93 array(
94 'level_name' => 'WARNING',
95 'channel' => 'log',
96 'message' => 'foo',
97 'context' => array(),
98 'datetime' => new \DateTime,
99 'extra' => array(),
100 ),
101 ));
102 $this->assertEquals(array(
103 array(
104 'level_name' => 'CRITICAL',
105 'channel' => 'test',
106 'message' => 'bar',
107 'context' => array(),
108 'datetime' => date('Y-m-d'),
109 'extra' => array(),
110 ),
111 array(
112 'level_name' => 'WARNING',
113 'channel' => 'log',
114 'message' => 'foo',
115 'context' => array(),
116 'datetime' => date('Y-m-d'),
117 'extra' => array(),
118 ),
119 ), $formatted);
120 }
121
126 {
127 // set up the recursion
128 $foo = new \stdClass();
129 $bar = new \stdClass();
130
131 $foo->bar = $bar;
132 $bar->foo = $foo;
133
134 // set an error handler to assert that the error is not raised anymore
135 $that = $this;
136 set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
137 if (error_reporting() & $level) {
138 restore_error_handler();
139 $that->fail("$message should not be raised");
140 }
141 });
142
143 $formatter = new NormalizerFormatter();
144 $reflMethod = new \ReflectionMethod($formatter, 'toJson');
145 $reflMethod->setAccessible(true);
146 $res = $reflMethod->invoke($formatter, array($foo, $bar), true);
147
148 restore_error_handler();
149
150 $this->assertEquals(@json_encode(array($foo, $bar)), $res);
151 }
152
153 public function testIgnoresInvalidTypes()
154 {
155 // set up the recursion
156 $resource = fopen(__FILE__, 'r');
157
158 // set an error handler to assert that the error is not raised anymore
159 $that = $this;
160 set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
161 if (error_reporting() & $level) {
162 restore_error_handler();
163 $that->fail("$message should not be raised");
164 }
165 });
166
167 $formatter = new NormalizerFormatter();
168 $reflMethod = new \ReflectionMethod($formatter, 'toJson');
169 $reflMethod->setAccessible(true);
170 $res = $reflMethod->invoke($formatter, array($resource), true);
171
172 restore_error_handler();
173
174 $this->assertEquals(@json_encode(array($resource)), $res);
175 }
176
181 {
182 $formatter = new NormalizerFormatter();
183 $reflMethod = new \ReflectionMethod($formatter, 'toJson');
184 $reflMethod->setAccessible(true);
185
186 // send an invalid unicode sequence
187 $res = $reflMethod->invoke($formatter, array('message' => "\xB1\x31"));
188 if (PHP_VERSION_ID < 50500 && $res === '{"message":null}') {
189 throw new \RuntimeException('PHP 5.3/5.4 throw a warning and null the value instead of returning false entirely');
190 }
191 }
192
194 {
195 if (defined('HHVM_VERSION')) {
196 $this->markTestSkipped('Not supported in HHVM since it detects errors differently');
197 }
198
199 // This happens i.e. in React promises or Guzzle streams where stream wrappers are registered
200 // and no file or line are included in the trace because it's treated as internal function
201 set_error_handler(function ($errno, $errstr, $errfile, $errline) {
202 throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
203 });
204
205 try {
206 // This will contain $resource and $wrappedResource as arguments in the trace item
207 $resource = fopen('php://memory', 'rw+');
208 fwrite($resource, 'test_resource');
209 $wrappedResource = new TestFooNorm;
210 $wrappedResource->foo = $resource;
211 // Just do something stupid with a resource/wrapped resource as argument
212 array_keys($wrappedResource);
213 } catch (\Exception $e) {
214 restore_error_handler();
215 }
216
217 $formatter = new NormalizerFormatter();
218 $record = array('context' => array('exception' => $e));
219 $result = $formatter->format($record);
220
221 $this->assertRegExp(
222 '%"resource":"\[resource\]"%',
223 $result['context']['exception']['trace'][0]
224 );
225
226 if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
227 $pattern = '%"wrappedResource":"\[object\] \‍(Monolog\\\\\\\\Formatter\\\\\\\\TestFooNorm: \‍)"%';
228 } else {
229 $pattern = '%\\\\"foo\\\\":null%';
230 }
231
232 // Tests that the wrapped resource is ignored while encoding, only works for PHP <= 5.4
233 $this->assertRegExp(
234 $pattern,
235 $result['context']['exception']['trace'][0]
236 );
237 }
238}
239
241{
242 public $foo = 'foo';
243}
244
246{
247 public function __toString()
248 {
249 return 'bar';
250 }
251}
252
254{
255 public $foo;
256 public $resource;
257
258 public function __construct($resource)
259 {
260 $this->resource = $resource;
261 $this->foo = 'BAR';
262 }
263
264 public function __toString()
265 {
266 fseek($this->resource, 0);
267
268 return $this->foo . ' - ' . (string) stream_get_contents($this->resource);
269 }
270}
$result
print $file
@covers Monolog\Formatter\NormalizerFormatter
testThrowsOnInvalidEncoding()
@expectedException RuntimeException
Normalizes incoming records to remove objects/resources so it's easier to dump to various targets.