Skip to content

PHPLIB-462: ensure compatibility with PHP 7.4 #665

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

Merged
merged 6 commits into from
Aug 20, 2019

Conversation

alcaeus
Copy link
Member

@alcaeus alcaeus commented Aug 9, 2019

While we're not going to be running any PHP 7.4 features for a while, we at least want to make sure that we test the library on PHP 7.4. This requires upgrading to newer PHPUnit releases to avoid errors due to the deprecation of the __toString methods in reflection classes.

Upgrading to PHPUnit 7 or newer is non-trivial, as support for PHP 5 was dropped and PHPUnit introduces type hints. To cope with that, we use symfony/phpunit-bridge to provide compatibility layers for the TestCase class. Once symfony/symfony#33078 is merged, we can also drop the constraint traits from this packages. However, since the traits are marked as @internal we don't need to wait for a merge of that pull request and can drop them once they're available in symfony/phpunit-bridge.

@alcaeus alcaeus self-assigned this Aug 9, 2019
@alcaeus alcaeus changed the title [WIP] PHPLIB-462: ensure compatibility with PHP 7.4 PHPLIB-462: ensure compatibility with PHP 7.4 Aug 13, 2019
@alcaeus alcaeus requested review from kvwalker and jmikola August 13, 2019 11:59
Copy link
Member

@jmikola jmikola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

symfony/symfony#33078 appears to have been merged already.

Was that related to using ^4.4@dev in composer.json, or do we still need that until a tagged release is made upstream?

A couple of other questions, but changes LGTM.

backupStaticAttributes="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.3/phpunit.xsd"
beStrictAboutOutputDuringTests="true"
beStrictAboutChangesToGlobalState="true"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I correct that this option was introduced in 4.6 (see: blog post), even though it was never documented? I'm not sure about beStrictAboutOutputDuringTests, but there are some online references to that dating back to 2015 so I assume that's fine.

Just wanted to confirm that these will apply to all PHPUnit versions we use for testing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XSD option was added in sebastianbergmann/phpunit@9101f51#diff-365e6053dce410a51198fc699549f0ae, which was first included in 4.0.0. The comments in the code indicate that the functionality itself was added in 3.8.0, so we should be safe here.

The reason this was added is that I regenerated a new configuration file using phpunit --generate-configuration to account for changes in the default configuration.

*/
trait PolyfillAssertTrait
{
use SymfonyPolyfillAssertTrait;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason that PolyfillAssertTrait doesn't have a compat shim, like SetUpTearDownTrait?

Is that because it really is only relevant to older PHPUnit versions, so Symfony is careful not to use it in newer branches?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I talked to @nicolas-grekas about this. The assertion polypill is marked as @internal because they only use it to patch PHPUnit classes in their simple-phpunit binary: https://github.com/symfony/symfony/blob/a9ace363899373f4fed96f32cd38fc94187666d2/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php#L154..L157. With the myriad of PHPUnit versions Symfony needs to support, it's too risky for them to have a single trait and let people use that in classes extending from PHPUnit\Framework\Assert, as it would then override the methods already shipped by PHPUnit. Patching the original class works around this issue as the code in PHPUnit\Framework\Assert then overrides the trait code.

In our case, I didn't want to patch PHPUnit code and with the PHPUnit versions we currently support, the single trait is good enough for us as all new assertion methods were added in or after PHPUnit 7. That's why we declare our own trait, which is empty if the PHPUnit version is new enough, as it allows us to always include our polyfill trait in the test classes.

There is still a certain risk using internal code from Symfony, but given that they need to keep the trait around as long as they support PHPUnit < 7 I feel rather confident there: dropping older PHPUnit versions for them won't be possible until Symfony 4.4 is EOL, which will be in November 2023. I hope we'll be able to get rid of support for PHP 5 before then. However, if you'd rather not use an internal class we can always duplicate the polyfill to our library, of course keeping the original copyright intact.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or you could use simple-phpunit :)
But I agree, the risk is low.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the deep explanation! I'm content with this.

@nicolas-grekas: Thanks for chiming in. simple-phpunit looks interesting (first I've seen of it) and is probably something (along with the bridge) that I could have benefited from a good while back 😄. I'll defer to @alcaeus about whether it's worth migrating over to that at some later point.

private $expectedCollection;

public function setUp()
private function doSetUp()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm, can we still chain to parent::setUp() below despite this method being renamed to doSetUp()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is still possible. The parent::setUp() call in doSetUp will always go to the parent class. In this case, the parent (FunctionalTestCase) also includes the trait, so the call will again land in the shim and call the doSetUp method that is written in FunctionalTestCase. Chaining the setup/teardown methods is still possible as before, we just have to remember to use the polyfill trait and write doSetUp methods until we can get rid of PHPUnit < 8.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirm: the trait has been designed so that only the signature of the method is changed, and not its body.

@alcaeus
Copy link
Member Author

alcaeus commented Aug 20, 2019

symfony/symfony#33078 appears to have been merged already.

Yes, I originally included the code I PR'ed to Symfony in this library, but now that it has been merged we no longer need to include it ourselves.

Was that related to using ^4.4@dev in composer.json, or do we still need that until a tagged release is made upstream?

Symfony 4.4 will be released in November, so we have to use an @dev release until then. I don't like relying on pre-release versions, but in this case it's the only option we have if we want to test on PHP 7.4 without PHPUnit causing deprecation errors and tripping over them itself. PHPUnit 7.5.15 will fix this (once released), but that version wouldn't be installable without changes either so I decided to update to the newest version where possible. Once Symfony 4.4 is released, I'll update the version constraint to require a stable release.

@alcaeus alcaeus removed the request for review from kvwalker August 20, 2019 09:16
alcaeus added a commit that referenced this pull request Aug 20, 2019
@alcaeus alcaeus merged commit e0c6531 into mongodb:master Aug 20, 2019
@alcaeus alcaeus deleted the php-7.4-compat branch August 20, 2019 09:24
@jmikola
Copy link
Member

jmikola commented Aug 20, 2019

Once Symfony 4.4 is released, I'll update the version constraint to require a stable release.

Please make a PHPLIB ticket as a reminder to do so (if you haven't already).

@alcaeus
Copy link
Member Author

alcaeus commented Aug 20, 2019

Created PHPLIB-465 to track changing the dev requirement after the release of Symfony 4.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants