Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
@mondrake
How about deprecating also the assertEquals override in KernelTestBase and BrowserTestBase, so forcing tests to call explicitly castSafeStrings when needed?
@alexpott
the gain with it is less obvious.One thing that is interesting is instead of the assertEquals hack we could register a Comparator to compare MarkupInterface objects...
Comment | File | Size | Author |
---|---|---|---|
#60 | interdiff_57-60.txt | 3.93 KB | mondrake |
#60 | 3082340-60.patch | 10.07 KB | mondrake |
Comments
Comment #2
mondrakeOut of curiosity, I run the tests with the
assertEquals
override removed from the base classes in #3065023-56: Ignore, testing issue, and we only land with 44 test fails.Comment #3
mondrakeTest only patch, conditionally triggering deprecation errors when MarkupInterface objects are cast into strings in
assertEquals
.Comment #4
mondrakeComment #6
mondrakeThis is a first attempt at trying implementing a MarkupInterfaceComparator as suggested by @alexpott. No interdiff, it's a different approach.
Comment #7
mondrakeIf both expected and actual are MarkupInterface objects, there's no need to cast them to string (also because that fails in unit tests where there's no container available to resolve them to strings), and we can let the standard ObjectComparator do its job.
Comment #9
mondrake#7 does not work. We need to work on higher level and check if the container is initialised so that casting a MarkupInterface object to string is possible. If not, we are in a unit test and we need to fall back to ObjectComparator.
Comment #11
mondrakeActually, we do not need to resolve the conversion to string of MarkupInterface array items in the Comparator like in the assertEquals override. PHPUnit will use its own ArrayComparator to walk through the comparison of two arrays and break down each item into its own needed Comparator - and ours will then fit with the comparison of single MarkupInterface objects.
Comment #12
Krzysztof Domański1. In the new class
MarkupInterfaceComparator
theassertEquals
method contains an additional parameter ($processed
) that should be described. Dock block forassertEquals
cannot be inherited.2. Coding standards.
Comment #13
mondrakeAlso, needs tests. I am on it.
Comment #14
mondrakeThank you @Krzysztof Domański
This is fixing #12 and adding thorough testing of the new comparator.
Comment #15
mondrakeCode style fixes.
Comment #17
mondrakeRerolled.
Comment #19
mondrakeThe tests were not testing what I was expecting and the now stricter
assertTrue
andassertFalse
helped find that out!Comment #20
mondrakeComment #21
longwaveI think it is slightly more accurate to say something like "If at least one argument is a MarkupInterface object" here, as we also handle the case when both are objects?
Otherwise this looks good to me and will help with #3097892: Remove all @deprecated code in test base classes
Comment #22
mondrakeThanks @longwave, done #21.
Comment #23
longwaveDo we need an explicit dev dependency on
sebastian/comparator
now?Comment #24
mondrake#23 I don't think so, it is a requirement of phpunit/phpunit which would not work without, and I doubt we would be using the comparator in a dev environment without phpunit :)
Comment #25
longwaveNo, but do we need to pin a version/set of known working versions? Otherwise Comparator 4.0 may be released and it could be backward incompatible with what we are doing here?
Comment #26
mondrake#25 I'd let phpunit/phpunit manage it's own dependencies:
PHPUnit 6 has
"sebastian/comparator": "^2.1"
PHPUnit 7 has
"sebastian/comparator": "^3.0"
PHPUnit 8 has
"sebastian/comparator": "^3.0.2"
If we start pinning it down explicitly we may incur in PHPUnit not being able to update later
Comment #27
longwaveThanks for the explanation, I think that is OK - in which case this looks good to go to me.
Comment #28
alexpottHmmm... the container thing is a bit nasty. I wonder if we can add the comparator in a different place. For example, can we add it in the base test classes. I dunno.
Comment #29
longwaveThis might work?
Comment #30
longwaveFixed up the test data provider comment.
edit: @returns should be @return, that can be fixed on next patch or commit
Comment #31
alexpott@longwave nice one! TIL about \PHPUnit\Framework\TestCase::registerComparator() :)
Comment #32
mondrakeSo much nicer!
this is now an override of ::setUp, so the docblock should be @inheritdoc and $mock argument is no longer needed
I think these would benefit a short comment what they are about
Comment #33
longwaveThanks for review, addressed #30 and #32.
Comment #34
mondrake+1 to RTBC, but I cannot set it myself
Comment #35
longwaveAs a followup I wonder if we will be able to refactor away Drupal\Tests\AssertHelperTrait::castSafeStrings() as the code is suspiciously similar (although it also deals with arrays of MarkupInterfaces)
Comment #36
mondrake#35 interesting...
Comment #37
alexpottWhat's also super interesting is that I think we only need this comparator when both sides are MarkupInterface objects - otherwise the regular scalar comparator is going to do the work for us. And yes I think a follow-up to see if this allows us to deprecate Drupal\Tests\AssertHelperTrait::castSafeStrings() is a good idea. But that might mean that we need to do something for Unit tests.
Comment #38
longwaveLet's try your hypothesis from #37.
Comment #40
mondrakeLet's see if it's as easy as this.
edit - however hmmm... this can be a change in behaviour impacting contrib tests
Comment #41
alexpottYeah I think we should go back to #33 unfortunately.
Let's drop this in favour of doing
Less methods and simpler.
Comment #42
longwaveI think #33 is better in order to deal with the int vs MarkupInterface case, as otherwise this would trigger NumericComparator which doesn't support objects, but I think this is a valid thing to try and do in a test.
Comment #44
mondrakeWorking on #41. @longwave re. #42 I'm not sure I understand what you mean, can you elaborate?
Comment #45
mondrakeHere's #41, interdiff vs #33.
Comment #46
mondrakeComment #48
mondrakeThis should do.
Comment #49
longwaveIn #42 I was just trying to say that I think the #33 approach is both valid and correct, and we need to handle more than just the case where both sides are MarkupInterfaces, but I did not explain that very well :)
Comment #50
mondrake@longwave :) so nothing else to do here then
Comment #51
alexpottI'm pretty sure that we can cast to string here without the
$expected instanceof MarkupInterface
What is fixing #45 is now we stringify when both are MarkupInterface objects.
Comment #52
longwave@alexpott That blew up the test when I tried it as neither array nor stdClass can be cast to string, but I guess that part of the test is invalid anyway, as it will never be called with these arguments. It does however mean int is cast to string but I suppose that doesn't ultimately matter?
Comment #53
mondrakeLike this?
Comment #54
longwaveI think that looks OK, a clever way of testing the three possible states that I hadn't thought of. Tentatively marking RTBC even though I worked on some of this, hope that's OK.
Comment #55
longwaveOn second thoughts I think we need to assert that $equals_result is TRUE after this, if no exception was thrown?
Comment #56
mondrakeFair, I am on it
Comment #57
mondrakeDone #55, and improved tests a bit.
Comment #58
longwaveNice work, the changes are all good improvements.
Comment #59
alexpottJust realised this in the main core namespace. Let's put this in the test tools. There's no need for this to be autoloadable by the non test core autoloader.
Also this will make our life simpler if as probable Comparator changes signature in different PHPUnit versions.
Comment #60
mondrakeDone #59.
Comment #61
longwaveBack to RTBC.
Comment #62
alexpottSo we should favour composition over inheritance :)
Committed and pushed 398a61b7e0 to 9.0.x and 8d8cff8854 to 8.9.x. Thanks!
Comment #65
longwaveGreat! Raised #3101247: Deprecate AssertHelperTrait::castSafeStrings() in favour of MarkupInterfaceComparator as followup.
Comment #66
mondrakeHow about backporting this to 8.8.x? To have consistency across.
Comment #67
alexpott@mondrake I don't think it is worth it. We're not going to make major changes to 8.8.x now. And there's enough to think about with 9.0.x and 8.9.x