Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
48 / 48 |
|
100.00% |
4 / 4 |
CRAP | |
100.00% |
1 / 1 |
AppTesting | |
100.00% |
48 / 48 |
|
100.00% |
4 / 4 |
13 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
suppressOutputBuffer | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
runCli | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
runHttp | |
100.00% |
31 / 31 |
|
100.00% |
1 / 1 |
9 |
1 | <?php declare(strict_types=1); |
2 | /* |
3 | * This file is part of Aplus Framework Testing Library. |
4 | * |
5 | * (c) Natan Felles <natanfelles@gmail.com> |
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 Framework\Testing; |
11 | |
12 | use Closure; |
13 | use Framework\CLI\Streams\Stderr; |
14 | use Framework\CLI\Streams\Stdout; |
15 | use Framework\Config\Config; |
16 | use Framework\HTTP\URL; |
17 | use Framework\MVC\App; |
18 | |
19 | /** |
20 | * Class AppTesting. |
21 | * |
22 | * @package testing |
23 | */ |
24 | class AppTesting |
25 | { |
26 | protected App $app; |
27 | |
28 | /** |
29 | * AppTesting constructor. |
30 | * |
31 | * @param Config $config |
32 | */ |
33 | public function __construct(Config $config) |
34 | { |
35 | $this->app = new class($config) extends App { |
36 | public function runCliWithExec(string $command) : void |
37 | { |
38 | $this->prepareToRun(); |
39 | static::console()->exec($command); |
40 | } |
41 | }; |
42 | } |
43 | |
44 | /** |
45 | * Run App in a Closure suppressing the output buffer. |
46 | * |
47 | * It avoids buffer to be output in the PHPUnit terminal. |
48 | * |
49 | * @param Closure $closure |
50 | */ |
51 | protected function suppressOutputBuffer(Closure $closure) : void |
52 | { |
53 | \ob_start(static function () { |
54 | return ''; |
55 | }); |
56 | $closure($this->app); |
57 | \ob_end_clean(); |
58 | } |
59 | |
60 | /** |
61 | * Simulate a CLI request for tests. |
62 | * |
63 | * @param string $command Command line |
64 | * @param array<string,string> $env Environment variables |
65 | * |
66 | * @return void |
67 | */ |
68 | public function runCli(string $command, array $env = []) : void |
69 | { |
70 | App::setIsCli(true); |
71 | Stderr::init(); |
72 | Stdout::init(); |
73 | $this->suppressOutputBuffer(static function (App $app) use ($command) : void { |
74 | if ($command === '') { |
75 | $command = 'index'; |
76 | } |
77 | $app->runCliWithExec($command); // @phpstan-ignore-line |
78 | }); |
79 | } |
80 | |
81 | /** |
82 | * Simulate an HTTP Request for tests. |
83 | * |
84 | * @param string|URL $url |
85 | * @param string $method |
86 | * @param array<string,string> $headers |
87 | * @param string $body |
88 | * |
89 | * @return void |
90 | */ |
91 | public function runHttp( |
92 | URL | string $url, |
93 | string $method = 'GET', |
94 | array $headers = [], |
95 | string $body = '' |
96 | ) : void { |
97 | App::setIsCli(false); |
98 | if ( ! $url instanceof URL) { |
99 | $url = new URL($url); |
100 | } |
101 | $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1'; |
102 | $_SERVER['REQUEST_METHOD'] = \strtoupper($method); |
103 | $_SERVER['REQUEST_SCHEME'] = $url->getScheme(); |
104 | $_SERVER['HTTP_HOST'] = $url->getHost(); |
105 | $query = $url->getQuery(); |
106 | $query = $query === null ? '' : '?' . $query; |
107 | $_SERVER['REQUEST_URI'] = $url->getPath() . $query; |
108 | foreach ($headers as $name => $value) { |
109 | $name = \strtoupper($name); |
110 | $name = \strtr($name, ['-' => '_']); |
111 | $_SERVER['HTTP_' . $name] = $value; |
112 | } |
113 | if (isset($_SERVER['HTTP_COOKIE'])) { |
114 | $cookies = \explode(';', $_SERVER['HTTP_COOKIE']); |
115 | foreach ($cookies as $cookie) { |
116 | $cookie = \explode('=', $cookie, 2); |
117 | $cookie = \array_pad($cookie, 2, ''); |
118 | $cookie[0] = \ltrim($cookie[0]); |
119 | $cookie[0] = \strtr($cookie[0], [' ' => '_']); |
120 | $_COOKIE[$cookie[0]] = $cookie[1]; |
121 | } |
122 | } |
123 | $_GET = $url->getQueryData(); |
124 | App::request()->setBody($body); // @phpstan-ignore-line |
125 | if ($_SERVER['REQUEST_METHOD'] === 'POST' |
126 | && isset($_SERVER['HTTP_CONTENT_TYPE']) |
127 | && $_SERVER['HTTP_CONTENT_TYPE'] === 'application/x-www-form-urlencoded' |
128 | ) { |
129 | \parse_str($body, $_POST); |
130 | } |
131 | $this->suppressOutputBuffer(static function (App $app) : void { |
132 | $app->runHttp(); |
133 | }); |
134 | } |
135 | } |