Skip to content

Commit b6ab088

Browse files
authored
Merge pull request #622 from flightphp/new-request-object
Added ability to generate new requests/responses on duplicate start()
2 parents f411592 + 7dd52c9 commit b6ab088

File tree

7 files changed

+170
-28
lines changed

7 files changed

+170
-28
lines changed

flight/Engine.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ class Engine
9494
/** If the framework has been initialized or not. */
9595
protected bool $initialized = false;
9696

97+
/** If the request has been handled or not. */
98+
protected bool $requestHandled = false;
99+
97100
public function __construct()
98101
{
99102
$this->loader = new Loader();
@@ -476,6 +479,19 @@ public function _start(): void
476479
{
477480
$dispatched = false;
478481
$self = $this;
482+
483+
// This behavior is specifically for test suites, and for async platforms like swoole, workerman, etc.
484+
if ($this->requestHandled === false) {
485+
// not doing much here, just setting the requestHandled flag to true
486+
$this->requestHandled = true;
487+
} else {
488+
// deregister the request and response objects and re-register them with new instances
489+
$this->unregister('request');
490+
$this->unregister('response');
491+
$this->register('request', Request::class);
492+
$this->register('response', Response::class);
493+
$this->router()->reset();
494+
}
479495
$request = $this->request();
480496
$response = $this->response();
481497
$router = $this->router();
@@ -498,7 +514,6 @@ public function _start(): void
498514

499515
// Route the request
500516
$failedMiddlewareCheck = false;
501-
502517
while ($route = $router->route($request)) {
503518
$params = array_values($route->params);
504519

flight/net/Request.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@ public function init(array $properties = []): self
211211
$this->data->setData($data);
212212
}
213213
}
214-
// Check PUT, PATCH, DELETE for application/x-www-form-urlencoded data
215-
} else if (in_array($this->method, [ 'PUT', 'DELETE', 'PATCH' ], true) === true) {
214+
// Check PUT, PATCH, DELETE for application/x-www-form-urlencoded data
215+
} elseif (in_array($this->method, [ 'PUT', 'DELETE', 'PATCH' ], true) === true) {
216216
$body = $this->getBody();
217217
if ($body !== '') {
218218
$data = [];

tests/EngineTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,30 @@ public function getInitializedVar()
175175
$engine->start();
176176
}
177177

178+
public function testDoubleStart()
179+
{
180+
$engine = new Engine();
181+
$engine->route('/someRoute', function () {
182+
echo 'i ran';
183+
}, true);
184+
$engine->request()->url = '/someRoute';
185+
$engine->start();
186+
187+
$request = $engine->request();
188+
$response = $engine->response();
189+
190+
// This is pretending like this is embodied in a platform like swoole where
191+
// another request comes in while still holding all the same state.
192+
$_SERVER['REQUEST_METHOD'] = 'GET';
193+
$_SERVER['REQUEST_URI'] = '/someRoute';
194+
$engine->start();
195+
196+
$this->assertFalse($request === $engine->request());
197+
$this->assertFalse($response === $engine->response());
198+
199+
$this->expectOutputString('i rani ran');
200+
}
201+
178202
public function testStopWithCode()
179203
{
180204
$engine = new class extends Engine {

tests/FlightAsyncTest.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace tests;
6+
7+
use Flight;
8+
use flight\Engine;
9+
use PHPUnit\Framework\TestCase;
10+
11+
class FlightAsyncTest extends TestCase
12+
{
13+
public static function setUpBeforeClass(): void
14+
{
15+
Flight::setEngine(new Engine());
16+
}
17+
18+
protected function setUp(): void
19+
{
20+
$_SERVER = [];
21+
$_REQUEST = [];
22+
}
23+
24+
protected function tearDown(): void
25+
{
26+
unset($_REQUEST);
27+
unset($_SERVER);
28+
}
29+
30+
// Checks that default components are loaded
31+
public function testSingleRoute()
32+
{
33+
Flight::route('GET /', function () {
34+
echo 'hello world';
35+
});
36+
37+
$this->expectOutputString('hello world');
38+
Flight::start();
39+
}
40+
41+
public function testMultipleRoutes()
42+
{
43+
Flight::route('GET /', function () {
44+
echo 'hello world';
45+
});
46+
47+
Flight::route('GET /test', function () {
48+
echo 'test';
49+
});
50+
51+
$this->expectOutputString('test');
52+
$_SERVER['REQUEST_URI'] = '/test';
53+
Flight::start();
54+
}
55+
56+
public function testMultipleStartsSingleRoute()
57+
{
58+
Flight::route('GET /', function () {
59+
echo 'hello world';
60+
});
61+
62+
$this->expectOutputString('hello worldhello world');
63+
Flight::start();
64+
Flight::start();
65+
}
66+
67+
public function testMultipleStartsMultipleRoutes()
68+
{
69+
Flight::route('GET /', function () {
70+
echo 'hello world';
71+
});
72+
73+
Flight::route('GET /test', function () {
74+
echo 'test';
75+
});
76+
77+
$this->expectOutputString('testhello world');
78+
$_SERVER['REQUEST_URI'] = '/test';
79+
Flight::start();
80+
$_SERVER['REQUEST_URI'] = '/';
81+
Flight::start();
82+
}
83+
}

tests/FlightTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,15 +378,20 @@ public function testDoesNotPreserveVarsWhenFlagIsDisabled(
378378

379379
public function testKeepThePreviousStateOfOneViewComponentByDefault(): void
380380
{
381-
$this->expectOutputString(<<<'html'
381+
$html = <<<'html'
382382
<div>Hi</div>
383383
<div>Hi</div>
384384
385385
<input type="number" />
386386
387387
<input type="number" />
388388

389-
html);
389+
html;
390+
391+
// if windows replace \n with \r\n
392+
$html = str_replace("\n", PHP_EOL, $html);
393+
394+
$this->expectOutputString($html);
390395

391396
Flight::render('myComponent', ['prop' => 'Hi']);
392397
Flight::render('myComponent');

tests/RequestTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public function testInitUrlSameAsBaseDirectory()
163163
'base' => '/vagrant/public',
164164
'query' => new Collection(),
165165
'type' => '',
166-
'method' => 'GET'
166+
'method' => 'GET'
167167
]);
168168
$this->assertEquals('/flightphp', $request->url);
169169
}
@@ -174,7 +174,7 @@ public function testInitNoUrl()
174174
'url' => '',
175175
'base' => '/vagrant/public',
176176
'type' => '',
177-
'method' => 'GET'
177+
'method' => 'GET'
178178
]);
179179
$this->assertEquals('/', $request->url);
180180
}
@@ -193,13 +193,13 @@ public function testInitWithJsonBody()
193193
'data' => new Collection(),
194194
'query' => new Collection(),
195195
'stream_path' => $stream_path,
196-
'method' => 'POST'
196+
'method' => 'POST'
197197
]);
198198
$this->assertEquals([ 'foo' => 'bar' ], $request->data->getData());
199199
$this->assertEquals('{"foo":"bar"}', $request->getBody());
200200
}
201201

