Instantly share code, notes, and snippets.

Embed
What would you like to do?
Testing write of data to STDERR with atoum
<?php namespace estvoyage\ticTacToe\tests\units\output\cli;
require __DIR__ . '/../../../runner.php';
use estvoyage\ticTacToe\tests\units;
use mock\estvoyage\ticTacToe as mockOfTicTacToe;
class stderr extends units\test
{
private
$stderr = ''
;
function beforeTestMethod($method = null)
{
// Thanks to rwb from https://stackoverflow.com/questions/8348927/is-there-a-way-test-stderr-output-in-phpunit for the idea!
stream_filter_register("bufferizer", "estvoyage\\ticTacToe\\tests\\units\\output\\cli\\bufferizer");
// STDERR constant is not available if reading code from stdin, and atoum read code from stdin when concurrent engine is used,
// so, we define the constant here to avoid error about undefined constant.
if (! defined('STDERR'))
{
define('STDERR', fopen('php://stderr', 'w'));
}
// append an instance of bufferizer to STDERR and link `this->stderr` to it, so each data sent to STDERR is now appended to this property.
// We use an array because php does not allow to pass argument by reference directly (very crappy, but it works fine).
stream_filter_append(STDERR, "bufferizer", STREAM_FILTER_WRITE, [ & $this->stderr ]);
}
function testClass()
{
$this->testedClass
->implements('estvoyage\ticTacToe\output\cli')
;
}
function testControllerOfOutputDataIs() :void
{
$this
->given(
$this->newTestedInstance,
$data = new mockOfTicTacToe\output\data,
$controller = new mockOfTicTacToe\output\controller
)
->if(
// this method use STDERR
$this->testedInstance->controllerOfOutputDataIs($data, $controller)
)
->then
->mock($controller)
->receive('dataIsInOutput')
->never
->given(
$string = uniqid(),
$this->calling($data)->recipientOfStringIs = function($recipient) use ($string) {
$recipient->stringIs($string);
}
)
->if(
$this->testedInstance->controllerOfOutputDataIs($data, $controller)
)
->then
->string($this->stderr)
->isEqualTo($string)
->mock($controller)
->receive('dataIsInOutput')
->once
;
}
}
// Bufferizer class used by `stream_filter_register`.
// Basically append to a variable all data writed in the `$in` stream.
class bufferizer extends \php_user_filter
{
private
$buffer
;
function filter($in, $out, &$consumed, $closing)
{
while ($bucket = stream_bucket_make_writeable($in)) {
$this->buffer .= $bucket->data;
}
return PSFS_PASS_ON;
}
function onCreate()
{
// Init the buffer using the null coalesce operator, at least i'm using it!
$this->buffer = & $this->params[0] ?? '';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment