-
Notifications
You must be signed in to change notification settings - Fork 44
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
Stubbing Query class #5
Comments
I knew this would come up sooner or later 😆. Long story short, implementing this with any degree of robustness would require creating mini-Psalm for DQL queries. Not entirely impossible, but certainly not the easiest thing to do. Not really possible with simple approach like stubbing/generics. Generics operate on types, and all you've got, type-wise, is $result = $em->createQuery(file_get_contents('somefile.dql'))->getResult(); Here, static analysis tool like Psalm has no way to know if that was SELECT, DELETE or UPDATE query, what fields there were mentioned, what were FROM clauses, etc. All of those factors affect the result set shape. If we consider a more restricted case of a known literal string, that could be parsed to figure out aforementioned factors. Would require custom inference code (probably reusing Doctrine query parser). To use Doctrine parser we would need to find a way to obtain initialized and configured EntityManager, which means the plugin would need fully bootstrapped Doctrine environment, configured the same way you do in your application. Having parsed On the upside, it would be able to report issues in DQL queries. |
What you could do instead is to specify the result type manually like this: /** @var BlogPost[] $result */
$result = $query->getResult(); Of course it becomes your responsibility to make sure the type actually matches that |
Thank you very much for the detailed explanation, it is very appreciated! Ok, I understand that the safe solution is more a project in itself. Your suggestions is what also came to my mind and maybe a good middleground. But would it be possible to use instanceof checks instead of the inline docblock which is, as you said, very fragile? Something like this: $result = $query->getResult();
foreach ($result as $element) {
if (!$element instanceof BlogPost) {
throw new InvalidTypeException();
}
} Does this proof psalm that all elements are of the type |
No, foreach wouldn't work like that (see vimeo/psalm#649), but I have even better idea: https://getpsalm.org/r/7396e44181 It completely avoids runtime overhead when Keep in mind that it would only work with a rewindable iterables. Non-rewindable iterables (like generators) will have become consumed by the time |
Thanks a lot for the effort you put into this. My problem with the |
Requires #10 |
Maybe it will make our lives easier with this info that will be easier to implement the return type of [
0 => [
1 => "asddas 2"
]
1 => [
1 => "asddas"
]
] this might need to be reported to Doctrine, so that return types for
|
I need a lot of suppressions because the methods of the
Query
class likegetResult()
,getSingleResult()
,getOneOrNullResult()
, etc. return mixed. I've tried to create a stub for theAbstractQuery
(thats where the methods actually live), but I was only able to let it returnarray
(in the case ofgetResult()
) which causes other issues. I am not really familiar with the concepts of generics, but I think this would be the way to go here.Any hints whether this is possible at all and maybe point me in the right direction?
The text was updated successfully, but these errors were encountered: