Completed
Push — master ( 588d10...6487a1 )
by Alessandro
10:24
created

LogPrinter::addIncompleteTest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 12
Ratio 100 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 12
loc 12
ccs 7
cts 7
cp 1
rs 9.4285
cc 1
eloc 8
nc 1
nop 3
crap 1
1
<?php
2
3
namespace Paraunit\Parser\JSON;
4
5
use Paraunit\Configuration\StaticOutputPath;
6
7
/**
8
 * This class comes from \PHPUnit_Util_Log_JSON.
9
 * It's copied and refactored here because it's deprecated in PHPUnit 5.7 and it will be dropped in PHPUnit 6
10
 *
11
 * Class LogPrinter
12
 * @package Paraunit\Parser\JSON
13
 */
14
class LogPrinter extends \PHPUnit_Util_Printer implements \PHPUnit_Framework_TestListener
15
{
16
    /** @var string */
17
    private $logDirectory;
18
19
    /** @var int */
20
    private $testSuiteLevel;
21
22
    /** @var string */
23
    private $currentTestSuiteName;
24
25
    /** @var string */
26
    private $currentTestName;
27
28
    /** @var bool */
29
    private $currentTestPass;
30
31
    /**
32
     * LogPrinter constructor.
33
     */
34 10
    public function __construct()
35
    {
36 10
        $this->logDirectory = null;
37 10
        $this->testSuiteLevel = 0;
38 10
    }
39
40
    /**
41
     * An error occurred.
42
     *
43
     * @param \PHPUnit_Framework_Test $test
44
     * @param \Exception              $e
45
     * @param float                   $time
46
     */
47 1
    public function addError(\PHPUnit_Framework_Test $test, \Exception $e, $time)
48
    {
49 1
        $this->writeCase(
50 1
            'error',
51
            $time,
52 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...
53 1
            \PHPUnit_Framework_TestFailure::exceptionToString($e),
54
            $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...
55
        );
56
57 1
        $this->currentTestPass = false;
58 1
    }
59
60
    /**
61
     * A warning occurred.
62
     *
63
     * @param \PHPUnit_Framework_Test    $test
64
     * @param \PHPUnit_Framework_Warning $e
65
     * @param float                      $time
66
     */
67 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...
68
    {
69 1
        $this->writeCase(
70 1
            'warning',
71
            $time,
72 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...
73 1
            \PHPUnit_Framework_TestFailure::exceptionToString($e),
74
            $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...
75
        );
76
77 1
        $this->currentTestPass = false;
78 1
    }
79
80
    /**
81
     * A failure occurred.
82
     *
83
     * @param \PHPUnit_Framework_Test                 $test
84
     * @param \PHPUnit_Framework_AssertionFailedError $e
85
     * @param float                                   $time
86
     */
87 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...
88
    {
89 1
        $this->writeCase(
90 1
            'fail',
91
            $time,
92 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...
93 1
            \PHPUnit_Framework_TestFailure::exceptionToString($e),
94
            $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...
95
        );
96
97 1
        $this->currentTestPass = false;
98 1
    }
99
100
    /**
101
     * Incomplete test.
102
     *
103
     * @param \PHPUnit_Framework_Test $test
104
     * @param \Exception              $e
105
     * @param float                   $time
106
     */
107 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...
108
    {
109 1
        $this->writeCase(
110 1
            'error',
111
            $time,
112 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...
113 1
            'Incomplete Test: ' . $e->getMessage(),
114
            $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...
115
        );
116
117 1
        $this->currentTestPass = false;
118 1
    }
119
120
    /**
121
     * Risky test.
122
     *
123
     * @param \PHPUnit_Framework_Test $test
124
     * @param \Exception              $e
125
     * @param float                   $time
126
     */
127 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...
128
    {
129 1
        $this->writeCase(
130 1
            'error',
131
            $time,
132 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...
133 1
            'Risky Test: ' . $e->getMessage(),
134
            $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...
135
        );
136
137 1
        $this->currentTestPass = false;
138 1
    }
139
140
    /**
141
     * Skipped test.
142
     *
143
     * @param \PHPUnit_Framework_Test $test
144
     * @param \Exception              $e
145
     * @param float                   $time
146
     */
147 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...
148
    {
149 1
        $this->writeCase(
150 1
            'error',
151
            $time,
152 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...
153 1
            'Skipped Test: ' . $e->getMessage(),
154
            $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...
155
        );
156
157 1
        $this->currentTestPass = false;
158 1
    }
159
160
    /**
161
     * A testsuite started.
162
     *
163
     * @param \PHPUnit_Framework_TestSuite $suite
164
     * @throws \RuntimeException
165
     */
166 9
    public function startTestSuite(\PHPUnit_Framework_TestSuite $suite)
167
    {
168 9
        if ($this->testSuiteLevel === 0) {
169 9
            $logFilename = $this->getLogFilename($suite);
170
171 9
            $logDir = dirname($logFilename);
172 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...
173
                throw new \RuntimeException('Cannot create folder for JSON logs');
174
            }
175
176 9
            $this->out = fopen($logFilename, 'wt');
177
        }
178
179 9
        $this->testSuiteLevel++;
180 9
        $this->currentTestSuiteName = $suite->getName();
181 9
        $this->currentTestName      = '';
182
183 9
        $this->writeArray(
184
            array(
185 9
                'event' => 'suiteStart',
186 9
                'suite' => $this->currentTestSuiteName,
187 9
                'tests' => count($suite)
188
            )
189
        );
190 9
    }
