CoreTest.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. <?php
  2. namespace GuzzleHttp\Tests\Ring;
  3. use GuzzleHttp\Ring\Core;
  4. use GuzzleHttp\Ring\Future\CompletedFutureArray;
  5. use GuzzleHttp\Ring\Future\FutureArray;
  6. use GuzzleHttp\Stream\Stream;
  7. use React\Promise\Deferred;
  8. class CoreTest extends \PHPUnit_Framework_TestCase
  9. {
  10. public function testReturnsNullNoHeadersAreSet()
  11. {
  12. $this->assertNull(Core::header([], 'Foo'));
  13. $this->assertNull(Core::firstHeader([], 'Foo'));
  14. }
  15. public function testChecksIfHasHeader()
  16. {
  17. $message = [
  18. 'headers' => [
  19. 'Foo' => ['Bar', 'Baz'],
  20. 'foo' => ['hello'],
  21. 'bar' => ['1']
  22. ]
  23. ];
  24. $this->assertTrue(Core::hasHeader($message, 'Foo'));
  25. $this->assertTrue(Core::hasHeader($message, 'foo'));
  26. $this->assertTrue(Core::hasHeader($message, 'FoO'));
  27. $this->assertTrue(Core::hasHeader($message, 'bar'));
  28. $this->assertFalse(Core::hasHeader($message, 'barr'));
  29. }
  30. public function testReturnsFirstHeaderWhenSimple()
  31. {
  32. $this->assertEquals('Bar', Core::firstHeader([
  33. 'headers' => ['Foo' => ['Bar', 'Baz']],
  34. ], 'Foo'));
  35. }
  36. public function testReturnsFirstHeaderWhenMultiplePerLine()
  37. {
  38. $this->assertEquals('Bar', Core::firstHeader([
  39. 'headers' => ['Foo' => ['Bar, Baz']],
  40. ], 'Foo'));
  41. }
  42. public function testExtractsCaseInsensitiveHeader()
  43. {
  44. $this->assertEquals(
  45. 'hello',
  46. Core::header(['headers' => ['foo' => ['hello']]], 'FoO')
  47. );
  48. }
  49. public function testExtractsCaseInsensitiveHeaderLines()
  50. {
  51. $this->assertEquals(
  52. ['a', 'b', 'c', 'd'],
  53. Core::headerLines([
  54. 'headers' => [
  55. 'foo' => ['a', 'b'],
  56. 'Foo' => ['c', 'd']
  57. ]
  58. ], 'foo')
  59. );
  60. }
  61. public function testExtractsHeaderLines()
  62. {
  63. $this->assertEquals(
  64. ['bar', 'baz'],
  65. Core::headerLines([
  66. 'headers' => [
  67. 'Foo' => ['bar', 'baz'],
  68. ],
  69. ], 'Foo')
  70. );
  71. }
  72. public function testExtractsHeaderAsString()
  73. {
  74. $this->assertEquals(
  75. 'bar, baz',
  76. Core::header([
  77. 'headers' => [
  78. 'Foo' => ['bar', 'baz'],
  79. ],
  80. ], 'Foo', true)
  81. );
  82. }
  83. public function testReturnsNullWhenHeaderNotFound()
  84. {
  85. $this->assertNull(Core::header(['headers' => []], 'Foo'));
  86. }
  87. public function testRemovesHeaders()
  88. {
  89. $message = [
  90. 'headers' => [
  91. 'foo' => ['bar'],
  92. 'Foo' => ['bam'],
  93. 'baz' => ['123'],
  94. ],
  95. ];
  96. $this->assertSame($message, Core::removeHeader($message, 'bam'));
  97. $this->assertEquals([
  98. 'headers' => ['baz' => ['123']],
  99. ], Core::removeHeader($message, 'foo'));
  100. }
  101. public function testCreatesUrl()
  102. {
  103. $req = [
  104. 'scheme' => 'http',
  105. 'headers' => ['host' => ['foo.com']],
  106. 'uri' => '/',
  107. ];
  108. $this->assertEquals('http://foo.com/', Core::url($req));
  109. }
  110. /**
  111. * @expectedException \InvalidArgumentException
  112. * @expectedExceptionMessage No Host header was provided
  113. */
  114. public function testEnsuresHostIsAvailableWhenCreatingUrls()
  115. {
  116. Core::url([]);
  117. }
  118. public function testCreatesUrlWithQueryString()
  119. {
  120. $req = [
  121. 'scheme' => 'http',
  122. 'headers' => ['host' => ['foo.com']],
  123. 'uri' => '/',
  124. 'query_string' => 'foo=baz',
  125. ];
  126. $this->assertEquals('http://foo.com/?foo=baz', Core::url($req));
  127. }
  128. public function testUsesUrlIfSet()
  129. {
  130. $req = ['url' => 'http://foo.com'];
  131. $this->assertEquals('http://foo.com', Core::url($req));
  132. }
  133. public function testReturnsNullWhenNoBody()
  134. {
  135. $this->assertNull(Core::body([]));
  136. }
  137. public function testReturnsStreamAsString()
  138. {
  139. $this->assertEquals(
  140. 'foo',
  141. Core::body(['body' => Stream::factory('foo')])
  142. );
  143. }
  144. public function testReturnsString()
  145. {
  146. $this->assertEquals('foo', Core::body(['body' => 'foo']));
  147. }
  148. public function testReturnsResourceContent()
  149. {
  150. $r = fopen('php://memory', 'w+');
  151. fwrite($r, 'foo');
  152. rewind($r);
  153. $this->assertEquals('foo', Core::body(['body' => $r]));
  154. fclose($r);
  155. }
  156. public function testReturnsIteratorContent()
  157. {
  158. $a = new \ArrayIterator(['a', 'b', 'cd', '']);
  159. $this->assertEquals('abcd', Core::body(['body' => $a]));
  160. }
  161. public function testReturnsObjectToString()
  162. {
  163. $this->assertEquals('foo', Core::body(['body' => new StrClass]));
  164. }
  165. /**
  166. * @expectedException \InvalidArgumentException
  167. */
  168. public function testEnsuresBodyIsValid()
  169. {
  170. Core::body(['body' => false]);
  171. }
  172. public function testParsesHeadersFromLines()
  173. {
  174. $lines = ['Foo: bar', 'Foo: baz', 'Abc: 123', 'Def: a, b'];
  175. $this->assertEquals([
  176. 'Foo' => ['bar', 'baz'],
  177. 'Abc' => ['123'],
  178. 'Def' => ['a, b'],
  179. ], Core::headersFromLines($lines));
  180. }
  181. public function testParsesHeadersFromLinesWithMultipleLines()
  182. {
  183. $lines = ['Foo: bar', 'Foo: baz', 'Foo: 123'];
  184. $this->assertEquals([
  185. 'Foo' => ['bar', 'baz', '123'],
  186. ], Core::headersFromLines($lines));
  187. }
  188. public function testCreatesArrayCallFunctions()
  189. {
  190. $called = [];
  191. $a = function ($a, $b) use (&$called) {
  192. $called['a'] = func_get_args();
  193. };
  194. $b = function ($a, $b) use (&$called) {
  195. $called['b'] = func_get_args();
  196. };
  197. $c = Core::callArray([$a, $b]);
  198. $c(1, 2);
  199. $this->assertEquals([1, 2], $called['a']);
  200. $this->assertEquals([1, 2], $called['b']);
  201. }
  202. public function testRewindsGuzzleStreams()
  203. {
  204. $str = Stream::factory('foo');
  205. $this->assertTrue(Core::rewindBody(['body' => $str]));
  206. }
  207. public function testRewindsStreams()
  208. {
  209. $str = Stream::factory('foo')->detach();
  210. $this->assertTrue(Core::rewindBody(['body' => $str]));
  211. }
  212. public function testRewindsIterators()
  213. {
  214. $iter = new \ArrayIterator(['foo']);
  215. $this->assertTrue(Core::rewindBody(['body' => $iter]));
  216. }
  217. public function testRewindsStrings()
  218. {
  219. $this->assertTrue(Core::rewindBody(['body' => 'hi']));
  220. }
  221. public function testRewindsToStrings()
  222. {
  223. $this->assertTrue(Core::rewindBody(['body' => new StrClass()]));
  224. }
  225. public function typeProvider()
  226. {
  227. return [
  228. ['foo', 'string(3) "foo"'],
  229. [true, 'bool(true)'],
  230. [false, 'bool(false)'],
  231. [10, 'int(10)'],
  232. [1.0, 'float(1)'],
  233. [new StrClass(), 'object(GuzzleHttp\Tests\Ring\StrClass)'],
  234. [['foo'], 'array(1)']
  235. ];
  236. }
  237. /**
  238. * @dataProvider typeProvider
  239. */
  240. public function testDescribesType($input, $output)
  241. {
  242. $this->assertEquals($output, Core::describeType($input));
  243. }
  244. public function testDoesSleep()
  245. {
  246. $t = microtime(true);
  247. $expected = $t + (100 / 1000);
  248. Core::doSleep(['client' => ['delay' => 100]]);
  249. $this->assertGreaterThanOrEqual($expected, microtime(true));
  250. }
  251. public function testProxiesFuture()
  252. {
  253. $f = new CompletedFutureArray(['status' => 200]);
  254. $res = null;
  255. $proxied = Core::proxy($f, function ($value) use (&$res) {
  256. $value['foo'] = 'bar';
  257. $res = $value;
  258. return $value;
  259. });
  260. $this->assertNotSame($f, $proxied);
  261. $this->assertEquals(200, $f->wait()['status']);
  262. $this->assertArrayNotHasKey('foo', $f->wait());
  263. $this->assertEquals('bar', $proxied->wait()['foo']);
  264. $this->assertEquals(200, $proxied->wait()['status']);
  265. }
  266. public function testProxiesDeferredFuture()
  267. {
  268. $d = new Deferred();
  269. $f = new FutureArray($d->promise());
  270. $f2 = Core::proxy($f);
  271. $d->resolve(['foo' => 'bar']);
  272. $this->assertEquals('bar', $f['foo']);
  273. $this->assertEquals('bar', $f2['foo']);
  274. }
  275. public function testProxiesDeferredFutureFailure()
  276. {
  277. $d = new Deferred();
  278. $f = new FutureArray($d->promise());
  279. $f2 = Core::proxy($f);
  280. $d->reject(new \Exception('foo'));
  281. try {
  282. $f2['hello?'];
  283. $this->fail('did not throw');
  284. } catch (\Exception $e) {
  285. $this->assertEquals('foo', $e->getMessage());
  286. }
  287. }
  288. }
  289. final class StrClass
  290. {
  291. public function __toString()
  292. {
  293. return 'foo';
  294. }
  295. }