mirror of
https://github.com/guzzle/guzzle.git
synced 2025-02-24 18:13:00 +01:00
[Service] Allowing commands to be sent more than once through a client
Allowing cloned commands that have previously been sent to be sent again. Redesigning the ResourceIterator class so that it accepts a command and iterates over the command until the sendRequest() method returns an empty array. Adding the name of the parameter that received a type validation error to Inpector error messages
This commit is contained in:
parent
f7e6aa551a
commit
f5a9e9bf82
@ -7,6 +7,7 @@ use Guzzle\Common\Collection;
|
||||
use Guzzle\Common\Exception\InvalidArgumentException;
|
||||
use Guzzle\Common\Exception\BadMethodCallException;
|
||||
use Guzzle\Http\Client as HttpClient;
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Service\Exception\CommandSetException;
|
||||
use Guzzle\Service\Command\CommandInterface;
|
||||
use Guzzle\Service\Command\CommandSet;
|
||||
@ -178,14 +179,23 @@ class Client extends HttpClient implements ClientInterface
|
||||
public function execute($command)
|
||||
{
|
||||
if ($command instanceof CommandInterface) {
|
||||
|
||||
$command->setClient($this)->prepare();
|
||||
$this->dispatch('command.before_send', array(
|
||||
'command' => $command
|
||||
));
|
||||
$command->getRequest()->send();
|
||||
|
||||
$request = $command->getRequest();
|
||||
// Set the state to new if the command was previously executed
|
||||
if ($request->getState() !== RequestInterface::STATE_NEW) {
|
||||
$request->setState(RequestInterface::STATE_NEW);
|
||||
}
|
||||
|
||||
$request->send();
|
||||
$this->dispatch('command.after_send', array(
|
||||
'command' => $command
|
||||
));
|
||||
|
||||
return $command->getResult();
|
||||
} else if ($command instanceof CommandSet) {
|
||||
foreach ($command as $c) {
|
||||
|
@ -66,6 +66,15 @@ abstract class AbstractCommand extends Collection implements CommandInterface
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom clone behavior
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->request = null;
|
||||
$this->result = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables magic methods for setting parameters.
|
||||
*
|
||||
|
@ -269,7 +269,7 @@ class Inspector
|
||||
if ($validate && $this->typeValidation && $configValue !== null && $argType = $arg->getType()) {
|
||||
$validation = $this->validateConstraint($argType, $configValue);
|
||||
if ($validation !== true) {
|
||||
$errors[] = $validation;
|
||||
$errors[] = $name . ': ' . $validation;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Guzzle\Service;
|
||||
|
||||
use Guzzle\Common\AbstractHasDispatcher;
|
||||
use Guzzle\Service\Command\CommandInterface;
|
||||
|
||||
/**
|
||||
* Iterate over a paginated set of resources that requires subsequent paginated
|
||||
@ -11,40 +12,35 @@ use Guzzle\Common\AbstractHasDispatcher;
|
||||
abstract class ResourceIterator extends AbstractHasDispatcher implements \Iterator, \Countable
|
||||
{
|
||||
/**
|
||||
* @var ClientInterface
|
||||
* @var CommandInterface Command used to send requests
|
||||
*/
|
||||
protected $client;
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* @var mixed Current iterator value
|
||||
* @var CommandInterface First sent command
|
||||
*/
|
||||
protected $current;
|
||||
protected $originalCommand;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array Currently loaded resources
|
||||
*/
|
||||
protected $resourceList;
|
||||
protected $resources;
|
||||
|
||||
/**
|
||||
* @var int Current index in $resourceList
|
||||
* @var int Total number of resources that have been retrieved
|
||||
*/
|
||||
protected $currentIndex = -1;
|
||||
|
||||
/**
|
||||
* @var int Current number of resources that have been iterated
|
||||
*/
|
||||
protected $pos = -1;
|
||||
|
||||
/**
|
||||
* @var string NextToken/Marker for a subsequent request
|
||||
*/
|
||||
protected $nextToken;
|
||||
protected $retrievedCount = 0;
|
||||
|
||||
/**
|
||||
* @var int Total number of resources that have been iterated
|
||||
*/
|
||||
protected $iteratedCount = 0;
|
||||
|
||||
/**
|
||||
* @var string NextToken/Marker for a subsequent request
|
||||
*/
|
||||
protected $nextToken = false;
|
||||
|
||||
/**
|
||||
* @var int Maximum number of resources to fetch per request
|
||||
*/
|
||||
@ -56,7 +52,7 @@ abstract class ResourceIterator extends AbstractHasDispatcher implements \Iterat
|
||||
protected $limit;
|
||||
|
||||
/**
|
||||
* @var array Initial data passed to the constructor -- used with rewind()
|
||||
* @var array Initial data passed to the constructor
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
@ -76,43 +72,33 @@ abstract class ResourceIterator extends AbstractHasDispatcher implements \Iterat
|
||||
/**
|
||||
* This should only be invoked by a {@see ClientInterface} object.
|
||||
*
|
||||
* @param ClientInterface $client Client responsible for sending requests
|
||||
* @param CommandInterface $command Initial command used for iteration
|
||||
*
|
||||
* @param array $data Associative array of additional parameters, including
|
||||
* any initial data to be iterated.
|
||||
* @param array $data (optional) Associative array of additional parameters,
|
||||
* including any initial data to be iterated:
|
||||
*
|
||||
* <ul>
|
||||
* <li>page_size => Max number of results to retrieve per request.</li>
|
||||
* <li>resources => Initial resources to associate with the iterator.</li>
|
||||
* <li>next_token => The value used to mark the beginning of a subsequent result set.</li>
|
||||
* </ul>
|
||||
* limit: Attempt to limit the maximum number of resources to this amount
|
||||
* page_size: Attempt to retrieve this number of resources per request
|
||||
*/
|
||||
public function __construct(ClientInterface $client, array $data)
|
||||
public function __construct(CommandInterface $command, array $data = array())
|
||||
{
|
||||
$this->client = $client;
|
||||
// Clone the command to keep track of the originating command for rewind
|
||||
$this->originalCommand = $command;
|
||||
|
||||
// Parse options from the array of options
|
||||
$this->data = $data;
|
||||
$this->limit = array_key_exists('limit', $data) ? $data['limit'] : -1;
|
||||
$this->limit = array_key_exists('limit', $data) ? $data['limit'] : 0;
|
||||
$this->pageSize = array_key_exists('page_size', $data) ? $data['page_size'] : false;
|
||||
$this->resourceList = array_key_exists('resources', $data) ? $data['resources'] : array();
|
||||
$this->nextToken = array_key_exists('next_token', $data) ? $data['next_token'] : false;
|
||||
$this->retrievedCount = count($this->resourceList);
|
||||
$this->onLoad();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the resources as an array (be careful as this could issue a
|
||||
* large number of requests if no limit is specified)
|
||||
*
|
||||
* @param bool $rewind (optional) By default, rewind() will be called
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($rewind = true)
|
||||
public function toArray()
|
||||
{
|
||||
if ($rewind) {
|
||||
$this->rewind();
|
||||
}
|
||||
|
||||
return iterator_to_array($this, false);
|
||||
}
|
||||
|
||||
@ -123,15 +109,23 @@ abstract class ResourceIterator extends AbstractHasDispatcher implements \Iterat
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->current;
|
||||
return $this->resources ? current($this->resources) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key of the current element.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return max(0, $this->iteratedCount - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total number of items that have been retrieved thus far.
|
||||
*
|
||||
* Implements Countable
|
||||
*
|
||||
* @return string Returns the total number of items retrieved.
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
@ -139,37 +133,16 @@ abstract class ResourceIterator extends AbstractHasDispatcher implements \Iterat
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total number of items that have been iterated thus far.
|
||||
*
|
||||
* @return string Returns the total number of items iterated.
|
||||
*/
|
||||
public function getPosition()
|
||||
{
|
||||
return $this->pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key of the current element.
|
||||
*
|
||||
* @return string Returns the current key.
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
return $this->currentIndex;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind the Iterator to the first element.
|
||||
* Rewind the Iterator to the first element and send the original command
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->currentIndex = -1;
|
||||
$this->pos = -1;
|
||||
$this->resourceList = $this->data['resources'];
|
||||
$this->nextToken = $this->data['next_token'];
|
||||
$this->retrievedCount = count($this->resourceList);
|
||||
// Use the original command
|
||||
$this->command = clone $this->originalCommand;
|
||||
$this->iteratedCount = 0;
|
||||
$this->retrievedCount = 0;
|
||||
$this->nextToken = false;
|
||||
$this->resources = null;
|
||||
$this->next();
|
||||
}
|
||||
|
||||
@ -180,10 +153,8 @@ abstract class ResourceIterator extends AbstractHasDispatcher implements \Iterat
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return isset($this->resourceList)
|
||||
&& $this->current
|
||||
&& ($this->pos < $this->limit || $this->limit == -1)
|
||||
&& ($this->currentIndex < count($this->resourceList) || $this->nextToken);
|
||||
return (!$this->resources || $this->current() || $this->nextToken)
|
||||
&& (!$this->limit || $this->iteratedCount < $this->limit + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,26 +162,39 @@ abstract class ResourceIterator extends AbstractHasDispatcher implements \Iterat
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->pos++;
|
||||
$this->iteratedCount++;
|
||||
|
||||
if (!isset($this->resourceList)
|
||||
|| ++$this->currentIndex >= count($this->resourceList)
|
||||
&& $this->nextToken
|
||||
&& ($this->limit == -1 || $this->pos < $this->limit)) {
|
||||
$this->dispatch('resource_iterator.before_send', array(
|
||||
'iterator' => $this,
|
||||
'resources' => $this->resourceList
|
||||
));
|
||||
$this->sendRequest();
|
||||
$this->dispatch('resource_iterator.after_send', array(
|
||||
'iterator' => $this,
|
||||
'resources' => $this->resourceList
|
||||
));
|
||||
// Check if a new set of resources needs to be retrieved
|
||||
$sendRequest = false;
|
||||
if (!$this->resources) {
|
||||
$sendRequest = true;
|
||||
} else {
|
||||
// iterate over the internal array
|
||||
$current = next($this->resources);
|
||||
$sendRequest = $current === false && $this->nextToken && (!$this->limit || $this->iteratedCount < $this->limit + 1);
|
||||
}
|
||||
|
||||
$this->current = (array_key_exists($this->currentIndex, $this->resourceList))
|
||||
? $this->resourceList[$this->currentIndex]
|
||||
: null;
|
||||
if ($sendRequest) {
|
||||
|
||||
$this->dispatch('resource_iterator.before_send', array(
|
||||
'iterator' => $this,
|
||||
'resources' => $this->resources
|
||||
));
|
||||
|
||||
// Get a new command object from the original command
|
||||
$this->command = clone $this->originalCommand;
|
||||
// Send a request and retrieve the newly loaded resources
|
||||
$this->resources = $this->sendRequest() ?: array();
|
||||
// Add to the number of retrieved resources
|
||||
$this->retrievedCount += count($this->resources);
|
||||
// Ensure that we rewind to the beginning of the array
|
||||
reset($this->resources);
|
||||
|
||||
$this->dispatch('resource_iterator.after_send', array(
|
||||
'iterator' => $this,
|
||||
'resources' => $this->resources
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -223,12 +207,6 @@ abstract class ResourceIterator extends AbstractHasDispatcher implements \Iterat
|
||||
return $this->nextToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request to retrieve the next page of results.
|
||||
* Hook for sublasses to implement.
|
||||
*/
|
||||
abstract protected function sendRequest();
|
||||
|
||||
/**
|
||||
* Returns the value that should be specified for the page size for
|
||||
* a request that will maintain any hard limits, but still honor the
|
||||
@ -239,21 +217,18 @@ abstract class ResourceIterator extends AbstractHasDispatcher implements \Iterat
|
||||
*/
|
||||
protected function calculatePageSize()
|
||||
{
|
||||
if ($this->limit == -1) {
|
||||
return $this->pageSize;
|
||||
} else if ($this->pos + $this->pageSize > $this->limit) {
|
||||
return $this->limit - $this->pos;
|
||||
if ($this->limit && $this->iteratedCount + $this->pageSize > $this->limit) {
|
||||
return 1 + ($this->limit - $this->iteratedCount);
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return $this->pageSize;
|
||||
// @codeCoverageIgnoreEnd
|
||||
return (int) $this->pageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the iterator is constructed.
|
||||
* Send a request to retrieve the next page of results.
|
||||
* Hook for sublasses to implement.
|
||||
*
|
||||
* Hook for sub-classes to implement.
|
||||
* @return array Returns the newly loaded resources
|
||||
*/
|
||||
protected function onLoad() {}
|
||||
abstract protected function sendRequest();
|
||||
}
|
||||
|
@ -92,8 +92,8 @@ class ClientTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
{
|
||||
$client = new Client('http://www.test.com/');
|
||||
$client->getEventDispatcher()->addSubscriber(new MockPlugin(array(
|
||||
new \Guzzle\Http\Message\Response(200),
|
||||
new \Guzzle\Http\Message\Response(200)
|
||||
new Response(200),
|
||||
new Response(200)
|
||||
)));
|
||||
|
||||
// Create a command set and a command
|
||||
@ -143,7 +143,7 @@ class ClientTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
{
|
||||
$client = new Client('http://www.test.com/');
|
||||
$client->getEventDispatcher()->addSubscriber(new MockPlugin(array(
|
||||
new \Guzzle\Http\Message\Response(200)
|
||||
new Response(200)
|
||||
)));
|
||||
|
||||
// Create a command set and a command
|
||||
@ -319,4 +319,23 @@ class ClientTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
$command = $client->getCommand('other_command');
|
||||
$this->assertTrue($command->get('command.magic_method_call'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Guzzle\Service\Client::execute
|
||||
*/
|
||||
public function testClientResetsRequestsBeforeExecutingCommands()
|
||||
{
|
||||
$this->getServer()->flush();
|
||||
$this->getServer()->enqueue(array(
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nHi",
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 1\r\n\r\nI"
|
||||
));
|
||||
|
||||
$client = new Mock\MockClient($this->getServer()->getUrl());
|
||||
|
||||
$command = $client->getCommand('mock_command');
|
||||
$client->execute($command);
|
||||
$client->execute($command);
|
||||
$this->assertEquals('I', $command->getResponse()->getBody(true));
|
||||
}
|
||||
}
|
||||
|
@ -307,4 +307,22 @@ class CommandTest extends AbstractCommandTest
|
||||
$command->setTest('foo');
|
||||
$this->assertEquals('foo', $command->get('test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Guzzle\Service\Command\AbstractCommand::__clone
|
||||
*/
|
||||
public function testCloneMakesNewRequest()
|
||||
{
|
||||
$client = $this->getClient();
|
||||
$command = new MockCommand(array(
|
||||
'command.magic_method_call' => true
|
||||
), $this->getApiCommand());
|
||||
$command->setClient($client);
|
||||
|
||||
$command->prepare();
|
||||
$this->assertTrue($command->isPrepared());
|
||||
|
||||
$command2 = clone $command;
|
||||
$this->assertFalse($command2->isPrepared());
|
||||
}
|
||||
}
|
||||
|
@ -199,8 +199,8 @@ EOT;
|
||||
$this->assertContains("Validation errors: Requires that the username argument be supplied. (API username)", $concat);
|
||||
$this->assertContains("Requires that the password argument be supplied. (API password)", $concat);
|
||||
$this->assertContains("Requires that the subdomain argument be supplied. (Unfuddle project subdomain)", $concat);
|
||||
$this->assertContains("Value must be one of: v1, v2, v3", $concat);
|
||||
$this->assertContains("Value must be of type object", $concat);
|
||||
$this->assertContains("api_version: Value must be one of: v1, v2, v3", $concat);
|
||||
$this->assertContains("class: Value must be of type object", $concat);
|
||||
}
|
||||
}
|
||||
|
||||
|
27
tests/Guzzle/Tests/Service/Mock/Command/IterableCommand.php
Normal file
27
tests/Guzzle/Tests/Service/Mock/Command/IterableCommand.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Guzzle\Tests\Service\Mock\Command;
|
||||
|
||||
/**
|
||||
* Iterable mock command
|
||||
*
|
||||
* @guzzle page_size type="integer"
|
||||
* @guzzle next_token type="string"
|
||||
*/
|
||||
class IterableCommand extends MockCommand
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function build()
|
||||
{
|
||||
$this->request = $this->client->createRequest('GET');
|
||||
|
||||
// Add the next token and page size query string values
|
||||
$this->request->getQuery()->set('next_token', $this->get('next_token'));
|
||||
|
||||
if ($this->get('page_size')) {
|
||||
$this->request->getQuery()->set('page_size', $this->get('page_size'));
|
||||
}
|
||||
}
|
||||
}
|
@ -8,13 +8,17 @@ class MockResourceIterator extends ResourceIterator
|
||||
{
|
||||
protected function sendRequest()
|
||||
{
|
||||
$request = $this->client->createRequest();
|
||||
$request->getQuery()->set('count', $this->calculatePageSize());
|
||||
$data = json_decode($request->send()->getBody(true), true);
|
||||
if ($this->nextToken) {
|
||||
$this->command->set('next_token', $this->nextToken);
|
||||
}
|
||||
|
||||
$this->command->set('page_size', (int) $this->calculatePageSize());
|
||||
$this->command->execute();
|
||||
|
||||
$data = json_decode($this->command->getResponse()->getBody(true), true);
|
||||
|
||||
$this->resourceList = $data['resources'];
|
||||
$this->nextToken = $data['next_token'];
|
||||
$this->retrievedCount += count($this->data['resources']);
|
||||
$this->currentIndex = 0;
|
||||
|
||||
return $data['resources'];
|
||||
}
|
||||
}
|
||||
|
@ -31,10 +31,9 @@ class ResourceIteratorApplyBatchedTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 41\r\n\r\n{ \"next_token\": \"\", \"resources\": [\"j\"] }",
|
||||
));
|
||||
|
||||
$ri = new MockResourceIterator($this->getServiceBuilder()->get('mock'), array(
|
||||
$ri = new MockResourceIterator($this->getServiceBuilder()->get('mock')->getCommand('iterable_command'), array(
|
||||
'page_size' => 3,
|
||||
'resources' => array('a', 'b', 'c'),
|
||||
'next_token' => 'd'
|
||||
'limit' => 7
|
||||
));
|
||||
|
||||
$received = array();
|
||||
@ -46,16 +45,15 @@ class ResourceIteratorApplyBatchedTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
|
||||
$requests = $this->getServer()->getReceivedRequests(true);
|
||||
$this->assertEquals(3, count($requests));
|
||||
$this->assertEquals(3, $requests[0]->getQuery()->get('count'));
|
||||
$this->assertEquals(3, $requests[1]->getQuery()->get('count'));
|
||||
$this->assertEquals(3, $requests[2]->getQuery()->get('count'));
|
||||
$this->assertEquals(3, $requests[0]->getQuery()->get('page_size'));
|
||||
$this->assertEquals(3, $requests[1]->getQuery()->get('page_size'));
|
||||
$this->assertEquals(1, $requests[2]->getQuery()->get('page_size'));
|
||||
|
||||
$this->assertEquals(array('a', 'b', 'c'), array_values($received[0]));
|
||||
$this->assertEquals(array('d', 'e', 'f'), array_values($received[1]));
|
||||
$this->assertEquals(array('g', 'h', 'i'), array_values($received[2]));
|
||||
$this->assertEquals(array('j'), array_values($received[3]));
|
||||
$this->assertEquals(array('d', 'e', 'f'), array_values($received[0]));
|
||||
$this->assertEquals(array('g', 'h', 'i'), array_values($received[1]));
|
||||
$this->assertEquals(array('j'), array_values($received[2]));
|
||||
|
||||
$this->assertEquals(4, $apply->getBatchCount());
|
||||
$this->assertEquals(10, $apply->getIteratedCount());
|
||||
$this->assertEquals(3, $apply->getBatchCount());
|
||||
$this->assertEquals(7, $apply->getIteratedCount());
|
||||
}
|
||||
}
|
||||
|
@ -24,39 +24,15 @@ class ResourceIteratorTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
public function testConstructorConfiguresDefaults()
|
||||
{
|
||||
$ri = $this->getMockForAbstractClass('Guzzle\\Service\\ResourceIterator', array(
|
||||
$this->getServiceBuilder()->get('mock'),
|
||||
$this->getServiceBuilder()->get('mock')->getCommand('iterable_command'),
|
||||
array(
|
||||
'limit' => 10,
|
||||
'page_size' => 3,
|
||||
'resources' => array('a', 'b', 'c'),
|
||||
'next_token' => 'd'
|
||||
'page_size' => 3
|
||||
)
|
||||
), 'MockIterator');
|
||||
|
||||
$this->assertEquals('d', $ri->getNextToken());
|
||||
$this->assertEquals(array('a', 'b', 'c'), $ri->toArray());
|
||||
|
||||
$ri->rewind();
|
||||
$this->assertEquals('a', $ri->current());
|
||||
$ri->next();
|
||||
$this->assertEquals('b', $ri->current());
|
||||
$ri->next();
|
||||
$this->assertEquals('c', $ri->current());
|
||||
|
||||
// It ran out
|
||||
$ri->next();
|
||||
$this->assertEquals('', $ri->current());
|
||||
|
||||
$this->assertEquals(3, count($ri));
|
||||
$this->assertEquals(3, $ri->getPosition());
|
||||
|
||||
// Rewind works?
|
||||
$ri->rewind();
|
||||
$this->assertEquals('a', $ri->current());
|
||||
$ri->next();
|
||||
$this->assertEquals('b', $ri->current());
|
||||
$ri->next();
|
||||
$this->assertEquals('c', $ri->current());
|
||||
$this->assertEquals(false, $ri->getNextToken());
|
||||
$this->assertEquals(false, $ri->current());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,25 +40,30 @@ class ResourceIteratorTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
*/
|
||||
public function testSendsRequestsForNextSetOfResources()
|
||||
{
|
||||
// Queue up an array of responses for iterating
|
||||
$this->getServer()->flush();
|
||||
$this->getServer()->enqueue(array(
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 52\r\n\r\n{ \"next_token\": \"g\", \"resources\": [\"d\", \"e\", \"f\"] }",
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 52\r\n\r\n{ \"next_token\": \"j\", \"resources\": [\"g\", \"h\", \"i\"] }",
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 41\r\n\r\n{ \"next_token\": \"\", \"resources\": [\"j\"] }",
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 41\r\n\r\n{ \"next_token\": \"\", \"resources\": [\"j\"] }"
|
||||
));
|
||||
|
||||
$ri = new MockResourceIterator($this->getServiceBuilder()->get('mock'), array(
|
||||
'page_size' => 3,
|
||||
'resources' => array('a', 'b', 'c'),
|
||||
'next_token' => 'd'
|
||||
// Create a new resource iterator using the IteraableCommand mock
|
||||
$ri = new MockResourceIterator($this->getServiceBuilder()->get('mock')->getCommand('iterable_command'), array(
|
||||
'page_size' => 3
|
||||
));
|
||||
|
||||
$this->assertEquals(array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), $ri->toArray());
|
||||
// Ensure that no requests have been sent yet
|
||||
$this->assertEquals(0, count($this->getServer()->getReceivedRequests(false)));
|
||||
|
||||
//$this->assertEquals(array('d', 'e', 'f', 'g', 'h', 'i', 'j'), $ri->toArray());
|
||||
$ri->toArray();
|
||||
$requests = $this->getServer()->getReceivedRequests(true);
|
||||
$this->assertEquals(3, count($requests));
|
||||
$this->assertEquals(3, $requests[0]->getQuery()->get('count'));
|
||||
$this->assertEquals(3, $requests[1]->getQuery()->get('count'));
|
||||
$this->assertEquals(3, $requests[2]->getQuery()->get('count'));
|
||||
|
||||
$this->assertEquals(3, $requests[0]->getQuery()->get('page_size'));
|
||||
$this->assertEquals(3, $requests[1]->getQuery()->get('page_size'));
|
||||
$this->assertEquals(3, $requests[2]->getQuery()->get('page_size'));
|
||||
|
||||
// Reset and resend
|
||||
$this->getServer()->flush();
|
||||
@ -91,12 +72,13 @@ class ResourceIteratorTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 52\r\n\r\n{ \"next_token\": \"j\", \"resources\": [\"g\", \"h\", \"i\"] }",
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 41\r\n\r\n{ \"next_token\": \"\", \"resources\": [\"j\"] }",
|
||||
));
|
||||
|
||||
$d = array();
|
||||
reset($ri);
|
||||
foreach ($ri as $data) {
|
||||
$d[] = $data;
|
||||
}
|
||||
$this->assertEquals(array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), $d);
|
||||
$this->assertEquals(array('d', 'e', 'f', 'g', 'h', 'i', 'j'), $d);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,20 +90,47 @@ class ResourceIteratorTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
$this->getServer()->enqueue(array(
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 52\r\n\r\n{ \"next_token\": \"g\", \"resources\": [\"d\", \"e\", \"f\"] }",
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 52\r\n\r\n{ \"next_token\": \"j\", \"resources\": [\"g\", \"h\", \"i\"] }",
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 52\r\n\r\n{ \"next_token\": \"j\", \"resources\": [\"g\", \"h\"] }"
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 52\r\n\r\n{ \"next_token\": \"j\", \"resources\": [\"j\", \"k\"] }"
|
||||
));
|
||||
|
||||
$ri = new MockResourceIterator($this->getServiceBuilder()->get('mock'), array(
|
||||
$ri = new MockResourceIterator($this->getServiceBuilder()->get('mock')->getCommand('iterable_command'), array(
|
||||
'page_size' => 3,
|
||||
'limit' => 8,
|
||||
'resources' => array('a', 'b', 'c'),
|
||||
'next_token' => 'd'
|
||||
'limit' => 7
|
||||
));
|
||||
|
||||
$this->assertEquals(array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'), $ri->toArray());
|
||||
$this->assertEquals(array('d', 'e', 'f', 'g', 'h', 'i', 'j'), $ri->toArray());
|
||||
$requests = $this->getServer()->getReceivedRequests(true);
|
||||
$this->assertEquals(2, count($requests));
|
||||
$this->assertEquals(3, $requests[0]->getQuery()->get('count'));
|
||||
$this->assertEquals(2, $requests[1]->getQuery()->get('count'));
|
||||
$this->assertEquals(3, count($requests));
|
||||
$this->assertEquals(3, $requests[0]->getQuery()->get('page_size'));
|
||||
$this->assertEquals(3, $requests[1]->getQuery()->get('page_size'));
|
||||
$this->assertEquals(1, $requests[2]->getQuery()->get('page_size'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Guzzle\Service\ResourceIterator
|
||||
*/
|
||||
public function testUseAsArray()
|
||||
{
|
||||
$this->getServer()->flush();
|
||||
$this->getServer()->enqueue(array(
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 52\r\n\r\n{ \"next_token\": \"g\", \"resources\": [\"d\", \"e\", \"f\"] }",
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 52\r\n\r\n{ \"next_token\": \"\", \"resources\": [\"g\", \"h\", \"i\"] }"
|
||||
));
|
||||
|
||||
$ri = new MockResourceIterator($this->getServiceBuilder()->get('mock')->getCommand('iterable_command'));
|
||||
|
||||
// Ensure that the key is never < 0
|
||||
$this->assertEquals(0, $ri->key());
|
||||
$this->assertEquals(0, count($ri));
|
||||
|
||||
// Ensure that the iterator can be used as KVP array
|
||||
$data = array();
|
||||
foreach ($ri as $key => $value) {
|
||||
$data[$key] = $value;
|
||||
}
|
||||
|
||||
// Ensure that the iterate is countable
|
||||
$this->assertEquals(6, count($ri));
|
||||
$this->assertEquals(array('d', 'e', 'f', 'g', 'h', 'i'), $data);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user