Update to drupal-org-drupal 8.0.0-rc2. For more information, see https://www.drupal.org/node/2598668

This commit is contained in:
Pantheon Automation 2015-10-21 21:44:50 -07:00 committed by Greg Anderson
parent f32e58e4b1
commit 8e18df8c36
3062 changed files with 15044 additions and 172506 deletions

View file

@ -1,14 +0,0 @@
<?php
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\AggregateException;
class AggregateExceptionTest extends \PHPUnit_Framework_TestCase
{
public function testHasReason()
{
$e = new AggregateException('foo', ['baz', 'bar']);
$this->assertContains('foo', $e->getMessage());
$this->assertEquals(['baz', 'bar'], $e->getReason());
}
}

View file

@ -1,288 +0,0 @@
<?php
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\RejectedPromise;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\EachPromise;
use GuzzleHttp\Promise as P;
/**
* @covers GuzzleHttp\Promise\EachPromise
*/
class EachPromiseTest extends \PHPUnit_Framework_TestCase
{
public function testReturnsSameInstance()
{
$each = new EachPromise([], ['concurrency' => 100]);
$this->assertSame($each->promise(), $each->promise());
}
public function testInvokesAllPromises()
{
$promises = [new Promise(), new Promise(), new Promise()];
$called = [];
$each = new EachPromise($promises, [
'fulfilled' => function ($value) use (&$called) {
$called[] = $value;
}
]);
$p = $each->promise();
$promises[0]->resolve('a');
$promises[1]->resolve('c');
$promises[2]->resolve('b');
P\queue()->run();
$this->assertEquals(['a', 'c', 'b'], $called);
$this->assertEquals(PromiseInterface::FULFILLED, $p->getState());
}
public function testIsWaitable()
{
$a = new Promise(function () use (&$a) { $a->resolve('a'); });
$b = new Promise(function () use (&$b) { $b->resolve('b'); });
$called = [];
$each = new EachPromise([$a, $b], [
'fulfilled' => function ($value) use (&$called) { $called[] = $value; }
]);
$p = $each->promise();
$this->assertNull($p->wait());
$this->assertEquals(PromiseInterface::FULFILLED, $p->getState());
$this->assertEquals(['a', 'b'], $called);
}
public function testCanResolveBeforeConsumingAll()
{
$called = 0;
$a = new Promise(function () use (&$a) { $a->resolve('a'); });
$b = new Promise(function () { $this->fail(); });
$each = new EachPromise([$a, $b], [
'fulfilled' => function ($value, $idx, Promise $aggregate) use (&$called) {
$this->assertSame($idx, 0);
$this->assertEquals('a', $value);
$aggregate->resolve(null);
$called++;
},
'rejected' => function (\Exception $reason) {
$this->fail($reason->getMessage());
}
]);
$p = $each->promise();
$p->wait();
$this->assertNull($p->wait());
$this->assertEquals(1, $called);
$this->assertEquals(PromiseInterface::FULFILLED, $a->getState());
$this->assertEquals(PromiseInterface::PENDING, $b->getState());
// Resolving $b has no effect on the aggregate promise.
$b->resolve('foo');
$this->assertEquals(1, $called);
}
public function testLimitsPendingPromises()
{
$pending = [new Promise(), new Promise(), new Promise(), new Promise()];
$promises = new \ArrayIterator($pending);
$each = new EachPromise($promises, ['concurrency' => 2]);
$p = $each->promise();
$this->assertCount(2, $this->readAttribute($each, 'pending'));
$pending[0]->resolve('a');
$this->assertCount(2, $this->readAttribute($each, 'pending'));
$this->assertTrue($promises->valid());
$pending[1]->resolve('b');
P\queue()->run();
$this->assertCount(2, $this->readAttribute($each, 'pending'));
$this->assertTrue($promises->valid());
$promises[2]->resolve('c');
P\queue()->run();
$this->assertCount(1, $this->readAttribute($each, 'pending'));
$this->assertEquals(PromiseInterface::PENDING, $p->getState());
$promises[3]->resolve('d');
P\queue()->run();
$this->assertNull($this->readAttribute($each, 'pending'));
$this->assertEquals(PromiseInterface::FULFILLED, $p->getState());
$this->assertFalse($promises->valid());
}
public function testDynamicallyLimitsPendingPromises()
{
$calls = [];
$pendingFn = function ($count) use (&$calls) {
$calls[] = $count;
return 2;
};
$pending = [new Promise(), new Promise(), new Promise(), new Promise()];
$promises = new \ArrayIterator($pending);
$each = new EachPromise($promises, ['concurrency' => $pendingFn]);
$p = $each->promise();
$this->assertCount(2, $this->readAttribute($each, 'pending'));
$pending[0]->resolve('a');
$this->assertCount(2, $this->readAttribute($each, 'pending'));
$this->assertTrue($promises->valid());
$pending[1]->resolve('b');
$this->assertCount(2, $this->readAttribute($each, 'pending'));
P\queue()->run();
$this->assertTrue($promises->valid());
$promises[2]->resolve('c');
P\queue()->run();
$this->assertCount(1, $this->readAttribute($each, 'pending'));
$this->assertEquals(PromiseInterface::PENDING, $p->getState());
$promises[3]->resolve('d');
P\queue()->run();
$this->assertNull($this->readAttribute($each, 'pending'));
$this->assertEquals(PromiseInterface::FULFILLED, $p->getState());
$this->assertEquals([0, 1, 1, 1], $calls);
$this->assertFalse($promises->valid());
}
public function testClearsReferencesWhenResolved()
{
$called = false;
$a = new Promise(function () use (&$a, &$called) {
$a->resolve('a');
$called = true;
});
$each = new EachPromise([$a], [
'concurrency' => function () { return 1; },
'fulfilled' => function () {},
'rejected' => function () {}
]);
$each->promise()->wait();
$this->assertNull($this->readAttribute($each, 'onFulfilled'));
$this->assertNull($this->readAttribute($each, 'onRejected'));
$this->assertNull($this->readAttribute($each, 'iterable'));
$this->assertNull($this->readAttribute($each, 'pending'));
$this->assertNull($this->readAttribute($each, 'concurrency'));
$this->assertTrue($called);
}
public function testCanBeCancelled()
{
$this->markTestIncomplete();
}
public function testDoesNotBlowStackWithFulfilledPromises()
{
$pending = [];
for ($i = 0; $i < 100; $i++) {
$pending[] = new FulfilledPromise($i);
}
$values = [];
$each = new EachPromise($pending, [
'fulfilled' => function ($value) use (&$values) {
$values[] = $value;
}
]);
$called = false;
$each->promise()->then(function () use (&$called) {
$called = true;
});
$this->assertFalse($called);
P\queue()->run();
$this->assertTrue($called);
$this->assertEquals(range(0, 99), $values);
}
public function testDoesNotBlowStackWithRejectedPromises()
{
$pending = [];
for ($i = 0; $i < 100; $i++) {
$pending[] = new RejectedPromise($i);
}
$values = [];
$each = new EachPromise($pending, [
'rejected' => function ($value) use (&$values) {
$values[] = $value;
}
]);
$called = false;
$each->promise()->then(
function () use (&$called) { $called = true; },
function () { $this->fail('Should not have rejected.'); }
);
$this->assertFalse($called);
P\queue()->run();
$this->assertTrue($called);
$this->assertEquals(range(0, 99), $values);
}
public function testReturnsPromiseForWhatever()
{
$called = [];
$arr = ['a', 'b'];
$each = new EachPromise($arr, [
'fulfilled' => function ($v) use (&$called) { $called[] = $v; }
]);
$p = $each->promise();
$this->assertNull($p->wait());
$this->assertEquals(['a', 'b'], $called);
}
public function testRejectsAggregateWhenNextThrows()
{
$iter = function () {
yield 'a';
throw new \Exception('Failure');
};
$each = new EachPromise($iter());
$p = $each->promise();
$e = null;
$received = null;
$p->then(null, function ($reason) use (&$e) { $e = $reason; });
P\queue()->run();
$this->assertInstanceOf('Exception', $e);
$this->assertEquals('Failure', $e->getMessage());
}
public function testDoesNotCallNextOnIteratorUntilNeededWhenWaiting()
{
$results = [];
$values = [10];
$remaining = 9;
$iter = function () use (&$values) {
while ($value = array_pop($values)) {
yield $value;
}
};
$each = new EachPromise($iter(), [
'concurrency' => 1,
'fulfilled' => function ($r) use (&$results, &$values, &$remaining) {
$results[] = $r;
if ($remaining > 0) {
$values[] = $remaining--;
}
}
]);
$each->promise()->wait();
$this->assertEquals(range(10, 1), $results);
}
public function testDoesNotCallNextOnIteratorUntilNeededWhenAsync()
{
$firstPromise = new Promise();
$pending = [$firstPromise];
$values = [$firstPromise];
$results = [];
$remaining = 9;
$iter = function () use (&$values) {
while ($value = array_pop($values)) {
yield $value;
}
};
$each = new EachPromise($iter(), [
'concurrency' => 1,
'fulfilled' => function ($r) use (&$results, &$values, &$remaining, &$pending) {
$results[] = $r;
if ($remaining-- > 0) {
$pending[] = $values[] = new Promise();
}
}
]);
$i = 0;
$each->promise();
while ($promise = array_pop($pending)) {
$promise->resolve($i++);
P\queue()->run();
}
$this->assertEquals(range(0, 9), $results);
}
}

View file

@ -1,108 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Promise;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\FulfilledPromise;
/**
* @covers GuzzleHttp\Promise\FulfilledPromise
*/
class FulfilledPromiseTest extends \PHPUnit_Framework_TestCase
{
public function testReturnsValueWhenWaitedUpon()
{
$p = new FulfilledPromise('foo');
$this->assertEquals('fulfilled', $p->getState());
$this->assertEquals('foo', $p->wait(true));
}
public function testCannotCancel()
{
$p = new FulfilledPromise('foo');
$this->assertEquals('fulfilled', $p->getState());
$p->cancel();
$this->assertEquals('foo', $p->wait());
}
/**
* @expectedException \LogicException
* @exepctedExceptionMessage Cannot resolve a fulfilled promise
*/
public function testCannotResolve()
{
$p = new FulfilledPromise('foo');
$p->resolve('bar');
}
/**
* @expectedException \LogicException
* @exepctedExceptionMessage Cannot reject a fulfilled promise
*/
public function testCannotReject()
{
$p = new FulfilledPromise('foo');
$p->reject('bar');
}
public function testCanResolveWithSameValue()
{
$p = new FulfilledPromise('foo');
$p->resolve('foo');
}
/**
* @expectedException \InvalidArgumentException
*/
public function testCannotResolveWithPromise()
{
new FulfilledPromise(new Promise());
}
public function testReturnsSelfWhenNoOnFulfilled()
{
$p = new FulfilledPromise('a');
$this->assertSame($p, $p->then());
}
public function testAsynchronouslyInvokesOnFulfilled()
{
$p = new FulfilledPromise('a');
$r = null;
$f = function ($d) use (&$r) { $r = $d; };
$p2 = $p->then($f);
$this->assertNotSame($p, $p2);
$this->assertNull($r);
\GuzzleHttp\Promise\queue()->run();
$this->assertEquals('a', $r);
}
public function testReturnsNewRejectedWhenOnFulfilledFails()
{
$p = new FulfilledPromise('a');
$f = function () { throw new \Exception('b'); };
$p2 = $p->then($f);
$this->assertNotSame($p, $p2);
try {
$p2->wait();
$this->fail();
} catch (\Exception $e) {
$this->assertEquals('b', $e->getMessage());
}
}
public function testOtherwiseIsSugarForRejections()
{
$c = null;
$p = new FulfilledPromise('foo');
$p->otherwise(function ($v) use (&$c) { $c = $v; });
$this->assertNull($c);
}
public function testDoesNotTryToFulfillTwiceDuringTrampoline()
{
$fp = new FulfilledPromise('a');
$t1 = $fp->then(function ($v) { return $v . ' b'; });
$t1->resolve('why!');
$this->assertEquals('why!', $t1->wait());
}
}

View file

@ -1,50 +0,0 @@
<?php
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\PromiseInterface;
class NotPromiseInstance extends Thennable implements PromiseInterface
{
private $nextPromise = null;
public function __construct()
{
$this->nextPromise = new Promise();
}
public function then(callable $res = null, callable $rej = null)
{
return $this->nextPromise->then($res, $rej);
}
public function otherwise(callable $onRejected)
{
return $this->then($onRejected);
}
public function resolve($value)
{
$this->nextPromise->resolve($value);
}
public function reject($reason)
{
$this->nextPromise->reject($reason);
}
public function wait($unwrap = true, $defaultResolution = null)
{
}
public function cancel()
{
}
public function getState()
{
return $this->nextPromise->getState();
}
}

View file

