TypePHP 编译器 https://swoole.com/aot/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

291 lines
10 KiB

<?php
namespace TypePhp\Tests\Generator;
use TypePhp\Type;
use PHPUnit\Framework\TestCase;
use TypePhp\CompilerTest;
class UtilsTest extends TestCase
{
private string $testDir;
private CompilerTest $compiler;
protected function setUp(): void
{
parent::setUp();
$this->testDir = sys_get_temp_dir() . '/utils_test_' . uniqid();
mkdir($this->testDir, 0777, true);
$this->compiler = CompilerTest::create($this->testDir);
}
protected function tearDown(): void
{
parent::tearDown();
array_map('unlink', glob($this->testDir . '/*'));
rmdir($this->testDir);
}
private function invokeMethod(string $method, ...$args): mixed
{
$ref = new \ReflectionClass($this->compiler);
$meth = $ref->getMethod($method);
$meth->setAccessible(true);
return $meth->invoke($this->compiler, ...$args);
}
// ========================================================================
// genCValue
// ========================================================================
public function testGenCValueInt(): void
{
$this->assertSame($this->invokeMethod('genIntegerLiteral', 42), $this->invokeMethod('genCValue', 42));
$this->assertSame($this->invokeMethod('genIntegerLiteral', -1), $this->invokeMethod('genCValue', -1));
$this->assertSame($this->invokeMethod('genIntegerLiteral', 0), $this->invokeMethod('genCValue', 0));
}
public function testGenCValueFloat(): void
{
$result = $this->invokeMethod('genCValue', 3.14);
$this->assertSame((string) 3.14, $result);
}
public function testGenCValueBool(): void
{
$this->assertSame('1', $this->invokeMethod('genCValue', true));
$this->assertSame('0', $this->invokeMethod('genCValue', false));
}
public function testGenCValueString(): void
{
$result = $this->invokeMethod('genCValue', 'hello');
$this->assertEquals('"hello"', $result);
}
// ========================================================================
// genCharPtr
// ========================================================================
public function testGenCharPtr(): void
{
$this->assertEquals('"hello"', $this->invokeMethod('genCharPtr', 'hello'));
$this->assertEquals('""', $this->invokeMethod('genCharPtr', ''));
}
public function testGenCharPtrEscape(): void
{
$result = $this->invokeMethod('genCharPtr', 'hello "world"', true);
$this->assertStringContainsString('\\"', $result);
}
// ========================================================================
// genArray
// ========================================================================
public function testGenArray(): void
{
$result = $this->invokeMethod('genArray', ['1', '2', '3']);
$this->assertStringStartsWith(Type::ARRAY . '{', $result);
$this->assertStringContainsString('1, 2, 3', $result);
}
public function testGenArrayEmpty(): void
{
$result = $this->invokeMethod('genArray', []);
$this->assertStringStartsWith(Type::ARRAY . '{', $result);
}
// ========================================================================
// escapeString
// ========================================================================
public function testEscapeStringSimple(): void
{
$this->assertEquals('hello', $this->invokeMethod('escapeString', 'hello'));
}
public function testEscapeStringQuotes(): void
{
$result = $this->invokeMethod('escapeString', 'he"llo');
$this->assertStringContainsString('\\"', $result);
}
public function testEscapeStringBackslash(): void
{
$result = $this->invokeMethod('escapeString', 'a\\b');
$this->assertStringContainsString('\\\\', $result);
}
public function testEscapeStringNewline(): void
{
$result = $this->invokeMethod('escapeString', "a\nb");
// newline may be escaped as \n or literal depending on addcslashes behavior
$this->assertNotEquals("a\nb", $result);
}
// ========================================================================
// escapeBool
// ========================================================================
public function testEscapeBool(): void
{
$this->assertEquals('true', $this->invokeMethod('escapeBool', true));
$this->assertEquals('false', $this->invokeMethod('escapeBool', false));
}
// ========================================================================
// escapeVarName / unescapeVarName
// ========================================================================
public function testEscapeVarNameNormal(): void
{
$this->assertEquals('foo', $this->invokeMethod('escapeVarName', 'foo'));
$this->assertEquals('bar', $this->invokeMethod('escapeVarName', 'bar'));
}
public function testEscapeVarNameThis(): void
{
$this->assertEquals('this_', $this->invokeMethod('escapeVarName', 'this'));
}
public function testEscapeVarNameReservedKeyword(): void
{
// 'class' is in CPP_RESERVED_NAMES
$result = $this->invokeMethod('escapeVarName', 'class');
$this->assertStringStartsWith('_php__var__', $result);
}
public function testEscapeVarNameStdioMacros(): void
{
foreach (['stdin', 'stdout', 'stderr'] as $name) {
$this->assertEquals('_php__var__' . $name, $this->invokeMethod('escapeVarName', $name));
}
}
public function testUnescapeVarName(): void
{
$this->assertEquals('foo', $this->invokeMethod('unescapeVarName', '_php__var__foo'));
$this->assertEquals('bar', $this->invokeMethod('unescapeVarName', 'bar'));
}
// ========================================================================
// escapeNamespace
// ========================================================================
public function testEscapeNamespace(): void
{
$result = $this->invokeMethod('escapeNamespace', 'App\\Lib\\Module');
$this->assertEquals('app__lib__module', $result);
}
public function testEscapeNamespaceNoBackslash(): void
{
$result = $this->invokeMethod('escapeNamespace', 'app');
$this->assertEquals('app', $result);
}
// ========================================================================
// escapeZendFnName / escapeCeName
// ========================================================================
public function testEscapeZendFnNameLower(): void
{
$result = $this->invokeMethod('escapeZendFnName', 'App\\Foo\\bar', true);
$this->assertEquals('app_foo_bar', $result);
}
public function testEscapeZendFnNameNoLower(): void
{
$result = $this->invokeMethod('escapeZendFnName', 'App\\Foo\\bar', false);
$this->assertEquals('App_Foo_bar', $result);
}
public function testEscapeCeName(): void
{
$result = $this->invokeMethod('escapeCeName', 'App\\Entity\\User');
$this->assertEquals('App_Entity_User', $result);
}
// ========================================================================
// escapeName
// ========================================================================
public function testEscapeName(): void
{
$this->assertEquals('foo', $this->invokeMethod('escapeName', 'FOO'));
$this->assertEquals('bar', $this->invokeMethod('escapeName', 'BAR'));
}
// ========================================================================
// escapeClass / escapeFunction
// ========================================================================
public function testEscapeClass(): void
{
$result = $this->invokeMethod('escapeClass', '\\App\\Lib\\MyClass');
$this->assertEquals('app_lib_myclass', $result);
}
public function testEscapeFunction(): void
{
$result = $this->invokeMethod('escapeFunction', 'App\\Foo\\run');
$this->assertEquals('app_foo_run', $result);
}
// ========================================================================
// escapeFileName
// ========================================================================
public function testEscapeFileName(): void
{
$this->assertEquals('my_file', $this->invokeMethod('escapeFileName', 'my-file'));
$this->assertEquals('a_b_c', $this->invokeMethod('escapeFileName', 'a-b-c'));
}
public function testEscapeFileNameNoDash(): void
{
$this->assertEquals('already_good', $this->invokeMethod('escapeFileName', 'already_good'));
}
// ========================================================================
// escapeGlobalVar
// ========================================================================
public function testEscapeGlobalVar(): void
{
$result = $this->invokeMethod('escapeGlobalVar', 'myvar');
$this->assertStringStartsWith('_global_var_', $result);
$this->assertStringEndsWith('myvar', $result);
}
// ========================================================================
// isClosedExpr
// ========================================================================
public function testIsClosedExprSimple(): void
{
$this->assertTrue($this->invokeMethod('isClosedExpr', '(a + b)', ''));
$this->assertTrue($this->invokeMethod('isClosedExpr', '(1)', ''));
}
public function testIsClosedExprNotClosed(): void
{
$this->assertFalse($this->invokeMethod('isClosedExpr', 'a + b', ''));
$this->assertFalse($this->invokeMethod('isClosedExpr', '(a + b', ''));
}
public function testIsClosedExprNested(): void
{
$this->assertTrue($this->invokeMethod('isClosedExpr', '((a + b) * c)', ''));
}
public function testIsClosedExprWithCall(): void
{
$this->assertTrue($this->invokeMethod('isClosedExpr', 'foo(1, 2)', 'foo'));
$this->assertFalse($this->invokeMethod('isClosedExpr', 'bar(1, 2)', 'foo'));
}
}