Add PHPUnit tests for Image Loading Optimization#898
Add PHPUnit tests for Image Loading Optimization#898westonruter merged 52 commits intofeature/image-loading-optimizationfrom
Conversation
4906f55 to
e1a13d6
Compare
| // Immediately pop off self-closing tags. | ||
| if ( in_array( $tag_name, self::VOID_TAGS, true ) ) { | ||
| if ( | ||
| in_array( $tag_name, self::VOID_TAGS, true ) | ||
| || | ||
| ( $p->has_self_closing_flag() && $this->is_foreign_element() ) | ||
| ) { | ||
| array_pop( $this->open_stack_tags ); | ||
| } |
There was a problem hiding this comment.
@dmsnell: FYI, I'm pretty happy with how has_self_closing_flag and the foreign element aspect of the HTML spec simplified things! Now it can properly get breadcrumbs/XPaths for each SVG/MathML element as well.
| $minimum_viewport_widths = array_keys( $lcp_elements_by_minimum_viewport_widths ); | ||
| for ( $i = 0, $len = count( $minimum_viewport_widths ); $i < $len; $i++ ) { | ||
| $lcp_element = $lcp_images_by_minimum_viewport_widths[ $minimum_viewport_widths[ $i ] ]; | ||
| if ( false === $lcp_element || empty( $lcp_element['attributes'] ) ) { |
There was a problem hiding this comment.
The empty( $lcp_element['attributes'] ) check is removed here because it is always set.
There was a problem hiding this comment.
Another benefit of using a class to represent LCP elements would be that that would be truly enforced :)
| $needs_detection = in_array( | ||
| true, | ||
| // Each array item is array{int, bool}, with the second item being whether the viewport width is needed. | ||
| array_column( $needed_minimum_viewport_widths, 1 ), | ||
| true | ||
| ); |
There was a problem hiding this comment.
Some cool things with PHPStan's static analysis here. If 0 is supplied as the second arg to array_column() it detects an error:
phpstan: Call to function in_array() with arguments true, list and true will always evaluate to false.
This is because from the array shape returned by ilo_get_needed_minimum_viewport_widths() it knows that the first column will all be integers (the minimum viewport widths) and thus the in_array() check will always be false.
Conversely, if I supply a higher index like 2 in array_column(), I get:
phpstan: Call to function in_array() with arguments true, array{} and true will always evaluate to false.
Here PHPStan knows that since there are only two items in each tuple, the return of array_column() will be an empty array, and thus in_array() will also always return false.
Agreed. As mentioned above, I wanted to limit further refactoring until tests were written. The code changes not related to test coverage were primarily to fix blatant issues I uncovered while writing the tests. Sorry it grew so large. Since the review cycles have been pretty long, it's hard to keep the PRs very concise.
Agreed. Done in #924. I've reverted the changes in this PR via 2181d88. |
|
Unit tests are failing due to |
|
The PHPStan failures are likewise not related to code changes here. They may be resolved by merging |
…om/WordPress/performance into add/ilo-tests * 'feature/image-loading-optimization' of https://github.com/WordPress/performance: (155 commits) Remove scheduler from globals since not yet used Fix or ignore eslint rules Remove modules/images/webp-uploads/fallback.js from ignorePatterns Run format-js on JS files Cherry pick fixes to JS linting from feature/image-loading-optimization Prevent sending header during test Manually fix remaining phpcs issues Run php-format Discontinue excluding all WordPress-Extra from tests so phpcbf can format Add @joemcgill to images and measurement focuses. Update codeowners, removing inactive contributors. Introduce perflab-plugin-management.js Load migration script in settings page Update function name Apply suggestions from code review Address slow query feedbacks Revise migration pointer un-dismissal to work for all admins Rename variable. improve code Require Node v20 ...
felixarntz
left a comment
There was a problem hiding this comment.
Thanks @westonruter, LGTM! I think this is good to merge once the PHPStan problems have been addressed (here or via the other PR).
Let's separately follow up on simplifying some of the logic with classes, and also file structure (see my comment below).
| * @covers ::ilo_can_optimize_response | ||
| * @dataProvider data_provider_test_ilo_can_optimize_response | ||
| */ | ||
| public function test_ilo_can_optimize_response( Closure $set_up, bool $expected ) { |
There was a problem hiding this comment.
I was just wondering why this function is in the storage/data.php file. It's only called in optimization.php, and the function name to me suggests it would fit better in there.
I then noticed storage/data.php contains several other functions like this, that to me don't seem storage related. Is that intentional? If so, can you clarify how you see the responsibilities between these two files?
Maybe there's a more intuitive way to break apart the functions here. To be fair, some of it may sort of automatically be addressed when using classes for some of those things as applicable.
There was a problem hiding this comment.
Good catch! Function moved in ed305a9.
The other functions are generally storage related in that they relate to how fresh the stored data is, how to determine the slug for the data, manipulating the stored data, etc. But I agree this the functions in this file are much more of a grab bag compared to the functions in other files. I'll work to organize them better with the refactoring.
| $slug = ilo_get_url_metrics_slug( array() ); | ||
| $nonce1 = ilo_get_url_metrics_storage_nonce( $slug ); | ||
| $this->assertMatchesRegularExpression( '/^[0-9a-f]{10}$/', $nonce1 ); | ||
| $this->assertSame( 1, ilo_verify_url_metrics_storage_nonce( $nonce1, $slug ) ); |
There was a problem hiding this comment.
Nit-pick: I find the return of 0, 1, or 2 an odd choice. I realize wp_verify_nonce() returns that, but it's extremely unintuitive, and I don't think many people know, except from reading the docs.
There's no value for us (and probably any other use-cases) to make a difference between when the nonce was generated, so I'd prefer to just return a boolean (i.e. cast the result to a bool). You aren't testing the 2 return value here either as far as I can tell (which makes sense IMO!), so that confirms it's useless to us :)
Fix PHPStan errors in tests
… add/ilo-tests * 'trunk' of https://github.com/WordPress/performance: Re-run composer update with PHP 8.1 Run composer update Fix PHPStan errors in tests
modules/images/image-loading-optimization/class-ilo-html-tag-processor.php
Show resolved
Hide resolved
Co-authored-by: Mukesh Panchal <mukeshpanchal27@users.noreply.github.com>
mukeshpanchal27
left a comment
There was a problem hiding this comment.
Thank you, @westonruter, for the updates. I've left some minor suggestions, but they don't pose any blockers.
- It would be nice to add
@paramannotations for the parameters used in thedataProviderfor tests.
| * @covers ::open_tags | ||
| * @covers ::get_xpath | ||
| * | ||
| * @dataProvider data_provider_sample_documents |
There was a problem hiding this comment.
Nice if we add @param that used in dataProvider.
There was a problem hiding this comment.
Yeah, somewhat. But it looks like most of the other tests using data providers don't have @param tags in the plugin. Not that this is a good reason.
tests/modules/images/image-loading-optimization/detection-tests.php
Outdated
Show resolved
Hide resolved
tests/modules/images/image-loading-optimization/storage/post-type-tests.php
Show resolved
Hide resolved
tests/modules/images/image-loading-optimization/storage/rest-api-tests.php
Show resolved
Hide resolved
Co-authored-by: Mukesh Panchal <mukeshpanchal27@users.noreply.github.com>
Co-authored-by: Mukesh Panchal <mukeshpanchal27@users.noreply.github.com>
Summary
This is part of #869.
This adds full test coverage for the functions in the Image Loading Optimization module.
Relevant technical choices
ILO_HTML_Tag_Processor::open_tags()generator is updated to ensure accurate breadcrumbs/XPath for SVG and MathML elements.ilo_construct_preload_links().integrityattribute is no longer copied from anIMGelement to the preloadLINK. This attribute doesn't appear onIMG, but rather is only onLINKandSCRIPT.ilo_unshift_url_metrics(). Previously the timestamp was added inilo_store_url_metric()before passing toilo_construct_preload_links().ilo_unshift_url_metrics()to make it easier to test by passing more arguments.ilo_register_endpoint().Discontinue excludingSee Update PHPCS formatting in tests #924.WordPress-Extrasniffs from applying to tests, and add specific sniff exclusions. By allowingWordPress-Extrato apply, PHPCBF can do automatic formatting. PHPCS errors were fixed in other test files.Checklist
[Focus]orInfrastructurelabel.[Type]label.no milestonelabel.