Skip to content

Commit 2aa85e2

Browse files
author
Sebastian Bergmann
committed
Refactor
1 parent cea45c4 commit 2aa85e2

File tree

12 files changed

+266
-237
lines changed

12 files changed

+266
-237
lines changed

src/Event/Value/TestSuite/TestSuiteBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use PHPUnit\Framework\DataProviderTestSuite;
2020
use PHPUnit\Framework\TestCase;
2121
use PHPUnit\Framework\TestSuite as FrameworkTestSuite;
22-
use PHPUnit\Runner\PhptTestCase;
22+
use PHPUnit\Runner\Phpt\TestCase as PhptTestCase;
2323
use ReflectionClass;
2424
use ReflectionMethod;
2525

src/Framework/TestSuite.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
use PHPUnit\Metadata\MetadataCollection;
3838
use PHPUnit\Runner\Exception as RunnerException;
3939
use PHPUnit\Runner\Filter\Factory;
40-
use PHPUnit\Runner\PhptTestCase;
40+
use PHPUnit\Runner\Phpt\TestCase as PhptTestCase;
4141
use PHPUnit\Runner\TestSuiteLoader;
4242
use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade;
4343
use PHPUnit\Util\Filter;

src/Runner/Filter/GroupFilterIterator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use PHPUnit\Framework\Test;
1616
use PHPUnit\Framework\TestCase;
1717
use PHPUnit\Framework\TestSuite;
18-
use PHPUnit\Runner\PhptTestCase;
18+
use PHPUnit\Runner\Phpt\TestCase as PhptTestCase;
1919
use RecursiveFilterIterator;
2020
use RecursiveIterator;
2121

src/Runner/Filter/NameFilterIterator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use function substr;
1717
use PHPUnit\Framework\Test;
1818
use PHPUnit\Framework\TestSuite;
19-
use PHPUnit\Runner\PhptTestCase;
19+
use PHPUnit\Runner\Phpt\TestCase as PhptTestCase;
2020
use RecursiveFilterIterator;
2121
use RecursiveIterator;
2222

src/Runner/Filter/TestIdFilterIterator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use PHPUnit\Framework\Test;
1515
use PHPUnit\Framework\TestCase;
1616
use PHPUnit\Framework\TestSuite;
17-
use PHPUnit\Runner\PhptTestCase;
17+
use PHPUnit\Runner\Phpt\TestCase as PhptTestCase;
1818
use RecursiveFilterIterator;
1919
use RecursiveIterator;
2020

