Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Improves SapiStreamEmitter tests, preventing unnecessary string casts #226

Merged

Conversation

fcabralpacheco
Copy link
Contributor

@Ocramius

I tried to improve some points in the SapiStreamEmitter tests:

  • Reduced code repetition by creating a new method for the Stream Prophecy common code.

  • Added a method for expanding the test data set. This facilitates the addition of new data set with one information changed (e.g.: the contents).

  • Improved checks of methods that can or cannot be called.

  • Removed the expectation of read counts because the buffer size is the maximum, the implementation can use a smaller one if you want.

  • Considering bug JsonResponse not working #225, which I was not able to reproduce, both in the test and in an Expressive application. Added new tests for each type of response, checking what was emitted, and whether the content type was not changed.

Just a few comments:

  • I didn't add out of range conditions to the tests (in testEmitRangeStreamResponse). I think that the application should handle this type of case, and it may be not possible to detect this type of condition in non seekable bodies.

  • Please keep prophecy prediction after reveal. The Prophecy don't calls promise if it signature don't match exact with prediction signature.
    E.g.: $stream->seek(Argument::type('integer'), Argument::any()); vs $stream->seek($first)->should($seekPredictionClosure); and $ stream->seek($first, SEEK_SET)->should($seekPredictionClosure);
    This occurs because signatures generate three different prophecies, one with a promise and two with a prediction, on execution only highest rated prophecy is executed. If you pass the "$first" value, only first prediction would be executed.

Linked to #224, #223

{
$stream = $this->prophesize('Psr\Http\Message\StreamInterface');

$stream->__toString()->will(function () use (& $contents, & $position, $size) {
Copy link
Member

Choose a reason for hiding this comment

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

Is $size supposed to not be passed in by reference?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The $size don't need by ref.

}
};

array_walk(array_shift($initialData), $closureExpand, [
Copy link
Member

Choose a reason for hiding this comment

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

Please use consistent alignment (PSR-2)


$resultData = [];

$closureExpand = function ($item, $key, $parameters) use (& $closureExpand) {
Copy link
Member

Choose a reason for hiding this comment

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

What does closureExpand mean here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The method expands data like a tree. In the end of branch resides one data set.

return $resultData;
}

private function getStreamProphecy(& $contents, & $size, & $position, & $peakBufferLength)
Copy link
Member

Choose a reason for hiding this comment

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

s/get/build

Copy link
Member

Choose a reason for hiding this comment

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

The act that all this stuff is by-ref makes it extremely hard to read

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok. The $size don't need by ref, the $contents too (I thought it would be necessary at first due to memory usage).

The $position and $peakBufferLength is necessary, I can return them in an array. Like this:
private function getStreamProphecy($contents, $size)
...
return [
$stream,
& $position,
& $peakBufferLength,
];

And I can rename getStreamProphecy to setUpStreamProphecy.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed unecessary by-ref and replaced $peakBufferLength by a callable.
I think it's now become more intuitive.

return $stream;
}

public function emitStreamResponseProvider()
Copy link
Member

Choose a reason for hiding this comment

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

Please document the return type o this data provider

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Ocramius
I'm not sure if after the changes this still necessary.
Also, I don't know exactly how to document elements of an array according to the ZF CS (as far as I know. There is no official way to do this in phpdoc).

Copy link
Member

Choose a reason for hiding this comment

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

Oh, it just needed a human-friendly description. The new syntax makes it much more approachable, so it's not needed anymore.

});
public function emitJsonResponseProvider()
{
return [[0.1 ],
Copy link
Member

Choose a reason for hiding this comment

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

Alignment broken here

['bytes 0-2/*', 'Hello world', 'Hel'],
['bytes 3-6/*', 'Hello world', 'lo w'],
['items 0-0/1', 'Hello world', 'Hello world'],
['bytes 0-2/*', 'Hello world', 'Hel'],
Copy link
Member

Choose a reason for hiding this comment

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

Alignment broken here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay. It was supposed to be just a reordering of this piece of the code. I messed things.

@@ -57,76 +61,322 @@ public function testDoesNotInjectContentLengthHeaderIfStreamSizeIsUnknown()
}
}

public function emitBodyProvider()
private function expandTestData()
Copy link
Member

Choose a reason for hiding this comment

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

While I get that you wanted to normalize the mocking done for the data providers, this method has become absolutely unreadable. I would suggest duplicating or the supported scenarios. Specifically based on:

  • number of passed in parameters
  • types of passed in parameters

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I get it. I'll use duplication.
I thought the same when I finished writing this method.
I tried a version without array_walk (using for, next, current), it got worse.

return $data;
});
if ($readable) {
$stream->__toString()->shouldNotBeCalled();
Copy link
Member

Choose a reason for hiding this comment

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

Most probably the important assertion that we missed before :S

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with you.

/**
* @dataProvider emitRangeStreamResponseProvider
*/
public function testEmitRangeStreamResponse($seekable, $readable, array $range, $contents, $maxBufferLength)
Copy link
Member

Choose a reason for hiding this comment

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

Please document the parameter types/formats

…and minor bug (last byte position in testEmitMemoryUsage).
return $stream;
}

public function emitStreamResponseProvider()
Copy link
Member

Choose a reason for hiding this comment

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

Oh, it just needed a human-friendly description. The new syntax makes it much more approachable, so it's not needed anymore.

@Ocramius Ocramius changed the title Improves SapiStreamEmitter tests Improves SapiStreamEmitter tests, preventing unnecessary string casts Jan 23, 2017
@Ocramius Ocramius merged commit 2faeff4 into zendframework:develop Jan 23, 2017
@Ocramius
Copy link
Member

Backported into master via c2c5982

@fcabralpacheco
Copy link
Contributor Author

@Ocramius

I'm sorry, just a little type correction/type hinting.

fcabralpacheco@346e468

Thanks.

@Ocramius
Copy link
Member

@fcabralpacheco cherry-picking it, thanks!

@Ocramius
Copy link
Member

@fcabralpacheco also, sorry for having to do all this because of a messed up CS fix by me: thanks for all the patience!

@fcabralpacheco
Copy link
Contributor Author

I'm sorry again, just a little correction.

fcabralpacheco@555e9cd

fcabralpacheco@e406769

Thanks

@Ocramius
Copy link
Member

Already applied fcabralpacheco@555e9cd

@fcabralpacheco
Copy link
Contributor Author

And thanks for all the patience too.

@Ocramius Ocramius self-assigned this Jan 23, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants