Skip to content

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

Merged
merged 1 commit into from
Sep 23, 2015
Merged

Add sendRequests method as a trait #54

merged 1 commit into from
Sep 23, 2015

Conversation

joelwurtz
Copy link
Member

See discussion in #48

@joelwurtz
Copy link
Member Author

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 = []);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dunno about this...

Copy link
Member

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.

Copy link
Contributor

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.

Copy link
Member

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.

@sagikazarmark
Copy link
Member

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);
Copy link
Member

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?

Copy link
Member Author

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

Copy link
Member

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.

Copy link
Member Author

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;

Copy link
Member

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.

@joelwurtz
Copy link
Member Author

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)

@sagikazarmark
Copy link
Member

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.

@joelwurtz
Copy link
Member Author

Yes it works, will update the PR

@joelwurtz
Copy link
Member Author

Should be good with last comments

@sagikazarmark
Copy link
Member

Can you squash the commits?

@joelwurtz
Copy link
Member Author

done

@sagikazarmark
Copy link
Member

Thank you @joelwurtz

sagikazarmark added a commit that referenced this pull request Sep 23, 2015
@sagikazarmark sagikazarmark merged commit 26c9257 into php-http:terminology Sep 23, 2015
Nyholm pushed a commit to Nyholm/httplug that referenced this pull request Dec 26, 2019
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants