From 7721ad4a4effd94af5f3fc313b1faaf4851ff627 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 27 Jul 2026 10:27:22 +1000 Subject: [PATCH 1/3] Updated dev tooling to latest PHP 8.3-compatible versions. Bumped 'phpunit/phpunit' to ^12.5.32 (13.x requires PHP 8.4, above the library's >=8.3 floor), 'drevops/phpcs-standard' to ^1.0.0 and 'rector/rector' to ^2.5.7. Capped 'phpstan/phpstan' below 2.2.6: that release changed a PHPStan RichParser internal that 'rector/rector' 2.5.7 reads via reflection, crashing the lint step. composer.lock is not committed, so CI re-resolves to the newest allowed release on every run, and the ceiling keeps the static-analysis tooling working together. --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index f9702352..21dd9dd9 100644 --- a/composer.json +++ b/composer.json @@ -23,14 +23,14 @@ "require-dev": { "alexskrypnyk/phpunit-helpers": "^0.16.0", "dealerdirect/phpcodesniffer-composer-installer": "^1.2.1", - "drevops/phpcs-standard": "^0.7", + "drevops/phpcs-standard": "^1.0.0", "drupal/coder": "^9.0.1", "ergebnis/composer-normalize": "^2.52.0", "mikey179/vfsstream": "^1.6.12", "opis/closure": "^4.5.0", - "phpstan/phpstan": "^2.2.4", - "phpunit/phpunit": "^11.5.55", - "rector/rector": "^2.5.2" + "phpstan/phpstan": ">=2.2.4 <2.2.6", + "phpunit/phpunit": "^12.5.32", + "rector/rector": "^2.5.7" }, "suggest": { "ext-mbstring": "Provides full Unicode case folding and native multibyte string handling; PCRE-based fallbacks with ASCII-only case folding are used when it is absent." From 99268c011c91d6bafde47f41716313583bb627d0 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 27 Jul 2026 10:41:36 +1000 Subject: [PATCH 2/3] Migrated trait coverage attributes to 'CoversTrait' for PHPUnit 12. PHPUnit 12 no longer accepts a trait as a '#[CoversClass]' target and emits a 'not a valid target for code coverage' warning for each one. Because phpunit.xml sets 'failOnWarning', the coverage run ('composer test-coverage', which CI runs) failed once phpunit moved to 12, even though the plain 'composer test' run (no coverage) stayed green. Converted the capability-trait covers in the widget tests to '#[CoversTrait]' and added the matching import, keeping '#[CoversClass]' for the widget and helper classes. --- tests/phpunit/Unit/Widget/FilePickerWidgetTest.php | 5 +++-- tests/phpunit/Unit/Widget/NumberWidgetTest.php | 3 ++- tests/phpunit/Unit/Widget/PasswordWidgetTest.php | 3 ++- tests/phpunit/Unit/Widget/ReorderWidgetTest.php | 3 ++- tests/phpunit/Unit/Widget/SearchWidgetTest.php | 13 +++++++------ tests/phpunit/Unit/Widget/SelectWidgetTest.php | 11 ++++++----- tests/phpunit/Unit/Widget/SuggestWidgetTest.php | 3 ++- tests/phpunit/Unit/Widget/TextWidgetTest.php | 5 +++-- tests/phpunit/Unit/Widget/TextareaWidgetTest.php | 3 ++- 9 files changed, 29 insertions(+), 20 deletions(-) diff --git a/tests/phpunit/Unit/Widget/FilePickerWidgetTest.php b/tests/phpunit/Unit/Widget/FilePickerWidgetTest.php index d34c7e70..b4d60bff 100644 --- a/tests/phpunit/Unit/Widget/FilePickerWidgetTest.php +++ b/tests/phpunit/Unit/Widget/FilePickerWidgetTest.php @@ -20,6 +20,7 @@ use DrevOps\Tui\Widget\Capability\SelectionBoundedTrait; use org\bovigo\vfs\vfsStream; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\CoversTrait; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; @@ -28,8 +29,8 @@ */ #[CoversClass(FilePickerWidget::class)] #[CoversClass(AbstractWidget::class)] -#[CoversClass(PagingCapableTrait::class)] -#[CoversClass(SelectionBoundedTrait::class)] +#[CoversTrait(PagingCapableTrait::class)] +#[CoversTrait(SelectionBoundedTrait::class)] #[Group('widget')] final class FilePickerWidgetTest extends TestCase { diff --git a/tests/phpunit/Unit/Widget/NumberWidgetTest.php b/tests/phpunit/Unit/Widget/NumberWidgetTest.php index 5ae6782b..a7dfd588 100644 --- a/tests/phpunit/Unit/Widget/NumberWidgetTest.php +++ b/tests/phpunit/Unit/Widget/NumberWidgetTest.php @@ -15,6 +15,7 @@ use DrevOps\Tui\Widget\NumberWidget; use DrevOps\Tui\Widget\Capability\TextEditCapableTrait; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\CoversTrait; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; @@ -22,7 +23,7 @@ * Tests the number widget. */ #[CoversClass(NumberWidget::class)] -#[CoversClass(TextEditCapableTrait::class)] +#[CoversTrait(TextEditCapableTrait::class)] #[Group('widget')] final class NumberWidgetTest extends TestCase { diff --git a/tests/phpunit/Unit/Widget/PasswordWidgetTest.php b/tests/phpunit/Unit/Widget/PasswordWidgetTest.php index 7fe27ba4..df7457e7 100644 --- a/tests/phpunit/Unit/Widget/PasswordWidgetTest.php +++ b/tests/phpunit/Unit/Widget/PasswordWidgetTest.php @@ -13,6 +13,7 @@ use DrevOps\Tui\Widget\PasswordWidget; use DrevOps\Tui\Widget\Capability\TextEditCapableTrait; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\CoversTrait; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; @@ -20,7 +21,7 @@ * Tests the password widget. */ #[CoversClass(PasswordWidget::class)] -#[CoversClass(TextEditCapableTrait::class)] +#[CoversTrait(TextEditCapableTrait::class)] #[Group('widget')] final class PasswordWidgetTest extends TestCase { diff --git a/tests/phpunit/Unit/Widget/ReorderWidgetTest.php b/tests/phpunit/Unit/Widget/ReorderWidgetTest.php index 0a018e31..ceaa9ecc 100644 --- a/tests/phpunit/Unit/Widget/ReorderWidgetTest.php +++ b/tests/phpunit/Unit/Widget/ReorderWidgetTest.php @@ -19,6 +19,7 @@ use DrevOps\Tui\Widget\Capability\PagingCapableTrait; use DrevOps\Tui\Widget\ReorderWidget; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\CoversTrait; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; @@ -27,7 +28,7 @@ */ #[CoversClass(ReorderWidget::class)] #[CoversClass(AbstractWidget::class)] -#[CoversClass(PagingCapableTrait::class)] +#[CoversTrait(PagingCapableTrait::class)] #[Group('widget')] final class ReorderWidgetTest extends TestCase { diff --git a/tests/phpunit/Unit/Widget/SearchWidgetTest.php b/tests/phpunit/Unit/Widget/SearchWidgetTest.php index 2f5033da..b84a52fa 100644 --- a/tests/phpunit/Unit/Widget/SearchWidgetTest.php +++ b/tests/phpunit/Unit/Widget/SearchWidgetTest.php @@ -23,6 +23,7 @@ use DrevOps\Tui\Widget\Capability\SelectionCapableTrait; use DrevOps\Tui\Widget\SearchWidget; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\CoversTrait; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; @@ -30,12 +31,12 @@ * Tests the search widget, single-choice and multiple-choice. */ #[CoversClass(SearchWidget::class)] -#[CoversClass(SelectionCapableTrait::class)] -#[CoversClass(SelectionBoundedTrait::class)] -#[CoversClass(FilterCapableTrait::class)] -#[CoversClass(SearchCapableTrait::class)] -#[CoversClass(OptionsCapableTrait::class)] -#[CoversClass(PagingCapableTrait::class)] +#[CoversTrait(SelectionCapableTrait::class)] +#[CoversTrait(SelectionBoundedTrait::class)] +#[CoversTrait(FilterCapableTrait::class)] +#[CoversTrait(SearchCapableTrait::class)] +#[CoversTrait(OptionsCapableTrait::class)] +#[CoversTrait(PagingCapableTrait::class)] #[Group('widget')] final class SearchWidgetTest extends TestCase { diff --git a/tests/phpunit/Unit/Widget/SelectWidgetTest.php b/tests/phpunit/Unit/Widget/SelectWidgetTest.php index 7b03d697..8daffe04 100644 --- a/tests/phpunit/Unit/Widget/SelectWidgetTest.php +++ b/tests/phpunit/Unit/Widget/SelectWidgetTest.php @@ -27,6 +27,7 @@ use DrevOps\Tui\Widget\Capability\SelectionCapableTrait; use DrevOps\Tui\Widget\SelectWidget; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\CoversTrait; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; @@ -35,11 +36,11 @@ */ #[CoversClass(SelectWidget::class)] #[CoversClass(AbstractWidget::class)] -#[CoversClass(OptionsCapableTrait::class)] -#[CoversClass(SelectionCapableTrait::class)] -#[CoversClass(SelectionBoundedTrait::class)] -#[CoversClass(FilterCapableTrait::class)] -#[CoversClass(PagingCapableTrait::class)] +#[CoversTrait(OptionsCapableTrait::class)] +#[CoversTrait(SelectionCapableTrait::class)] +#[CoversTrait(SelectionBoundedTrait::class)] +#[CoversTrait(FilterCapableTrait::class)] +#[CoversTrait(PagingCapableTrait::class)] #[Group('widget')] final class SelectWidgetTest extends TestCase { diff --git a/tests/phpunit/Unit/Widget/SuggestWidgetTest.php b/tests/phpunit/Unit/Widget/SuggestWidgetTest.php index b6ad8031..f04042b7 100644 --- a/tests/phpunit/Unit/Widget/SuggestWidgetTest.php +++ b/tests/phpunit/Unit/Widget/SuggestWidgetTest.php @@ -16,6 +16,7 @@ use DrevOps\Tui\Widget\Capability\PagingCapableTrait; use DrevOps\Tui\Widget\SuggestWidget; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\CoversTrait; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; @@ -24,7 +25,7 @@ */ #[CoversClass(SuggestWidget::class)] #[CoversClass(AbstractWidget::class)] -#[CoversClass(PagingCapableTrait::class)] +#[CoversTrait(PagingCapableTrait::class)] #[Group('widget')] final class SuggestWidgetTest extends TestCase { diff --git a/tests/phpunit/Unit/Widget/TextWidgetTest.php b/tests/phpunit/Unit/Widget/TextWidgetTest.php index 48808b27..8ecf655c 100644 --- a/tests/phpunit/Unit/Widget/TextWidgetTest.php +++ b/tests/phpunit/Unit/Widget/TextWidgetTest.php @@ -15,6 +15,7 @@ use DrevOps\Tui\Widget\Capability\TextEditCapableTrait; use DrevOps\Tui\Widget\TextWidget; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\CoversTrait; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; @@ -23,8 +24,8 @@ */ #[CoversClass(TextWidget::class)] #[CoversClass(AbstractWidget::class)] -#[CoversClass(TextEditCapableTrait::class)] -#[CoversClass(CompletionCapableTrait::class)] +#[CoversTrait(TextEditCapableTrait::class)] +#[CoversTrait(CompletionCapableTrait::class)] #[CoversClass(WidgetRunner::class)] #[Group('widget')] final class TextWidgetTest extends TestCase { diff --git a/tests/phpunit/Unit/Widget/TextareaWidgetTest.php b/tests/phpunit/Unit/Widget/TextareaWidgetTest.php index b564e2c7..8bc33076 100644 --- a/tests/phpunit/Unit/Widget/TextareaWidgetTest.php +++ b/tests/phpunit/Unit/Widget/TextareaWidgetTest.php @@ -13,6 +13,7 @@ use DrevOps\Tui\Widget\TextareaWidget; use DrevOps\Tui\Widget\Capability\TextEditCapableTrait; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\CoversTrait; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; @@ -20,7 +21,7 @@ * Tests the textarea widget. */ #[CoversClass(TextareaWidget::class)] -#[CoversClass(TextEditCapableTrait::class)] +#[CoversTrait(TextEditCapableTrait::class)] #[Group('widget')] final class TextareaWidgetTest extends TestCase { From a188bb2ac451424648646f2fafd8bbd9110fd2fb Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 27 Jul 2026 10:47:53 +1000 Subject: [PATCH 3/3] Addressed code review: aligned PHPUnit schema and Rector set with the 12 upgrade. Pointed 'phpunit.xml' at the 12.5 schema and switched the Rector set from 'PHPUnitSetList::PHPUNIT_110' to 'PHPUNIT_120'. The 120 set introduces no rewrites here, so this is a configuration alignment only. --- phpunit.xml | 2 +- rector.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 545b11ca..d6e622ea 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,5 +1,5 @@ -withSets([ - PHPUnitSetList::PHPUNIT_110, + PHPUnitSetList::PHPUNIT_120, ]) ->withRules([ DeclareStrictTypesRector::class,