refactor phpunit-swoole to phpunit-zm and move old test cases

This commit is contained in:
crazywhalecc
2022-08-20 17:49:33 +08:00
parent cecdb1681c
commit 4ba74e9f3e
23 changed files with 188 additions and 128 deletions

View File

@@ -0,0 +1,71 @@
<?php
declare(strict_types=1);
namespace Tests\ZM\Utils;
use PHPUnit\Framework\TestCase;
use ZM\Annotation\CQ\CommandArgument;
use ZM\Annotation\CQ\CQCommand;
use ZM\Event\EventManager;
use ZM\Utils\CommandInfoUtil;
/**
* @internal
*/
class CommandInfoUtilTest extends TestCase
{
/**
* @var CommandInfoUtil
*/
private static $util;
/**
* @var string
*/
private static $command_id;
public static function setUpBeforeClass(): void
{
$cmd = new CQCommand('测试命令');
$cmd->class = self::class;
$cmd->method = __FUNCTION__;
$args = [
new CommandArgument('文本', '一个神奇的文本', 'string', true),
new CommandArgument('数字', '一个神奇的数字', 'int', false, '', '233'),
];
self::$command_id = "{$cmd->class}@{$cmd->method}";
EventManager::$events[CQCommand::class] = [];
EventManager::$event_map = [];
EventManager::addEvent(CQCommand::class, $cmd);
EventManager::$event_map[$cmd->class][$cmd->method] = $args;
self::$util = resolve(CommandInfoUtil::class);
}
public function testGet(): void
{
$commands = self::$util->get();
$this->assertIsArray($commands);
$this->assertCount(1, $commands);
$this->assertArrayHasKey(self::$command_id, $commands);
}
public function testGetHelp(): void
{
$help = self::$util->getHelp(self::$command_id);
$this->assertIsString($help);
$this->assertNotEmpty($help);
$expected = <<<'EOF'
测试命令 <文本: string> [数字: number = 233]
作者很懒,啥也没说
文本;一个神奇的文本
数字;一个神奇的数字
EOF;
$this->assertEquals($expected, $help);
}
}

View File

@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
namespace Tests\ZM\Utils;
use PHPUnit\Framework\TestCase;
use ZM\Utils\DataProvider;
/**
* @internal
*/
class DataProviderTest extends TestCase
{
public function testGetSourceRootDir(): void
{
$this->assertEquals(SOURCE_ROOT_DIR, DataProvider::getSourceRootDir());
}
public function testGetDataFolder(): void
{
$this->assertEquals(SOURCE_ROOT_DIR . '/zm_data/', DataProvider::getDataFolder());
}
public function testGetResourceFolder(): void
{
$this->assertEquals(SOURCE_ROOT_DIR . '/resources/', DataProvider::getResourceFolder());
}
public function testScanDirFiles(): void
{
$files = DataProvider::scanDirFiles(SOURCE_ROOT_DIR . '/src/Module');
$this->assertContains(SOURCE_ROOT_DIR . '/src/Module/Example/Hello.php', $files);
}
public function testGetFrameworkRootDir(): void
{
$this->assertEquals(FRAMEWORK_ROOT_DIR, DataProvider::getFrameworkRootDir());
}
public function testGetWorkingDir(): void
{
$this->assertEquals(SOURCE_ROOT_DIR, DataProvider::getWorkingDir());
}
public function testSaveLoadJson(): void
{
$data = [
'a' => 1,
'b' => 2,
'c' => 3,
];
$file = 'test.json';
DataProvider::saveToJson($file, $data);
$this->assertEquals($data, DataProvider::loadFromJson($file));
}
public function testGetFrameworkLink(): void
{
$this->assertNotFalse(filter_var(DataProvider::getFrameworkLink(), FILTER_VALIDATE_URL));
}
public function testIsRelativePath(): void
{
$this->assertTrue(DataProvider::isRelativePath('./'));
$this->assertTrue(DataProvider::isRelativePath('../'));
$this->assertFalse(DataProvider::isRelativePath('/'));
$this->assertTrue(DataProvider::isRelativePath('test.php'));
}
}

View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace Tests\ZM\Utils;
use PHPUnit\Framework\TestCase;
use Swoole\Http\Request;
use Symfony\Component\Routing\RouteCollection;
use ZM\Annotation\Http\RequestMapping;
use ZM\Annotation\Http\RequestMethod;
use ZM\Utils\HttpUtil;
use ZM\Utils\Manager\RouteManager;
/**
* @internal
*/
class HttpUtilTest extends TestCase
{
public function providerTestHandleStaticPage(): array
{
return [
'exists page' => ['/static.html', true],
'not exists page' => ['/not_exists.html', false],
];
}
public function providerTestGetHttpCodePage(): array
{
return [
'code 404' => [404, true],
'code 500' => [500, false],
'code 403' => [403, false],
];
}
public function testParseUri(): void
{
RouteManager::$routes = new RouteCollection();
RouteManager::importRouteByAnnotation(
new RequestMapping('/test', 'test', RequestMethod::GET),
__FUNCTION__,
__CLASS__,
[]
);
$r = new Request();
$r->server['request_uri'] = '/test';
$r->server['request_method'] = 'GET';
$this->assertTrue(HttpUtil::parseUri(
$r,
null,
'/test',
$node,
$params
));
}
}

View File

@@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace Tests\ZM\Utils;
use PHPUnit\Framework\TestCase;
use ZM\Exception\MethodNotFoundException;
use ZM\Utils\Macroable;
/**
* @internal
*/
class MacroableTest extends TestCase
{
private $macroable;
protected function setUp(): void
{
$this->macroable = new class() {
use Macroable;
private $secret = 'secret';
private static function anotherSecret()
{
return 'another secret';
}
};
}
public function testMacroCanBeDefined(): void
{
$this->macroable::macro('getSecret', function () {
return $this->secret;
});
$this->assertEquals('secret', $this->macroable->getSecret());
}
public function testMacroCanBeDefinedStatically(): void
{
$this->macroable::macro('getSecret', static function () {
return 'static secret';
});
$this->assertEquals('static secret', $this->macroable::getSecret());
}
public function testMacroCanBeDefinedWithParameters(): void
{
$this->macroable::macro('getParam', function ($param) {
return $param;
});
$this->assertEquals('param', $this->macroable->getParam('param'));
}
public function testExceptionIsThrownWhenMacroIsNotDefined(): void
{
$this->expectException(MethodNotFoundException::class);
$this->macroable->unknownMacro();
}
}

View File