src/Runner/PHPT/Parser.php

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <sebastian@phpunit.de>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\Runner\Phpt;
11+
12+
use const DIRECTORY_SEPARATOR;
13+
use function assert;
14+
use function dirname;
15+
use function explode;
16+
use function file;
17+
use function file_get_contents;
18+
use function is_array;
19+
use function is_file;
20+
use function is_readable;
21+
use function is_string;
22+
use function preg_match;
23+
use function rtrim;
24+
use function str_contains;
25+
use function trim;
26+
use PHPUnit\Runner\Exception;
27+
use PHPUnit\Runner\InvalidPhptFileException;
28+
use PHPUnit\Runner\PhptExternalFileCannotBeLoadedException;
29+
use PHPUnit\Runner\UnsupportedPhptSectionException;
30+
31+
/**
32+
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
33+
*
34+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
35+
*
36+
* @see https://qa.php.net/phpt_details.php
37+
*/
38+
final readonly class Parser
39+
{
40+
/**
41+
* @param non-empty-string $phptFile
42+
*
43+
* @throws Exception
44+
*
45+
* @return array<non-empty-string, non-empty-string>
46+
*/
47+
public function parse(string $phptFile): array
48+
{
49+
$sections = [];
50+
$section = '';
51+
52+
$unsupportedSections = [
53+
'CGI',
54+
'COOKIE',
55+
'DEFLATE_POST',
56+
'EXPECTHEADERS',
57+
'EXTENSIONS',
58+
'GET',
59+
'GZIP_POST',
60+
'HEADERS',
61+
'PHPDBG',
62+
'POST',
63+
'POST_RAW',
64+
'PUT',
65+
'REDIRECTTEST',
66+
'REQUEST',
67+
];
68+
69+
$lineNr = 0;
70+
71+
foreach (file($phptFile) as $line) {
72+
$lineNr++;
73+
74+
if (preg_match('/^--([_A-Z]+)--/', $line, $result)) {
75+
$section = $result[1];
76+
$sections[$section] = '';
77+
$sections[$section . '_offset'] = $lineNr;
78+
79+
continue;
80+
}
81+
82+
if ($section === '') {
83+
throw new InvalidPhptFileException;
84+
}
85+
86+
$sections[$section] .= $line;
87+
}
88+
89+
if (isset($sections['FILEEOF'])) {
90+
$sections['FILE'] = rtrim($sections['FILEEOF'], "\r\n");
91+
92+
unset($sections['FILEEOF']);
93+
}
94+
95+
$this->parseExternal($phptFile, $sections);
96+
$this->validate($sections);
97+
98+
foreach ($unsupportedSections as $unsupportedSection) {
99+
if (isset($sections[$unsupportedSection])) {
100+
throw new UnsupportedPhptSectionException($unsupportedSection);
101+
}
102+
}
103+
104+
return $sections;
105+
}
106+
107+
/**
108+
* @return array<non-empty-string, non-empty-string>
109+
*/
110+
public function parseEnvSection(string $content): array
111+
{
112+
$env = [];
113+
114+
foreach (explode("\n", trim($content)) as $e) {
115+
$e = explode('=', trim($e), 2);
116+
117+
if ($e[0] !== '' && isset($e[1])) {
118+
$env[$e[0]] = $e[1];
119+
}
120+
}
121+
122+
return $env;
123+
}
124+
125+
/**
126+
* @param array<string>|string $content
127+
* @param array<non-empty-string, array<non-empty-string>|non-empty-string> $ini
128+
*
129+
* @return array<non-empty-string, array<non-empty-string>|non-empty-string>
130+
*/
131+
public function parseIniSection(array|string $content, array $ini = []): array
132+
{
133+
if (is_string($content)) {
134+
$content = explode("\n", trim($content));
135+
}
136+
137+
foreach ($content as $setting) {
138+
if (!str_contains($setting, '=')) {
139+
continue;
140+
}
141+
142+
$setting = explode('=', $setting, 2);
143+
$name = trim($setting[0]);
144+
$value = trim($setting[1]);
145+
146+
if ($name === 'extension' || $name === 'zend_extension') {
147+
if (!isset($ini[$name])) {
148+
$ini[$name] = [];
149+
}
150+
151+
$ini[$name][] = $value;
152+
153+
continue;
154+
}
155+
156+
$ini[$name] = $value;
157+
}
158+
159+
return $ini;
160+
}
161+
162+
/**
163+
* @param non-empty-string $phptFile
164+
* @param array<non-empty-string, non-empty-string> $sections
165+
*
166+
* @throws Exception
167+
*/
168+
private function parseExternal(string $phptFile, array &$sections): void
169+
{
170+
$allowSections = [
171+
'FILE',
172+
'EXPECT',
173+
'EXPECTF',
174+
'EXPECTREGEX',
175+
];
176+
177+
$testDirectory = dirname($phptFile) . DIRECTORY_SEPARATOR;
178+
179+
foreach ($allowSections as $section) {
180+
if (isset($sections[$section . '_EXTERNAL'])) {
181+
$externalFilename = trim($sections[$section . '_EXTERNAL']);
182+
183+
if (!is_file($testDirectory . $externalFilename) ||
184+
!is_readable($testDirectory . $externalFilename)) {
185+
throw new PhptExternalFileCannotBeLoadedException(
186+
$section,
187+
$testDirectory . $externalFilename,
188+
);
189+
}
190+
191+
$contents = file_get_contents($testDirectory . $externalFilename);
192+
193+
assert($contents !== false && $contents !== '');
194+
195+
$sections[$section] = $contents;
196+
}
197+
}
198+
}
199+
200+
/**
201+
* @param array<non-empty-string, non-empty-string> $sections
202+
*
203+
* @throws InvalidPhptFileException
204+
*/
205+
private function validate(array $sections): void
206+
{
207+
$requiredSections = [
208+
'FILE',
209+
[
210+
'EXPECT',
211+
'EXPECTF',
212+
'EXPECTREGEX',
213+
],
214+
];
215+
216+
foreach ($requiredSections as $section) {
217+
if (is_array($section)) {
218+
$foundSection = false;
219+
220+
foreach ($section as $anySection) {
221+
if (isset($sections[$anySection])) {
222+
$foundSection = true;
223+
224+
break;
225+
}
226+
}
227+
228+
if (!$foundSection) {
229+
throw new InvalidPhptFileException;
230+
}
231+
232+
continue;
233+
}
234+
235+
if (!isset($sections[$section])) {
236+
throw new InvalidPhptFileException;
237+
}
238+
}
239+
}
240+
}

0 commit comments

Comments
 (0)