bmewburn / vscode-intelephense

PHP intellisense for Visual Studio Code
https://intelephense.com
Other
1.64k stars 93 forks source link

Cannot get autocomplete to work with Pest (works fine with PHP unit) #2181

Closed swikrit closed 2 years ago

swikrit commented 2 years ago

Describe the bug In my Pest files I cannot get autocomplete to work. So $this->assert would normally give me a lot of options on PHP Unit but none in a pest file.

I did find thanks to the answer here: https://github.com/pestphp/pest/discussions/419#discussioncomment-1564573 that adding /**@var TestCase $this */ to an individual test fixes this. Can we expect an update to have this work automatically? Or perhaps there already is a method I just can't seem to find.

To Reproduce Create a test file using Pest and try to assert anything

Expected behavior I was hoping the same autocomplete that works for PHP Unit will work here.

jorqensen commented 2 years ago

While this issue is quite old, some might find this answer useful.

I do not believe it's the job for Intelephense to provide you Intellisense for calling $this-> in a closure outside of a class, even if it actually works behind the scenes.

Pest is designed and inspired by JavaScript testing frameworks such as Jest where you should use a function based approach of testing.

Take a look at this example:

use function PHPUnit\Framework\assertArrayHasKey;
use function PHPUnit\Framework\assertTrue;

it('asserts that true is true', function () {
    assertTrue(true);
});

it('asserts array has key', function () {
    $array = [
        'foo' => '123123123',
        'bar' => '987987987'
    ];

    assertArrayHasKey('foo', $array);
});

Both of these tests will pass - while Intelephense will provide you auto-import suggestions for the functions. So you should just write out the type of assertion you'd want, without prefixing $this->.

The same works for plugins, such as the Laravel plugin for get() and assertDatabaseHas() etc.

This issue can probably be closed with this in mind @bmewburn - perhaps placed within a FAQ somewhere.

swikrit commented 2 years ago

Thank you!

johnRivs commented 1 year ago

I gave it a try but I'm not quite getting fuzzy search to work on auto complete suggestions the way I'd expect it to. Am I doing something wrong or do I just have a wrong understanding of how fuzzy search is meant to behave?

jorqensen commented 1 year ago

Hello @johnRivs

  1. Did you follow the Intelephense README and disable @builtin php language features?

image

  1. Did you remember to follow the Pest documentation for Laravel support, by running:
composer require pestphp/pest-plugin-laravel --dev
php artisan pest:install

In doing so, when you type get and autocomplete, your editor should auto-import use function Pest\Laravel\get;. This will give you intellisense for chaining assertions to the function:

image

You can read more on the Pest Laravel plugin page in the documentation.

Hope this helps. 👍

johnRivs commented 1 year ago

Hey, thanks for your response.

Yes to both. I do get get imported when I press enter on the autocompletion. From there, fuzzy search on suggestions work.

However, I was more worried about the other stuff. In regular PHPUnit tests, I can $this->assdh and get it:

What's interesting is, when I type assert in Pest, you can see assertDatabaseHas so Intelephense knows it exists. assd won't work though :/ No luck with higher order tests either.

I'm on Intelephense 1.8.2, in case that matters.

jorqensen commented 1 year ago

Hey again @johnRivs

Please refer to my previous message in regards to using $this in Pest.

If there should be completions on $this inside a closure. That should be an entire plugin in itself dedicated to Pest, sort of like the PHPStorm Pest Plugin.

I do not believe it's Intelephense job to provide completions to this, as it leverages PHP's dynamic features to achieve this behavior. Intellisense etc. has and will always be better in a statically typed language, but PHP is classified as a dynamic language.

This is also why you experience your IDE isn't aware of things like User::where() in Laravel, as it makes use of the PHP __callStatic method to "proxy" the static call to the actual method. This is however easily avoided by using User::query()-> thanks to a PR for the framework. So as you can see, they fixed it by actually writing "proper" code. 😉

Higher order tests seem to work just fine for me, though higher order assertDatabaseHas() etc. are sort of broken, that's right. I think that's due to Pest source with the return type/docblocks though. I have not dived enough in the source to confirm this, but I have a pretty decent gut feeling.

If you check the source for the use function Pest\Laravel\assertDatabaseHas;, you can see it just calls a higher order:

/**
 * Assert that a given where condition exists in the database.
 *
 * @return TestCase
 */
function assertDatabaseHas(string $table, array $data, string $connection = null)
{
    return test()->assertDatabaseHas(...func_get_args());
}

Perhaps this would have value to open as an issue on the Pest repository.

I can't get assd to work either, I do not think Intelephense has this level of fuzzy searching for functions & methods unfortunately. It has personally not bothered me, but obviously worth mentioning for the maintainer.

NB: Remember to re-index your workspace in case you have some fuzzy/completions that don't seem to work, just in case:

image

johnRivs commented 1 year ago

I was not using $this in my GIF. My "I gave it a try" was about using functions. I said "In regular PHPUnit tests" to draw the comparison. I didn't know Intelephense didn't behave the same way completing methods in $this vs. completing functions.

I guess I gotta start being a bit more thorough when writing these names. Thank you for your time @jorqensen.

jorqensen commented 1 year ago

Ah sorry, my bad @johnRivs. I missed the point you were trying to make.

Anyways, if anyone comes across this issue they'll have a more thorough answer to my intial post.

Glad to be of help. 👍

kenng commented 1 year ago

Just as a note, if you prefer not to include the whole vendor folder for Intelephense to scan, you can add the following settings for the VS Code plugin:

settings.json

    "intelephense.environment.includePaths": [
        "./vendor/pestphp",
        "./vendor/phpunit/phpunit",
        "./vendor/laravel"
    ],