191
192
    /**
193
     * A testsuite ended.
194
     *
195
     * @param \PHPUnit_Framework_TestSuite $suite
196
     */
197 1
    public function endTestSuite(\PHPUnit_Framework_TestSuite $suite)
198
    {
199 1
        $this->testSuiteLevel--;
200 1
        $this->currentTestSuiteName = '';
201 1
        $this->currentTestName      = '';
202 1
    }
203
204
    /**
205
     * A test started.
206
     *
207
     * @param \PHPUnit_Framework_Test $test
208
     */
209 7
    public function startTest(\PHPUnit_Framework_Test $test)
210
    {
211 7
        $this->currentTestName = \PHPUnit_Util_Test::describe($test);
212 7
        $this->currentTestPass = true;
213
214 7
        $this->writeArray(
215
            array(
216 7
                'event' => 'testStart',
217 7
                'suite' => $this->currentTestSuiteName,
218 7
                'test'  => $this->currentTestName
219
            )
220
        );
221 7
    }
222
223
    /**
224
     * A test ended.
225
     *
226
     * @param \PHPUnit_Framework_Test $test
227
     * @param float                  $time
228
     */
229 1
    public function endTest(\PHPUnit_Framework_Test $test, $time)
230
    {
231 1
        if ($this->currentTestPass) {
232 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...
233
        }
234 1
    }
235
236
    /**
237
     * @param string                           $status
238
     * @param float                            $time
239
     * @param array                            $trace
240
     * @param string                           $message
241
     * @param \PHPUnit_Framework_TestCase|null $test
242
     */
243 7
    protected function writeCase($status, $time, array $trace = array(), $message = '', $test = null)
244
    {
245 7
        $output = '';
246
        // take care of TestSuite producing error (e.g. by running into exception) as TestSuite doesn't have hasOutput
247 7
        if ($test !== null && method_exists($test, 'hasOutput') && $test->hasOutput()) {
248
            $output = $test->getActualOutput();
249
        }
250 7
        $this->writeArray(
251
            array(
252 7
                'event'   => 'test',
253 7
                'suite'   => $this->currentTestSuiteName,
254 7
                'test'    => $this->currentTestName,
255 7
                'status'  => $status,
256 7
                'time'    => $time,
257 7
                'trace'   => $trace,
258 7
                'message' => \PHPUnit_Util_String::convertToUtf8($message),
259 7
                'output'  => $output,
260
            )
261
        );
262 7
    }
263
264
    /**
265
     * @param array $buffer
266
     */
267
    public function writeArray($buffer)
268
    {
269 9
        array_walk_recursive($buffer, function (&$input) {
270 9
            if (is_string($input)) {
271 9
                $input = \PHPUnit_Util_String::convertToUtf8($input);
272
            }
273 9
        });
274
275 9
        $flags = 0;
276
277 9
        if (defined('JSON_PRETTY_PRINT')) {
278 9
            $flags |= JSON_PRETTY_PRINT;
279
        }
280
281 9
        $this->write(json_encode($buffer, $flags));
282 9
    }
283
284
    /**
285
     * @param \PHPUnit_Framework_TestSuite $suite
286
     * @return string
287
     */
288 10
    private function getLogFilename(\PHPUnit_Framework_TestSuite $suite)
289
    {
290 10
        $testFilename = $this->getTestFilename($suite);
291
        
292 10
        return $this->getLogDirectory() . md5($testFilename) . '.json.log';
293
    }
294
295
    /**
296
     * @param \PHPUnit_Framework_TestSuite $suite
297
     * @return string
298
     */
299 10
    private function getTestFilename(\PHPUnit_Framework_TestSuite $suite)
300
    {
301 10
        $reflection = new \ReflectionClass($suite->getName());
302
        
303 10
        return $reflection->getFileName();
304
    }
305
306
    /**
307
     * @return string
308
     */
309 10
    private function getLogDirectory()
310
    {
311 10
        $this->logDirectory = StaticOutputPath::getPath();
312 10
        if (substr($this->logDirectory, -1) !== DIRECTORY_SEPARATOR) {
313 10
            $this->logDirectory .= DIRECTORY_SEPARATOR;
314
        }
315
316 10
        return $this->logDirectory;
317
    }
318
}
319