From dd98511c1cdfbb039a63e2a6a9f4b2b0b5a7f0bd Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Fri, 14 Jun 2019 15:45:13 -0700 Subject: [PATCH] Regression tests for symbol dependency handling --- .../vscode/boot/app/SpringSymbolIndex.java | 4 + .../boot/java/utils/FileScanListener.java | 15 ++ .../boot/java/utils/SpringIndexerJava.java | 20 ++- ...stMappingDependentConstantChangedTest.java | 165 ++++++++++++++++++ .../RequestMappingSymbolProviderTest.java | 62 +++++++ .../test/TestFileScanListener.java | 58 ++++++ .../project/harness/ProjectsHarness.java | 14 +- .../org/test/PingConstantRequestMapping.java | 15 ++ .../org/test/PongConstantRequestMapping.java | 14 ++ 9 files changed, 361 insertions(+), 6 deletions(-) create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/FileScanListener.java create mode 100644 headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingDependentConstantChangedTest.java create mode 100644 headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/TestFileScanListener.java create mode 100644 headless-services/spring-boot-language-server/src/test/resources/test-projects/test-request-mapping-symbols/src/main/java/org/test/PingConstantRequestMapping.java create mode 100644 headless-services/spring-boot-language-server/src/test/resources/test-projects/test-request-mapping-symbols/src/main/java/org/test/PongConstantRequestMapping.java diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java index 2dda2a3b6..96f27598b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java @@ -284,6 +284,10 @@ public class SpringSymbolIndex implements InitializingBean { } } + public SpringIndexerJava getJavaIndexer() { + return springIndexerJava; + } + public CompletableFuture deleteProject(IJavaProject project) { try { if (project.getElementName() == null) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/FileScanListener.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/FileScanListener.java new file mode 100644 index 000000000..d09f8679d --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/FileScanListener.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2019 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.utils; + +public interface FileScanListener { + void fileScanned(String path); +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java index dfc7bd111..78fbffc5b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java @@ -76,10 +76,15 @@ public class SpringIndexerJava implements SpringIndexer { private final SymbolCache cache; private final JavaProjectFinder projectFinder; private boolean scanTestJavaSources = false; + private FileScanListener fileScanListener = null; //used by test code only private final DependencyTracker dependencyTracker = new DependencyTracker(); - static class DependencyTracker { + public DependencyTracker getDependencyTracker() { + return dependencyTracker; + } + + public static class DependencyTracker { private Multimap dependencies = MultimapBuilder.hashKeys().hashSetValues().build(); @@ -190,7 +195,6 @@ public class SpringIndexerJava implements SpringIndexer { List generatedSymbols = new ArrayList(); AtomicReference docRef = new AtomicReference<>(); String file = UriUtil.toFileString(docURI); - Set changedTypes = new HashSet<>(); SpringIndexerJavaContext context = new SpringIndexerJavaContext(project, cu, docURI, file, lastModified, docRef, content, generatedSymbols, SCAN_PASS.ONE, new ArrayList<>(), changedTypes); @@ -206,10 +210,17 @@ public class SpringIndexerJava implements SpringIndexer { } Set scannedFiles = new HashSet<>(); scannedFiles.add(file); + fileScannedEvent(file); scanAffectedFiles(project, changedTypes, scannedFiles); } } + private void fileScannedEvent(String file) { + if (fileScanListener!=null) { + fileScanListener.fileScanned(file); + } + } + private void scanAffectedFiles(IJavaProject project, Set changedTypes, Set scannedFiles) { log.info("Start scanning affected files for types {}", changedTypes); //TODO: optimise? When multiple files are 'affected', we could try to parse and scan them in batch. @@ -231,6 +242,7 @@ public class SpringIndexerJava implements SpringIndexer { log.debug("Should also scan affected file: {}", file); File f = new File(file); scanAffectedFile(project, UriUtil.toUri(f).toString(), f.lastModified(), FileUtils.readFileToString(f), changedTypes); + fileScannedEvent(file); } } } catch (Exception e) { @@ -600,4 +612,8 @@ public class SpringIndexerJava implements SpringIndexer { } } + public void setFileScanListener(FileScanListener fileScanListener) { + this.fileScanListener = fileScanListener; + } + } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingDependentConstantChangedTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingDependentConstantChangedTest.java new file mode 100644 index 000000000..7d28dc54c --- /dev/null +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingDependentConstantChangedTest.java @@ -0,0 +1,165 @@ +package org.springframework.ide.vscode.boot.java.requestmapping.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.FileUtils; +import org.eclipse.lsp4j.Location; +import org.eclipse.lsp4j.SymbolInformation; +import org.eclipse.lsp4j.TextDocumentIdentifier; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Import; +import org.springframework.ide.vscode.boot.app.SpringSymbolIndex; +import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest; +import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf; +import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject; +import org.springframework.ide.vscode.commons.util.UriUtil; +import org.springframework.ide.vscode.commons.util.text.LanguageId; +import org.springframework.ide.vscode.commons.util.text.TextDocument; +import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness; +import org.springframework.ide.vscode.project.harness.ProjectsHarness; +import org.springframework.ide.vscode.project.harness.ProjectsHarness.CustomizableProjectContent; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@BootLanguageServerTest +@Import(SymbolProviderTestConf.class) +public class RequestMappingDependentConstantChangedTest { + + @Autowired private BootLanguageServerHarness harness; + @Autowired private JavaProjectFinder projectFinder; + @Autowired private SpringSymbolIndex indexer; + + ProjectsHarness projects = ProjectsHarness.INSTANCE; + private MavenJavaProject project; + private Path directory; + + @Before + public void setup() throws Exception { + harness.intialize(null); + + project = (MavenJavaProject) projects.mavenProject("test-request-mapping-symbols", false, new ProjectsHarness.ProjectCustomizer() { + @Override + public void customize(CustomizableProjectContent projectContent) throws Exception { + //dummy (forces every test to use a new copy of the project, we do this because project + //files are being mutated! + } + }); + directory = new File(project.getLocationUri()).toPath(); + + // trigger project creation + projectFinder.find(new TextDocumentIdentifier(project.getLocationUri().toString())).get(); + + CompletableFuture initProject = indexer.waitOperation(); + initProject.get(5, TimeUnit.SECONDS); + } + + @Test + public void testSimpleRequestMappingSymbolFromConstantInDifferentClass() throws Exception { + String docUri = directory.resolve("src/main/java/org/test/SimpleMappingClassWithConstantInDifferentClass.java").toUri().toString(); + String constantsUri = directory.resolve("src/main/java/org/test/Constants.java").toUri().toString(); + List symbols = indexer.getSymbols(docUri); + assertEquals(1, symbols.size()); + assertSymbol(docUri, "@/path/from/constant", "@RequestMapping(Constants.REQUEST_MAPPING_PATH)"); + + TestFileScanListener fileScanListener = new TestFileScanListener(); + indexer.getJavaIndexer().setFileScanListener(fileScanListener); + + replaceInFile(constantsUri, "path/from/constant", "/changed-path"); + fileScanListener.assertScannedUris(constantsUri, docUri); + fileScanListener.assertScannedUri(constantsUri, 1); + fileScanListener.assertScannedUri(docUri, 1); + + symbols = indexer.getSymbols(docUri); + assertSymbolCount(1, symbols); + assertSymbol(docUri, "@/changed-path", "@RequestMapping(Constants.REQUEST_MAPPING_PATH)"); + } + + @Test public void testCyclicalDependency() throws Exception { + //cyclical dependency between two files (ping refers pong and vice versa) + + String pingUri = directory.resolve("src/main/java/org/test/PingConstantRequestMapping.java").toUri().toString(); + String pongUri = directory.resolve("src/main/java/org/test/PongConstantRequestMapping.java").toUri().toString(); + + { + List symbols = indexer.getSymbols(pingUri); + for (SymbolInformation s : symbols) { + System.out.println(s.getName()); + } + assertSymbolCount(1, symbols); + assertSymbol(pingUri, "@/pong -- GET", "@GetMapping(PongConstantRequestMapping.PONG)"); + } + { + List symbols = indexer.getSymbols(pongUri); + assertSymbolCount(1, symbols); + assertSymbol(pongUri, "@/ping -- GET", "@GetMapping(PingConstantRequestMapping.PING)"); + } + + replaceInFile(pingUri, "/ping", "/changed"); + + { + List symbols = indexer.getSymbols(pingUri); + assertSymbolCount(1, symbols); + assertSymbol(pingUri, "@/pong -- GET", "@GetMapping(PongConstantRequestMapping.PONG)"); + } + { + List symbols = indexer.getSymbols(pongUri); + assertSymbolCount(1, symbols); + assertSymbol(pongUri, "@/changed -- GET", "@GetMapping(PingConstantRequestMapping.PING)"); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + + private void assertSymbolCount(int expectedCount, List symbols) { + if (symbols.size()!=expectedCount) { + StringBuilder found = new StringBuilder(); + for (SymbolInformation s : symbols) { + found.append(s.getName()); + found.append("\n"); + } + fail("Expected "+expectedCount+" symbols but found "+symbols.size()+":\n"+found); + } + } + + private void assertSymbol(String docUri, String name, String coveredText) throws Exception { + List symbols = indexer.getSymbols(docUri); + Optional maybeSymbol = symbols.stream().filter(s -> name.equals(s.getName())).findFirst(); + assertTrue(maybeSymbol.isPresent()); + + TextDocument doc = new TextDocument(docUri, LanguageId.JAVA); + doc.setText(FileUtils.readFileToString(UriUtil.toFile(docUri))); + + SymbolInformation symbol = maybeSymbol.get(); + Location loc = symbol.getLocation(); + assertEquals(docUri, loc.getUri()); + int start = doc.toOffset(loc.getRange().getStart()); + int end = doc.toOffset(loc.getRange().getEnd()); + String actualCoveredText = doc.textBetween(start, end); + assertEquals(coveredText, actualCoveredText); + } + + public void replaceInFile(String docUri, String find, String replace) throws Exception { + File target = UriUtil.toFile(docUri); + String oldContent = FileUtils.readFileToString(target, "UTF8"); + assertTrue(oldContent.contains(find)); + String newContent = oldContent.replace(find, replace); + FileUtils.write(target, newContent, "UTF8"); + + indexer.updateDocument(docUri, null, "triggered by test code").get(); + } +} diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java index 4dbba78bf..cc6a0cc6b 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java @@ -16,9 +16,12 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import org.apache.commons.io.FileUtils; +import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.SymbolInformation; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.junit.Before; @@ -29,11 +32,17 @@ import org.springframework.context.annotation.Import; import org.springframework.ide.vscode.boot.app.SpringSymbolIndex; import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest; import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf; +import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJava.DependencyTracker; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +import org.springframework.ide.vscode.commons.util.UriUtil; +import org.springframework.ide.vscode.commons.util.text.LanguageId; +import org.springframework.ide.vscode.commons.util.text.TextDocument; import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness; import org.springframework.ide.vscode.project.harness.ProjectsHarness; import org.springframework.test.context.junit4.SpringRunner; +import com.google.common.collect.ImmutableSet; + /** * @author Martin Lippert */ @@ -73,9 +82,45 @@ public class RequestMappingSymbolProviderTest { @Test public void testSimpleRequestMappingSymbolFromConstantInDifferentClass() throws Exception { String docUri = directory.toPath().resolve("src/main/java/org/test/SimpleMappingClassWithConstantInDifferentClass.java").toUri().toString(); + String constantsUri = directory.toPath().resolve("src/main/java/org/test/Constants.java").toUri().toString(); List symbols = indexer.getSymbols(docUri); assertEquals(1, symbols.size()); assertTrue(containsSymbol(symbols, "@/path/from/constant", docUri, 6, 1, 6, 48)); + + //Verify whether dependency tracker logics works properly for this example. + DependencyTracker dt = indexer.getJavaIndexer().getDependencyTracker(); + assertEquals(ImmutableSet.of("Lorg/test/Constants;"), dt.getAllDependencies().get(UriUtil.toFileString(docUri))); + + + TestFileScanListener fileScanListener = new TestFileScanListener(); + indexer.getJavaIndexer().setFileScanListener(fileScanListener); + indexer.updateDocument(constantsUri, FileUtils.readFileToString(UriUtil.toFile(constantsUri)), "test triggered").get(); + fileScanListener.assertScannedUris(constantsUri, docUri); + fileScanListener.assertScannedUri(constantsUri, 1); + fileScanListener.assertScannedUri(docUri, 1); + } + + @Test + public void testCyclicalRequestMappingDependency() throws Exception { + //Cyclical dependency: + //file a => file b => file a + //This has the potential to cause infinite loop. + + String pingUri = directory.toPath().resolve("src/main/java/org/test/PingConstantRequestMapping.java").toUri().toString(); + String pongUri = directory.toPath().resolve("src/main/java/org/test/PongConstantRequestMapping.java").toUri().toString(); + + assertSymbol(pingUri, "@/pong -- GET", "@GetMapping(PongConstantRequestMapping.PONG)"); + assertSymbol(pongUri, "@/ping -- GET", "@GetMapping(PingConstantRequestMapping.PING)"); + + TestFileScanListener fileScanListener = new TestFileScanListener(); + indexer.getJavaIndexer().setFileScanListener(fileScanListener); + indexer.updateDocument(pingUri, null, "test triggered").get(); + fileScanListener.assertScannedUris(pingUri, pongUri); + + fileScanListener.reset(); + fileScanListener.assertScannedUris(/*none*/); + indexer.updateDocument(pongUri, null, "test triggered").get(); + fileScanListener.assertScannedUris(pingUri, pongUri); } @Test @@ -190,4 +235,21 @@ public class RequestMappingSymbolProviderTest { return false; } + + private void assertSymbol(String docUri, String name, String coveredText) throws Exception { + List symbols = indexer.getSymbols(docUri); + Optional maybeSymbol = symbols.stream().filter(s -> name.equals(s.getName())).findFirst(); + assertTrue(maybeSymbol.isPresent()); + + TextDocument doc = new TextDocument(docUri, LanguageId.JAVA); + doc.setText(FileUtils.readFileToString(UriUtil.toFile(docUri))); + + SymbolInformation symbol = maybeSymbol.get(); + Location loc = symbol.getLocation(); + assertEquals(docUri, loc.getUri()); + int start = doc.toOffset(loc.getRange().getStart()); + int end = doc.toOffset(loc.getRange().getEnd()); + String actualCoveredText = doc.textBetween(start, end); + assertEquals(coveredText, actualCoveredText); + } } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/TestFileScanListener.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/TestFileScanListener.java new file mode 100644 index 000000000..445c98c0d --- /dev/null +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/TestFileScanListener.java @@ -0,0 +1,58 @@ +package org.springframework.ide.vscode.boot.java.requestmapping.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.TreeSet; + +import org.springframework.ide.vscode.boot.java.utils.FileScanListener; +import org.springframework.ide.vscode.commons.util.UriUtil; + +public class TestFileScanListener implements FileScanListener { + public final List scannedFiles = new ArrayList(); + + @Override + public void fileScanned(String path) { + scannedFiles.add(path); + } + + public void assertScanned(String path) { + assertTrue(scannedFiles.contains(path)); + } + + public void assertScanned(String path, int scanCount) { + assertEquals(scanCount, scannedFiles.stream().filter(e -> e.equals(path)).count()); + } + + public void assertScannedUris(String... docUris) { + List docPaths = new ArrayList<>(); + for (String docUri : docUris) { + docPaths.add(UriUtil.toFileString(docUri)); + } + Collections.sort(docPaths); + StringBuilder expected = new StringBuilder(); + for (String string : docPaths) { + expected.append(string+"\n"); + } + TreeSet actualPaths = new TreeSet<>(); + for (String string : scannedFiles) { + actualPaths.add(string); + } + StringBuilder actual = new StringBuilder(); + for (String string : actualPaths) { + actual.append(string+"\n"); + } + assertEquals(expected.toString(), actual.toString()); + } + + public void assertScannedUri(String docUri, int scanCount) { + assertScanned(UriUtil.toFileString(docUri), scanCount); + } + + public void reset() { + scannedFiles.clear(); + } +} \ No newline at end of file diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/project/harness/ProjectsHarness.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/project/harness/ProjectsHarness.java index c18f0b777..e9a476175 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/project/harness/ProjectsHarness.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/project/harness/ProjectsHarness.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.springframework.ide.vscode.project.harness; +import static org.junit.Assert.assertTrue; + import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; @@ -73,7 +75,7 @@ public class ProjectsHarness { File target = new File(projectRoot, path); IOUtil.pipe(new ByteArrayInputStream(content.getBytes("UTF8")), target); } - + public void createType(String fqName, String sourceCode) throws Exception { String sourceFile = sourceFolder()+"/"+fqName.replace('.', '/')+".java"; createFile(sourceFile, sourceCode); @@ -98,7 +100,7 @@ public class ProjectsHarness { this.fileObserver = fileObserver; } - public IJavaProject project(ProjectType type, String name, ProjectCustomizer customizer, boolean build) throws Exception { + public IJavaProject project(ProjectType type, String name, boolean build, ProjectCustomizer customizer) throws Exception { Tuple3 key = Tuples.of(type, name, customizer); return cache.get(key, () -> { Path baseProjectPath = getProjectPath(name); @@ -122,7 +124,7 @@ public class ProjectsHarness { } } - public IJavaProject project(ProjectType type, String name, boolean build) throws Exception { + private IJavaProject project(ProjectType type, String name, boolean build) throws Exception { return cache.get(type + "/" + name, () -> { Path testProjectPath = getProjectPath(name); return createProject(type, testProjectPath, build); @@ -138,8 +140,12 @@ public class ProjectsHarness { return Paths.get(resource); } + public MavenJavaProject mavenProject(String name, boolean build, ProjectCustomizer customizer) throws Exception { + return (MavenJavaProject) project(ProjectType.MAVEN, name, build, customizer); + } + public MavenJavaProject mavenProject(String name, ProjectCustomizer customizer) throws Exception { - return (MavenJavaProject) project(ProjectType.MAVEN, name, customizer, true); + return (MavenJavaProject) project(ProjectType.MAVEN, name, true, customizer); } public MavenJavaProject mavenProject(String name) throws Exception { diff --git a/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-request-mapping-symbols/src/main/java/org/test/PingConstantRequestMapping.java b/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-request-mapping-symbols/src/main/java/org/test/PingConstantRequestMapping.java new file mode 100644 index 000000000..692f9836e --- /dev/null +++ b/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-request-mapping-symbols/src/main/java/org/test/PingConstantRequestMapping.java @@ -0,0 +1,15 @@ +package org.test; + +import org.springframework.web.bind.annotation.GetMapping; + +public class PingConstantRequestMapping { + + public final static String PING = "/ping"; + + @GetMapping(PongConstantRequestMapping.PONG) + public String hello() { + return "oy?"; + } + + +} diff --git a/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-request-mapping-symbols/src/main/java/org/test/PongConstantRequestMapping.java b/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-request-mapping-symbols/src/main/java/org/test/PongConstantRequestMapping.java new file mode 100644 index 000000000..92dce7621 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-request-mapping-symbols/src/main/java/org/test/PongConstantRequestMapping.java @@ -0,0 +1,14 @@ +package org.test; + +import org.springframework.web.bind.annotation.GetMapping; + +public class PongConstantRequestMapping { + + public static final String PONG="/pong"; + + @GetMapping(PingConstantRequestMapping.PING) + public String hello() { + return "oy?"; + } + +}