fix: detect PHPUnit #[Test] attribute with fully-qualified name#121
fix: detect PHPUnit #[Test] attribute with fully-qualified name#121zoispag wants to merge 1 commit into
Conversation
Extends the phpunit-test runnable query to also match methods annotated
with a fully-qualified attribute such as:
#[\PHPUnit\Framework\Attributes\Test]
Previously only the short form `#[Test]` was matched, because the query
only handled `(attribute (name))`. For a FQDN attribute the tree-sitter
node is a `qualified_name` whose direct `name` child is the class name
("Test"); the namespace segments live inside the nested `prefix` field
and are not matched.
The fix adds an alternative branch `(qualified_name (name) @_attribute)`
alongside the existing `(name) @_attribute` inside the attribute match,
so both forms produce the gutter play button.
|
We require contributors to sign our Contributor License Agreement, and we don't have @zoispag on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
- Require a base_clause on the name-convention (*Test) patterns: a PHPUnit test class always extends TestCase (directly or transitively), so a *Test class with no `extends` is not PHPUnit and is no longer tagged phpunit-test (it is most likely a test from another framework). - Disambiguate method-level #[Test] by the imported attribute (PHPUnit\Framework\Attributes\Test) via the file's `use`, and by a fully-qualified #[\PHPUnit\Framework\Attributes\Test], instead of the class name — so it no longer misfires on another framework's method-level #[Test]. This supersedes zed-extensions#121, which matched any attribute whose last name segment is "Test" (and would also tag e.g. #[\Testo\Test] or #[\App\Test] as PHPUnit).
|
Thanks for tackling this — the fully-qualified One thing to consider about this approach: capturing only the last segment of the qualified name and checking To attribute it specifically to PHPUnit, it's safer to match the whole name: (attribute (qualified_name) @_attribute)
(#eq? @_attribute "\\PHPUnit\\Framework\\Attributes\\Test")For the short I ran into the same problem while adding Testo support and included this fix — the fully-qualified PHPUnit form plus the |
Problem
When a PHPUnit test method is annotated with the fully-qualified attribute form:
Zed does not show the ▷ gutter play button, so the test cannot be run from the editor. Only the short imported form
#[Test]triggers the runnable.Root cause
The
runnables.scmquery for the#[Test]case only matches a simplenamenode inside theattribute:(attribute (name) @_attribute) (#eq? @_attribute "Test")For a fully-qualified attribute, the tree-sitter PHP grammar produces a
qualified_namenode instead of a barename. According to the grammar definition,qualified_namehas the structure:The namespace segments (
PHPUnit,Framework,Attributes) are nested inside theprefixfield, while the class name (Test) is a directnamechild ofqualified_name. The existing query never reaches this node.Fix
Add an alternative branch
(qualified_name (name) @_attribute)inside the attribute match so both the short and fully-qualified forms are handled:(attribute [ (name) @_attribute (qualified_name (name) @_attribute) ] ) (#eq? @_attribute "Test")This covers:
#[Test]— short form (existing, unchanged)#[PHPUnit\Framework\Attributes\Test]— relative qualified form#[\PHPUnit\Framework\Attributes\Test]— fully-qualified form (global namespace prefix)