@ -1,579 +0,0 @@
<?php
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\CancellationException;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\RejectedPromise;
use GuzzleHttp\Promise\RejectionException;
/**
* @covers GuzzleHttp\Promise\Promise
*/
class PromiseTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \LogicException
* @expectedExceptionMessage The promise is already fulfilled
*/
public function testCannotResolveNonPendingPromise()
{
$p = new Promise();
$p->resolve('foo');
$p->resolve('bar');
$this->assertEquals('foo', $p->wait());
}
public function testCanResolveWithSameValue()
{
$p = new Promise();
$p->resolve('foo');
$p->resolve('foo');
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage Cannot change a fulfilled promise to rejected
*/
public function testCannotRejectNonPendingPromise()
{
$p = new Promise();
$p->resolve('foo');
$p->reject('bar');
$this->assertEquals('foo', $p->wait());
}
public function testCanRejectWithSameValue()
{
$p = new Promise();
$p->reject('foo');
$p->reject('foo');
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage Cannot change a fulfilled promise to rejected
*/
public function testCannotRejectResolveWithSameValue()
{
$p = new Promise();
$p->resolve('foo');
$p->reject('foo');
}
public function testInvokesWaitFunction()
{
$p = new Promise(function () use (&$p) { $p->resolve('10'); });
$this->assertEquals('10', $p->wait());
}
/**
* @expectedException \GuzzleHttp\Promise\RejectionException
*/
public function testRejectsAndThrowsWhenWaitFailsToResolve()
{
$p = new Promise(function () {});
$p->wait();
}
/**
* @expectedException \GuzzleHttp\Promise\RejectionException
* @expectedExceptionMessage The promise was rejected with reason: foo
*/
public function testThrowsWhenUnwrapIsRejectedWithNonException()
{
$p = new Promise(function () use (&$p) { $p->reject('foo'); });
$p->wait();
}
/**
* @expectedException \UnexpectedValueException
* @expectedExceptionMessage foo
*/
public function testThrowsWhenUnwrapIsRejectedWithException()
{
$e = new \UnexpectedValueException('foo');
$p = new Promise(function () use (&$p, $e) { $p->reject($e); });
$p->wait();
}
public function testDoesNotUnwrapExceptionsWhenDisabled()
{
$p = new Promise(function () use (&$p) { $p->reject('foo'); });
$this->assertEquals('pending', $p->getState());
$p->wait(false);
$this->assertEquals('rejected', $p->getState());
}
public function testRejectsSelfWhenWaitThrows()
{
$e = new \UnexpectedValueException('foo');
$p = new Promise(function () use ($e) { throw $e; });
try {
$p->wait();
$this->fail();
} catch (\UnexpectedValueException $e) {
$this->assertEquals('rejected', $p->getState());
}
}
public function testWaitsOnNestedPromises()
{
$p = new Promise(function () use (&$p) { $p->resolve('_'); });
$p2 = new Promise(function () use (&$p2) { $p2->resolve('foo'); });
$p3 = $p->then(function () use ($p2) { return $p2; });
$this->assertSame('foo', $p3->wait());
}
/**
* @expectedException \GuzzleHttp\Promise\RejectionException
*/
public function testThrowsWhenWaitingOnPromiseWithNoWaitFunction()
{
$p = new Promise();
$p->wait();
}
public function testThrowsWaitExceptionAfterPromiseIsResolved()
{
$p = new Promise(function () use (&$p) {
$p->reject('Foo!');
throw new \Exception('Bar?');
});
try {
$p->wait();
$this->fail();
} catch (\Exception $e) {
$this->assertEquals('Bar?', $e->getMessage());
}
}
public function testGetsActualWaitValueFromThen()
{
$p = new Promise(function () use (&$p) { $p->reject('Foo!'); });
$p2 = $p->then(null, function ($reason) {
return new RejectedPromise([$reason]);
});
try {
$p2->wait();
$this->fail('Should have thrown');
} catch (RejectionException $e) {
$this->assertEquals(['Foo!'], $e->getReason());
}
}
public function testWaitBehaviorIsBasedOnLastPromiseInChain()
{
$p3 = new Promise(function () use (&$p3) { $p3->resolve('Whoop'); });
$p2 = new Promise(function () use (&$p2, $p3) { $p2->reject($p3); });
$p = new Promise(function () use (&$p, $p2) { $p->reject($p2); });
$this->assertEquals('Whoop', $p->wait());
}
public function testCannotCancelNonPending()
{
$p = new Promise();
$p->resolve('foo');
$p->cancel();
$this->assertEquals('fulfilled', $p->getState());
}
/**
* @expectedException \GuzzleHttp\Promise\CancellationException
*/
public function testCancelsPromiseWhenNoCancelFunction()
{
$p = new Promise();
$p->cancel();
$this->assertEquals('rejected', $p->getState());
$p->wait();
}
public function testCancelsPromiseWithCancelFunction()
{
$called = false;
$p = new Promise(null, function () use (&$called) { $called = true; });
$p->cancel();
$this->assertEquals('rejected', $p->getState());
$this->assertTrue($called);
}
public function testCancelsUppermostPendingPromise()
{
$called = false;
$p1 = new Promise(null, function () use (&$called) { $called = true; });
$p2 = $p1->then(function () {});
$p3 = $p2->then(function () {});
$p4 = $p3->then(function () {});
$p3->cancel();
$this->assertEquals('rejected', $p1->getState());
$this->assertEquals('rejected', $p2->getState());
$this->assertEquals('rejected', $p3->getState());
$this->assertEquals('pending', $p4->getState());
$this->assertTrue($called);
try {
$p3->wait();
$this->fail();
} catch (CancellationException $e) {
$this->assertContains('cancelled', $e->getMessage());
}
try {
$p4->wait();
$this->fail();
} catch (CancellationException $e) {
$this->assertContains('cancelled', $e->getMessage());
}
$this->assertEquals('rejected', $p4->getState());
}
public function testCancelsChildPromises()
{
$called1 = $called2 = $called3 = false;
$p1 = new Promise(null, function () use (&$called1) { $called1 = true; });
$p2 = new Promise(null, function () use (&$called2) { $called2 = true; });
$p3 = new Promise(null, function () use (&$called3) { $called3 = true; });
$p4 = $p2->then(function () use ($p3) { return $p3; });
$p5 = $p4->then(function () { $this->fail(); });
$p4->cancel();
$this->assertEquals('pending', $p1->getState());
$this->assertEquals('rejected', $p2->getState());
$this->assertEquals('rejected', $p4->getState());
$this->assertEquals('pending', $p5->getState());
$this->assertFalse($called1);
$this->assertTrue($called2);
$this->assertFalse($called3);
}
public function testRejectsPromiseWhenCancelFails()
{
$called = false;
$p = new Promise(null, function () use (&$called) {
$called = true;
throw new \Exception('e');
});
$p->cancel();
$this->assertEquals('rejected', $p->getState());
$this->assertTrue($called);
try {
$p->wait();
$this->fail();
} catch (\Exception $e) {
$this->assertEquals('e', $e->getMessage());
}
}
public function testCreatesPromiseWhenFulfilledAfterThen()
{
$p = new Promise();
$carry = null;
$p2 = $p->then(function ($v) use (&$carry) { $carry = $v; });
$this->assertNotSame($p, $p2);
$p->resolve('foo');
P\queue()->run();
$this->assertEquals('foo', $carry);
}
public function testCreatesPromiseWhenFulfilledBeforeThen()
{
$p = new Promise();
$p->resolve('foo');
$carry = null;
$p2 = $p->then(function ($v) use (&$carry) { $carry = $v; });
$this->assertNotSame($p, $p2);
$this->assertNull($carry);
\GuzzleHttp\Promise\queue()->run();
$this->assertEquals('foo', $carry);
}
public function testCreatesPromiseWhenFulfilledWithNoCallback()
{
$p = new Promise();
$p->resolve('foo');
$p2 = $p->then();
$this->assertNotSame($p, $p2);
$this->assertInstanceOf('GuzzleHttp\Promise\FulfilledPromise', $p2);
}
public function testCreatesPromiseWhenRejectedAfterThen()
{
$p = new Promise();
$carry = null;
$p2 = $p->then(null, function ($v) use (&$carry) { $carry = $v; });
$this->assertNotSame($p, $p2);
$p->reject('foo');
P\queue()->run();
$this->assertEquals('foo', $carry);
}
public function testCreatesPromiseWhenRejectedBeforeThen()
{
$p = new Promise();
$p->reject('foo');
$carry = null;
$p2 = $p->then(null, function ($v) use (&$carry) { $carry = $v; });
$this->assertNotSame($p, $p2);
$this->assertNull($carry);
P\queue()->run();
$this->assertEquals('foo', $carry);
}
public function testCreatesPromiseWhenRejectedWithNoCallback()
{
$p = new Promise();
$p->reject('foo');
$p2 = $p->then();
$this->assertNotSame($p, $p2);
$this->assertInstanceOf('GuzzleHttp\Promise\RejectedPromise', $p2);
}
public function testInvokesWaitFnsForThens()
{
$p = new Promise(function () use (&$p) { $p->resolve('a'); });
$p2 = $p
->then(function ($v) { return $v . '-1-'; })
->then(function ($v) { return $v . '2'; });
$this->assertEquals('a-1-2', $p2->wait());
}
public function testStacksThenWaitFunctions()
{
$p1 = new Promise(function () use (&$p1) { $p1->resolve('a'); });
$p2 = new Promise(function () use (&$p2) { $p2->resolve('b'); });
$p3 = new Promise(function () use (&$p3) { $p3->resolve('c'); });
$p4 = $p1
->then(function () use ($p2) { return $p2; })
->then(function () use ($p3) { return $p3; });
$this->assertEquals('c', $p4->wait());
}
public function testForwardsFulfilledDownChainBetweenGaps()
{
$p = new Promise();
$r = $r2 = null;
$p->then(null, null)
->then(function ($v) use (&$r) { $r = $v; return $v . '2'; })
->then(function ($v) use (&$r2) { $r2 = $v; });
$p->resolve('foo');
P\queue()->run();
$this->assertEquals('foo', $r);
$this->assertEquals('foo2', $r2);
}
public function testForwardsRejectedPromisesDownChainBetweenGaps()
{
$p = new Promise();
$r = $r2 = null;
$p->then(null, null)
->then(null, function ($v) use (&$r) { $r = $v; return $v . '2'; })
->then(function ($v) use (&$r2) { $r2 = $v; });
$p->reject('foo');
P\queue()->run();
$this->assertEquals('foo', $r);
$this->assertEquals('foo2', $r2);
}
public function testForwardsThrownPromisesDownChainBetweenGaps()
{
$e = new \Exception();
$p = new Promise();
$r = $r2 = null;
$p->then(null, null)
->then(null, function ($v) use (&$r, $e) {
$r = $v;
throw $e;
})
->then(
null,
function ($v) use (&$r2) { $r2 = $v; }
);
$p->reject('foo');
P\queue()->run();
$this->assertEquals('foo', $r);
$this->assertSame($e, $r2);
}
public function testForwardsReturnedRejectedPromisesDownChainBetweenGaps()
{
$p = new Promise();
$rejected = new RejectedPromise('bar');
$r = $r2 = null;
$p->then(null, null)
->then(null, function ($v) use (&$r, $rejected) {
$r = $v;
return $rejected;
})
->then(
null,
function ($v) use (&$r2) { $r2 = $v; }
);
$p->reject('foo');
P\queue()->run();
$this->assertEquals('foo', $r);
$this->assertEquals('bar', $r2);
try {
$p->wait();
} catch (RejectionException $e) {
$this->assertEquals('foo', $e->getReason());
}
}
public function testForwardsHandlersToNextPromise()
{
$p = new Promise();
$p2 = new Promise();
$resolved = null;
$p
->then(function ($v) use ($p2) { return $p2; })
->then(function ($value) use (&$resolved) { $resolved = $value; });
$p->resolve('a');
$p2->resolve('b');
P\queue()->run();
$this->assertEquals('b', $resolved);
}
public function testRemovesReferenceFromChildWhenParentWaitedUpon()
{
$r = null;
$p = new Promise(function () use (&$p) { $p->resolve('a'); });
$p2 = new Promise(function () use (&$p2) { $p2->resolve('b'); });
$pb = $p->then(
function ($v) use ($p2, &$r) {
$r = $v;
return $p2;
})
->then(function ($v) { return $v . '.'; });
$this->assertEquals('a', $p->wait());
$this->assertEquals('b', $p2->wait());
$this->assertEquals('b.', $pb->wait());
$this->assertEquals('a', $r);
}
public function testForwardsHandlersWhenFulfilledPromiseIsReturned()
{
$res = [];
$p = new Promise();
$p2 = new Promise();
$p2->resolve('foo');
$p2->then(function ($v) use (&$res) { $res[] = 'A:' . $v; });
// $res is A:foo
$p
->then(function () use ($p2, &$res) { $res[] = 'B'; return $p2; })
->then(function ($v) use (&$res) { $res[] = 'C:' . $v; });
$p->resolve('a');
$p->then(function ($v) use (&$res) { $res[] = 'D:' . $v; });
P\queue()->run();
$this->assertEquals(['A:foo', 'B', 'D:a', 'C:foo'], $res);
}
public function testForwardsHandlersWhenRejectedPromiseIsReturned()
{
$res = [];
$p = new Promise();
$p2 = new Promise();
$p2->reject('foo');
$p2->then(null, function ($v) use (&$res) { $res[] = 'A:' . $v; });
$p->then(null, function () use ($p2, &$res) { $res[] = 'B'; return $p2; })
->then(null, function ($v) use (&$res) { $res[] = 'C:' . $v; });
$p->reject('a');
$p->then(null, function ($v) use (&$res) { $res[] = 'D:' . $v; });
P\queue()->run();
$this->assertEquals(['A:foo', 'B', 'D:a', 'C:foo'], $res);
}
public function testDoesNotForwardRejectedPromise()
{
$res = [];
$p = new Promise();
$p2 = new Promise();
$p2->cancel();
$p2->then(function ($v) use (&$res) { $res[] = "B:$v"; return $v; });
$p->then(function ($v) use ($p2, &$res) { $res[] = "B:$v"; return $p2; })
->then(function ($v) use (&$res) { $res[] = 'C:' . $v; });
$p->resolve('a');
$p->then(function ($v) use (&$res) { $res[] = 'D:' . $v; });
P\queue()->run();
$this->assertEquals(['B:a', 'D:a'], $res);
}
public function testRecursivelyForwardsWhenOnlyThennable()
{
$res = [];
$p = new Promise();
$p2 = new Thennable();
$p2->resolve('foo');
$p2->then(function ($v) use (&$res) { $res[] = 'A:' . $v; });
$p->then(function () use ($p2, &$res) { $res[] = 'B'; return $p2; })
->then(function ($v) use (&$res) { $res[] = 'C:' . $v; });
$p->resolve('a');
$p->then(function ($v) use (&$res) { $res[] = 'D:' . $v; });
P\queue()->run();
$this->assertEquals(['A:foo', 'B', 'D:a', 'C:foo'], $res);
}
public function testRecursivelyForwardsWhenNotInstanceOfPromise()
{
$res = [];
$p = new Promise();
$p2 = new NotPromiseInstance();
$p2->then(function ($v) use (&$res) { $res[] = 'A:' . $v; });
$p->then(function () use ($p2, &$res) { $res[] = 'B'; return $p2; })
->then(function ($v) use (&$res) { $res[] = 'C:' . $v; });
$p->resolve('a');
$p->then(function ($v) use (&$res) { $res[] = 'D:' . $v; });
P\queue()->run();
$this->assertEquals(['B', 'D:a'], $res);
$p2->resolve('foo');
P\queue()->run();
$this->assertEquals(['B', 'D:a', 'A:foo', 'C:foo'], $res);
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage Cannot fulfill or reject a promise with itself
*/
public function testCannotResolveWithSelf()
{
$p = new Promise();
$p->resolve($p);
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage Cannot fulfill or reject a promise with itself
*/
public function testCannotRejectWithSelf()
{
$p = new Promise();
$p->reject($p);
}
public function testDoesNotBlowStackWhenWaitingOnNestedThens()
{
$inner = new Promise(function () use (&$inner) { $inner->resolve(0); });
$prev = $inner;
for ($i = 1; $i < 100; $i++) {
$prev = $prev->then(function ($i) { return $i + 1; });
}
$parent = new Promise(function () use (&$parent, $prev) {
$parent->resolve($prev);
});
$this->assertEquals(99, $parent->wait());
}
public function testOtherwiseIsSugarForRejections()
{
$p = new Promise();
$p->reject('foo');
$p->otherwise(function ($v) use (&$c) { $c = $v; });
P\queue()->run();
$this->assertEquals($c, 'foo');
}
}

View file

@ -1,143 +0,0 @@
<?php
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\RejectedPromise;
/**
* @covers GuzzleHttp\Promise\RejectedPromise
*/
class RejectedPromiseTest extends \PHPUnit_Framework_TestCase
{
public function testThrowsReasonWhenWaitedUpon()
{
$p = new RejectedPromise('foo');
$this->assertEquals('rejected', $p->getState());
try {
$p->wait(true);
$this->fail();
} catch (\Exception $e) {
$this->assertEquals('rejected', $p->getState());
$this->assertContains('foo', $e->getMessage());
}
}
public function testCannotCancel()
{
$p = new RejectedPromise('foo');
$p->cancel();
$this->assertEquals('rejected', $p->getState());
}
/**
* @expectedException \LogicException
* @exepctedExceptionMessage Cannot resolve a rejected promise
*/
public function testCannotResolve()
{
$p = new RejectedPromise('foo');
$p->resolve('bar');
}
/**
* @expectedException \LogicException
* @exepctedExceptionMessage Cannot reject a rejected promise
*/
public function testCannotReject()
{
$p = new RejectedPromise('foo');
$p->reject('bar');
}
public function testCanRejectWithSameValue()
{
$p = new RejectedPromise('foo');
$p->reject('foo');
}
public function testThrowsSpecificException()
{
$e = new \Exception();
$p = new RejectedPromise($e);
try {
$p->wait(true);
$this->fail();
} catch (\Exception $e2) {
$this->assertSame($e, $e2);
}
}
/**
* @expectedException \InvalidArgumentException
*/
public function testCannotResolveWithPromise()
{
new RejectedPromise(new Promise());
}
public function testReturnsSelfWhenNoOnReject()
{
$p = new RejectedPromise('a');
$this->assertSame($p, $p->then());
}
public function testInvokesOnRejectedAsynchronously()
{
$p = new RejectedPromise('a');
$r = null;
$f = function ($reason) use (&$r) { $r = $reason; };
$p->then(null, $f);
$this->assertNull($r);
\GuzzleHttp\Promise\queue()->run();
$this->assertEquals('a', $r);
}
public function testReturnsNewRejectedWhenOnRejectedFails()
{
$p = new RejectedPromise('a');
$f = function () { throw new \Exception('b'); };
$p2 = $p->then(null, $f);
$this->assertNotSame($p, $p2);
try {
$p2->wait();
$this->fail();
} catch (\Exception $e) {
$this->assertEquals('b', $e->getMessage());
}
}
public function testWaitingIsNoOp()
{
$p = new RejectedPromise('a');
$p->wait(false);
}
public function testOtherwiseIsSugarForRejections()
{
$p = new RejectedPromise('foo');
$p->otherwise(function ($v) use (&$c) { $c = $v; });
\GuzzleHttp\Promise\queue()->run();
$this->assertSame('foo', $c);
}
public function testCanResolveThenWithSuccess()
{
$actual = null;
$p = new RejectedPromise('foo');
$p->otherwise(function ($v) {
return $v . ' bar';
})->then(function ($v) use (&$actual) {
$actual = $v;
});
\GuzzleHttp\Promise\queue()->run();
$this->assertEquals('foo bar', $actual);
}
public function testDoesNotTryToRejectTwiceDuringTrampoline()
{
$fp = new RejectedPromise('a');
$t1 = $fp->then(null, function ($v) { return $v . ' b'; });
$t1->resolve('why!');
$this->assertEquals('why!', $t1->wait());
}
}

View file

@ -1,47 +0,0 @@
<?php
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\RejectionException;
class Thing1
{
public function __construct($message)
{
$this->message = $message;
}
public function __toString()
{
return $this->message;
}
}
class Thing2 implements \JsonSerializable
{
public function jsonSerialize()
{
return '{}';
}
}
/**
* @covers GuzzleHttp\Promise\RejectionException
*/
class RejectionExceptionTest extends \PHPUnit_Framework_TestCase
{
public function testCanGetReasonFromException()
{
$thing = new Thing1('foo');
$e = new RejectionException($thing);
$this->assertSame($thing, $e->getReason());
$this->assertEquals('The promise was rejected with reason: foo', $e->getMessage());
}
public function testCanGetReasonMessageFromJson()
{
$reason = new Thing2();
$e = new RejectionException($reason);
$this->assertContains("{}", $e->getMessage());
}
}

View file

@ -1,31 +0,0 @@
<?php
namespace GuzzleHttp\Promise\Test;
use GuzzleHttp\Promise\TaskQueue;
class TaskQueueTest extends \PHPUnit_Framework_TestCase
{
public function testKnowsIfEmpty()
{
$tq = new TaskQueue(false);
$this->assertTrue($tq->isEmpty());
}
public function testKnowsIfFull()
{
$tq = new TaskQueue(false);
$tq->add(function () {});
$this->assertFalse($tq->isEmpty());
}
public function testExecutesTasksInOrder()
{
$tq = new TaskQueue(false);
$called = [];
$tq->add(function () use (&$called) { $called[] = 'a'; });
$tq->add(function () use (&$called) { $called[] = 'b'; });
$tq->add(function () use (&$called) { $called[] = 'c'; });
$tq->run();
$this->assertEquals(['a', 'b', 'c'], $called);
}
}

View file

@ -1,24 +0,0 @@
<?php
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise\Promise;
class Thennable
{
private $nextPromise = null;
public function __construct()
{
$this->nextPromise = new Promise();
}
public function then(callable $res = null, callable $rej = null)
{
return $this->nextPromise->then($res, $rej);
}
public function resolve($value)
{
$this->nextPromise->resolve($value);
}
}

View file

@ -1,4 +0,0 @@
<?php
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/Thennable.php';
require __DIR__ . '/NotPromiseInstance.php';

View file

@ -1,694 +0,0 @@
<?php
namespace GuzzleHttp\Promise\Tests;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\RejectedPromise;
class FunctionsTest extends \PHPUnit_Framework_TestCase
{
public function testCreatesPromiseForValue()
{
$p = \GuzzleHttp\Promise\promise_for('foo');
$this->assertInstanceOf('GuzzleHttp\Promise\FulfilledPromise', $p);
}
public function testReturnsPromiseForPromise()
{
$p = new Promise();
$this->assertSame($p, \GuzzleHttp\Promise\promise_for($p));
}
public function testReturnsPromiseForThennable()
{
$p = new Thennable();
$wrapped = \GuzzleHttp\Promise\promise_for($p);
$this->assertNotSame($p, $wrapped);
$this->assertInstanceOf('GuzzleHttp\Promise\PromiseInterface', $wrapped);
$p->resolve('foo');
P\queue()->run();
$this->assertEquals('foo', $wrapped->wait());
}
public function testReturnsRejection()
{
$p = \GuzzleHttp\Promise\rejection_for('fail');
$this->assertInstanceOf('GuzzleHttp\Promise\RejectedPromise', $p);
$this->assertEquals('fail', $this->readAttribute($p, 'reason'));
}
public function testReturnsPromisesAsIsInRejectionFor()
{
$a = new Promise();
$b = \GuzzleHttp\Promise\rejection_for($a);
$this->assertSame($a, $b);
}
public function testWaitsOnAllPromisesIntoArray()
{
$e = new \Exception();
$a = new Promise(function () use (&$a) { $a->resolve('a'); });
$b = new Promise(function () use (&$b) { $b->reject('b'); });
$c = new Promise(function () use (&$c, $e) { $c->reject($e); });
$results = \GuzzleHttp\Promise\inspect_all([$a, $b, $c]);
$this->assertEquals([
['state' => 'fulfilled', 'value' => 'a'],
['state' => 'rejected', 'reason' => 'b'],
['state' => 'rejected', 'reason' => $e]
], $results);
}
/**
* @expectedException \GuzzleHttp\Promise\RejectionException
*/
public function testUnwrapsPromisesWithNoDefaultAndFailure()
{
$promises = [new FulfilledPromise('a'), new Promise()];
\GuzzleHttp\Promise\unwrap($promises);
}
public function testUnwrapsPromisesWithNoDefault()
{
$promises = [new FulfilledPromise('a')];
$this->assertEquals(['a'], \GuzzleHttp\Promise\unwrap($promises));
}
public function testUnwrapsPromisesWithKeys()
{
$promises = [
'foo' => new FulfilledPromise('a'),
'bar' => new FulfilledPromise('b'),
];
$this->assertEquals([
'foo' => 'a',
'bar' => 'b'
], \GuzzleHttp\Promise\unwrap($promises));
}
public function testAllAggregatesSortedArray()
{
$a = new Promise();
$b = new Promise();
$c = new Promise();
$d = \GuzzleHttp\Promise\all([$a, $b, $c]);
$b->resolve('b');
$a->resolve('a');
$c->resolve('c');
$d->then(
function ($value) use (&$result) { $result = $value; },
function ($reason) use (&$result) { $result = $reason; }
);
P\queue()->run();
$this->assertEquals(['a', 'b', 'c'], $result);
}
public function testAllThrowsWhenAnyRejected()
{
$a = new Promise();
$b = new Promise();
$c = new Promise();
$d = \GuzzleHttp\Promise\all([$a, $b, $c]);
$b->resolve('b');
$a->reject('fail');
$c->resolve('c');
$d->then(
function ($value) use (&$result) { $result = $value; },
function ($reason) use (&$result) { $result = $reason; }
);
P\queue()->run();
$this->assertEquals('fail', $result);
}
public function testSomeAggregatesSortedArrayWithMax()
{
$a = new Promise();
$b = new Promise();
$c = new Promise();
$d = \GuzzleHttp\Promise\some(2, [$a, $b, $c]);
$b->resolve('b');
$c->resolve('c');
$a->resolve('a');
$d->then(function ($value) use (&$result) { $result = $value; });
P\queue()->run();
$this->assertEquals(['b', 'c'], $result);
}
public function testSomeRejectsWhenTooManyRejections()
{
$a = new Promise();
$b = new Promise();
$d = \GuzzleHttp\Promise\some(2, [$a, $b]);
$a->reject('bad');
$b->resolve('good');
P\queue()->run();
$this->assertEquals($a::REJECTED, $d->getState());
$d->then(null, function ($reason) use (&$called) {
$called = $reason;
});
P\queue()->run();
$this->assertInstanceOf('GuzzleHttp\Promise\AggregateException', $called);
$this->assertContains('bad', $called->getReason());
}
public function testCanWaitUntilSomeCountIsSatisfied()
{
$a = new Promise(function () use (&$a) { $a->resolve('a'); });
$b = new Promise(function () use (&$b) { $b->resolve('b'); });
$c = new Promise(function () use (&$c) { $c->resolve('c'); });
$d = \GuzzleHttp\Promise\some(2, [$a, $b, $c]);
$this->assertEquals(['a', 'b'], $d->wait());
}
/**
* @expectedException \GuzzleHttp\Promise\AggregateException
* @expectedExceptionMessage Not enough promises to fulfill count
*/
public function testThrowsIfImpossibleToWaitForSomeCount()
{
$a = new Promise(function () use (&$a) { $a->resolve('a'); });
$d = \GuzzleHttp\Promise\some(2, [$a]);
$d->wait();
}
/**
* @expectedException \GuzzleHttp\Promise\AggregateException
* @expectedExceptionMessage Not enough promises to fulfill count
*/
public function testThrowsIfResolvedWithoutCountTotalResults()
{
$a = new Promise();
$b = new Promise();
$d = \GuzzleHttp\Promise\some(3, [$a, $b]);
$a->resolve('a');
$b->resolve('b');
$d->wait();
}
public function testAnyReturnsFirstMatch()
{
$a = new Promise();
$b = new Promise();
$c = \GuzzleHttp\Promise\any([$a, $b]);
$b->resolve('b');
$a->resolve('a');
//P\queue()->run();
//$this->assertEquals('fulfilled', $c->getState());
$c->then(function ($value) use (&$result) { $result = $value; });
P\queue()->run();
$this->assertEquals('b', $result);
}
public function testSettleFulfillsWithFulfilledAndRejected()
{
$a = new Promise();
$b = new Promise();
$c = new Promise();
$d = \GuzzleHttp\Promise\settle([$a, $b, $c]);
$b->resolve('b');
$c->resolve('c');
$a->reject('a');
P\queue()->run();
$this->assertEquals('fulfilled', $d->getState());
$d->then(function ($value) use (&$result) { $result = $value; });
P\queue()->run();
$this->assertEquals([
['state' => 'rejected', 'reason' => 'a'],
['state' => 'fulfilled', 'value' => 'b'],
['state' => 'fulfilled', 'value' => 'c']
], $result);
}
public function testCanInspectFulfilledPromise()
{
$p = new FulfilledPromise('foo');
$this->assertEquals([
'state' => 'fulfilled',
'value' => 'foo'
], \GuzzleHttp\Promise\inspect($p));
}
public function testCanInspectRejectedPromise()
{
$p = new RejectedPromise('foo');
$this->assertEquals([
'state' => 'rejected',
'reason' => 'foo'
], \GuzzleHttp\Promise\inspect($p));
}
public function testCanInspectRejectedPromiseWithNormalException()
{
$e = new \Exception('foo');
$p = new RejectedPromise($e);
$this->assertEquals([
'state' => 'rejected',
'reason' => $e
], \GuzzleHttp\Promise\inspect($p));
}
public function testCallsEachLimit()
{
$p = new Promise();
$aggregate = \GuzzleHttp\Promise\each_limit($p, 2);
$p->resolve('a');
P\queue()->run();
$this->assertEquals($p::FULFILLED, $aggregate->getState());
}
public function testEachLimitAllRejectsOnFailure()
{
$p = [new FulfilledPromise('a'), new RejectedPromise('b')];
$aggregate = \GuzzleHttp\Promise\each_limit_all($p, 2);
P\queue()->run();
$this->assertEquals(P\PromiseInterface::REJECTED, $aggregate->getState());
$result = \GuzzleHttp\Promise\inspect($aggregate);
$this->assertEquals('b', $result['reason']);
}
public function testIterForReturnsIterator()
{
$iter = new \ArrayIterator();
$this->assertSame($iter, \GuzzleHttp\Promise\iter_for($iter));
}
public function testKnowsIfFulfilled()
{
$p = new FulfilledPromise(null);
$this->assertTrue(P\is_fulfilled($p));
$this->assertFalse(P\is_rejected($p));
}
public function testKnowsIfRejected()
{
$p = new RejectedPromise(null);
$this->assertTrue(P\is_rejected($p));
$this->assertFalse(P\is_fulfilled($p));
}
public function testKnowsIfSettled()
{
$p = new RejectedPromise(null);
$this->assertTrue(P\is_settled($p));
$p = new Promise();
$this->assertFalse(P\is_settled($p));
}
public function testReturnsTrampoline()
{
$this->assertInstanceOf('GuzzleHttp\Promise\TaskQueue', P\queue());
$this->assertSame(P\queue(), P\queue());
}
public function testCanScheduleThunk()
{
$tramp = P\queue();
$promise = P\task(function () { return 'Hi!'; });
$c = null;
$promise->then(function ($v) use (&$c) { $c = $v; });
$this->assertNull($c);
$tramp->run();
$this->assertEquals('Hi!', $c);
}
public function testCanScheduleThunkWithRejection()
{
$tramp = P\queue();
$promise = P\task(function () { throw new \Exception('Hi!'); });
$c = null;
$promise->otherwise(function ($v) use (&$c) { $c = $v; });
$this->assertNull($c);
$tramp->run();
$this->assertEquals('Hi!', $c->getMessage());
}
public function testCanScheduleThunkWithWait()
{
$tramp = P\queue();
$promise = P\task(function () { return 'a'; });
$this->assertEquals('a', $promise->wait());
$tramp->run();
}
public function testYieldsFromCoroutine()
{
$promise = P\coroutine(function () {
$value = (yield new P\FulfilledPromise('a'));
yield $value . 'b';
});
$promise->then(function ($value) use (&$result) { $result = $value; });
P\queue()->run();
$this->assertEquals('ab', $result);
}
public function testCanCatchExceptionsInCoroutine()
{
$promise = P\coroutine(function () {
try {
yield new P\RejectedPromise('a');
$this->fail('Should have thrown into the coroutine!');
} catch (P\RejectionException $e) {
$value = (yield new P\FulfilledPromise($e->getReason()));
yield $value . 'b';
}
});
$promise->then(function ($value) use (&$result) { $result = $value; });
P\queue()->run();
$this->assertEquals(P\PromiseInterface::FULFILLED, $promise->getState());
$this->assertEquals('ab', $result);
}
public function testRejectsParentExceptionWhenException()
{
$promise = P\coroutine(function () {
yield new P\FulfilledPromise(0);
throw new \Exception('a');
});
$promise->then(
function () { $this->fail(); },
function ($reason) use (&$result) { $result = $reason; }
);
P\queue()->run();
$this->assertInstanceOf('Exception', $result);
$this->assertEquals('a', $result->getMessage());
}
public function testCanRejectFromRejectionCallback()
{
$promise = P\coroutine(function () {
yield new P\FulfilledPromise(0);
yield new P\RejectedPromise('no!');
});
$promise->then(
function () { $this->fail(); },
function ($reason) use (&$result) { $result = $reason; }
);
P\queue()->run();
$this->assertInstanceOf('GuzzleHttp\Promise\RejectionException', $result);
$this->assertEquals('no!', $result->getReason());
}
public function testCanAsyncReject()
{
$rej = new P\Promise();
$promise = P\coroutine(function () use ($rej) {
yield new P\FulfilledPromise(0);
yield $rej;
});
$promise->then(
function () { $this->fail(); },
function ($reason) use (&$result) { $result = $reason; }
);
$rej->reject('no!');
P\queue()->run();
$this->assertInstanceOf('GuzzleHttp\Promise\RejectionException', $result);
$this->assertEquals('no!', $result->getReason());
}
public function testCanCatchAndThrowOtherException()
{
$promise = P\coroutine(function () {
try {
yield new P\RejectedPromise('a');
$this->fail('Should have thrown into the coroutine!');
} catch (P\RejectionException $e) {
throw new \Exception('foo');
}
});
$promise->otherwise(function ($value) use (&$result) { $result = $value; });
P\queue()->run();
$this->assertEquals(P\PromiseInterface::REJECTED, $promise->getState());
$this->assertContains('foo', $result->getMessage());
}
public function testCanCatchAndYieldOtherException()
{
$promise = P\coroutine(function () {
try {
yield new P\RejectedPromise('a');
$this->fail('Should have thrown into the coroutine!');
} catch (P\RejectionException $e) {
yield new P\RejectedPromise('foo');
}
});
$promise->otherwise(function ($value) use (&$result) { $result = $value; });
P\queue()->run();
$this->assertEquals(P\PromiseInterface::REJECTED, $promise->getState());
$this->assertContains('foo', $result->getMessage());
}
public function createLotsOfSynchronousPromise()
{
return P\coroutine(function () {
$value = 0;
for ($i = 0; $i < 1000; $i++) {
$value = (yield new P\FulfilledPromise($i));
}
yield $value;
});
}
public function testLotsOfSynchronousDoesNotBlowStack()
{
$promise = $this->createLotsOfSynchronousPromise();
$promise->then(function ($v) use (&$r) { $r = $v; });
P\queue()->run();
$this->assertEquals(999, $r);
}
public function testLotsOfSynchronousWaitDoesNotBlowStack()
{
$promise = $this->createLotsOfSynchronousPromise();
$promise->then(function ($v) use (&$r) { $r = $v; });
$this->assertEquals(999, $promise->wait());
$this->assertEquals(999, $r);
}
private function createLotsOfFlappingPromise()
{
return P\coroutine(function () {
$value = 0;
for ($i = 0; $i < 1000; $i++) {
try {
if ($i % 2) {
$value = (yield new P\FulfilledPromise($i));
} else {
$value = (yield new P\RejectedPromise($i));
}
} catch (\Exception $e) {
$value = (yield new P\FulfilledPromise($i));
}
}
yield $value;
});
}
public function testLotsOfTryCatchingDoesNotBlowStack()
{
$promise = $this->createLotsOfFlappingPromise();
$promise->then(function ($v) use (&$r) { $r = $v; });
P\queue()->run();
$this->assertEquals(999, $r);
}
public function testLotsOfTryCatchingWaitingDoesNotBlowStack()
{
$promise = $this->createLotsOfFlappingPromise();
$promise->then(function ($v) use (&$r) { $r = $v; });
$this->assertEquals(999, $promise->wait());
$this->assertEquals(999, $r);
}
public function testAsyncPromisesWithCorrectlyYieldedValues()
{
$promises = [
new P\Promise(),
new P\Promise(),
new P\Promise()
];
$promise = P\coroutine(function () use ($promises) {
$value = null;
$this->assertEquals('skip', (yield new P\FulfilledPromise('skip')));
foreach ($promises as $idx => $p) {
$value = (yield $p);
$this->assertEquals($value, $idx);
$this->assertEquals('skip', (yield new P\FulfilledPromise('skip')));
}
$this->assertEquals('skip', (yield new P\FulfilledPromise('skip')));
yield $value;
});
$promises[0]->resolve(0);
$promises[1]->resolve(1);
$promises[2]->resolve(2);
$promise->then(function ($v) use (&$r) { $r = $v; });
P\queue()->run();
$this->assertEquals(2, $r);
}
public function testYieldFinalWaitablePromise()
{
$p1 = new P\Promise(function () use (&$p1) {
$p1->resolve('skip me');
});
$p2 = new P\Promise(function () use (&$p2) {
$p2->resolve('hello!');
});
$co = P\coroutine(function() use ($p1, $p2) {
yield $p1;
yield $p2;
});
P\queue()->run();
$this->assertEquals('hello!', $co->wait());
}
public function testCanYieldFinalPendingPromise()
{
$p1 = new P\Promise();
$p2 = new P\Promise();
$co = P\coroutine(function() use ($p1, $p2) {
yield $p1;
yield $p2;
});
$p1->resolve('a');
$p2->resolve('b');
$co->then(function ($value) use (&$result) { $result = $value; });
P\queue()->run();
$this->assertEquals('b', $result);
}
public function testCanNestYieldsAndFailures()
{
$p1 = new P\Promise();
$p2 = new P\Promise();
$p3 = new P\Promise();
$p4 = new P\Promise();
$p5 = new P\Promise();
$co = P\coroutine(function() use ($p1, $p2, $p3, $p4, $p5) {
try {
yield $p1;
} catch (\Exception $e) {
yield $p2;
try {
yield $p3;
yield $p4;
} catch (\Exception $e) {
yield $p5;
}
}
});
$p1->reject('a');
$p2->resolve('b');
$p3->resolve('c');
$p4->reject('d');
$p5->resolve('e');
$co->then(function ($value) use (&$result) { $result = $value; });
P\queue()->run();
$this->assertEquals('e', $result);
}
public function testCanYieldErrorsAndSuccessesWithoutRecursion()
{
$promises = [];
for ($i = 0; $i < 20; $i++) {
$promises[] = new P\Promise();
}
$co = P\coroutine(function() use ($promises) {
for ($i = 0; $i < 20; $i += 4) {
try {
yield $promises[$i];
yield $promises[$i + 1];
} catch (\Exception $e) {
yield $promises[$i + 2];
yield $promises[$i + 3];
}
}
});
for ($i = 0; $i < 20; $i += 4) {
$promises[$i]->resolve($i);
$promises[$i + 1]->reject($i + 1);
$promises[$i + 2]->resolve($i + 2);
$promises[$i + 3]->resolve($i + 3);
}
$co->then(function ($value) use (&$result) { $result = $value; });
P\queue()->run();
$this->assertEquals('19', $result);
}
public function testCanWaitOnPromiseAfterFulfilled()
{
$f = function () {
static $i = 0;
$i++;
return $p = new P\Promise(function () use (&$p, $i) {
$p->resolve($i . '-bar');
});
};
$promises = [];
for ($i = 0; $i < 20; $i++) {
$promises[] = $f();
}
$p = P\coroutine(function () use ($promises) {
yield new P\FulfilledPromise('foo!');
foreach ($promises as $promise) {
yield $promise;
}
});
$this->assertEquals('20-bar', $p->wait());
}
public function testCanWaitOnErroredPromises()
{
$p1 = new P\Promise(function () use (&$p1) { $p1->reject('a'); });
$p2 = new P\Promise(function () use (&$p2) { $p2->resolve('b'); });
$p3 = new P\Promise(function () use (&$p3) { $p3->resolve('c'); });
$p4 = new P\Promise(function () use (&$p4) { $p4->reject('d'); });
$p5 = new P\Promise(function () use (&$p5) { $p5->resolve('e'); });
$p6 = new P\Promise(function () use (&$p6) { $p6->reject('f'); });
$co = P\coroutine(function() use ($p1, $p2, $p3, $p4, $p5, $p6) {
try {
yield $p1;
} catch (\Exception $e) {
yield $p2;
try {
yield $p3;
yield $p4;
} catch (\Exception $e) {
yield $p5;
yield $p6;
}
}
});
$res = P\inspect($co);
$this->assertEquals('f', $res['reason']);
}
public function testCoroutineOtherwiseIntegrationTest()
{
$a = new P\Promise();
$b = new P\Promise();
$promise = P\coroutine(function () use ($a, $b) {
// Execute the pool of commands concurrently, and process errors.
yield $a;
yield $b;
})->otherwise(function (\Exception $e) {
// Throw errors from the operations as a specific Multipart error.
throw new \OutOfBoundsException('a', 0, $e);
});
$a->resolve('a');
$b->reject('b');
$reason = P\inspect($promise)['reason'];
$this->assertInstanceOf('OutOfBoundsException', $reason);
$this->assertInstanceOf('GuzzleHttp\Promise\RejectionException', $reason->getPrevious());
}
}

View file

@ -1,186 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\AppendStream;
use GuzzleHttp\Psr7;
class AppendStreamTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Each stream must be readable
*/
public function testValidatesStreamsAreReadable()
{
$a = new AppendStream();
$s = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
->setMethods(['isReadable'])
->getMockForAbstractClass();
$s->expects($this->once())
->method('isReadable')
->will($this->returnValue(false));
$a->addStream($s);
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage The AppendStream can only seek with SEEK_SET
*/
public function testValidatesSeekType()
{
$a = new AppendStream();
$a->seek(100, SEEK_CUR);
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Unable to seek stream 0 of the AppendStream
*/
public function testTriesToRewindOnSeek()
{
$a = new AppendStream();
$s = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
->setMethods(['isReadable', 'rewind', 'isSeekable'])
->getMockForAbstractClass();
$s->expects($this->once())
->method('isReadable')
->will($this->returnValue(true));
$s->expects($this->once())
->method('isSeekable')
->will($this->returnValue(true));
$s->expects($this->once())
->method('rewind')
->will($this->throwException(new \RuntimeException()));
$a->addStream($s);
$a->seek(10);
}
public function testSeeksToPositionByReading()
{
$a = new AppendStream([
Psr7\stream_for('foo'),
Psr7\stream_for('bar'),
Psr7\stream_for('baz'),
]);
$a->seek(3);
$this->assertEquals(3, $a->tell());
$this->assertEquals('bar', $a->read(3));
$a->seek(6);
$this->assertEquals(6, $a->tell());
$this->assertEquals('baz', $a->read(3));
}
public function testDetachesEachStream()
{
$s1 = Psr7\stream_for('foo');
$s2 = Psr7\stream_for('bar');
$a = new AppendStream([$s1, $s2]);
$this->assertSame('foobar', (string) $a);
$a->detach();
$this->assertSame('', (string) $a);
$this->assertSame(0, $a->getSize());
}
public function testClosesEachStream()
{
$s1 = Psr7\stream_for('foo');
$a = new AppendStream([$s1]);
$a->close();
$this->assertSame('', (string) $a);
}
/**
* @expectedExceptionMessage Cannot write to an AppendStream
* @expectedException \RuntimeException
*/
public function testIsNotWritable()
{
$a = new AppendStream([Psr7\stream_for('foo')]);
$this->assertFalse($a->isWritable());
$this->assertTrue($a->isSeekable());
$this->assertTrue($a->isReadable());
$a->write('foo');
}
public function testDoesNotNeedStreams()
{
$a = new AppendStream();
$this->assertEquals('', (string) $a);
}
public function testCanReadFromMultipleStreams()
{
$a = new AppendStream([
Psr7\stream_for('foo'),
Psr7\stream_for('bar'),
Psr7\stream_for('baz'),
]);
$this->assertFalse($a->eof());
$this->assertSame(0, $a->tell());
$this->assertEquals('foo', $a->read(3));
$this->assertEquals('bar', $a->read(3));
$this->assertEquals('baz', $a->read(3));
$this->assertSame('', $a->read(1));
$this->assertTrue($a->eof());
$this->assertSame(9, $a->tell());
$this->assertEquals('foobarbaz', (string) $a);
}
public function testCanDetermineSizeFromMultipleStreams()
{
$a = new AppendStream([
Psr7\stream_for('foo'),
Psr7\stream_for('bar')
]);
$this->assertEquals(6, $a->getSize());
$s = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
->setMethods(['isSeekable', 'isReadable'])
->getMockForAbstractClass();
$s->expects($this->once())
->method('isSeekable')
->will($this->returnValue(null));
$s->expects($this->once())
->method('isReadable')
->will($this->returnValue(true));
$a->addStream($s);
$this->assertNull($a->getSize());
}
public function testCatchesExceptionsWhenCastingToString()
{
$s = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
->setMethods(['isSeekable', 'read', 'isReadable', 'eof'])
->getMockForAbstractClass();
$s->expects($this->once())
->method('isSeekable')
->will($this->returnValue(true));
$s->expects($this->once())
->method('read')
->will($this->throwException(new \RuntimeException('foo')));
$s->expects($this->once())
->method('isReadable')
->will($this->returnValue(true));
$s->expects($this->any())
->method('eof')
->will($this->returnValue(false));
$a = new AppendStream([$s]);
$this->assertFalse($a->eof());
$this->assertSame('', (string) $a);
}
public function testCanDetach()
{
$s = new AppendStream();
$s->detach();
}
public function testReturnsEmptyMetadata()
{
$s = new AppendStream();
$this->assertEquals([], $s->getMetadata());
$this->assertNull($s->getMetadata('foo'));
}
}

View file

@ -1,63 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\BufferStream;
class BufferStreamTest extends \PHPUnit_Framework_TestCase
{
public function testHasMetadata()
{
$b = new BufferStream(10);
$this->assertTrue($b->isReadable());
$this->assertTrue($b->isWritable());
$this->assertFalse($b->isSeekable());
$this->assertEquals(null, $b->getMetadata('foo'));
$this->assertEquals(10, $b->getMetadata('hwm'));
$this->assertEquals([], $b->getMetadata());
}
public function testRemovesReadDataFromBuffer()
{
$b = new BufferStream();
$this->assertEquals(3, $b->write('foo'));
$this->assertEquals(3, $b->getSize());
$this->assertFalse($b->eof());
$this->assertEquals('foo', $b->read(10));
$this->assertTrue($b->eof());
$this->assertEquals('', $b->read(10));
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Cannot determine the position of a BufferStream
*/
public function testCanCastToStringOrGetContents()
{
$b = new BufferStream();
$b->write('foo');
$b->write('baz');
$this->assertEquals('foo', $b->read(3));
$b->write('bar');
$this->assertEquals('bazbar', (string) $b);
$b->tell();
}
public function testDetachClearsBuffer()
{
$b = new BufferStream();
$b->write('foo');
$b->detach();
$this->assertTrue($b->eof());
$this->assertEquals(3, $b->write('abc'));
$this->assertEquals('abc', $b->read(10));
}
public function testExceedingHighwaterMarkReturnsFalseButStillBuffers()
{
$b = new BufferStream(5);
$this->assertEquals(3, $b->write('hi '));
$this->assertFalse($b->write('hello'));
$this->assertEquals('hi hello', (string) $b);
$this->assertEquals(4, $b->write('test'));
}
}

View file

@ -1,166 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\CachingStream;
/**
* @covers GuzzleHttp\Psr7\CachingStream
*/
class CachingStreamTest extends \PHPUnit_Framework_TestCase
{
/** @var CachingStream */
protected $body;
protected $decorated;
public function setUp()
{
$this->decorated = Psr7\stream_for('testing');
$this->body = new CachingStream($this->decorated);
}
public function tearDown()
{
$this->decorated->close();
$this->body->close();
}
public function testUsesRemoteSizeIfPossible()
{
$body = Psr7\stream_for('test');
$caching = new CachingStream($body);
$this->assertEquals(4, $caching->getSize());
}
public function testReadsUntilCachedToByte()
{
$this->body->seek(5);
$this->assertEquals('n', $this->body->read(1));
$this->body->seek(0);
$this->assertEquals('t', $this->body->read(1));
}
public function testCanSeekNearEndWithSeekEnd()
{
$baseStream = Psr7\stream_for(implode('', range('a', 'z')));
$cached = new CachingStream($baseStream);
$cached->seek(1, SEEK_END);
$this->assertEquals(24, $baseStream->tell());
$this->assertEquals('y', $cached->read(1));
$this->assertEquals(26, $cached->getSize());
}
public function testCanSeekToEndWithSeekEnd()
{
$baseStream = Psr7\stream_for(implode('', range('a', 'z')));
$cached = new CachingStream($baseStream);
$cached->seek(0, SEEK_END);
$this->assertEquals(25, $baseStream->tell());
$this->assertEquals('z', $cached->read(1));
$this->assertEquals(26, $cached->getSize());
}
public function testCanUseSeekEndWithUnknownSize()
{
$baseStream = Psr7\stream_for('testing');
$decorated = Psr7\FnStream::decorate($baseStream, [
'getSize' => function () { return null; }
]);
$cached = new CachingStream($decorated);
$cached->seek(1, SEEK_END);
$this->assertEquals('ng', $cached->read(2));
}
public function testRewindUsesSeek()
{
$a = Psr7\stream_for('foo');
$d = $this->getMockBuilder('GuzzleHttp\Psr7\CachingStream')
->setMethods(array('seek'))
->setConstructorArgs(array($a))
->getMock();
$d->expects($this->once())
->method('seek')
->with(0)
->will($this->returnValue(true));
$d->seek(0);
}
public function testCanSeekToReadBytes()
{
$this->assertEquals('te', $this->body->read(2));
$this->body->seek(0);
$this->assertEquals('test', $this->body->read(4));
$this->assertEquals(4, $this->body->tell());
$this->body->seek(2);
$this->assertEquals(2, $this->body->tell());
$this->body->seek(2, SEEK_CUR);
$this->assertEquals(4, $this->body->tell());
$this->assertEquals('ing', $this->body->read(3));
}
public function testWritesToBufferStream()
{
$this->body->read(2);
$this->body->write('hi');
$this->body->seek(0);
$this->assertEquals('tehiing', (string) $this->body);
}
public function testSkipsOverwrittenBytes()
{
$decorated = Psr7\stream_for(
implode("\n", array_map(function ($n) {
return str_pad($n, 4, '0', STR_PAD_LEFT);
}, range(0, 25)))
);
$body = new CachingStream($decorated);
$this->assertEquals("0000\n", Psr7\readline($body));
$this->assertEquals("0001\n", Psr7\readline($body));
// Write over part of the body yet to be read, so skip some bytes
$this->assertEquals(5, $body->write("TEST\n"));
$this->assertEquals(5, $this->readAttribute($body, 'skipReadBytes'));
// Read, which skips bytes, then reads
$this->assertEquals("0003\n", Psr7\readline($body));
$this->assertEquals(0, $this->readAttribute($body, 'skipReadBytes'));
$this->assertEquals("0004\n", Psr7\readline($body));
$this->assertEquals("0005\n", Psr7\readline($body));
// Overwrite part of the cached body (so don't skip any bytes)
$body->seek(5);
$this->assertEquals(5, $body->write("ABCD\n"));
$this->assertEquals(0, $this->readAttribute($body, 'skipReadBytes'));
$this->assertEquals("TEST\n", Psr7\readline($body));
$this->assertEquals("0003\n", Psr7\readline($body));
$this->assertEquals("0004\n", Psr7\readline($body));
$this->assertEquals("0005\n", Psr7\readline($body));
$this->assertEquals("0006\n", Psr7\readline($body));
$this->assertEquals(5, $body->write("1234\n"));
$this->assertEquals(5, $this->readAttribute($body, 'skipReadBytes'));
// Seek to 0 and ensure the overwritten bit is replaced
$body->seek(0);
$this->assertEquals("0000\nABCD\nTEST\n0003\n0004\n0005\n0006\n1234\n0008\n0009\n", $body->read(50));
// Ensure that casting it to a string does not include the bit that was overwritten
$this->assertContains("0000\nABCD\nTEST\n0003\n0004\n0005\n0006\n1234\n0008\n0009\n", (string) $body);
}
public function testClosesBothStreams()
{
$s = fopen('php://temp', 'r');
$a = Psr7\stream_for($s);
$d = new CachingStream($a);
$d->close();
$this->assertFalse(is_resource($s));
}
/**
* @expectedException \InvalidArgumentException
*/
public function testEnsuresValidWhence()
{
$this->body->seek(10, -123456);
}
}

View file

@ -1,26 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\BufferStream;
use GuzzleHttp\Psr7\DroppingStream;
class DroppingStreamTest extends \PHPUnit_Framework_TestCase
{
public function testBeginsDroppingWhenSizeExceeded()
{
$stream = new BufferStream();
$drop = new DroppingStream($stream, 5);
$this->assertEquals(3, $drop->write('hel'));
$this->assertEquals(2, $drop->write('lo'));
$this->assertEquals(5, $drop->getSize());
$this->assertEquals('hello', $drop->read(5));
$this->assertEquals(0, $drop->getSize());
$drop->write('12345678910');
$this->assertEquals(5, $stream->getSize());
$this->assertEquals(5, $drop->getSize());
$this->assertEquals('12345', (string) $drop);
$this->assertEquals(0, $drop->getSize());
$drop->write('hello');
$this->assertSame(0, $drop->write('test'));
}
}

View file

@ -1,90 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\FnStream;
/**
* @covers GuzzleHttp\Psr7\FnStream
*/
class FnStreamTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \BadMethodCallException
* @expectedExceptionMessage seek() is not implemented in the FnStream
*/
public function testThrowsWhenNotImplemented()
{
(new FnStream([]))->seek(1);
}
public function testProxiesToFunction()
{
$s = new FnStream([
'read' => function ($len) {
$this->assertEquals(3, $len);
return 'foo';
}
]);
$this->assertEquals('foo', $s->read(3));
}
public function testCanCloseOnDestruct()
{
$called = false;
$s = new FnStream([
'close' => function () use (&$called) {
$called = true;
}
]);
unset($s);
$this->assertTrue($called);
}
public function testDoesNotRequireClose()
{
$s = new FnStream([]);
unset($s);
}
public function testDecoratesStream()
{
$a = Psr7\stream_for('foo');
$b = FnStream::decorate($a, []);
$this->assertEquals(3, $b->getSize());
$this->assertEquals($b->isWritable(), true);
$this->assertEquals($b->isReadable(), true);
$this->assertEquals($b->isSeekable(), true);
$this->assertEquals($b->read(3), 'foo');
$this->assertEquals($b->tell(), 3);
$this->assertEquals($a->tell(), 3);
$this->assertSame('', $a->read(1));
$this->assertEquals($b->eof(), true);
$this->assertEquals($a->eof(), true);
$b->seek(0);
$this->assertEquals('foo', (string) $b);
$b->seek(0);
$this->assertEquals('foo', $b->getContents());
$this->assertEquals($a->getMetadata(), $b->getMetadata());
$b->seek(0, SEEK_END);
$b->write('bar');
$this->assertEquals('foobar', (string) $b);
$this->assertInternalType('resource', $b->detach());
$b->close();
}
public function testDecoratesWithCustomizations()
{
$called = false;
$a = Psr7\stream_for('foo');
$b = FnStream::decorate($a, [
'read' => function ($len) use (&$called, $a) {
$called = true;
return $a->read($len);
}
]);
$this->assertEquals('foo', $b->read(3));
$this->assertTrue($called);
}
}

View file

@ -1,586 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\FnStream;
use GuzzleHttp\Psr7\NoSeekStream;
class FunctionsTest extends \PHPUnit_Framework_TestCase
{
public function testCopiesToString()
{
$s = Psr7\stream_for('foobaz');
$this->assertEquals('foobaz', Psr7\copy_to_string($s));
$s->seek(0);
$this->assertEquals('foo', Psr7\copy_to_string($s, 3));
$this->assertEquals('baz', Psr7\copy_to_string($s, 3));
$this->assertEquals('', Psr7\copy_to_string($s));
}
public function testCopiesToStringStopsWhenReadFails()
{
$s1 = Psr7\stream_for('foobaz');
$s1 = FnStream::decorate($s1, [
'read' => function () { return ''; }
]);
$result = Psr7\copy_to_string($s1);
$this->assertEquals('', $result);
}
public function testCopiesToStream()
{
$s1 = Psr7\stream_for('foobaz');
$s2 = Psr7\stream_for('');
Psr7\copy_to_stream($s1, $s2);
$this->assertEquals('foobaz', (string) $s2);
$s2 = Psr7\stream_for('');
$s1->seek(0);
Psr7\copy_to_stream($s1, $s2, 3);
$this->assertEquals('foo', (string) $s2);
Psr7\copy_to_stream($s1, $s2, 3);
$this->assertEquals('foobaz', (string) $s2);
}
public function testStopsCopyToStreamWhenWriteFails()
{
$s1 = Psr7\stream_for('foobaz');
$s2 = Psr7\stream_for('');
$s2 = FnStream::decorate($s2, ['write' => function () { return 0; }]);
Psr7\copy_to_stream($s1, $s2);
$this->assertEquals('', (string) $s2);
}
public function testStopsCopyToSteamWhenWriteFailsWithMaxLen()
{
$s1 = Psr7\stream_for('foobaz');
$s2 = Psr7\stream_for('');
$s2 = FnStream::decorate($s2, ['write' => function () { return 0; }]);
Psr7\copy_to_stream($s1, $s2, 10);
$this->assertEquals('', (string) $s2);
}
public function testStopsCopyToSteamWhenReadFailsWithMaxLen()
{
$s1 = Psr7\stream_for('foobaz');
$s1 = FnStream::decorate($s1, ['read' => function () { return ''; }]);
$s2 = Psr7\stream_for('');
Psr7\copy_to_stream($s1, $s2, 10);
$this->assertEquals('', (string) $s2);
}
public function testReadsLines()
{
$s = Psr7\stream_for("foo\nbaz\nbar");
$this->assertEquals("foo\n", Psr7\readline($s));
$this->assertEquals("baz\n", Psr7\readline($s));
$this->assertEquals("bar", Psr7\readline($s));
}
public function testReadsLinesUpToMaxLength()
{
$s = Psr7\stream_for("12345\n");
$this->assertEquals("123", Psr7\readline($s, 4));
$this->assertEquals("45\n", Psr7\readline($s));
}
public function testReadsLineUntilFalseReturnedFromRead()
{
$s = $this->getMockBuilder('GuzzleHttp\Psr7\Stream')
->setMethods(['read', 'eof'])
->disableOriginalConstructor()
->getMock();
$s->expects($this->exactly(2))
->method('read')
->will($this->returnCallback(function () {
static $c = false;
if ($c) {
return false;
}
$c = true;
return 'h';
}));
$s->expects($this->exactly(2))
->method('eof')
->will($this->returnValue(false));
$this->assertEquals("h", Psr7\readline($s));
}
public function testCalculatesHash()
{
$s = Psr7\stream_for('foobazbar');
$this->assertEquals(md5('foobazbar'), Psr7\hash($s, 'md5'));
}
/**
* @expectedException \RuntimeException
*/
public function testCalculatesHashThrowsWhenSeekFails()
{
$s = new NoSeekStream(Psr7\stream_for('foobazbar'));
$s->read(2);
Psr7\hash($s, 'md5');
}
public function testCalculatesHashSeeksToOriginalPosition()
{
$s = Psr7\stream_for('foobazbar');
$s->seek(4);
$this->assertEquals(md5('foobazbar'), Psr7\hash($s, 'md5'));
$this->assertEquals(4, $s->tell());
}
public function testOpensFilesSuccessfully()
{
$r = Psr7\try_fopen(__FILE__, 'r');
$this->assertInternalType('resource', $r);
fclose($r);
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Unable to open /path/to/does/not/exist using mode r
*/
public function testThrowsExceptionNotWarning()
{
Psr7\try_fopen('/path/to/does/not/exist', 'r');
}
public function parseQueryProvider()
{
return [
// Does not need to parse when the string is empty
['', []],
// Can parse mult-values items
['q=a&q=b', ['q' => ['a', 'b']]],
// Can parse multi-valued items that use numeric indices
['q[0]=a&q[1]=b', ['q[0]' => 'a', 'q[1]' => 'b']],
// Can parse duplicates and does not include numeric indices
['q[]=a&q[]=b', ['q[]' => ['a', 'b']]],
// Ensures that the value of "q" is an array even though one value
['q[]=a', ['q[]' => 'a']],
// Does not modify "." to "_" like PHP's parse_str()
['q.a=a&q.b=b', ['q.a' => 'a', 'q.b' => 'b']],
// Can decode %20 to " "
['q%20a=a%20b', ['q a' => 'a b']],
// Can parse funky strings with no values by assigning each to null
['q&a', ['q' => null, 'a' => null]],
// Does not strip trailing equal signs
['data=abc=', ['data' => 'abc=']],
// Can store duplicates without affecting other values
['foo=a&foo=b&?µ=c', ['foo' => ['a', 'b'], '?µ' => 'c']],
// Sets value to null when no "=" is present
['foo', ['foo' => null]],
// Preserves "0" keys.
['0', ['0' => null]],
// Sets the value to an empty string when "=" is present
['0=', ['0' => '']],
// Preserves falsey keys
['var=0', ['var' => '0']],
['a[b][c]=1&a[b][c]=2', ['a[b][c]' => ['1', '2']]],
['a[b]=c&a[d]=e', ['a[b]' => 'c', 'a[d]' => 'e']],
// Ensure it doesn't leave things behind with repeated values
// Can parse mult-values items
['q=a&q=b&q=c', ['q' => ['a', 'b', 'c']]],
];
}
/**
* @dataProvider parseQueryProvider
*/
public function testParsesQueries($input, $output)
{
$result = Psr7\parse_query($input);
$this->assertSame($output, $result);
}
public function testDoesNotDecode()
{
$str = 'foo%20=bar';
$data = Psr7\parse_query($str, false);
$this->assertEquals(['foo%20' => 'bar'], $data);
}
/**
* @dataProvider parseQueryProvider
*/
public function testParsesAndBuildsQueries($input, $output)
{
$result = Psr7\parse_query($input, false);
$this->assertSame($input, Psr7\build_query($result, false));
}
public function testEncodesWithRfc1738()
{
$str = Psr7\build_query(['foo bar' => 'baz+'], PHP_QUERY_RFC1738);
$this->assertEquals('foo+bar=baz%2B', $str);
}
public function testEncodesWithRfc3986()
{
$str = Psr7\build_query(['foo bar' => 'baz+'], PHP_QUERY_RFC3986);
$this->assertEquals('foo%20bar=baz%2B', $str);
}
public function testDoesNotEncode()
{
$str = Psr7\build_query(['foo bar' => 'baz+'], false);
$this->assertEquals('foo bar=baz+', $str);
}
public function testCanControlDecodingType()
{
$result = Psr7\parse_query('var=foo+bar', PHP_QUERY_RFC3986);
$this->assertEquals('foo+bar', $result['var']);
$result = Psr7\parse_query('var=foo+bar', PHP_QUERY_RFC1738);
$this->assertEquals('foo bar', $result['var']);
}
public function testParsesRequestMessages()
{
$req = "GET /abc HTTP/1.0\r\nHost: foo.com\r\nFoo: Bar\r\nBaz: Bam\r\nBaz: Qux\r\n\r\nTest";
$request = Psr7\parse_request($req);
$this->assertEquals('GET', $request->getMethod());
$this->assertEquals('/abc', $request->getRequestTarget());
$this->assertEquals('1.0', $request->getProtocolVersion());
$this->assertEquals('foo.com', $request->getHeaderLine('Host'));
$this->assertEquals('Bar', $request->getHeaderLine('Foo'));
$this->assertEquals('Bam, Qux', $request->getHeaderLine('Baz'));
$this->assertEquals('Test', (string) $request->getBody());
$this->assertEquals('http://foo.com/abc', (string) $request->getUri());
}
public function testParsesRequestMessagesWithHttpsScheme()
{
$req = "PUT /abc?baz=bar HTTP/1.1\r\nHost: foo.com:443\r\n\r\n";
$request = Psr7\parse_request($req);
$this->assertEquals('PUT', $request->getMethod());
$this->assertEquals('/abc?baz=bar', $request->getRequestTarget());
$this->assertEquals('1.1', $request->getProtocolVersion());
$this->assertEquals('foo.com:443', $request->getHeaderLine('Host'));
$this->assertEquals('', (string) $request->getBody());
$this->assertEquals('https://foo.com/abc?baz=bar', (string) $request->getUri());
}
public function testParsesRequestMessagesWithUriWhenHostIsNotFirst()
{
$req = "PUT / HTTP/1.1\r\nFoo: Bar\r\nHost: foo.com\r\n\r\n";
$request = Psr7\parse_request($req);
$this->assertEquals('PUT', $request->getMethod());
$this->assertEquals('/', $request->getRequestTarget());
$this->assertEquals('http://foo.com/', (string) $request->getUri());
}
public function testParsesRequestMessagesWithFullUri()
{
$req = "GET https://www.google.com:443/search?q=foobar HTTP/1.1\r\nHost: www.google.com\r\n\r\n";
$request = Psr7\parse_request($req);
$this->assertEquals('GET', $request->getMethod());
$this->assertEquals('https://www.google.com:443/search?q=foobar', $request->getRequestTarget());
$this->assertEquals('1.1', $request->getProtocolVersion());
$this->assertEquals('www.google.com', $request->getHeaderLine('Host'));
$this->assertEquals('', (string) $request->getBody());
$this->assertEquals('https://www.google.com/search?q=foobar', (string) $request->getUri());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testValidatesRequestMessages()
{
Psr7\parse_request("HTTP/1.1 200 OK\r\n\r\n");
}
public function testParsesResponseMessages()
{
$res = "HTTP/1.0 200 OK\r\nFoo: Bar\r\nBaz: Bam\r\nBaz: Qux\r\n\r\nTest";
$response = Psr7\parse_response($res);
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('OK', $response->getReasonPhrase());
$this->assertEquals('1.0', $response->getProtocolVersion());
$this->assertEquals('Bar', $response->getHeaderLine('Foo'));
$this->assertEquals('Bam, Qux', $response->getHeaderLine('Baz'));
$this->assertEquals('Test', (string) $response->getBody());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testValidatesResponseMessages()
{
Psr7\parse_response("GET / HTTP/1.1\r\n\r\n");
}
public function testDetermineMimetype()
{
$this->assertNull(Psr7\mimetype_from_extension('not-a-real-extension'));
$this->assertEquals(
'application/json',
Psr7\mimetype_from_extension('json')
);
$this->assertEquals(
'image/jpeg',
Psr7\mimetype_from_filename('/tmp/images/IMG034821.JPEG')
);
}
public function testCreatesUriForValue()
{
$this->assertInstanceOf('GuzzleHttp\Psr7\Uri', Psr7\uri_for('/foo'));
$this->assertInstanceOf(
'GuzzleHttp\Psr7\Uri',
Psr7\uri_for(new Psr7\Uri('/foo'))
);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testValidatesUri()
{
Psr7\uri_for([]);
}
public function testKeepsPositionOfResource()
{
$h = fopen(__FILE__, 'r');
fseek($h, 10);
$stream = Psr7\stream_for($h);
$this->assertEquals(10, $stream->tell());
$stream->close();
}
public function testCreatesWithFactory()
{
$stream = Psr7\stream_for('foo');
$this->assertInstanceOf('GuzzleHttp\Psr7\Stream', $stream);
$this->assertEquals('foo', $stream->getContents());
$stream->close();
}
public function testFactoryCreatesFromEmptyString()
{
$s = Psr7\stream_for();
$this->assertInstanceOf('GuzzleHttp\Psr7\Stream', $s);
}
public function testFactoryCreatesFromNull()
{
$s = Psr7\stream_for(null);
$this->assertInstanceOf('GuzzleHttp\Psr7\Stream', $s);
}
public function testFactoryCreatesFromResource()
{
$r = fopen(__FILE__, 'r');
$s = Psr7\stream_for($r);
$this->assertInstanceOf('GuzzleHttp\Psr7\Stream', $s);
$this->assertSame(file_get_contents(__FILE__), (string) $s);
}
public function testFactoryCreatesFromObjectWithToString()
{
$r = new HasToString();
$s = Psr7\stream_for($r);
$this->assertInstanceOf('GuzzleHttp\Psr7\Stream', $s);
$this->assertEquals('foo', (string) $s);
}
public function testCreatePassesThrough()
{
$s = Psr7\stream_for('foo');
$this->assertSame($s, Psr7\stream_for($s));
}
/**
* @expectedException \InvalidArgumentException
*/
public function testThrowsExceptionForUnknown()
{
Psr7\stream_for(new \stdClass());
}
public function testReturnsCustomMetadata()
{
$s = Psr7\stream_for('foo', ['metadata' => ['hwm' => 3]]);
$this->assertEquals(3, $s->getMetadata('hwm'));
$this->assertArrayHasKey('hwm', $s->getMetadata());
}
public function testCanSetSize()
{
$s = Psr7\stream_for('', ['size' => 10]);
$this->assertEquals(10, $s->getSize());
}
public function testCanCreateIteratorBasedStream()
{
$a = new \ArrayIterator(['foo', 'bar', '123']);
$p = Psr7\stream_for($a);
$this->assertInstanceOf('GuzzleHttp\Psr7\PumpStream', $p);
$this->assertEquals('foo', $p->read(3));
$this->assertFalse($p->eof());
$this->assertEquals('b', $p->read(1));
$this->assertEquals('a', $p->read(1));
$this->assertEquals('r12', $p->read(3));
$this->assertFalse($p->eof());
$this->assertEquals('3', $p->getContents());
$this->assertTrue($p->eof());
$this->assertEquals(9, $p->tell());
}
public function testConvertsRequestsToStrings()
{
$request = new Psr7\Request('PUT', 'http://foo.com/hi?123', [
'Baz' => 'bar',
'Qux' => ' ipsum'
], 'hello', '1.0');
$this->assertEquals(
"PUT /hi?123 HTTP/1.0\r\nHost: foo.com\r\nBaz: bar\r\nQux: ipsum\r\n\r\nhello",
Psr7\str($request)
);
}
public function testConvertsResponsesToStrings()
{
$response = new Psr7\Response(200, [
'Baz' => 'bar',
'Qux' => ' ipsum'
], 'hello', '1.0', 'FOO');
$this->assertEquals(
"HTTP/1.0 200 FOO\r\nBaz: bar\r\nQux: ipsum\r\n\r\nhello",
Psr7\str($response)
);
}
public function parseParamsProvider()
{
$res1 = array(
array(
'<http:/.../front.jpeg>',
'rel' => 'front',
'type' => 'image/jpeg',
),
array(
'<http://.../back.jpeg>',
'rel' => 'back',
'type' => 'image/jpeg',
),
);
return array(
array(
'<http:/.../front.jpeg>; rel="front"; type="image/jpeg", <http://.../back.jpeg>; rel=back; type="image/jpeg"',
$res1
),
array(
'<http:/.../front.jpeg>; rel="front"; type="image/jpeg",<http://.../back.jpeg>; rel=back; type="image/jpeg"',
$res1
),
array(
'foo="baz"; bar=123, boo, test="123", foobar="foo;bar"',
array(
array('foo' => 'baz', 'bar' => '123'),
array('boo'),
array('test' => '123'),
array('foobar' => 'foo;bar')
)
),
array(
'<http://.../side.jpeg?test=1>; rel="side"; type="image/jpeg",<http://.../side.jpeg?test=2>; rel=side; type="image/jpeg"',
array(
array('<http://.../side.jpeg?test=1>', 'rel' => 'side', 'type' => 'image/jpeg'),
array('<http://.../side.jpeg?test=2>', 'rel' => 'side', 'type' => 'image/jpeg')
)
),
array(
'',
array()
)
);
}
/**
* @dataProvider parseParamsProvider
*/
public function testParseParams($header, $result)
{
$this->assertEquals($result, Psr7\parse_header($header));
}
public function testParsesArrayHeaders()
{
$header = ['a, b', 'c', 'd, e'];
$this->assertEquals(['a', 'b', 'c', 'd', 'e'], Psr7\normalize_header($header));
}
public function testRewindsBody()
{
$body = Psr7\stream_for('abc');
$res = new Psr7\Response(200, [], $body);
Psr7\rewind_body($res);
$this->assertEquals(0, $body->tell());
$body->rewind(1);
Psr7\rewind_body($res);
$this->assertEquals(0, $body->tell());
}
/**
* @expectedException \RuntimeException
*/
public function testThrowsWhenBodyCannotBeRewound()
{
$body = Psr7\stream_for('abc');
$body->read(1);
$body = FnStream::decorate($body, [
'rewind' => function () { throw new \RuntimeException('a'); }
]);
$res = new Psr7\Response(200, [], $body);
Psr7\rewind_body($res);
}
public function testCanModifyRequestWithUri()
{
$r1 = new Psr7\Request('GET', 'http://foo.com');
$r2 = Psr7\modify_request($r1, [
'uri' => new Psr7\Uri('http://www.foo.com')
]);
$this->assertEquals('http://www.foo.com', (string) $r2->getUri());
$this->assertEquals('www.foo.com', (string) $r2->getHeaderLine('host'));
}
public function testCanModifyRequestWithCaseInsensitiveHeader()
{
$r1 = new Psr7\Request('GET', 'http://foo.com', ['User-Agent' => 'foo']);
$r2 = Psr7\modify_request($r1, ['set_headers' => ['User-agent' => 'bar']]);
$this->assertEquals('bar', $r2->getHeaderLine('User-Agent'));
$this->assertEquals('bar', $r2->getHeaderLine('User-agent'));
}
public function testReturnsAsIsWhenNoChanges()
{
$request = new Psr7\Request('GET', 'http://foo.com');
$this->assertSame($request, Psr7\modify_request($request, []));
}
public function testReturnsUriAsIsWhenNoChanges()
{
$r1 = new Psr7\Request('GET', 'http://foo.com');
$r2 = Psr7\modify_request($r1, ['set_headers' => ['foo' => 'bar']]);
$this->assertNotSame($r1, $r2);
$this->assertEquals('bar', $r2->getHeaderLine('foo'));
}
public function testRemovesHeadersFromMessage()
{
$r1 = new Psr7\Request('GET', 'http://foo.com', ['foo' => 'bar']);
$r2 = Psr7\modify_request($r1, ['remove_headers' => ['foo']]);
$this->assertNotSame($r1, $r2);
$this->assertFalse($r2->hasHeader('foo'));
}
public function testAddsQueryToUri()
{
$r1 = new Psr7\Request('GET', 'http://foo.com');
$r2 = Psr7\modify_request($r1, ['query' => 'foo=bar']);
$this->assertNotSame($r1, $r2);
$this->assertEquals('foo=bar', $r2->getUri()->getQuery());
}
}

View file

@ -1,16 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\InflateStream;
class InflateStreamtest extends \PHPUnit_Framework_TestCase
{
public function testInflatesStreams()
{
$content = gzencode('test');
$a = Psr7\stream_for($content);
$b = new InflateStream($a);
$this->assertEquals('test', (string) $b);
}
}

View file

@ -1,64 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\LazyOpenStream;
class LazyOpenStreamTest extends \PHPUnit_Framework_TestCase
{
private $fname;
public function setup()
{
$this->fname = tempnam('/tmp', 'tfile');
if (file_exists($this->fname)) {
unlink($this->fname);
}
}
public function tearDown()
{
if (file_exists($this->fname)) {
unlink($this->fname);
}
}
public function testOpensLazily()
{
$l = new LazyOpenStream($this->fname, 'w+');
$l->write('foo');
$this->assertInternalType('array', $l->getMetadata());
$this->assertFileExists($this->fname);
$this->assertEquals('foo', file_get_contents($this->fname));
$this->assertEquals('foo', (string) $l);
}
public function testProxiesToFile()
{
file_put_contents($this->fname, 'foo');
$l = new LazyOpenStream($this->fname, 'r');
$this->assertEquals('foo', $l->read(4));
$this->assertTrue($l->eof());
$this->assertEquals(3, $l->tell());
$this->assertTrue($l->isReadable());
$this->assertTrue($l->isSeekable());
$this->assertFalse($l->isWritable());
$l->seek(1);
$this->assertEquals('oo', $l->getContents());
$this->assertEquals('foo', (string) $l);
$this->assertEquals(3, $l->getSize());
$this->assertInternalType('array', $l->getMetadata());
$l->close();
}
public function testDetachesUnderlyingStream()
{
file_put_contents($this->fname, 'foo');
$l = new LazyOpenStream($this->fname, 'r');
$r = $l->detach();
$this->assertInternalType('resource', $r);
fseek($r, 0);
$this->assertEquals('foo', stream_get_contents($r));
fclose($r);
}
}

View file

@ -1,166 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\FnStream;
use GuzzleHttp\Psr7\Stream;
use GuzzleHttp\Psr7\LimitStream;
use GuzzleHttp\Psr7\NoSeekStream;
/**
* @covers GuzzleHttp\Psr7\LimitStream
*/
class LimitStreamTest extends \PHPUnit_Framework_TestCase
{
/** @var LimitStream */
protected $body;
/** @var Stream */
protected $decorated;
public function setUp()
{
$this->decorated = Psr7\stream_for(fopen(__FILE__, 'r'));
$this->body = new LimitStream($this->decorated, 10, 3);
}
public function testReturnsSubset()
{
$body = new LimitStream(Psr7\stream_for('foo'), -1, 1);
$this->assertEquals('oo', (string) $body);
$this->assertTrue($body->eof());
$body->seek(0);
$this->assertFalse($body->eof());
$this->assertEquals('oo', $body->read(100));
$this->assertSame('', $body->read(1));
$this->assertTrue($body->eof());
}
public function testReturnsSubsetWhenCastToString()
{
$body = Psr7\stream_for('foo_baz_bar');
$limited = new LimitStream($body, 3, 4);
$this->assertEquals('baz', (string) $limited);
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Unable to seek to stream position 10 with whence 0
*/
public function testEnsuresPositionCanBeekSeekedTo()
{
new LimitStream(Psr7\stream_for(''), 0, 10);
}
public function testReturnsSubsetOfEmptyBodyWhenCastToString()
{
$body = Psr7\stream_for('01234567891234');
$limited = new LimitStream($body, 0, 10);
$this->assertEquals('', (string) $limited);
}
public function testReturnsSpecificSubsetOBodyWhenCastToString()
{
$body = Psr7\stream_for('0123456789abcdef');
$limited = new LimitStream($body, 3, 10);
$this->assertEquals('abc', (string) $limited);
}
public function testSeeksWhenConstructed()
{
$this->assertEquals(0, $this->body->tell());
$this->assertEquals(3, $this->decorated->tell());
}
public function testAllowsBoundedSeek()
{
$this->body->seek(100);
$this->assertEquals(10, $this->body->tell());
$this->assertEquals(13, $this->decorated->tell());
$this->body->seek(0);
$this->assertEquals(0, $this->body->tell());
$this->assertEquals(3, $this->decorated->tell());
try {
$this->body->seek(-10);
$this->fail();
} catch (\RuntimeException $e) {}
$this->assertEquals(0, $this->body->tell());
$this->assertEquals(3, $this->decorated->tell());
$this->body->seek(5);
$this->assertEquals(5, $this->body->tell());
$this->assertEquals(8, $this->decorated->tell());
// Fail
try {
$this->body->seek(1000, SEEK_END);
$this->fail();
} catch (\RuntimeException $e) {}
}
public function testReadsOnlySubsetOfData()
{
$data = $this->body->read(100);
$this->assertEquals(10, strlen($data));
$this->assertSame('', $this->body->read(1000));
$this->body->setOffset(10);
$newData = $this->body->read(100);
$this->assertEquals(10, strlen($newData));
$this->assertNotSame($data, $newData);
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Could not seek to stream offset 2
*/
public function testThrowsWhenCurrentGreaterThanOffsetSeek()
{
$a = Psr7\stream_for('foo_bar');
$b = new NoSeekStream($a);
$c = new LimitStream($b);
$a->getContents();
$c->setOffset(2);
}
public function testCanGetContentsWithoutSeeking()
{
$a = Psr7\stream_for('foo_bar');
$b = new NoSeekStream($a);
$c = new LimitStream($b);
$this->assertEquals('foo_bar', $c->getContents());
}
public function testClaimsConsumedWhenReadLimitIsReached()
{
$this->assertFalse($this->body->eof());
$this->body->read(1000);
$this->assertTrue($this->body->eof());
}
public function testContentLengthIsBounded()
{
$this->assertEquals(10, $this->body->getSize());
}
public function testGetContentsIsBasedOnSubset()
{
$body = new LimitStream(Psr7\stream_for('foobazbar'), 3, 3);
$this->assertEquals('baz', $body->getContents());
}
public function testReturnsNullIfSizeCannotBeDetermined()
{
$a = new FnStream([
'getSize' => function () { return null; },
'tell' => function () { return 0; },
]);
$b = new LimitStream($a);
$this->assertNull($b->getSize());
}
public function testLengthLessOffsetWhenNoLimitSize()
{
$a = Psr7\stream_for('foo_bar');
$b = new LimitStream($a, -1, 4);
$this->assertEquals(3, $b->getSize());
}
}

View file

@ -1,214 +0,0 @@
<?php
namespace GuzzleHttp\Tests;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\MultipartStream;
class MultipartStreamTest extends \PHPUnit_Framework_TestCase
{
public function testCreatesDefaultBoundary()
{
$b = new MultipartStream();
$this->assertNotEmpty($b->getBoundary());
}
public function testCanProvideBoundary()
{
$b = new MultipartStream([], 'foo');
$this->assertEquals('foo', $b->getBoundary());
}
public function testIsNotWritable()
{
$b = new MultipartStream();
$this->assertFalse($b->isWritable());
}
public function testCanCreateEmptyStream()
{
$b = new MultipartStream();
$boundary = $b->getBoundary();
$this->assertSame("--{$boundary}--\r\n", $b->getContents());
$this->assertSame(strlen($boundary) + 6, $b->getSize());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testValidatesFilesArrayElement()
{
new MultipartStream([['foo' => 'bar']]);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testEnsuresFileHasName()
{
new MultipartStream([['contents' => 'bar']]);
}
public function testSerializesFields()
{
$b = new MultipartStream([
[
'name' => 'foo',
'contents' => 'bar'
],
[
'name' => 'baz',
'contents' => 'bam'
]
], 'boundary');
$this->assertEquals(
"--boundary\r\nContent-Disposition: form-data; name=\"foo\"\r\nContent-Length: 3\r\n\r\n"
. "bar\r\n--boundary\r\nContent-Disposition: form-data; name=\"baz\"\r\nContent-Length: 3"
. "\r\n\r\nbam\r\n--boundary--\r\n", (string) $b);
}
public function testSerializesFiles()
{
$f1 = Psr7\FnStream::decorate(Psr7\stream_for('foo'), [
'getMetadata' => function () {
return '/foo/bar.txt';
}
]);
$f2 = Psr7\FnStream::decorate(Psr7\stream_for('baz'), [
'getMetadata' => function () {
return '/foo/baz.jpg';
}
]);
$f3 = Psr7\FnStream::decorate(Psr7\stream_for('bar'), [
'getMetadata' => function () {
return '/foo/bar.gif';
}
]);
$b = new MultipartStream([
[
'name' => 'foo',
'contents' => $f1
],
[
'name' => 'qux',
'contents' => $f2
],
[
'name' => 'qux',
'contents' => $f3
],
], 'boundary');
$expected = <<<EOT
--boundary
Content-Disposition: form-data; name="foo"; filename="bar.txt"
Content-Length: 3
Content-Type: text/plain
foo
--boundary
Content-Disposition: form-data; name="qux"; filename="baz.jpg"
Content-Length: 3
Content-Type: image/jpeg
baz
--boundary
Content-Disposition: form-data; name="qux"; filename="bar.gif"
Content-Length: 3
Content-Type: image/gif
bar
--boundary--
EOT;
$this->assertEquals($expected, str_replace("\r", '', $b));
}
public function testSerializesFilesWithCustomHeaders()
{
$f1 = Psr7\FnStream::decorate(Psr7\stream_for('foo'), [
'getMetadata' => function () {
return '/foo/bar.txt';
}
]);
$b = new MultipartStream([
[
'name' => 'foo',
'contents' => $f1,
'headers' => [
'x-foo' => 'bar',
'content-disposition' => 'custom'
]
]
], 'boundary');
$expected = <<<EOT
--boundary
x-foo: bar
content-disposition: custom
Content-Length: 3
Content-Type: text/plain
foo
--boundary--
EOT;
$this->assertEquals($expected, str_replace("\r", '', $b));
}
public function testSerializesFilesWithCustomHeadersAndMultipleValues()
{
$f1 = Psr7\FnStream::decorate(Psr7\stream_for('foo'), [
'getMetadata' => function () {
return '/foo/bar.txt';
}
]);
$f2 = Psr7\FnStream::decorate(Psr7\stream_for('baz'), [
'getMetadata' => function () {
return '/foo/baz.jpg';
}
]);
$b = new MultipartStream([
[
'name' => 'foo',
'contents' => $f1,
'headers' => [
'x-foo' => 'bar',
'content-disposition' => 'custom'
]
],
[
'name' => 'foo',
'contents' => $f2,
'headers' => ['cOntenT-Type' => 'custom'],
]
], 'boundary');
$expected = <<<EOT
--boundary
x-foo: bar
content-disposition: custom
Content-Length: 3
Content-Type: text/plain
foo
--boundary
cOntenT-Type: custom
Content-Disposition: form-data; name="foo"; filename="baz.jpg"
Content-Length: 3
baz
--boundary--
EOT;
$this->assertEquals($expected, str_replace("\r", '', $b));
}
}

View file

@ -1,40 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\NoSeekStream;
/**
* @covers GuzzleHttp\Psr7\NoSeekStream
* @covers GuzzleHttp\Psr7\StreamDecoratorTrait
*/
class NoSeekStreamTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Cannot seek a NoSeekStream
*/
public function testCannotSeek()
{
$s = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
->setMethods(['isSeekable', 'seek'])
->getMockForAbstractClass();
$s->expects($this->never())->method('seek');
$s->expects($this->never())->method('isSeekable');
$wrapped = new NoSeekStream($s);
$this->assertFalse($wrapped->isSeekable());
$wrapped->seek(2);
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Cannot write to a non-writable stream
*/
public function testHandlesClose()
{
$s = Psr7\stream_for('foo');
$wrapped = new NoSeekStream($s);
$wrapped->close();
$wrapped->write('foo');
}
}

View file

@ -1,72 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\LimitStream;
use GuzzleHttp\Psr7\PumpStream;
use GuzzleHttp\Psr7;
class PumpStreamTest extends \PHPUnit_Framework_TestCase
{
public function testHasMetadataAndSize()
{
$p = new PumpStream(function () {}, [
'metadata' => ['foo' => 'bar'],
'size' => 100
]);
$this->assertEquals('bar', $p->getMetadata('foo'));
$this->assertEquals(['foo' => 'bar'], $p->getMetadata());
$this->assertEquals(100, $p->getSize());
}
public function testCanReadFromCallable()
{
$p = Psr7\stream_for(function ($size) {
return 'a';
});
$this->assertEquals('a', $p->read(1));
$this->assertEquals(1, $p->tell());
$this->assertEquals('aaaaa', $p->read(5));
$this->assertEquals(6, $p->tell());
}
public function testStoresExcessDataInBuffer()
{
$called = [];
$p = Psr7\stream_for(function ($size) use (&$called) {
$called[] = $size;
return 'abcdef';
});
$this->assertEquals('a', $p->read(1));
$this->assertEquals('b', $p->read(1));
$this->assertEquals('cdef', $p->read(4));
$this->assertEquals('abcdefabc', $p->read(9));
$this->assertEquals([1, 9, 3], $called);
}
public function testInifiniteStreamWrappedInLimitStream()
{
$p = Psr7\stream_for(function () { return 'a'; });
$s = new LimitStream($p, 5);
$this->assertEquals('aaaaa', (string) $s);
}
public function testDescribesCapabilities()
{
$p = Psr7\stream_for(function () {});
$this->assertTrue($p->isReadable());
$this->assertFalse($p->isSeekable());
$this->assertFalse($p->isWritable());
$this->assertNull($p->getSize());
$this->assertEquals('', $p->getContents());
$this->assertEquals('', (string) $p);
$p->close();
$this->assertEquals('', $p->read(10));
$this->assertTrue($p->eof());
try {
$this->assertFalse($p->write('aa'));
$this->fail();
} catch (\RuntimeException $e) {}
}
}

View file

@ -1,157 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Uri;
/**
* @covers GuzzleHttp\Psr7\Request
*/
class RequestTest extends \PHPUnit_Framework_TestCase
{
public function testRequestUriMayBeString()
{
$r = new Request('GET', '/');
$this->assertEquals('/', (string) $r->getUri());
}
public function testRequestUriMayBeUri()
{
$uri = new Uri('/');
$r = new Request('GET', $uri);
$this->assertSame($uri, $r->getUri());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testValidateRequestUri()
{
new Request('GET', true);
}
public function testCanConstructWithBody()
{
$r = new Request('GET', '/', [], 'baz');
$this->assertEquals('baz', (string) $r->getBody());
}
public function testCapitalizesMethod()
{
$r = new Request('get', '/');
$this->assertEquals('GET', $r->getMethod());
}
public function testCapitalizesWithMethod()
{
$r = new Request('GET', '/');
$this->assertEquals('PUT', $r->withMethod('put')->getMethod());
}
public function testWithUri()
{
$r1 = new Request('GET', '/');
$u1 = $r1->getUri();
$u2 = new Uri('http://www.example.com');
$r2 = $r1->withUri($u2);
$this->assertNotSame($r1, $r2);
$this->assertSame($u2, $r2->getUri());
$this->assertSame($u1, $r1->getUri());
}
public function testSameInstanceWhenSameUri()
{
$r1 = new Request('GET', 'http://foo.com');
$r2 = $r1->withUri($r1->getUri());
$this->assertSame($r1, $r2);
}
public function testWithRequestTarget()
{
$r1 = new Request('GET', '/');
$r2 = $r1->withRequestTarget('*');
$this->assertEquals('*', $r2->getRequestTarget());
$this->assertEquals('/', $r1->getRequestTarget());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testRequestTargetDoesNotAllowSpaces()
{
$r1 = new Request('GET', '/');
$r1->withRequestTarget('/foo bar');
}
public function testRequestTargetDefaultsToSlash()
{
$r1 = new Request('GET', '');
$this->assertEquals('/', $r1->getRequestTarget());
$r2 = new Request('GET', '*');
$this->assertEquals('*', $r2->getRequestTarget());
$r3 = new Request('GET', 'http://foo.com/bar baz/');
$this->assertEquals('/bar%20baz/', $r3->getRequestTarget());
}
public function testBuildsRequestTarget()
{
$r1 = new Request('GET', 'http://foo.com/baz?bar=bam');
$this->assertEquals('/baz?bar=bam', $r1->getRequestTarget());
}
public function testHostIsAddedFirst()
{
$r = new Request('GET', 'http://foo.com/baz?bar=bam', ['Foo' => 'Bar']);
$this->assertEquals([
'Host' => ['foo.com'],
'Foo' => ['Bar']
], $r->getHeaders());
}
public function testCanGetHeaderAsCsv()
{
$r = new Request('GET', 'http://foo.com/baz?bar=bam', [
'Foo' => ['a', 'b', 'c']
]);
$this->assertEquals('a, b, c', $r->getHeaderLine('Foo'));
$this->assertEquals('', $r->getHeaderLine('Bar'));
}
public function testHostIsNotOverwrittenWhenPreservingHost()
{
$r = new Request('GET', 'http://foo.com/baz?bar=bam', ['Host' => 'a.com']);
$this->assertEquals(['Host' => ['a.com']], $r->getHeaders());
$r2 = $r->withUri(new Uri('http://www.foo.com/bar'), true);
$this->assertEquals('a.com', $r2->getHeaderLine('Host'));
}
public function testOverridesHostWithUri()
{
$r = new Request('GET', 'http://foo.com/baz?bar=bam');
$this->assertEquals(['Host' => ['foo.com']], $r->getHeaders());
$r2 = $r->withUri(new Uri('http://www.baz.com/bar'));
$this->assertEquals('www.baz.com', $r2->getHeaderLine('Host'));
}
public function testAggregatesHeaders()
{
$r = new Request('GET', 'http://foo.com', [
'ZOO' => 'zoobar',
'zoo' => ['foobar', 'zoobar']
]);
$this->assertEquals('zoobar, foobar, zoobar', $r->getHeaderLine('zoo'));
}
public function testAddsPortToHeader()
{
$r = new Request('GET', 'http://foo.com:8124/bar');
$this->assertEquals('foo.com:8124', $r->getHeaderLine('host'));
}
public function testAddsPortToHeaderAndReplacePreviousPort()
{
$r = new Request('GET', 'http://foo.com:8124/bar');
$r = $r->withUri(new Uri('http://foo.com:8125/bar'));
$this->assertEquals('foo.com:8125', $r->getHeaderLine('host'));
}
}

View file

@ -1,146 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7;
/**
* @covers GuzzleHttp\Psr7\MessageTrait
* @covers GuzzleHttp\Psr7\Response
*/
class ResponseTest extends \PHPUnit_Framework_TestCase
{
public function testAddsDefaultReason()
{
$r = new Response('200');
$this->assertSame(200, $r->getStatusCode());
$this->assertEquals('OK', $r->getReasonPhrase());
}
public function testCanGiveCustomReason()
{
$r = new Response(200, [], null, '1.1', 'bar');
$this->assertEquals('bar', $r->getReasonPhrase());
}
public function testCanGiveCustomProtocolVersion()
{
$r = new Response(200, [], null, '1000');
$this->assertEquals('1000', $r->getProtocolVersion());
}
public function testCanCreateNewResponseWithStatusAndNoReason()
{
$r = new Response(200);
$r2 = $r->withStatus(201);
$this->assertEquals(200, $r->getStatusCode());
$this->assertEquals('OK', $r->getReasonPhrase());
$this->assertEquals(201, $r2->getStatusCode());
$this->assertEquals('Created', $r2->getReasonPhrase());
}
public function testCanCreateNewResponseWithStatusAndReason()
{
$r = new Response(200);
$r2 = $r->withStatus(201, 'Foo');
$this->assertEquals(200, $r->getStatusCode());
$this->assertEquals('OK', $r->getReasonPhrase());
$this->assertEquals(201, $r2->getStatusCode());
$this->assertEquals('Foo', $r2->getReasonPhrase());
}
public function testCreatesResponseWithAddedHeaderArray()
{
$r = new Response();
$r2 = $r->withAddedHeader('foo', ['baz', 'bar']);
$this->assertFalse($r->hasHeader('foo'));
$this->assertEquals('baz, bar', $r2->getHeaderLine('foo'));
}
public function testReturnsIdentityWhenRemovingMissingHeader()
{
$r = new Response();
$this->assertSame($r, $r->withoutHeader('foo'));
}
public function testAlwaysReturnsBody()
{
$r = new Response();
$this->assertInstanceOf('Psr\Http\Message\StreamInterface', $r->getBody());
}
public function testCanSetHeaderAsArray()
{
$r = new Response(200, [
'foo' => ['baz ', ' bar ']
]);
$this->assertEquals('baz, bar', $r->getHeaderLine('foo'));
$this->assertEquals(['baz', 'bar'], $r->getHeader('foo'));
}
public function testSameInstanceWhenSameBody()
{
$r = new Response(200, [], 'foo');
$b = $r->getBody();
$this->assertSame($r, $r->withBody($b));
}
public function testNewInstanceWhenNewBody()
{
$r = new Response(200, [], 'foo');
$b2 = Psr7\stream_for('abc');
$this->assertNotSame($r, $r->withBody($b2));
}
public function testSameInstanceWhenSameProtocol()
{
$r = new Response(200);
$this->assertSame($r, $r->withProtocolVersion('1.1'));
}
public function testNewInstanceWhenNewProtocol()
{
$r = new Response(200);
$this->assertNotSame($r, $r->withProtocolVersion('1.0'));
}
public function testNewInstanceWhenRemovingHeader()
{
$r = new Response(200, ['Foo' => 'Bar']);
$r2 = $r->withoutHeader('Foo');
$this->assertNotSame($r, $r2);
$this->assertFalse($r2->hasHeader('foo'));
}
public function testNewInstanceWhenAddingHeader()
{
$r = new Response(200, ['Foo' => 'Bar']);
$r2 = $r->withAddedHeader('Foo', 'Baz');
$this->assertNotSame($r, $r2);
$this->assertEquals('Bar, Baz', $r2->getHeaderLine('foo'));
}
public function testNewInstanceWhenAddingHeaderThatWasNotThereBefore()
{
$r = new Response(200, ['Foo' => 'Bar']);
$r2 = $r->withAddedHeader('Baz', 'Bam');
$this->assertNotSame($r, $r2);
$this->assertEquals('Bam', $r2->getHeaderLine('Baz'));
$this->assertEquals('Bar', $r2->getHeaderLine('Foo'));
}
public function testRemovesPreviouslyAddedHeaderOfDifferentCase()
{
$r = new Response(200, ['Foo' => 'Bar']);
$r2 = $r->withHeader('foo', 'Bam');
$this->assertNotSame($r, $r2);
$this->assertEquals('Bam', $r2->getHeaderLine('Foo'));
}
public function testBodyConsistent()
{
$r = new Response(200, [], '0');
$this->assertEquals('0', (string)$r->getBody());
}
}

View file

@ -1,137 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use Psr\Http\Message\StreamInterface;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\StreamDecoratorTrait;
class Str implements StreamInterface
{
use StreamDecoratorTrait;
}
/**
* @covers GuzzleHttp\Psr7\StreamDecoratorTrait
*/
class StreamDecoratorTraitTest extends \PHPUnit_Framework_TestCase
{
private $a;
private $b;
private $c;
public function setUp()
{
$this->c = fopen('php://temp', 'r+');
fwrite($this->c, 'foo');
fseek($this->c, 0);
$this->a = Psr7\stream_for($this->c);
$this->b = new Str($this->a);
}
public function testCatchesExceptionsWhenCastingToString()
{
$s = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
->setMethods(['read'])
->getMockForAbstractClass();
$s->expects($this->once())
->method('read')
->will($this->throwException(new \Exception('foo')));
$msg = '';
set_error_handler(function ($errNo, $str) use (&$msg) { $msg = $str; });
echo new Str($s);
restore_error_handler();
$this->assertContains('foo', $msg);
}
public function testToString()
{
$this->assertEquals('foo', (string) $this->b);
}
public function testHasSize()
{
$this->assertEquals(3, $this->b->getSize());
}
public function testReads()
{
$this->assertEquals('foo', $this->b->read(10));
}
public function testCheckMethods()
{
$this->assertEquals($this->a->isReadable(), $this->b->isReadable());
$this->assertEquals($this->a->isWritable(), $this->b->isWritable());
$this->assertEquals($this->a->isSeekable(), $this->b->isSeekable());
}
public function testSeeksAndTells()
{
$this->b->seek(1);
$this->assertEquals(1, $this->a->tell());
$this->assertEquals(1, $this->b->tell());
$this->b->seek(0);
$this->assertEquals(0, $this->a->tell());
$this->assertEquals(0, $this->b->tell());
$this->b->seek(0, SEEK_END);
$this->assertEquals(3, $this->a->tell());
$this->assertEquals(3, $this->b->tell());
}
public function testGetsContents()
{
$this->assertEquals('foo', $this->b->getContents());
$this->assertEquals('', $this->b->getContents());
$this->b->seek(1);
$this->assertEquals('oo', $this->b->getContents(1));
}
public function testCloses()
{
$this->b->close();
$this->assertFalse(is_resource($this->c));
}
public function testDetaches()
{
$this->b->detach();
$this->assertFalse($this->b->isReadable());
}
public function testWrapsMetadata()
{
$this->assertSame($this->b->getMetadata(), $this->a->getMetadata());
$this->assertSame($this->b->getMetadata('uri'), $this->a->getMetadata('uri'));
}
public function testWrapsWrites()
{
$this->b->seek(0, SEEK_END);
$this->b->write('foo');
$this->assertEquals('foofoo', (string) $this->a);
}
/**
* @expectedException \UnexpectedValueException
*/
public function testThrowsWithInvalidGetter()
{
$this->b->foo;
}
/**
* @expectedException \BadMethodCallException
*/
public function testThrowsWhenGetterNotImplemented()
{
$s = new BadStream();
$s->stream;
}
}
class BadStream
{
use StreamDecoratorTrait;
public function __construct() {}
}

View file

@ -1,161 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\NoSeekStream;
use GuzzleHttp\Psr7\Stream;
/**
* @covers GuzzleHttp\Psr7\Stream
*/
class StreamTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \InvalidArgumentException
*/
public function testConstructorThrowsExceptionOnInvalidArgument()
{
new Stream(true);
}
public function testConstructorInitializesProperties()
{
$handle = fopen('php://temp', 'r+');
fwrite($handle, 'data');
$stream = new Stream($handle);
$this->assertTrue($stream->isReadable());
$this->assertTrue($stream->isWritable());
$this->assertTrue($stream->isSeekable());
$this->assertEquals('php://temp', $stream->getMetadata('uri'));
$this->assertInternalType('array', $stream->getMetadata());
$this->assertEquals(4, $stream->getSize());
$this->assertFalse($stream->eof());
$stream->close();
}
public function testStreamClosesHandleOnDestruct()
{
$handle = fopen('php://temp', 'r');
$stream = new Stream($handle);
unset($stream);
$this->assertFalse(is_resource($handle));
}
public function testConvertsToString()
{
$handle = fopen('php://temp', 'w+');
fwrite($handle, 'data');
$stream = new Stream($handle);
$this->assertEquals('data', (string) $stream);
$this->assertEquals('data', (string) $stream);
$stream->close();
}
public function testGetsContents()
{
$handle = fopen('php://temp', 'w+');
fwrite($handle, 'data');
$stream = new Stream($handle);
$this->assertEquals('', $stream->getContents());
$stream->seek(0);
$this->assertEquals('data', $stream->getContents());
$this->assertEquals('', $stream->getContents());
}
public function testChecksEof()
{
$handle = fopen('php://temp', 'w+');
fwrite($handle, 'data');
$stream = new Stream($handle);
$this->assertFalse($stream->eof());
$stream->read(4);
$this->assertTrue($stream->eof());
$stream->close();
}
public function testGetSize()
{
$size = filesize(__FILE__);
$handle = fopen(__FILE__, 'r');
$stream = new Stream($handle);
$this->assertEquals($size, $stream->getSize());
// Load from cache
$this->assertEquals($size, $stream->getSize());
$stream->close();
}
public function testEnsuresSizeIsConsistent()
{
$h = fopen('php://temp', 'w+');
$this->assertEquals(3, fwrite($h, 'foo'));
$stream = new Stream($h);
$this->assertEquals(3, $stream->getSize());
$this->assertEquals(4, $stream->write('test'));
$this->assertEquals(7, $stream->getSize());
$this->assertEquals(7, $stream->getSize());
$stream->close();
}
public function testProvidesStreamPosition()
{
$handle = fopen('php://temp', 'w+');
$stream = new Stream($handle);
$this->assertEquals(0, $stream->tell());
$stream->write('foo');
$this->assertEquals(3, $stream->tell());
$stream->seek(1);
$this->assertEquals(1, $stream->tell());
$this->assertSame(ftell($handle), $stream->tell());
$stream->close();
}
public function testCanDetachStream()
{
$r = fopen('php://temp', 'w+');
$stream = new Stream($r);
$stream->write('foo');
$this->assertTrue($stream->isReadable());
$this->assertSame($r, $stream->detach());
$stream->detach();
$this->assertFalse($stream->isReadable());
$this->assertFalse($stream->isWritable());
$this->assertFalse($stream->isSeekable());
$throws = function (callable $fn) use ($stream) {
try {
$fn($stream);
$this->fail();
} catch (\Exception $e) {}
};
$throws(function ($stream) { $stream->read(10); });
$throws(function ($stream) { $stream->write('bar'); });
$throws(function ($stream) { $stream->seek(10); });
$throws(function ($stream) { $stream->tell(); });
$throws(function ($stream) { $stream->eof(); });
$throws(function ($stream) { $stream->getSize(); });
$throws(function ($stream) { $stream->getContents(); });
$this->assertSame('', (string) $stream);
$stream->close();
}
public function testCloseClearProperties()
{
$handle = fopen('php://temp', 'r+');
$stream = new Stream($handle);
$stream->close();
$this->assertFalse($stream->isSeekable());
$this->assertFalse($stream->isReadable());
$this->assertFalse($stream->isWritable());
$this->assertNull($stream->getSize());
$this->assertEmpty($stream->getMetadata());
}
public function testDoesNotThrowInToString()
{
$s = \GuzzleHttp\Psr7\stream_for('foo');
$s = new NoSeekStream($s);
$this->assertEquals('foo', (string) $s);
}
}

View file

@ -1,100 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\StreamWrapper;
use GuzzleHttp\Psr7;
/**
* @covers GuzzleHttp\Psr7\StreamWrapper
*/
class StreamWrapperTest extends \PHPUnit_Framework_TestCase
{
public function testResource()
{
$stream = Psr7\stream_for('foo');
$handle = StreamWrapper::getResource($stream);
$this->assertSame('foo', fread($handle, 3));
$this->assertSame(3, ftell($handle));
$this->assertSame(3, fwrite($handle, 'bar'));
$this->assertSame(0, fseek($handle, 0));
$this->assertSame('foobar', fread($handle, 6));
$this->assertSame('', fread($handle, 1));
$this->assertTrue(feof($handle));
// This fails on HHVM for some reason
if (!defined('HHVM_VERSION')) {
$this->assertEquals([
'dev' => 0,
'ino' => 0,
'mode' => 33206,
'nlink' => 0,
'uid' => 0,
'gid' => 0,
'rdev' => 0,
'size' => 6,
'atime' => 0,
'mtime' => 0,
'ctime' => 0,
'blksize' => 0,
'blocks' => 0,
0 => 0,
1 => 0,
2 => 33206,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
7 => 6,
8 => 0,
9 => 0,
10 => 0,
11 => 0,
12 => 0,
], fstat($handle));
}
$this->assertTrue(fclose($handle));
$this->assertSame('foobar', (string) $stream);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testValidatesStream()
{
$stream = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
->setMethods(['isReadable', 'isWritable'])
->getMockForAbstractClass();
$stream->expects($this->once())
->method('isReadable')
->will($this->returnValue(false));
$stream->expects($this->once())
->method('isWritable')
->will($this->returnValue(false));
StreamWrapper::getResource($stream);
}
/**
* @expectedException \PHPUnit_Framework_Error_Warning
*/
public function testReturnsFalseWhenStreamDoesNotExist()
{
fopen('guzzle://foo', 'r');
}
public function testCanOpenReadonlyStream()
{
$stream = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
->setMethods(['isReadable', 'isWritable'])
->getMockForAbstractClass();
$stream->expects($this->once())
->method('isReadable')
->will($this->returnValue(false));
$stream->expects($this->once())
->method('isWritable')
->will($this->returnValue(true));
$r = StreamWrapper::getResource($stream);
$this->assertInternalType('resource', $r);
fclose($r);
}
}

View file

@ -1,247 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
use GuzzleHttp\Psr7\Uri;
/**
* @covers GuzzleHttp\Psr7\Uri
*/
class UriTest extends \PHPUnit_Framework_TestCase
{
const RFC3986_BASE = "http://a/b/c/d;p?q";
public function testParsesProvidedUrl()
{
$uri = new Uri('https://michael:test@test.com:443/path/123?q=abc#test');
// Standard port 443 for https gets ignored.
$this->assertEquals(
'https://michael:test@test.com/path/123?q=abc#test',
(string) $uri
);
$this->assertEquals('test', $uri->getFragment());
$this->assertEquals('test.com', $uri->getHost());
$this->assertEquals('/path/123', $uri->getPath());
$this->assertEquals(null, $uri->getPort());
$this->assertEquals('q=abc', $uri->getQuery());
$this->assertEquals('https', $uri->getScheme());
$this->assertEquals('michael:test', $uri->getUserInfo());
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Unable to parse URI
*/
public function testValidatesUriCanBeParsed()
{
new Uri('///');
}
public function testCanTransformAndRetrievePartsIndividually()
{
$uri = (new Uri(''))
->withFragment('#test')
->withHost('example.com')
->withPath('path/123')
->withPort(8080)
->withQuery('?q=abc')
->withScheme('http')
->withUserInfo('user', 'pass');
// Test getters.
$this->assertEquals('user:pass@example.com:8080', $uri->getAuthority());
$this->assertEquals('test', $uri->getFragment());
$this->assertEquals('example.com', $uri->getHost());
$this->assertEquals('path/123', $uri->getPath());
$this->assertEquals(8080, $uri->getPort());
$this->assertEquals('q=abc', $uri->getQuery());
$this->assertEquals('http', $uri->getScheme());
$this->assertEquals('user:pass', $uri->getUserInfo());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testPortMustBeValid()
{
(new Uri(''))->withPort(100000);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testPathMustBeValid()
{
(new Uri(''))->withPath([]);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testQueryMustBeValid()
{
(new Uri(''))->withQuery(new \stdClass);
}
public function testAllowsFalseyUrlParts()
{
$url = new Uri('http://a:1/0?0#0');
$this->assertSame('a', $url->getHost());
$this->assertEquals(1, $url->getPort());
$this->assertSame('/0', $url->getPath());
$this->assertEquals('0', (string) $url->getQuery());
$this->assertSame('0', $url->getFragment());
$this->assertEquals('http://a:1/0?0#0', (string) $url);
$url = new Uri('');
$this->assertSame('', (string) $url);
$url = new Uri('0');
$this->assertSame('0', (string) $url);
$url = new Uri('/');
$this->assertSame('/', (string) $url);
}
/**
* @dataProvider getResolveTestCases
*/
public function testResolvesUris($base, $rel, $expected)
{
$uri = new Uri($base);
$actual = Uri::resolve($uri, $rel);
$this->assertEquals($expected, (string) $actual);
}
public function getResolveTestCases()
{
return [
//[self::RFC3986_BASE, 'g:h', 'g:h'],
[self::RFC3986_BASE, 'g', 'http://a/b/c/g'],
[self::RFC3986_BASE, './g', 'http://a/b/c/g'],
[self::RFC3986_BASE, 'g/', 'http://a/b/c/g/'],
[self::RFC3986_BASE, '/g', 'http://a/g'],
[self::RFC3986_BASE, '//g', 'http://g'],
[self::RFC3986_BASE, '?y', 'http://a/b/c/d;p?y'],
[self::RFC3986_BASE, 'g?y', 'http://a/b/c/g?y'],
[self::RFC3986_BASE, '#s', 'http://a/b/c/d;p?q#s'],
[self::RFC3986_BASE, 'g#s', 'http://a/b/c/g#s'],
[self::RFC3986_BASE, 'g?y#s', 'http://a/b/c/g?y#s'],
[self::RFC3986_BASE, ';x', 'http://a/b/c/;x'],
[self::RFC3986_BASE, 'g;x', 'http://a/b/c/g;x'],
[self::RFC3986_BASE, 'g;x?y#s', 'http://a/b/c/g;x?y#s'],
[self::RFC3986_BASE, '', self::RFC3986_BASE],
[self::RFC3986_BASE, '.', 'http://a/b/c/'],
[self::RFC3986_BASE, './', 'http://a/b/c/'],
[self::RFC3986_BASE, '..', 'http://a/b/'],
[self::RFC3986_BASE, '../', 'http://a/b/'],
[self::RFC3986_BASE, '../g', 'http://a/b/g'],
[self::RFC3986_BASE, '../..', 'http://a/'],
[self::RFC3986_BASE, '../../', 'http://a/'],
[self::RFC3986_BASE, '../../g', 'http://a/g'],
[self::RFC3986_BASE, '../../../g', 'http://a/g'],
[self::RFC3986_BASE, '../../../../g', 'http://a/g'],
[self::RFC3986_BASE, '/./g', 'http://a/g'],
[self::RFC3986_BASE, '/../g', 'http://a/g'],
[self::RFC3986_BASE, 'g.', 'http://a/b/c/g.'],
[self::RFC3986_BASE, '.g', 'http://a/b/c/.g'],
[self::RFC3986_BASE, 'g..', 'http://a/b/c/g..'],
[self::RFC3986_BASE, '..g', 'http://a/b/c/..g'],
[self::RFC3986_BASE, './../g', 'http://a/b/g'],
[self::RFC3986_BASE, 'foo////g', 'http://a/b/c/foo////g'],
[self::RFC3986_BASE, './g/.', 'http://a/b/c/g/'],
[self::RFC3986_BASE, 'g/./h', 'http://a/b/c/g/h'],
[self::RFC3986_BASE, 'g/../h', 'http://a/b/c/h'],
[self::RFC3986_BASE, 'g;x=1/./y', 'http://a/b/c/g;x=1/y'],
[self::RFC3986_BASE, 'g;x=1/../y', 'http://a/b/c/y'],
['http://u@a/b/c/d;p?q', '.', 'http://u@a/b/c/'],
['http://u:p@a/b/c/d;p?q', '.', 'http://u:p@a/b/c/'],
//[self::RFC3986_BASE, 'http:g', 'http:g'],
];
}
public function testAddAndRemoveQueryValues()
{
$uri = new Uri('http://foo.com/bar');
$uri = Uri::withQueryValue($uri, 'a', 'b');
$uri = Uri::withQueryValue($uri, 'c', 'd');
$uri = Uri::withQueryValue($uri, 'e', null);
$this->assertEquals('a=b&c=d&e', $uri->getQuery());
$uri = Uri::withoutQueryValue($uri, 'c');
$uri = Uri::withoutQueryValue($uri, 'e');
$this->assertEquals('a=b', $uri->getQuery());
$uri = Uri::withoutQueryValue($uri, 'a');
$uri = Uri::withoutQueryValue($uri, 'a');
$this->assertEquals('', $uri->getQuery());
}
public function testGetAuthorityReturnsCorrectPort()
{
// HTTPS non-standard port
$uri = new Uri('https://foo.co:99');
$this->assertEquals('foo.co:99', $uri->getAuthority());
// HTTP non-standard port
$uri = new Uri('http://foo.co:99');
$this->assertEquals('foo.co:99', $uri->getAuthority());
// No scheme
$uri = new Uri('foo.co:99');
$this->assertEquals('foo.co:99', $uri->getAuthority());
// No host or port
$uri = new Uri('http:');
$this->assertEquals('', $uri->getAuthority());
// No host or port
$uri = new Uri('http://foo.co');
$this->assertEquals('foo.co', $uri->getAuthority());
}
public function pathTestProvider()
{
return [
// Percent encode spaces.
['http://foo.com/baz bar', 'http://foo.com/baz%20bar'],
// Don't encoding something that's already encoded.
['http://foo.com/baz%20bar', 'http://foo.com/baz%20bar'],
// Percent encode invalid percent encodings
['http://foo.com/baz%2-bar', 'http://foo.com/baz%252-bar'],
// Don't encode path segments
['http://foo.com/baz/bar/bam?a', 'http://foo.com/baz/bar/bam?a'],
['http://foo.com/baz+bar', 'http://foo.com/baz+bar'],
['http://foo.com/baz:bar', 'http://foo.com/baz:bar'],
['http://foo.com/baz@bar', 'http://foo.com/baz@bar'],
['http://foo.com/baz(bar);bam/', 'http://foo.com/baz(bar);bam/'],
['http://foo.com/a-zA-Z0-9.-_~!$&\'()*+,;=:@', 'http://foo.com/a-zA-Z0-9.-_~!$&\'()*+,;=:@'],
];
}
/**
* @dataProvider pathTestProvider
*/
public function testUriEncodesPathProperly($input, $output)
{
$uri = new Uri($input);
$this->assertEquals((string) $uri, $output);
}
public function testDoesNotAddPortWhenNoPort()
{
$this->assertEquals('bar', new Uri('//bar'));
$this->assertEquals('bar', (new Uri('//bar'))->getHost());
}
public function testAllowsForRelativeUri()
{
$uri = (new Uri)->withPath('foo');
$this->assertEquals('foo', $uri->getPath());
$this->assertEquals('foo', (string) $uri);
}
public function testAddsSlashForRelativeUriStringWithHost()
{
$uri = (new Uri)->withPath('foo')->withHost('bar.com');
$this->assertEquals('foo', $uri->getPath());
$this->assertEquals('bar.com/foo', (string) $uri);
}
}

View file

@ -1,11 +0,0 @@
<?php
namespace GuzzleHttp\Tests\Psr7;
require __DIR__ . '/../vendor/autoload.php';
class HasToString
{
public function __toString() {
return 'foo';
}
}