@@ -0,0 +1,176 @@
<?php
declare(strict_types=1);
namespace Tests\ZM\Utils;
use Exception;
use PHPUnit\Framework\TestCase;
use Throwable;
use ZM\Annotation\CQ\CQCommand;
use ZM\Event\EventManager;
use ZM\Utils\DataProvider;
use ZM\Utils\MessageUtil;
/**
* @internal
*/
class MessageUtilTest extends TestCase
{
/**
* @throws Exception
*/
public function testAddShortCommand(): void
{
EventManager::$events[CQCommand::class] = [];
MessageUtil::addShortCommand('test', 'test');
$this->assertCount(1, EventManager::$events[CQCommand::class]);
}
/**
* @dataProvider providerTestContainsImage
*/
public function testContainsImage(string $msg, bool $expected): void
{
$this->assertEquals($expected, MessageUtil::containsImage($msg));
}
public function providerTestContainsImage(): array
{
return [
'empty' => ['', false],
'text only' => ['hello world', false],
'image only' => ['[CQ:image,file=123456.jpg]', true],
'image' => ['hello world![CQ:image,file=123456.jpg]', true],
'two image' => ['hello world![CQ:image,file=123456.jpg][CQ:image,file=123456.jpg]', true],
// 'malformed image' => ['[CQ:image,file=]', false],
];
}
/**
* @dataProvider providerTestArrayToStr
*/
public function testArrayToStr(array $array, string $expected): void
{
$this->assertEquals($expected, MessageUtil::arrayToStr($array));
}
public function providerTestArrayToStr(): array
{
$tmp = $this->providerTestStrToArray();
$result = [];
foreach ($tmp as $desc => $case) {
$result[$desc] = [$case[1], $case[0]];
}
return $result;
}
public function testMatchCommand(): void
{
// 这里理论上需要覆盖所有条件,但先暂时这样好了
EventManager::$events[CQCommand::class] = [
new CQCommand('测试命令'),
];
$this->assertEquals(true, MessageUtil::matchCommand('测试命令', [
'user_id' => '123456',
'group_id' => '123456',
'message_type' => 'group',
])->status);
}
/**
* @dataProvider providerTestIsAtMe
*/
public function testIsAtMe(string $msg, bool $expected): void
{
$this->assertEquals($expected, MessageUtil::isAtMe($msg, 123456789));
}
public function providerTestIsAtMe(): array
{
return [
'me only' => ['[CQ:at,qq=123456789]', true],
'empty qq' => ['[CQ:at,qq=]', false],
'message behind' => ['[CQ:at,qq=123456789] hello', true],
'message front' => ['hello [CQ:at,qq=123456789]', true],
'message surround' => ['hello [CQ:at,qq=123456789] world', true],
'not at me' => ['hello world', false],
'other' => ['[CQ:at,qq=123456789] hello [CQ:at,qq=987654321]', true],
'other only' => ['[CQ:at,qq=987654321]', false],
];
}
public function testGetImageCQFromLocal(): void
{
file_put_contents('/tmp/test.jpg', 'test');
$this->assertEquals('[CQ:image,file=base64://' . base64_encode('test') . ']', MessageUtil::getImageCQFromLocal('/tmp/test.jpg'));
unlink('/tmp/test.jpg');
}
/**
* @dataProvider providerTestStrToArray
*/
public function testStrToArray(string $str, array $expected): void
{
$this->assertEquals($expected, MessageUtil::strToArray($str));
}
public function providerTestStrToArray(): array
{
$text = static function ($str): array {
return ['type' => 'text', 'data' => ['text' => $str]];
};
return [
'empty string' => ['', []],
'pure string' => ['foobar', [$text('foobar')]],
'spaced string' => ['hello world', [$text('hello world')]],
'spaced and multiline string' => ["hello\n world", [$text("hello\n world")]],
'string containing CQ' => ['[CQ:at,qq=123456789]', [['type' => 'at', 'data' => ['qq' => '123456789']]]],
];
}
/**
* @dataProvider providerTestSplitCommand
*/
public function testSplitCommand(string $msg, array $expected): void
{
$this->assertEquals($expected, MessageUtil::splitCommand($msg));
}
public function providerTestSplitCommand(): array
{
return [
'empty' => ['', ['']],
'spaced' => ['hello world', ['hello', 'world']],
'multiline' => ["hello\nworld", ['hello', 'world']],
'many spaces' => ['hello world', ['hello', 'world']],
'many spaces and multiline' => ["hello\n world", ['hello', 'world']],
'many parts' => ['hello world foo bar', ['hello', 'world', 'foo', 'bar']],
];
}
/**
* @throws Throwable
*/
public function testDownloadCQImage(): void
{
if (file_exists(DataProvider::getDataFolder('images') . '/test.png')) {
unlink(DataProvider::getDataFolder('images') . '/test.png');
}
$msg = '[CQ:image,file=test.png,url=https://zhamao.xin/file/hello.png]';
try {
$result = MessageUtil::downloadCQImage($msg);
$this->assertIsArray($result);
$this->assertCount(1, $result);
$this->assertFileExists(DataProvider::getDataFolder('images') . '/test.png');
unlink(DataProvider::getDataFolder('images') . '/test.png');
} catch (Throwable $e) {
if (strpos($e->getMessage(), 'enable-openssl') !== false) {
$this->markTestSkipped('OpenSSL is not enabled');
}
throw $e;
}
}
}

View File

