Completed
Push — master ( 979448...f8182d )
by Alessandro
05:10
created

LogPrinter::writeCase()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4.0058

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 20
ccs 13
cts 14
cp 0.9286
rs 9.2
cc 4
eloc 14
nc 2
nop 5
crap 4.0058
1
<?php
2
3
namespace Paraunit\Parser\JSON;
4
5
/**
6
 * This class comes from \PHPUnit_Util_Log_JSON.
7
 * It's copied and refactored here because it's deprecated in PHPUnit 5.7 and it will be dropped in PHPUnit 6
8
 *
9
 * Class LogPrinter
10
 * @package Paraunit\Parser\JSON
11
 */
12
class LogPrinter extends \PHPUnit_Util_Printer implements \PHPUnit_Framework_TestListener
13
{
14
    /** @var string */
15
    private $logDirectory;
16
17
    /** @var int */
18
    private $testSuiteLevel;
19
20
    /** @var string */
21
    private $currentTestSuiteName;
22
23
    /** @var string */
24
    private $currentTestName;
25
26
    /** @var bool */
27
    private $currentTestPass;
28
29
    /**
30
     * LogPrinter constructor.
31
     * @param mixed $out
32
     */
33 10
    public function __construct($out = null)
34
    {
35 10
        if (substr($out, -1) !== DIRECTORY_SEPARATOR) {
36 10
            $out .= DIRECTORY_SEPARATOR;
37
        }
38
39 10
        $this->logDirectory = $out;
40 10
        $this->testSuiteLevel = 0;
41 10
    }
42
43
    /**
44
     * An error occurred.
45
     *
46
     * @param \PHPUnit_Framework_Test $test
47
     * @param \Exception              $e
48
     * @param float                   $time
49
     */
50 1 View Code Duplication
    public function addError(\PHPUnit_Framework_Test $test, \Exception $e, $time)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
51
    {
52 1
        $this->writeCase(
53 1
            'error',
54
            $time,
55 1
            \PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
0 ignored issues
show
Bug introduced by
It seems like \PHPUnit_Util_Filter::ge...edStacktrace($e, false) targeting PHPUnit_Util_Filter::getFilteredStacktrace() can also be of type string; however, Paraunit\Parser\JSON\LogPrinter::writeCase() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
56 1
            \PHPUnit_Framework_TestFailure::exceptionToString($e),
57
            $test
0 ignored issues
show
Documentation introduced by
$test is of type object<PHPUnit_Framework_Test>, but the function expects a object<PHPUnit_Framework_TestCase>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
58
        );
59
60 1
        $this->currentTestPass = false;
61 1
    }
62
63
    /**
64
     * A warning occurred.
65
     *
66
     * @param \PHPUnit_Framework_Test    $test
67
     * @param \PHPUnit_Framework_Warning $e
68
     * @param float                      $time
69
     */
70 1 View Code Duplication
    public function addWarning(\PHPUnit_Framework_Test $test, \PHPUnit_Framework_Warning $e, $time)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
    {
72 1
        $this->writeCase(
73 1
            'warning',
74
            $time,
75 1
            \PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
0 ignored issues
show
Bug introduced by
It seems like \PHPUnit_Util_Filter::ge...edStacktrace($e, false) targeting PHPUnit_Util_Filter::getFilteredStacktrace() can also be of type string; however, Paraunit\Parser\JSON\LogPrinter::writeCase() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
76 1
            \PHPUnit_Framework_TestFailure::exceptionToString($e),
77
            $test
0 ignored issues
show
Documentation introduced by
$test is of type object<PHPUnit_Framework_Test>, but the function expects a object<PHPUnit_Framework_TestCase>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
78
        );
79
80 1
        $this->currentTestPass = false;
81 1
    }
82
83
    /**
84
     * A failure occurred.
85
     *
86
     * @param \PHPUnit_Framework_Test                 $test
87
     * @param \PHPUnit_Framework_AssertionFailedError $e
88
     * @param float                                   $time
89
     */
90 1 View Code Duplication
    public function addFailure(\PHPUnit_Framework_Test $test, \PHPUnit_Framework_AssertionFailedError $e, $time)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
    {
92 1
        $this->writeCase(
93 1
            'fail',
94
            $time,
95 1
            \PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
0 ignored issues
show
Bug introduced by
It seems like \PHPUnit_Util_Filter::ge...edStacktrace($e, false) targeting PHPUnit_Util_Filter::getFilteredStacktrace() can also be of type string; however, Paraunit\Parser\JSON\LogPrinter::writeCase() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
96 1
            \PHPUnit_Framework_TestFailure::exceptionToString($e),
97
            $test
0 ignored issues
show
Documentation introduced by
$test is of type object<PHPUnit_Framework_Test>, but the function expects a object<PHPUnit_Framework_TestCase>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
98
        );
99
100 1
        $this->currentTestPass = false;
101 1
    }
102
103
    /**
104
     * Incomplete test.
105
     *
106
     * @param \PHPUnit_Framework_Test $test
107
     * @param \Exception              $e
108
     * @param float                   $time
109
     */
110 1 View Code Duplication
    public function addIncompleteTest(\PHPUnit_Framework_Test $test, \Exception $e, $time)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
111
    {
112 1
        $this->writeCase(
113 1
            'error',
114
            $time,
115 1
            \PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
0 ignored issues
show
Bug introduced by
It seems like \PHPUnit_Util_Filter::ge...edStacktrace($e, false) targeting PHPUnit_Util_Filter::getFilteredStacktrace() can also be of type string; however, Paraunit\Parser\JSON\LogPrinter::writeCase() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
116 1
            'Incomplete Test: ' . $e->getMessage(),
117
            $test
0 ignored issues
show
Documentation introduced by
$test is of type object<PHPUnit_Framework_Test>, but the function expects a object<PHPUnit_Framework_TestCase>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
118
        );
119
120 1
        $this->currentTestPass = false;
121 1
    }
122
123
    /**
124
     * Risky test.
125
     *
126
     * @param \PHPUnit_Framework_Test $test
127
     * @param \Exception              $e
128
     * @param float                   $time
129
     */
130 1 View Code Duplication
    public function addRiskyTest(\PHPUnit_Framework_Test $test, \Exception $e, $time)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
    {
132 1
        $this->writeCase(
133 1
            'error',
134
            $time,
135 1
            \PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
0 ignored issues
show
Bug introduced by
It seems like \PHPUnit_Util_Filter::ge...edStacktrace($e, false) targeting PHPUnit_Util_Filter::getFilteredStacktrace() can also be of type string; however, Paraunit\Parser\JSON\LogPrinter::writeCase() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
136 1
            'Risky Test: ' . $e->getMessage(),
137
            $test
0 ignored issues
show
Documentation introduced by
$test is of type object<PHPUnit_Framework_Test>, but the function expects a object<PHPUnit_Framework_TestCase>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
138
        );
139
140 1
        $this->currentTestPass = false;
141 1
    }
142
143
    /**
144
     * Skipped test.
145
     *
146
     * @param \PHPUnit_Framework_Test $test
147
     * @param \Exception              $e
148
     * @param float                   $time
149
     */
150 1 View Code Duplication
    public function addSkippedTest(\PHPUnit_Framework_Test $test, \Exception $e, $time)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
151
    {
152 1
        $this->writeCase(
153 1
            'error',
154
            $time,
155 1
            \PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
0 ignored issues
show
Bug introduced by
It seems like \PHPUnit_Util_Filter::ge...edStacktrace($e, false) targeting PHPUnit_Util_Filter::getFilteredStacktrace() can also be of type string; however, Paraunit\Parser\JSON\LogPrinter::writeCase() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
156 1
            'Skipped Test: ' . $e->getMessage(),
157
            $test
0 ignored issues
show
Documentation introduced by
$test is of type object<PHPUnit_Framework_Test>, but the function expects a object<PHPUnit_Framework_TestCase>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
158
        );
159
160 1
        $this->currentTestPass = false;
161 1
    }
162
163
    /**
164
     * A testsuite started.
165
     *
166
     * @param \PHPUnit_Framework_TestSuite $suite
167
     * @throws \RuntimeException
168
     */
169 9
    public function startTestSuite(\PHPUnit_Framework_TestSuite $suite)
170
    {
171 9
        if ($this->testSuiteLevel === 0) {
172 9
            $logFilename = $this->getLogFilename($suite);
173
174 9
            $logDir = dirname($logFilename);
175 9 View Code Duplication
            if (! @mkdir($logDir, 0777, true) && !is_dir($logDir)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
176
                throw new \RuntimeException('Cannot create folder for JSON logs');
177
            }
178
179 9
            $this->out = fopen($logFilename, 'wt');
180
        }
181
182 9
        $this->testSuiteLevel++;
183 9
        $this->currentTestSuiteName = $suite->getName();
184 9
        $this->currentTestName      = '';
185
186 9
        $this->write(
187
            array(
0 ignored issues
show
Documentation introduced by
array('event' => 'suiteS...ests' => count($suite)) is of type array<string,string|inte...ng","tests":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
188 9
                'event' => 'suiteStart',
189 9
                'suite' => $this->currentTestSuiteName,
190 9
                'tests' => count($suite)
191
            )
192
        );
193 9
    }
194
195
    /**
196
     * A testsuite ended.
197
     *
198
     * @param \PHPUnit_Framework_TestSuite $suite
199
     */
200 1
    public function endTestSuite(\PHPUnit_Framework_TestSuite $suite)
201
    {
202 1
        $this->testSuiteLevel--;
203 1
        $this->currentTestSuiteName = '';
204 1
        $this->currentTestName      = '';
205 1
    }
206
207
    /**
208
     * A test started.
209
     *
210
     * @param \PHPUnit_Framework_Test $test
211
     */
212 7
    public function startTest(\PHPUnit_Framework_Test $test)
213
    {
214 7
        $this->currentTestName = \PHPUnit_Util_Test::describe($test);
215 7
        $this->currentTestPass = true;
216
217 7
        $this->write(
218
            array(
0 ignored issues
show
Documentation introduced by
array('event' => 'testSt...$this->currentTestName) is of type array<string,*,{"event":...":"string","test":"*"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
219 7
                'event' => 'testStart',
220 7
                'suite' => $this->currentTestSuiteName,
221 7
                'test'  => $this->currentTestName
222
            )
223
        );
224 7
    }
225
226
    /**
227
     * A test ended.
228
     *
229
     * @param \PHPUnit_Framework_Test $test
230
     * @param float                  $time
231
     */
232 1
    public function endTest(\PHPUnit_Framework_Test $test, $time)
233
    {
234 1
        if ($this->currentTestPass) {
235 1
            $this->writeCase('pass', $time, array(), '', $test);
0 ignored issues
show
Documentation introduced by
$test is of type object<PHPUnit_Framework_Test>, but the function expects a object<PHPUnit_Framework_TestCase>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
236
        }
237 1
    }
238
239
    /**
240
     * @param string                           $status
241
     * @param float                            $time
242
     * @param array                            $trace
243
     * @param string                           $message
244
     * @param \PHPUnit_Framework_TestCase|null $test
245
     */
246 7
    protected function writeCase($status, $time, array $trace = array(), $message = '', $test = null)
247
    {
248 7
        $output = '';
249
        // take care of TestSuite producing error (e.g. by running into exception) as TestSuite doesn't have hasOutput
250 7
        if ($test !== null && method_exists($test, 'hasOutput') && $test->hasOutput()) {
251
            $output = $test->getActualOutput();
252
        }
253 7
        $this->write(
254
            array(
0 ignored issues
show
Documentation introduced by
array('event' => 'test',...), 'output' => $output) is of type array<string,string|doub...ng","output":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
255 7
                'event'   => 'test',
256 7
                'suite'   => $this->currentTestSuiteName,
257 7
                'test'    => $this->currentTestName,
258 7
                'status'  => $status,
259 7
                'time'    => $time,
260 7
                'trace'   => $trace,
261 7
                'message' => \PHPUnit_Util_String::convertToUtf8($message),
262 7
                'output'  => $output,
263
            )
264
        );
265 7
    }
266
267
    /**
268
     * @param string $buffer
269
     */
270
    public function write($buffer)
271
    {
272 9
        array_walk_recursive($buffer, function (&$input) {
273 9
            if (is_string($input)) {
274 9
                $input = \PHPUnit_Util_String::convertToUtf8($input);
275
            }
276 9
        });
277
278 9
        $flags = 0;
279
280 9
        if (defined('JSON_PRETTY_PRINT')) {
281 9
            $flags |= JSON_PRETTY_PRINT;
282
        }
283
284 9
        parent::write(json_encode($buffer, $flags));
285 9
    }
286
287
    /**
288
     * @param \PHPUnit_Framework_TestSuite $suite
289
     * @return string
290
     */
291 10
    private function getLogFilename(\PHPUnit_Framework_TestSuite $suite)
292
    {
293 10
        $testFilename = $this->getTestFilename($suite);
294
        
295 10
        return $this->logDirectory . md5($testFilename) . '.json.log';
296
    }
297
298
    /**
299
     * @param \PHPUnit_Framework_TestSuite $suite
300
     * @return string
301
     */
302 10
    private function getTestFilename(\PHPUnit_Framework_TestSuite $suite)
303
    {
304 10
        $reflection = new \ReflectionClass($suite->getName());
305
        
306 10
        return $reflection->getFileName();
307
    }
308
}
309