New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
php: Add runnable tests #11514
php: Add runnable tests #11514
Conversation
90191b1
to
fb882a4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! Just leaving a few comments based on a version that I was working on before I saw that someone had beat me to it! 😄
Ahhh sorry man, didn't know that. I hope this satisfies your needs! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks Remco :)
I gonna add pest & docblock annotation support aswell. Working on it right now! |
Error: multiple different run targets found on a single line, only the last target will be rendered
It definitely does. No worries here! Thank you! |
You want to hack on the pest support together? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Thank you to doing this. It's certainly more robust that what I had hacked together! 😆
@osiewicz Can you help me out, I have the following 2 queries. They seem to work because I can see the runnable icon before the test functions. But when I click on them nothing happens, what am I missing here? Or not understanding correctly? It seems like it cannot get the value correctly from the query. This query support non-chaining methods: test("example", function () {
expect(true)->toBeTrue();
}); (
(expression_statement
(function_call_expression
function: (_) @name
(#any-of? @name "it" "test" "describe")
arguments: (arguments
(argument
(encapsed_string (string_value)) @run
)
)
)
)
) @pest-test This query support chaining methods: test("example", function () {
expect(true)->toBeTrue();
})->with(["1", "2"]); (
(expression_statement
(member_call_expression
object: (function_call_expression
function: (_) @name
(#any-of? @name "it" "test" "describe")
arguments: (arguments
(argument
(encapsed_string (string_value)) @run
)
)
)
)
)
) @pest-test |
…ne scheme This will allow to run the Pest runnable. Because before this change These function call expressions were not recognized as symbols. This resulted in that the Symbol key inside the task context not being set.
While digging inside the runnable/task code, looking why clicking the runnable icon inside the gutter for Pest runnable didn't open a new terminal panel to run the tests in. I finally found the issue that not only applies to Pest runnable. The issue is that the following code does not contain any symbols according to the Zed PHP outline scheme. <?php
test("example", function () {
expect(true)->toBeTrue();
});
describe("tests", function () {
test("test1", function () {
expect(true)->toBeTrue();
});
test("test2", function () {
expect(true)->toBeTrue();
});
});
it("has a name")
->expect(fn() => User::create(["name" => "Nuno Maduro"])->name)
->toBe("Nuno Maduro"); So when the task context is getting build inside So if we go higher up the stack we are trying to build a task from the task template, which could not be done because the symbol information does not exist inside the context which is required for the Pest task template. So I was talking to @osiewicz to explain what I found, why the Pest runnable did not work. So I came up with a fix for this issue by adding the following code to the PHP outline scheme: ; Add support for Pest runnable
(function_call_expression
function: (_) @context
(#any-of? @context "it" "test" "describe")
arguments: (arguments
(argument
(encapsed_string (string_value) @name)
)
)
) @item After adding this to the outline scheme, I got the Pest runnable too work😀 That being said, as I already mentioned we are going to have this issue with more languages. So @osiewicz came up with an idea to store the query captures inside the Env key of the task context. So we could use them instead of having to add these expressions to the outline scheme. NoteWe have to think about how we want to solve this in the feature. For now, having them inside the outline scheme is fine. |
This allows people to use the following code: ```php it("has a name") ->expect(fn() => User::create(["name" => "Nuno Maduro"])->name) ->toBe("Nuno Maduro"); --- And --- describe("tests in describe", function () { test("test1", function () { expect(true)->toBeTrue(); }); test("test2", function () { expect(true)->toBeTrue(); }); })->with(["1", "2"])->group("group1"); ```
This allows multiple chainable methods to be run in a single test
We have to do this because we cannot specify dynamic child node matching for more than one node. If you would have more than one chained method the previous version did not work. NOTE: This will also match test("asdf") inside function/method declarations..
27ac200
to
ef2b3ee
Compare
@osiewicz one thing I'm not happy about yet is that the Pest query/outline scheme is not specific enough. This results in invalid results that should not happen, but could. The original query/scheme that I made prevented this, but did not support more than one chained method. So ideally I want to wildcard all the member_call_expressions that are inside the expression_statement. Is there away to do this? I had a query similar to this to wildcard a single child node. (
(expression_statement
(_
(function_call_expression
function: (_) @name
(#any-of? @name "it" "test" "describe")
arguments: (arguments
(argument
(encapsed_string (string_value)) @run
)
)
)
)
)
) @pest-test |
Hey, wanna pair on it sometime later in the day? E.g. at 5 PM (we're in the same timezone). |
Yeah sure, sounds good! |
Can Pest tests be defined in classes, or are they only correct when defined at the "top level" of the file/script? If so, could it work to query for any |
Pest does not support the following methods Yeah, we have to do something like that. But I'm not sure how to do that. |
If this is the case, would it work to wrap the query in Is there a tree-sitter way to query for something that does not have a particular node as an ancestor? |
Yeah, adding the program as top level node inside the query fixes the issue that it matches also expressions inside the function/class declarations. The query looks like this: ; Match non chained methods for Pest test
(program
(expression_statement
(function_call_expression
function: (_) @_name
(#any-of? @_name "it" "test" "describe")
arguments: (arguments
.
(argument
(encapsed_string (string_value) @run)
)
)
)
)
) @pest-test So I expect that no one wraps them inside an |
@RemcoSmitsDev possible to add support for Laravel Dusk? |
@mansoorkhan96 You can make that possible by your self, when this pull request is merged by adding the following task to your {
"label": "laravel dusk test $ZED_SYMBOL",
"command": "php artisan dusk",
"args": ["--filter $ZED_SYMBOL $ZED_FILE"],
"tags": ["phpunit-test", "pest-test"]
} |
@RemcoSmitsDev I've merged main into this branch btw |
9fd6e08
to
ea831c2
Compare
Thanks! |
This PR bumps the PHP extension to v0.0.4. Changes: - #11514 Release Notes: - N/A
This pull request adds the following:
yield
keyword.describe
,it
andtest
function_call_expressions (to support Pest runnable)Queries explanations
Query 1 (PHPUnit: Run specific method test):
Test
suffixtest
prefixQuery 2 (PHPUnit: Run specific method test with
@test
annotation):Test
suffix@test
annotationQuery 3 (PHPUnit: Run specific method test with
#[Test]
attribute):Test
suffix#[Test]
attributeQuery 4 (PHPUnit: Run all tests inside the class):
Test
suffixQuery 5 (Pest: Run function test)
describe
,it
ortest
PHPUnit: Example for valid test class
PHPUnit: Example for invalid test class
All the methods should be ignored because you cannot run tests on an abstract class.
Pest: Example
Screen.Recording.2024-05-08.at.21.29.51.mov
You should now see all your Pest tests inside the buffer symbols modal.
Release Notes:
describe
,test
andit
functions to buffer symbols, to support Pest runnable.yield
keyword to PHP keyword mapping.