diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/build.properties b/eclipse-distribution/org.springframework.boot.ide.branding/build.properties index 9efd2a1f3..2e60f9237 100644 --- a/eclipse-distribution/org.springframework.boot.ide.branding/build.properties +++ b/eclipse-distribution/org.springframework.boot.ide.branding/build.properties @@ -10,6 +10,7 @@ bin.includes = META-INF/,\ sts4-48.png,\ sts4-32.png,\ sts4-128.png,\ + sts4-256.png,\ sts4-64.png,\ about.html,\ sts4-16.png diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/plugin.xml b/eclipse-distribution/org.springframework.boot.ide.branding/plugin.xml index fc24f84b2..e1df17e6a 100644 --- a/eclipse-distribution/org.springframework.boot.ide.branding/plugin.xml +++ b/eclipse-distribution/org.springframework.boot.ide.branding/plugin.xml @@ -4,7 +4,7 @@ - + diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/sts4-128.png b/eclipse-distribution/org.springframework.boot.ide.branding/sts4-128.png index 4b9ad4fa8..fd632c5b1 100644 Binary files a/eclipse-distribution/org.springframework.boot.ide.branding/sts4-128.png and b/eclipse-distribution/org.springframework.boot.ide.branding/sts4-128.png differ diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/sts4-16.png b/eclipse-distribution/org.springframework.boot.ide.branding/sts4-16.png index d4430d9b7..55a33fb44 100644 Binary files a/eclipse-distribution/org.springframework.boot.ide.branding/sts4-16.png and b/eclipse-distribution/org.springframework.boot.ide.branding/sts4-16.png differ diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/sts4-32.png b/eclipse-distribution/org.springframework.boot.ide.branding/sts4-32.png index 4d20308ec..ff1bef1dc 100644 Binary files a/eclipse-distribution/org.springframework.boot.ide.branding/sts4-32.png and b/eclipse-distribution/org.springframework.boot.ide.branding/sts4-32.png differ diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/sts4-48.png b/eclipse-distribution/org.springframework.boot.ide.branding/sts4-48.png index 6ec583399..e253c4531 100644 Binary files a/eclipse-distribution/org.springframework.boot.ide.branding/sts4-48.png and b/eclipse-distribution/org.springframework.boot.ide.branding/sts4-48.png differ diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/sts4-64.png b/eclipse-distribution/org.springframework.boot.ide.branding/sts4-64.png index 7be4db7d1..f84354e4c 100644 Binary files a/eclipse-distribution/org.springframework.boot.ide.branding/sts4-64.png and b/eclipse-distribution/org.springframework.boot.ide.branding/sts4-64.png differ diff --git a/eclipse-distribution/org.springframework.boot.ide.product.e47/org.springframework.boot.ide.product b/eclipse-distribution/org.springframework.boot.ide.product.e47/org.springframework.boot.ide.product index a39eddb79..80fb4a8c8 100644 --- a/eclipse-distribution/org.springframework.boot.ide.product.e47/org.springframework.boot.ide.product +++ b/eclipse-distribution/org.springframework.boot.ide.product.e47/org.springframework.boot.ide.product @@ -13,7 +13,7 @@ openFile --add-modules=ALL-SYSTEM -Xms40m -Xverify:none - -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts -Xdock:icon=../Resources/sts.icns + -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts -Xdock:icon=../Resources/sts4.icns -Xmx1200m diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/conditionals/ConditionalsLiveHoverProvider.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/conditionals/ConditionalsLiveHoverProvider.java index 6edc357b9..fbffb34f2 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/conditionals/ConditionalsLiveHoverProvider.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/conditionals/ConditionalsLiveHoverProvider.java @@ -132,6 +132,13 @@ public class ConditionalsLiveHoverProvider implements HoverProvider { */ protected boolean matchesAnnotation(Annotation annotation, LiveConditional liveConditional) { + // First check that the annotation matches the live conditional annotation + String annotationName = annotation.resolveTypeBinding().getName(); + if (!liveConditional.getMessage().contains(annotationName)) { + return false; + } + + // Check that Java type in annotation in editor matches Java information in the live Conditional ASTNode parent = annotation.getParent(); String rawJsonKey = liveConditional.getPositiveMatchKey(); diff --git a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java index 354c5cc64..68cb348fb 100644 --- a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java +++ b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java @@ -10,11 +10,13 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.conditionals.test; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; import java.time.Duration; +import org.eclipse.lsp4j.Hover; import org.junit.Before; import org.junit.Test; import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; @@ -67,7 +69,7 @@ public class ConditionalsLiveHoverTest { // Build a mock running boot app mockAppProvider.builder().isSpringBootApp(true).port("1111").processId("22022").host("cfapps.io") .processName("test-conditionals-live-hover") - .getLiveConditionals( + .positiveMatchesJsonForLiveConditionals( "{\"positiveMatches\":{\"ConditionalOnBeanConfig#hi\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found bean 'missing'\"}]}}") .build(); @@ -91,7 +93,7 @@ public class ConditionalsLiveHoverTest { // Build a mock running boot app mockAppProvider.builder().isSpringBootApp(true).port("1111").processId("22022").host("cfapps.io") .processName("test-conditionals-live-hover") - .getLiveConditionals( + .positiveMatchesJsonForLiveConditionals( "{\"positiveMatches\":{\"ConditionalOnMissingBeanConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}]}}") .build(); @@ -114,7 +116,7 @@ public class ConditionalsLiveHoverTest { // Build a mock running boot app mockAppProvider.builder().isSpringBootApp(true).port("1111").processId("22022").host("cfapps.io") .processName("test-conditionals-live-hover") - .getLiveConditionals( + .positiveMatchesJsonForLiveConditionals( "{\"positiveMatches\":{\"HelloConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}],\"HelloConfig2#hi\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found bean 'missing'\"}],\"MultipleConditionals#hi\":[{\"condition\":\"OnClassCondition\",\"message\":\"@ConditionalOnClass found required class; @ConditionalOnMissingClass did not find unwanted class\"},{\"condition\":\"OnWebApplicationCondition\",\"message\":\"@ConditionalOnWebApplication (required) found StandardServletEnvironment\"},{\"condition\":\"OnJavaCondition\",\"message\":\"@ConditionalOnJava (1.8 or newer) found 1.8\"},{\"condition\":\"OnExpressionCondition\",\"message\":\"@ConditionalOnExpression (#{true}) resulted in true\"},{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found beans 'hi', 'missing'\"}]}}") .build(); @@ -144,10 +146,10 @@ public class ConditionalsLiveHoverTest { "Process 22022: test-conditionals-live-hover"); } - @Test - public void testMultipleAppsLiveHover() throws Exception { + public void testMultipleAppInstances() throws Exception { + // Test that live hover shows information for multiple app instances File directory = new File( ProjectsHarness.class.getResource("/test-projects/test-conditionals-live-hover/").toURI()); String docUri = "file://" + directory.getAbsolutePath() @@ -156,21 +158,21 @@ public class ConditionalsLiveHoverTest { // Build a mock running boot app mockAppProvider.builder().isSpringBootApp(true).port("1000").processId("70000").host("cfapps.io") .processName("test-conditionals-live-hover") - .getLiveConditionals( + .positiveMatchesJsonForLiveConditionals( "{\"positiveMatches\":{\"ConditionalOnMissingBeanConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}]}}") .build(); mockAppProvider.builder().isSpringBootApp(true).port("1001").processId("80000").host("cfapps.io") - .processName("test-conditionals-live-hover") - .getLiveConditionals( - "{\"positiveMatches\":{\"ConditionalOnMissingBeanConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}]}}") - .build(); + .processName("test-conditionals-live-hover") + .positiveMatchesJsonForLiveConditionals( + "{\"positiveMatches\":{\"ConditionalOnMissingBeanConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}]}}") + .build(); mockAppProvider.builder().isSpringBootApp(true).port("1002").processId("90000").host("cfapps.io") - .processName("test-conditionals-live-hover") - .getLiveConditionals( - "{\"positiveMatches\":{\"ConditionalOnMissingBeanConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}]}}") - .build(); + .processName("test-conditionals-live-hover") + .positiveMatchesJsonForLiveConditionals( + "{\"positiveMatches\":{\"ConditionalOnMissingBeanConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}]}}") + .build(); harness.intialize(directory); @@ -195,73 +197,120 @@ public class ConditionalsLiveHoverTest { } -// @Test -// public void testMultipleLiveHoverHints() throws Exception { -// -// File directory = new File( -// ProjectsHarness.class.getResource("/test-projects/test-conditionals-live-hover/").toURI()); -// String docUri = "file://" + directory.getAbsolutePath() + "/src/main/java/example/MultipleConditionals.java"; -// -// // Build a mock running boot app -// mockAppProvider.builder().isSpringBootApp(true).port("1111").processId("22022").host("cfapps.io") -// .processName("test-conditionals-live-hover") -// .getAutoConfigReport( -// "{\"positiveMatches\":{\"HelloConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}],\"HelloConfig2#hi\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found bean 'missing'\"}],\"MultipleConditionals#hi\":[{\"condition\":\"OnClassCondition\",\"message\":\"@ConditionalOnClass found required class; @ConditionalOnMissingClass did not find unwanted class\"},{\"condition\":\"OnWebApplicationCondition\",\"message\":\"@ConditionalOnWebApplication (required) found StandardServletEnvironment\"},{\"condition\":\"OnJavaCondition\",\"message\":\"@ConditionalOnJava (1.8 or newer) found 1.8\"},{\"condition\":\"OnExpressionCondition\",\"message\":\"@ConditionalOnExpression (#{true}) resulted in true\"},{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found beans 'hi', 'missing'\"}]}}") -// .build(); -// -// harness.intialize(directory); -// -// Editor editor = harness.newEditor(LanguageId.JAVA, "package example;\n" + -// "\n" + -// "import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;\n" + -// "import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;\n" + -// "import org.springframework.boot.autoconfigure.condition.ConditionalOnJava;\n" + -// "import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;\n" + -// "import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;\n" + -// "import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;\n" + -// "import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;\n" + -// "import org.springframework.context.annotation.Bean;\n" + -// "import org.springframework.context.annotation.Configuration;\n" + -// "\n" + -// "@Configuration\n" + -// "public class MultipleConditionals {\n" + -// "\n" + -// " @Bean\n" + -// " @ConditionalOnBean\n" + -// " @ConditionalOnWebApplication\n" + -// " @ConditionalOnJava(value=ConditionalOnJava.JavaVersion.EIGHT)\n" + -// " @ConditionalOnMissingClass\n" + -// " @ConditionalOnExpression\n" + -// " public Hello hi() {\n" + -// " return null;\n" + -// " }\n" + -// " \n" + -// " @Bean\n" + -// " @ConditionalOnMissingBean\n" + -// " @ConditionalOnNotWebApplication\n" + -// " public Hello missing() {\n" + -// " return null;\n" + -// " }\n" + -// "}"); -// -//// editor.assertHoverContains("@ConditionalOnBean", "Condition: OnBeanCondition\n" + "\n" -//// + "Message: @ConditionalOnBean (types: example.Hello; SearchStrategy: all) found beans 'hi', 'missing'"); -//// -//// editor.assertHoverContains("@ConditionalOnWebApplication", "Condition: OnWebApplicationCondition\n" + "\n" -//// + "Message: @ConditionalOnWebApplication (required) found StandardServletEnvironment"); -//// -//// editor.assertHoverContains("@ConditionalOnJava(value=ConditionalOnJava.JavaVersion.EIGHT)", -//// "Condition: OnJavaCondition\n" + "\n" + "Message: @ConditionalOnJava (1.8 or newer) found 1.8"); -//// -//// editor.assertHoverContains("@ConditionalOnMissingClass", "Condition: OnClassCondition\n" + "\n" -//// + "Message: @ConditionalOnClass found required class; @ConditionalOnMissingClass did not find unwanted class"); -//// -//// editor.assertHoverContains("@ConditionalOnExpression", "Condition: OnExpressionCondition\n" + "\n" -//// + "Message: @ConditionalOnExpression (#{true}) resulted in true"); -// -// editor.assertHighlights("@ConditionalOnBean", "@ConditionalOnWebApplication", -// "@ConditionalOnJava(value=ConditionalOnJava.JavaVersion.EIGHT)", "@ConditionalOnMissingClass", -// "@ConditionalOnExpression"); -// -// } + @Test + public void testMultipleConditionalsSameMethod() throws Exception { + + // Tests something like this: +// @Bean +// @ConditionalOnBean +// @ConditionalOnWebApplication +// @ConditionalOnJava(value=ConditionalOnJava.JavaVersion.EIGHT) +// @ConditionalOnMissingClass +// @ConditionalOnExpression +// public Hello hi() { +// return null; +// } + + File directory = new File( + ProjectsHarness.class.getResource("/test-projects/test-conditionals-live-hover/").toURI()); + String docUri = "file://" + directory.getAbsolutePath() + "/src/main/java/example/MultipleConditionals.java"; + + // Build a mock running boot app + mockAppProvider.builder().isSpringBootApp(true).port("1000").processId("70000").host("cfapps.io") + .processName("test-conditionals-live-hover") + .positiveMatchesJsonForLiveConditionals( + "{\"positiveMatches\":{\"HelloConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}],\"HelloConfig2#hi\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found bean 'missing'\"}],\"MultipleConditionals#hi\":[{\"condition\":\"OnClassCondition\",\"message\":\"@ConditionalOnClass found required class; @ConditionalOnMissingClass did not find unwanted class\"},{\"condition\":\"OnWebApplicationCondition\",\"message\":\"@ConditionalOnWebApplication (required) found StandardServletEnvironment\"},{\"condition\":\"OnJavaCondition\",\"message\":\"@ConditionalOnJava (1.8 or newer) found 1.8\"},{\"condition\":\"OnExpressionCondition\",\"message\":\"@ConditionalOnExpression (#{true}) resulted in true\"},{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found beans 'hi', 'missing'\"}]}}") + .build(); + + harness.intialize(directory); + + Editor editor = harness.newEditorFromFileUri(docUri, LanguageId.JAVA); + + // IMPORTANT: test EXACT text to ensure that multiple conditionals on the same method do not show + // up while + // hovering over only one of the conditional annotations + editor.assertHoverExactText("@ConditionalOnBean", + "@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found beans 'hi', 'missing'\n" + "\n" + + "Process 70000: test-conditionals-live-hover"); + + editor.assertHoverExactText("@ConditionalOnWebApplication", + "@ConditionalOnWebApplication (required) found StandardServletEnvironment\n" + "\n" + + "Process 70000: test-conditionals-live-hover"); + + editor.assertHoverExactText("@ConditionalOnJava(value=ConditionalOnJava.JavaVersion.EIGHT)", + "@ConditionalOnJava (1.8 or newer) found 1.8\n" + "\n" + "Process 70000: test-conditionals-live-hover"); + + editor.assertHoverExactText("@ConditionalOnMissingClass", + "@ConditionalOnClass found required class; @ConditionalOnMissingClass did not find unwanted class\n" + + "\n" + "Process 70000: test-conditionals-live-hover"); + + editor.assertHoverExactText("@ConditionalOnExpression", "@ConditionalOnExpression (#{true}) resulted in true\n" + + "\n" + "Process 70000: test-conditionals-live-hover"); + } + + @Test + public void PT152535713testMultipleLiveHoverHints() throws Exception { + + // Tests fix for PT152535713. Ensure that in a method with multiple + // conditionals, + // hovering over any one conditional annotation only shows content for that + // conditional + // and not any of the other ones + File directory = new File( + ProjectsHarness.class.getResource("/test-projects/test-conditionals-live-hover/").toURI()); + String docUri = "file://" + directory.getAbsolutePath() + + "/src/main/java/example/MultipleConditionalsPT152535713.java"; + + // Build a mock running boot app + mockAppProvider.builder().isSpringBootApp(true).port("1000").processId("70000").host("cfapps.io") + .processName("test-conditionals-live-hover") + .positiveMatchesJsonForLiveConditionals( + "{\"positiveMatches\":{\"MultipleConditionalsPT152535713#hi\":[{\"condition\":\"OnWebApplicationCondition\",\"message\":\"@ConditionalOnWebApplication (required) found StandardServletEnvironment\"},{\"condition\":\"OnJavaCondition\",\"message\":\"@ConditionalOnJava (1.8 or newer) found 1.8\"}]}}") + .build(); + + harness.intialize(directory); + + Editor editor = harness.newEditorFromFileUri(docUri, LanguageId.JAVA); + + editor.assertHoverExactText("@ConditionalOnWebApplication", + "@ConditionalOnWebApplication (required) found StandardServletEnvironment\n" + "\n" + + "Process 70000: test-conditionals-live-hover"); + + editor.assertHoverExactText("@ConditionalOnJava(value=ConditionalOnJava.JavaVersion.EIGHT)", + "@ConditionalOnJava (1.8 or newer) found 1.8\n" + "\n" + "Process 70000: test-conditionals-live-hover"); + + // Test that the hovers dont have extra information of the other conditionals: + Hover hover = editor.getHover("@ConditionalOnWebApplication"); + String hoverContent = editor.hoverString(hover); + assertFalse(hoverContent.contains("@ConditionalOnJava")); + + hover = editor.getHover("@ConditionalOnJava(value=ConditionalOnJava.JavaVersion.EIGHT)"); + hoverContent = editor.hoverString(hover); + assertFalse(hoverContent.contains("@ConditionalOnWebApplication")); + } + + @Test + public void testHighlights() throws Exception { + + File directory = new File( + ProjectsHarness.class.getResource("/test-projects/test-conditionals-live-hover/").toURI()); + String docUri = "file://" + directory.getAbsolutePath() + "/src/main/java/example/MultipleConditionals.java"; + + // Build a mock running boot app + mockAppProvider.builder().isSpringBootApp(true).port("1111").processId("22022").host("cfapps.io") + .processName("test-conditionals-live-hover") + .positiveMatchesJsonForLiveConditionals( + "{\"positiveMatches\":{\"HelloConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}],\"HelloConfig2#hi\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found bean 'missing'\"}],\"MultipleConditionals#hi\":[{\"condition\":\"OnClassCondition\",\"message\":\"@ConditionalOnClass found required class; @ConditionalOnMissingClass did not find unwanted class\"},{\"condition\":\"OnWebApplicationCondition\",\"message\":\"@ConditionalOnWebApplication (required) found StandardServletEnvironment\"},{\"condition\":\"OnJavaCondition\",\"message\":\"@ConditionalOnJava (1.8 or newer) found 1.8\"},{\"condition\":\"OnExpressionCondition\",\"message\":\"@ConditionalOnExpression (#{true}) resulted in true\"},{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found beans 'hi', 'missing'\"}]}}") + .build(); + + harness.intialize(directory); + + + Editor editor = harness.newEditorFromFileUri(docUri, LanguageId.JAVA); + + editor.assertHighlights("@ConditionalOnBean", "@ConditionalOnWebApplication", + "@ConditionalOnJava(value=ConditionalOnJava.JavaVersion.EIGHT)", "@ConditionalOnMissingClass", + "@ConditionalOnExpression"); + + } } diff --git a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingLiveHoverTest.java b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingLiveHoverTest.java index e3206c386..4ecb2544e 100644 --- a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingLiveHoverTest.java +++ b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingLiveHoverTest.java @@ -55,7 +55,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"/webjars/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**/favicon.ico\":{\"bean\":\"faviconHandlerMapping\"},\"{[/hello-world],methods=[GET]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public example.Greeting example.HelloWorldController.sayHello(java.lang.String)\"},\"{[/goodbye]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.goodbye()\"},\"{[/hello]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.hello()\"},\"{[/error]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)\"},\"{[/error],produces=[text/html]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)\"}}") .build(); @@ -85,7 +85,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"/webjars/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**/favicon.ico\":{\"bean\":\"faviconHandlerMapping\"},\"{[/hello-world],methods=[GET]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public example.Greeting example.HelloWorldController.sayHello(java.lang.String)\"},\"{[/goodbye]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.goodbye()\"},\"{[/hello]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.hello()\"},\"{[/error]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)\"},\"{[/error],produces=[text/html]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)\"}}") . build(); @@ -143,7 +143,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/greetings],methods=[DELETE]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public void com.example.RestApi.deleteGreetings()\"}}") . build(); @@ -189,7 +189,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/greetings],methods=[DELETE]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public void com.example.RestApi.deleteGreetings()\"}}") . build(); @@ -235,7 +235,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/greetings],methods=[PUT]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.updateGreetings()\"}}") . build(); @@ -279,7 +279,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/greetings || /hello],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.greetings()\"}}") . build(); @@ -326,7 +326,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/find],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public org.springframework.http.ResponseEntity com.example.RestApi.find(java.lang.String,java.util.Date,java.lang.String)\"}}") . build(); @@ -376,7 +376,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/find],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.Object com.example.RestApi.set(java.lang.String,java.util.Map)\"}}") . build(); @@ -426,7 +426,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/find],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.Object com.example.RestApi.set(java.lang.String,java.util.Map>)\"}}") . build(); @@ -477,7 +477,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/find],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.Object com.example.RestApi.set(java.lang.String,java.util.Map>)\"}}") . build(); @@ -528,7 +528,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/find],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.Object com.example.RestApi.set(java.lang.String[])\"}}") . build(); @@ -577,7 +577,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/find],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.Object com.example.RestApi.set(java.lang.String[][])\"}}") . build(); @@ -626,7 +626,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"{[/find],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.Object com.example.RestApi.set(java.lang.String...)\"}}") . build(); @@ -674,7 +674,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"/webjars/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**/favicon.ico\":{\"bean\":\"faviconHandlerMapping\"},\"{[/hello-world],methods=[GET]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public example.Greeting example.HelloWorldController.sayHello(java.lang.String)\"},\"{[/goodbye]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.goodbye()\"},\"{[/hello]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.hello()\"},\"{[/error]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)\"},\"{[/error],produces=[text/html]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)\"}}") . build(); @@ -686,7 +686,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"/webjars/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**/favicon.ico\":{\"bean\":\"faviconHandlerMapping\"},\"{[/hello-world],methods=[GET]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public example.Greeting example.HelloWorldController.sayHello(java.lang.String)\"},\"{[/goodbye]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.goodbye()\"},\"{[/hello]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.hello()\"},\"{[/error]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)\"},\"{[/error],produces=[text/html]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)\"}}") . build(); @@ -698,7 +698,7 @@ public class RequestMappingLiveHoverTest { .processName("test-request-mapping-live-hover") // Ugly, but this is real JSON copied from a real live running app. We want the // mock app to return realistic results if possible - .getRequestMappings( + .requestMappings( "{\"/webjars/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**/favicon.ico\":{\"bean\":\"faviconHandlerMapping\"},\"{[/hello-world],methods=[GET]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public example.Greeting example.HelloWorldController.sayHello(java.lang.String)\"},\"{[/goodbye]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.goodbye()\"},\"{[/hello]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.hello()\"},\"{[/error]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)\"},\"{[/error],produces=[text/html]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)\"}}") . build(); harness.intialize(directory); diff --git a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/project/harness/MockRunningAppProvider.java b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/project/harness/MockRunningAppProvider.java index 409fd34cb..f5c6aaade 100644 --- a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/project/harness/MockRunningAppProvider.java +++ b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/project/harness/MockRunningAppProvider.java @@ -105,19 +105,19 @@ public class MockRunningAppProvider { return this; } - public MockAppBuilder getRequestMappings(String mappings) throws Exception { + public MockAppBuilder requestMappings(String mappings) throws Exception { Collection requestMappings = SpringBootApp.parseRequestMappingsJson(mappings); when(app.getRequestMappings()).thenReturn(requestMappings); return this; } - public MockAppBuilder getAutoConfigReport(String autoConfigReport) throws Exception { + public MockAppBuilder autoConfigReport(String autoConfigReport) throws Exception { when(app.getAutoConfigReport()).thenReturn(autoConfigReport); return this; } - public MockAppBuilder getLiveConditionals(String autoConfigReport) throws Exception{ - when(app.getLiveConditionals()).thenReturn(SpringBootApp.getLiveConditionals(autoConfigReport, processId, processName)); + public MockAppBuilder positiveMatchesJsonForLiveConditionals(String rawJson) throws Exception{ + when(app.getLiveConditionals()).thenReturn(SpringBootApp.getLiveConditionals(rawJson, processId, processName)); return this; } diff --git a/headless-services/boot-java-language-server/src/test/resources/test-projects/test-conditionals-live-hover/src/main/java/example/MultipleConditionalsPT152535713.java b/headless-services/boot-java-language-server/src/test/resources/test-projects/test-conditionals-live-hover/src/main/java/example/MultipleConditionalsPT152535713.java new file mode 100644 index 000000000..1d49e9bd0 --- /dev/null +++ b/headless-services/boot-java-language-server/src/test/resources/test-projects/test-conditionals-live-hover/src/main/java/example/MultipleConditionalsPT152535713.java @@ -0,0 +1,17 @@ +package example; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnJava; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MultipleConditionalsPT152535713 { + + @Bean + @ConditionalOnWebApplication + @ConditionalOnJava(value=ConditionalOnJava.JavaVersion.EIGHT) + public Hello hi() { + return null; + } +} diff --git a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java index 42e281fc8..48ce44d82 100644 --- a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java +++ b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java @@ -550,7 +550,7 @@ public class Editor { assertContains(snippet, hoverString(hover)); } - protected String hoverString(Hover hover) { + public String hoverString(Hover hover) { StringBuilder buf = new StringBuilder(); boolean first = true; for (Either block : hover.getContents()) { @@ -644,6 +644,14 @@ public class Editor { assertEquals(expectedHover, hoverString(hover)); } + public Hover getHover(String afterString) throws Exception { + int pos = getRawText().indexOf(afterString); + if (pos>=0) { + pos += afterString.length(); + } + return harness.getHover(doc, doc.toPosition(pos)); + } + public CompletionItem assertCompletionDetails(String expectLabel, String expectDetail, String expectDocSnippet) throws Exception { CompletionItem it = harness.resolveCompletionItem(assertCompletionWithLabel(expectLabel)); if (expectDetail!=null) {