PHPUnitJSONReporter::endTestSuite()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 0
c 1
b 0
f 0
dl 0
loc 2
ccs 0
cts 1
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Debug\Api\Inspector\Test;
6
7
use PHPUnit\Framework\AssertionFailedError;
8
use PHPUnit\Framework\Test;
9
use PHPUnit\Framework\TestCase;
10
use PHPUnit\Framework\TestResult;
11
use PHPUnit\Framework\TestSuite;
12
use PHPUnit\Framework\Warning;
13
use PHPUnit\Runner\BaseTestRunner;
14
use PHPUnit\TextUI\ResultPrinter;
15
use PHPUnit\Util\TestDox\NamePrettifier;
16
use ReflectionClass;
17
use Throwable;
18
19
/**
20
 * @psalm-suppress InternalClass, InternalMethod
21
 */
22
class PHPUnitJSONReporter implements ResultPrinter
23
{
24
    public const FILENAME = 'phpunit-report.json';
25
    public const ENVIRONMENT_VARIABLE_DIRECTORY_NAME = 'REPORTER_OUTPUT_PATH';
26
27
    private array $data = [];
28
    private NamePrettifier $prettifier;
29
30
    public function __construct()
31
    {
32
        $this->prettifier = new NamePrettifier();
33
    }
34
35
    public function printResult(TestResult $result): void
36
    {
37
        $path = getenv(self::ENVIRONMENT_VARIABLE_DIRECTORY_NAME) ?: getcwd();
38
        ksort($this->data);
39
40
        file_put_contents(
41
            $path . DIRECTORY_SEPARATOR . self::FILENAME,
42
            json_encode(array_values($this->data), JSON_THROW_ON_ERROR)
43
        );
44
    }
45
46
    public function write(string $buffer): void
47
    {
48
        $this->data = [];
49
    }
50
51
    public function addError(Test $test, Throwable $t, float $time): void
52
    {
53
        $this->logErroredTest($test, $t);
54
    }
55
56
    public function addWarning(Test $test, Warning $e, float $time): void
57
    {
58
        $this->logErroredTest($test, $e);
59
    }
60
61
    public function addFailure(Test $test, AssertionFailedError $e, float $time): void
62
    {
63
        $this->logErroredTest($test, $e);
64
    }
65
66
    public function addIncompleteTest(Test $test, Throwable $t, float $time): void
67
    {
68
        $this->logErroredTest($test, $t);
69
    }
70
71
    public function addRiskyTest(Test $test, Throwable $t, float $time): void
72
    {
73
        $this->logErroredTest($test, $t);
74
    }
75
76
    public function addSkippedTest(Test $test, Throwable $t, float $time): void
77
    {
78
        $this->logErroredTest($test, $t);
79
    }
80
81
    public function startTestSuite(TestSuite $suite): void
82
    {
83
    }
84
85
    public function endTestSuite(TestSuite $suite): void
86
    {
87
    }
88
89
    public function startTest(Test $test): void
90
    {
91
    }
92
93
    public function endTest(Test $test, float $time): void
94
    {
95
        if (!$test instanceof TestCase) {
96
            return;
97
        }
98
        if ($test->getStatus() !== BaseTestRunner::STATUS_PASSED) {
99
            return;
100
        }
101
102
        $parsedName = $this->parseName($test);
103
104
        $this->data[$parsedName] = [
105
            'file' => $this->parseFilename($test),
106
            'test' => $parsedName,
107
            'status' => 'ok',
108
            'stacktrace' => [],
109
        ];
110
    }
111
112
    private function parseName(Test $test): string
113
    {
114
        if ($test instanceof TestCase) {
115
            return $test::class . '::' . $test->getName(true);
116
        }
117
        return $this->prettifier->prettifyTestClass($test::class);
118
    }
119
120
    private function parseFilename(Test $test): string
121
    {
122
        $reflection = new ReflectionClass($test);
123
124
        return $reflection->getFileName();
125
    }
126
127
    private function logErroredTest(Test $test, Throwable $t): void
128
    {
129
        $parsedName = $this->parseName($test);
130
131
        $this->data[$parsedName] = [
132
            'file' => $this->parseFilename($test),
133
            'test' => $parsedName,
134
            'status' => $t->getMessage(),
135
            'stacktrace' => $t->getTrace(),
136
        ];
137
    }
138
}
139