Test coverage
This commit is contained in:
parent
0ed7a34948
commit
99c5ac9697
20
phpunit.xml
Normal file
20
phpunit.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
colors="true"
|
||||
stopOnFailure="false"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true"
|
||||
>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
<testsuites>
|
||||
<testsuite name="PHPKilo">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<logging>
|
||||
<log type="coverage-html" target="coverage"/>
|
||||
</logging>
|
||||
</phpunit>
|
@ -6,6 +6,8 @@ namespace Aviat\Kilo\Enum;
|
||||
* Just a namespace for C language constants
|
||||
*/
|
||||
class C {
|
||||
use ConstList;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// ! Misc I/O constants
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -6,6 +6,8 @@ namespace Aviat\Kilo\Enum;
|
||||
* ANSI Color escape sequences
|
||||
*/
|
||||
class Color {
|
||||
use ConstList;
|
||||
|
||||
// Foreground colors
|
||||
public const FG_BLACK = 30;
|
||||
public const FG_RED = 31;
|
||||
|
12
src/Enum/ConstList.php
Normal file
12
src/Enum/ConstList.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Aviat\Kilo\Enum;
|
||||
|
||||
use ReflectionClass;
|
||||
|
||||
trait ConstList {
|
||||
public static function getConstList(): array
|
||||
{
|
||||
return (new ReflectionClass(static::class))->getConstants();
|
||||
}
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
namespace Aviat\Kilo\Enum;
|
||||
|
||||
class Highlight {
|
||||
use ConstList;
|
||||
|
||||
public const NORMAL = 0;
|
||||
public const COMMENT = 1;
|
||||
public const ML_COMMENT = 2;
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace Aviat\Kilo\Enum;
|
||||
|
||||
use ReflectionClass;
|
||||
|
||||
class Key {
|
||||
use ConstList;
|
||||
|
||||
public const ARROW_DOWN = 'ARROW_DOWN';
|
||||
public const ARROW_LEFT = 'ARROW_LEFT';
|
||||
public const ARROW_RIGHT = 'ARROW_RIGHT';
|
||||
@ -17,9 +17,4 @@ class Key {
|
||||
public const HOME_KEY = 'HOME';
|
||||
public const PAGE_DOWN = 'PAGE_DOWN';
|
||||
public const PAGE_UP = 'PAGE_UP';
|
||||
|
||||
public static function getConstList(): array
|
||||
{
|
||||
return (new ReflectionClass(static::class))->getConstants();
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ use Aviat\Kilo\Enum\{
|
||||
|
||||
/**
|
||||
* @TODO fix
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
function get_cursor_position()
|
||||
{
|
||||
@ -37,6 +38,12 @@ function get_cursor_position()
|
||||
return [$rows, $cols];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the current terminal window
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
function get_window_size()
|
||||
{
|
||||
$ffi = get_ffi();
|
||||
@ -103,7 +110,7 @@ function is_ascii(string $single_char): bool
|
||||
function is_cntrl(string $char): bool
|
||||
{
|
||||
$c = ord($char);
|
||||
return is_ascii($char) && ( $c < 0x20 || $c === 0x7f );
|
||||
return is_ascii($char) && ( $c === 0x7f || $c < 0x20 );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,6 +181,7 @@ function is_separator(string $char): bool
|
||||
/**
|
||||
* Pull input from the stdin stream.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @param int $len
|
||||
* @return string
|
||||
*/
|
||||
@ -189,6 +197,7 @@ function read_stdin(int $len = 128): string
|
||||
/**
|
||||
* Write to the stdout stream
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @param string $str
|
||||
* @param int|NULL $len
|
||||
* @return int
|
||||
@ -205,6 +214,11 @@ function write_stdout(string $str, int $len = NULL): int
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @param int $len
|
||||
* @return string
|
||||
*/
|
||||
function read_stdout(int $len = 128): string
|
||||
{
|
||||
$handle = fopen('php://stdout', 'rb');
|
||||
@ -234,14 +248,16 @@ function array_replace_range(array &$array, int $offset, int $length, $value):vo
|
||||
|
||||
$replacement = array_fill(0, $length, $value);
|
||||
array_splice($array, $offset, $length, $replacement);
|
||||
|
||||
/* $end = $offset + $length;
|
||||
for ($i = $offset; $i < $end; $i++)
|
||||
{
|
||||
$array[$i] = $value;
|
||||
} */
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the string $haystack contain $str, optionally searching from $offset?
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string $str
|
||||
* @param int|null $offset
|
||||
* @return bool
|
||||
*/
|
||||
function str_contains(string $haystack, string $str, ?int $offset = NULL): bool
|
||||
{
|
||||
if (empty($str))
|
||||
|
25
tests/Enum/ConstListTest.php
Normal file
25
tests/Enum/ConstListTest.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Aviat\Kilo\Tests\Enum;
|
||||
|
||||
use Aviat\Kilo\Enum\ConstList;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ConstListTest extends TestCase {
|
||||
public function testGetConstList(): void
|
||||
{
|
||||
$testClass = new class {
|
||||
use ConstList;
|
||||
|
||||
public const foo = 'foo';
|
||||
public const bar = 'bar';
|
||||
};
|
||||
|
||||
$expected = [
|
||||
'foo' => 'foo',
|
||||
'bar' => 'bar',
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $testClass::getConstList());
|
||||
}
|
||||
}
|
@ -2,10 +2,22 @@
|
||||
|
||||
namespace Aviat\Kilo\Tests;
|
||||
|
||||
use Aviat\Kilo\Enum\Color;
|
||||
use Aviat\Kilo\Enum\Highlight;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
use function Aviat\Kilo\array_replace_range;
|
||||
use function Aviat\Kilo\ctrl_key;
|
||||
use function Aviat\Kilo\get_file_syntax_map;
|
||||
use function Aviat\Kilo\get_window_size;
|
||||
use function Aviat\Kilo\is_ascii;
|
||||
use function Aviat\Kilo\is_cntrl;
|
||||
use function Aviat\Kilo\is_digit;
|
||||
use function Aviat\Kilo\is_separator;
|
||||
use function Aviat\Kilo\is_space;
|
||||
use function Aviat\Kilo\str_contains;
|
||||
use function Aviat\Kilo\syntax_to_color;
|
||||
use function Aviat\Kilo\tabs_to_spaces;
|
||||
|
||||
class FunctionTest extends TestCase {
|
||||
public function test_get_window_size(): void
|
||||
@ -20,5 +32,125 @@ class FunctionTest extends TestCase {
|
||||
$this->assertFalse(is_ascii('©'));
|
||||
$this->assertFalse(is_ascii("\x80"));
|
||||
$this->assertTrue(is_ascii('a'));
|
||||
$this->assertTrue(is_ascii("\x7b"));
|
||||
}
|
||||
|
||||
public function test_ctrl_key(): void
|
||||
{
|
||||
$this->assertEquals(-1, ctrl_key("\x80"));
|
||||
|
||||
$this->assertEquals(0x01, ctrl_key('a'));
|
||||
}
|
||||
|
||||
public function test_is_cntrl(): void
|
||||
{
|
||||
for ($i = 0x0; $i < 0x20; $i++)
|
||||
{
|
||||
$char = chr($i);
|
||||
$this->assertTrue(is_cntrl($char), 'Should be a control character');
|
||||
}
|
||||
|
||||
for ($n = 0x20; $n < 0x7f; $n++)
|
||||
{
|
||||
$char = chr($n);
|
||||
$this->assertFalse(is_cntrl($char), 'Should not be a control character');
|
||||
}
|
||||
|
||||
// Escape, code 7f, is an outlier
|
||||
$this->assertTrue(is_cntrl(chr(0x7f)));
|
||||
}
|
||||
|
||||
public function test_is_space(): void
|
||||
{
|
||||
$this->assertFalse(is_space("\x80"), 'Non-ascii character is not considered a space');
|
||||
|
||||
foreach ([' ', "\t", "\n", "\r", "\xa", "\xb", "\xc"] as $char)
|
||||
{
|
||||
$this->assertTrue(is_space($char), 'Should be considered a space character');
|
||||
}
|
||||
}
|
||||
|
||||
public function test_is_digit(): void
|
||||
{
|
||||
$this->assertFalse(is_separator("\x80"), 'Non-ascii character is not a digit');
|
||||
|
||||
$digits = str_split('01234567890');
|
||||
foreach ($digits as $digit)
|
||||
{
|
||||
$this->assertTrue(is_digit($digit));
|
||||
}
|
||||
}
|
||||
|
||||
public function test_is_separator(): void
|
||||
{
|
||||
$this->assertFalse(is_separator("\x80"), 'Non-ascii character is not a separator');
|
||||
|
||||
$chars = str_split(',.()+-/*=~%<>[];');
|
||||
foreach ($chars as $char)
|
||||
{
|
||||
$this->assertTrue(is_separator($char), 'The character should be considered a separator');
|
||||
}
|
||||
|
||||
// Null byte is considered a separator
|
||||
$this->assertTrue(is_separator("\0"));
|
||||
}
|
||||
|
||||
public function test_syntax_to_color(): void
|
||||
{
|
||||
// Nonsense input returns FG::White
|
||||
$this->assertEquals(syntax_to_color(999), Color::FG_WHITE);
|
||||
|
||||
$this->assertNotEquals(syntax_to_color(Highlight::OPERATOR), Color::FG_WHITE);
|
||||
}
|
||||
|
||||
public function test_get_file_syntax_map(): void
|
||||
{
|
||||
$this->assertNotEmpty(get_file_syntax_map());
|
||||
}
|
||||
|
||||
public function test_str_contains(): void
|
||||
{
|
||||
// Search from string offset
|
||||
$this->assertTrue(str_contains(' vcd', 'vcd', 2));
|
||||
|
||||
$this->assertFalse(str_contains('', "\0"));
|
||||
|
||||
// An empty search string returns false
|
||||
$this->assertFalse(str_contains('', ''));
|
||||
|
||||
$this->assertTrue(str_contains('alphabet', 'phab'));
|
||||
}
|
||||
|
||||
public function test_tabs_to_spaces(): void
|
||||
{
|
||||
$original = "\t\t\t{";
|
||||
$this->assertFalse(str_contains(tabs_to_spaces($original), "\t"));
|
||||
}
|
||||
|
||||
public function test_array_replace_range_length_1(): void
|
||||
{
|
||||
$original = [
|
||||
'a', 'b', 'c', 'd', 'e', 'f'
|
||||
];
|
||||
|
||||
$expected = ['a', 'b', 'c', 'foo', 'e', 'f'];
|
||||
|
||||
array_replace_range($original, 3, 1, 'foo');
|
||||
|
||||
$this->assertEquals($expected, $original);
|
||||
}
|
||||
|
||||
public function test_array_replace_range_length_gt_1(): void
|
||||
{
|
||||
$original = [
|
||||
'a', 'b', 'c', 'd', 'e', 'f'
|
||||
];
|
||||
|
||||
$expected = [
|
||||
'a', 'foo', 'foo', 'foo', 'e', 'f'
|
||||
];
|
||||
|
||||
array_replace_range($original, 1, 3, 'foo');
|
||||
$this->assertEquals($expected, $original);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user