test: 添加AOT多项功能验证测试

pull/14/head
韩天峰 2 months ago
parent 934628e2c2
commit 7ccdd3add9
  1. 31
      tests/aot/array/array-diff-key-strict-dominators.phpt
  2. 31
      tests/aot/array/array-unique-values-reindex.phpt
  3. 61
      tests/aot/basic/repeatable-argv-parser.phpt
  4. 37
      tests/aot/class/dynamic-subclass-interface-check.phpt
  5. 47
      tests/aot/coalesce/assign-coalesce-instanceof-rhs.phpt
  6. 31
      tests/aot/control_flow/match-true-instanceof.phpt
  7. 23
      tests/aot/functions/array-unique-count-strict.phpt
  8. 81
      tests/aot/stdlib/array-accessible-countable-iterable.phpt

@ -0,0 +1,31 @@
--TEST--
array_keys after array_diff_key with integer block ids
--FILE--
<?php
function strict_dominators(array $dominators, int $block): array
{
return array_keys(array_diff_key($dominators[$block], [$block => true]));
}
function main(): void
{
$dominators = [
0 => [0 => true],
1 => [0 => true, 1 => true],
2 => [0 => true, 1 => true, 2 => true],
];
var_dump(strict_dominators($dominators, 0));
var_dump(strict_dominators($dominators, 2));
}
?>
--EXPECT--
array(0) {
}
array(2) {
[0]=>
int(0)
[1]=>
int(1)
}

@ -0,0 +1,31 @@
--TEST--
array_values reindexes array_unique result
--FILE--
<?php
function unique_defs(array $defs): array
{
return array_values(array_unique($defs));
}
function main(): void
{
var_dump(unique_defs(['a', 'b', 'a', 'c', 'b']));
var_dump(unique_defs([2 => 'x', 5 => 'x', 9 => 'y']));
}
?>
--EXPECT--
array(3) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
}
array(2) {
[0]=>
string(1) "x"
[1]=>
string(1) "y"
}

@ -0,0 +1,61 @@
--TEST--
repeatable argv parser with separated equals and compact short flags
--FILE--
<?php
function is_long_flag_with_equals(string $arg, array $flags, array &$values): bool
{
foreach ($flags as $flag) {
if (str_starts_with($arg, $flag . '=')) {
$values[] = substr($arg, strlen($flag) + 1);
return true;
}
}
return false;
}
function parse_repeatable_argv(array $argv, array $flags): array
{
$values = [];
for ($i = 1; $i < count($argv); $i++) {
if (in_array($argv[$i], $flags, true) && isset($argv[$i + 1]) && $argv[$i + 1] !== '' && $argv[$i + 1][0] !== '-') {
$values[] = $argv[$i + 1];
$i++;
} elseif (!is_long_flag_with_equals($argv[$i], $flags, $values)) {
foreach ($flags as $flag) {
if (strlen($flag) === 2 && $flag[0] === '-') {
$short = substr($flag, 1);
if (preg_match('/^-' . preg_quote($short, '/') . '(.+)$/', $argv[$i], $m)) {
$values[] = $m[1];
}
}
}
}
}
return $values;
}
function main(): void
{
$argv = [
'compiler.php',
'-I', 'include',
'--include-path=/opt/include',
'-Irelative',
'-I', '-not-a-value',
'--include-path', '',
'--other', 'skip',
];
var_dump(parse_repeatable_argv($argv, ['-I', '--include-path']));
}
?>
--EXPECT--
array(3) {
[0]=>
string(7) "include"
[1]=>
string(12) "/opt/include"
[2]=>
string(8) "relative"
}

@ -0,0 +1,37 @@
--TEST--
dynamic is_subclass_of and class_implements checks
--FILE--
<?php
interface DynamicContract {}
class DynamicBase {}
class DynamicImpl extends DynamicBase implements DynamicContract {}
function check_subclass(string|object $value, string $class): bool
{
return is_subclass_of($value, $class);
}
function check_implements(string|object $value, string $interface): bool
{
return in_array($interface, class_implements($value));
}
function main(): void
{
var_dump(check_subclass(DynamicImpl::class, DynamicBase::class));
var_dump(check_subclass(new DynamicImpl(), DynamicBase::class));
var_dump(check_subclass(DynamicBase::class, DynamicImpl::class));
var_dump(check_implements(DynamicImpl::class, DynamicContract::class));
var_dump(check_implements(new DynamicImpl(), DynamicContract::class));
var_dump(check_implements(DynamicBase::class, DynamicContract::class));
}
?>
--EXPECT--
bool(true)
bool(true)
bool(false)
bool(true)
bool(true)
bool(false)

@ -0,0 +1,47 @@
--TEST--
null coalescing assignment with instanceof boolean expression rhs
--FILE--
<?php
class CoalescePlatform
{
public function enabled(): bool
{
echo "enabled\n";
return true;
}
}
function ensure_option(array &$options, object $platform): void
{
$options['is_zts'] ??= $platform instanceof CoalescePlatform && $platform->enabled();
}
function main(): void
{
$options = [];
ensure_option($options, new CoalescePlatform());
var_dump($options);
ensure_option($options, new CoalescePlatform());
var_dump($options);
$options = [];
ensure_option($options, new stdClass());
var_dump($options);
}
?>
--EXPECT--
enabled
array(1) {
["is_zts"]=>
bool(true)
}
array(1) {
["is_zts"]=>
bool(true)
}
array(1) {
["is_zts"]=>
bool(false)
}

@ -0,0 +1,31 @@
--TEST--
match true with instanceof conditions
--FILE--
<?php
class MatchTrueBase {}
class MatchTrueChild extends MatchTrueBase {}
function describe_value(mixed $value): string
{
return match (true) {
$value instanceof MatchTrueChild => 'child',
$value instanceof MatchTrueBase => 'base',
is_string($value) => 'string:' . $value,
default => 'other',
};
}
function main(): void
{
var_dump(describe_value(new MatchTrueChild()));
var_dump(describe_value(new MatchTrueBase()));
var_dump(describe_value('x'));
var_dump(describe_value(42));
}
?>
--EXPECT--
string(5) "child"
string(4) "base"
string(8) "string:x"
string(5) "other"

@ -0,0 +1,23 @@
--TEST--
count array_unique result for duplicate detection
--FILE--
<?php
function duplicate_count(array $values): int
{
$allValues = count($values);
$uniqueValues = count(array_unique($values));
return $allValues - $uniqueValues;
}
function main(): void
{
var_dump(duplicate_count(['a', 'b', 'a', 'c', 'b']));
var_dump(duplicate_count([1, '1', true, 2]));
var_dump(duplicate_count([]));
}
?>
--EXPECT--
int(2)
int(2)
int(0)

@ -0,0 +1,81 @@
--TEST--
array or interface object checks for accessible countable iterable values
--FILE--
<?php
class AccessCountIterator implements ArrayAccess, Countable, IteratorAggregate
{
private array $items = ['a' => 1, 'b' => 2];
public function offsetExists(mixed $offset): bool
{
return isset($this->items[$offset]);
}
public function offsetGet(mixed $offset): mixed
{
return $this->items[$offset];
}
public function offsetSet(mixed $offset, mixed $value): void
{
$this->items[$offset] = $value;
}
public function offsetUnset(mixed $offset): void
{
unset($this->items[$offset]);
}
public function count(): int
{
return count($this->items);
}
public function getIterator(): Traversable
{
return new ArrayIterator($this->items);
}
}
function check_value(mixed $value): array
{
return [
is_array($value) || $value instanceof ArrayAccess,
is_array($value) || $value instanceof Countable,
is_array($value) || $value instanceof Traversable,
];
}
function main(): void
{
var_dump(check_value(['x']));
var_dump(check_value(new AccessCountIterator()));
var_dump(check_value(new stdClass()));
}
?>
--EXPECT--
array(3) {
[0]=>
bool(true)
[1]=>
bool(true)
[2]=>
bool(true)
}
array(3) {
[0]=>
bool(true)
[1]=>
bool(true)
[2]=>
bool(true)
}
array(3) {
[0]=>
bool(false)
[1]=>
bool(false)
[2]=>
bool(false)
}
Loading…
Cancel
Save