Allow the named selector to skip the partial fallback - #882
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #882 +/- ##
============================================
- Coverage 98.56% 98.46% -0.11%
- Complexity 389 393 +4
============================================
Files 24 25 +1
Lines 909 913 +4
============================================
+ Hits 896 899 +3
- Misses 13 14 +1 ☔ View full report in Codecov by Harness. |
|
Hi @Amoifr, thanks for working on this, I'm super keen for it to get in! I had a couple of points of feedback:
|
|
I think we should rather put those constants on a dedicated class than on |
| $this->assertEquals(array(), $finder->findAll('named', 'test', 'parent_xpath')); | ||
| } | ||
|
|
||
| public function testNamedExactModeStillReturnsExactMatches() |
There was a problem hiding this comment.
Please:
- rename this test into
testNamedExactModeDoesNotFallBackToPartial - drop the
testNamedExactModeDoesNotFallBackToPartial(declared above this one)
Most of test in this class assert search-behavior and return-behavior in the same method. No need to overcomplicate this by checking both things in separate test methods.
| public function __construct(DriverInterface $driver, ?SelectorsHandler $selectorsHandler = null) | ||
| /** | ||
| * @param ElementFinder::NAMED_* $namedMode How the "named" selector is resolved: an exact match | ||
| * falling back to a partial one, or an exact match only. |
There was a problem hiding this comment.
Maybe indentation is wrong (missing space before falling word).
|
|
||
| public function testNamedModeIsForwardedToTheElementFinder() | ||
| { | ||
| $selectorsHandler = $this->getMockBuilder('Behat\\Mink\\Selector\\SelectorsHandler')->getMock(); |
There was a problem hiding this comment.
Please use ::class with corresponding class import instead of specifying it's FQCN as string.
|
Agree with moving new class constants into a |
a20a286 to
6a1cd24
Compare
|
Thanks all three of you. Pushed everything that is not the open question. @andriokha you are right, and it undercuts my own argument on the issue: I said
Say which and I will move them in the next push. If it is a dedicated class it also needs a name, which is @stof's point about naming the enum we cannot write. The validation is back, @andriokha, with one consequence worth stating rather than hiding. The narrow @aik099, the three review points:
Suite green at 526 tests, PHPStan clean. |
Actually, we can have the precise type in phpdoc and the runtime guard by setting |
|
I suggest going for the separate class to hold the constants. Based on the packagist installation stats, I'm considering dropping support for PHP <8.1, which would then allow turning this separate class into an actual enum before releasing it. |
6a1cd24 to
890036b
Compare
|
Done, @stof. The constants now live in I put it in the use Behat\Mink\Selector\NamedSelectorMode;
$session = new Session($driver, $selectorsHandler, NamedSelectorMode::EXACT);That also answers @andriokha's objection properly: nothing users have to name is marked Suite green at 526 tests, PHPStan clean. |
| * | ||
| * This is the historical behaviour, and stays the default. |
There was a problem hiding this comment.
| * | |
| * This is the historical behaviour, and stays the default. |
I'd suggest avoiding describing historical behavior - code comments should describe how things work now imho. Source control can give historical information.
|
|
||
| public function __construct(DriverInterface $driver, ?SelectorsHandler $selectorsHandler = null) | ||
| /** | ||
| * @param string $namedMode How the "named" selector is resolved: one of the |
There was a problem hiding this comment.
I think the advantage of switching off treatPhpDocTypesAsCertain is we can be more specific with the type here without upsetting phpstan.
| * @param string $namedMode How the "named" selector is resolved: one of the | |
| * @param NamedSelectorMode::* $namedMode How the "named" selector is resolved: one of the |
890036b to
bb330a7
Compare
|
Both applied, thanks @andriokha. The second one corrects something I got wrong earlier in this pull request. I claimed the narrow The historical note is gone from the constant, you are right that git carries that. One thing I have left as is, so you can tell me if you would rather have it otherwise: Suite green at 526 tests, PHPStan clean. |
Just for transparency, I'm a nobody :)
Dunno if the maintainers think it's worth it, but you can always do something like the following prior to attempting to instantiate the class: $this->expectException(\Error::class); |
Fixes #880.
Implements the shape @aik099 settled on: an optional mode on
ElementFinderdeciding how thenamedselector resolves, and an optional mode onSessionthat forwards it. Nothing outside those two constructors changes, and both default to today's behaviour.ElementFinderstays untouched from the outside, which is the point of passing a mode rather than a finder instance: users never name a class that is marked@internal.On the tests you asked for
The mode reaching
ElementFinderis checked through behaviour rather than through a getter, since a fallback costs an extra driver query and that is observable.SessionTestcovers both directions:testNamedModeIsForwardedToTheElementFinderbuilds aSessionwithNAMED_EXACTand asserts the driver is queried once, so no partial lookup happened.testTheDefaultNamedModeStillFallsBackToPartialbuilds one without the argument and asserts the driver is queried twice.ElementFinderTestcovers each mode symmetrically, two tests per mode:testNamedFoundandtestNamedPartialFallbackfor the default,testNamedExactModeStillReturnsExactMatchesandtestNamedExactModeDoesNotFallBackToPartialfor the strict one. I checked they fail against an unmodifiedsrc/.One design note
The condition reads
self::NAMED_EXACT !== $this->namedModerather than testing for the default. It is the safer way round: a mode that is neither constant falls back to the historical behaviour instead of silently switching to strict.I first added a runtime guard rejecting unknown modes, then dropped it. PHPStan flagged the test for it, because the
@param self::NAMED_*annotation makes an invalid argument impossible statically, and this repository keeps level 8 clean without a single inline@phpstan-ignore. Inverting the condition made the guard unnecessary rather than merely unenforced.Full suite green, PHPStan clean. Point 3 of your plan shipped separately in #881.