-
Notifications
You must be signed in to change notification settings - Fork 39
Add sendRequests method as a trait #54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add sendRequests method as a trait #54
Conversation
Method should be good, but i'm having a hard time to write specification for the Trait (never done phpspec before) and it's seems quite hards since i use the sendRequest method internally, do you have an idea for the spec @sagikazarmark ? |
/** | ||
* {@inheritdoc} | ||
*/ | ||
abstract public function sendRequest(RequestInterface $request, array $options = []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dunno about this...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I usually do this as well. This makes sure your code works, even if you don't implement the relevant interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did some reading. I'm cool with this, was just worried about keeping this in sync with the interface definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This problem can be handled on a test level: if the stub implements HttpPsrClient then the tests will fail if the signature is incorrect.
Nice work @joelwurtz! 👍 👍 Unfortunately it is hard to test internal methods with phpspec. I usually use a hack with the stub: inject the response/exception in the stub's constructor. You can then return it in the sendRequest method. Alternatively you can inject a HttpPsrClient mock and call its sendRequest in the stub. This way you have greater control over what's happening. Then in your tests you can add calls to the HttpPsrClient mock. |
{ | ||
$batchResult = new BatchResult(); | ||
$batchException = new BatchException(); | ||
$batchException->setResult($batchResult); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is the first case we use the batch result/exception solution, we don't have any reference. But I wonder if we should create both the result and the exception at the beginning. Shouldn't we create the excetpion on demand?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can create the exception on demand but i think it will make code harder to read, as we must add some conditions / loop system as there is no way to pass an array of request -> exceptions to the BatchException in its current implementation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it is on purpose that you have to add them one by one, because in most cases (and in this as well) processing of results is linear. This way you don't have to mess with array indicies. Alternatively we could have a method in the BatchException which allows an array input with array elements of a Request and an Exception. But that would be more complicated IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, should i keep the current implementation or do you prefer something like this :
$batchResult = new BatchResult();
$batchException = null;
foreach ($requests as $request) {
try {
$batchResult->addResponse($request, $this->sendRequest($request, $options));
} catch (Exception $e) {
if (null === $batchException) {
$batchException = new BatchException();
$batchException->setResult($batchResult);
}
$batchException->addException($request, $e);
}
}
if (null !== $batchException) {
throw $batchException;
}
return $batchResult;
or something like this :
$batchResult = new BatchResult();
$batchExceptions = new \SplObjectStorage();
foreach ($requests as $request) {
try {
$batchResult->addResponse($request, $this->sendRequest($request, $options));
} catch (Exception $e) {
$batchExceptions[$request] = $e;
}
}
if (count($batchExceptions) > 0) {
$batchException = new BatchException();
$batchException->setResult($batchResult);
foreach ($batchExceptions as $request => $exception) {
$batchException->addException($request, $exception);
}
throw $batchException;
}
return $batchResult;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, both versions are harder to read. Probably the first one is cleaner. Let's leave it as is for now, from a public API point of view it doesn't matter, we can change this later.
Yeah but the problem is that i need a implementation for the ResponseInterface (i have try to use prophecy but it only mock method and the interface is not used so it always fail in the sendRequests method) |
I am not sure I understand this. You can do something like this: class BatchRequestSpec extends ObjectBehavior
{
function let()
{
$this->beAnInstanceOf('spec\Http\Client\Util\BatchRequestStub');
}
function let(HttpPsrClient $client)
{
$this->beAnInstanceOf('spec\Http\Client\Util\BatchRequestStub', [$client]);
}
function it_does_something(HttpPsrClient $client, RequestInterface $request1, RequestInterface $request2, ResponseInterface $response, Exception $e)
{
$client->sendRequest($request1)->willReturn($response);
$client->sendRequest($request2)->willThrow($e);
$this->sendRequests([$request1, $request2]);
}
}
class BatchRequestStub
{
use BatchRequest;
protected $client;
public function __construct(HttpPsrClient $client)
{
$this->client = $client;
}
/**
* {@inheritdoc}
*/
public function sendRequest(RequestInterface $request, array $options = [])
{
return $this->client->sendRequest($request, $options);
}
} At least I think it should work. |
Yes it works, will update the PR |
Should be good with last comments |
Can you squash the commits? |
done |
Thank you @joelwurtz |
Add sendRequests method as a trait
POC how to not be dependent on discovery Fix unit tests Fix factory method Remove duplicated service Move discovery to compiler pass Applied fixes from StyleCI Fix puli executable Use class constant Fix puli command order Fix lowest dependency issue Fix HHVM tests Improve tests
See discussion in #48