Porting all the tests from YamlEditorTests in old STS
Moved into ApplicationPropertiesTests suite. All tests running but most are not yet passing. Tests that are expected to fail w.r.t. already implemented functionlaity are marked with @Ignore annotations.
This commit is contained in:
@@ -33,20 +33,22 @@
|
||||
</dependency>
|
||||
|
||||
<!-- Reactor -->
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-core</artifactId>
|
||||
<version>3.0.2.RELEASE</version>
|
||||
<version>${reactor-version}</version>
|
||||
</dependency>
|
||||
-->
|
||||
<!-- Common Utilities -->
|
||||
<!-- Common Utilities -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-util</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-language-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,129 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.properties.metadata;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.ide.vscode.boot.properties.metadata.ValueProviderRegistry.ValueProviderStrategy;
|
||||
|
||||
/**
|
||||
* A abstract {@link ValueProviderStrategy} that is mean to help speedup successive invocations of
|
||||
* content assist with a similar 'query' string.
|
||||
* <p>
|
||||
* This implementation is meant to be used for providers that use potentially lenghty/expensive searches
|
||||
* to determine hints. Since content assist hints are requested by Eclipse CA framework directly on
|
||||
* the UI thread, they can not simply perform a lengthy search and block UI thread until it finished.
|
||||
* <p>
|
||||
* This implementation therefore does the following:
|
||||
* <ul>
|
||||
* <li>Limit the duration of time spent on the UI thread.
|
||||
* <li>Cache results of searches for a limited time.
|
||||
* <li>Speedup queries for successive queries by using the already cached result of a similar (prefix) query.
|
||||
* <li>When the time spent on UI thread waiting for a current search exceeds the allowed time limit,
|
||||
* return immediately with whatever results have been found so far.
|
||||
* </ul>
|
||||
*
|
||||
* TODO: rather than an abstract class this should really be 'Wrapper' class that delegates to another
|
||||
* {@link ValueProviderStrategy} and adds a cache in front of it.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public abstract class CachingValueProvider implements ValueProviderStrategy {
|
||||
|
||||
private static final Duration DEFAULT_TIMEOUT = Duration.ofMillis(1000);
|
||||
|
||||
/**
|
||||
* Content assist is called inside UI thread and so doing something lenghty things
|
||||
* like a JavaSearch will block the UI thread completely freezing the UI. So, we
|
||||
* only return as many results as can be obtained within this hard TIMEOUT limit.
|
||||
*/
|
||||
public static Duration TIMEOUT = DEFAULT_TIMEOUT;
|
||||
|
||||
/**
|
||||
* The maximum number of results returned for a single request. Used to limit the
|
||||
* values that are cached per entry.
|
||||
*/
|
||||
private int MAX_RESULTS = 500;
|
||||
|
||||
// private Cache<Tuple2<String,String>, CacheEntry> cache = createCache();
|
||||
//
|
||||
// private class CacheEntry {
|
||||
// boolean isComplete = false;
|
||||
// int count = 0;
|
||||
// Flux<StsValueHint> values;
|
||||
//
|
||||
// public CacheEntry(String query, Flux<StsValueHint> producer) {
|
||||
// values = producer
|
||||
// .take(MAX_RESULTS)
|
||||
// .cache(MAX_RESULTS);
|
||||
// values.subscribe(); // create infinite demand so that we actually force cache entries to be fetched upto the max.
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String toString() {
|
||||
// return "CacheEntry [isComplete=" + isComplete + ", count=" + count + "]";
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public final Flux<StsValueHint> getValues(IJavaProject javaProject, String query) {
|
||||
//// debug("CA query: "+query);
|
||||
// Tuple2<String, String> key = key(javaProject, query);
|
||||
// CacheEntry cached = cache.get(key);
|
||||
// if (cached==null) {
|
||||
// cache.put(key, cached = new CacheEntry(query, getValuesIncremental(javaProject, query)));
|
||||
// }
|
||||
// return cached.values;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Tries to use an already cached, complete result for a query that is a prefix of the current query to speed things up.
|
||||
// * <p>
|
||||
// * Falls back on doing a full-blown search if there's no usable 'prefix-query' in the cache.
|
||||
// */
|
||||
// private Flux<StsValueHint> getValuesIncremental(IJavaProject javaProject, String query) {
|
||||
//// debug("trying to solve "+query+" incrementally");
|
||||
// String subquery = query;
|
||||
// while (subquery.length()>=1) {
|
||||
// subquery = subquery.substring(0, subquery.length()-1);
|
||||
// CacheEntry cached = cache.get(key(javaProject, subquery));
|
||||
// if (cached!=null) {
|
||||
// System.out.println("cached "+subquery+": "+cached);
|
||||
// if (cached.isComplete) {
|
||||
//// debug("filtering "+subquery+" -> "+query);
|
||||
// return cached.values
|
||||
//// .doOnNext((hint) -> debug("filter["+query+"]: "+hint.getValue()))
|
||||
// .filter((hint) -> 0!=FuzzyMatcher.matchScore(query, hint.getValue().toString()));
|
||||
// } else {
|
||||
//// debug("subquery "+subquery+" cached but is incomplete");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//// debug("full search for: "+query);
|
||||
// return getValuesAsycn(javaProject, query);
|
||||
// }
|
||||
//
|
||||
// protected abstract Flux<StsValueHint> getValuesAsycn(IJavaProject javaProject, String query);
|
||||
//
|
||||
// private Tuple2<String,String> key(IJavaProject javaProject, String query) {
|
||||
// return Tuples.of(javaProject==null?null:javaProject.getElementName(), query);
|
||||
// }
|
||||
//
|
||||
// protected <K,V> Cache<K,V> createCache() {
|
||||
// return new LimitedTimeCache<>(Duration.ofMinutes(1));
|
||||
// }
|
||||
|
||||
public static void restoreDefaults() {
|
||||
TIMEOUT = DEFAULT_TIMEOUT;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.properties.metadata;
|
||||
|
||||
import org.springframework.ide.vscode.util.IDocument;
|
||||
import org.springframework.ide.vscode.boot.properties.util.FuzzyMap;
|
||||
|
||||
|
||||
public abstract class SpringPropertyIndexProvider {
|
||||
|
||||
public abstract FuzzyMap<PropertyInfo> getIndex(IDocument doc);
|
||||
|
||||
}
|
||||
@@ -218,7 +218,7 @@ public class Editor {
|
||||
assertEquals(expect.toString(), actual.toString());
|
||||
}
|
||||
|
||||
private void apply(CompletionItem completion) throws Exception {
|
||||
public void apply(CompletionItem completion) throws Exception {
|
||||
TextEdit edit = completion.getTextEdit();
|
||||
String docText = document.getText();
|
||||
if (edit!=null) {
|
||||
@@ -269,7 +269,7 @@ public class Editor {
|
||||
}
|
||||
}
|
||||
|
||||
private List<? extends CompletionItem> getCompletions() throws Exception {
|
||||
public List<CompletionItem> getCompletions() throws Exception {
|
||||
CompletionList cl = harness.getCompletions(this.document, this.getCursor());
|
||||
ArrayList<CompletionItem> items = new ArrayList<>(cl.getItems());
|
||||
Collections.sort(items, new Comparator<CompletionItem>() {
|
||||
@@ -290,6 +290,10 @@ public class Editor {
|
||||
return items;
|
||||
}
|
||||
|
||||
public CompletionItem getFirstCompletion() throws Exception {
|
||||
return getCompletions().get(0);
|
||||
}
|
||||
|
||||
private Position getCursor() {
|
||||
return document.toPosition(selectionStart);
|
||||
}
|
||||
@@ -302,6 +306,10 @@ public class Editor {
|
||||
throw new UnsupportedOperationException("Not implemented yet!");
|
||||
}
|
||||
|
||||
public void assertNoHover(String string) {
|
||||
throw new UnsupportedOperationException("Not implemented yet!");
|
||||
}
|
||||
|
||||
public void setSelection(int start, int end) {
|
||||
Assert.assertTrue(start>=0);
|
||||
Assert.assertTrue(end>=start);
|
||||
@@ -315,4 +323,44 @@ public class Editor {
|
||||
return "Editor(\n"+getText()+"\n)";
|
||||
}
|
||||
|
||||
public void assertLinkTargets(String hoverOver, String... expecteds) {
|
||||
throw new UnsupportedOperationException("Not implemented yet!");
|
||||
// Editor editor = this;
|
||||
// int pos = editor.middleOf(hoverOver);
|
||||
// assertTrue("Not found in editor: '"+hoverOver+"'", pos>=0);
|
||||
//
|
||||
// List<IJavaElement> targets = getLinkTargets(editor, pos);
|
||||
// assertEquals(expecteds.length, targets.size());
|
||||
// for (int i = 0; i < expecteds.length; i++) {
|
||||
// assertEquals(expecteds[i], JavaElementLabels.getElementLabel(targets.get(i), JavaElementLabels.DEFAULT_QUALIFIED | JavaElementLabels.M_PARAMETER_TYPES));
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a problem that covers the given text in the editor. Throws exception
|
||||
* if no matching problem is found.
|
||||
*/
|
||||
public Diagnostic assertProblem(String coveredText) throws Exception {
|
||||
Editor editor = this;
|
||||
List<Diagnostic> problems = editor.reconcile();
|
||||
for (Diagnostic p : problems) {
|
||||
String c = editor.getText(p.getRange());
|
||||
if (c.equals(coveredText)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
fail("No problem found covering the text '"+coveredText+"' in: \n"
|
||||
+ problemSumary(editor, problems)
|
||||
);
|
||||
return null; //unreachable but compiler doesn't know
|
||||
}
|
||||
|
||||
public CompletionItem assertFirstQuickfix(Diagnostic problem, String expectLabel) {
|
||||
throw new UnsupportedOperationException("Not implemented yet!");
|
||||
}
|
||||
|
||||
public void assertText(String expected) {
|
||||
assertEquals(expected, getText());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.springframework.ide.vscode.testharness;
|
||||
|
||||
/**
|
||||
* Replaces eclipse JDT IType. Maybe we keep this maybe not, if keep, it should move to some
|
||||
* other place, not stay here in the testharness.
|
||||
*/
|
||||
public interface IType {
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.springframework.ide.vscode.testharness;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
@@ -252,4 +254,30 @@ public class LanguageServerHarness {
|
||||
return File.createTempFile("workingcopy", getFileExtension()).toURI().toString();
|
||||
}
|
||||
|
||||
public void assertCompletion(String textBefore, String expectTextAfter) throws Exception {
|
||||
Editor editor = newEditor(textBefore);
|
||||
CompletionItem completion = editor.getFirstCompletion();
|
||||
editor.apply(completion);
|
||||
assertEquals(expectTextAfter, editor.getText());
|
||||
}
|
||||
|
||||
public void assertCompletions(String textBefore, String... expectTextAfter) throws Exception {
|
||||
Editor editor = newEditor(textBefore);
|
||||
StringBuilder expect = new StringBuilder();
|
||||
StringBuilder actual = new StringBuilder();
|
||||
for (String after : expectTextAfter) {
|
||||
expect.append(after);
|
||||
expect.append("\n-------------------\n");
|
||||
}
|
||||
|
||||
List<? extends CompletionItem> completions = editor.getCompletions();
|
||||
for (CompletionItem ci : completions) {
|
||||
editor = newEditor(textBefore);
|
||||
editor.apply(ci);
|
||||
actual.append(editor.getText());
|
||||
actual.append("\n-------------------\n");
|
||||
}
|
||||
assertEquals(expect.toString(), actual.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.springframework.ide.vscode.testharness;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface TestProject {
|
||||
|
||||
Path getPath();
|
||||
|
||||
IType findType(String string);
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
<jackson-2-version>2.5.0</jackson-2-version>
|
||||
<jersey-2-version>2.10</jersey-2-version>
|
||||
<lsapi-version>0.3.0</lsapi-version>
|
||||
<reactor-version>3.0.2.RELEASE</reactor-version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
||||
Reference in New Issue
Block a user