202-
public function testInitWithFormBody()
202+
public function testInitWithFormBody()
203203
{
204204
// create dummy file to pull request body from
205205
$tmpfile = tmpfile();
@@ -213,12 +213,12 @@ public function testInitWithFormBody()
213213
'data' => new Collection(),
214214
'query' => new Collection(),
215215
'stream_path' => $stream_path,
216-
'method' => 'PATCH'
216+
'method' => 'PATCH'
217217
]);
218-
$this->assertEquals([
219-
'foo' => 'bar',
220-
'baz' => 'qux'
221-
], $request->data->getData());
218+
$this->assertEquals([
219+
'foo' => 'bar',
220+
'baz' => 'qux'
221+
], $request->data->getData());
222222
$this->assertEquals('foo=bar&baz=qux', $request->getBody());
223223
}
224224

tests/ViewTest.php

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,20 @@ public function testDoesNotPreserveVarsWhenFlagIsDisabled(
175175

176176
public function testKeepThePreviousStateOfOneViewComponentByDefault(): void
177177
{
178-
$this->expectOutputString(<<<'html'
178+
$html = <<<'html'
179179
<div>Hi</div>
180180
<div>Hi</div>
181181
182182
<input type="number" />
183183
184184
<input type="number" />
185185

186-
html);
186+
html;
187+
188+
// if windows replace \n with \r\n
189+
$html = str_replace("\n", PHP_EOL, $html);
190+
191+
$this->expectOutputString($html);
187192

188193
$this->view->render('myComponent', ['prop' => 'Hi']);
189194
$this->view->render('myComponent');
@@ -197,36 +202,46 @@ public function testKeepThePreviousStateOfDataSettedBySetMethod(): void
197202

198203
$this->view->set('prop', 'bar');
199204

200-
$this->expectOutputString(<<<'html'
205+
$html = <<<'html'
201206
<div>qux</div>
202207
<div>bar</div>
203208

204-
html);
209+
html;
210+
211+
// if windows replace \n with \r\n
212+
$html = str_replace("\n", PHP_EOL, $html);
213+
214+
$this->expectOutputString($html);
205215

206216
$this->view->render('myComponent', ['prop' => 'qux']);
207217
$this->view->render('myComponent');
208218
}
209219

210220
public static function renderDataProvider(): array
211221
{
212-
return [
213-
[
214-
<<<'html'
222+
$html1 = <<<'html'
215223
<div>Hi</div>
216224
<div></div>
217225

218-
html,
219-
['myComponent', ['prop' => 'Hi']],
220-
'/^Undefined variable:? \$?prop$/'
221-
],
222-
[
223-
<<<'html'
226+
html;
227+
$html2 = <<<'html'
224228
225229
<input type="number" />
226230
227231
<input type="text" />
228232

229-
html,
233+
html;
234+
235+
$html1 = str_replace("\n", PHP_EOL, $html1);
236+
$html2 = str_replace("\n", PHP_EOL, $html2);
237+
return [
238+
[
239+
$html1,
240+
['myComponent', ['prop' => 'Hi']],
241+
'/^Undefined variable:? \$?prop$/'
242+
],
243+
[
244+
$html2,
230245
['input', ['type' => 'number']],
231246
'/^.*$/'
232247
],

0 commit comments

Comments
 (0)