From b2b9130261a6607d0b133db730b4d0381efbf116 Mon Sep 17 00:00:00 2001 From: Daniel Espendiller Date: Wed, 29 Nov 2023 20:48:47 +0100 Subject: [PATCH] add support for AssetMapper and importmap --- .../assetMapper/AssetMapperUtil.java | 259 ++++++++++++++++++ .../assetMapper/dict/AssetMapperModule.java | 20 ++ .../assetMapper/dict/MappingFileEnum.java | 22 ++ ...AssetMapperModuleReferenceContributor.java | 39 +++ .../TwigTemplateCompletionContributor.java | 15 + .../TwigTemplateGoToDeclarationHandler.java | 22 +- .../symfony2plugin/util/PhpElementsUtil.java | 19 ++ src/main/resources/META-INF/plugin.xml | 4 + .../assetMapper/AssetMapperUtilTest.java | 44 +++ .../tests/assetMapper/fixtures/importmap.php | 40 +++ .../tests/assetMapper/fixtures/installed.php | 63 +++++ 11 files changed, 543 insertions(+), 4 deletions(-) create mode 100644 src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/AssetMapperUtil.java create mode 100644 src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/dict/AssetMapperModule.java create mode 100644 src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/dict/MappingFileEnum.java create mode 100644 src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/references/AssetMapperModuleReferenceContributor.java create mode 100644 src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/AssetMapperUtilTest.java create mode 100644 src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/fixtures/importmap.php create mode 100644 src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/fixtures/installed.php diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/AssetMapperUtil.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/AssetMapperUtil.java new file mode 100644 index 000000000..e968210f2 --- /dev/null +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/AssetMapperUtil.java @@ -0,0 +1,259 @@ +package fr.adrienbrault.idea.symfony2plugin.assetMapper; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.*; +import com.jetbrains.php.lang.psi.elements.ArrayCreationExpression; +import com.jetbrains.php.lang.psi.elements.PhpReturn; +import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons; +import fr.adrienbrault.idea.symfony2plugin.assetMapper.dict.AssetMapperModule; +import fr.adrienbrault.idea.symfony2plugin.assetMapper.dict.MappingFileEnum; +import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil; +import fr.adrienbrault.idea.symfony2plugin.util.ProjectUtil; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author Daniel Espendiller + */ +public class AssetMapperUtil { + + private static final Key>> MAPPING_CACHE = new Key<>("SYMFONY_ASSET_MAPPER_MAPPING_CACHE"); + + public static List getMappingFiles(@NotNull Project project) { + return CachedValuesManager.getManager(project).getCachedValue( + project, + MAPPING_CACHE, + () -> CachedValueProvider.Result.create(getMappingFilesInner(project), PsiModificationTracker.MODIFICATION_COUNT), + false + ); + } + + @NotNull + private static List getMappingFilesInner(@NotNull Project project) { + List modules = new ArrayList<>(); + + Set files = new LinkedHashSet<>(); + + VirtualFile importmapFile = VfsUtil.findRelativeFile(ProjectUtil.getProjectDir(project), "importmap.php"); + if (importmapFile != null) { + files.add(importmapFile); + } + + VirtualFile installedFile = VfsUtil.findRelativeFile(ProjectUtil.getProjectDir(project), "assets", "vendor", "installed.php"); + if (installedFile != null) { + files.add(installedFile); + } + + files.addAll(FilenameIndex.getVirtualFilesByName("importmap.php", GlobalSearchScope.allScope(project))); + for (VirtualFile file : FilenameIndex.getVirtualFilesByName("installed.php", GlobalSearchScope.allScope(project))) { + // composer + VirtualFile parent = file.getParent(); + if (parent != null && "composer".equals(parent.getName())) { + continue; + } + + files.add(file); + } + + for (VirtualFile file : files) { + PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + if (psiFile == null) { + continue; + } + + for (PhpReturn phpReturn : PsiTreeUtil.collectElementsOfType(psiFile, PhpReturn.class)) { + PsiElement argument = phpReturn.getArgument(); + if (argument instanceof ArrayCreationExpression arrayCreationExpression) { + for (Map.Entry entry : PhpElementsUtil.getArrayKeyValueMapWithValueAsPsiElement(arrayCreationExpression).entrySet()) { + String path = null; + String url = null; + String version = null; + Boolean entrypoint = false; + String type = null; + + PsiElement value = entry.getValue(); + if (value instanceof ArrayCreationExpression value2) { + path = PhpElementsUtil.getArrayValueString(value2, "path"); + url = PhpElementsUtil.getArrayValueString(value2, "url"); + version = PhpElementsUtil.getArrayValueString(value2, "version"); + entrypoint = PhpElementsUtil.getArrayValueBool(value2, "entrypoint"); + type = PhpElementsUtil.getArrayValueString(value2, "type"); + } + + modules.add(new AssetMapperModule(MappingFileEnum.fromString(file.getName()), file, entry.getKey(), path, url, version, entrypoint, type)); + } + } + } + } + + return modules; + } + + @NotNull + private static Collection getModuleReferences(@NotNull String module, @NotNull List modules) { + Collection files = new HashSet<>(); + + for (AssetMapperModule mappingFile : modules) { + if (!mappingFile.key().equals(module)) { + continue; + } + + if (mappingFile.sourceType() == MappingFileEnum.IMPORTMAP) { + // default project structure: "assets/vendor/*" + VirtualFile parent = mappingFile.sourceFile().getParent(); + if (parent != null) { + if (mappingFile.path() != null) { + // simple path normalize: "./app.js" + String[] split = Arrays.stream(StringUtils.split(mappingFile.path(), "/")) + .filter(s -> !s.equals(".")) + .toArray(String[]::new); + + VirtualFile relativeFile = VfsUtil.findRelativeFile(parent, split); + if (relativeFile != null) { + files.add(relativeFile); + break; + } + } else { + if ("css".equals(mappingFile.type())) { + String[] split = StringUtils.split("assets/vendor/" + mappingFile.key(), "/"); + VirtualFile relativeFile = VfsUtil.findRelativeFile(parent, split); + if (relativeFile != null) { + files.add(relativeFile); + break; + } + } else if (mappingFile.key().contains("/")) { + String[] split = StringUtils.split("assets/vendor/" + mappingFile.key() + ".js", "/"); + VirtualFile relativeFile = VfsUtil.findRelativeFile(parent, split); + if (relativeFile != null) { + files.add(relativeFile); + break; + } + } else { + VirtualFile relativeFile = VfsUtil.findRelativeFile(parent, "assets", "vendor", mappingFile.key(), mappingFile.key() + ".index.js"); + if (relativeFile != null) { + files.add(relativeFile); + break; + } + } + } + } + } else if (mappingFile.sourceType() == MappingFileEnum.INSTALLED) { + // fallback without project structure: every folder like "vendor/installed.php" => "vendor/bootstrap" + VirtualFile parent = mappingFile.sourceFile().getParent(); + if (parent != null) { + if (mappingFile.key().endsWith("css")) { + String[] split = StringUtils.split(mappingFile.key(), "/"); + VirtualFile relativeFile = VfsUtil.findRelativeFile(parent, split); + if (relativeFile != null) { + files.add(relativeFile); + break; + } + } else if (mappingFile.key().contains("/")) { + String[] split = StringUtils.split(mappingFile.key() + ".js", "/"); + VirtualFile relativeFile = VfsUtil.findRelativeFile(parent, split); + if (relativeFile != null) { + files.add(relativeFile); + break; + } + } else { + VirtualFile relativeFile = VfsUtil.findRelativeFile(parent, mappingFile.key(), mappingFile.key() + ".index.js"); + if (relativeFile != null) { + files.add(relativeFile); + break; + } + } + } + } + } + + return files; + } + + @NotNull + public static Collection getModuleReferences(@NotNull Project project, @NotNull String module) { + return getModuleReferences(module, AssetMapperUtil.getMappingFiles(project)); + } + + @NotNull + public static Collection getEntrypointModuleReferences(@NotNull Project project, @NotNull String module) { + List collect = getEntrypointMappings(project).stream().filter(module1 -> module1.key().equals(module)).collect(Collectors.toList()); + + // mapping targets + Collection files = collect.stream() + .map(AssetMapperModule::sourceFile) + .collect(Collectors.toSet()); + + // mapping reference tags + files.addAll(getModuleReferences(module, collect)); + + return files; + } + + @NotNull + private static List getEntrypointMappings(@NotNull Project project) { + return AssetMapperUtil.getMappingFiles(project).stream().filter(m -> m.entrypoint() != null && m.entrypoint()).collect(Collectors.toList()); + } + + @NotNull + public static Collection getLookupElements(@NotNull Project project) { + return getLookupElements(AssetMapperUtil.getMappingFiles(project)); + } + + @NotNull + public static Collection getEntrypointLookupElements(@NotNull Project project) { + return getLookupElements(getEntrypointMappings(project)); + } + + @NotNull + public static Collection getLookupElements(@NotNull List modules) { + Collection lookupElements = new ArrayList<>(); + + Set visited = new HashSet<>(); + for (AssetMapperModule module : modules) { + if (visited.contains(module.key())) { + continue; + } + + visited.add(module.key()); + + LookupElementBuilder elementBuilder = LookupElementBuilder.create(module.key()).withIcon(Symfony2Icons.SYMFONY); + String typeText = ""; + + if (module.url() != null) { + typeText = module.url(); + } else if (module.path() != null) { + typeText = module.path(); + } + + if (module.version() != null) { + if (!typeText.isBlank()) { + typeText = module.version() + " " + typeText; + } else { + typeText = module.version(); + } + } + + if (!typeText.isBlank()) { + elementBuilder = elementBuilder.withTypeText(typeText); + } + + lookupElements.add(elementBuilder); + } + + return lookupElements; + } +} diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/dict/AssetMapperModule.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/dict/AssetMapperModule.java new file mode 100644 index 000000000..3b7692fb7 --- /dev/null +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/dict/AssetMapperModule.java @@ -0,0 +1,20 @@ +package fr.adrienbrault.idea.symfony2plugin.assetMapper.dict; + +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Daniel Espendiller + */ +public record AssetMapperModule( + @NotNull MappingFileEnum sourceType, + @NotNull VirtualFile sourceFile, + @NotNull String key, + @Nullable String path, + @Nullable String url, + @Nullable String version, + @Nullable Boolean entrypoint, + @Nullable String type +) { +} diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/dict/MappingFileEnum.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/dict/MappingFileEnum.java new file mode 100644 index 000000000..d5d10a6d0 --- /dev/null +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/dict/MappingFileEnum.java @@ -0,0 +1,22 @@ +package fr.adrienbrault.idea.symfony2plugin.assetMapper.dict; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Daniel Espendiller + */ +public enum MappingFileEnum { + IMPORTMAP, INSTALLED; + + public static MappingFileEnum fromString(@NotNull String text) { + if (text.equalsIgnoreCase("importmap.php")) { + return IMPORTMAP; + } + + if (text.equalsIgnoreCase("installed.php")) { + return INSTALLED; + } + + throw new RuntimeException("invalid filename"); + } +} diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/references/AssetMapperModuleReferenceContributor.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/references/AssetMapperModuleReferenceContributor.java new file mode 100644 index 000000000..b72dd0a19 --- /dev/null +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/assetMapper/references/AssetMapperModuleReferenceContributor.java @@ -0,0 +1,39 @@ +package fr.adrienbrault.idea.symfony2plugin.assetMapper.references; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.lang.javascript.frameworks.modules.JSResolvableModuleReferenceContributor; +import com.intellij.lang.javascript.psi.resolve.JSResolveResult; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.ResolveResult; +import fr.adrienbrault.idea.symfony2plugin.assetMapper.AssetMapperUtil; +import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * @author Daniel Espendiller + */ +public class AssetMapperModuleReferenceContributor extends JSResolvableModuleReferenceContributor { + @Override + protected ResolveResult @NotNull [] resolveElement(@NotNull PsiElement psiElement, @NotNull String module) { + Collection files = AssetMapperUtil.getModuleReferences(psiElement.getProject(), module); + + if (files.isEmpty()) { + return new ResolveResult[0]; + } + + return JSResolveResult.toResolveResults(PsiElementUtils.convertVirtualFilesToPsiFiles(psiElement.getProject(), files)); + } + + @Override + public @NotNull Collection getLookupElements(@NotNull String unquotedEscapedText, @NotNull PsiElement host) { + return AssetMapperUtil.getLookupElements(host.getProject()); + } + + @Override + public int getDefaultWeight() { + return 10; + } +} diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateCompletionContributor.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateCompletionContributor.java index 6bc88b701..b0b524b41 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateCompletionContributor.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateCompletionContributor.java @@ -29,6 +29,7 @@ import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent; import fr.adrienbrault.idea.symfony2plugin.asset.AssetDirectoryReader; import fr.adrienbrault.idea.symfony2plugin.asset.provider.AssetCompletionProvider; +import fr.adrienbrault.idea.symfony2plugin.assetMapper.AssetMapperUtil; import fr.adrienbrault.idea.symfony2plugin.dic.MethodReferenceBag; import fr.adrienbrault.idea.symfony2plugin.dic.ServiceCompletionProvider; import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper; @@ -298,6 +299,9 @@ public void addCompletions(@NotNull CompletionParameters parameters, @NotNull Pr // {% render(controller('')) %} extend(CompletionType.BASIC, TwigPattern.getPrintBlockOrTagFunctionPattern("controller"), new ControllerCompletionProvider()); + // {{ importmap('') }} + extend(CompletionType.BASIC, TwigPattern.getPrintBlockOrTagFunctionPattern("importmap"), new ImportmapCompletionProvider()); + // {% foo() %} // {% foo.bar() %} // {{ 'test'| }} @@ -642,6 +646,17 @@ public void addCompletions(@NotNull CompletionParameters parameters, @NotNull Pr } } + private static class ImportmapCompletionProvider extends CompletionProvider { + public void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet resultSet) { + PsiElement position = parameters.getPosition(); + if(!Symfony2ProjectComponent.isEnabled(position)) { + return; + } + + resultSet.addAllElements(AssetMapperUtil.getEntrypointLookupElements(position.getProject())); + } + } + private static class TwigSimpleTestParametersCompletionProvider extends CompletionProvider { public void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet resultSet) { PsiElement position = parameters.getPosition(); diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateGoToDeclarationHandler.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateGoToDeclarationHandler.java index 557e2244a..815a4f767 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateGoToDeclarationHandler.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateGoToDeclarationHandler.java @@ -6,10 +6,7 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.patterns.PlatformPatterns; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiManager; -import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.php.PhpIndex; @@ -22,6 +19,7 @@ import com.jetbrains.twig.elements.TwigPsiReference; import com.jetbrains.twig.elements.TwigVariableReference; import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent; +import fr.adrienbrault.idea.symfony2plugin.assetMapper.AssetMapperUtil; import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper; import fr.adrienbrault.idea.symfony2plugin.templating.dict.TwigExtension; import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigExtensionParser; @@ -108,6 +106,10 @@ public PsiElement[] getGotoDeclarationTargets(PsiElement psiElement, int offset, targets.addAll(getControllerGoTo(psiElement)); } + if (TwigPattern.getPrintBlockOrTagFunctionPattern("importmap").accepts(psiElement)) { + targets.addAll(getImportmapGoTo(psiElement)); + } + if (TwigPattern.getTransDefaultDomainPattern().accepts(psiElement)) { targets.addAll(TranslationUtil.getDomainPsiFiles(psiElement.getProject(), psiElement.getText())); } @@ -251,6 +253,18 @@ private Collection getControllerGoTo(@NotNull PsiElement psiElement return Arrays.asList(RouteHelper.getMethodsOnControllerShortcut(psiElement.getProject(), text)); } + private Collection getImportmapGoTo(@NotNull PsiElement psiElement) { + String text = PsiElementUtils.trimQuote(psiElement.getText()); + if (text.isBlank()) { + return Collections.emptyList(); + } + + return PsiElementUtils.convertVirtualFilesToPsiFiles( + psiElement.getProject(), + AssetMapperUtil.getEntrypointModuleReferences(psiElement.getProject(), text) + ); + } + @NotNull private Collection getTwigFiles(@NotNull PsiElement psiElement, int offset) { int calulatedOffset = offset - psiElement.getTextRange().getStartOffset(); diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java index b82656480..bf2d9d39a 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java @@ -311,6 +311,25 @@ static public String getArrayValueString(@NotNull ArrayCreationExpression arrayC return null; } + @Nullable + static public Boolean getArrayValueBool(@NotNull ArrayCreationExpression arrayCreationExpression, @NotNull String name) { + PhpPsiElement phpPsiElement = getArrayValue(arrayCreationExpression, name); + if(phpPsiElement == null) { + return null; + } + + if (phpPsiElement instanceof ConstantReference) { + String lowerCase = phpPsiElement.getText().toLowerCase(); + if (lowerCase.equals("true")) { + return true; + } else if (lowerCase.equals("false")) { + return false; + } + } + + return null; + } + static public PhpNamedElement[] getPsiElementsBySignature(@NotNull Project project, @Nullable String signature) { if(signature == null) { diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 2a212d3fc..6703a6299 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -711,6 +711,10 @@ + + + + com.jetbrains.twig com.jetbrains.php JavaScript diff --git a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/AssetMapperUtilTest.java b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/AssetMapperUtilTest.java new file mode 100644 index 000000000..0407581c1 --- /dev/null +++ b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/AssetMapperUtilTest.java @@ -0,0 +1,44 @@ +package fr.adrienbrault.idea.symfony2plugin.tests.assetMapper; + +import fr.adrienbrault.idea.symfony2plugin.assetMapper.AssetMapperUtil; +import fr.adrienbrault.idea.symfony2plugin.assetMapper.dict.AssetMapperModule; +import fr.adrienbrault.idea.symfony2plugin.assetMapper.dict.MappingFileEnum; +import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase; + +import java.util.List; + +/** + * @author Daniel Espendiller + */ +public class AssetMapperUtilTest extends SymfonyLightCodeInsightFixtureTestCase { + public void setUp() throws Exception { + super.setUp(); + + myFixture.copyFileToProject("importmap.php"); + myFixture.copyFileToProject("installed.php"); + } + + public String getTestDataPath() { + return "src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/fixtures"; + } + + public void testGetMappingFiles() { + List mappingFiles = AssetMapperUtil.getMappingFiles(getProject()); + + AssetMapperModule app = mappingFiles.stream().filter(m -> m.sourceType() == MappingFileEnum.IMPORTMAP && m.key().equals("app")).findFirst().get(); + assertTrue(app.entrypoint()); + assertEquals("./assets/app.js", app.path()); + assertNull(app.version()); + + AssetMapperModule css = mappingFiles.stream().filter(m -> m.sourceType() == MappingFileEnum.IMPORTMAP && m.key().equals("bootstrap/dist/css/bootstrap.min.css")).findFirst().get(); + assertNull(css.entrypoint()); + assertNull(css.path()); + assertEquals("5.3.2", css.version()); + assertEquals("css", css.type()); + + AssetMapperModule lodash = mappingFiles.stream().filter(m -> m.sourceType() == MappingFileEnum.INSTALLED && m.key().equals("lodash")).findFirst().get(); + assertNull(lodash.entrypoint()); + assertNull(lodash.path()); + assertEquals("4.17.21", lodash.version()); + } +} diff --git a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/fixtures/importmap.php b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/fixtures/importmap.php new file mode 100644 index 000000000..6dd3c84f2 --- /dev/null +++ b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/fixtures/importmap.php @@ -0,0 +1,40 @@ + [ + 'path' => './assets/app.js', + 'entrypoint' => true, + ], + 'lodash' => [ + 'version' => '4.17.21', + ], + 'bootstrap' => [ + 'version' => '5.3.2', + ], + '@popperjs/core' => [ + 'version' => '2.11.8', + ], + 'bootstrap/dist/css/bootstrap.min.css' => [ + 'version' => '5.3.2', + 'type' => 'css', + ], + 'highlight.js/lib/core' => [ + 'version' => '11.9.0', + ], + 'highlight.js/lib/languages/javascript' => [ + 'version' => '11.9.0', + ], +]; diff --git a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/fixtures/installed.php b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/fixtures/installed.php new file mode 100644 index 000000000..3d4e1004b --- /dev/null +++ b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/assetMapper/fixtures/installed.php @@ -0,0 +1,63 @@ + + array ( + 'version' => '4.17.21', + 'dependencies' => + array ( + ), + 'extraFiles' => + array ( + ), + ), + 'bootstrap' => + array ( + 'version' => '5.3.2', + 'dependencies' => + array ( + 0 => '@popperjs/core', + ), + 'extraFiles' => + array ( + ), + ), + '@popperjs/core' => + array ( + 'version' => '2.11.8', + 'dependencies' => + array ( + ), + 'extraFiles' => + array ( + ), + ), + 'bootstrap/dist/css/bootstrap.min.css' => + array ( + 'version' => '5.3.2', + 'dependencies' => + array ( + ), + 'extraFiles' => + array ( + ), + ), + 'highlight.js/lib/core' => + array ( + 'version' => '11.9.0', + 'dependencies' => + array ( + ), + 'extraFiles' => + array ( + ), + ), + 'highlight.js/lib/languages/javascript' => + array ( + 'version' => '11.9.0', + 'dependencies' => + array ( + ), + 'extraFiles' => + array ( + ), + ), +); \ No newline at end of file