False positives with `assertSame` on generics with compatible subtypes

Open
#105 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
php
Domain
testing, tooling

Research direction

Start by reproducing the reported assertSame diagnostic with the CollectionAbstractModel and CollectionPaymentMethods examples. Trace the assertSame rule's handling of generic type arguments, then add a regression test for compatible contained types. Done means valid identity assertions no longer produce a false-positive while genuinely incompatible types remain reported.

Written by the indexing model from the issue text.

Description

I have a Collection container class that uses generics:


/**
 * This class represents a list of models.
 *
 * @template M of AbstractModel
 * @extends \SplObjectStorage<M, int>
 */
class Collection extends \SplObjectStorage
{
     …
}

(with AbstractModel being the abstract base class for domain models)

Now I get error messages like this:

  3069   Call to static method PHPUnit\Framework\Assert::assertSame() with      
         OliverKlee\Oelib\DataStructures\Collection<OliverKlee\Oelib\Model\Abs  
         tractModel> and                                                        
         OliverKlee\Oelib\DataStructures\Collection<Tx_Seminars_Model_Organize  
         r> will always evaluate to false.               

(Organizer is a subclass of AbstractModel, as is PaymentMethods used in the example below.)

for code that basically looks like this (simplified):


class Event
{
    /**
     * @return Collection<PaymentMethods>
     */
    public function getPaymentMethods(): Collection;

    /**
     * @param Collection<PaymentMethods> $paymentMethods
     */
    public function setPaymentMethods(Collection $paymentMethods): void;
}

class EvenTest
{
    public function testPaymentMethodsSetsPaymentMethods(): void
    {
        $paymentMethods = new Collection();
        $this->subject->setPaymentMethods($paymentMethods);

        self::assertSame($paymentMethods, $this->subject->getPaymentMethods());
    }
}

So either the check for assertSame should completely disregard the contained type within generics, or it should allow contained types that are compatible to each other.

Dominant language
PHP
Stars
544
Forks
58
Avg merge
2d 1h
Merged PRs (30d)
5

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from phpstan/phpstan-phpunit

All issues in phpstan/phpstan-phpunit

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.