Skip to content

Commit 0b9ee74

Browse files
authored
Merge pull request #45 from clue-labs/terminate
Explicitly close all STDIO streams when terminating
2 parents fa49ce8 + d28f62c commit 0b9ee74

5 files changed

Lines changed: 29 additions & 19 deletions

File tree

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
"react/event-loop": "~0.4.0|~0.3.0",
1717
"react/child-process": "~0.4.0|~0.3.0"
1818
},
19+
"require-dev": {
20+
"clue/block-react": "^1.1"
21+
},
1922
"autoload": {
2023
"psr-4": { "Clue\\React\\Zenity\\": "src/" }
2124
}

src/Zen/BaseZen.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,16 @@ public function promise()
5151

5252
public function close()
5353
{
54+
// resolve with whatever is currently buffered
5455
$this->deferred->resolve();
5556

5657
if ($this->process !== null && $this->process->isRunning()) {
5758
$this->process->terminate(SIGKILL);
59+
60+
// explicitly close all streams immediately
61+
$this->process->stdin->close();
62+
$this->process->stdout->close();
63+
$this->process->stderr->close();
5864
}
5965

6066
return $this;

tests/FunctionalLauncherTest.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<?php
22

3+
use Clue\React\Block;
34
use Clue\React\Zenity\Launcher;
4-
use React\EventLoop\Factory;
55
use Clue\React\Zenity\Zen\BaseZen;
6+
use React\EventLoop\Factory;
67

7-
class LauncherTest extends TestCase
8+
class FunctionalLauncherTest extends TestCase
89
{
910
private $loop;
1011
private $dialog;
@@ -27,9 +28,9 @@ public function testEchoParameters()
2728

2829
$promise = $this->launcher->launch($this->dialog);
2930

30-
$this->loop->run();
31+
$result = Block\await($promise, $this->loop, 1.0);
3132

32-
$promise->then($this->expectCallableOnceWith('--hello --world'));
33+
$this->assertEquals('--hello --world', $result);
3334
}
3435

3536
public function testDoesPassStdin()
@@ -44,9 +45,9 @@ public function testDoesPassStdin()
4445
$zen->close();
4546
});
4647

47-
$this->loop->run();
48+
$result = Block\await($zen->promise(), $this->loop, 1.0);
4849

49-
$zen->promise()->then($this->expectCallableOnceWith('okay'));
50+
$this->assertEquals('okay', $result);
5051
}
5152

5253
public function testWaitForOutput()

tests/Zen/BaseZenTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public function setUp()
2222
$this->process->stdin = $this->instream;
2323

2424
$this->process->stdout = $this->getMock('React\Stream\ReadableStreamInterface');
25+
$this->process->stderr = $this->getMock('React\Stream\ReadableStreamInterface');
2526
}
2627

2728
public function testClosingZenTerminatesProcess()

tests/Zen/FunctionalBaseZenTest.php

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<?php
22

3+
use Clue\React\Block;
4+
use Clue\React\Zenity\Zen\BaseZen;
35
use React\EventLoop\Factory;
46
use React\ChildProcess\Process;
5-
use Clue\React\Zenity\Zen\BaseZen;
7+
68
class FunctionalBaseZenTest extends TestCase
79
{
810
public function setUp()
@@ -18,9 +20,9 @@ public function testZenResolvesWithProcessOutput()
1820
$zen = new BaseZen();
1921
$zen->go($process);
2022

21-
$this->loop->run();
23+
$result = Block\await($zen->promise(), $this->loop, 1.0);
2224

23-
$zen->promise()->then($this->expectCallableOnceWith('okay'));
25+
$this->assertEquals('okay', $result);
2426
}
2527

2628
public function testZenResolvesWithTrueWhenProcessHasNoOutput()
@@ -31,9 +33,9 @@ public function testZenResolvesWithTrueWhenProcessHasNoOutput()
3133
$zen = new BaseZen();
3234
$zen->go($process);
3335

34-
$this->loop->run();
36+
$result = Block\await($zen->promise(), $this->loop, 1.0);
3537

36-
$zen->promise()->then($this->expectCallableOnceWith(true));
38+
$this->assertTrue($result);
3739
}
3840

3941
public function testZenRejectsWhenProcessReturnsError()
@@ -44,9 +46,7 @@ public function testZenRejectsWhenProcessReturnsError()
4446
$zen = new BaseZen();
4547
$zen->go($process);
4648

47-
$this->loop->run();
48-
49-
$zen->promise()->then(null, $this->expectCallableOnceWith(1));
49+
Block\await($zen->promise()->then(null, $this->expectCallableOnceWith(1)), $this->loop, 1.0);
5050
}
5151

5252
public function testClosingZenResolvesWithOutputSoFar()
@@ -61,9 +61,9 @@ public function testClosingZenResolvesWithOutputSoFar()
6161
$zen->close();
6262
});
6363

64-
$this->loop->run();
64+
$result = Block\await($zen->promise(), $this->loop, 1.0);
6565

66-
$zen->promise()->then($this->expectCallableOnceWith('okay'));
66+
$this->assertEquals('okay', $result);
6767
}
6868

6969
public function testTerminatingProcessReturnsError()
@@ -76,10 +76,9 @@ public function testTerminatingProcessReturnsError()
7676

7777
$this->loop->addTimer(0.1, function() use ($process) {
7878
$process->terminate(SIGKILL);
79+
$process->stdin->end();
7980
});
8081

81-
$this->loop->run();
82-
83-
$zen->promise()->then(null, $this->expectCallableOnce());
82+
Block\await($zen->promise()->then(null, $this->expectCallableOnce()), $this->loop, 1.0);
8483
}
8584
}

0 commit comments

Comments
 (0)