Skip to content
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

Adapt tests to work with v1.1 and v2.0 of PSR-7 #68

Merged
merged 8 commits into from
Apr 20, 2023

Conversation

weierophinney
Copy link
Contributor

@weierophinney weierophinney commented Apr 4, 2023

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Related tickets Provides more comprehensive change than #65. Fix #64
Documentation TBD
License MIT

What's in this PR?

Refactors tests that were using the assumption of throwing an InvalidArgumentException to test for either InvalidArgumentException OR TypeError.

The change goes further than #65 in that it provides test changes, not just dependency changes. The test changes have been vetted by running against a laminas-diactoros checkout that modifies its codebase to conform to the PSR-7 changes.

Why?

This change will allow testing against PSR-7 1.1+ releases safely.

Checklist

  • Updated CHANGELOG.md to describe BC breaks / deprecations | new feature | bugfix

weierophinney added a commit to weierophinney/psr7-integration-tests that referenced this pull request Apr 4, 2023
@weierophinney
Copy link
Contributor Author

@dbu So... I have a bit of a conundrum.

A number of the tests, when run against an implementation, will result in failures UNLESS I modify the test cases you provide to add declare(strict_types=1). The reason is because when not used with strict mode, the values will be munged to fit the declared type, allowing them to be used "safely". As a result, the test cases now result in the AssertionFailedError I raise if the methods do not otherwise raise a validation error.

If I update to enable strict types, they work correctly.

The tests I specifically ran up against were:

  • RequestIntegrationTest::testMethodWithInvalidArguments()
  • ResponseIntegrationTest::withStatusCodeInvalidArgument()

In Laminas, we always declare strict types, and do so in our tests as well, so I'd not come across this. However, because the base abstract test cases defined here do not.... now we're hitting the issue.

I was rather excited about being able to rip out validation code that was unnecessary due to having scalar parameter type declarations, but if we cannot assume strict types are enabled, it seems they need to be there... and that then raises errors with static analysis due to redundant checks. 😠

How would you like to proceed? Should I add the strict types declaration as part of ths patch?

@dbu dbu mentioned this pull request Apr 5, 2023
2 tasks
Copy link

@simPod simPod left a comment

Choose a reason for hiding this comment

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

Dataprovider for Tests\Nyholm\Psr7\Integration\ResponseTest::testStatusCodeInvalidArgument needs to have inputs of invalid types removed.

(keep only ints for strict types or remove only the float one)


also Tests\Nyholm\Psr7\Integration\UriTest::testWithSchemeInvalidArguments (true and 34)

@weierophinney
Copy link
Contributor Author

I've updated the PR to take the advice of @simPod , and removed the provider values that fail when strict types is not enabled.

Copy link

@simPod simPod left a comment

Choose a reason for hiding this comment

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

also Tests\Nyholm\Psr7\Integration\UriTest::testWithSchemeInvalidArguments (true and 34)

this is missing yet

@weierophinney
Copy link
Contributor Author

weierophinney commented Apr 6, 2023

@simPod

also Tests\Nyholm\Psr7\Integration\UriTest::testWithSchemeInvalidArguments (true and 34)

this is missing yet

Those should stay. The spec cleary states:

Implementations MUST support the schemes "http" and "https" case insensitively, and MAY accommodate other schemes if required.

If an implementation is allowing casting of true or 34 to strings ("1" and "34" respectively) and considering them valid, then they are incorrectly allowing invalid schemes. RFC-3986 section 3.1 requires a scheme to start with an alphabetical character. As such, regardless of whether or not strict types is enabled, those values MUST be considered invalid.

@simPod
Copy link

simPod commented Apr 6, 2023

But mind this test https://github.com/Nyholm/psr7/blob/c06c9e0f03ca36a2c4e1823c34a8937eec90ed11/tests/UriTest.php#L204 It seems schema values should not be validated based on that.

@weierophinney
Copy link
Contributor Author

But mind this test https://github.com/Nyholm/psr7/blob/c06c9e0f03ca36a2c4e1823c34a8937eec90ed11/tests/UriTest.php#L204 It seems schema values should not be validated based on that.

That's a problem in that particular implementation; that scheme value should not be accepted.

@simPod
Copy link

simPod commented Apr 6, 2023

I have added a validation and removed that test case, will see how it goes in review in Nyholm/psr7#223

@dbu
Copy link
Contributor

dbu commented Apr 7, 2023

thanks for the merge request!

How would you like to proceed? Should I add the strict types declaration as part of ths patch?

i would be ok to enable strict typing in the test cases, it is best practice to have them enabled.

is there a way to discover the version of the PSR interfaces that is used? then we could $this->markAsSkipped() the test cases that become obsolete with strict typing. that way we would still test correct behaviour of 1.0 implementations that lack the typing but not have redundant tests that the type declarations already enforce.

@weierophinney
Copy link
Contributor Author

is there a way to discover the version of the PSR interfaces that is used? then we could $this->markAsSkipped() the test cases that become obsolete with strict typing. that way we would still test correct behaviour of 1.0 implementations that lack the typing but not have redundant tests that the type declarations already enforce.

