-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: console write using stream (#369)
- Loading branch information
1 parent
939e0f7
commit ea2d45d
Showing
5 changed files
with
200 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace System\Console\IO; | ||
|
||
use System\Console\Interfaces\OutputStream; | ||
|
||
/** | ||
* inspire by Aydin Hassan <[email protected]>. | ||
* | ||
* @source https://github.com/php-school/terminal/blob/master/src/IO/OutputStream.php | ||
*/ | ||
class ResourceOutputStream implements OutputStream | ||
{ | ||
/** | ||
* @var resource | ||
*/ | ||
private $stream; | ||
|
||
/** | ||
* ResourceOutputStream constructor. | ||
* | ||
* @param resource $stream | ||
* | ||
* @throws \InvalidArgumentException if the stream is not a valid or writable resource | ||
*/ | ||
public function __construct($stream = \STDOUT) | ||
{ | ||
if (!is_resource($stream) || get_resource_type($stream) !== 'stream') { | ||
throw new \InvalidArgumentException('Expected a valid stream'); | ||
} | ||
|
||
$meta = stream_get_meta_data($stream); | ||
if (str_contains($meta['mode'], 'r') && !str_contains($meta['mode'], '+')) { | ||
throw new \InvalidArgumentException('Expected a writable stream'); | ||
} | ||
|
||
$this->stream = $stream; | ||
} | ||
|
||
/** | ||
* Writes the buffer to the stream. | ||
* | ||
* @throws \InvalidArgumentException if writing to the stream fails | ||
*/ | ||
public function write(string $buffer): void | ||
{ | ||
if (fwrite($this->stream, $buffer) === false) { | ||
throw new \InvalidArgumentException('Failed to write to stream'); | ||
} | ||
} | ||
|
||
/** | ||
* Checks whether the stream is interactive (connected to a terminal). | ||
*/ | ||
public function isInteractive(): bool | ||
{ | ||
return stream_isatty($this->stream); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace System\Console\Interfaces; | ||
|
||
/** | ||
* inspire by Aydin Hassan <[email protected]>. | ||
* | ||
* @source https://github.com/php-school/terminal/blob/master/src/IO/OutputStream.php | ||
*/ | ||
interface OutputStream | ||
{ | ||
public function write(string $buffer): void; | ||
|
||
public function isInteractive(): bool; | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace System\Test\Console\IO; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use System\Console\IO\ResourceOutputStream; | ||
|
||
class ResourceOutputStreamTest extends TestCase | ||
{ | ||
/** | ||
* Test constructing the ResourceOutputStream with valid stream. | ||
*/ | ||
public function testConstructorWithValidStream(): void | ||
{ | ||
$stream = fopen('php://memory', 'w+'); | ||
$outputStream = new ResourceOutputStream($stream); | ||
|
||
$this->assertInstanceOf(ResourceOutputStream::class, $outputStream); | ||
fclose($stream); | ||
} | ||
|
||
/** | ||
* Test constructor throws exception for invalid stream. | ||
*/ | ||
public function testConstructorThrowsForInvalidStream(): void | ||
{ | ||
$this->expectException(\InvalidArgumentException::class); | ||
$this->expectExceptionMessage('Expected a valid stream'); | ||
|
||
new ResourceOutputStream('invalid_stream'); | ||
} | ||
|
||
/** | ||
* Test constructor throws exception for non-writable stream. | ||
*/ | ||
public function testConstructorThrowsForNonWritableStream(): void | ||
{ | ||
$stream = fopen('php://memory', 'r'); | ||
|
||
$this->expectException(\InvalidArgumentException::class); | ||
$this->expectExceptionMessage('Expected a writable stream'); | ||
|
||
new ResourceOutputStream($stream); | ||
|
||
fclose($stream); | ||
} | ||
|
||
/** | ||
* Test writing to a valid stream. | ||
*/ | ||
public function testWriteToStream(): void | ||
{ | ||
$stream = fopen('php://memory', 'w+'); | ||
$outputStream = new ResourceOutputStream($stream); | ||
|
||
$outputStream->write('Hello, World!'); | ||
|
||
rewind($stream); | ||
$this->assertEquals('Hello, World!', stream_get_contents($stream)); | ||
|
||
fclose($stream); | ||
} | ||
|
||
/** | ||
* Test if the stream is interactive. | ||
*/ | ||
public function testIsInteractive(): void | ||
{ | ||
$stream = fopen('php://memory', 'w+'); | ||
$outputStream = new ResourceOutputStream($stream); | ||
|
||
$this->assertFalse($outputStream->isInteractive()); | ||
|
||
fclose($stream); | ||
} | ||
} |
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