Skip to content

Commit

Permalink
replace echo with App::emitResponse()
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed Feb 28, 2023
1 parent b353374 commit 60e12f0
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 37 deletions.
40 changes: 34 additions & 6 deletions src/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -1091,19 +1091,17 @@ function () {
*/
protected function outputResponseUnsafe(string $data): void
{
http_response_code($this->response->getStatusCode());

$isCli = \PHP_SAPI === 'cli'; // for phpunit
/* $isCli = \PHP_SAPI === 'cli'; // for phpunit
/* if (count($headersNew) > 0 && headers_sent() && !$isCli) {
if (count($headersNew) > 0 && headers_sent() && !$isCli) {
$lateError = new LateOutputError('Headers already sent, more headers cannot be set at this stage');
if ($this->catchExceptions) {
$this->caughtException($lateError);
$this->outputLateOutputError($lateError);
}
throw $lateError;
} */
}
if (!headers_sent() || $isCli) {
foreach ($this->response->getHeaders() as $name => $values) {
Expand All @@ -1113,9 +1111,39 @@ protected function outputResponseUnsafe(string $data): void
}
}
}
} */

$this->response->getBody()->write($data);

$this->emitResponse();
}

/**
* @internal should be called only from self::outputResponseUnsafe()
*/
protected function emitResponse(): void
{
http_response_code($this->response->getStatusCode());

foreach ($this->response->getHeaders() as $name => $values) {
foreach ($values as $value) {
header($name . ': ' . $value, false);
}
}

echo $data;
$stream = $this->response->getBody();
if ($stream->isSeekable()) {
$stream->rewind();
}

// for streaming response
if (!$stream->isReadable()) {
return;
}

while (!$stream->eof()) {
echo $stream->read(4096);
}
}

/**
Expand Down
47 changes: 16 additions & 31 deletions tests/DemosTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
use Atk4\Ui\Layout;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\Utils;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

Expand Down Expand Up @@ -136,6 +134,10 @@ public function callExit(): void
{
throw new DemosTestExitError();
}

protected function emitResponse(): void
{
}
};
$app->initLayout([Layout\Maestro::class]);

Expand Down Expand Up @@ -167,44 +169,27 @@ protected function getClient(): Client
ob_start();
try {
$app = $this->createTestingApp();
require $localPath;

if (!$app->runCalled) {
$app->run();
}
try {
require $localPath;

$this->assertNoGlobalSticky($app);
} catch (\Throwable $e) {
// session_start() or ini_set() functions can be used only with native HTTP tests
// override test expectation here to finish there tests cleanly (TODO better to make the code testable without calling these functions)
// TODO impl. volatile session manager for unit testing
if ($e instanceof \ErrorException && preg_match('~^(session_start|ini_set)\(\).* headers already sent$~', $e->getMessage())) {
$this->expectExceptionObject($e);
}
if (!$app->runCalled) {
$app->run();
}

if (!$e instanceof DemosTestExitError) {
throw $e;
$this->assertNoGlobalSticky($app);
} catch (DemosTestExitError $e) {
}
} finally {
$body = ob_get_clean();
static::assertSame('', ob_get_clean());
$this->resetSuperglobals();
}

// Attach a response to the easy handle with the parsed headers.
$response = new Response(
$app->getResponse()->getStatusCode(), // @phpstan-ignore-line
$app->getResponse()->getHeaders(), // @phpstan-ignore-line
class_exists(Utils::class) ? Utils::streamFor($body) : \GuzzleHttp\Psr7\stream_for($body), // @phpstan-ignore-line Utils class present since guzzlehttp/psr7 v1.7
'1.0'
);

// Rewind the body of the response if possible.
$body = $response->getBody();
if ($body->isSeekable()) {
$body->rewind();
// rewind the body of the response if possible
if ($app->getResponse()->getBody()->isSeekable()) {
$app->getResponse()->getBody()->rewind();
}

return new \GuzzleHttp\Promise\FulfilledPromise($response);
return new \GuzzleHttp\Promise\FulfilledPromise($app->getResponse());
};

return new Client(['base_uri' => 'http://localhost/', 'handler' => $handler]);
Expand Down

0 comments on commit 60e12f0

Please sign in to comment.