Next batch of JDT reconcilers

This commit is contained in:
aboyko
2023-08-09 17:46:13 -04:00
parent a140519874
commit 1b17d55486
17 changed files with 1759 additions and 9 deletions

View File

@@ -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());
}
}

View File

@@ -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();
}
}

View File

@@ -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());
}
}

View File

@@ -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());
}
}

View File

@@ -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());
}
}

View File

@@ -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());
}
}