Created
December 8, 2017 10:08
-
-
Save mageekguy/44e4b3dda3b207a07032357dd5ef4a1e to your computer and use it in GitHub Desktop.
Testing write of data to STDERR with atoum
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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