@@ -0,0 +1,104 @@
<?php
declare(strict_types=1);
namespace Tests\ZM\Utils;
use Closure;
use PHPUnit\Framework\TestCase;
use ReflectionFunctionAbstract;
use ZM\Utils\ReflectionUtil;
/**
* @internal
*/
class ReflectionUtilTest extends TestCase
{
public function testDetermineStaticMethod(): void
{
$this->assertFalse(ReflectionUtil::isNonStaticMethod([ReflectionUtilTestClass::class, 'staticMethod']));
}
public function testDetermineNonStaticMethod(): void
{
$this->assertTrue(ReflectionUtil::isNonStaticMethod([ReflectionUtilTestClass::class, 'method']));
}
public function testGetParameterClassName(): void
{
$class = new \ReflectionClass(ReflectionUtilTestClass::class);
$method = $class->getMethod('method');
[$string_parameter, $object_parameter] = $method->getParameters();
$this->assertNull(ReflectionUtil::getParameterClassName($string_parameter));
$this->assertSame(ReflectionUtilTestClass::class, ReflectionUtil::getParameterClassName($object_parameter));
}
/**
* @dataProvider provideTestVariableToString
* @param mixed $variable
*/
public function testVariableToString($variable, string $expected): void
{
$this->assertSame($expected, ReflectionUtil::variableToString($variable));
}
public function provideTestVariableToString(): array
{
return [
'callable' => [[new ReflectionUtilTestClass(), 'method'], ReflectionUtilTestClass::class . '@method'],
'static callable' => [[ReflectionUtilTestClass::class, 'staticMethod'], ReflectionUtilTestClass::class . '::staticMethod'],
'closure' => [Closure::fromCallable([$this, 'testVariableToString']), 'closure'],
'string' => ['string', 'string'],
'array' => [['123', '42', 'hello', 122], 'array["123","42","hello",122]'],
'object' => [new \stdClass(), 'stdClass'],
'resource' => [fopen('php://memory', 'rb'), 'resource(stream)'],
'null' => [null, 'null'],
'boolean 1' => [true, 'true'],
'boolean 2' => [false, 'false'],
'float' => [123.456, '123.456'],
'integer' => [123, '123'],
];
}
/**
* @dataProvider provideTestGetCallReflector
* @param mixed $callback
*/
public function testGetCallReflector($callback, ReflectionFunctionAbstract $expected): void
{
$this->assertEquals($expected, ReflectionUtil::getCallReflector($callback));
}
public function provideTestGetCallReflector(): array
{
$closure = function () {
};
return [
'callable' => [[new ReflectionUtilTestClass(), 'method'], new \ReflectionMethod(ReflectionUtilTestClass::class, 'method')],
'static callable' => [[ReflectionUtilTestClass::class, 'staticMethod'], new \ReflectionMethod(ReflectionUtilTestClass::class, 'staticMethod')],
'class::method' => [ReflectionUtilTestClass::class . '::staticMethod', new \ReflectionMethod(ReflectionUtilTestClass::class, 'staticMethod')],
'invokable class' => [new InvokableClass(), new \ReflectionMethod(InvokableClass::class, '__invoke')],
'closure' => [$closure, new \ReflectionFunction($closure)],
];
}
}
class ReflectionUtilTestClass
{
public function method(string $string, ReflectionUtilTestClass $class): void
{
}
public static function staticMethod(string $string, ReflectionUtilTestClass $class): void
{
}
}
class InvokableClass
{
public function __invoke(): void
{
}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Tests\ZM\Utils;
use PHPUnit\Framework\TestCase;
use ZM\Utils\SingletonTrait;
/**
* @internal
*/
class SingletonTraitTest extends TestCase
{
public function testGetInstance(): void
{
$mock = $this->getObjectForTrait(SingletonTrait::class);
$this->assertEquals($mock, $mock::getInstance());
}
}

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Tests\ZM\Utils;
use PHPUnit\Framework\TestCase;
use Throwable;
use ZM\Console\Console;
use ZM\Utils\Terminal;
/**
* @internal
*/
class TerminalTest extends TestCase
{
public function testInit()
{
$this->markTestIncomplete('logger level change in need');
Console::setLevel(4);
Terminal::init();
Console::setLevel(0);
$this->expectOutputRegex('/Initializing\ Terminal/');
}
/**
* @throws Throwable
*/
public function testExecuteCommand()
{
$this->markTestIncomplete('logger level change in need');
Console::setLevel(2);
Terminal::executeCommand('echo zhamao-framework');
Console::setLevel(0);
$this->expectOutputRegex('/zhamao-framework/');
}
}