diff --git a/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php b/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php index 674c8075..6b5c9e6d 100644 --- a/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php +++ b/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php @@ -248,22 +248,23 @@ class GenExtTestMatrixCommand extends BaseCommand } } - if (!empty($filter_extensions)) { - $entries = array_values(array_filter($entries, function (array $entry) use ($filter_extensions): bool { + if (!empty($filter_extensions) || !empty($filter_libs)) { + $entries = array_values(array_filter($entries, function (array $entry) use ($filter_extensions, $filter_libs, $all_ext_lib_deps): bool { $names = explode(',', $entry['extension']); - return count(array_intersect($names, $filter_extensions)) > 0; - })); - } - if (!empty($filter_libs)) { - $entries = array_values(array_filter($entries, function (array $entry) use ($filter_libs, $all_ext_lib_deps): bool { - $names = explode(',', $entry['extension']); - $lib_deps = $all_ext_lib_deps[$entry['os']] ?? []; - foreach ($names as $name) { - if (count(array_intersect($lib_deps[$name] ?? [], $filter_libs)) > 0) { - return true; + if (!empty($filter_extensions) && count(array_intersect($names, $filter_extensions)) > 0) { + return true; + } + + if (!empty($filter_libs)) { + $lib_deps = $all_ext_lib_deps[$entry['os']] ?? []; + foreach ($names as $name) { + if (count(array_intersect($lib_deps[$name] ?? [], $filter_libs)) > 0) { + return true; + } } } + return false; })); } diff --git a/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php b/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php index 4e3fc33a..4db6da59 100644 --- a/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php +++ b/tests/StaticPHP/Command/Dev/GenExtTestMatrixCommandTest.php @@ -190,6 +190,17 @@ class GenExtTestMatrixCommandTest extends TestCase } } + /** + * Multiple filters should include entries matching any changed package. + */ + public function testExtensionAndLibraryFiltersAreCombinedAsUnion(): void + { + $matrix = $this->runMatrix(['--os' => 'Linux', '--for-extensions' => 'simdjson', '--for-libs' => 'libde265']); + + $this->assertNotEmpty($this->findEntriesContaining($matrix, 'simdjson'), 'simdjson entry must be included'); + $this->assertNotEmpty($this->findEntriesContaining($matrix, 'imagick'), 'imagick entry must be included through libde265'); + } + /** * --tier2 must produce only Tier2 runners and no Windows entries. */ @@ -272,6 +283,7 @@ class GenExtTestMatrixCommandTest extends TestCase * - ext-swoole-hook-* virtual (arg-type: none) — must be bundled with swoole * - ext-curl simple orphan, depended on by swoole but must NOT be pulled into swoole entry * - ext-redis simple orphan + * - ext-simdjson simple orphan used for combined filter tests * - ext-xml depends on lib 'libxml2' * - ext-dom depends on ext-xml (DFS chain) * - ext-imagick depends on imagemagick -> libheif -> libde265 @@ -295,6 +307,7 @@ class GenExtTestMatrixCommandTest extends TestCase // Simple orphans 'ext-curl' => $ext(), 'ext-redis' => $ext(), + 'ext-simdjson' => $ext(), // DFS chain: dom depends on xml; xml depends on lib 'libxml2' 'ext-xml' => $ext(['arg-type' => 'standard'], ['depends' => ['libxml2']]),