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 | } |