Skip to content

Lazy assert types gathering in TypeInferenceTestCase #1991

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

Conversation

herndlm
Copy link
Contributor

@herndlm herndlm commented Nov 11, 2022

Just an idea I had in mind I want to propose. This is more about the concept and not the actual implementation. I adapted NodeScopeResolverTest to make use of it, looks like there would be 14 more.

This PR adds new methods to TypeInferenceTestCase that make it possible to write tests where the assert type gathering is not happening in the dataprovider, but in the actual test method. This is done by returning callbacks in the dataprovider.

This has various upsides

  • tests start immediately, feel faster and likely fail faster. previously it took a while until e.g. NodeScopeResolver printed output
  • code coverage can be collected because the code parts are not executed in the dataprovider anymore CC @staabm @szepeviktor
  • the phpunit configuration here prints risky test files that don't assert anything (there are 2 in the NodeScopeResolver right now) which makes the tests safer
  • using $file in the yield makes PHPUnit print the test case file instead of the test case number, e.g.
There were 2 riskys:

1) PHPStan\Analyser\NodeScopeResolverTest::testFileAssertsCallbacks with data set "/Users/herndlm/Development/source/git-forks/phpstan-src/tests/PHPStan/Analyser/data/DateTimeModifyReturnTypes.php" (Closure Object (...))
This test did not perform any assertions

/Users/herndlm/Development/source/git-forks/phpstan-src/tests/PHPStan/Analyser/NodeScopeResolverTest.php:1136

2) PHPStan\Analyser\NodeScopeResolverTest::testFileAssertsCallbacks with data set "/Users/herndlm/Development/source/git-forks/phpstan-src/tests/PHPStan/Analyser/data/bug-7031.php" (Closure Object (...))
This test did not perform any assertions

I don't like that these are new methods and users have to manually migrate. Not sure if this can be made "smoother". I also don't like their names. If this idea is accepted, we could also come up with completely different names and deprecate the old methods even at some point maybe.

What do people think about this?

@ondrejmirtes
Copy link
Member

I think something like this has been proposed before but the main blocker for me is that only the first failure from a file is reported, not all of them. That's why it's currently done with generators like that.

@herndlm
Copy link
Contributor Author

herndlm commented Nov 11, 2022

oh, you're right, yes. I also noticed that when fixing the test files where assertType was not working. that is kind of a deal-breaker I guess hmm :/
I'll think about this, maybe I can simply adapt the way things are currently asserted. Basically a new assertFileAsserts() variant within assertFileAssertsCallbacks().

@herndlm herndlm force-pushed the improve-type-inference-test-case-asserts branch from 1d87bff to 864c707 Compare November 11, 2022 15:42
@herndlm
Copy link
Contributor Author

herndlm commented Nov 12, 2022

I re-implemented the assertion part, in the simplest way I could currently imagine, to only fail once per file basically => output all errors in a file at once. I like the output even more than before tbh, because it's more compact, e.g.:

There were 2 failures:

1) PHPStan\Analyser\NodeScopeResolverTest::testAssertions with data set "/home/martin/PhpstormProjects/phpstan-src/tests/PHPStan/Analyser/data/implode.php" (Closure Object (...))
Expected type 'wrong', got type '12345' in /home/martin/PhpstormProjects/phpstan-src/tests/PHPStan/Analyser/data/implode.php on line 15.
Expected type 'wrong', got type '12345' in /home/martin/PhpstormProjects/phpstan-src/tests/PHPStan/Analyser/data/implode.php on line 16.
Failed asserting that an array is empty.

/home/martin/PhpstormProjects/phpstan-src/src/Testing/TypeInferenceTestCase.php:108
/home/martin/PhpstormProjects/phpstan-src/tests/PHPStan/Analyser/NodeScopeResolverTest.php:1138

2) PHPStan\Analyser\NodeScopeResolverTest::testAssertions with data set "/home/martin/PhpstormProjects/phpstan-src/tests/PHPStan/Analyser/data/bug-1945.php" (Closure Object (...))
Expected Maybe, actual certainty of variable $foo is Yes in /Users/herndlm/Development/source/git-forks/phpstan-src/tests/PHPStan/Analyser/data/bug-1945.php on line 23.
Expected No, actual certainty of variable $foo is Yes in /Users/herndlm/Development/source/git-forks/phpstan-src/tests/PHPStan/Analyser/data/bug-1945.php on line 47.
Failed asserting that an array is empty.

/home/martin/PhpstormProjects/phpstan-src/src/Testing/TypeInferenceTestCase.php:108
/home/martin/PhpstormProjects/phpstan-src/tests/PHPStan/Analyser/NodeScopeResolverTest.php:1138

it could be made even more compact, e.g. the file info is redundant now because one assertion failure is for one file and the file is already used as dataprovider array key.

differences

  • now multiple failures per file are only counted as one failure, which is kind of what we want though I think, at least we get it now without any weird dataprovider behaviour.
  • the "Failed asserting that an array is empty." message is a maybe a bit weird? With a custom constraint we could get rid of that message easily I think.
  • time shown in the phpunit summary is now correct, this was way too short before

@herndlm herndlm force-pushed the improve-type-inference-test-case-asserts branch 3 times, most recently from effc76e to 68f36dc Compare November 12, 2022 20:16
@@ -13,566 +13,566 @@
class NodeScopeResolverTest extends TypeInferenceTestCase
{

public function dataFileAsserts(): iterable
public function dataAssertions(): iterable
Copy link
Contributor

Choose a reason for hiding this comment

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

I am wondering whether we can adjust this PR in a way that already exisiting TypeInferenceTestCase subclasses immediately benefit from the base-class changes without modifications..?

(Do we need this new mechanism in parallel to the pre-exisiting one?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

didn't figure that out yet, I think it's not possible, but maybe I'm missing some magic to make it possible :) the problems are different return and argument types for the 2 methods

Copy link
Contributor

@staabm staabm Nov 23, 2022

Choose a reason for hiding this comment

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

wondering still about the same thing.

couldn't you rename the gatherAssertTypes method which existed before this PR to e.g. gatherAssertTypesFromFile and implement the PRs gatherAssertions as gatherAssertTypes (same for assertFileAsserts) and then we can take this changes as a drop-in replacement without needs for change in NodeScopeResolver test..
maybe I am missing something obvious?

Copy link
Contributor

Choose a reason for hiding this comment

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

@herndlm herndlm force-pushed the improve-type-inference-test-case-asserts branch from fac1616 to 68f36dc Compare November 13, 2022 18:08
@herndlm herndlm force-pushed the improve-type-inference-test-case-asserts branch from 68f36dc to 82846bc Compare November 23, 2022 08:53
@herndlm herndlm marked this pull request as ready for review November 23, 2022 09:08
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

@herndlm
Copy link
Contributor Author

herndlm commented Feb 25, 2023

should I fix conflicts here again or do something else? Otherwise I would just close it for now I guess, no worries

@herndlm herndlm closed this Apr 5, 2023
@herndlm herndlm deleted the improve-type-inference-test-case-asserts branch April 5, 2023 08:39
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.

5 participants