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

Test standalone template renders #425

Open
lulco opened this issue Aug 1, 2023 · 8 comments
Open

Test standalone template renders #425

lulco opened this issue Aug 1, 2023 · 8 comments

Comments

@lulco
Copy link
Contributor

lulco commented Aug 1, 2023

Let's say we have some custom service, where is TemplateFactory to create Template and then it is rendered to string. This should be tested too

@lulco
Copy link
Contributor Author

lulco commented Aug 24, 2023

@MartinMystikJonas do you think it is possible to create generic solution for this? or we have to implement it in each project against its specific requirements?

@MartinMystikJonas
Copy link
Collaborator

I am not sure I understand that use-case corerctly but if I fot it that I do not think there could be universal solution for that. We have no way to know which places to consider analysis "entry points" for lette tempalte context collecting.

Currently this could be solved by custom LatteTemplateResolvers

But I think we can do two things to make it easier for users.

  1. Create annotation @phpstan-late-entry (or similar) that would allow to mark any method as entry point for context collecting. Then we would create noew LatteTemplateResolver that would resolve templates form these entry points.
  2. Report calls to render, sendTempalte and similar that was not covered by any entry point. We would need to collect all calls to this (we probably already do in RenderCollector) and then remove calls when they are added to any tempalte in Template REsolver.This should point to places where annotation should be added.

@lulco
Copy link
Contributor Author

lulco commented Aug 24, 2023

My use case:

final class SomeTransformer
{
    public function __construct(private TemplateFactory $templateFactory)
    {
    }

    public function transform(): string
    {
        $template = $this->templateFactory->createTemplate();
        $template->foo = 'bar';
        $template->bar = 'baz';

        $template->setFile(__DIR__ . '/default.latte');
        return $template->renderToString();
    }
}

I wanted t find all Template->render() / Template->renderToString() calls, but I realize I don't know how to collect data for them. That's why I asked the question before. You've confirmed my thoughts that it couldn't be universal solution.

@lulco
Copy link
Contributor Author

lulco commented Aug 28, 2023

Basically I want the createTemplate to be “entry point” and render / renderToString etc. to be the “end point”. Actual state is that entry point is always Class method, but that’s not always truth.

@MartinMystikJonas
Copy link
Collaborator

Entry point must be class method for other parts of analysis to work (eslecially call chains).

We could find all methods containing createTemplate and use them as entry points. But it could easily generate tons of false positives if context is set outside such method.

Example: Method A calls B. B contains createTemplate and returns created template. A then sets context to template and calls render.

In this scenario A is our correct entry point. But createTemplate is in B.

@lulco
Copy link
Contributor Author

lulco commented Aug 28, 2023

Entry point must be class method for other parts of analysis to work (eslecially call chains).

And this is imho wrong design we use here :) entry point is class method only for components and presenters. Because the template is created there magically.

We could find all methods containing createTemplate and use them as entry points. But it could easily generate tons of false positives if context is set outside such method.

If we call e.g. sendResponse($template); sooner than some variable is assigned to template, we have false positive / negative too.
I think we should collect also lines of code. But it could be overcomplicated...

Example: Method A calls B. B contains createTemplate and returns created template. A then sets context to template and calls render.

Yes but this is the problem also now. We can't know if the context is added to correct template in some method call where the template is passed.

In this scenario A is our correct entry point. But createTemplate is in B.

I have to think about it. For now I'll create some Resolvers for our use cases.

@MartinMystikJonas
Copy link
Collaborator

I am afraid that what you want is not possible by using static analysis of PHPStan. We would need something that works as "almost interpreter" to track lifecycle of template across codebase to solve it. It would be better but orders of magnitude more complex.

@lulco
Copy link
Contributor Author

lulco commented Aug 29, 2023

Yes I know :(

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

No branches or pull requests

2 participants