Ensure column options map to an existing method#2846
Ensure column options map to an existing method#2846Ocramius merged 5 commits intodoctrine:masterfrom
Conversation
5c2747d to
4cfec3a
Compare
lib/Doctrine/DBAL/Schema/Column.php
Outdated
| if (method_exists($this, $method)) { | ||
| $this->$method($value); | ||
| if (!method_exists($this, $method)) { | ||
| throw InvalidArgumentException::fromUnsupportedOption($name); |
There was a problem hiding this comment.
Might be considered a BC-break, tell me if you want me to trigger deprecation errors instead.
There was a problem hiding this comment.
I notice that it does not seem to be used anywhere in the code, but maybe you're not against it?
There was a problem hiding this comment.
Yes, this could indeed be considered unnecessary BC break in 2.x for no real benefit... And I'm not even sure deprecation notice is worth it. Maybe we should just retarget this to develop/3.0?
There was a problem hiding this comment.
How about retargetting only this part, and merging the rest in master, since it's BC?
There was a problem hiding this comment.
for no real benefit...
A smooth upgrade path for people misusing this method is a good benefit IMHO. And the number of misuses I found in doctrine/dbal alone suggests this might be useful to many, don't you think.
There was a problem hiding this comment.
Agreed, I meant there is "no real benefit" in throwing an exception in 2.x due possible BC concerns.
Anyway, I'm not sure what is the correct approach regarging deprecations. I think the silent variant (what i.e. Symfony does) @triger_error('blahblah', E_USER_DEPRECATED) would be just fine. We will eventually need to deprecate multiple things anyway at latest in last 2.x before 3.0 comes (especially in ORM).
There was a problem hiding this comment.
Great, I'll go with that then!
There was a problem hiding this comment.
It's funny to see old options in the tests, that had no use at all. I like the stricter handling with that exception, but I agree on BC and the deprecation trigger.
There was a problem hiding this comment.
To test it properly, I will need to make simple-phpunit work though :(
Right now I get:
PHP Fatal error: Class 'Doctrine\Tests\DbalTestCase' not found in /home/greg/dev/dbal/tests/Doctrine/Tests/DBAL/Cache/QueryCacheProfileTest.php on line 9
Fatal error: Class 'Doctrine\Tests\DbalTestCase' not found in /home/greg/dev/dbal/tests/Doctrine/Tests/DBAL/Cache/QueryCacheProfileTest.php on line 9
|
ping |
lib/Doctrine/DBAL/Schema/Column.php
Outdated
| $method = "set".$name; | ||
| if (method_exists($this, $method)) { | ||
| $this->$method($value); | ||
| if (!method_exists($this, $method)) { |
There was a problem hiding this comment.
There should be a space around !.
lib/Doctrine/DBAL/Schema/Column.php
Outdated
| if (method_exists($this, $method)) { | ||
| $this->$method($value); | ||
| if (!method_exists($this, $method)) { | ||
| throw InvalidArgumentException::fromUnsupportedOption($name); |
There was a problem hiding this comment.
Yes, this could indeed be considered unnecessary BC break in 2.x for no real benefit... And I'm not even sure deprecation notice is worth it. Maybe we should just retarget this to develop/3.0?
| return new self('Empty criteria was used, expected non-empty criteria'); | ||
| } | ||
|
|
||
| public static function fromUnsupportedOption(string $name): self |
There was a problem hiding this comment.
Spaces between return types.
65a4dcd to
b388d42
Compare
.travis.yml
Outdated
| - travis_retry composer -n install | ||
|
|
||
| script: ./vendor/bin/phpunit --configuration tests/travis/$DB.travis.xml | ||
| script: SYMFONY_DEPRECATIONS_HELPER=weak_vendors ./vendor/bin/phpunit --configuration tests/travis/$DB.travis.xml |
There was a problem hiding this comment.
Not using the simple-phpunit binary because of a crash I don't understand (seems to have to do with autoloading).
The "weak_vendors" will make the tests suite fail if I forget to remove any call to setOption with an unknown option, unless it's in a test marked with the "@legacy" annotation. The test suite won't fail if a vendor suddenly adds a deprecation (that's why it's called weak vendors, it's lenient with deprecations from vendors).
More details here. And yes, I'm the author of that feature :P
There was a problem hiding this comment.
I pushed something new. Turns out you don't have to use simple-phpunit to test deprecations properly.
| "symfony/console": "2.*||^3.0", | ||
| "doctrine/coding-standard": "^1.0", | ||
| "squizlabs/php_codesniffer": "^3.0" | ||
| "symfony/phpunit-bridge": "^3.3" |
There was a problem hiding this comment.
Adding this so that we get a report of deprecations at the end of the test suite. It's not necessary to use the simple-phpunit binary to get it.
There was a problem hiding this comment.
Is everyone on board with this?
There was a problem hiding this comment.
What's the purpose of reporting the usage of deprecated code in a test run? As far as I understand, the code is deprecated for the outside usage but it still has to be tested until removed entirely.
There was a problem hiding this comment.
@morozov you are right in that in needs to be tested. Such tests are supposed to be marked with a dedicated annotation @group legacy, so that it does not make the build fail. But if somewhere in the lib, we call the deprecated API ourselves, we must be aware of it, and change that. If we, don't users will get a deprecation and won't be able to do anything about it. That's what this is about.
| "bin": ["bin/doctrine-dbal"], | ||
| "config": { | ||
| "sort-packages": true | ||
| }, |
There was a problem hiding this comment.
Sorted packages in a separate commit, please review commit by commit.
| public static function fromUnsupportedOption(string $name) : self | ||
| { | ||
| return new self(sprintf('The "%s" option is not supported', $name)); | ||
| } |
There was a problem hiding this comment.
Unused at the moment, should be used in 3.0.
There was a problem hiding this comment.
Should I remove it or should I strive to make the diff of the 3.0 PR minimal?
There was a problem hiding this comment.
I'd remove it since it's not used anywhere.
| self::assertEquals($expected, $this->createColumn()->toArray()); | ||
| } | ||
|
|
||
| /** |
There was a problem hiding this comment.
I was not able to use the simple-phpunit binary, which means I can't test the deprecation message as described here: https://symfony.com/doc/current/components/phpunit_bridge.html#write-assertions-about-deprecations
UPDATE: no it does not mean that, and yes I was able to test it properly.
| $this->$method($value); | ||
| if ( ! method_exists($this, $method)) { | ||
| // next major: use InvalidArgumentException::fromUnsupportedOption() | ||
| @trigger_error(sprintf( |
There was a problem hiding this comment.
Scrutinizer does not like the silencing
There was a problem hiding this comment.
It seems like Scrutinizer allows silencing in an if block, but that's no option for this case. I haven't worked much with the Scrutinizer config, but maybe there's a way to ignore it just for trigger_error.
There was a problem hiding this comment.
Maybe this link would help: https://scrutinizer-ci.com/docs/reviews/filtering_issues_and_false_positives ?
There was a problem hiding this comment.
Could anyone please point me to the article explaining why this silencing operator is used in Symfony and we want it here? As far as I understand, the built-in PHP error handler will not display such errors. A user-defined handler, if it respects error_reporting(), it will ignore such errors as well. Does it mean users will have to use some specialized error handler to catch these errors?
There was a problem hiding this comment.
@morozov here is the handler: https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php IIRC most implementations ignore silenced errors, this one does not. I think a PSR is coming regarding all this.
There was a problem hiding this comment.
We want it here not only for Symfony users, but for us: we want to know if we use a deprecated path somewhere else in the lib
b388d42 to
cecbbbd
Compare
|
|
||
| <listeners> | ||
| <listener class="Doctrine\Tests\DbalPerformanceTestListener"/> | ||
| <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" /> |
There was a problem hiding this comment.
This is how you get to test deprecations with annotations
There was a problem hiding this comment.
Not a fan of this, but hey, it's dev-only, so I can live with it.
cecbbbd to
2b38d9f
Compare
|
|
||
| /** | ||
| * @group legacy | ||
| * @expectedDeprecation The "unknown_option" option is not supported, setting it is deprecated and will cause an exception in 3.0 |
There was a problem hiding this comment.
The build passed from red to green after adding this line... not sure why: symfony/symfony#21896
6753d83 to
87c56a3
Compare
|
I remove the |
|
@morozov thanks for making me dig deeper, I understand it better too now :) |
lib/Doctrine/DBAL/Schema/Column.php
Outdated
|
|
||
| namespace Doctrine\DBAL\Schema; | ||
|
|
||
| use Doctrine\DBAL\Exception\InvalidArgumentException; |
lib/Doctrine/DBAL/Schema/Column.php
Outdated
| // next major: throw an exception | ||
| @trigger_error(sprintf( | ||
| 'The "%s" option is not supported,'. | ||
| ' setting it is deprecated and will cause an exception in 3.0', |
There was a problem hiding this comment.
Probably should not mention exception directly (implementation detail), just error.
People do not need to know that this will be implemented as an exception.
db6853a to
e8209e0
Compare
|
@Ocramius Are you on board with using |
|
@Majkl578 yes, this is something I discussed in person with @nicolas-grekas, and the approach is solid. |
|
🚢 |
|
@greg0ire can I ask you to rename the PR title to something more clear to future readers?. |
|
@Ocramius sure! |
| * @group legacy | ||
| * @expectedDeprecation The "unknown_option" option is not supported, setting it is deprecated and will cause an error in 3.0 | ||
| */ | ||
| public function testSettingUnknownOptionIsStillSupported() : void |
There was a problem hiding this comment.
@greg0ire, in some cases, this test is reported as risky:
There was 1 risky test:
- Doctrine\Tests\DBAL\Schema\ColumnTest::testSettingUnknownOptionIsStillSupported
This test did not perform any assertions
...
Legacy deprecation notices (1)
Is it expected?
There was a problem hiding this comment.
Older versions of Symfony's phpunit bridge do not count expected deprecation as assertion (and thus mark the test risky).
I would advice to always run all test jobs with the latest version of the bridge
There was a problem hiding this comment.
Dropping the left part of the pipe is completely fine IMO.
There was a problem hiding this comment.
@greg0ire on the build in question, this constraint was resolved to v4.0.6.
There was a problem hiding this comment.
Ah sorry I misread this as 4.0.6 fixes the issue… latest is 4.0.7
There was a problem hiding this comment.
Can we somehow isolate the issue and report it to upstream?
There was a problem hiding this comment.
I'm trying to reproduce it as we speak but I'm afraid it only ever happens on windows. Should I create a PR with zero tests but the faulty one and let appveyor show the bug?
There was a problem hiding this comment.
It's fine if it helps to isolate the issue.
| $name | ||
| ), E_USER_DEPRECATED); | ||
|
|
||
| return $this; |
No description provided.