-
Notifications
You must be signed in to change notification settings - Fork 5
/
ExamplesTest.php
116 lines (92 loc) 路 3.47 KB
/
ExamplesTest.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php
namespace M6WebExamplesTests\Tornado;
use PHPUnit\Framework\TestCase;
class ExamplesTest extends TestCase
{
private const EXAMPLES_DIR = __DIR__.'/../';
public function examplesProvider()
{
$iterator = new \FilesystemIterator(
self::EXAMPLES_DIR,
\FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME | \FilesystemIterator::SKIP_DOTS
);
foreach ($iterator as $name => $fileinfo) {
if ($fileinfo->isDir()) {
continue;
}
foreach ($this->extractExampleCode($fileinfo->getRealPath()) as $eventloopName => $code) {
yield "$name $eventloopName" => [$fileinfo->getRealPath(), $eventloopName, $code];
}
}
}
/**
* @dataProvider examplesProvider
*/
public function testExampleShouldRun(string $exampleFile, string $eventloopName, string $exampleCode): void
{
// Sanitize loop name to create a relevant temporary filename
$eventLoopFileId = preg_replace('/[^a-z0-9]+/', '', strtolower($eventloopName));
$tmpFilePath = tempnam(self::EXAMPLES_DIR, basename($exampleFile, '.php')."-$eventLoopFileId-");
try {
file_put_contents($tmpFilePath, $exampleCode);
$output = [];
$code = null;
exec("php $tmpFilePath", $output, $code);
$this->assertSame(0, $code);
$this->assertStringStartsWith("Let's start!", reset($output));
$this->assertStringEndsWith('Finished!', end($output));
} finally {
unlink($tmpFilePath);
}
}
private function extractExampleCode(string $exampleFile): iterable
{
$originalContent = file($exampleFile);
foreach ($this->selectEventLoop($originalContent) as $nameEL => $contentEL) {
$exampleUseHttpClient = false;
foreach ($this->selectHttpClient($contentEL) as $nameHC => $contentELHC) {
$exampleUseHttpClient = true;
yield "$nameEL - $nameHC" => implode('', $contentELHC);
}
if (!$exampleUseHttpClient) {
yield $nameEL => implode('', $contentEL);
}
}
}
/**
* Very naive approach to iterate over various eventLoop implementations.
*/
private function selectEventLoop(array $originalContent): iterable
{
foreach ($originalContent as &$line) {
if (false === strpos($line, '$eventLoop = new ')) {
continue;
}
// Extract relevant name
$name = strstr(strstr($line, '(', true), 'Adapter\\');
// Enable current eventLoop
$line = ltrim($line, '/');
yield $name => $originalContent;
// Disable this eventLoop
$line = "//$line";
}
}
/**
* Very naive approach to iterate over various httpClient implementations.
*/
private function selectHttpClient(array $originalContent): iterable
{
foreach ($originalContent as &$line) {
if (false === strpos($line, '$httpClient = new ')) {
continue;
}
// Extract relevant name
$name = strstr(strstr($line, '(', true), 'Adapter\\');
// Enable current eventLoop
$line = ltrim($line, '/');
yield $name => $originalContent;
// Disable this eventLoop
$line = "//$line";
}
}
}