Yes; Composer provides this. That said, I don't think it's necessary. By testing if either InvalidArgument or TypeError are thrown for the given arguments, we are able to test against either version of the spec. The only reason I needed to remove any provider cases was due to strict mode not being present in these test class files; if that's added, then we can keep these, and test against all versions without issue.

I'm happy to update to do this in this patch.

@dbu
Copy link
Contributor

dbu commented Apr 10, 2023

strict mode not being present in these test class files; if that's added, then we can keep these, and test against all versions without issue.

then lets do it that way.

i would assume that if a sloppy conversion is possible, sloppy code would end up with working requests. so people who do not use strict will be happy, and those that use strict will also be happy.

Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

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

Im happy with this PR

@dbu
Copy link
Contributor

dbu commented Apr 17, 2023

can you please rebase on master? this will make this use the github actions so we can see the builds (there will be failures for some clients, we found no way to mark them as allowed to fail but will still merge if there is not mistake with the tests)

Refactors tests that were using the assumption of throwing an `InvalidArgumentException` to test for either `InvalidArgumentException` OR `TypeError`.
This change will allow testing against PSR-7 1.1+ releases safely.
When performing try/catch blocks, and the catch represents a valid condition, we need to assert SOMETHING, or else the test is flagged as risky.
A simple assertion that we got a throwable works in these cases.
Adds a `fail()` call when an invalid argument is not caught.
Per a comment from @simPod, removes the following:

- From `RequestIntegrationTest::getInvalidMethod()`:
  - The test cases for 1 and 1.01 (integer and float)
- From `ResponseIntegrationTest::getInvalidStatusCodeArguments()`:
  - The test cases for 200.34

Additionally, this patch adds keys to each entry returned by these two providers, to better facilitate understanding which test failed.

The removals were necessary as the test case does not enable strict mode, and these particular types can be converted to the specified type "safely", leading to false negative results.
Evidently, aligning operators is not allowed in this project.
(I wish the required style guide was published with the project...)
@weierophinney
Copy link
Contributor Author

@dbu Rebased!

@weierophinney
Copy link
Contributor Author

@dbu What are the next steps? This is the last library that Diactoros needs updated before we can release PSR-7 v2 support. We are currently testing against this PR successfull (see laminas/laminas-diactoros#136), but are waiting to release until we can update to test against an official release.

For others who are writing implementations: are any of you having issues with this patch? If so, I'd be happy to review and see if either (a) it requires updates/fixes in your library , or (b) the patch needs revisions to better mirror the specification interfaces.

@dbu
Copy link
Contributor

dbu commented Apr 19, 2023

the CI shows that i made a mistake in the CI script: we install the dependencies and then require the implementation without allowing to update dependencies.

can you delete the line that does composer update before doing the composer require? that would be more efficient anyways and would run the builds again. in master the laminas builds for PHP 8 are green :-)

@weierophinney
Copy link
Contributor Author

can you delete the line that does composer update before doing the composer require?

Done!

One thing to note: current Diactoros offerings are only on PHP 8.0 and above, so the tests for PHP 7 versions will ALWAYS fail here. Is it possible to change the matrix so it doesn't try testing those?

@dbu dbu merged commit 30a7596 into php-http:master Apr 20, 2023
@dbu
Copy link
Contributor

dbu commented Apr 20, 2023

thanks a lot! i merged as it updates the current state to know about PSR-7 1.1 and 2.0

current Diactoros offerings are only on PHP 8.0 and above, so the tests for PHP 7 versions will ALWAYS fail here. Is it possible to change the matrix so it doesn't try testing those?

i noticed when i set up the build matrix and was also wondering. there might be some value in knowing what the problems of outdated versions of diactoros are. the most comprehensive would be to split off some sort of legacy test suite for the no longer maintained versions and update the table to show the status of the maintained versions and also specify what PHP version should be used.

@weierophinney weierophinney deleted the feature/psr-7-type-hints branch April 21, 2023 17:41
@weierophinney
Copy link
Contributor Author

thanks a lot! i merged as it updates the current state to know about PSR-7 1.1 and 2.0

My pleasure!

Question: when will this be included in a release, and what version (I'm assuming 1.3.0)? Trying to plan when I can complete the tasks for Diactoros. 😄

weierophinney added a commit to weierophinney/laminas-diactoros that referenced this pull request Apr 25, 2023
This is until a 1.3.0 release is made, and represents the commit in which the changes in php-http/psr7-integration-tests#68 were merged.

Signed-off-by: Matthew Weier O'Phinney <matthew@weierophinney.net>
@dbu
Copy link
Contributor

dbu commented Apr 28, 2023

i was on holidays this week and managed to not open my laptop for several days :-D

i now split the tests for the badges in the README and laminas is looking good 👍

i just tagged https://github.com/php-http/psr7-integration-tests/releases/tag/1.3.0

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.

Support for recently released psr/http-message v2
4 participants