From 8bf5c9c8061b7ebcf8fa15a7259c363defeb533c Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 19 Mar 2026 12:45:42 +0800 Subject: [PATCH] =?UTF-8?q?test(aot):=20=E6=B7=BB=E5=8A=A0=E8=BF=AD?= =?UTF-8?q?=E4=BB=A3=E5=99=A8=E5=92=8C=E5=8C=B9=E9=85=8D=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改generators.phpt使用exit替代echo进行跳过提示 - 新增iterators.phpt测试文件实现Iterator和IteratorAggregate接口 - 添加Range类测试基于生成器的迭代器聚合 - 实现FilterIterator类测试过滤功能 - 新增match-expression.phpt测试PHP8+匹配表达式功能 - 测试基本匹配、多重条件、严格比较和嵌套匹配场景 --- tests/aot/generators.phpt | 2 +- tests/aot/iterators.phpt | 193 ++++++++++++++++++++++++++++++++ tests/aot/match-expression.phpt | 121 ++++++++++++++++++++ 3 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 tests/aot/iterators.phpt create mode 100644 tests/aot/match-expression.phpt diff --git a/tests/aot/generators.phpt b/tests/aot/generators.phpt index f1784d48..3544449b 100644 --- a/tests/aot/generators.phpt +++ b/tests/aot/generators.phpt @@ -2,7 +2,7 @@ Generators - Yield keyword and generator functions --SKIPIF-- --FILE-- +--FILE-- +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 diff --git a/tests/aot/match-expression.phpt b/tests/aot/match-expression.phpt new file mode 100644 index 00000000..ccc4b9fa --- /dev/null +++ b/tests/aot/match-expression.phpt @@ -0,0 +1,121 @@ +--TEST-- +Match Expression - PHP 8+ enhanced switch statement +--FILE-- + '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"