-
Notifications
You must be signed in to change notification settings - Fork 191
feat: add tests folder with phpstan level 8 solved all errors #417
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
base: master
Are you sure you want to change the base?
feat: add tests folder with phpstan level 8 solved all errors #417
Conversation
Why should we accept a generic object? It seems to me that your change decreases type safety rather than increasing it. |
derrabus
left a comment
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.
I think you're trying to solve too many problems at once. Running static analysis on the tests might be a good idea by itself, but let's not combine it with raising the PHPStan level.
| $pt1 = $this->pt1; | ||
| $this->assertNotNull($pt1); | ||
| $ch2 = $this->ch2; | ||
| $this->assertNotNull($ch2); | ||
| $gc1 = $this->gc1; | ||
| $this->assertNotNull($gc1); | ||
| $menu = $this->menu; | ||
| $this->assertNotNull($menu); |
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.
Those assertions don't make sense. We'd be testing our own test setup.
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.
I think that the assertions are needed, since if I remove for example for pt1, it produces:
Line tests/Knp/Menu/Tests/Iterator/CurrentItemFilterIteratorTest.php
------ -----------------------------------------------------------------
:20 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
This is mostly because ItemInterface declaration allows null, so phpstan could not infer that is non empty via the extends in MenuTestCase.
So the asserts remove the uncertain in this case and also the phpstan error. Let me know if you want or know another way to skip this error
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.
I understand which PHPStan error your change is coming from. It's just that cluttering the codebase with assertions is not the only (and rarely the best) way to fix them.
And from a sematic point of view: PHPUnit assertions are supposed to validate the state produced by the code under test. Here you're running a PHPUnit assertion before even testing anything.
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.
The only way to avoid this, I think that it should be changing and remove in MenuTestCase all the |null or ? per attribute class and avoiding to assign as null in the tearDown() of MenuTestCase, do you want that way instead this? That should clean out all assetNotNull warnings
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.
That sounds promising.
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.
Changed in f1db5be
| protected ?ItemInterface $menu; | ||
|
|
||
| protected ItemInterface|null $pt1; | ||
| protected ?ItemInterface $pt1; | ||
|
|
||
| protected ItemInterface|null $ch1; | ||
| protected ?ItemInterface $ch1; | ||
|
|
||
| protected ItemInterface|null $ch2; | ||
| protected ?ItemInterface $ch2; | ||
|
|
||
| protected ItemInterface|null $ch3; | ||
| protected ?ItemInterface $ch3; | ||
|
|
||
| protected ItemInterface|null $pt2; | ||
| protected ?ItemInterface $pt2; | ||
|
|
||
| protected ItemInterface|null $ch4; | ||
| protected ?ItemInterface $ch4; | ||
|
|
||
| protected ItemInterface|null $gc1; | ||
| protected ?ItemInterface $gc1; |
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.
Why?
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.
It is just sugar syntax for union types, very common in my opinion in a lot projects
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.
Okay, so the change is abosutely unrealted to and irrelevant for the goal that you're trying to achieve? Let's revert it then?
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.
Changed in f1db5be
The exact change is: Adding |object will allow pass the phpstan error. In this case I don't know another way to resolve this, but it is only affecting to phpstan side. I am open to make a change if you suggest a better way |
phpstan level is not raised in this PR, as you can see in master is level 8 https://github.com/KnpLabs/KnpMenu/blob/master/phpstan.neon#L2 I am just adding tests folder, and resolving the errors which appear in level 8 for tests folder |
no it is not only affecting phpstan. It changes the public API of the class, which affects what we need to cover with BC. |
what would you suggest instead?
|
| { | ||
| $count = 0; | ||
| foreach ($this->pt1 as $key => $value) { | ||
| foreach ($this->pt1->getChildren() as $key => $value) { |
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.
why ? This should not be needed. This test is even meant to cover the iterable API of the menu IMO, based on its name.
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.
Fixed at 2ccbffb
| yield 'skipping' => [fn (): ?bool => null, null]; | ||
| yield 'matching' => [[self::class, 'matchingCallable'], true]; | ||
| yield 'not matching' => [[self::class, 'notMatchingCallable'], false]; | ||
| yield 'skipping' => [[self::class, 'skippingCallable'], null]; |
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.
Why this change ?
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.
Originally was
Line CallbackVoterTest.php
:60 Anonymous function never returns null so it can be removed from the return type.
🪪 return.unusedType
:61 Anonymous function never returns null so it can be removed from the return type.
🪪 return.unusedType
But I over complicate doing a static function instead of closure. Reverting only solving the nullables at cf50474
| $this->assertCount(3, $this->pt1->getChildren()); | ||
| $this->assertCount(1, $this->pt2->getChildren()); | ||
| $this->assertCount(1, $this->ch4->getChildren()); | ||
| $this->assertEquals('Grandchild 1', $this->gc1->getName()); |
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.
This is totally changing the assertions being done. It does not test the integrity of the ArrayAccess anymore.
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.
Fixed at 584ec1e and other cases for ensure the ArrayAccess instead getChildren
| $this->menu->addChild('Child Menu'); | ||
| $this->assertEquals('Child Menu', $this->menu['Child Menu']->getName()); | ||
| $this->assertNull($this->menu['Fake']); | ||
| $this->assertEquals('Child Menu', $this->menu->getChildren()['Child Menu']->getName()); |
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.
This is not testing the ArrayAccess implementation anymore, while this is what the test is about.
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.
Fixed at 2d5281f
| abstract class MenuTestCase extends TestCase | ||
| { | ||
| protected ItemInterface|null $menu; | ||
| protected ?ItemInterface $menu; |
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.
To me, the right fix is to make all those properties non-nullable and removing the tearDown method that assigns them to null (which is useless as the Test object itself is dereferenced after it is tear down so everything will still be collected)
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.
Changed in f1db5be
| $names = []; | ||
| // FilterIterator expects an Iterator implementation explicitly, not an IteratorAggregate. | ||
| $iterator = new CurrentItemFilterIterator($this->menu->getIterator(), new Matcher()); | ||
| $iterator = new CurrentItemFilterIterator(new \ArrayIterator($this->menu->getChildren()), new Matcher()); |
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.
I'd rather use new IteratorIterator($this->menu), which is the built-in way in PHP to wrap a Traversable into an Iterator.
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.
Fixed at 3f6fef6
|
As I don't know what phpstan warning you are trying to fix, I cannot provide alternative fixes. Please provide the warning being reported. |
Full list of errors that I am fixing (around 283) over master in folder test directories: $ ./vendor/bin/phpstan analyse --level=8 ./tests/
Note: Using configuration file phpstan.neon.
28/28 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/Iterator/CurrentItemFilterIteratorTest.php
------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
:14 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:15 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:16 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:20 Cannot call method getIterator() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:20 Parameter #1 $iterator of class Knp\Menu\Iterator\CurrentItemFilterIterator constructor expects Iterator<TKey, Knp\Menu\ItemInterface>, Traversable<string, Knp\Menu\ItemInterface> given.
🪪 argument.type
:31 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:32 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:33 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:37 Parameter #1 $iterator of class Knp\Menu\Iterator\RecursiveItemIterator constructor expects Traversable<string, Knp\Menu\ItemInterface>, Knp\Menu\ItemInterface|null given.
🪪 argument.type
------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/Iterator/DisplayedItemFilterIteratorTest.php
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
:13 Cannot call method setDisplay() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:14 Cannot call method setDisplay() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:15 Cannot call method setDisplayChildren() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:19 Parameter #1 $iterator of class Knp\Menu\Iterator\RecursiveItemIterator constructor expects Traversable<string, Knp\Menu\ItemInterface>, Knp\Menu\ItemInterface|null given.
🪪 argument.type
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/Iterator/IteratorTest.php
------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
:14 Argument of an invalid type Knp\Menu\ItemInterface|null supplied for foreach, only iterables are supported.
🪪 foreach.nonIterable
:31 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:34 Parameter #1 $iterator of class Knp\Menu\Iterator\RecursiveItemIterator constructor expects Traversable<string, Knp\Menu\ItemInterface>, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:44 Parameter #1 $iterator of class Knp\Menu\Iterator\RecursiveItemIterator constructor expects Traversable<string, Knp\Menu\ItemInterface>, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:54 Parameter #1 $iterator of class Knp\Menu\Iterator\RecursiveItemIterator constructor expects Traversable<int, Knp\Menu\ItemInterface>, ArrayIterator<int, Knp\Menu\ItemInterface|null> given.
🪪 argument.type
------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------ ----------------------------------------------------------------------------------
Line Knp/Menu/Tests/Matcher/Voter/CallbackVoterTest.php
------ ----------------------------------------------------------------------------------
:60 Anonymous function never returns null so it can be removed from the return type.
🪪 return.unusedType
:61 Anonymous function never returns null so it can be removed from the return type.
🪪 return.unusedType
------ ----------------------------------------------------------------------------------
------ -------------------------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/MenuFactoryTest.php
------ -------------------------------------------------------------------------------------------------------------------------------
:62 Call to function method_exists() with $this(Knp\Menu\Tests\MenuFactoryTest) and 'contains' will always evaluate to false.
🪪 function.impossibleType
:66 Call to function method_exists() with $this(Knp\Menu\Tests\MenuFactoryTest) and 'containsEqual' will always evaluate to true.
🪪 function.alreadyNarrowedType
------ -------------------------------------------------------------------------------------------------------------------------------
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/MenuItemGetterSetterTest.php
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------
:174 Parameter #1 $children of method Knp\Menu\ItemInterface::setChildren() expects array<string, Knp\Menu\ItemInterface>, array<int, Knp\Menu\ItemInterface> given.
🪪 argument.type
:185 Cannot call method setName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------
------ -----------------------------------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/MenuItemTreeTest.php
------ -----------------------------------------------------------------------------------------------------------------------------------------
:16 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:17 Offset 'Parent 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:17 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:18 Offset 'Parent 2' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:18 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:19 Offset 'Child 4' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:19 Offset 'Parent 2' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:19 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:20 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:20 Offset 'Child 4' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:20 Offset 'Grandchild 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:20 Offset 'Parent 2' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:25 Cannot call method getLevel() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:26 Cannot call method getLevel() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:27 Cannot call method getLevel() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:28 Cannot call method getLevel() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:29 Cannot call method getLevel() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:34 Cannot call method getRoot() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:35 Cannot call method getRoot() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:36 Cannot call method getRoot() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:41 Cannot call method isRoot() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:42 Cannot call method isRoot() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:43 Cannot call method isRoot() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:48 Cannot call method getParent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:49 Cannot call method getParent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:50 Cannot call method getParent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:56 Parameter #1 $child of method Knp\Menu\MenuItem::addChild() expects Knp\Menu\ItemInterface|string, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:58 Cannot call method getLevel() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:59 Cannot call method getLevel() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:61 Cannot call method getRoot() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:62 Cannot call method getRoot() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:63 Cannot call method isRoot() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:65 Cannot call method getParent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:70 Cannot call method isFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:71 Cannot call method isFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:72 Cannot call method isFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:73 Cannot call method isFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:78 Cannot call method setDisplay() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:79 Cannot call method actsLikeFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:80 Cannot call method actsLikeFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:81 Cannot call method actsLikeFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:82 Cannot call method actsLikeFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:83 Cannot call method actsLikeFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:88 Cannot call method setDisplay() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:89 Cannot call method setDisplay() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:90 Cannot call method actsLikeFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:91 Cannot call method actsLikeFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:96 Cannot call method isLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:97 Cannot call method isLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:98 Cannot call method isLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:99 Cannot call method isLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:104 Cannot call method setDisplay() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:105 Cannot call method actsLikeLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:106 Cannot call method actsLikeLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:107 Cannot call method actsLikeLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:108 Cannot call method actsLikeLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:109 Cannot call method actsLikeLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:114 Cannot call method setDisplay() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:115 Cannot call method setDisplay() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:116 Cannot call method actsLikeLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:117 Cannot call method actsLikeLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:122 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:123 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:123 Offset 'Child Menu' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:124 Offset 'Fake' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:126 Knp\Menu\ItemInterface|null does not accept string.
🪪 offsetAssign.valueType
:127 Parameter #1 $object of function get_class expects object, string given.
🪪 argument.type
:128 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:128 Offset 'New Child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:129 Cannot call method getLabel() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:129 Offset 'New Child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:132 Offset 'New Child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:137 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:139 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:140 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:143 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:148 Cannot call method getChildren() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:150 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:155 Cannot call method getFirstChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:157 Cannot call method getChildren() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:159 Cannot call method getFirstChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:164 Cannot call method getLastChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:166 Cannot call method getChildren() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:168 Cannot call method getLastChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:195 Cannot call method getChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:196 Cannot call method getChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:201 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:202 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:203 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:204 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:205 Cannot call method removeChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:206 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:207 Cannot call method getChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:207 Cannot call method isFirst() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:208 Cannot call method getChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:208 Cannot call method isLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:213 Cannot call method removeChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:214 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:219 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:220 Cannot call method removeChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:221 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:222 Parameter #2 $haystack of method PHPUnit\Framework\Assert::assertCount() expects Countable|iterable, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:224 Cannot call method isLast() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:229 Cannot call method setName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:230 Cannot call method getChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:231 Cannot call method getChildren() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:232 Cannot call method getChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:239 Cannot call method setName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:245 Cannot call method getUri() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:246 Cannot call method getUri() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:246 Offset 'child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:251 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
------ -----------------------------------------------------------------------------------------------------------------------------------------
------ ---------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/Provider/ArrayAccessProviderTest.php
------ ---------------------------------------------------------------------------------------------------------------
:23 ArrayObject<*NEVER*, *NEVER*> does not accept Knp\Menu\ItemInterface&PHPUnit\Framework\MockObject\MockObject.
🪪 offsetAssign.valueType
:32 ArrayObject<*NEVER*, *NEVER*> does not accept Closure.
🪪 offsetAssign.valueType
:33 Cannot access offset 'options' on object.
🪪 offsetAccess.nonOffsetAccessible
------ ---------------------------------------------------------------------------------------------------------------
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/Provider/LazyProviderTest.php
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
:13 Parameter #1 $builders of class Knp\Menu\Provider\LazyProvider constructor expects array<string, array{Closure(): object, string}|(callable(): Knp\Menu\ItemInterface)>, array{first: Closure
(): void, second: Closure(): void} given.
🪪 argument.type
:46 Parameter #1 $builders of class Knp\Menu\Provider\LazyProvider constructor expects array<string, array{Closure(): object, string}|(callable(): Knp\Menu\ItemInterface)>, array{broken: stdCla
ss} given.
🪪 argument.type
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------ ---------------------------------------------------------------------------
Line Knp/Menu/Tests/Renderer/AbstractRendererTest.php
------ ---------------------------------------------------------------------------
:35 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:44 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:53 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:62 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:71 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:83 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:92 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:103 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:116 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:127 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:136 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:145 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:154 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:163 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:174 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:185 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:191 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:196 Cannot call method setAttribute() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:197 Cannot call method setAttribute() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:199 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:204 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:206 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:216 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:238 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:255 Cannot call method setChildrenAttribute() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:257 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:257 Offset 'Parent 2' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:262 Cannot call method setDisplayChildren() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:264 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:269 Cannot call method setDisplayChildren() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:269 Offset 'Parent 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:271 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:276 Cannot call method setDisplay() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:276 Offset 'Parent 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:278 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:284 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:290 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:296 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:301 Cannot call method setDisplayChildren() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:301 Offset 'Parent 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:303 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:309 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:314 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:314 Offset 'Child 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:314 Offset 'Parent 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:316 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:321 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:321 Offset 'Child 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:321 Offset 'Parent 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:323 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:328 Cannot call method setCurrent() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:328 Offset 'Child 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:328 Offset 'Parent 1' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:330 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
:337 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
------ ---------------------------------------------------------------------------
------ ----------------------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/Renderer/ArrayAccessProviderTest.php
------ ----------------------------------------------------------------------------------------------------------------------------
:23 ArrayObject<*NEVER*, *NEVER*> does not accept Knp\Menu\Renderer\RendererInterface&PHPUnit\Framework\MockObject\MockObject.
🪪 offsetAssign.valueType
:32 ArrayObject<*NEVER*, *NEVER*> does not accept Knp\Menu\Renderer\RendererInterface&PHPUnit\Framework\MockObject\MockObject.
🪪 offsetAssign.valueType
------ ----------------------------------------------------------------------------------------------------------------------------
------ --------------------------------------------------------------------------
Line Knp/Menu/Tests/Renderer/ListRendererTest.php
------ --------------------------------------------------------------------------
:30 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
------ --------------------------------------------------------------------------
------ --------------------------------------------------------------------------
Line Knp/Menu/Tests/Renderer/TwigRendererTest.php
------ --------------------------------------------------------------------------
:31 Cannot call method render() on Knp\Menu\Renderer\RendererInterface|null.
🪪 method.nonObject
------ --------------------------------------------------------------------------
------ ---------------------------------------------------------------
Line Knp/Menu/Tests/Twig/HelperTest.php
------ ---------------------------------------------------------------
:271 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:273 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:274 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:275 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:275 Offset 'c2_2' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:276 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:276 Offset 'c2_2' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:277 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:277 Offset 'c2_2' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:281 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
------ ---------------------------------------------------------------
------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/Twig/MenuExtensionTest.php
------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
:24 Call to an undefined method Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:30 Parameter #2 $helper of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Twig\Helper, Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:37 Call to an undefined method Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:43 Parameter #2 $helper of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Twig\Helper, Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:50 Call to an undefined method Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:56 Parameter #2 $helper of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Twig\Helper, Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:62 Call to an undefined method Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:68 Parameter #2 $helper of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Twig\Helper, Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:75 Call to an undefined method Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:80 Call to an undefined method Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:86 Parameter #2 $helper of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Twig\Helper, Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:92 Call to an undefined method Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:98 Parameter #2 $helper of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Twig\Helper, Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:106 Call to an undefined method Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:110 Call to an undefined method Knp\Menu\Util\MenuManipulator|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:116 Parameter #2 $helper of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Twig\Helper, Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:116 Parameter #4 $menuManipulator of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Util\MenuManipulator|null,
Knp\Menu\Util\MenuManipulator|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:124 Call to an undefined method Knp\Menu\Matcher\MatcherInterface|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:130 Parameter #2 $helper of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Twig\Helper, Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:130 Parameter #3 $matcher of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Matcher\MatcherInterface|null,
Knp\Menu\Matcher\MatcherInterface|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:138 Call to an undefined method Knp\Menu\Matcher\MatcherInterface|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:144 Parameter #2 $helper of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Twig\Helper, Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:144 Parameter #3 $matcher of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Matcher\MatcherInterface|null,
Knp\Menu\Matcher\MatcherInterface|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:151 Call to an undefined method Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:157 Call to an undefined method Knp\Menu\Matcher\MatcherInterface|PHPUnit\Framework\MockObject\MockObject::expects().
🪪 method.notFound
:163 Parameter #2 $helper of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Twig\Helper, Knp\Menu\Twig\Helper|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:163 Parameter #3 $matcher of method Knp\Menu\Tests\Twig\MenuExtensionTest::getTemplate() expects Knp\Menu\Matcher\MatcherInterface|null,
Knp\Menu\Matcher\MatcherInterface|PHPUnit\Framework\MockObject\MockObject given.
🪪 argument.type
:169 Parameter #1 $filename of function filemtime expects string, string|false given.
🪪 argument.type
:170 Parameter #1 $filename of function filemtime expects string, string|false given.
🪪 argument.type
------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Line Knp/Menu/Tests/Util/MenuManipulatorTest.php
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
:22 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::moveToFirstPosition() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:35 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::moveToLastPosition() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:48 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::moveToPosition() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:62 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::slice() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:75 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:75 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:76 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:76 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:76 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:77 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:77 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:78 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:79 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:79 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:80 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:80 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:93 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::split() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:109 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:110 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:110 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:111 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:111 Cannot call method getName() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:118 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::getPathAsString() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:119 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::getPathAsString() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:125 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:126 Cannot call method addChild() on Knp\Menu\ItemInterface|null.
🪪 method.nonObject
:130 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::getBreadcrumbsArray() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:133 Offset 'child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:134 Offset 'child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:134 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::getBreadcrumbsArray() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:139 Offset 'child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:142 Offset 'child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:142 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::getBreadcrumbsArray() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:152 Offset 'child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:159 Offset 'child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:159 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::getBreadcrumbsArray() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:169 Offset '123' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:170 Offset '123' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:170 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::getBreadcrumbsArray() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:176 Offset 'child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:179 Offset 'child' might not exist on Knp\Menu\ItemInterface|null.
🪪 offsetAccess.notFound
:179 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::getBreadcrumbsArray() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:188 Parameter #1 $item of method Knp\Menu\Util\MenuManipulator::getBreadcrumbsArray() expects Knp\Menu\ItemInterface, Knp\Menu\ItemInterface|null given.
🪪 argument.type
:188 Parameter #2 $subItem of method Knp\Menu\Util\MenuManipulator::getBreadcrumbsArray() expects array<int|string, array{label: string, uri: string|null, item: Knp\Menu\ItemInterface|null}|floa
t|int|Knp\Menu\ItemInterface|string|null>|string|Traversable<mixed, array{label: string, uri: string|null, item: Knp\Menu\ItemInterface|null}|float|int|Knp\Menu\ItemInterface|string|null>|n
ull, array{stdClass} given.
🪪 argument.type
------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[ERROR] Found 283 errors |
stof
left a comment
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.
Many of the changes you made were done in response to the previous way of fixing access to nullable test properties.
I suggest that you start from the master branch again (potentially from the commit fixing the invalid phpdoc type which is based on it), make the properties non-nullable, and then work on the remaining phpstan errors (which will be a lot less than on the master branch), to avoid all those useless change in the PR diff.
| * @param string|ItemInterface|array<int|string, mixed>|\Traversable<mixed>|null $subItem A string or array to append onto the end of the array | ||
| * | ||
| * @phpstan-param string|ItemInterface|array<int|string, string|int|float|null|array{label: string, uri: string|null, item: ItemInterface|null}|ItemInterface>|\Traversable<string|int|float|null|array{label: string, uri: string|null, item: ItemInterface|null}|ItemInterface>|null $subItem | ||
| * @phpstan-param string|ItemInterface|array<int|string, string|int|float|null|array{label: string, uri: string|null, item: ItemInterface|null}|ItemInterface|object>|\Traversable<string|int|float|null|array{label: string, uri: string|null, item: ItemInterface|null}|ItemInterface|object>|null $subItem |
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.
This must be reverted. the place where phpstan is reported an error is inside testBreadcrumbsArrayInvalidData, which is specifically testing the runtime behavior when passing invalid data (as not all users of the library might be using static analysis to catch such usage, and the code has some defense against that in that case).
the proper way to fix the phpstan warning is to use @phpstan-expect-error to make phpstan aware that an error is expected in that line.
| $this->gc1->setCurrent(true); | ||
| $pt1 = $this->pt1; | ||
| $ch2 = $this->ch2; | ||
| $gc1 = $this->gc1; |
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.
Those changes should be reverted
| $this->gc1->setCurrent(true); | ||
| $pt1 = $this->pt1; | ||
| $ch2 = $this->ch2; | ||
| $gc1 = $this->gc1; |
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.
Those changes should be reverted
| $this->ch4->setDisplayChildren(false); | ||
| $ch1 = $this->ch1; | ||
| $ch2 = $this->ch2; | ||
| $ch4 = $this->ch4; |
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.
Those changes should be reverted
| { | ||
| public function testIterator(): void | ||
| { | ||
| $pt1 = $this->pt1; |
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.
Those changes should be reverted
| /** @var Helper&MockObject $helper */ | ||
| $helper = $helperMock; | ||
| $matcher = null; | ||
| $manipulator = null; |
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.
should be reverted IMO.
| * @param array<string> $methods | ||
| */ | ||
| private function getHelperMock(array $methods): MockObject|Helper | ||
| private function getHelperMock(array $methods): MockObject |
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.
this should be documented as Helper&MockObject as return type instead, which is the proper type.
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.
same for the other mock methods below (with the corresponding type of course)
| { | ||
| $manipulator = new MenuManipulator(); | ||
| $sliced = $manipulator->slice($this->pt1, $offset, $length); | ||
| $pt1 = $this->pt1; |
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.
should be reverted.
|
|
||
| $ch1 = $this->ch1; | ||
| $ch2 = $this->ch2; | ||
| $ch3 = $this->ch3; |
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.
should be reverted.
| ->with(['foo' => 'bar']) | ||
| ->willReturn(['uri' => 'foobar']); | ||
| ->with(['uri' => 'foobar']) | ||
| ->willReturnArgument(0); |
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.
This changes the behavior of the test.
Type Safety and PHPStan Improvements
testsdirectory to PHPStan analysis inphpstan.neon, ensuring static analysis coverage for test files.@phpstan-paramdocblock inMenuManipulator.phpto allowobjecttypes in traversables and arrays, improving type safety for menu items.Improving the reliability and correctness of the test suite for menu iterators, filters, and factory logic, as well as enhancing type safety in PHPStan configuration and docblocks.
The main changes include refactoring tests to ensure proper variable initialization and null checks, updating iterator usage for consistency, and making minor improvements to type annotations and test mocks.
Test Logic and Mock Enhancements
MenuFactoryTestby correcting extension mock expectations and replacing the customcontainsCustomhelper with direct usage ofcontainsEqual, simplifying test assertions.CallbackVoterTest.Menu Item Getter/Setter Correction
MenuItemGetterSetterTestto use associative arrays, matching expected API usage and ensuring proper test coverage.