test(aot): 添加迭代器和匹配表达式测试

- 修改generators.phpt使用exit替代echo进行跳过提示
- 新增iterators.phpt测试文件实现Iterator和IteratorAggregate接口
- 添加Range类测试基于生成器的迭代器聚合
- 实现FilterIterator类测试过滤功能
- 新增match-expression.phpt测试PHP8+匹配表达式功能
- 测试基本匹配、多重条件、严格比较和嵌套匹配场景
pull/1/head
韩天峰 5 months ago
parent 23f2fa48af
commit 8bf5c9c806
  1. 2
      tests/aot/generators.phpt
  2. 193
      tests/aot/iterators.phpt
  3. 121
      tests/aot/match-expression.phpt

@ -2,7 +2,7 @@
Generators - Yield keyword and generator functions
--SKIPIF--
<?php
echo "skip Generator syntax not supported in AOT";
exit("skip: Generator syntax not supported in AOT");
?>
--FILE--
<?php

@ -0,0 +1,193 @@
--TEST--
Iterable and Iterator - Custom iteration with Traversable
--SKIPIF--
<?php
exit("skip: Generator syntax not supported in AOT");
?>
--FILE--
<?php
// Test implementing Iterator interface
class NumberIterator implements Iterator {
private int $start;
private int $end;
private int $current = 0;
public function __construct(int $start, int $end) {
$this->start = $start;
$this->end = $end;
$this->current = $start;
}
public function rewind(): void {
$this->current = $this->start;
}
public function current(): int {
return $this->current;
}
public function key(): int {
return $this->current - $this->start;
}
public function next(): void {
$this->current++;
}
public function valid(): bool {
return $this->current <= $this->end;
}
}
// Test implementing IteratorAggregate interface
class NumberCollection implements IteratorAggregate {
private array $numbers;
public function __construct(array $numbers) {
$this->numbers = $numbers;
}
public function getIterator(): Traversable {
return new ArrayIterator($this->numbers);
}
}
// Test a simple iterable range
class Range implements IteratorAggregate {
private int $start;
private int $end;
public function __construct(int $start, int $end) {
$this->start = $start;
$this->end = $end;
}
public function getIterator(): Traversable {
for ($i = $this->start; $i <= $this->end; $i++) {
yield $i;
}
}
}
// Test filtering iterator
class FilterIterator implements Iterator {
private Iterator $iterator;
private mixed $filterValue;
public function __construct(Iterator $iterator, mixed $filterValue) {
$this->iterator = $iterator;
$this->filterValue = $filterValue;
// Rewind to first valid element
$this->iterator->rewind();
$this->advanceToValid();
}
private function advanceToValid(): void {
while ($this->iterator->valid() && $this->iterator->current() < $this->filterValue) {
$this->iterator->next();
}
}
public function rewind(): void {
$this->iterator->rewind();
$this->advanceToValid();
}
public function current(): mixed {
return $this->iterator->current();
}
public function key(): mixed {
return $this->iterator->key();
}
public function next(): void {
$this->iterator->next();
$this->advanceToValid();
}
public function valid(): bool {
return $this->iterator->valid();
}
}
function main() {
// Test custom Iterator
echo "Custom Iterator:\n";
$iterator = new NumberIterator(5, 10);
foreach ($iterator as $key => $value) {
echo "{$key}: {$value}\n";
}
// Test IteratorAggregate with ArrayIterator
echo "\nIteratorAggregate:\n";
$collection = new NumberCollection([10, 20, 30, 40, 50]);
foreach ($collection as $index => $number) {
echo "{$index}: {$number}\n";
}
// Test Generator-based IteratorAggregate
echo "\nGenerator-based:\n";
$range = new Range(1, 5);
foreach ($range as $num) {
echo "{$num}\n";
}
// Test FilterIterator
echo "\nFilterIterator:\n";
$baseIterator = new NumberIterator(1, 10);
$filterIterator = new FilterIterator($baseIterator, 5);
foreach ($filterIterator as $value) {
echo "{$value}\n";
}
// Test multiple iterations
echo "\nMultiple iterations:\n";
$reusable = new Range(1, 3);
foreach ($reusable as $num) {
echo "First: {$num}\n";
}
foreach ($reusable as $num) {
echo "Second: {$num}\n";
}
}
?>
--EXPECT--
Custom Iterator:
0: 5
1: 6
2: 7
3: 8
4: 9
5: 10
IteratorAggregate:
0: 10
1: 20
2: 30
3: 40
4: 50
Generator-based:
1
2
3
4
5
FilterIterator:
5
6
7
8
9
10
Multiple iterations:
First: 1
First: 2
First: 3
Second: 1
Second: 2
Second: 3

@ -0,0 +1,121 @@
--TEST--
Match Expression - PHP 8+ enhanced switch statement
--FILE--
<?php
function test_basic_match($value) {
return match($value) {
1 => 'one',
2 => 'two',
3 => 'three',
default => 'other',
};
}
function test_multiple_conditions($status) {
return match($status) {
200, 201, 202 => 'success',
400, 401, 403, 404 => 'client_error',
500, 501, 502, 503 => 'server_error',
default => 'unknown',
};
}
function test_strict_comparison($value) {
return match($value) {
0 => 'integer zero',
'0' => 'string zero',
false => 'boolean false',
null => 'null value',
default => 'other',
};
}
function test_expression_result($a, $b, $op) {
return match($op) {
'add' => $a + $b,
'sub' => $a - $b,
'mul' => $a * $b,
'div' => $b !== 0 ? $a / $b : 'error',
default => 'invalid operation',
};
}
function test_nested_match($level) {
return match($level) {
1 => match(true) {
true => 'level 1 - true',
false => 'level 1 - false',
},
2 => 'level 2',
default => 'other level',
};
}
function test_no_default($value) {
try {
return match($value) {
1 => 'one',
2 => 'two',
};
} catch (UnhandledMatchError $e) {
return "Error: " . $e->getMessage();
}
}
function main() {
// Test basic match
var_dump(test_basic_match(1));
var_dump(test_basic_match(2));
var_dump(test_basic_match(5));
// Test multiple conditions
var_dump(test_multiple_conditions(200));
var_dump(test_multiple_conditions(404));
var_dump(test_multiple_conditions(500));
var_dump(test_multiple_conditions(999));
// Test strict comparison
var_dump(test_strict_comparison(0));
var_dump(test_strict_comparison('0'));
var_dump(test_strict_comparison(false));
var_dump(test_strict_comparison(null));
// Test expression result
var_dump(test_expression_result(10, 5, 'add'));
var_dump(test_expression_result(10, 5, 'sub'));
var_dump(test_expression_result(10, 5, 'mul'));
var_dump(test_expression_result(10, 5, 'div'));
var_dump(test_expression_result(10, 0, 'div'));
// Test nested match
var_dump(test_nested_match(1));
var_dump(test_nested_match(2));
var_dump(test_nested_match(3));
// Test no default (should throw error)
var_dump(test_no_default(1));
var_dump(test_no_default(5));
}
?>
--EXPECT--
string(3) "one"
string(3) "two"
string(5) "other"
string(7) "success"
string(12) "client_error"
string(12) "server_error"
string(7) "unknown"
string(12) "integer zero"
string(11) "string zero"
string(13) "boolean false"
string(10) "null value"
int(15)
int(5)
int(50)
int(2)
string(5) "error"
string(14) "level 1 - true"
string(7) "level 2"
string(11) "other level"
string(3) "one"
string(27) "Error: Unhandled match case"
Loading…
Cancel
Save