Redid some core IO stuff and fixed tests.
This commit is contained in:
parent
5ec90ec1ba
commit
eae6e12ac0
6 changed files with 344 additions and 330 deletions
294
src/IO/File.php
294
src/IO/File.php
|
@ -1,167 +1,26 @@
|
|||
<?php
|
||||
namespace Misuzu\IO;
|
||||
|
||||
use ErrorException;
|
||||
|
||||
/**
|
||||
* Wrapper for f* (file stream) functions and other cool stuff.
|
||||
* Static file meta functions.
|
||||
* @package Misuzu\IO
|
||||
* @author flashwave <me@flash.moe>
|
||||
*/
|
||||
class File
|
||||
{
|
||||
/**
|
||||
* Open + Read flag.
|
||||
*/
|
||||
public const OPEN_READ = 'rb';
|
||||
|
||||
/**
|
||||
* Open + Write flag.
|
||||
*/
|
||||
public const OPEN_WRITE = 'cb';
|
||||
|
||||
/**
|
||||
* Open + Read + Write flag.
|
||||
*/
|
||||
public const OPEN_READ_WRITE = 'rb+';
|
||||
|
||||
/**
|
||||
* Create (truncates!) + Write flag.
|
||||
*/
|
||||
public const CREATE_WRITE = 'wb';
|
||||
|
||||
/**
|
||||
* Create (truncates!) + Read + Write flag.
|
||||
*/
|
||||
public const CREATE_READ_WRITE = 'wb+';
|
||||
|
||||
/**
|
||||
* Open + Write flag.
|
||||
*/
|
||||
public const OPEN_CREATE_WRITE = 'xb';
|
||||
|
||||
/**
|
||||
* Open or Create + Read + Write flag.
|
||||
*/
|
||||
public const OPEN_CREATE_READ_WRITE = 'xb+';
|
||||
|
||||
/**
|
||||
* Resource/stream container.
|
||||
* @var resource
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* Filename.
|
||||
* @var string
|
||||
*/
|
||||
public $name = '';
|
||||
|
||||
/**
|
||||
* Real, fixed path.
|
||||
* @var string
|
||||
*/
|
||||
public $path = '';
|
||||
|
||||
/**
|
||||
* Filesize in bytes.
|
||||
* @var int
|
||||
*/
|
||||
public $size = 0;
|
||||
|
||||
/**
|
||||
* ID of file owner.
|
||||
* @var int
|
||||
*/
|
||||
public $owner = 0;
|
||||
|
||||
/**
|
||||
* ID of file's owning group.
|
||||
* @var int
|
||||
*/
|
||||
public $group = 0;
|
||||
|
||||
/**
|
||||
* Last time this file has been accessed.
|
||||
* @var int
|
||||
*/
|
||||
public $accessTime = 0;
|
||||
|
||||
/**
|
||||
* Last time this file has been modified.
|
||||
* @var int
|
||||
*/
|
||||
public $modifiedTime = 0;
|
||||
|
||||
/**
|
||||
* Current stream position.
|
||||
* @var int
|
||||
*/
|
||||
public $position = 0;
|
||||
|
||||
/**
|
||||
* Fixes path and opens resource.
|
||||
* @param string $path
|
||||
* @param string $mode
|
||||
* @throws FileDoesNotExistException
|
||||
* @throws IOException
|
||||
*/
|
||||
public function __construct(string $path, string $mode)
|
||||
public static function open(string $filename): FileStream
|
||||
{
|
||||
$path = Directory::fixSlashes($path);
|
||||
$this->path = realpath($path);
|
||||
$this->name = basename($this->path);
|
||||
|
||||
try {
|
||||
$this->resource = fopen($path, $mode, false);
|
||||
} catch (ErrorException $e) {
|
||||
throw new FileDoesNotExistException($e->getMessage());
|
||||
}
|
||||
|
||||
if (!is_resource($this->resource)) {
|
||||
throw new IOException('Failed to create resource.');
|
||||
}
|
||||
|
||||
$this->updateMetaData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the meta data of the resource.
|
||||
*/
|
||||
private function updateMetaData(): void
|
||||
{
|
||||
$meta = fstat($this->resource);
|
||||
$this->size = intval($meta['size']);
|
||||
$this->owner = intval($meta['uid']);
|
||||
$this->group = intval($meta['gid']);
|
||||
$this->accessTime = intval($meta['atime']);
|
||||
$this->modifiedTime = intval($meta['mtime']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the position variable.
|
||||
*/
|
||||
private function updatePosition(): void
|
||||
{
|
||||
$this->position = ftell($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the close method.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
return new FileStream($filename, FileStream::MODE_READ_WRITE, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of a temporary file.
|
||||
* @param string $prefix
|
||||
* @return File
|
||||
* @return FileStream
|
||||
*/
|
||||
public static function temp(string $prefix = 'Misuzu'): File
|
||||
public static function temp(string $prefix = 'Misuzu'): FileStream
|
||||
{
|
||||
return new static(tempnam(sys_get_temp_dir(), $prefix));
|
||||
return static::open(tempnam(sys_get_temp_dir(), $prefix));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,145 +49,4 @@ class File
|
|||
|
||||
unlink($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the resource context.
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
if (is_resource($this->resource)) {
|
||||
fclose($this->resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the position to 0.
|
||||
*/
|
||||
public function start(): void
|
||||
{
|
||||
rewind($this->resource);
|
||||
$this->updatePosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the position to the end of the file.
|
||||
*/
|
||||
public function end(): void
|
||||
{
|
||||
fseek($this->resource, 0, SEEK_END);
|
||||
$this->updatePosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position.
|
||||
* @param int $offset
|
||||
* @param bool $relative
|
||||
* @return int
|
||||
*/
|
||||
public function position(int $offset, bool $relative = false): int
|
||||
{
|
||||
fseek($this->resource, $offset, $relative ? SEEK_CUR : SEEK_SET);
|
||||
$this->updatePosition();
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current position is the end of the file.
|
||||
* @return bool
|
||||
*/
|
||||
public function atEOF(): bool
|
||||
{
|
||||
return feof($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find the position of a string in the context.
|
||||
* @param string $string
|
||||
* @return int
|
||||
*/
|
||||
public function find(string $string): int
|
||||
{
|
||||
while ($this->position < $this->size) {
|
||||
$find = strpos($this->read(8192), $string);
|
||||
|
||||
if ($find !== false) {
|
||||
return $find + $this->position;
|
||||
}
|
||||
|
||||
$this->position($this->position + 8192);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the file and reads from it.
|
||||
* @param int $length
|
||||
* @throws IOException
|
||||
* @return string
|
||||
*/
|
||||
public function read(int $length = null): string
|
||||
{
|
||||
if ($length === null) {
|
||||
$length = $this->size;
|
||||
$this->start();
|
||||
}
|
||||
|
||||
flock($this->resource, LOCK_SH);
|
||||
$data = fread($this->resource, $length);
|
||||
flock($this->resource, LOCK_UN);
|
||||
|
||||
if ($data === false) {
|
||||
throw new IOException('Read failed.');
|
||||
}
|
||||
|
||||
$this->updateMetaData();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the character at the current position.
|
||||
* @return string
|
||||
*/
|
||||
public function char(): string
|
||||
{
|
||||
return fgetc($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the file, writes to the stream and flushes to file.
|
||||
* @param string $data
|
||||
* @param int $length
|
||||
* @throws IOException
|
||||
*/
|
||||
public function write(string $data, int $length = 0): void
|
||||
{
|
||||
if ($length > 0) {
|
||||
$length = strlen($data);
|
||||
}
|
||||
|
||||
flock($this->resource, LOCK_EX);
|
||||
$write = fwrite($this->resource, $data, $length);
|
||||
$flush = fflush($this->resource);
|
||||
flock($this->resource, LOCK_UN);
|
||||
|
||||
if ($write === false || $flush === false) {
|
||||
throw new IOException('Write failed.');
|
||||
}
|
||||
|
||||
$this->updateMetaData();
|
||||
$this->updatePosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* The same as write except it moves to the end of the file first.
|
||||
* @param string $data
|
||||
* @param int $length
|
||||
*/
|
||||
public function append(string $data, int $length = 0): void
|
||||
{
|
||||
$this->end();
|
||||
$this->write($data, $length);
|
||||
}
|
||||
}
|
||||
|
|
252
src/IO/FileStream.php
Normal file
252
src/IO/FileStream.php
Normal file
|
@ -0,0 +1,252 @@
|
|||
<?php
|
||||
namespace Misuzu\IO;
|
||||
|
||||
use ErrorException;
|
||||
|
||||
class FileStream extends Stream
|
||||
{
|
||||
public const MODE_READ = 0x1;
|
||||
public const MODE_WRITE = 0x2;
|
||||
public const MODE_READ_WRITE = self::MODE_READ | self::MODE_WRITE;
|
||||
private const MODE_TRUNCATE_RAW = 0x4;
|
||||
public const MODE_TRUNCATE = self::MODE_TRUNCATE_RAW | self::MODE_WRITE;
|
||||
private const MODE_APPEND_RAW = 0x8;
|
||||
public const MODE_APPEND = self::MODE_APPEND_RAW | self::MODE_WRITE;
|
||||
|
||||
protected $fileHandle;
|
||||
protected $filePath;
|
||||
protected $fileMode;
|
||||
protected $isLocked;
|
||||
|
||||
public function __construct(string $path, int $mode, bool $lock = true)
|
||||
{
|
||||
$this->isLocked = $lock;
|
||||
$this->filePath = $path;
|
||||
$this->fileMode = $mode;
|
||||
|
||||
try {
|
||||
$this->fileHandle = fopen($this->filePath, static::constructFileMode($this->fileMode));
|
||||
} catch (ErrorException $ex) {
|
||||
throw new FileDoesNotExistException($ex->getMessage());
|
||||
}
|
||||
|
||||
$this->ensureHandleActive();
|
||||
|
||||
if ($this->isLocked) {
|
||||
flock($this->fileHandle, LOCK_EX | LOCK_NB);
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (!is_resource($this->fileHandle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->close();
|
||||
}
|
||||
|
||||
protected static function constructFileMode(int $mode): string
|
||||
{
|
||||
$mode_read = ($mode & static::MODE_READ) > 0;
|
||||
$mode_write = ($mode & static::MODE_WRITE) > 0;
|
||||
$mode_truncate = ($mode & static::MODE_TRUNCATE_RAW) > 0;
|
||||
$mode_append = ($mode & static::MODE_APPEND_RAW) > 0;
|
||||
|
||||
// why would you ever
|
||||
if ($mode_append && $mode_truncate) {
|
||||
throw new IOException("Can't append and truncate at the same time.");
|
||||
}
|
||||
|
||||
if (($mode_append || $mode_truncate) && !$mode_write) {
|
||||
throw new IOException("Can't append or truncate without write privileges.");
|
||||
}
|
||||
|
||||
$mode_string = '';
|
||||
|
||||
if ($mode_append) {
|
||||
$mode_string = 'a';
|
||||
} elseif ($mode_truncate) {
|
||||
$mode_string = 'w';
|
||||
} elseif ($mode_write) {
|
||||
$mode_string = 'c';
|
||||
}
|
||||
|
||||
$mode_string .= 'b';
|
||||
|
||||
if ($mode_read) {
|
||||
if (strlen($mode_string) < 2) {
|
||||
$mode_string = 'r' . $mode_string;
|
||||
} else {
|
||||
$mode_string .= '+';
|
||||
}
|
||||
}
|
||||
|
||||
// should be at least two characters because of the b flag
|
||||
if (strlen($mode_string) < 2) {
|
||||
throw IOException('Failed to construct mode???');
|
||||
}
|
||||
|
||||
return $mode_string;
|
||||
}
|
||||
|
||||
public function getResource(): resource
|
||||
{
|
||||
$this->ensureHandleActive();
|
||||
return $this->fileHandle;
|
||||
}
|
||||
|
||||
protected function ensureHandleActive(): void
|
||||
{
|
||||
if (!is_resource($this->fileHandle)) {
|
||||
throw new IOException("No active file handle.");
|
||||
}
|
||||
}
|
||||
|
||||
protected function ensureCanRead(): void
|
||||
{
|
||||
if (!$this->getCanRead()) {
|
||||
throw new IOException('This stream cannot perform read operations.');
|
||||
}
|
||||
}
|
||||
|
||||
protected function ensureCanWrite(): void
|
||||
{
|
||||
if (!$this->getCanWrite()) {
|
||||
throw new IOException('This stream cannot perform write operations.');
|
||||
}
|
||||
}
|
||||
|
||||
protected function ensureCanSeek(): void
|
||||
{
|
||||
if (!$this->getCanSeek()) {
|
||||
throw new IOException('This stream cannot perform seek operations.');
|
||||
}
|
||||
}
|
||||
|
||||
protected function getCanRead(): bool
|
||||
{
|
||||
return ($this->fileMode & static::MODE_READ) > 0 && is_readable($this->filePath);
|
||||
}
|
||||
|
||||
protected function getCanSeek(): bool
|
||||
{
|
||||
return ($this->fileMode & static::MODE_APPEND_RAW) == 0 && $this->getCanRead();
|
||||
}
|
||||
|
||||
protected function getCanTimeout(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getCanWrite(): bool
|
||||
{
|
||||
return ($this->fileMode & static::MODE_WRITE) > 0 && is_writable($this->filePath);
|
||||
}
|
||||
|
||||
protected function getLength(): int
|
||||
{
|
||||
$this->ensureHandleActive();
|
||||
return fstat($this->fileHandle)['size'];
|
||||
}
|
||||
|
||||
protected function getPosition(): int
|
||||
{
|
||||
$this->ensureHandleActive();
|
||||
return ftell($this->fileHandle);
|
||||
}
|
||||
|
||||
protected function getReadTimeout(): int
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected function getWriteTimeout(): int
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function flush(): void
|
||||
{
|
||||
$this->ensureHandleActive();
|
||||
fflush($this->fileHandle);
|
||||
}
|
||||
|
||||
public function close(): void
|
||||
{
|
||||
$this->ensureHandleActive();
|
||||
|
||||
if ($this->isLocked) {
|
||||
flock($this->fileHandle, LOCK_UN | LOCK_NB);
|
||||
}
|
||||
|
||||
fclose($this->fileHandle);
|
||||
}
|
||||
|
||||
public function read(int $length): string
|
||||
{
|
||||
$this->ensureHandleActive();
|
||||
$this->ensureCanRead();
|
||||
|
||||
$read = fread($this->fileHandle, $length);
|
||||
|
||||
if ($read === false) {
|
||||
throw new IOException('Read failed.');
|
||||
}
|
||||
|
||||
return $read;
|
||||
}
|
||||
|
||||
public function readChar(): int
|
||||
{
|
||||
$this->ensureHandleActive();
|
||||
return ord(fgetc($this->fileHandle));
|
||||
}
|
||||
|
||||
public function write(string $data): int
|
||||
{
|
||||
$this->ensureHandleActive();
|
||||
$this->ensureCanWrite();
|
||||
|
||||
$write = fwrite($this->fileHandle, $data);
|
||||
|
||||
if ($write === false) {
|
||||
throw new IOException('Write failed.');
|
||||
}
|
||||
|
||||
return $write;
|
||||
}
|
||||
|
||||
public function writeChar(int $char): void
|
||||
{
|
||||
$this->ensureHandleActive();
|
||||
$this->write(chr($char), 0, 1);
|
||||
}
|
||||
|
||||
public function seek(int $offset, int $origin): void
|
||||
{
|
||||
$this->ensureHandleActive();
|
||||
$this->ensureCanSeek();
|
||||
|
||||
switch ($origin) {
|
||||
case Stream::ORIGIN_BEGIN:
|
||||
$origin = SEEK_SET;
|
||||
break;
|
||||
|
||||
case Stream::ORIGIN_END:
|
||||
$origin = SEEK_END;
|
||||
break;
|
||||
|
||||
case Stream::ORIGIN_CURRENT:
|
||||
$origin = SEEK_CUR;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IOException('Invalid seek origin.');
|
||||
}
|
||||
|
||||
if (fseek($this->fileHandle, $offset, $origin) !== 0) {
|
||||
throw new IOException('Seek operation failed.');
|
||||
}
|
||||
}
|
||||
}
|
40
src/IO/Stream.php
Normal file
40
src/IO/Stream.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
namespace Misuzu\IO;
|
||||
|
||||
abstract class Stream
|
||||
{
|
||||
public const ORIGIN_CURRENT = 0;
|
||||
public const ORIGIN_BEGIN = 1;
|
||||
public const ORIGIN_END = 2;
|
||||
|
||||
public function __get(string $name)
|
||||
{
|
||||
$name = 'get' . ucfirst($name);
|
||||
|
||||
if (method_exists(static::class, $name)) {
|
||||
return $this->{$name}();
|
||||
}
|
||||
|
||||
// todo: specialised exception type
|
||||
throw new IOException('Invalid property.');
|
||||
}
|
||||
|
||||
abstract protected function getCanRead(): bool;
|
||||
abstract protected function getCanSeek(): bool;
|
||||
abstract protected function getCanTimeout(): bool;
|
||||
abstract protected function getCanWrite(): bool;
|
||||
abstract protected function getLength(): int;
|
||||
abstract protected function getPosition(): int;
|
||||
abstract protected function getReadTimeout(): int;
|
||||
abstract protected function getWriteTimeout(): int;
|
||||
|
||||
abstract public function flush(): void;
|
||||
abstract public function close(): void;
|
||||
abstract public function seek(int $offset, int $origin): void;
|
||||
|
||||
abstract public function read(int $length): string;
|
||||
abstract public function readChar(): int;
|
||||
|
||||
abstract public function write(string $data): int;
|
||||
abstract public function writeChar(int $char): void;
|
||||
}
|
|
@ -40,9 +40,9 @@ class Zalgo
|
|||
public const ZALGO_MODE_MAX = 3;
|
||||
|
||||
private const ZALGO_MODES = [
|
||||
ZALGO_MODE_MINI,
|
||||
ZALGO_MODE_NORMAL,
|
||||
ZALGO_MODE_MAX,
|
||||
self::ZALGO_MODE_MINI,
|
||||
self::ZALGO_MODE_NORMAL,
|
||||
self::ZALGO_MODE_MAX,
|
||||
];
|
||||
|
||||
public const ZALGO_DIR_UP = 0x1;
|
||||
|
@ -105,7 +105,7 @@ class Zalgo
|
|||
}
|
||||
|
||||
$str .= $char;
|
||||
|
||||
|
||||
switch ($mode) {
|
||||
case self::ZALGO_MODE_MINI:
|
||||
$num_up = mt_rand(0, 8);
|
||||
|
@ -129,9 +129,11 @@ class Zalgo
|
|||
if ($going_up) {
|
||||
$str .= self::getZalgo(self::ZALGO_CHARS_UP, $num_up);
|
||||
}
|
||||
|
||||
if ($going_mid) {
|
||||
$str .= self::getZalgo(self::ZALGO_CHARS_MIDDLE, $num_mid);
|
||||
}
|
||||
|
||||
if ($going_down) {
|
||||
$str .= self::getZalgo(self::ZALGO_CHARS_DOWN, $num_down);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace MisuzuTests;
|
|||
use PHPUnit\Framework\TestCase;
|
||||
use Misuzu\IO\Directory;
|
||||
use Misuzu\IO\File;
|
||||
use Misuzu\IO\FileStream;
|
||||
|
||||
define('WORKING_DIR', sys_get_temp_dir() . '/MisuzuFileSystemTest' . time());
|
||||
|
||||
|
@ -34,48 +35,48 @@ class FileSystemTest extends TestCase
|
|||
|
||||
public function testCreateFile()
|
||||
{
|
||||
$file = new File(WORKING_DIR . '/file', File::CREATE_READ_WRITE);
|
||||
$this->assertInstanceOf(File::class, $file);
|
||||
$file = File::open(WORKING_DIR . '/file');
|
||||
$this->assertInstanceOf(FileStream::class, $file);
|
||||
$file->close();
|
||||
}
|
||||
|
||||
public function testWriteFile()
|
||||
{
|
||||
$file = new File(WORKING_DIR . '/file', File::OPEN_WRITE);
|
||||
$this->assertInstanceOf(File::class, $file);
|
||||
$file = new FileStream(WORKING_DIR . '/file', FileStream::MODE_TRUNCATE, false);
|
||||
$this->assertInstanceOf(FileStream::class, $file);
|
||||
|
||||
$file->write('misuzu');
|
||||
$this->assertEquals(6, $file->size);
|
||||
$this->assertEquals(6, $file->length);
|
||||
|
||||
$file->close();
|
||||
}
|
||||
|
||||
public function testAppendFile()
|
||||
{
|
||||
$file = new File(WORKING_DIR . '/file', File::OPEN_WRITE);
|
||||
$this->assertInstanceOf(File::class, $file);
|
||||
$file = new FileStream(WORKING_DIR . '/file', FileStream::MODE_APPEND);
|
||||
$this->assertInstanceOf(FileStream::class, $file);
|
||||
|
||||
$file->append(' test');
|
||||
$this->assertEquals(11, $file->size);
|
||||
$file->write(' test');
|
||||
$this->assertEquals(11, $file->length);
|
||||
|
||||
$file->close();
|
||||
}
|
||||
|
||||
public function testPosition()
|
||||
{
|
||||
$file = new File(WORKING_DIR . '/file', File::OPEN_READ);
|
||||
$this->assertInstanceOf(File::class, $file);
|
||||
$file = new FileStream(WORKING_DIR . '/file', FileStream::MODE_READ);
|
||||
$this->assertInstanceOf(FileStream::class, $file);
|
||||
|
||||
$file->start();
|
||||
$file->seek(0, FileStream::ORIGIN_BEGIN);
|
||||
$this->assertEquals(0, $file->position);
|
||||
|
||||
$file->end();
|
||||
$this->assertEquals($file->size, $file->position);
|
||||
$file->seek(0, FileStream::ORIGIN_END);
|
||||
$this->assertEquals($file->length, $file->position);
|
||||
|
||||
$file->position(4);
|
||||
$file->seek(4, FileStream::ORIGIN_BEGIN);
|
||||
$this->assertEquals(4, $file->position);
|
||||
|
||||
$file->position(4, true);
|
||||
$file->seek(4, FileStream::ORIGIN_CURRENT);
|
||||
$this->assertEquals(8, $file->position);
|
||||
|
||||
$file->close();
|
||||
|
@ -83,34 +84,24 @@ class FileSystemTest extends TestCase
|
|||
|
||||
public function testRead()
|
||||
{
|
||||
$file = new File(WORKING_DIR . '/file', File::OPEN_READ);
|
||||
$this->assertInstanceOf(File::class, $file);
|
||||
$file = new FileStream(WORKING_DIR . '/file', FileStream::MODE_READ);
|
||||
$this->assertInstanceOf(FileStream::class, $file);
|
||||
|
||||
$this->assertEquals('misuzu test', $file->read());
|
||||
$this->assertEquals('misuzu test', $file->read($file->length));
|
||||
|
||||
$file->position(7);
|
||||
$this->assertEquals('test', $file->read());
|
||||
|
||||
$file->close();
|
||||
}
|
||||
|
||||
public function testFind()
|
||||
{
|
||||
$file = new File(WORKING_DIR . '/file', File::OPEN_READ);
|
||||
$this->assertInstanceOf(File::class, $file);
|
||||
|
||||
$this->assertEquals(7, $file->find('test'));
|
||||
$file->seek(7, FileStream::ORIGIN_BEGIN);
|
||||
$this->assertEquals('test', $file->read(4));
|
||||
|
||||
$file->close();
|
||||
}
|
||||
|
||||
public function testChar()
|
||||
{
|
||||
$file = new File(WORKING_DIR . '/file', File::OPEN_READ);
|
||||
$this->assertInstanceOf(File::class, $file);
|
||||
$file = new FileStream(WORKING_DIR . '/file', FileStream::MODE_READ);
|
||||
$this->assertInstanceOf(FileStream::class, $file);
|
||||
|
||||
$file->position(3);
|
||||
$this->assertEquals('s', $file->char());
|
||||
$file->seek(3, FileStream::ORIGIN_BEGIN);
|
||||
$this->assertEquals(ord('u'), $file->readChar());
|
||||
|
||||
$file->close();
|
||||
}
|
||||
|
|
|
@ -10,8 +10,19 @@ class ZalgoTest extends TestCase
|
|||
|
||||
public function testStrip()
|
||||
{
|
||||
$this->assertEquals(TEST_STRING, Zalgo::strip(Zalgo::run(TEST_STRING, Zalgo::ZALGO_MODE_MINI)));
|
||||
$this->assertEquals(TEST_STRING, Zalgo::strip(Zalgo::run(TEST_STRING, Zalgo::ZALGO_MODE_NORMAL)));
|
||||
$this->assertEquals(TEST_STRING, Zalgo::strip(Zalgo::run(TEST_STRING, Zalgo::ZALGO_MODE_MAX)));
|
||||
$this->assertEquals(
|
||||
static::TEST_STRING,
|
||||
Zalgo::strip(Zalgo::run(static::TEST_STRING, Zalgo::ZALGO_MODE_MINI))
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
static::TEST_STRING,
|
||||
Zalgo::strip(Zalgo::run(static::TEST_STRING, Zalgo::ZALGO_MODE_NORMAL))
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
static::TEST_STRING,
|
||||
Zalgo::strip(Zalgo::run(static::TEST_STRING, Zalgo::ZALGO_MODE_MAX))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue