From 23a2bf44d7e0b845057e4069a00d7a3d2781d034 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 24 Aug 2026 16:53:18 +0800 Subject: [PATCH] test(compiler): add comprehensive test coverage for PHP language features - Add alternative control structure syntax test with if/for/while/foreach/switch - Implement DNF types test covering intersection and union type combinations - Create numeric literal syntax test for binary, octal and separated numbers - Remove outdated test coverage documentation files - Add traditional operator precedence and short-circuiting behavior test - Verify compound assignment operations and bitwise operations - Test negative and positive unary operators with integer and float values --- tests/compiler/README_TEST_COVERAGE.md | 282 ----------- tests/compiler/TEST_SUPPLEMENT_REPORT.md | 456 ------------------ .../basic/numeric-literal-syntax.phpt | 29 ++ .../control_flow/alternative-syntax.phpt | 52 ++ .../traditional-syntax-regression.phpt | 74 +++ tests/compiler/type_decl/dnf-types.phpt | 113 +++++ 6 files changed, 268 insertions(+), 738 deletions(-) delete mode 100644 tests/compiler/README_TEST_COVERAGE.md delete mode 100644 tests/compiler/TEST_SUPPLEMENT_REPORT.md create mode 100644 tests/compiler/basic/numeric-literal-syntax.phpt create mode 100644 tests/compiler/control_flow/alternative-syntax.phpt create mode 100644 tests/compiler/operator/traditional-syntax-regression.phpt create mode 100644 tests/compiler/type_decl/dnf-types.phpt diff --git a/tests/compiler/README_TEST_COVERAGE.md b/tests/compiler/README_TEST_COVERAGE.md deleted file mode 100644 index eda0eac0..00000000 --- a/tests/compiler/README_TEST_COVERAGE.md +++ /dev/null @@ -1,282 +0,0 @@ -# PHP AOT 编译器单元测试覆盖总结 - -## 新增测试文件列表 - -本次为 PHP AOT 编译器添加了以下单元测试文件,覆盖了 PHP 语言的核心语法特性: - -### 1. **trait-basic.phpt** - Traits (特征) -- 基础 trait 使用 -- trait 中的抽象方法 -- 多个 trait 的组合使用 -- trait 方法继承 - -### 2. **generators.phpt** - Generators (生成器) -- 基础 yield 语法 -- 带键的生成器 -- 生成器对象操作 -- 有限和无限生成器 - -### 3. **attributes.phpt** - Attributes (注解/属性) -- Attribute 定义和使用 -- 类属性、方法属性、属性属性 -- Reflection API 读取属性 -- 属性参数传递 - -### 4. **match-expression.phpt** - Match Expression (匹配表达式) -- 基础 match 语法 -- 多条件匹配 -- 严格类型比较 -- 表达式作为返回值 -- 嵌套 match -- UnhandledMatchError 异常处理 - -### 5. **named-arguments.phpt** - Named Arguments (命名参数) -- 基础命名参数调用 -- 跳过可选参数 -- 混合位置和命名参数 -- 参数顺序无关性 -- 复杂场景应用 - -### 6. **union-intersection-types.phpt** - Union and Intersection Types (联合和交集类型) -- Union 类型声明 -- Nullable union 类型 -- mixed 类型 -- never 返回类型 -- instanceof 检查 - -### 7. **constructor-promotion.phpt** - Constructor Property Promotion (构造函数属性提升) -- 基础构造函数提升 -- 可见性修饰符 (public/private/protected) -- 可空类型和默认值 -- 混合传统和提升方式 -- readonly 属性 (PHP 8.1+) - -### 8. **null-coalescing.phpt** - Null Coalescing Operators (空合并运算符) -- 基础 ?? 运算符 -- 链式 null coalescing -- ??= 赋值运算符 -- 数组访问中的 coalescing -- 嵌套数组 coalescing -- 表达式中的使用 - -### 9. **array-spread.phpt** - Spread Operator in Arrays (数组展开运算符) -- 基础数组展开 -- 展开时添加额外元素 -- 多个展开操作 -- 带键的数组展开 -- 字符串键的覆盖行为 -- 展开空数组 - -### 10. **arrow-functions.phpt** - Arrow Functions (箭头函数) -- 基础箭头函数语法 -- 多参数箭头函数 -- 变量捕获 (by value) -- 嵌套箭头函数 -- 在 array_map/filter/reduce 中使用 -- 链式调用 - -### 11. **magic-methods.phpt** - Magic Methods (魔术方法) -- __get / __set -- __isset / __unset -- __call / __callStatic -- __invoke -- __toString -- __debugInfo -- __clone -- __serialize / __unserialize - -### 12. **iterators.phpt** - Iterators (迭代器) -- Iterator 接口实现 -- IteratorAggregate 接口实现 -- Generator-based 迭代器 -- FilterIterator 实现 -- 可重复使用的迭代器 - -### 13. **anonymous-classes.phpt** - Anonymous Classes (匿名类) -- 基础匿名类定义 -- 继承父类的匿名类 -- 实现接口的匿名类 -- 带属性的匿名类 -- 嵌套匿名类 -- 匿名类数组 -- 静态方法和属性 - -### 14. **type-declarations.phpt** - Type Declarations (类型声明) -- 标量类型声明 (int/string/float/bool) -- 可空类型 (?T) -- callable 类型 -- array/object/iterable 类型 -- strict_types 模式 -- 返回类型声明 - -### 15. **late-static-binding.phpt** - Late Static Binding (后期静态绑定) -- self:: vs static:: -- 静态属性的后期绑定 -- 静态方法的后期绑定 -- 构造函数中的 static:: - -### 16. **variadic-functions.phpt** - Variadic Functions (可变参数函数) -- 基础可变参数 (...$args) -- 必需参数 + 可变参数 -- 类方法中的可变参数 -- 类型化的可变参数 -- 数组展开到函数调用 - -## 现有测试覆盖的主要领域 - -### 已覆盖的 PHP 语法特性: - -#### 基础语法 -- ✅ 算术运算符 (arithmetic_operators.phpt) -- ✅ 比较运算符 (comparison_operators.phpt) -- ✅ 逻辑运算符 (logical_operators.phpt) -- ✅ 赋值运算符 (assignment_operators.phpt) -- ✅ 位运算符 -- ✅ 递增/递减运算符 (postincdec.phpt) - -#### 控制结构 -- ✅ if/else/elseif (control_structures.phpt) -- ✅ for/while/do-while (control_structures.phpt) -- ✅ switch (switch-001.phpt, switch-002.phpt) -- ✅ break/continue -- ✅ try-catch-finally (try-catch.phpt, try-catch-2.phpt) -- ✅ throw (throw-in-php.phpt) - -#### 函数 -- ✅ 函数定义和调用 (functions.phpt) -- ✅ 参数传递 (class_args.phpt) -- ✅ 默认参数 (func-default-param.phpt) -- ✅ 返回类型 (func-return-type.phpt) -- ✅ 可变参数 (variadic-args.phpt, variadic-functions.phpt) -- ✅ 命名参数 (named-arguments.phpt) -- ✅ 闭包 (closure-001.phpt, closure-002.phpt) -- ✅ 箭头函数 (arrow-func.phpt, arrow-func-2.phpt, arrow-functions.phpt) -- ✅ 生成器 (generators.phpt) - -#### 类与对象 -- ✅ 类定义 (class-namespace.phpt) -- ✅ 构造函数 (ctor.phpt) -- ✅ 析构函数 -- ✅ 继承 -- ✅ 访问修饰符 (private-prop-001.phpt, private-prop-002.phpt) -- ✅ 静态属性和方法 (class-static-001~005.phpt) -- ✅ 常量 (const-test.phpt) -- ✅ 抽象类 -- ✅ 接口 (enum1.phpt, enum2.phpt) -- ✅ Traits (trait-basic.phpt) -- ✅ 匿名类 (anonymous-classes.phpt) -- ✅ 枚举 (enum1.phpt, enum2.phpt) - -#### 对象特性 -- ✅ 属性访问 (prop-001.phpt, prop-002.phpt) -- ✅ 方法调用 (method-call.phpt) -- ✅ 静态调用 (static-call.phpt) -- ✅ 对象引用 (object-link.phpt, object-link-002.phpt, object-link-003.phpt) -- ✅ 克隆 -- ✅ 序列化 -- ✅ 魔术方法 (magic-methods.phpt) -- ✅ 迭代器 (iterators.phpt) - -#### 类型系统 -- ✅ 标量类型 (native-type.phpt) -- ✅ 联合类型 (union-intersection-types.phpt) -- ✅ 可空类型 -- ✅ mixed 类型 -- ✅ never 类型 -- ✅ 类型声明 (type-declarations.phpt) -- ✅ 类型转换 (to-str.phpt) - -#### 数组 -- ✅ 数组创建 (arrays.phpt, array_001~003.phpt) -- ✅ 数组访问 -- ✅ 数组修改 (array_assignment_edge_cases.phpt) -- ✅ 数组运算符 (array_assignment_operators.phpt) -- ✅ 多维数组 (complex_array_operations.phpt) -- ✅ 数组展开 (array-spread.phpt) -- ✅ list() 解构 (list-test.phpt) -- ✅ 数组项自增自减 (array-item-dec-inc.phpt) - -#### 字符串 -- ✅ 字符串连接 -- ✅ 字符串函数 (string_functions.phpt) -- ✅ 字符串长度 (strlen.phpt) -- ✅ 字符串偏移量 (str-offset-set.phpt) -- ✅ 格式化字符串 (fstring.py) - -#### 变量 -- ✅ 变量定义 (basic_variables.phpt) -- ✅ 变量作用域 (global-vars.phpt, static-vars.phpt) -- ✅ 引用 (ref.phpt, ref-005.phpt, ref-func-param.phpt, ref-closure-param.phpt, ref-call-arg.phpt) -- ✅ 可变变量 - -#### 运算符 -- ✅ 算术运算符 (arithmetic_operators.phpt) -- ✅ 比较运算符 (comparison_operators.phpt) -- ✅ 逻辑运算符 (logical_operators.phpt) -- ✅ 赋值运算符 (assignment_operators.phpt) -- ✅ 三元运算符 (assign-compare.phpt) -- ✅ 空合并运算符 (assign_coalesce_001.phpt, assign_coalesce_002.phpt, null-coalescing.phpt) -- ✅ 实例运算符 (instanceof) -- ✅ 按位运算符 - -#### 高级特性 -- ✅ 命名空间 (class-namespace.phpt, ns-const.phpt) -- ✅ 自动加载 -- ✅ 特性 (trait-basic.phpt) -- ✅ 生成器 (generators.phpt) -- ✅ 闭包 (closure-001.phpt, closure-002.phpt) -- ✅ 匿名函数 (arrow-func.phpt, arrow-func-2.phpt) -- ✅ 匿名类 (anonymous-classes.phpt) -- ✅ 属性 (attributes.phpt) -- ✅ 匹配表达式 (match-expression.phpt) -- ✅ 空船运算符 (null-coalescing.phpt) -- ✅ 展开运算符 (array-spread.phpt, variadic-functions.phpt) -- ✅ 类型声明 (type-declarations.phpt) -- ✅ 后期静态绑定 (late-static-binding.phpt) - -#### 错误处理 -- ✅ 异常处理 (try-catch.phpt, try-catch-2.phpt) -- ✅ 错误报告 -- ✅ 自定义错误处理 - -#### 内置类 -- ✅ DateTime (datetime_builtin_class.phpt) -- ✅ ArrayObject -- ✅ Exception -- ✅ Reflection (attributes.phpt) - -## 测试覆盖率统计 - -- **总测试文件数**: 116 个 phpt 文件 -- **新增测试文件**: 16 个 -- **覆盖的 PHP 版本**: PHP 7.4+ ~ PHP 8.x - -## 主要覆盖的 PHP 特性类别 - -1. **基础语法** (100%) - 运算符、控制结构、变量等 -2. **函数** (95%) - 定义、调用、闭包、生成器等 -3. **类与对象** (90%) - 继承、多态、封装等 OOP 特性 -4. **类型系统** (95%) - 类型声明、类型转换、联合类型等 -5. **数组处理** (95%) - 创建、访问、修改、遍历等 -6. **字符串处理** (90%) - 连接、函数、格式化等 -7. **错误处理** (85%) - 异常、错误报告等 -8. **高级特性** (85%) - 反射、迭代器、序列化等 - -## 测试质量保证 - -- 所有测试都遵循标准的 phpt 格式 -- 包含 --TEST--、--FILE--、--EXPECT-- 三个必要部分 -- 测试用例覆盖正常情况和边界情况 -- 包含错误处理和异常情况测试 -- 符合 PHP AOT 编译器的特殊要求 - -## 后续建议 - -虽然已经覆盖了大量 PHP 语法,但仍有以下方面可以继续加强: - -1. **性能测试**: 添加更多性能基准测试 -2. **边缘案例**: 更多极端情况和边界条件的测试 -3. **并发测试**: 多线程/协程相关测试 -4. **内存管理**: 内存泄漏和垃圾回收测试 -5. **扩展集成**: 与 PHP 扩展的集成测试 -6. **兼容性测试**: 不同 PHP 版本的兼容性测试 diff --git a/tests/compiler/TEST_SUPPLEMENT_REPORT.md b/tests/compiler/TEST_SUPPLEMENT_REPORT.md deleted file mode 100644 index e3cf6015..00000000 --- a/tests/compiler/TEST_SUPPLEMENT_REPORT.md +++ /dev/null @@ -1,456 +0,0 @@ -# AOT 编译器测试补充报告 - -## 📋 概述 - -本次 review 了 `tests/compiler/` 目录下的所有单测文件,分析了 PHP 语法覆盖情况,并新增了多个重要测试场景。 - ---- - -## ✅ 新增测试文件 - -### 1. **readonly-class.phpt** - Readonly Classes (PHP 8.2+) - -**覆盖的语法特性**: -- ✅ `readonly` 类定义 -- ✅ Readonly 类的构造函数 -- ✅ Readonly 类继承 -- ✅ Constructor Property Promotion with readonly -- ✅ Readonly 类中的方法定义 - -**测试场景**: -```php -// 基础 readonly 类 -readonly class Point { - public int $x; - public int $y; -} - -// Readonly 类继承 -readonly abstract class Shape { } -readonly class Rectangle extends Shape { } - -// Constructor promotion -readonly class Circle { - public function __construct( - public float $radius, - ) {} -} -``` - ---- - -### 2. **backed-enum.phpt** - Backed Enums (PHP 8.1+) - -**覆盖的语法特性**: -- ✅ Int backed enums -- ✅ String backed enums -- ✅ Enum 方法定义 -- ✅ `match()` 与 enum 配合使用 -- ✅ Enum 的 `value` 和 `name` 属性 -- ✅ `from()` 方法使用 -- ✅ Enum 在数组中的使用 - -**测试场景**: -```php -// Int backed enum -enum Status: int { - case Pending = 0; - case Active = 1; -} - -// String backed enum -enum Color: string { - case Red = 'red'; - case Green = 'green'; -} - -// Enum 方法 -enum Status: int { - case Pending; - case Active; - - public function label(): string { - return match($this) { - self::Pending => 'Pending', - self::Active => 'Active', - }; - } -} -``` - ---- - -### 3. **first-class-callable.phpt** - First-Class Callable Syntax (PHP 8.1+) - -**覆盖的语法特性**: -- ✅ 函数作为可调用对象 -- ✅ 静态方法的可调用语法 -- ✅ 实例方法的可调用语法 -- ✅ 可调用对象在 array_map/array_filter 中的应用 -- ✅ 返回 callable 的函数 -- ✅ 可调用对象与箭头函数结合 - -**测试场景**: -```php -// 基本可调用语法 -$callable = 'function_name'; -array_map($callable, $array); - -// 静态方法可调用 -$staticCallable = ['ClassName', 'methodName']; - -// 实例方法可调用 -$instanceCallable = [$object, 'methodName']; - -// 返回 callable 的函数 -function multiplier(int $factor): callable { - return fn(int $value) => $value * $factor; -} -``` - ---- - -### 4. **deep-recursion.phpt** - Deep Recursion Patterns - -**覆盖的语法特性**: -- ✅ 深度递归函数 -- ✅ 记忆化递归(memoization) -- ✅ 相互递归(mutual recursion) -- ✅ 树形递归(tree recursion) -- ✅ 分治算法(quicksort) -- ✅ 引用参数在递归中的应用 - -**测试场景**: -```php -// 阶乘递归 -function factorial(int $n): int { - if ($n <= 1) return 1; - return $n * factorial($n - 1); -} - -// 斐波那契(带记忆化) -function fib(int $n, array &$memo = []): int { - if (isset($memo[$n])) return $memo[$n]; - $memo[$n] = fib($n - 1, $memo) + fib($n - 2, $memo); - return $memo[$n]; -} - -// 相互递归 -function isEven(int $n): bool { - if ($n === 0) return true; - return isOdd($n - 1); -} - -function isOdd(int $n): bool { - if ($n === 0) return false; - return isEven($n - 1); -} - -// 树形递归 -function sumTree(array $tree): int { - $sum = $tree['value']; - foreach ($tree['children'] as $child) { - $sum += sumTree($child); - } - return $sum; -} -``` - ---- - -## 📊 当前测试覆盖统计 - -### 总体统计 - -| 类别 | 测试文件数 | 覆盖率 | -|------|-----------|--------| -| **基础语法** | ~25 | 100% | -| **函数** | ~15 | 98% | -| **类与对象** | ~20 | 95% | -| **类型系统** | ~10 | 97% | -| **数组处理** | ~15 | 96% | -| **字符串** | ~8 | 92% | -| **控制结构** | ~12 | 98% | -| **错误处理** | ~6 | 90% | -| **高级特性** | ~15 | 93% | -| **总计** | **126** | **96%** | - -### PHP 版本覆盖 - -| PHP 版本 | 特性支持 | 测试覆盖 | -|---------|---------|----------| -| PHP 7.4 | 箭头函数、可空类型等 | ✅ 100% | -| PHP 8.0 | Match 表达式、命名参数、Attributes 等 | ✅ 100% | -| PHP 8.1 | Enums、Readonly properties、First-class callable 等 | ✅ 98% | -| PHP 8.2 | Readonly classes、Disjunctive Normal Form 等 | ✅ 95% | -| PHP 8.3 | Typed constants、Override attribute 等 | ⚠️ 待补充 | - ---- - -## 🎯 重点补充的测试场景 - -### 1. 复杂递归模式 -- ✅ 基础递归(factorial) -- ✅ 记忆化优化(fibonacci) -- ✅ 相互递归(isEven/isOdd) -- ✅ 树形遍历(sumTree) -- ✅ 分治算法(quicksort) - -### 2. 枚举高级用法 -- ✅ Backed enums(int/string) -- ✅ Enum 方法 -- ✅ Enum 与 match 表达式 -- ✅ Enum 数组操作 -- ✅ `from()` 和 `tryFrom()` 方法 - -### 3. 可调用对象 -- ✅ 函数作为 callable -- ✅ 静态方法 callable -- ✅ 实例方法 callable -- ✅ 返回 callable 的高阶函数 -- ✅ Callable 在 array_* 函数中的应用 - -### 4. Readonly 特性 -- ✅ Readonly 类定义 -- ✅ Readonly 类继承 -- ✅ Readonly constructor promotion -- ✅ Readonly 不可变性验证 - ---- - -## 📝 已覆盖的 PHP 核心特性清单 - -### ✅ 完全覆盖的特性 - -#### 基础语法 -- [x] 所有运算符(算术、比较、逻辑、赋值、位运算) -- [x] 控制结构(if/else、switch、for/while/do-while) -- [x] 异常处理(try/catch/finally、throw) -- [x] 命名空间和自动加载 - -#### 函数相关 -- [x] 函数定义和调用 -- [x] 参数传递(默认值、引用、可变参数) -- [x] 返回类型声明 -- [x] 箭头函数 -- [x] 闭包 -- [x] 生成器 -- [x] 第一类可调用语法 -- [x] 命名参数 - -#### 面向对象 -- [x] 类定义和实例化 -- [x] 构造函数和析构函数 -- [x] 继承和多态 -- [x] 访问修饰符(public/protected/private) -- [x] 静态属性和方法 -- [x] 抽象类和接口 -- [x] Traits -- [x] Anonymous classes -- [x] Enums(unit 和 backed) -- [x] Readonly 类和属性 -- [x] Constructor property promotion -- [x] Magic methods -- [x] Late static binding - -#### 类型系统 -- [x] 标量类型(int/string/float/bool) -- [x] 复合类型(array/object/callable/iterable) -- [x] 可空类型(?T) -- [x] 联合类型(T1|T2) -- [x] mixed 类型 -- [x] never 返回类型 -- [x] 类型声明和转换 - -#### 数组操作 -- [x] 数组创建和初始化 -- [x] 数组访问和修改 -- [x] 多维数组 -- [x] 数组运算符 -- [x] 数组展开(spread operator) -- [x] list() 解构 -- [x] 数组项自增自减 - -#### 字符串处理 -- [x] 字符串连接和插值 -- [x] 字符串函数 -- [x] 字符串偏移量 -- [x] 格式化字符串 - -#### 高级特性 -- [x] Attributes(注解) -- [x] Match 表达式 -- [x] Null coalescing 运算符 -- [x] 太空船运算符(<=>) -- [x] 迭代器(Iterator/IteratorAggregate) -- [x] 生成器 -- [x] 序列化 -- [x] 克隆 - ---- - -## ⚠️ 待补充的测试场景 - -### 优先级高 - -1. **PHP 8.3+ 新特性** - - [ ] Typed constants in interfaces - - [ ] #[\Override] attribute - - [ ] json_validate() function - - [ ] str_shuffle() deprecation alternatives - -2. **边缘案例和边界条件** - - [ ] 极大数字的处理 - - [ ] 极深递归(栈溢出测试) - - [ ] 内存限制边缘测试 - - [ ] 浮点数精度问题 - -3. **性能基准测试** - - [ ] 循环性能对比 - - [ ] 数组操作性能 - - [ ] 字符串拼接性能 - - [ ] 函数调用开销 - -### 优先级中 - -4. **并发和并行** - - [ ] 多进程场景 - - [ ] 协程基础测试 - - [ ] 线程安全测试 - -5. **扩展集成** - - [ ] Redis 扩展测试 - - [ ] MySQL/PDO 测试 - - [ ] JSON 处理测试 - - [ ] Filesystem 测试 - -6. **特殊语法组合** - - [ ] Attributes + Reflection 完整测试 - - [ ] Generators + Async 测试 - - [ ] Traits + Abstract 组合测试 - ---- - -## 🔍 测试质量分析 - -### 优势 - -✅ **覆盖面广**: 126 个测试文件,覆盖 96% 的 PHP 语法 -✅ **结构清晰**: 每个测试文件专注于一个特定特性 -✅ **示例丰富**: 包含大量实际使用场景 -✅ **边界测试**: 多数测试包含了边界条件检查 -✅ **符合规范**: 所有测试遵循标准 phpt 格式 - -### 改进空间 - -⚠️ **性能测试不足**: 缺少系统的性能基准测试 -⚠️ **压力测试缺乏**: 极端条件下的测试较少 -⚠️ **集成测试有限**: 与真实项目结合的测试不多 -⚠️ **回归测试需加强**: 历史 bug 的回归测试不够完善 - ---- - -## 📈 后续行动计划 - -### 短期(1-2 周) - -1. ✅ 完成 PHP 8.1 所有特性的测试覆盖 -2. ✅ 添加更多递归和算法测试 -3. ✅ 补充 enum 的高级用法测试 -4. ✅ 完善 callable 相关测试 - -### 中期(1 个月) - -1. 🔄 添加 PHP 8.3 新特性测试 -2. 🔄 创建性能基准测试套件 -3. 🔄 增加边缘案例和压力测试 -4. 🔄 编写真实项目集成测试 - -### 长期(3 个月) - -1. 📅 建立完整的回归测试集 -2. 📅 实现自动化测试覆盖率检查 -3. 📅 创建性能监控和对比系统 -4. 📅 编写详细的测试文档和指南 - ---- - -## 📚 测试文件索引 - -### 新增文件位置 - -所有新增测试文件位于 `tests/compiler/` 目录: - -``` -tests/compiler/ -├── readonly-class.phpt # Readonly 类测试 -├── backed-enum.phpt # Backed 枚举测试 -├── first-class-callable.phpt # 一类可调用语法测试 -└── deep-recursion.phpt # 深度递归测试 -``` - -### 运行测试 - -```bash -# 运行单个测试 -php run-tests.php tests/compiler/readonly-class.phpt - -# 运行所有新增测试 -php run-tests.php tests/compiler/readonly-class.phpt \ - tests/compiler/backed-enum.phpt \ - tests/compiler/first-class-callable.phpt \ - tests/compiler/deep-recursion.phpt - -# 运行所有 AOT 测试 -php run-tests.php tests/compiler/ -``` - ---- - -## 🎓 测试编写最佳实践 - -基于本次 review,总结出以下最佳实践: - -### 1. 测试结构 - -```php ---TEST-- -清晰的测试描述 ---FILE-- - ---EXPECT-- -// 期望的输出结果 -``` - -### 2. 测试设计原则 - -- ✅ **单一职责**: 每个测试文件专注于一个特性 -- ✅ **自包含**: 测试不依赖外部文件或状态 -- ✅ **可重复**: 多次运行结果一致 -- ✅ **边界覆盖**: 包含正常值和边界值 -- ✅ **错误处理**: 测试异常情况的行为 - -### 3. 代码组织 - -```php -// 好的组织方式 -1. 简单场景 → 复杂场景 -2. 基础用法 → 高级用法 -3. 单一特性 → 组合特性 -4. 正常流程 → 异常流程 -``` - ---- - -**报告生成时间**: 2024 年 3 月 20 日 -**测试文件总数**: 126 个 -**覆盖率**: 96% -**下次审查日期**: 2024 年 4 月 20 日 diff --git a/tests/compiler/basic/numeric-literal-syntax.phpt b/tests/compiler/basic/numeric-literal-syntax.phpt new file mode 100644 index 00000000..9c0a5f62 --- /dev/null +++ b/tests/compiler/basic/numeric-literal-syntax.phpt @@ -0,0 +1,29 @@ +--TEST-- +Binary, explicit octal and separated numeric literals preserve their values +--FILE-- + +--EXPECT-- +int(10) +int(15) +int(15) +int(16) +int(1234567) +int(165) +int(493) +int(51966) +float(125) diff --git a/tests/compiler/control_flow/alternative-syntax.phpt b/tests/compiler/control_flow/alternative-syntax.phpt new file mode 100644 index 00000000..bba72a1e --- /dev/null +++ b/tests/compiler/control_flow/alternative-syntax.phpt @@ -0,0 +1,52 @@ +--TEST-- +Alternative control structure syntax shares normal control-flow semantics +--FILE-- + 1, 'b' => 2] as $key => $item): + $events[] = 'foreach:' . $key . '=' . $item; + endforeach; + + switch ($value): + case 1: + $events[] = 'switch:one'; + break; + case 2: + $events[] = 'switch:two'; + break; + default: + $events[] = 'switch:other'; + break; + endswitch; + + echo implode('|', $events), "\n"; +} +?> +--EXPECT-- +if:two|for:0|for:2|for:3|while:0|while:1|foreach:a=1|foreach:b=2|switch:two diff --git a/tests/compiler/operator/traditional-syntax-regression.phpt b/tests/compiler/operator/traditional-syntax-regression.phpt new file mode 100644 index 00000000..8a146cdc --- /dev/null +++ b/tests/compiler/operator/traditional-syntax-regression.phpt @@ -0,0 +1,74 @@ +--TEST-- +Traditional operators preserve precedence, short-circuiting, values and compound writes +--FILE-- +>= 2); + var_dump($values[2] ^= 0b1010); + var_dump($values[2] &= 0b0011); + var_dump($values); +} +?> +--EXPECT-- +int(2) +int(2) +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +array(2) { + [0]=> + string(8) "and-left" + [1]=> + string(7) "or-left" +} +int(-7) +float(-2.5) +int(6) +int(24) +int(4) +int(6) +int(2) +array(3) { + [0]=> + int(24) + [1]=> + int(4) + [2]=> + int(2) +} diff --git a/tests/compiler/type_decl/dnf-types.phpt b/tests/compiler/type_decl/dnf-types.phpt new file mode 100644 index 00000000..f73d7f4e --- /dev/null +++ b/tests/compiler/type_decl/dnf-types.phpt @@ -0,0 +1,113 @@ +--TEST-- +DNF types enforce intersection alternatives on parameters, returns and properties +--FILE-- +label(); + } + return $value->left() . '+' . $value->right(); +} + +function dnf_identity( + (DnfLeft&DnfRight)|DnfFallback $value, +): (DnfLeft&DnfRight)|DnfFallback { + return $value; +} + +function dnf_dynamic_return(mixed $value): (DnfLeft&DnfRight)|DnfFallback +{ + return $value; +} + +final class DnfBox +{ + public (DnfLeft&DnfRight)|DnfFallback $value; + + public function __construct((DnfLeft&DnfRight)|DnfFallback $value) + { + $this->value = $value; + } +} + +function main(): void +{ + $both = new DnfBoth(); + $fallback = new DnfFallback(); + var_dump(dnf_label($both)); + var_dump(dnf_label($fallback)); + var_dump(dnf_identity($both) instanceof DnfBoth); + + $box = new DnfBox($fallback); + var_dump($box->value instanceof DnfFallback); + $box->value = $both; + var_dump($box->value instanceof DnfBoth); + + $invalid = any(new DnfOnlyLeft()); + try { + dnf_label($invalid); + } catch (TypeError $error) { + echo "parameter TypeError\n"; + } + try { + dnf_dynamic_return($invalid); + } catch (TypeError $error) { + echo "return TypeError\n"; + } + try { + $box->value = $invalid; + } catch (TypeError $error) { + echo "property TypeError\n"; + } +} +?> +--EXPECT-- +string(10) "left+right" +string(8) "fallback" +bool(true) +bool(true) +bool(true) +parameter TypeError +return TypeError +property TypeError