Merge pull request #194 from zhamao-robot/add-tests

添加些许测试
This commit is contained in:
sunxyw 2022-12-23 22:56:33 +08:00 committed by GitHub
commit 1e037b9610
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 248 additions and 11 deletions

View File

@ -31,7 +31,9 @@
"require-dev": {
"brainmaestro/composer-git-hooks": "^3.0",
"friendsofphp/php-cs-fixer": "^3.2 != 3.7.0",
"jangregor/phpstan-prophecy": "^1.0",
"jetbrains/phpstorm-attributes": "^1.0",
"mikey179/vfsstream": "^1.6",
"phpspec/prophecy": "1.x-dev",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.1",

View File

@ -129,9 +129,6 @@ class FileSystem
$tokens = \PhpToken::tokenize(file_get_contents($path));
$found = false;
foreach ($tokens as $token) {
if (!$token instanceof \PhpToken) {
continue;
}
if ($token->is(T_CLASS)) {
$found = true;
break;

View File

@ -11,7 +11,7 @@ class CatCode
/**
* MessageSegment 转换为 CatCode 字符串
*/
public static function fromSegment(mixed $message_segment): string
public static function fromSegment(array|MessageSegment|string $message_segment): string
{
// 传入的必须是段数组或段对象
if (is_array($message_segment)) {
@ -24,13 +24,12 @@ class CatCode
}
return $str;
}
if ($message_segment instanceof MessageSegment) {
return self::segment2CatCode($message_segment);
}
if (is_string($message_segment)) {
return $message_segment;
}
return '';
return $message_segment;
}
/**

View File

@ -4,8 +4,10 @@ declare(strict_types=1);
namespace Tests\Trait;
use Prophecy\Argument;
use Prophecy\Prophet;
use Psr\Log\AbstractLogger;
use Psr\Log\LogLevel;
/**
* 模拟 Logger 行为
@ -36,9 +38,21 @@ trait HasLogger
private function startMockLogger(): void
{
$logger = $this->prophet->prophesize(AbstractLogger::class);
$logger->log()->will(function ($args) {
$this->mockLog(...$args);
});
$levels = [
LogLevel::EMERGENCY,
LogLevel::ALERT,
LogLevel::CRITICAL,
LogLevel::ERROR,
LogLevel::WARNING,
LogLevel::NOTICE,
LogLevel::INFO,
LogLevel::DEBUG,
];
$log_it = fn (...$args) => $this->mockLog(...$args);
foreach ($levels as $level) {
$logger->{$level}(Argument::type('string'), Argument::any())->will(fn ($args) => $log_it($level, ...$args));
}
$logger->log(Argument::in($levels), Argument::type('string'), Argument::any())->will(fn ($args) => $log_it(...$args));
ob_logger_register($logger->reveal());
}
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Tests\Trait;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
trait HasVirtualFileSystem
{
private vfsStreamDirectory $vfs;
private function setUpVfs(string $dir = 'root'): void
{
$this->vfs = vfsStream::setup($dir);
}
}

View File

@ -0,0 +1,133 @@
<?php
declare(strict_types=1);
namespace Tests\ZM\Store;
use org\bovigo\vfs\vfsStream;
use Tests\TestCase;
use Tests\Trait\HasLogger;
use Tests\Trait\HasVirtualFileSystem;
use ZM\Store\FileSystem;
/**
* @internal
*/
class FileSystemTest extends TestCase
{
use HasVirtualFileSystem;
use HasLogger;
protected function setUp(): void
{
parent::setUp();
$this->setUpVfs();
$this->startMockLogger();
}
/**
* @dataProvider provideTestDetermineRelativePath
*/
public function testDetermineRelativePath(string $path, bool $expected): void
{
$this->assertSame($expected, FileSystem::isRelativePath($path));
}
public function provideTestDetermineRelativePath(): array
{
return [
'relative' => ['relative/path', true],
'absolute' => ['/absolute/path', false],
'windows' => ['C:\Windows', !(DIRECTORY_SEPARATOR === '\\')],
];
}
public function testCreateDirectoryWithNoPerm(): void
{
$old_perm = $this->vfs->getPermissions();
$this->vfs->chmod(0000);
$this->assertFalse($this->vfs->hasChild('test'));
$this->expectExceptionMessageMatches('/无法建立目录/');
FileSystem::createDir($this->vfs->url() . '/test');
$this->vfs->chmod($old_perm);
}
public function testCreateDirectory(): void
{
$this->assertFalse($this->vfs->hasChild('test'));
FileSystem::createDir($this->vfs->url() . '/test');
$this->assertTrue($this->vfs->hasChild('test'));
}
public function testGetReloadableFiles(): void
{
$files = FileSystem::getReloadableFiles();
$this->assertIsArray($files);
$this->assertNotEmpty($files);
}
public function testGetClassesPsr4(): void
{
vfsStream::create([
'Foo' => [
'Bar.php' => '<?php namespace Foo; class Bar {}',
'Baz.php' => '<?php namespace Foo; class Baz {}',
'Qux' => [
'Quux.php' => '<?php namespace Bar\Qux; class Quux {}',
],
],
'Chore' => [
'global.php' => '<?php function global_function() {}',
'global_classes.php' => '<?php class GlobalClass {}',
],
'Baz.php.ignore' => '',
], $this->vfs);
$classes = FileSystem::getClassesPsr4($this->vfs->url(), '');
$this->assertSame([
'\Foo\Bar',
'\Foo\Qux\Quux',
], $classes);
}
public function testGetClassesPsr4WithCustomRule(): void
{
vfsStream::create([
'Foo' => [
'Bar.php' => '<?php namespace Foo; class Bar {}',
'Baz.php' => '<?php namespace Foo; class Baz {}',
],
], $this->vfs);
$classes = FileSystem::getClassesPsr4($this->vfs->url(), '', fn (string $dir, array $pathinfo) => $pathinfo['filename'] === 'Bar');
$this->assertSame(['\Foo\Bar'], $classes);
}
public function testGetClassesPsr4WithReturnPath(): void
{
vfsStream::create([
'Foo' => [
'Bar.php' => '<?php namespace Foo; class Bar {}',
'Baz.php' => '<?php namespace Foo; class Baz {}',
],
], $this->vfs);
$classes = FileSystem::getClassesPsr4($this->vfs->url(), '', return_path_value: 'my_path');
$this->assertSame([
'\Foo\Bar' => 'my_path/Foo/Bar.php',
'\Foo\Baz' => 'my_path/Foo/Baz.php',
], $classes);
}
public function testScanDirFilesWithNotExistsDir(): void
{
FileSystem::scanDirFiles($this->vfs->url() . '/not_exists');
$this->assertLogged('warning', zm_internal_errcode('E00080') . '扫描目录失败,目录不存在');
}
public function testScanDirFilesWithNoPerm(): void
{
$old_perm = $this->vfs->getPermissions();
$this->vfs->chmod(0000);
FileSystem::scanDirFiles($this->vfs->url());
$this->assertLogged('warning', zm_internal_errcode('E00080') . '扫描目录失败,目录无法读取: ' . $this->vfs->url());
$this->vfs->chmod($old_perm);
}
}

View File

@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
namespace Tests\ZM\Utils;
use OneBot\V12\Object\MessageSegment;
use Tests\TestCase;
use ZM\Utils\CatCode;
/**
* @internal
*/
class CatCodeTest extends TestCase
{
/**
* @dataProvider provideTestConvertFromSegment
*/
public function testConvertFromSegment(mixed $segment, string $expected): void
{
$this->assertSame($expected, CatCode::fromSegment($segment));
}
public function provideTestConvertFromSegment(): array
{
return [
'string' => ['[CatCode:mention,user_id=123456789]', '[CatCode:mention,user_id=123456789]'],
'segment instance' => [new MessageSegment('mention', ['user_id' => '123456789']), '[CatCode:mention,user_id=123456789]'],
'multiple segment instance' => [
[
new MessageSegment('mention', ['user_id' => '123456789']),
new MessageSegment('text', ['text' => 'Hello']),
],
'[CatCode:mention,user_id=123456789]Hello',
],
'array contains non-segment' => [
[
new MessageSegment('mention', ['user_id' => '123456789']),
'Hello',
],
'',
],
];
}
/**
* @dataProvider provideTestEscapeText
*/
public function testEscapeText(string $text): void
{
$encoded = CatCode::encode($text);
$decoded = CatCode::decode($encoded);
$this->assertSame($text, $decoded);
}
public function provideTestEscapeText(): array
{
return [
["前缀是'['后缀是']', 还有以及一个特殊的&"],
["[前缀是'['后缀是']', 还有以及一个特殊的&"],
["前缀是'['后缀是']', 还有以及一个特殊的"],
["&前缀是'['后缀是']', 还有以及一个特殊的"],
["&前缀是'['后缀是']', 还有以及一个特殊的]"],
];
}
public function testEscapeTextForContent(): void
{
$text = "前缀是'['后缀是']', 还有以及一个特殊的&";
$encoded = CatCode::encode($text, true);
$decoded = CatCode::decode($encoded, true);
$this->assertSame($text, $decoded);
}
}