-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
fix is_wp_version_compatible() to accommodate incorrect format x.x.0 #5677
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great start. I think this might need a test to ensure that the notice is properly raised. I also left a couple of comments on the specific implementation.
src/wp-includes/functions.php
Outdated
@@ -8716,6 +8716,16 @@ function is_wp_version_compatible( $required ) { | |||
// Strip off any -alpha, -RC, -beta, -src suffixes. | |||
list( $version ) = explode( '-', $wp_version ); | |||
|
|||
if ( is_string( $required ) && substr_count( $required, '.' ) > 1 && str_ends_with( $required, '.0' ) ) { | |||
error_log( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use wp_trigger_error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was initially having issues with tests not passing due to the wp_trigger_error()
message being returned but found a solution by removing the error handler before the test and resetting afterwards.
src/wp-includes/functions.php
Outdated
error_log( | ||
__FUNCTION__ . '(): ' . | ||
/* translators: s: version string sent to function */ | ||
sprintf( __( '`%s` Not a valid WordPress version string.' ), $required ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be helpful to present both what was passed in and what the result was. What do you think of this instead?
"Invalid version 6.0.0 passed to is_wp_version_compatible
, 6.0 is assumed."
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
update to is_wp_version_compatible() sends trigger_warning causing tests to fail.
Thanks @aaronjorbin, I believe I've fixed the issues you've raised. I don't quite understand what you mean by ensuring the notice is properly raised? |
Thanks, the code changes look great. Also, glad to hear this helped find another spot where our tests could be improved!
I meant using something like what was implemented in https://core.trac.wordpress.org/changeset/57332 Essentially rather than silencing the error, setting an expect for it to be raised. |
The problem with raising the error to an Exception is that the comparison will then fail and what we've intended is for the provided incorrect version be modified so it's now correct and the comparison continues -- or am I missing something? |
Sorry I wasn't clear. I pushed some code to your branch since I thought showing the code would help. By using expectException, the exception won't cause the tests to fail. I did move the actual call to Let me know if this makes sense. It looks like I'll need to clean up some formatting as well, so I can try to add some comments if you think it would help |
$this->assertSame( $expected, is_wp_version_compatible( $required ) ); | ||
public function test_is_wp_version_compatible( $required, $expected, $expect_exception = false ) { | ||
|
||
if ( $expect_exception ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These latest changes provide a false sense of security, as does the test in this Core changeset.
For example, if you comment out all datasets except those that should throw an exception, and change the final assertion to $this->assertSame( $expected . 'should not pass', $result );
, the two datasets will still pass. This is because an exception was correctly detected, but the test also ended as soon as this occurred. This issue also exists with the test in the Core changeset linked above.
Instead, let's consider this approach:
- Add a new property to the test class:
/**
* A notice expected during the tests.
*
* @var string
*/
private $expected_notice = '';
- Add a
tear_down()
method that resets the property:
/**
* Resets the `expected_notice` property after each test runs.
*/
public function tear_down() {
$this->expected_notice = '';
parent::tear_down();
}
- Adjust the test so that instead of throwing an exception, we note the notice, restore the previous handler, and check that it matches the expected type and string:
public function test_is_wp_version_compatible( $required, $expected, $expect_notice = false ) {
if ( $expect_notice ) {
set_error_handler(
function ( $errno, $errstr ) {
$this->expected_notice = $errno . ' ' . $errstr;
},
E_ALL
);
}
$result = is_wp_version_compatible( $required );
if ( $expect_notice ) {
restore_error_handler();
$this->assertStringStartsWith(
E_USER_NOTICE . " is_wp_version_compatible(): `$required` Not a valid WordPress version string.",
$this->expected_notice,
'The expected notice was not thrown.'
);
}
$this->assertSame( $expected, $result );
}
Now, if we change the final assertion to $this->assertSame( $expected . 'should not pass', $result );
, the two datasets will correctly fail.
Run a few checks locally to see the issue with the existing test, and how the changes above resolve this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the discussion has moved away from having a notice. The above can be disregarded in that case. 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Un-resolving this as a decision on the notice hasn't finalized.
@aaronjorbin FYI: Take a look at the first comment in this thread regarding an issue with the changeset you referenced and previous commits to this PR that were influenced by it, and an alternative without this issue.
'correct version x.0.1' => array( | ||
'required' => '5.0.1', | ||
'expected' => true, | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth adding a test to ensure the version is converted correctly? It might require some code shuffling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provided there are tests covering all the bases, testing the output with each input should be enough, and the respective lines can be checked for coverage in a coverage report.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this test to ensure a .0
in the middle of a version number wouldn’t be changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add some new tests for that. I'll have it fixed by tomorrow.
…e_and_test Add notice and test.
Thinking this code is far too complex for what it needs to accomplish. We only care to strip Perhaps something simpler would also work: if ( is_string( $required ) && strlen( $required ) > 3 && str_ends_with( $required, '.0' ) ) {
// Strip trailing zero to properly match two digits (major) WP version numbers.
$required = substr( $required, 0, -2 );
} The Edit: actually this should probably be |
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @[email protected]. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. Core Committers: Use this line as a base for the props when committing in SVN:
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #5677 (comment).
@azaozz I've switched
|
Co-authored-by: Colin Stewart <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$required is developer input that can't be trusted to be entirely correct...
Right. Thinking it looks better now, and perhaps a very tiny bit faster (afaik PHP needs some time to "initialize" the external lib every time a regexp function is used) :)
Seems this is good to go if there isn't anything else.
Co-authored-by: Pascal Birchler <[email protected]>
Some users improperly test for releases of the format x.x.0. Unfortunately there is never a WordPress release with this version number and
version_compare( '5.2', '5.2.0', '>=' )
is false.Test value sent to
is_wp_version_compatible( $required )
to ensure a trailing zero (x.x.0) is fixed to be (x.x)and awp_trigger_error()
is sent.This will correctly test the improper version x.x.0 as x.x.
Trac ticket: https://core.trac.wordpress.org/ticket/59448
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.