From 55623c961734e8538f72846208e4ddd38dd5b850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sun, 12 Jul 2015 12:45:14 +0200 Subject: [PATCH 1/4] Use newer Promise API instead of Promise helpers --- composer.json | 2 +- tests/Io/StreamingParserTest.php | 5 +++-- tests/bootstrap.php | 16 ---------------- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/composer.json b/composer.json index 8ef0fdf..2b007f0 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "php": ">=5.3", "react/event-loop": "~0.3.0|~0.4.0", "clue/buzz-react": "~0.3.0", - "react/promise": "~1.0|~2.0", + "react/promise": "~2.0|~1.1", "clue/json-stream": "~0.1.0" }, "require-dev": { diff --git a/tests/Io/StreamingParserTest.php b/tests/Io/StreamingParserTest.php index 8fe95f9..3525530 100644 --- a/tests/Io/StreamingParserTest.php +++ b/tests/Io/StreamingParserTest.php @@ -4,6 +4,7 @@ use React\Promise\Deferred; use React\Stream\ReadableStream; use React\Promise\CancellablePromiseInterface; +use React\Promise; class StreamingParserTest extends TestCase { @@ -16,7 +17,7 @@ public function setUp() public function testJsonPassingRejectedPromiseResolvesWithClosedStream() { - $stream = $this->parser->parseJsonStream($this->createPromiseRejected()); + $stream = $this->parser->parseJsonStream(Promise\reject()); $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $stream); $this->assertFalse($stream->isReadable()); @@ -58,7 +59,7 @@ public function testJsonResolvingPromiseWillEmitCloseEvent() public function testPlainPassingRejectedPromiseResolvesWithClosedStream() { - $stream = $this->parser->parsePlainStream($this->createPromiseRejected()); + $stream = $this->parser->parsePlainStream(Promise\reject()); $this->assertInstanceOf('React\Stream\ReadableStreamInterface', $stream); $this->assertFalse($stream->isReadable()); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 8050a8a..02528be 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -106,22 +106,6 @@ protected function waitFor(PromiseInterface $promise, LoopInterface $loop) return $resolved; } - - protected function createPromiseResolved($value = null) - { - $deferred = new Deferred(); - $deferred->resolve($value); - - return $deferred->promise(); - } - - protected function createPromiseRejected($value = null) - { - $deferred = new Deferred(); - $deferred->reject($value); - - return $deferred->promise(); - } } class CallableStub From a1055e0f05fadf93e644137594b723a8d8fa295d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Wed, 15 Jul 2015 03:05:57 +0200 Subject: [PATCH 2/4] Use clue/block-react for blocking tests --- composer.json | 3 ++- tests/FunctionalClientTest.php | 17 +++++++++-------- tests/bootstrap.php | 22 ---------------------- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/composer.json b/composer.json index 2b007f0..21f8548 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ }, "require-dev": { "clue/tar-react": "~0.1.0", - "clue/caret-notation": "~0.2.0" + "clue/caret-notation": "~0.2.0", + "clue/block-react": "~0.3.0" } } diff --git a/tests/FunctionalClientTest.php b/tests/FunctionalClientTest.php index 0231f73..f3092e7 100644 --- a/tests/FunctionalClientTest.php +++ b/tests/FunctionalClientTest.php @@ -3,6 +3,7 @@ use Clue\React\Docker\Client; use React\EventLoop\Factory as LoopFactory; use Clue\React\Docker\Factory; +use Clue\React\Block; class FunctionalClientTest extends TestCase { @@ -19,7 +20,7 @@ public function setUp() $promise = $this->client->ping(); try { - $this->waitFor($promise, $this->loop); + Block\await($promise, $this->loop); } catch (Exception $e) { $this->markTestSkipped('Unable to connect to docker ' . $e->getMessage()); } @@ -40,18 +41,18 @@ public function testCreateStartAndRemoveContainer() ); $promise = $this->client->containerCreate($config); - $container = $this->waitFor($promise, $this->loop); + $container = Block\await($promise, $this->loop); $this->assertNotNull($container['Id']); $this->assertNull($container['Warnings']); $promise = $this->client->containerStart($container['Id']); - $ret = $this->waitFor($promise, $this->loop); + $ret = Block\await($promise, $this->loop); $this->assertEquals('', $ret); $promise = $this->client->containerRemove($container['Id'], false, true); - $ret = $this->waitFor($promise, $this->loop); + $ret = Block\await($promise, $this->loop); $this->assertEquals('', $ret); } @@ -62,13 +63,13 @@ public function testCreateStartAndRemoveContainer() public function testContainerRemoveInvalid() { $promise = $this->client->containerRemove('invalid123'); - $this->waitFor($promise, $this->loop); + Block\await($promise, $this->loop); } public function testImageSearch() { $promise = $this->client->imageSearch('clue'); - $ret = $this->waitFor($promise, $this->loop); + $ret = Block\await($promise, $this->loop); $this->assertGreaterThan(9, count($ret)); } @@ -77,11 +78,11 @@ public function testImageTag() { // create new tag "bb:now" on "busybox:latest" $promise = $this->client->imageTag('busybox', 'bb', 'now'); - $ret = $this->waitFor($promise, $this->loop); + $ret = Block\await($promise, $this->loop); // delete tag "bb:now" again $promise = $this->client->imageRemove('bb:now'); - $ret = $this->waitFor($promise, $this->loop); + $ret = Block\await($promise, $this->loop); } public function testImageCreateStreamMissingWillEmitJsonError() diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 02528be..5edb82a 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -84,28 +84,6 @@ protected function expectPromiseReject($promise) return $promise; } - - protected function waitFor(PromiseInterface $promise, LoopInterface $loop) - { - $resolved = null; - $exception = null; - - $promise->then(function ($c) use (&$resolved) { - $resolved = $c; - }, function($error) use (&$exception) { - $exception = $error; - }); - - while ($resolved === null && $exception === null) { - $loop->tick(); - } - - if ($exception !== null) { - throw $exception; - } - - return $resolved; - } } class CallableStub From a840421e76ee0198ee4cd4f32f0de8bdc3185d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Mon, 10 Aug 2015 23:50:51 +0200 Subject: [PATCH 3/4] Update clue/buzz-react to v0.4.0 --- composer.json | 2 +- tests/ClientTest.php | 2 +- tests/Io/ResponseParserTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 21f8548..3f12402 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "require": { "php": ">=5.3", "react/event-loop": "~0.3.0|~0.4.0", - "clue/buzz-react": "~0.3.0", + "clue/buzz-react": "~0.4.0", "react/promise": "~2.0|~1.1", "clue/json-stream": "~0.1.0" }, diff --git a/tests/ClientTest.php b/tests/ClientTest.php index d0f8b15..bc09d99 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -342,7 +342,7 @@ private function expectRequest($method, $url, Response $response) private function createResponse($body = '') { - return new Response('HTTP/1.0', 200, 'OK', null, new Body($body)); + return new Response('HTTP/1.0', 200, 'OK', array(), new Body($body)); } private function createResponseJson($json) diff --git a/tests/Io/ResponseParserTest.php b/tests/Io/ResponseParserTest.php index 2382309..ca745a3 100644 --- a/tests/Io/ResponseParserTest.php +++ b/tests/Io/ResponseParserTest.php @@ -32,7 +32,7 @@ public function testEmpty() private function createResponse($body = '') { - return new Response('HTTP/1.0', 200, 'OK', null, new Body($body)); + return new Response('HTTP/1.0', 200, 'OK', array(), new Body($body)); } } From 2fa27cfcf9442c4421a40ad4443264ffac6549e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Wed, 15 Jul 2015 03:06:48 +0200 Subject: [PATCH 4/4] DI for Browser and only exchange its Sender instance --- src/Factory.php | 13 +++++++++---- tests/FactoryTest.php | 20 ++++++++++++++++++-- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/Factory.php b/src/Factory.php index 30c3cbc..374f350 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -11,10 +11,16 @@ class Factory { private $loop; + private $browser; - public function __construct(LoopInterface $loop) + public function __construct(LoopInterface $loop, Browser $browser = null) { + if ($browser === null) { + $browser = new Browser($loop); + } + $this->loop = $loop; + $this->browser = $browser; } public function createClient($url = null) @@ -23,18 +29,17 @@ public function createClient($url = null) $url = 'unix:///var/run/docker.sock'; } - $sender = null; + $browser = $this->browser; if (substr($url, 0, 7) === 'unix://') { // send everything through a local unix domain socket $sender = Sender::createFromLoopUnix($this->loop, $url); + $browser = $browser->withSender($sender); // pretend all HTTP URLs to be on localhost $url = 'http://localhost'; } - $browser = new Browser($this->loop, $sender); - return new Client($browser, $url); } } diff --git a/tests/FactoryTest.php b/tests/FactoryTest.php index e8625b1..40e8872 100644 --- a/tests/FactoryTest.php +++ b/tests/FactoryTest.php @@ -6,18 +6,34 @@ class FactoryTest extends TestCase { private $loop; + private $browser; private $factory; public function setUp() { $this->loop = LoopFactory::create(); - $this->factory = new Factory($this->loop); + $this->browser = $this->getMockBuilder('Clue\React\Buzz\Browser')->disableOriginalConstructor()->getMock(); + $this->factory = new Factory($this->loop, $this->browser); } - public function testCreateClientDefault() + public function testCtorDefaultBrowser() { + $factory = new Factory($this->loop); + } + + public function testCreateClientUsesCustomUnixSender() + { + $this->browser->expects($this->once())->method('withSender')->will($this->returnValue($this->browser)); + $client = $this->factory->createClient(); $this->assertInstanceOf('Clue\React\Docker\Client', $client); } + + public function testCreateClientWithHttp() + { + $this->browser->expects($this->never())->method('withSender'); + + $this->factory->createClient('http://localhost:1234/'); + } }