@@ -234,11 +234,36 @@ public function testExecAfterExecWillStartAndCancelIdleTimerWhenSecondExecStarts
234234 $ this ->db ->exec ('CREATE ' );
235235 }
236236
237- public function testExecFollowedByIdleTimerWillCloseUnderlyingConnectionWithoutCloseEvent ()
237+ public function testExecFollowedByIdleTimerWillQuitUnderlyingConnectionWithoutCloseEvent ()
238238 {
239- $ client = $ this ->getMockBuilder ('Clue\React\SQLite\Io\ProcessIoDatabase ' )->disableOriginalConstructor ()->setMethods (array ('exec ' , 'close ' ))->getMock ();
239+ $ client = $ this ->getMockBuilder ('Clue\React\SQLite\Io\ProcessIoDatabase ' )->disableOriginalConstructor ()->setMethods (array ('exec ' , 'quit ' , 'close ' ))->getMock ();
240+ $ client ->expects ($ this ->once ())->method ('exec ' )->willReturn (\React \Promise \resolve ());
241+ $ client ->expects ($ this ->once ())->method ('quit ' )->willReturn (\React \Promise \resolve ());
242+ $ client ->expects ($ this ->never ())->method ('close ' );
243+
244+ $ this ->factory ->expects ($ this ->once ())->method ('open ' )->willReturn (\React \Promise \resolve ($ client ));
245+
246+ $ timeout = null ;
247+ $ timer = $ this ->getMockBuilder ('React\EventLoop\TimerInterface ' )->getMock ();
248+ $ this ->loop ->expects ($ this ->once ())->method ('addTimer ' )->with ($ this ->anything (), $ this ->callback (function ($ cb ) use (&$ timeout ) {
249+ $ timeout = $ cb ;
250+ return true ;
251+ }))->willReturn ($ timer );
252+
253+ $ this ->db ->on ('close ' , $ this ->expectCallableNever ());
254+
255+ $ this ->db ->exec ('CREATE ' );
256+
257+ $ this ->assertNotNull ($ timeout );
258+ $ timeout ();
259+ }
260+
261+ public function testExecFollowedByIdleTimerWillCloseUnderlyingConnectionWhenQuitFails ()
262+ {
263+ $ client = $ this ->getMockBuilder ('Clue\React\SQLite\Io\ProcessIoDatabase ' )->setMethods (array ('exec ' , 'quit ' , 'close ' ))->disableOriginalConstructor ()->getMock ();
240264 $ client ->expects ($ this ->once ())->method ('exec ' )->willReturn (\React \Promise \resolve ());
241- $ client ->expects ($ this ->once ())->method ('close ' )->willReturn (\React \Promise \resolve ());
265+ $ client ->expects ($ this ->once ())->method ('quit ' )->willReturn (\React \Promise \reject ());
266+ $ client ->expects ($ this ->once ())->method ('close ' );
242267
243268 $ this ->factory ->expects ($ this ->once ())->method ('open ' )->willReturn (\React \Promise \resolve ($ client ));
244269
@@ -257,6 +282,35 @@ public function testExecFollowedByIdleTimerWillCloseUnderlyingConnectionWithoutC
257282 $ timeout ();
258283 }
259284
285+ public function testExecAfterIdleTimerWillCloseUnderlyingConnectionBeforeCreatingSecondConnection ()
286+ {
287+ $ client = $ this ->getMockBuilder ('Clue\React\SQLite\Io\ProcessIoDatabase ' )->setMethods (array ('exec ' , 'quit ' , 'close ' ))->disableOriginalConstructor ()->getMock ();
288+ $ client ->expects ($ this ->once ())->method ('exec ' )->willReturn (\React \Promise \resolve ());
289+ $ client ->expects ($ this ->once ())->method ('quit ' )->willReturn (new Promise (function () { }));
290+ $ client ->expects ($ this ->once ())->method ('close ' );
291+
292+ $ this ->factory ->expects ($ this ->exactly (2 ))->method ('open ' )->willReturnOnConsecutiveCalls (
293+ \React \Promise \resolve ($ client ),
294+ new Promise (function () { })
295+ );
296+
297+ $ timeout = null ;
298+ $ timer = $ this ->getMockBuilder ('React\EventLoop\TimerInterface ' )->getMock ();
299+ $ this ->loop ->expects ($ this ->once ())->method ('addTimer ' )->with ($ this ->anything (), $ this ->callback (function ($ cb ) use (&$ timeout ) {
300+ $ timeout = $ cb ;
301+ return true ;
302+ }))->willReturn ($ timer );
303+
304+ $ this ->db ->on ('close ' , $ this ->expectCallableNever ());
305+
306+ $ this ->db ->exec ('CREATE ' );
307+
308+ $ this ->assertNotNull ($ timeout );
309+ $ timeout ();
310+
311+ $ this ->db ->exec ('CREATE ' );
312+ }
313+
260314 public function testQueryWillCreateUnderlyingDatabaseAndReturnPendingPromise ()
261315 {
262316 $ promise = new Promise (function () { });
@@ -407,11 +461,12 @@ public function testQueryAfterQueryWillStartAndCancelIdleTimerWhenSecondQuerySta
407461 $ this ->db ->query ('CREATE ' );
408462 }
409463
410- public function testQueryFollowedByIdleTimerWillCloseUnderlyingConnectionWithoutCloseEvent ()
464+ public function testQueryFollowedByIdleTimerWillQuitUnderlyingConnectionWithoutCloseEvent ()
411465 {
412- $ client = $ this ->getMockBuilder ('Clue\React\SQLite\Io\ProcessIoDatabase ' )->disableOriginalConstructor ()->setMethods (array ('query ' , 'close ' ))->getMock ();
466+ $ client = $ this ->getMockBuilder ('Clue\React\SQLite\Io\ProcessIoDatabase ' )->disableOriginalConstructor ()->setMethods (array ('query ' , 'quit ' , ' close ' ))->getMock ();
413467 $ client ->expects ($ this ->once ())->method ('query ' )->willReturn (\React \Promise \resolve ());
414- $ client ->expects ($ this ->once ())->method ('close ' )->willReturn (\React \Promise \resolve ());
468+ $ client ->expects ($ this ->once ())->method ('quit ' )->willReturn (\React \Promise \resolve ());
469+ $ client ->expects ($ this ->never ())->method ('close ' );
415470
416471 $ this ->factory ->expects ($ this ->once ())->method ('open ' )->willReturn (\React \Promise \resolve ($ client ));
417472
@@ -525,6 +580,44 @@ public function testCloseAfterExecRejectsWillEmitClose()
525580 $ deferred ->reject (new \RuntimeException ());
526581 }
527582
583+ public function testCloseAfterQuitAfterExecWillCloseUnderlyingConnectionWhenQuitIsStillPending ()
584+ {
585+ $ client = $ this ->getMockBuilder ('Clue\React\SQLite\DatabaseInterface ' )->getMock ();
586+ $ client ->expects ($ this ->once ())->method ('exec ' )->willReturn (\React \Promise \resolve ());
587+ $ client ->expects ($ this ->once ())->method ('quit ' )->willReturn (new Promise (function () { }));
588+ $ client ->expects ($ this ->once ())->method ('close ' );
589+
590+ $ this ->factory ->expects ($ this ->once ())->method ('open ' )->willReturn (\React \Promise \resolve ($ client ));
591+
592+ $ this ->db ->exec ('CREATE ' );
593+ $ this ->db ->quit ();
594+ $ this ->db ->close ();
595+ }
596+
597+ public function testCloseAfterExecAfterIdleTimeoutWillCloseUnderlyingConnectionWhenQuitIsStillPending ()
598+ {
599+ $ client = $ this ->getMockBuilder ('Clue\React\SQLite\DatabaseInterface ' )->getMock ();
600+ $ client ->expects ($ this ->once ())->method ('exec ' )->willReturn (\React \Promise \resolve ());
601+ $ client ->expects ($ this ->once ())->method ('quit ' )->willReturn (new Promise (function () { }));
602+ $ client ->expects ($ this ->once ())->method ('close ' );
603+
604+ $ this ->factory ->expects ($ this ->once ())->method ('open ' )->willReturn (\React \Promise \resolve ($ client ));
605+
606+ $ timeout = null ;
607+ $ timer = $ this ->getMockBuilder ('React\EventLoop\TimerInterface ' )->getMock ();
608+ $ this ->loop ->expects ($ this ->once ())->method ('addTimer ' )->with ($ this ->anything (), $ this ->callback (function ($ cb ) use (&$ timeout ) {
609+ $ timeout = $ cb ;
610+ return true ;
611+ }))->willReturn ($ timer );
612+
613+ $ this ->db ->exec ('CREATE ' );
614+
615+ $ this ->assertNotNull ($ timeout );
616+ $ timeout ();
617+
618+ $ this ->db ->close ();
619+ }
620+
528621 public function testQuitWillCloseDatabaseIfUnderlyingConnectionIsNotPendingAndResolveImmediately ()
529622 {
530623 $ this ->db ->on ('close ' , $ this ->expectCallableOnce ());
0 commit comments