Next batch of JDT reconcilers
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, 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:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.reconcilers.test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.AuthorizeHttpRequestsReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.JdtAstReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.RequiredCompleteAstException;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRegistry;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
|
||||
public class AuthorizeHttpRequestsReconcilerTest extends BaseReconcilerTest {
|
||||
|
||||
@Override
|
||||
protected String getFolder() {
|
||||
return "authorizerequests";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProjectName() {
|
||||
return "test-spring-indexing";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JdtAstReconciler getReconciler() {
|
||||
return new AuthorizeHttpRequestsReconciler(new QuickfixRegistry());
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
super.setup();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
void requireFullAst_1() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
|
||||
class A {
|
||||
|
||||
void something(HttpSecurity security) {
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
try {
|
||||
reconcile("A.java", source, false);
|
||||
fail("Should require full AST with method bodies");
|
||||
} catch (RequiredCompleteAstException e) {
|
||||
// pass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void requireFullAst_2() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
|
||||
|
||||
class A {
|
||||
|
||||
void something() {
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
try {
|
||||
reconcile("A.java", source, false);
|
||||
fail("Should require full AST with method bodies");
|
||||
} catch (RequiredCompleteAstException e) {
|
||||
// pass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void requireFullAst_3() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||
|
||||
class A {
|
||||
|
||||
void something(ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry reg) {
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
try {
|
||||
reconcile("A.java", source, false);
|
||||
fail("Should require full AST with method bodies");
|
||||
} catch (RequiredCompleteAstException e) {
|
||||
// pass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanityTest() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
|
||||
class A {
|
||||
|
||||
void something(HttpSecurity security) {
|
||||
security.authorizeRequests().mvcMatchers();
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, true);
|
||||
|
||||
assertEquals(1, problems.size());
|
||||
|
||||
ReconcileProblem problem = problems.get(0);
|
||||
|
||||
assertEquals(Boot2JavaProblemType.HTTP_SECURITY_AUTHORIZE_HTTP_REQUESTS, problem.getType());
|
||||
|
||||
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
|
||||
assertEquals("authorizeRequests", markedStr);
|
||||
|
||||
assertEquals(2, problem.getQuickfixes().size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleProblems() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
@Configuration
|
||||
public class JdbcSecurityConfiguration {
|
||||
@Bean
|
||||
SecurityFilterChain web(HttpSecurity http) throws Exception {
|
||||
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry reqs = http.authorizeRequests();
|
||||
reqs.antMatchers("/ll").authenticated();
|
||||
return http.build();
|
||||
}
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, true);
|
||||
|
||||
assertEquals(2, problems.size());
|
||||
|
||||
ReconcileProblem problem = problems.get(0);
|
||||
|
||||
assertEquals(Boot2JavaProblemType.HTTP_SECURITY_AUTHORIZE_HTTP_REQUESTS, problem.getType());
|
||||
|
||||
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
|
||||
assertEquals("ExpressionUrlAuthorizationConfigurer", markedStr);
|
||||
|
||||
assertEquals(2, problem.getQuickfixes().size());
|
||||
|
||||
problem = problems.get(1);
|
||||
|
||||
assertEquals(Boot2JavaProblemType.HTTP_SECURITY_AUTHORIZE_HTTP_REQUESTS, problem.getType());
|
||||
|
||||
markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
|
||||
assertEquals("authorizeRequests", markedStr);
|
||||
|
||||
assertEquals(2, problem.getQuickfixes().size());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import java.nio.file.Paths;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.FileASTRequestor;
|
||||
@@ -42,7 +43,7 @@ public abstract class BaseReconcilerTest {
|
||||
|
||||
abstract protected JdtAstReconciler getReconciler();
|
||||
|
||||
private Path createFile(String name, String content) throws IOException {
|
||||
protected Path createFile(String name, String content) throws IOException {
|
||||
Path filePath = Paths.get(project.getLocationUri()).resolve("src/main/java").resolve(getFolder()).resolve(name);
|
||||
Files.createDirectories(filePath.getParent());
|
||||
Files.createFile(filePath);
|
||||
@@ -75,6 +76,10 @@ public abstract class BaseReconcilerTest {
|
||||
}
|
||||
|
||||
List<ReconcileProblem> reconcile(String fileName, String source, boolean isCompleteAst) throws Exception {
|
||||
return reconcile(this::getReconciler, fileName, source, isCompleteAst);
|
||||
}
|
||||
|
||||
List<ReconcileProblem> reconcile(Supplier<JdtAstReconciler> reconcilerFactory, String fileName, String source, boolean isCompleteAst) throws Exception {
|
||||
Path path = createFile(fileName, source);
|
||||
TestProblemCollector problemCollector = new TestProblemCollector();
|
||||
AtomicBoolean requiredCompleteAst = new AtomicBoolean(false);
|
||||
@@ -83,7 +88,7 @@ public abstract class BaseReconcilerTest {
|
||||
@Override
|
||||
public void acceptAST(String sourceFilePath, CompilationUnit cu) {
|
||||
try {
|
||||
getReconciler().reconcile(project, path.toUri(), cu, problemCollector, isCompleteAst);
|
||||
reconcilerFactory.get().reconcile(project, path.toUri(), cu, problemCollector, isCompleteAst);
|
||||
} catch (RequiredCompleteAstException e) {
|
||||
requiredCompleteAst.set(true);
|
||||
}
|
||||
@@ -97,5 +102,4 @@ public abstract class BaseReconcilerTest {
|
||||
return problemCollector.getCollectedProblems();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, 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:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.reconcilers.test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.ide.vscode.boot.java.SpringAotJavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.BeanPostProcessingIgnoreInAotReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.JdtAstReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.RequiredCompleteAstException;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRegistry;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
|
||||
public class BeanPostProcessingIgnoreInAotReconcilerTest extends BaseReconcilerTest {
|
||||
|
||||
@Override
|
||||
protected String getFolder() {
|
||||
return "beanpostprocessingaot";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProjectName() {
|
||||
return "test-spring-validations";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JdtAstReconciler getReconciler() {
|
||||
return new BeanPostProcessingIgnoreInAotReconciler(new QuickfixRegistry());
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
super.setup();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
void noMethod() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
|
||||
|
||||
class A implements BeanPostProcessor, BeanRegistrationAotProcessor{
|
||||
|
||||
A() {};
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, false);
|
||||
|
||||
assertEquals(1, problems.size());
|
||||
|
||||
ReconcileProblem problem = problems.get(0);
|
||||
|
||||
assertEquals(SpringAotJavaProblemType.JAVA_BEAN_POST_PROCESSOR_IGNORED_IN_AOT, problem.getType());
|
||||
|
||||
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
|
||||
assertEquals("A", markedStr);
|
||||
|
||||
assertEquals(1, problem.getQuickfixes().size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void withMethodReturningTrue_IncompleteAst() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
|
||||
|
||||
class A implements BeanPostProcessor, BeanRegistrationAotProcessor{
|
||||
|
||||
A() {};
|
||||
|
||||
public boolean isBeanExcludedFromAotProcessing() { return true; }
|
||||
|
||||
}
|
||||
""";
|
||||
try {
|
||||
reconcile("A.java", source, false);
|
||||
fail("Should require complete AST");
|
||||
} catch (RequiredCompleteAstException e) {
|
||||
// good
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void withMethodReturningTrue_CompleteAst() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
|
||||
|
||||
class A implements BeanPostProcessor, BeanRegistrationAotProcessor{
|
||||
|
||||
A() {};
|
||||
|
||||
public boolean isBeanExcludedFromAotProcessing() { return true; }
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, true);
|
||||
|
||||
assertEquals(1, problems.size());
|
||||
|
||||
ReconcileProblem problem = problems.get(0);
|
||||
|
||||
assertEquals(SpringAotJavaProblemType.JAVA_BEAN_POST_PROCESSOR_IGNORED_IN_AOT, problem.getType());
|
||||
|
||||
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
|
||||
assertEquals("A", markedStr);
|
||||
|
||||
assertEquals(1, problem.getQuickfixes().size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void withMethodReturningFalse() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
|
||||
|
||||
class A implements BeanPostProcessor, BeanRegistrationAotProcessor{
|
||||
|
||||
A() {};
|
||||
|
||||
public boolean isBeanExcludedFromAotProcessing() { return false; }
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, true);
|
||||
|
||||
assertEquals(0, problems.size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void noBeanPostProcessor() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
|
||||
|
||||
class A implements BeanRegistrationAotProcessor{
|
||||
|
||||
A() {};
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, true);
|
||||
|
||||
assertEquals(0, problems.size());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, 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:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.reconcilers.test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.HttpSecurityLambdaDslReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.JdtAstReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.RequiredCompleteAstException;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRegistry;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
|
||||
public class HttpSecurityLambdaDslReconcilerTest extends BaseReconcilerTest {
|
||||
|
||||
@Override
|
||||
protected String getFolder() {
|
||||
return "httpsecuritydsl";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProjectName() {
|
||||
return "test-spring-indexing";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JdtAstReconciler getReconciler() {
|
||||
return new HttpSecurityLambdaDslReconciler(new QuickfixRegistry());
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
super.setup();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
void requireFullAst_1() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
|
||||
class A {
|
||||
|
||||
void something(HttpSecurity security) {
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
try {
|
||||
reconcile("A.java", source, false);
|
||||
fail("Should require full AST with method bodies");
|
||||
} catch (RequiredCompleteAstException e) {
|
||||
// pass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void requireFullAst_2() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.annotation.web.builders.*;
|
||||
|
||||
class A {
|
||||
|
||||
void something(HttpSecurity security) {
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
try {
|
||||
reconcile("A.java", source, false);
|
||||
fail("Should require full AST with method bodies");
|
||||
} catch (RequiredCompleteAstException e) {
|
||||
// pass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void requireFullAst_3() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
class A {
|
||||
|
||||
void something(org.springframework.security.config.annotation.web.builders.HttpSecurity security) {
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
try {
|
||||
reconcile("A.java", source, false);
|
||||
fail("Should require full AST with method bodies");
|
||||
} catch (RequiredCompleteAstException e) {
|
||||
// pass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanityTest() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
|
||||
class A {
|
||||
|
||||
void something(HttpSecurity security) {
|
||||
security.authorizeRequests().mvcMatchers();
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, true);
|
||||
|
||||
assertEquals(1, problems.size());
|
||||
|
||||
ReconcileProblem problem = problems.get(0);
|
||||
|
||||
assertEquals(Boot2JavaProblemType.JAVA_LAMBDA_DSL, problem.getType());
|
||||
|
||||
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
|
||||
assertEquals("security.authorizeRequests().mvcMatchers()", markedStr);
|
||||
|
||||
assertEquals(3, problem.getQuickfixes().size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void noProblem() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
|
||||
class A {
|
||||
|
||||
void something(HttpSecurity http) {
|
||||
http
|
||||
.authorizeRequests(requests -> requests
|
||||
.antMatchers("/blog/**").permitAll()
|
||||
.anyRequest().authenticated())
|
||||
.formLogin(login -> login
|
||||
.loginPage("/login")
|
||||
.permitAll())
|
||||
.rememberMe(withDefaults());
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, true);
|
||||
|
||||
assertEquals(0, problems.size());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, 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:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.reconcilers.test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbol;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
|
||||
import org.springframework.ide.vscode.boot.java.SpringAotJavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.beans.ConfigBeanSymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.JdtAstReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.NotRegisteredBeansReconciler;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRegistry;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
|
||||
|
||||
public class NotRegisteredBeansReconcilerTest extends BaseReconcilerTest {
|
||||
|
||||
@Override
|
||||
protected String getFolder() {
|
||||
return "notregisteredbeanaot";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProjectName() {
|
||||
return "test-spring-validations";
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected JdtAstReconciler getReconciler() {
|
||||
NotRegisteredBeansReconciler reconciler = new NotRegisteredBeansReconciler(new QuickfixRegistry());
|
||||
SpringSymbolIndex mockSymbolIndex = mock(SpringSymbolIndex.class);
|
||||
when(mockSymbolIndex.getSymbols(any(Predicate.class))).thenReturn(Stream.empty());
|
||||
|
||||
ApplicationContext context = mock(ApplicationContext.class);
|
||||
when(context.getBean(SpringSymbolIndex.class)).thenReturn(mockSymbolIndex);
|
||||
|
||||
reconciler.setApplicationContext(context);
|
||||
return reconciler;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private NotRegisteredBeansReconciler createReconciler(EnhancedSymbolInformation... beanSymbols) {
|
||||
NotRegisteredBeansReconciler reconciler = new NotRegisteredBeansReconciler(new QuickfixRegistry());
|
||||
SpringSymbolIndex mockSymbolIndex = mock(SpringSymbolIndex.class);
|
||||
when(mockSymbolIndex.getSymbols(any(Predicate.class))).thenReturn(Stream.empty());
|
||||
when(mockSymbolIndex.getEnhancedSymbols(any(IJavaProject.class))).thenReturn(Arrays.asList(beanSymbols));
|
||||
|
||||
ApplicationContext context = mock(ApplicationContext.class);
|
||||
when(context.getBean(SpringSymbolIndex.class)).thenReturn(mockSymbolIndex);
|
||||
|
||||
reconciler.setApplicationContext(context);
|
||||
return reconciler;
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
super.setup();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanityTest() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
|
||||
|
||||
class A implements BeanRegistrationAotProcessor {
|
||||
|
||||
public A(String k) {}
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile(() -> createReconciler(), "A.java", source, true);
|
||||
|
||||
assertEquals(1, problems.size());
|
||||
|
||||
ReconcileProblem problem = problems.get(0);
|
||||
|
||||
assertEquals(SpringAotJavaProblemType.JAVA_BEAN_NOT_REGISTERED_IN_AOT, problem.getType());
|
||||
|
||||
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
|
||||
assertEquals("A", markedStr);
|
||||
|
||||
assertEquals(0, problem.getQuickfixes().size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanityTestWithQuickFixes() throws Exception {
|
||||
Path configClassPath = createFile("TestConfig.java", """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
class TestConfig {
|
||||
}
|
||||
""");
|
||||
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
|
||||
|
||||
class A implements BeanRegistrationAotProcessor {
|
||||
|
||||
public A(String k) {}
|
||||
}
|
||||
""";
|
||||
|
||||
WorkspaceSymbol workspaceSymbol = new WorkspaceSymbol("testConfig", SymbolKind.Class, Either.forLeft(new Location(configClassPath.toUri().toASCIIString(), new Range())));
|
||||
ConfigBeanSymbolAddOnInformation configBeanAddOn = new ConfigBeanSymbolAddOnInformation("testConfig", "example.demo.TestConfig");
|
||||
|
||||
List<ReconcileProblem> problems = reconcile(() -> createReconciler(new EnhancedSymbolInformation(workspaceSymbol, new SymbolAddOnInformation[] { configBeanAddOn })), "A.java", source, true);
|
||||
|
||||
assertEquals(1, problems.size());
|
||||
|
||||
ReconcileProblem problem = problems.get(0);
|
||||
|
||||
assertEquals(SpringAotJavaProblemType.JAVA_BEAN_NOT_REGISTERED_IN_AOT, problem.getType());
|
||||
|
||||
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
|
||||
assertEquals("A", markedStr);
|
||||
|
||||
assertEquals(1, problem.getQuickfixes().size());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, 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:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.reconcilers.test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.JdtAstReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.RequiredCompleteAstException;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.ServerHttpSecurityLambdaDslReconciler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRegistry;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
|
||||
public class ServerHttpSecurityLambdaDslReconcilerTest extends BaseReconcilerTest {
|
||||
|
||||
@Override
|
||||
protected String getFolder() {
|
||||
return "serverhttpsecuritydsl";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProjectName() {
|
||||
return "test-spring-indexing";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JdtAstReconciler getReconciler() {
|
||||
return new ServerHttpSecurityLambdaDslReconciler(new QuickfixRegistry());
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
super.setup();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
void requireFullAst() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||
|
||||
class A {
|
||||
|
||||
void something(ServerHttpSecurity security) {
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
try {
|
||||
reconcile("A.java", source, false);
|
||||
fail("Should require full AST with method bodies");
|
||||
} catch (RequiredCompleteAstException e) {
|
||||
// pass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanityTest() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||
|
||||
class A {
|
||||
|
||||
void something(ServerHttpSecurity http) {
|
||||
http.authorizeExchange().pathMatchers("/blog/**").permitAll().anyExchange().authenticated();
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, true);
|
||||
|
||||
assertEquals(1, problems.size());
|
||||
|
||||
ReconcileProblem problem = problems.get(0);
|
||||
|
||||
assertEquals(Boot2JavaProblemType.JAVA_LAMBDA_DSL, problem.getType());
|
||||
|
||||
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
|
||||
assertEquals("http.authorizeExchange().pathMatchers(\"/blog/**\").permitAll().anyExchange().authenticated()", markedStr);
|
||||
|
||||
assertEquals(3, problem.getQuickfixes().size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void noProblem() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||
|
||||
class A {
|
||||
|
||||
void something(ServerHttpSecurity http) {
|
||||
http.authorizeExchange(exchange -> exchange.pathMatchers("/blog/**").permitAll().anyExchange().authenticated());
|
||||
};
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, true);
|
||||
|
||||
assertEquals(0, problems.size());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user