phpspec / prophecy

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

Double has signatures that are incompatible with prophesized interface when using self #484

Closed greg0ire closed 4 years ago

greg0ire commented 4 years ago

Observed this twice with 2 different classes already while working on https://github.com/sonata-project/SonataAdminBundle/pull/6186 :

Fatal error: Declaration of Double\ItemInterface\P22::setParent(?Double\ItemInterface\P22 $parent = NULL): Knp\Menu\ItemInterface must be compatible with Knp\Menu\ItemInterface::setParent(?Knp\Menu\ItemInterface $parent = NULL): Knp\Menu\ItemInterface in /home/greg/dev/SonataAdminBundle/vendor/bin/.phpunit/phpunit-8.5.0-0/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php(49)

Fatal error: Declaration of Double\FormInterface\P30::setParent(?Double\FormInterface\P30 $parent = NULL) must be compatible with Symfony\Component\Form\FormInterface::setParent(?Symfony\Component\Form\FormInterface $parent = NULL) in /home/greg/dev/SonataAdminBundle/vendor/bin/.phpunit/phpunit-8.5.0-0/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php(49)

In both cases, the interface references itself in the signature.

Possible next steps:

use Prophecy\Prophet;

require 'vendor/autoload.php';

interface SelfReferencing { public function __invoke(self $self); }

$selfReferencing = (new Prophet)->prophesize(SelfReferencing::class); $selfReferencing->reveal();


- [x]  bisect that issue down to a particular commit :arrow_forward: bf3f063a739b4f856ec0e88c75b61cb3a60ffc89 from #477
- [x]  Contribute [a failing test](https://github.com/phpspec/prophecy/pull/485)
- [x]  Diagnose the issue: `self` is a special case: https://3v4l.org/CVWn1 and needs to be handled accordingly
- [x]  Contribute [a fix](https://github.com/phpspec/prophecy/pull/485)
greg0ire commented 4 years ago

@Ayesh can you please take a look?

Ayesh commented 4 years ago

I hope it's OK to CC @stof, and hopefully @GrahamCampbell. They both recently worked on many PHP 8 upgrade changes, so hopefully we can get their valuable feedback as well.

My primary guess is that ClassMirror::getParameterClassName is not accommodating self well. Thanks for providing a failing test (#485), I will take a look now.

greg0ire commented 4 years ago

I just came to the same conclusion 👍, see my fourth checkbox

greg0ire commented 4 years ago

@Ayesh I think I found a fix, will amend #485

greg0ire commented 4 years ago

@Ayesh done, please review.

lchrusciel commented 4 years ago

We've experienced same issue in Sylius. Thanks for your contribution 👍