Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
PhpUnitFailure
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 3
210
0.00% covered (danger)
0.00%
0 / 1
 getFailureDetails
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 empty
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 processLine
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
132
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Composer\PhpUnitSplitter;
5
6class PhpUnitFailure {
7
8    private const STATE_EXPECT_TEST_ID_AND_NAME = 0;
9    private const STATE_EXPECT_FAILURE_DETAIL = 1;
10    private const STATE_EXPECT_LOGS = 2;
11
12    private int $failureNumber = 0;
13    private string $testCase;
14    private ?string $dataSet = null;
15    private ?string $failureDetail;
16    private ?string $logs;
17    private int $state = self::STATE_EXPECT_TEST_ID_AND_NAME;
18
19    public function getFailureDetails(): ?string {
20        $result = $this->failureNumber . ") " . $this->testCase;
21        if ( $this->dataSet ) {
22            $result .= " with data set " . $this->dataSet;
23        }
24        $result .= PHP_EOL;
25        $result .= $this->failureDetail;
26        return $result;
27    }
28
29    public function empty(): bool {
30        return $this->failureNumber === 0;
31    }
32
33    /**
34     * @throws PhpUnitConsoleOutputProcessingException
35     */
36    public function processLine( string $line ): bool {
37        $matches = [];
38        switch ( $this->state ) {
39            case self::STATE_EXPECT_TEST_ID_AND_NAME:
40                if ( preg_match(
41                    "/^(\d+)\) (.*::[^\b]+)( with data set (.*))?$/",
42                    $line,
43                    $matches,
44                    PREG_UNMATCHED_AS_NULL
45                ) ) {
46                    $this->failureNumber = intval( $matches[1] );
47                    $this->testCase = $matches[2];
48                    if ( $matches[3] !== null ) {
49                        $this->dataSet = $matches[4];
50                    }
51                    $this->state = self::STATE_EXPECT_FAILURE_DETAIL;
52                    $this->failureDetail = "";
53                }
54                break;
55
56            case self::STATE_EXPECT_FAILURE_DETAIL:
57                if ( $line === "=== Logs generated by test case" ) {
58                    $this->state = self::STATE_EXPECT_LOGS;
59                    $this->logs = "";
60                    break;
61                }
62                if ( preg_match( "/^(\d+)\) (.*::[^\b]+)/", $line ) ) {
63                    // Start of next error case
64                    return false;
65                }
66                $this->failureDetail .= $line . PHP_EOL;
67                break;
68
69            case self::STATE_EXPECT_LOGS:
70                if ( preg_match( "/^(\d+)\) (.*::[^\b]+)/", $line ) ||
71                    $line === "===" ) {
72                    // Start of next error case
73                    return false;
74                }
75                $this->logs .= $line . PHP_EOL;
76                break;
77
78            default:
79                throw new PhpUnitConsoleOutputProcessingException(
80                    "Unexpected processing state " . $this->state
81                );
82        }
83        return true;
84    }
85}