phpspec / prophecy

Highly opinionated mocking framework for PHP 5.3+
MIT License
8.53k stars 242 forks source link

Fix deprecated nullable areguments #624 #625

Closed andypost closed 3 weeks ago

andypost commented 6 months ago

Related to #624

jrfnl commented 3 months ago

Would be lovely if this PR could get finished off and merged (and released!) as anyone who is currently using PHPUnit 9 to assess their own project's PHP 8.4 readiness is faced with a wall of deprecation notices coming from Prophecy.

@andypost Anything you need help with ? Want me to review something ?

andypost commented 3 months ago

@jrfnl thank, please help me to improve the code as I don't like amount of \count() added to separate fixes for constructors and return values

andypost commented 3 months ago

Personally I do use it as a part of patch for Drupal compatibility issue

stof commented 3 months ago

To make things easier to review, I'd like to see this PR split in 2:

andypost commented 3 months ago

I did split code-style related fixes into https://github.com/phpspec/prophecy/pull/630

stof commented 3 months ago

Please rebase this branch now that the other PR doing the CS changes on the codebase is merged.

stof commented 3 months ago

@andypost what is the case which requires the change in this PR ? Is it for any nullable optional argument, or only for cases where the original code is relying on an implicit nullable type ?

andypost commented 3 months ago

@stof example failures are

The test case code

  public function testUnknownExtension(): void {
    $module_extension_list = $this->prophesize(ModuleExtensionList::class);
    $profile_extension_list = $this->prophesize(ProfileExtensionList::class);
    $theme_extension_list = $this->prophesize(ThemeExtensionList::class);
    $theme_engine_extension_list = $this->prophesize(ThemeEngineExtensionList::class);
    $resolver = new ExtensionPathResolver(
      $module_extension_list->reveal(),
      $profile_extension_list->reveal(),
      $theme_extension_list->reveal(),
      $theme_engine_extension_list->reveal()
    );

The mocked class

public function __construct($root, $type, CacheBackendInterface $cache,

produce following output

    /builds/issue/drupal-3427903/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php(44)
    : eval()'d code:5
    Double\Drupal\Core\Extension\ModuleExtensionList\P1::__construct():
    Implicitly marking parameter $cache as nullable is deprecated, the explicit
    nullable type must be used instead

    Triggered by:

    *
    Drupal\KernelTests\Core\Bootstrap\ExtensionPathResolverTest::testUnknownExtension

    /builds/issue/drupal-3427903/core/tests/Drupal/KernelTests/Core/Bootstrap/ExtensionPathResolverTest.php:99
andypost commented 3 months ago

As I get it... when class with required typed constructor argument is mocked, prophecy making argument nullable but somehow without leading ? on PHP 8.4

stof commented 3 months ago

@andypost can you show the class definition of ModuleExtensionList ?

andypost commented 3 months ago

Sure, here's a link https://git.drupalcode.org/project/drupal/-/blob/e5653c11cd20e66831aca7e7a7568717baff5d9d/core/lib/Drupal/Core/Extension/ModuleExtensionList.php#L20

and I updated comment above

andypost commented 3 months ago

Even better link https://github.com/drupal/drupal/blob/e5653c11cd20e66831aca7e7a7568717baff5d9d/core/lib/Drupal/Core/Extension/ModuleExtensionList.php#L20

andypost commented 3 months ago

Fixed nullable types in spec and now it pass

stof commented 3 months ago

@andypost if you update the $container_modules_info argument of the ModuleExtensionList constructor to avoid using an implicit nullable type, does the double still use an implicit nullable type (without this PR applied) ?

andypost commented 3 months ago

@stof The $container_modules_info supposed to have default value and is not nullable and without patch reveal() just setting to null the CacheBackendInterface $cache but so my patch adding ? for such cases

andypost commented 3 months ago

The error is the same

    Double\Drupal\Core\Extension\ModuleExtensionList\P1::__construct():
    Implicitly marking parameter $cache as nullable is deprecated, the explicit
    nullable type must be used instead
stof commented 3 months ago

OK, apparently, those errors come from the DisableConstructorPatch which aims at making all constructor arguments optional.

the right fix is to update the implementation of that class patch so that it makes all arguments nullable as well (by updating the argument type) instead of adding a null default on non-nullable types. This would be much cleaner than making the code generator turn implicit nullable types to explicit ones.

andypost commented 2 months ago

@stof I can't make such big refactoring and need help to cover all cases

stof commented 1 month ago

@andypost now that the DisableConstructorPatch has been updated in #632, is there anything left in that PR that should be merged ?

Jean85 commented 1 month ago

This PR seems to fix the same issue (implicit nullable arguments deprecation) but with generated methods, not constructors, so I think it should be merged.

The problem reported in https://github.com/phpspec/prophecy/pull/625#issuecomment-2317858043 was covered by #632.

andypost commented 1 month ago

I bet both issues solving compatibility as I have no 8.4 code yet (property getting unexplored yet) So looking for minor release or kind of it, also looking for feedback as next RC just arrived!