package fr.adrienbrault.idea.symfony2plugin.tests.routing; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.ide.highlighter.XmlFileType; import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFileFactory; import com.intellij.psi.xml.XmlFile; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.php.lang.psi.PhpPsiElementFactory; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; import fr.adrienbrault.idea.symfony2plugin.routing.Route; import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper; import fr.adrienbrault.idea.symfony2plugin.stubs.dict.StubIndexedRoute; import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase; import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil; import fr.adrienbrault.idea.symfony2plugin.util.yaml.YamlPsiElementFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.yaml.psi.YAMLDocument; import java.io.File; import java.util.*; /** * @author Daniel Espendiller <daniel@espendiller.net> * * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper */ public class RouteHelperTest extends SymfonyLightCodeInsightFixtureTestCase { public void setUp() throws Exception { super.setUp(); myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject("RouteHelper.php")); myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject("classes.php")); } protected String getTestDataPath() { return new File(this.getClass().getResource("fixtures").getFile()).getAbsolutePath(); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getYamlRouteDefinitions */ public void testGetYamlRouteDefinitionsAsHashAndKeyValue() { Collection<String[]> providers = new ArrayList<String[]>() {{ add(new String[] {"'MyController::fooAction'", "MyController::fooAction"}); add(new String[] {"MyController::fooAction", "MyController::fooAction"}); add(new String[] {"\"MyController::fooAction\"", "MyController::fooAction"}); }}; for (String[] provider : providers) { Collection<YAMLDocument> yamlDocuments = new ArrayList<YAMLDocument>(); yamlDocuments.add(YamlPsiElementFactory.createFromText(getProject(), YAMLDocument.class, String.format( "route1:\n" + " path: /foo\n" + " defaults: { _controller: %s }", provider[1] ))); yamlDocuments.add(YamlPsiElementFactory.createFromText(getProject(), YAMLDocument.class, String.format( "route1:\n" + " path: /foo\n" + " defaults:\n" + " _controller: %s", provider[1] ))); yamlDocuments.add(YamlPsiElementFactory.createFromText(getProject(), YAMLDocument.class, String.format( "route1:\n" + " pattern: /foo\n" + " defaults:\n" + " _controller: %s", provider[1] ))); for (YAMLDocument yamlDocument : yamlDocuments) { StubIndexedRoute route1 = ContainerUtil.find(RouteHelper.getYamlRouteDefinitions(yamlDocument), new MyEqualStubIndexedRouteCondition("route1")); assertNotNull(route1); assertEquals(provider[1], route1.getController()); assertEquals("route1", route1.getName()); assertEquals("/foo", route1.getPath()); } } } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getYamlRouteDefinitions */ public void testGetYamlRouteDefinitionsWithMethods() { Collection<StubIndexedRoute> yamlRouteDefinitions = RouteHelper.getYamlRouteDefinitions(YamlPsiElementFactory.createFromText(getProject(), YAMLDocument.class, "route1:\n" + " path: /foo\n" + " methods: [GET]\n" + "route2:\n" + " path: /foo\n" + " methods: GET\n" + "route3:\n" + " path: /foo\n" + " methods: [GET, POST]\n" )); assertContainsElements(Collections.singletonList("get"), ContainerUtil.find(yamlRouteDefinitions, new MyEqualStubIndexedRouteCondition("route1")).getMethods()); assertContainsElements(Collections.singletonList("get"), ContainerUtil.find(yamlRouteDefinitions, new MyEqualStubIndexedRouteCondition("route2")).getMethods()); assertContainsElements(Arrays.asList("get", "post"), ContainerUtil.find(yamlRouteDefinitions, new MyEqualStubIndexedRouteCondition("route3")).getMethods()); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getXmlRouteDefinitions */ public void testGetXmlRouteDefinitions() { Collection<XmlFile> xmlFiles = new ArrayList<XmlFile>(); xmlFiles.add(createXmlFile("" + "<routes>\n" + " <route id=\"foo2\" path=\"/blog/{slug}\">\n" + " <default key=\"_controller\">MyController::fooAction</default>\n" + " </route>\n" + "</routes>" )); xmlFiles.add(createXmlFile("" + "<routes>\n" + " <route id=\"foo2\" pattern=\"/blog/{slug}\">\n" + " <default key=\"_controller\">MyController::fooAction</default>\n" + " </route>\n" + "</routes>" )); for (XmlFile xmlFile : xmlFiles) { StubIndexedRoute route1 = ContainerUtil.find(RouteHelper.getXmlRouteDefinitions(xmlFile), new MyEqualStubIndexedRouteCondition("foo2")); assertNotNull(route1); assertEquals("MyController::fooAction", route1.getController()); assertEquals("foo2", route1.getName()); assertEquals("/blog/{slug}", route1.getPath()); } } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getXmlRouteDefinitions */ public void testGetXmlRouteDefinitionsWithoutController() { StubIndexedRoute route1 = ContainerUtil.find(RouteHelper.getXmlRouteDefinitions(createXmlFile("" + "<routes>\n" + " <route id=\"foo2\" pattern=\"/blog/{slug}\"/>\n" + "</routes>" )), new MyEqualStubIndexedRouteCondition("foo2")); assertNotNull(route1); assertNull(route1.getController()); assertEquals("foo2", route1.getName()); assertEquals("/blog/{slug}", route1.getPath()); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getXmlRouteDefinitions */ public void testGetXmlRouteDefinitionsWithoutPath() { StubIndexedRoute route = ContainerUtil.find(RouteHelper.getXmlRouteDefinitions(createXmlFile("" + "<routes>\n" + " <route id=\"foo2\"/>\n" + "</routes>" )), new MyEqualStubIndexedRouteCondition("foo2")); assertNotNull(route); assertNull(route.getController()); assertEquals("foo2", route.getName()); assertNull(route.getPath()); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getXmlRouteDefinitions */ public void testGetXmlRouteDefinitionsWithMethods() { Collection<StubIndexedRoute> xmlRouteDefinitions = RouteHelper.getXmlRouteDefinitions(createXmlFile("" + "<routes>\n" + " <route id=\"foo2\" methods=\"GET\"/>\n" + " <route id=\"foo3\" methods=\"GET | POST |PUT | FIGHT\"/>\n" + "</routes>" )); assertContainsElements( Collections.singletonList("get"), ContainerUtil.find(xmlRouteDefinitions, new MyEqualStubIndexedRouteCondition("foo2")).getMethods() ); assertContainsElements( Arrays.asList("get", "post", "put", "fight"), ContainerUtil.find(xmlRouteDefinitions, new MyEqualStubIndexedRouteCondition("foo3")).getMethods() ); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getAllRoutes */ public void testGetAllRoutes() { Map<String, Route> allRoutes = RouteHelper.getAllRoutes(getProject()); assertEquals("myfoobar_car_index", allRoutes.get("myfoobar_car_index").getName()); assertEquals("/foo_bar/edit/{id}", allRoutes.get("myfoobar_car_index").getPath()); assertEquals("MyFooBarBundle\\Controller\\CarController::indexAction", allRoutes.get("myfoobar_car_index").getController()); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getRoutesLookupElements */ public void testGetRoutesLookupElements() { assertNotNull(ContainerUtil.find(RouteHelper.getRoutesLookupElements(getProject()), new Condition<LookupElement>() { @Override public boolean value(LookupElement lookupElement) { return "myfoobar_car_index".equals(lookupElement.getLookupString()); } })); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getRoutesInsideUrlGeneratorFile */ public void testGetRoutesInsideUrlGeneratorFile() { Map<String, Route> routes = RouteHelper.getRoutesInsideUrlGeneratorFile(getProject(), myFixture.copyFileToProject("appTestUrlGenerator.php")); assertEquals("Lol\\CoreBundle\\Controller\\FeedbackController::feedbackAction", routes.get("feedback").getController()); assertEquals("Lol\\ApiBundle\\Controller\\UsersController::getInfoAction", routes.get("api_users_getInfo").getController()); assertNull(routes.get("ru__RG__page")); assertNull(routes.get("_assetic_91dd2a8")); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#convertMethodToRouteShortcutControllerName */ public void testConvertMethodToRouteShortcutControllerName() { myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject("GetRoutesOnControllerAction.php")); PhpClass phpClass = PhpPsiElementFactory.createPhpPsiFromText(getProject(), PhpClass.class, "<?php\n" + "namespace FooBar\\FooBundle\\Controller" + "{\n" + " class FooBarController\n" + " {\n" + " function fooAction() {}\n" + " }\n" + "}" ); Method fooAction = phpClass.findMethodByName("fooAction"); assertNotNull(fooAction); assertEquals("FooBarFooBundle:FooBar:foo", RouteHelper.convertMethodToRouteShortcutControllerName(fooAction)); phpClass = PhpPsiElementFactory.createPhpPsiFromText(getProject(), PhpClass.class, "<?php\n" + "namespace FooBar\\FooBundle\\Controller\\SubFolder" + "{\n" + " class SubController\n" + " {\n" + " function fooAction() {}\n" + " }\n" + "}" ); fooAction = phpClass.findMethodByName("fooAction"); assertNotNull(fooAction); assertEquals("FooBarFooBundle:SubFolder\\Sub:foo", RouteHelper.convertMethodToRouteShortcutControllerName(fooAction)); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getRoutesOnControllerAction */ public void testGetRoutesOnControllerAction() { myFixture.copyFileToProject("GetRoutesOnControllerAction.php"); myFixture.copyFileToProject("GetRoutesOnControllerAction.routing.xml"); myFixture.copyFileToProject("GetRoutesOnControllerAction.services.xml"); PhpClass phpClass = PhpPsiElementFactory.createPhpPsiFromText(getProject(), PhpClass.class, "<?php\n" + "namespace FooBar\\FooBundle\\Controller\\SubFolder" + "{\n" + " class FooBarController\n" + " {\n" + " function fooAction() {}\n" + " }\n" + "}" ); Method fooAction = phpClass.findMethodByName("fooAction"); assertNotNull(fooAction); List<Route> routesOnControllerAction = RouteHelper.getRoutesOnControllerAction(fooAction); assertNotNull(ContainerUtil.find(routesOnControllerAction, route -> "xml_route_subfolder_backslash".equals(route.getName()) )); assertNotNull(ContainerUtil.find(routesOnControllerAction, route -> "xml_route_subfolder_slash".equals(route.getName()) )); assertNotNull(ContainerUtil.find(routesOnControllerAction, route -> "xml_route_subfolder_class_syntax".equals(route.getName()) )); // controller as service Method indexAction = PhpElementsUtil.getClassMethod(getProject(), "Service\\Controller\\FooController", "indexAction"); assertNotNull(indexAction); assertNotNull(ContainerUtil.find(RouteHelper.getRoutesOnControllerAction(indexAction), route -> "xml_route_as_service".equals(route.getName()) )); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getRoutesInsideUrlGeneratorFile */ public void testGetRoutesInsideUrlGeneratorFileForConstructor() { Map<String, Route> routes = RouteHelper.getRoutesInsideUrlGeneratorFile(getProject(), myFixture.copyFileToProject("appDevUrlGenerator-28.php")); Route wdt = routes.get("_wdt"); assertEquals("web_profiler.controller.profiler:toolbarAction", wdt.getController()); assertSize(1, wdt.getVariables()); assertSize(1, wdt.getDefaults().values()); assertSize(2, wdt.getTokens()); } /** * @see fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper#getRouteNameTarget */ public void testGetRouteNameTarget() { PsiElement element = RouteHelper.getRouteNameTarget(getProject(), "my_car_foo_stuff"); assertNotNull(element); assertTrue(element.getText().contains("my_car_foo_stuff")); element = RouteHelper.getRouteNameTarget(getProject(), "myfoobar_car_index"); assertNotNull(element); assertTrue(element.getText().contains("Route")); element = RouteHelper.getRouteNameTarget(getProject(), "my_car_foo_stuff_2"); assertNotNull(element); assertTrue(element.getText().contains("my_car_foo_stuff_2")); } @NotNull private XmlFile createXmlFile(@NotNull String content) { return (XmlFile) PsiFileFactory.getInstance(getProject()).createFileFromText("DUMMY__." + XmlFileType.INSTANCE.getDefaultExtension(), XmlFileType.INSTANCE, content); } private static class MyEqualStubIndexedRouteCondition implements Condition<StubIndexedRoute> { @NotNull private final String routeName; public MyEqualStubIndexedRouteCondition(@NotNull String routeName) { this.routeName = routeName; } @Override public boolean value(StubIndexedRoute stubIndexedRoute) { return stubIndexedRoute.getName().equals(this.routeName); } } }