Skip to content

Ensure column options map to an existing method#2846

Merged
Ocramius merged 5 commits intodoctrine:masterfrom
greg0ire:validate_options
Dec 8, 2017
Merged

Ensure column options map to an existing method#2846
Ocramius merged 5 commits intodoctrine:masterfrom
greg0ire:validate_options

Conversation

@greg0ire
Copy link
Copy Markdown
Member

@greg0ire greg0ire commented Sep 6, 2017

No description provided.

@greg0ire greg0ire force-pushed the validate_options branch 5 times, most recently from 5c2747d to 4cfec3a Compare September 11, 2017 18:47
if (method_exists($this, $method)) {
$this->$method($value);
if (!method_exists($this, $method)) {
throw InvalidArgumentException::fromUnsupportedOption($name);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Might be considered a BC-break, tell me if you want me to trigger deprecation errors instead.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I notice that it does not seem to be used anywhere in the code, but maybe you're not against it?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

How about retargetting only this part, and merging the rest in master, since it's BC?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Great, I'll go with that then!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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

@greg0ire
Copy link
Copy Markdown
Member Author

ping

$method = "set".$name;
if (method_exists($this, $method)) {
$this->$method($value);
if (!method_exists($this, $method)) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There should be a space around !.

if (method_exists($this, $method)) {
$this->$method($value);
if (!method_exists($this, $method)) {
throw InvalidArgumentException::fromUnsupportedOption($name);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Spaces between return types.

@greg0ire greg0ire force-pushed the validate_options branch 3 times, most recently from 65a4dcd to b388d42 Compare September 20, 2017 22:14
.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
Copy link
Copy Markdown
Member Author

@greg0ire greg0ire Sep 20, 2017

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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"
Copy link
Copy Markdown
Member Author

@greg0ire greg0ire Sep 20, 2017

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Is everyone on board with this?

Copy link
Copy Markdown
Member

@morozov morozov Dec 6, 2017

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member Author

@greg0ire greg0ire Dec 6, 2017

Choose a reason for hiding this comment

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

@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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@greg0ire thanks for the explanation. Makes sense.

"bin": ["bin/doctrine-dbal"],
"config": {
"sort-packages": true
},
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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));
}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Unused at the moment, should be used in 3.0.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Should I remove it or should I strive to make the diff of the 3.0 PR minimal?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd remove it since it's not used anywhere.

self::assertEquals($expected, $this->createColumn()->toArray());
}

/**
Copy link
Copy Markdown
Member Author

@greg0ire greg0ire Sep 20, 2017

Choose a reason for hiding this comment

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

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(
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Scrutinizer does not like the silencing

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@lcobucci maybe you can help us here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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


<listeners>
<listener class="Doctrine\Tests\DbalPerformanceTestListener"/>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is how you get to test deprecations with annotations

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not a fan of this, but hey, it's dev-only, so I can live with it.


/**
* @group legacy
* @expectedDeprecation The "unknown_option" option is not supported, setting it is deprecated and will cause an exception in 3.0
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The build passed from red to green after adding this line... not sure why: symfony/symfony#21896

@greg0ire greg0ire force-pushed the validate_options branch 3 times, most recently from 6753d83 to 87c56a3 Compare September 28, 2017 15:08
@greg0ire
Copy link
Copy Markdown
Member Author

I remove the weak_vendors mode as asked by @Ocramius , please review again.

@greg0ire
Copy link
Copy Markdown
Member Author

greg0ire commented Dec 7, 2017

@morozov thanks for making me dig deeper, I understand it better too now :)


namespace Doctrine\DBAL\Schema;

use Doctrine\DBAL\Exception\InvalidArgumentException;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This use is unused.

// 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',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Probably should not mention exception directly (implementation detail), just error.

Grégoire Paris added 2 commits December 7, 2017 17:34
People do not need to know that this will be implemented as an
exception.
@Majkl578
Copy link
Copy Markdown
Contributor

Majkl578 commented Dec 8, 2017

@Ocramius Are you on board with using @trigger_error(..., E_USER_DEPRECATED) pattern for deprecations?

@Ocramius
Copy link
Copy Markdown
Member

Ocramius commented Dec 8, 2017

@Majkl578 yes, this is something I discussed in person with @nicolas-grekas, and the approach is solid.

@Ocramius Ocramius self-assigned this Dec 8, 2017
@Ocramius Ocramius added this to the 2.7.0 milestone Dec 8, 2017
@Ocramius
Copy link
Copy Markdown
Member

Ocramius commented Dec 8, 2017

🚢

@Ocramius Ocramius merged commit cb08c4d into doctrine:master Dec 8, 2017
@Ocramius
Copy link
Copy Markdown
Member

Ocramius commented Dec 8, 2017

@greg0ire can I ask you to rename the PR title to something more clear to future readers?.

@greg0ire greg0ire deleted the validate_options branch December 8, 2017 09:32
@greg0ire
Copy link
Copy Markdown
Member Author

greg0ire commented Dec 8, 2017

@Ocramius sure!

@greg0ire greg0ire changed the title Validate options Ensure column options map to an existing method Dec 8, 2017
@Majkl578 Majkl578 mentioned this pull request Feb 16, 2018
* @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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@greg0ire, in some cases, this test is reported as risky:

There was 1 risky test:

  1. Doctrine\Tests\DBAL\Schema\ColumnTest::testSettingUnknownOptionIsStillSupported
    This test did not perform any assertions
    ...
    Legacy deprecation notices (1)

Is it expected?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@wouterj could you suggest the proper composer.json constraints? Currently, we have:

"symfony/phpunit-bridge": "^3.4.5|^4.0.5"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Dropping the left part of the pipe is completely fine IMO.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@greg0ire on the build in question, this constraint was resolved to v4.0.6.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ah sorry I misread this as 4.0.6 fixes the issue… latest is 4.0.7

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we somehow isolate the issue and report it to upstream?

Copy link
Copy Markdown
Member Author

@greg0ire greg0ire Apr 4, 2018

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's fine if it helps to isolate the issue.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ok then. See symfony/symfony#26809

$name
), E_USER_DEPRECATED);

return $this;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

What is it @andytruong ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

beberlei added a commit to beberlei/dbal that referenced this pull request Mar 6, 2021
beberlei added a commit to beberlei/dbal that referenced this pull request Mar 7, 2021
beberlei added a commit to beberlei/dbal that referenced this pull request Mar 22, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants