1111use PHPUnit \Framework \TestCase ;
1212use Psr \Http \Message \ResponseInterface ;
1313use Psr \Http \Message \ServerRequestInterface ;
14- use React \EventLoop \Loop ;
1514use React \EventLoop \LoopInterface ;
1615use React \Http \Message \Response ;
1716use React \Http \Message \ServerRequest ;
2120use ReflectionProperty ;
2221use function React \Promise \reject ;
2322use function React \Promise \resolve ;
23+ use React \EventLoop \Loop ;
2424
2525class AppTest extends TestCase
2626{
27- public function testConstructWithLoopAssignsGivenLoopInstance ()
28- {
29- $ loop = $ this ->createMock (LoopInterface::class);
30- $ app = new App ($ loop );
31-
32- $ ref = new ReflectionProperty ($ app , 'loop ' );
33- $ ref ->setAccessible (true );
34- $ ret = $ ref ->getValue ($ app );
35-
36- $ this ->assertSame ($ loop , $ ret );
37- }
38-
39- public function testConstructWithoutLoopAssignsGlobalLoopInstance ()
27+ public function testConstructWithMiddlewareAssignsGivenMiddleware ()
4028 {
41- $ app = new App ();
42-
43- $ ref = new ReflectionProperty ($ app , 'loop ' );
44- $ ref ->setAccessible (true );
45- $ ret = $ ref ->getValue ($ app );
46-
47- $ this ->assertSame (Loop::get (), $ ret );
48- }
49-
50- public function testConstructWithLoopAndMiddlewareAssignsGivenLoopInstanceAndMiddleware ()
51- {
52- $ loop = $ this ->createMock (LoopInterface::class);
5329 $ middleware = function () { };
54- $ app = new App ($ loop , $ middleware );
55-
56- $ ref = new ReflectionProperty ($ app , 'loop ' );
57- $ ref ->setAccessible (true );
58- $ ret = $ ref ->getValue ($ app );
59-
60- $ this ->assertSame ($ loop , $ ret );
30+ $ app = new App ($ middleware );
6131
6232 $ ref = new ReflectionProperty ($ app , 'handler ' );
6333 $ ref ->setAccessible (true );
@@ -75,74 +45,79 @@ public function testConstructWithLoopAndMiddlewareAssignsGivenLoopInstanceAndMid
7545 $ this ->assertInstanceOf (RouteHandler::class, $ handlers [3 ]);
7646 }
7747
78- public function testConstructWithInvalidLoopThrows ()
79- {
80- $ this ->expectException (\TypeError::class);
81- $ this ->expectExceptionMessage ('Argument 1 ($loop) must be callable|React\EventLoop\LoopInterface, stdClass given ' );
82- new App ((object )[]);
83- }
84-
85- public function testConstructWithNullLoopButMiddlwareThrows ()
86- {
87- $ this ->expectException (\TypeError::class);
88- $ this ->expectExceptionMessage ('Argument 1 ($loop) must be callable|React\EventLoop\LoopInterface, null given ' );
89- new App (null , function () { });
90- }
91-
92- public function testRunWillRunGivenLoopInstanceAndReportListeningAddress ()
48+ public function testRunWillReportListeningAddressAndRunLoopWithSocketServer ()
9349 {
9450 $ socket = @stream_socket_server ('127.0.0.1:8080 ' );
9551 if ($ socket === false ) {
9652 $ this ->markTestSkipped ('Listen address :8080 already in use ' );
9753 }
9854 fclose ($ socket );
9955
100- $ loop = $ this ->createMock (LoopInterface::class);
101- $ loop ->expects ($ this ->once ())->method ('run ' );
102- $ app = new App ($ loop );
56+ $ app = new App ();
57+
58+ // lovely: remove socket server on next tick to terminate loop
59+ Loop::futureTick (function () {
60+ $ resources = get_resources ();
61+ $ socket = end ($ resources );
62+
63+ Loop::removeReadStream ($ socket );
64+ fclose ($ socket );
65+ });
10366
10467 $ this ->expectOutputRegex ('/ ' . preg_quote ('Listening on http://127.0.0.1:8080 ' . PHP_EOL , '/ ' ) . '$/ ' );
10568 $ app ->run ();
10669 }
10770
108- public function testRunWillRunGivenLoopInstanceAndReportListeningAddressFromEnvironment ()
71+ public function testRunWillReportListeningAddressFromEnvironmentAndRunLoopWithSocketServer ()
10972 {
11073 $ socket = @stream_socket_server ('127.0.0.1:0 ' );
11174 $ addr = stream_socket_get_name ($ socket , false );
11275 fclose ($ socket );
11376
11477 putenv ('X_LISTEN= ' . $ addr );
115- $ loop = $ this ->createMock (LoopInterface::class);
116- $ loop ->expects ($ this ->once ())->method ('run ' );
117- $ app = new App ($ loop );
78+ $ app = new App ();
79+
80+ // lovely: remove socket server on next tick to terminate loop
81+ Loop::futureTick (function () {
82+ $ resources = get_resources ();
83+ $ socket = end ($ resources );
84+
85+ Loop::removeReadStream ($ socket );
86+ fclose ($ socket );
87+ });
11888
11989 $ this ->expectOutputRegex ('/ ' . preg_quote ('Listening on http:// ' . $ addr . PHP_EOL , '/ ' ) . '$/ ' );
12090 $ app ->run ();
12191 }
12292
123- public function testRunWillRunGivenLoopInstanceAndReportListeningAddressFromEnvironmentWithRandomPort ()
93+ public function testRunWillReportListeningAddressFromEnvironmentWithRandomPortAndRunLoopWithSocketServer ()
12494 {
12595 putenv ('X_LISTEN=127.0.0.1:0 ' );
126- $ loop = $ this ->createMock (LoopInterface::class);
127- $ loop ->expects ($ this ->once ())->method ('run ' );
128- $ app = new App ($ loop );
96+ $ app = new App ();
97+
98+ // lovely: remove socket server on next tick to terminate loop
99+ Loop::futureTick (function () {
100+ $ resources = get_resources ();
101+ $ socket = end ($ resources );
102+
103+ Loop::removeReadStream ($ socket );
104+ fclose ($ socket );
105+ });
129106
130107 $ this ->expectOutputRegex ('/ ' . preg_quote ('Listening on http://127.0.0.1: ' , '/ ' ) . '\d+ ' . PHP_EOL . '$/ ' );
131108 $ app ->run ();
132109 }
133110
134- public function testRunAppWithEmptyAddressThrowsWithoutRunningLoop ()
111+ public function testRunAppWithEmptyAddressThrows ()
135112 {
136113 putenv ('X_LISTEN= ' );
137- $ loop = $ this ->createMock (LoopInterface::class);
138- $ loop ->expects ($ this ->never ())->method ('run ' );
139- $ app = new App ($ loop );
114+ $ app = new App ();
140115
141116 $ this ->expectException (\InvalidArgumentException::class);
142117 $ app ->run ();
143118 }
144119
145- public function testRunAppWithBusyPortThrowsWithoutRunningLoop ()
120+ public function testRunAppWithBusyPortThrows ()
146121 {
147122 $ socket = @stream_socket_server ('127.0.0.1:0 ' );
148123 $ addr = stream_socket_get_name ($ socket , false );
@@ -152,9 +127,7 @@ public function testRunAppWithBusyPortThrowsWithoutRunningLoop()
152127 }
153128
154129 putenv ('X_LISTEN= ' . $ addr );
155- $ loop = $ this ->createMock (LoopInterface::class);
156- $ loop ->expects ($ this ->never ())->method ('run ' );
157- $ app = new App ($ loop );
130+ $ app = new App ();
158131
159132 $ this ->expectException (\RuntimeException::class);
160133 $ this ->expectExceptionMessage ('Failed to listen on ' );
0 commit comments