added test cases for spel syntax checking via reconcile engine and improved testability a bit
This commit is contained in:
@@ -122,6 +122,7 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
private BootJavaHoverProvider hoverProvider;
|
||||
private CodeLensHandler codeLensHandler;
|
||||
private DocumentHighlightHandler highlightsEngine;
|
||||
private BootJavaReconcileEngine reconcileEngine;
|
||||
|
||||
private SpringProcessTracker liveProcessTracker;
|
||||
|
||||
@@ -203,6 +204,8 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
highlightsEngine = createDocumentHighlightEngine(indexer);
|
||||
documents.onDocumentHighlight(highlightsEngine);
|
||||
|
||||
reconcileEngine = new BootJavaReconcileEngine(cuCache, projectFinder);
|
||||
|
||||
config.addListener(ignore -> {
|
||||
log.info("update live process tracker settings - start");
|
||||
|
||||
@@ -222,6 +225,8 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
liveChangeDetectionWatchdog.disableHighlights();
|
||||
}
|
||||
|
||||
reconcileEngine.setSpelExpressionSyntaxValidationEnabled(config.isSpelExpressionValidationEnabled());
|
||||
|
||||
log.info("update live process tracker settings - done");
|
||||
});
|
||||
|
||||
@@ -253,7 +258,7 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
|
||||
@Override
|
||||
public Optional<IReconcileEngine> getReconcileEngine() {
|
||||
return Optional.of(new BootJavaReconcileEngine(this, config));
|
||||
return Optional.of(reconcileEngine);
|
||||
}
|
||||
|
||||
private void initialized() {
|
||||
|
||||
@@ -23,8 +23,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.ide.vscode.boot.app.BootJavaConfig;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
import org.springframework.ide.vscode.boot.java.value.Constants;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
@@ -44,13 +43,19 @@ public class BootJavaReconcileEngine implements IReconcileEngine {
|
||||
private static final Logger log = LoggerFactory.getLogger(BootJavaReconcileEngine.class);
|
||||
|
||||
private final JavaProjectFinder projectFinder;
|
||||
private final BootJavaLanguageServerComponents server;
|
||||
private final BootJavaConfig config;
|
||||
private final CompilationUnitCache compilationUnitCache;
|
||||
|
||||
private boolean spelExpressionValidationEnabled;
|
||||
|
||||
public BootJavaReconcileEngine(BootJavaLanguageServerComponents server, BootJavaConfig config) {
|
||||
this.server = server;
|
||||
this.config = config;
|
||||
this.projectFinder = this.server.getProjectFinder();
|
||||
public BootJavaReconcileEngine(CompilationUnitCache compilationUnitCache, JavaProjectFinder projectFinder) {
|
||||
this.compilationUnitCache = compilationUnitCache;
|
||||
this.projectFinder = projectFinder;
|
||||
|
||||
this.spelExpressionValidationEnabled = true;
|
||||
}
|
||||
|
||||
public void setSpelExpressionSyntaxValidationEnabled(boolean spelExpressionValidationEnabled) {
|
||||
this.spelExpressionValidationEnabled = spelExpressionValidationEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,7 +70,7 @@ public class BootJavaReconcileEngine implements IReconcileEngine {
|
||||
try {
|
||||
problemCollector.beginCollecting();
|
||||
|
||||
server.getCompilationUnitCache().withCompilationUnit(project, uri, cu -> {
|
||||
compilationUnitCache.withCompilationUnit(project, uri, cu -> {
|
||||
if (cu != null) {
|
||||
reconcileAST(cu, problemCollector);
|
||||
}
|
||||
@@ -95,7 +100,7 @@ public class BootJavaReconcileEngine implements IReconcileEngine {
|
||||
}
|
||||
|
||||
protected void visitAnnotation(SingleMemberAnnotation node, IProblemCollector problemCollector) {
|
||||
if (!config.isSpelExpressionValidationEnabled()) {
|
||||
if (!spelExpressionValidationEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2020 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.value.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.lsp4j.DidCloseTextDocumentParams;
|
||||
import org.eclipse.lsp4j.DidOpenTextDocumentParams;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.TextDocumentItem;
|
||||
import org.gradle.internal.impldep.com.google.common.collect.ImmutableList;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.ide.vscode.boot.app.BootJavaConfig;
|
||||
import org.springframework.ide.vscode.boot.app.BootLanguageServerParams;
|
||||
import org.springframework.ide.vscode.boot.bootiful.AdHocPropertyHarnessTestConf;
|
||||
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
|
||||
import org.springframework.ide.vscode.boot.editor.harness.PropertyIndexHarness;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaReconcileEngine;
|
||||
import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory;
|
||||
import org.springframework.ide.vscode.boot.java.links.SourceLinks;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SymbolCache;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SymbolCacheVoid;
|
||||
import org.springframework.ide.vscode.boot.metadata.ValueProviderRegistry;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@BootLanguageServerTest
|
||||
@Import({AdHocPropertyHarnessTestConf.class, ValueSpelExpressionValidationTest.TestConf.class})
|
||||
public class ValueSpelExpressionValidationTest {
|
||||
|
||||
@Autowired private BootLanguageServerHarness harness;
|
||||
@Autowired private IJavaProject testProject;
|
||||
@Autowired private JavaProjectFinder projectFinder;
|
||||
@Autowired private CompilationUnitCache compilationUnitCache;
|
||||
@Autowired private SimpleLanguageServer server;
|
||||
|
||||
private File directory;
|
||||
private String docUri;
|
||||
private TestProblemCollector problemCollector;
|
||||
private BootJavaReconcileEngine reconcileEngine;
|
||||
|
||||
@Configuration
|
||||
static class TestConf {
|
||||
|
||||
//Somewhat strange test setup, test provides a specific test project.
|
||||
//The project finder finds this test project,
|
||||
//But it is not used in the indexProvider/harness.
|
||||
//this is a bit odd... but we preserved the strangeness how it was.
|
||||
|
||||
@Bean MavenJavaProject testProject() throws Exception {
|
||||
return ProjectsHarness.INSTANCE.mavenProject("test-annotations");
|
||||
}
|
||||
|
||||
@Bean PropertyIndexHarness indexHarness(ValueProviderRegistry valueProviders) {
|
||||
return new PropertyIndexHarness(valueProviders);
|
||||
}
|
||||
|
||||
@Bean JavaProjectFinder projectFinder(MavenJavaProject testProject) {
|
||||
return new JavaProjectFinder() {
|
||||
|
||||
@Override
|
||||
public Optional<IJavaProject> find(TextDocumentIdentifier doc) {
|
||||
return Optional.ofNullable(testProject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends IJavaProject> all() {
|
||||
// TODO Auto-generated method stub
|
||||
return testProject == null ? Collections.emptyList() : ImmutableList.of(testProject);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean BootLanguageServerHarness harness(SimpleLanguageServer server, BootLanguageServerParams serverParams, PropertyIndexHarness indexHarness, JavaProjectFinder projectFinder) throws Exception {
|
||||
return new BootLanguageServerHarness(server, serverParams, indexHarness, projectFinder, LanguageId.JAVA, ".java");
|
||||
}
|
||||
|
||||
@Bean BootLanguageServerParams serverParams(SimpleLanguageServer server, JavaProjectFinder projectFinder, ValueProviderRegistry valueProviders, PropertyIndexHarness indexHarness) {
|
||||
BootLanguageServerParams testDefaults = BootLanguageServerHarness.createTestDefault(server, valueProviders);
|
||||
return new BootLanguageServerParams(
|
||||
projectFinder,
|
||||
ProjectObserver.NULL,
|
||||
indexHarness.getIndexProvider(),
|
||||
testDefaults.typeUtilProvider
|
||||
);
|
||||
}
|
||||
|
||||
@Bean SymbolCache symbolCache() {
|
||||
return new SymbolCacheVoid();
|
||||
}
|
||||
|
||||
@Bean SourceLinks sourceLinks(SimpleTextDocumentService documents, CompilationUnitCache cuCache) {
|
||||
return SourceLinkFactory.NO_SOURCE_LINKS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
harness.intialize(null);
|
||||
|
||||
directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotations/").toURI());
|
||||
docUri = directory.toPath().resolve("src/main/java/org/test/TestValueCompletion.java").toUri().toString();
|
||||
|
||||
problemCollector = new TestProblemCollector();
|
||||
reconcileEngine = new BootJavaReconcileEngine(compilationUnitCache, projectFinder);
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeDoc() throws Exception {
|
||||
TextDocumentIdentifier identifier = new TextDocumentIdentifier(docUri);
|
||||
DidCloseTextDocumentParams closeParams = new DidCloseTextDocumentParams(identifier);
|
||||
server.getTextDocumentService().didClose(closeParams);
|
||||
server.getAsync().waitForAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSpelExpressionFound() throws Exception {
|
||||
TextDocument doc = prepareDocument("@Value(\"onField\")", "@Value(\"something\")");
|
||||
assertNotNull(doc);
|
||||
|
||||
reconcileEngine.reconcile(doc, problemCollector);
|
||||
|
||||
List<ReconcileProblem> problems = problemCollector.getCollectedProblems();
|
||||
assertEquals(0, problems.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectSpelExpressionFound() throws Exception {
|
||||
TextDocument doc = prepareDocument("@Value(\"onField\")", "@Value(\"#{new String('hello world').toUpperCase()}\")");
|
||||
assertNotNull(doc);
|
||||
|
||||
reconcileEngine.reconcile(doc, problemCollector);
|
||||
|
||||
List<ReconcileProblem> problems = problemCollector.getCollectedProblems();
|
||||
assertEquals(0, problems.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncorrectSpelExpressionFound() throws Exception {
|
||||
TextDocument doc = prepareDocument("@Value(\"onField\")", "@Value(\"#{new String('hello world).toUpperCase()}\")");
|
||||
assertNotNull(doc);
|
||||
|
||||
reconcileEngine.reconcile(doc, problemCollector);
|
||||
|
||||
List<ReconcileProblem> problems = problemCollector.getCollectedProblems();
|
||||
assertEquals(1, problems.size());
|
||||
}
|
||||
|
||||
private TextDocument prepareDocument(String selectedAnnotation, String annotationStatementBeforeTest) throws Exception {
|
||||
String content = IOUtils.toString(new URI(docUri));
|
||||
|
||||
TextDocumentItem docItem = new TextDocumentItem(docUri, LanguageId.JAVA.toString(), 0, content);
|
||||
DidOpenTextDocumentParams openParams = new DidOpenTextDocumentParams(docItem);
|
||||
server.getTextDocumentService().didOpen(openParams);
|
||||
server.getAsync().waitForAll();
|
||||
|
||||
TextDocument doc = server.getTextDocumentService().get(docUri);
|
||||
|
||||
int position = content.indexOf(selectedAnnotation);
|
||||
doc.replace(position, selectedAnnotation.length(), annotationStatementBeforeTest);
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
public static class TestProblemCollector implements IProblemCollector {
|
||||
|
||||
private List<ReconcileProblem> problems = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void beginCollecting() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endCollecting() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ReconcileProblem problem) {
|
||||
problems.add(problem);
|
||||
}
|
||||
|
||||
protected List<ReconcileProblem> getCollectedProblems() {
|
||||
return problems;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user