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.
+// *
+// * Falls back on doing a full-blown search if there's no usable 'prefix-query' in the cache.
+// */
+// private Flux 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 getValuesAsycn(IJavaProject javaProject, String query);
+//
+// private Tuple2 key(IJavaProject javaProject, String query) {
+// return Tuples.of(javaProject==null?null:javaProject.getElementName(), query);
+// }
+//
+// protected Cache createCache() {
+// return new LimitedTimeCache<>(Duration.ofMinutes(1));
+// }
+
+ public static void restoreDefaults() {
+ TIMEOUT = DEFAULT_TIMEOUT;
+ }
+
+}
diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/SpringPropertyIndexProvider.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/SpringPropertyIndexProvider.java
new file mode 100644
index 000000000..6229380ca
--- /dev/null
+++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/SpringPropertyIndexProvider.java
@@ -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 getIndex(IDocument doc);
+
+}
diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/Editor.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/Editor.java
index 55e030de3..50c5b8e25 100644
--- a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/Editor.java
+++ b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/Editor.java
@@ -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 getCompletions() throws Exception {
CompletionList cl = harness.getCompletions(this.document, this.getCursor());
ArrayList items = new ArrayList<>(cl.getItems());
Collections.sort(items, new Comparator() {
@@ -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 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 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());
+ }
+
}
diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/IType.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/IType.java
new file mode 100644
index 000000000..6ed7f2d34
--- /dev/null
+++ b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/IType.java
@@ -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 {
+
+}
diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java
index 39f31ea73..a705116fd 100644
--- a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java
+++ b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java
@@ -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());
+ }
+
}
diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TestProject.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TestProject.java
new file mode 100644
index 000000000..1c06ceb61
--- /dev/null
+++ b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TestProject.java
@@ -0,0 +1,11 @@
+package org.springframework.ide.vscode.testharness;
+
+import java.nio.file.Path;
+
+public interface TestProject {
+
+ Path getPath();
+
+ IType findType(String string);
+
+}
diff --git a/vscode-extensions/commons/pom.xml b/vscode-extensions/commons/pom.xml
index fcd31ef6e..e41b048b6 100644
--- a/vscode-extensions/commons/pom.xml
+++ b/vscode-extensions/commons/pom.xml
@@ -26,6 +26,7 @@
2.5.0
2.10
0.3.0
+ 3.0.2.RELEASE
diff --git a/vscode-extensions/vscode-application-yaml/pom.xml b/vscode-extensions/vscode-application-yaml/pom.xml
index 4cb086205..65011bbe7 100644
--- a/vscode-extensions/vscode-application-yaml/pom.xml
+++ b/vscode-extensions/vscode-application-yaml/pom.xml
@@ -44,7 +44,13 @@
org.springframework.ide.vscode
commons-language-server
- 0.0.1-SNAPSHOT
+ ${project.version}
+
+
+
+ org.springframework.ide.vscode
+ application-properties-metadata
+ ${project.version}
diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/AbstractPropsEditorTest.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/AbstractPropsEditorTest.java
new file mode 100644
index 000000000..6500c1b29
--- /dev/null
+++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/AbstractPropsEditorTest.java
@@ -0,0 +1,182 @@
+package org.springframework.ide.vscode.yaml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Before;
+import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertyIndexProvider;
+import org.springframework.ide.vscode.testharness.Editor;
+import org.springframework.ide.vscode.testharness.LanguageServerHarness;
+import org.springframework.ide.vscode.testharness.TestProject;
+import org.springframework.ide.vscode.yaml.PropertyIndexHarness.ItemConfigurer;
+
+import io.typefox.lsapi.CompletionItem;
+
+public class AbstractPropsEditorTest {
+
+ private PropertyIndexHarness md;
+ private LanguageServerHarness harness;
+
+ public Editor newEditor(String contents) throws Exception {
+ return harness.newEditor(contents);
+ }
+
+ @Before
+ public void setup() throws Exception {
+ md = new PropertyIndexHarness();
+ harness = new LanguageServerHarness(YamlLanguageServer::new);
+ harness.intialize(null);
+ }
+
+ public ItemConfigurer data(String id, String type, Object deflt, String description, String... sources) {
+ return md.data(id, type, deflt, description, sources);
+ }
+
+ public void defaultTestData() {
+ md.defaultTestData();
+ }
+
+ public TestProject createPredefinedMavenProject(String string) {
+ notImplemented();
+ return null;
+ }
+
+ public void useProject(TestProject p) {
+ notImplemented(); //only tests that don't require project context / classpath work for now
+ }
+
+ /**
+ * Simulates applying the first completion to a text buffer and checks the result.
+ */
+ public void assertCompletion(String textBefore, String expectTextAfter) throws Exception {
+ harness.assertCompletion(textBefore, expectTextAfter);
+ }
+
+ private void notImplemented() {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Checks that completions contains a completion with a given display string and that that completion
+ * has a info hover that contains a given snippet of text.
+ */
+ public void assertCompletionWithInfoHover(String editorText, String expectLabel, String expectInfoSnippet) throws Exception {
+ notImplemented();
+ }
+
+ public boolean isEmptyMetadata() {
+ return md.isEmpty();
+ }
+
+ /**
+ * Checks that applying completions to a given 'textBefore' editor content produces the
+ * expected results.
+ */
+ public void assertCompletions(String textBefore, String... expectTextAfter) throws Exception {
+ harness.assertCompletions(textBefore, expectTextAfter);
+ }
+
+ public void assertNoCompletions(String text) throws Exception {
+ assertCompletions(text /*NONE*/);
+ }
+
+ /**
+ * Checks that completions contains a completion with a given display string (and check that
+ * it applies as expected).
+ */
+ public void assertCompletionWithLabel(String textBefore, String expectLabel, String expectTextAfter) throws Exception {
+ Editor editor = newEditor(textBefore);
+ List completions = editor.getCompletions();
+ CompletionItem completion = assertCompletionWithLabel(expectLabel, completions);
+ editor.apply(completion);
+ assertEquals(expectTextAfter, editor.getText());
+ }
+
+ private CompletionItem assertCompletionWithLabel(String expectLabel, List completions) {
+ StringBuilder found = new StringBuilder();
+ for (CompletionItem c : completions) {
+ String actualLabel = c.getLabel();
+ found.append(actualLabel+"\n");
+ if (actualLabel.equals(expectLabel)) {
+ return c;
+ }
+ }
+ fail("No completion found with label '"+expectLabel+"' in:\n"+found);
+ return null; //unreachable, but compiler doesn't know that.
+ }
+
+ public void assertCompletionCount(int expected, String editorText) throws Exception {
+ Editor editor = newEditor(editorText);
+ assertEquals(expected, editor.getCompletions().size());
+ }
+
+ public void assertCompletionsDisplayString(String editorText, String... completionsLabels) throws Exception {
+ Editor editor = newEditor(editorText);
+ List completions = editor.getCompletions();
+ String[] actualLabels = new String[completions.size()];
+ for (int i = 0; i < actualLabels.length; i++) {
+ actualLabels[i] = completions.get(i).getLabel();
+ }
+ assertElements(actualLabels, completionsLabels);
+ }
+
+ public SpringPropertyIndexProvider getIndexProvider() {
+ return md.getIndexProvider();
+ }
+
+ @SafeVarargs
+ public static void assertElements(T[] actual, T... expect) {
+ assertElements(Arrays.asList(actual), expect);
+ }
+
+ @SafeVarargs
+ public static void assertElements(Collection actual, T... expect) {
+ Set expectedSet = new HashSet(Arrays.asList(expect));
+
+ for (T propVal : actual) {
+ if (!expectedSet.remove(propVal)) {
+ fail("Unexpected element: "+propVal);
+ }
+ }
+
+ if (!expectedSet.isEmpty()) {
+ StringBuilder missing = new StringBuilder();
+ for (T propVal : expectedSet) {
+ missing.append(propVal+"\n");
+ }
+ fail("Missing elements: \n"+missing);
+ }
+ }
+
+ public void assertStyledCompletions(String editorText, StyledStringMatcher... expectStyles) throws Exception {
+ Editor editor = newEditor(editorText);
+ List completions = editor.getCompletions();
+ assertEquals("Wrong number of elements", expectStyles.length, completions.size());
+ for (int i = 0; i < expectStyles.length; i++) {
+ CompletionItem completion = completions.get(i);
+ throw new UnsupportedOperationException("Suport for styled labels not implemented");
+// StyledString actualLabel = getStyledDisplayString(completion);
+// expectStyles[i].match(actualLabel);
+ }
+ }
+
+
+ public void deprecate(String key, String replacedBy, String reason) {
+ md.deprecate(key, replacedBy, reason);
+ }
+
+ public void keyHints(String id, String... hintValues) {
+ md.keyHints(id, hintValues);
+ }
+
+ public void valueHints(String id, String... hintValues) {
+ md.valueHints(id, hintValues);
+ }
+
+}
diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java
index 11c33e3ca..086bef0a4 100644
--- a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java
+++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java
@@ -1,9 +1,32 @@
+/*******************************************************************************
+ * 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.yaml;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.time.Duration;
+
+import org.junit.Ignore;
import org.junit.Test;
+import org.springframework.ide.vscode.boot.properties.metadata.CachingValueProvider;
+import org.springframework.ide.vscode.boot.properties.metadata.PropertyInfo;
import org.springframework.ide.vscode.testharness.Editor;
import org.springframework.ide.vscode.testharness.LanguageServerHarness;
-import org.springframework.ide.vscode.yaml.YamlLanguageServer;
+import org.springframework.ide.vscode.testharness.TestProject;
+import org.springframework.ide.vscode.util.StringUtil;
+
+import io.typefox.lsapi.CompletionItem;
+import io.typefox.lsapi.Diagnostic;
/**
* This class is a placeholder where we will attempt to copy and port
@@ -12,26 +35,15 @@ import org.springframework.ide.vscode.yaml.YamlLanguageServer;
*
* @author Kris De Volder
*/
-public class ApplicationYamlEditorTest {
+public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
+
+ ////////////////////////////////////////////////////////////////////////////////////////
- @Test public void testReconcileCatchesParseError() throws Exception {
- LanguageServerHarness harness = new LanguageServerHarness(YamlLanguageServer::new);
- harness.intialize(null);
-
- Editor editor = harness.newEditor(
- "somemap: val\n"+
- "- sequence"
- );
- editor.assertProblems(
- "-|expected "
- );
- }
-
@Test public void linterRunsOnDocumentOpenAndChange() throws Exception {
LanguageServerHarness harness = new LanguageServerHarness(YamlLanguageServer::new);
harness.intialize(null);
- Editor editor = harness.newEditor(
+ Editor editor = newEditor(
"somemap: val\n"+
"- sequence"
);
@@ -49,4 +61,3460 @@ public class ApplicationYamlEditorTest {
"z|expected "
);
}
+
+ ///////////////////// ported tests from old STS code base ////////////////////////////////////////////////
+
+ @Ignore @Test public void testHovers() throws Exception {
+ defaultTestData();
+ Editor editor = newEditor(
+ "spring:\n" +
+ " application:\n" +
+ " name: foofoo\n" +
+ " beyond:\n" +
+ " the-valid: range\n" +
+ " \n" +
+ "server:\n" +
+ " port: 8888"
+ );
+
+ editor.assertIsHoverRegion("spring");
+ editor.assertIsHoverRegion("application");
+ editor.assertIsHoverRegion("name");
+
+ editor.assertIsHoverRegion("server");
+ editor.assertIsHoverRegion("port");
+
+ editor.assertHoverContains("name", "spring.application.name");
+ editor.assertHoverContains("port", "server.port");
+ editor.assertHoverContains("8888", "server.port"); // hover over value show info about corresponding key. Is this logical?
+
+ editor.assertNoHover("beyond");
+ editor.assertNoHover("the-valid");
+ editor.assertNoHover("range");
+
+ //Note currently, these provide no hovers, but maybe (some of them) should if we index proprty sources and not just the
+ // properties themselves.
+ editor.assertNoHover("spring");
+ editor.assertNoHover("application");
+ editor.assertNoHover("server");
+
+
+ //Test for the case where we can't produce an AST for editor text
+ editor = newEditor(
+ "- syntax\n" +
+ "error:\n"
+ );
+ editor.assertNoHover("syntax");
+ editor.assertNoHover("error");
+ }
+
+ @Ignore @Test public void testHoverInfoForEnumValueInMapKey() throws Exception {
+ Editor editor;
+ TestProject project = createPredefinedMavenProject("boot13");
+ useProject(project);
+
+ //This test will fail if source jars haven't been downloaded.
+ //Probably that is why it fails in CI build?
+ //Let's check:
+// IType type = project.findType("com.fasterxml.jackson.databind.SerializationFeature");
+// System.out.println(">>> source for: "+type.getFullyQualifiedName());
+// System.out.println(downloadSources(type));
+// System.out.println("<<< source for: "+type.getFullyQualifiedName());
+
+ editor = newEditor(
+ "spring:\n" +
+ " jackson:\n" +
+ " serialization:\n" +
+ " indent-output: true"
+ );
+ editor.assertIsHoverRegion("indent-output");
+ editor.assertHoverContains("indent-output", "allows enabling (or disabling) indentation");
+
+ //Also try that it works when spelled in all upper-case
+ editor = newEditor(
+ "spring:\n" +
+ " jackson:\n" +
+ " serialization:\n" +
+ " INDENT_OUTPUT: true"
+ );
+ editor.assertIsHoverRegion("INDENT_OUTPUT");
+ editor.assertHoverContains("INDENT_OUTPUT", "allows enabling (or disabling) indentation");
+ }
+
+ @Ignore @Test public void testHoverInfoForEnumValueInMapKeyCompletion() throws Exception {
+ TestProject project = createPredefinedMavenProject("boot13");
+ useProject(project);
+
+ //This test will fail if source jars haven't been downloaded.
+ //Probably that is why it fails in CI build?
+ //Let's check:
+// IType type = project.findType("com.fasterxml.jackson.databind.SerializationFeature");
+// System.out.println(">>> source for: "+type.getFullyQualifiedName());
+// System.out.println(downloadSources(type));
+// System.out.println("<<< source for: "+type.getFullyQualifiedName());
+
+ assertCompletionWithInfoHover(
+ "spring:\n" +
+ " jackson:\n" +
+ " serialization:\n" +
+ " ind<*>"
+ , // ==========
+ "indent-output : boolean"
+ , // ==>
+ "allows enabling (or disabling) indentation"
+ );
+ }
+
+ @Ignore @Test public void testHoverInfoForValueHintCompletion() throws Exception {
+ data("my.bonus", "java.lang.String", null, "Bonus type")
+ .valueHint("small", "A small bonus. For a little extra incentive.")
+ .valueHint("large", "An large bonus. For the ones who deserve it.")
+ .valueHint("exorbitant", "Truly outrageous. Who deserves a bonus like that?");
+
+ assertCompletionWithInfoHover(
+ "my:\n" +
+ " bonus: l<*>"
+ , // ==========
+ "large"
+ , // ==>
+ "For the ones who deserve it"
+ );
+ }
+
+ @Ignore @Test public void testHoverInfoForValueHint() throws Exception {
+ data("my.bonus", "java.lang.String", null, "Bonus type")
+ .valueHint("small", "A small bonus. For a little extra incentive.")
+ .valueHint("large", "An large bonus. For the ones who deserve it.")
+ .valueHint("exorbitant", "Truly outrageous. Who deserves a bonus like that?");
+
+ Editor editor = newEditor(
+ "#comment here\n" +
+ "my:\n" +
+ " bonus: large\n"
+ );
+
+ editor.assertIsHoverRegion("large");
+ editor.assertHoverContains("large", "For the ones who deserve it");
+ }
+
+
+ @Ignore @Test public void testUserDefinedHoversandLinkTargets() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+ data("foo.link-tester", "demo.LinkTestSubject", null, "for testing different Pojo link cases");
+ Editor editor = newEditor(
+ "#A comment at the start\n" +
+ "foo:\n" +
+ " data:\n" +
+ " wavelen: 666\n" +
+ " name: foo\n" +
+ " next: green\n" +
+ " link-tester:\n" +
+ " has-it-all: nice\n" +
+ " strange: weird\n" +
+ " getter-only: getme\n"
+ );
+
+ editor.assertHoverContains("data", "Pojo"); // description from json metadata
+ editor.assertHoverContains("wavelen", "JavaDoc from field"); // javadoc from field
+ editor.assertHoverContains("name", "Set the name"); // javadoc from setter
+ editor.assertHoverContains("next", "Get the next"); // javadoc from getter
+
+ editor.assertLinkTargets("data", "demo.FooProperties.setdata(ColorData)");
+ editor.assertLinkTargets("wavelen", "demo.ColorData.setWavelen(double)");
+
+ }
+
+ @Ignore @Test public void testHyperlinkTargets() throws Exception {
+ System.out.println(">>> testHyperlinkTargets");
+ TestProject p = createPredefinedMavenProject("demo");
+ useProject(p);
+
+ Editor editor = newEditor(
+ "server:\n"+
+ " port: 888\n" +
+ "spring:\n" +
+ " datasource:\n" +
+ " login-timeout: 1000\n" +
+ "flyway:\n" +
+ " init-sqls: a,b,c\n"
+ );
+
+ editor.assertLinkTargets("port",
+ "org.springframework.boot.autoconfigure.web.ServerProperties.setPort(Integer)"
+ );
+ editor.assertLinkTargets("login-",
+ "org.springframework.boot.autoconfigure.jdbc.DataSourceConfigMetadata.hikariDataSource()",
+ "org.springframework.boot.autoconfigure.jdbc.DataSourceConfigMetadata.tomcatDataSource()",
+ "org.springframework.boot.autoconfigure.jdbc.DataSourceConfigMetadata.dbcpDataSource()"
+ );
+ editor.assertLinkTargets("init-sql",
+ "org.springframework.boot.autoconfigure.flyway.FlywayProperties.setInitSqls(List)");
+ System.out.println("<<< testHyperlinkTargets");
+ }
+
+ @Ignore @Test public void testReconcile() throws Exception {
+ defaultTestData();
+ Editor editor = newEditor(
+ "server:\n" +
+ " port: \n" +
+ " extracrap: 8080\n" +
+ "logging:\n"+
+ " level:\n" +
+ " com.acme: INFO\n" +
+ " snuggem: what?\n" +
+ "bogus:\n" +
+ " no: \n" +
+ " good: true\n"
+ );
+ editor.assertProblems(
+ "extracrap: 8080|Expecting a 'int' but got a 'Mapping' node",
+ "snuggem|Unknown property",
+ "bogus|Unknown property"
+ );
+ }
+
+ @Ignore @Test public void test_STS_4140_StringArrayReconciling() throws Exception {
+ defaultTestData();
+
+ Editor editor;
+
+ //Case 0: very focussed test for easy debugging
+ editor = newEditor(
+ "flyway:\n" +
+ " schemas: [MEMBER_VERSION, MEMBER]"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ //Case 1: String[] as a flow sequence
+ editor = newEditor(
+ "something-bad: wrong\n"+
+ "flyway:\n" +
+ " url: jdbc:h2:file:~/localdb;IGNORECASE=TRUE;mv_store=false\n" +
+ " user: admin\n" +
+ " password: admin\n" +
+ " schemas: [MEMBER_VERSION, MEMBER]"
+ );
+ editor.assertProblems(
+ "something-bad|Unknown property"
+ //No other problems should be reported
+ );
+
+ //Case 1: String[] as a block sequence
+ editor = newEditor(
+ "something-bad: wrong\n"+
+ "flyway:\n" +
+ " url: jdbc:h2:file:~/localdb;IGNORECASE=TRUE;mv_store=false\n" +
+ " user: admin\n" +
+ " password: admin\n" +
+ " schemas:\n" +
+ " - MEMBER_VERSION\n" +
+ " - MEMBER"
+ );
+ editor.assertProblems(
+ "something-bad|Unknown property"
+ //No other problems should be reported
+ );
+ }
+
+ @Ignore @Test public void test_STS_4140_StringArrayCompletion() throws Exception {
+ defaultTestData();
+
+ assertCompletion(
+ "#some comment\n" +
+ "flyway:\n" +
+ " sch<*>\n"
+ , //=>
+ "#some comment\n" +
+ "flyway:\n" +
+ " schemas:\n" +
+ " - <*>\n"
+ );
+ }
+
+ @Ignore @Test public void testReconcileIntegerScalar() throws Exception {
+ data("server.port", "java.lang.Integer", null, "Port of server");
+ data("server.threads", "java.lang.Integer", null, "Number of threads for server threadpool");
+ Editor editor = newEditor(
+ "server:\n" +
+ " port: \n" +
+ " 8888\n" +
+ " threads:\n" +
+ " not-a-number\n"
+ );
+ editor.assertProblems(
+ "not-a-number|Expecting a 'int'"
+ );
+ }
+
+ @Ignore @Test public void testReconcileExpectMapping() throws Exception {
+ defaultTestData();
+ Editor editor = newEditor(
+ "server:\n" +
+ " - a\n" +
+ " - b\n"
+ );
+ editor.assertProblems(
+ "- a\n - b|Expecting a 'Mapping' node but got a 'Sequence' node"
+ );
+ }
+
+ @Ignore @Test public void testReconcileExpectScalar() throws Exception {
+ defaultTestData();
+ Editor editor = newEditor(
+ "server:\n" +
+ " ? - a\n" +
+ " - b\n" +
+ " : c"
+ );
+ editor.assertProblems(
+ "- a\n - b|Expecting a 'Scalar' node but got a 'Sequence' node"
+ );
+ }
+
+ @Ignore @Test public void testReconcileCamelCaseBasic() throws Exception {
+ Editor editor;
+ data("something.with-many-parts", "java.lang.Integer", "For testing tolerance of camelCase", null);
+ data("something.with-parts.and-more", "java.lang.Integer", "For testing tolerance of camelCase", null);
+
+ //Nothing special... not using camel case
+ editor = newEditor(
+ "#Comment for good measure\n" +
+ "something:\n" +
+ " with-many-parts: not-a-number"
+ );
+ editor.assertProblems(
+ "not-a-number|Expecting a 'int'"
+ );
+
+ //Now check that reconcile also tolerates camel case and reports no error for it
+ editor = newEditor(
+ "#Comment for good measure\n" +
+ "something:\n" +
+ " withManyParts: 123"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ //Now check that reconciler traverses camelCase and reports errors assigning to camelCase names
+ editor = newEditor(
+ "#Comment for good measure\n" +
+ "something:\n" +
+ " withManyParts: not-a-number"
+ );
+ editor.assertProblems(
+ "not-a-number|Expecting a 'int'"
+ );
+
+ //Now check also that camelcase tolerance works if its not in the end of the path
+ editor = newEditor(
+ "#Comment for good measure\n" +
+ "something:\n" +
+ " withParts:\n" +
+ " andMore: not-a-number\n" +
+ " bad: wrong\n" +
+ " something-bad: also wrong\n"
+ );
+ editor.assertProblems(
+ "not-a-number|Expecting a 'int'",
+ "bad|Unknown property",
+ "something-bad|Unknown property"
+ );
+ }
+
+ @Ignore @Test public void testContentAssistCamelCaseBasic() throws Exception {
+ data("something.with-many-parts", "java.lang.Integer", "For testing tolerance of camelCase", null);
+ data("something.with-parts.and-more", "java.lang.Integer", "For testing tolerance of camelCase", null);
+
+ assertCompletion(
+ "something:\n" +
+ " withParts:\n" +
+ " <*>",
+ // =>
+ "something:\n" +
+ " withParts:\n" +
+ " and-more: <*>"
+ );
+ }
+
+ @Ignore @Test public void testReconcileCamelCaseBeanProp() throws Exception {
+ Editor editor;
+
+ TestProject p = createPredefinedMavenProject("demo");
+ useProject(p);
+
+ data("demo.bean", "demo.CamelCaser", "For testing tolerance of camelCase", null);
+
+ //Nothing special... not using camel case
+ editor = newEditor(
+ "#Comment for good measure\n" +
+ "demo:\n" +
+ " bean:\n"+
+ " the-answer-to-everything: not-a-number\n"
+ );
+ editor.assertProblems(
+ "not-a-number|Expecting a 'int'"
+ );
+
+ //Now check that reconcile also tolerates camel case and reports no error for it
+ editor = newEditor(
+ "#Comment for good measure\n" +
+ "demo:\n" +
+ " bean:\n"+
+ " theAnswerToEverything: 42\n"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ //Now check that reconciler traverses camelCase and reports errors assigning to camelCase names
+ editor = newEditor(
+ "#Comment for good measure\n" +
+ "demo:\n" +
+ " bean:\n"+
+ " theAnswerToEverything: not-a-number\n"
+ );
+ editor.assertProblems(
+ "not-a-number|Expecting a 'int'"
+ );
+
+ //Now check also that camelcase tolerance works if its not in the end of the path
+ editor = newEditor(
+ "#Comment for good measure\n" +
+ "demo:\n" +
+ " bean:\n"+
+ " theAnswerToEverything: not-a-number\n"+
+ " theLeft:\n"+
+ " bad: wrong\n"+
+ " theAnswerToEverything: not-this\n"
+ );
+ editor.assertProblems(
+ "not-a-number|Expecting a 'int'",
+ "bad|Unknown property",
+ "not-this|Expecting a 'int'"
+ );
+ }
+
+ @Ignore @Test public void testContentAssistCamelCaseBeanProp() throws Exception {
+ TestProject p = createPredefinedMavenProject("demo");
+ useProject(p);
+
+ data("demo.bean", "demo.CamelCaser", "For testing tolerance of camelCase", null);
+
+ assertCompletion(
+ "demo:\n" +
+ " bean:\n" +
+ " theLeft:\n" +
+ " answer<*>\n",
+ // =>
+ "demo:\n" +
+ " bean:\n" +
+ " theLeft:\n" +
+ " the-answer-to-everything: <*>\n"
+ );
+ }
+
+ @Ignore @Test public void testContentAssistCamelCaseInsertInExistingContext() throws Exception {
+ data("demo-bean.first", "java.lang.String", "For testing tolerance of camelCase", null);
+ data("demo-bean.second", "java.lang.String", "For testing tolerance of camelCase", null);
+
+ //Confirm first it works correctly without camelizing complications
+// assertCompletion(
+// "demo-bean:\n" +
+// " first: numero uno\n" +
+// "something-else: separator\n"+
+// "sec<*>",
+// // =>
+// "demo-bean:\n" +
+// " first: numero uno\n" +
+// " second: <*>\n" +
+// "something-else: separator\n"
+// );
+
+ //Now with camels
+ assertCompletion(
+ "demoBean:\n" +
+ " first: numero uno\n" +
+ "something-else: separator\n"+
+ "sec<*>",
+ // =>
+ "demoBean:\n" +
+ " first: numero uno\n" +
+ " second: <*>\n" +
+ "something-else: separator\n"
+ );
+ }
+
+
+ @Ignore @Test public void testReconcileBeanPropName() throws Exception {
+ TestProject p = createPredefinedMavenProject("demo-list-of-pojo");
+ useProject(p);
+ assertNotNull(p.findType("demo.Foo"));
+ data("some-foo", "demo.Foo", null, "some Foo pojo property");
+ Editor editor = newEditor(
+ "some-foo:\n" +
+ " name: Good\n" +
+ " bogus: Bad\n" +
+ " ? - a\n"+
+ " - b\n"+
+ " : Weird\n"
+ );
+ editor.assertProblems(
+ "bogus|Unknown property 'bogus' for type 'demo.Foo'",
+ "- a\n - b|Expecting a bean-property name for object of type 'demo.Foo' "
+ + "but got a 'Sequence' node"
+ );
+ }
+
+ @Ignore @Test public void testIgnoreSpringExpression() throws Exception {
+ defaultTestData();
+ Editor editor = newEditor(
+ "server:\n" +
+ " port: ${random.int}\n" + //should not be an error
+ " bad: wrong\n"
+ );
+ editor.assertProblems(
+ "bad|Unknown property"
+ );
+ }
+
+ @Ignore @Test public void testReconcilePojoArray() throws Exception {
+ TestProject p = createPredefinedMavenProject("demo-list-of-pojo");
+ useProject(p);
+ assertNotNull(p.findType("demo.Foo"));
+
+ {
+ Editor editor = newEditor(
+ "token-bad-guy: problem\n"+
+ "volder:\n" +
+ " foo:\n" +
+ " list:\n"+
+ " - name: Kris\n" +
+ " description: Kris\n" +
+ " roles:\n" +
+ " - Developer\n" +
+ " - Admin\n" +
+ " bogus: Bad\n"
+ );
+
+ editor.assertProblems(
+ "token-bad-guy|Unknown property",
+ //'name' is ok
+ //'description' is ok
+ "bogus|Unknown property 'bogus' for type 'demo.Foo'"
+ );
+ }
+
+ { //Pojo array can also be entered as a map with integer keys
+
+ Editor editor = newEditor(
+ "token-bad-guy: problem\n"+
+ "volder:\n" +
+ " foo:\n" +
+ " list:\n"+
+ " 0:\n"+
+ " name: Kris\n" +
+ " description: Kris\n" +
+ " roles:\n" +
+ " 0: Developer\n" +
+ " one: Admin\n" +
+ " bogus: Bad\n"
+ );
+
+ editor.assertProblems(
+ "token-bad-guy|Unknown property",
+ "one|Expecting a 'int' but got 'one'",
+ "bogus|Unknown property 'bogus' for type 'demo.Foo'"
+ );
+
+ }
+
+ }
+
+ @Ignore @Test public void testReconcileSequenceGotAtomicType() throws Exception {
+ defaultTestData();
+ Editor editor = newEditor(
+ "liquibase:\n" +
+ " enabled:\n" +
+ " - element\n"
+ );
+ editor.assertProblems(
+ "- element|Expecting a 'boolean' but got a 'Sequence' node"
+ );
+ }
+
+ @Ignore @Test public void testReconcileSequenceGotMapType() throws Exception {
+ data("the-map", "java.util.Map", null, "Nice mappy");
+ Editor editor = newEditor(
+ "the-map:\n" +
+ " - a\n" +
+ " - b\n"
+ );
+ editor.assertProblems(
+ "- a\n - b|Expecting a 'Map' but got a 'Sequence' node"
+ );
+ }
+
+ @Ignore @Test public void testEnumPropertyReconciling() throws Exception {
+ TestProject p = createPredefinedMavenProject("demo-enum");
+ useProject(p);
+ assertNotNull(p.findType("demo.Color"));
+
+ data("foo.color", "demo.Color", null, "A foonky colour");
+ Editor editor = newEditor(
+ "foo:\n"+
+ " color: BLUE\n" +
+ "---\n" +
+ "foo:\n" +
+ " color: RED\n" +
+ "---\n" +
+ "foo:\n" +
+ " color: GREEN\n" +
+ "---\n" +
+ "foo:\n" +
+ " color:\n" +
+ " bad: BLUE\n" +
+ "---\n" +
+ "foo:\n" +
+ " color: Bogus\n"
+ );
+
+ editor.assertProblems(
+ "bad: BLUE|Expecting a 'demo.Color[RED, GREEN, BLUE]' but got a 'Mapping' node",
+ "Bogus|Expecting a 'demo.Color[RED, GREEN, BLUE]' but got 'Bogus'"
+ );
+ }
+
+ @Test public void testReconcileSkipIfNoMetadata() throws Exception {
+ Editor editor = newEditor(
+ "foo:\n"+
+ " color: BLUE\n" +
+ " color: RED\n" + //technically not allowed to bind same key twice but we don' check this
+ " color: GREEN\n" +
+ " color:\n" +
+ " bad: BLUE\n" +
+ " color: Bogus\n"
+ );
+ assertTrue(isEmptyMetadata());
+ editor.assertProblems(/*NONE*/);
+ }
+
+ @Test public void testReconcileCatchesParseError() throws Exception {
+ defaultTestData();
+ Editor editor = newEditor(
+ "somemap: val\n"+
+ "- sequence"
+ );
+ editor.assertProblems(
+ "-|expected "
+ );
+ }
+
+ @Test public void testReconcileCatchesScannerError() throws Exception {
+ defaultTestData();
+ Editor editor = newEditor(
+ "somemap: \"quotes not closed\n"
+ );
+ editor.assertProblems(
+ "|unexpected end of stream"
+ );
+ }
+
+ @Ignore @Test public void testContentAssistSimple() throws Exception {
+ defaultTestData();
+ assertCompletion("port<*>",
+ "server:\n"+
+ " port: <*>");
+ assertCompletion(
+ "#A comment\n" +
+ "port<*>",
+ "#A comment\n" +
+ "server:\n"+
+ " port: <*>");
+ assertCompletions(
+ "server:\n" +
+ " nonsense<*>\n"
+ //=> nothing
+ );
+ }
+
+ @Ignore @Test public void testContentAssistNullContext() throws Exception {
+ defaultTestData();
+ assertCompletions(
+ "#A comment\n" +
+ "foo:\n" +
+ " data:\n" +
+ " bogus:\n" +
+ " <*>"
+ // => nothing
+ );
+ }
+
+ @Ignore @Test public void testContentAssistNested() throws Exception {
+ data("server.port", "java.lang.Integer", null, "Server http port");
+ data("server.address", "java.lang.String", "localhost", "Server host address");
+
+ assertCompletion(
+ "server:\n"+
+ " port: 8888\n" +
+ " <*>"
+ ,
+ "server:\n"+
+ " port: 8888\n" +
+ " address: <*>"
+ );
+
+ assertCompletion(
+ "server:\n"+
+ " <*>"
+ ,
+ "server:\n"+
+ " address: <*>"
+ );
+
+ assertCompletion(
+ "server:\n"+
+ " a<*>"
+ ,
+ "server:\n"+
+ " address: <*>"
+ );
+
+ assertCompletion(
+ "server:\n"+
+ " <*>\n" +
+ " port: 8888"
+ ,
+ "server:\n"+
+ " address: <*>\n" +
+ " port: 8888"
+ );
+
+ assertCompletion(
+ "server:\n"+
+ " a<*>\n" +
+ " port: 8888"
+ ,
+ "server:\n"+
+ " address: <*>\n" +
+ " port: 8888"
+ );
+
+ }
+
+ @Ignore @Test public void testContentAssistNestedSameLine() throws Exception {
+ data("server.port", "java.lang.Integer", null, "Server http port");
+
+ assertCompletion(
+ "server: <*>"
+ ,
+ "server: \n" +
+ " port: <*>"
+ );
+
+ assertCompletion(
+ "#something before this stuff\n" +
+ "server: <*>"
+ ,
+ "#something before this stuff\n" +
+ "server: \n" +
+ " port: <*>"
+ );
+ }
+
+ @Ignore @Test public void testContentAssistInsertCompletionElsewhere() throws Exception {
+ defaultTestData();
+
+ assertCompletion(
+ "server:\n" +
+ " port: 8888\n" +
+ " address: \n" +
+ " servlet-path: \n" +
+ "spring:\n" +
+ " activemq:\n" +
+ "something-else: great\n" +
+ "aopauto<*>"
+ ,
+ "server:\n" +
+ " port: 8888\n" +
+ " address: \n" +
+ " servlet-path: \n" +
+ "spring:\n" +
+ " activemq:\n" +
+ " aop:\n" +
+ " auto: <*>\n" +
+ "something-else: great\n"
+ );
+
+ assertCompletion(
+ "server:\n"+
+ " address: localhost\n"+
+ "something: nice\n"+
+ "po<*>"
+ ,
+ "server:\n"+
+ " address: localhost\n"+
+ " port: <*>\n" +
+ "something: nice\n"
+ );
+ }
+
+ @Ignore @Test public void testContentAssistInsertCompletionElsewhereInEmptyParent() throws Exception {
+ data("server.port", "java.lang.Integer", null, "Server http port");
+ data("server.address", "String", "localhost", "Server host address");
+
+ assertCompletion(
+ "#comment\n" +
+ "server:\n" +
+ "something:\n" +
+ " more\n" +
+ "po<*>"
+ ,
+ "#comment\n" +
+ "server:\n" +
+ " port: <*>\n" +
+ "something:\n" +
+ " more\n"
+ );
+ }
+
+ @Ignore @Test public void testContentAssistInetAddress() throws Exception {
+ //Test that InetAddress is treated as atomic w.r.t indentation
+
+ defaultTestData();
+ assertCompletion(
+ "#set address of server\n" +
+ "servadd<*>"
+ , //=>
+ "#set address of server\n" +
+ "server:\n"+
+ " address: <*>"
+ );
+
+ assertCompletion(
+ "#set address of server\n" +
+ "server:\n"+
+ " port: 888\n" +
+ "more: stuff\n" +
+ "servadd<*>"
+ , //=>
+ "#set address of server\n" +
+ "server:\n"+
+ " port: 888\n" +
+ " address: <*>\n" +
+ "more: stuff\n"
+ );
+
+ }
+
+ @Ignore @Test public void testContentAssistInsertCompletionElsewhereThatAlreadyExists() throws Exception {
+ data("server.port", "java.lang.Integer", null, "Server http port");
+ data("server.address", "String", "localhost", "Server host address");
+
+ //inserting something that already exists should just move the cursor to existing node
+
+ assertCompletion(
+ "server:\n"+
+ " port:\n" +
+ " 8888\n"+
+ " address: localhost\n"+
+ "something: nice\n"+
+ "po<*>"
+ ,
+ "server:\n"+
+ " port:\n"+
+ " <*>8888\n" +
+ " address: localhost\n"+
+ "something: nice\n"
+ );
+
+ assertCompletion(
+ "server:\n"+
+ " port: 8888\n" +
+ " address: localhost\n"+
+ "something: nice\n"+
+ "po<*>"
+ ,
+ "server:\n"+
+ " port: <*>8888\n" +
+ " address: localhost\n"+
+ "something: nice\n"
+ );
+
+ assertCompletion(
+ "server:\n"+
+ " port:\n"+
+ " address: localhost\n"+
+ "something: nice\n"+
+ "po<*>"
+ ,
+ "server:\n"+
+ " port:<*>\n" +
+ " address: localhost\n"+
+ "something: nice\n"
+ );
+ }
+
+
+ @Ignore @Test public void testContentAssistPropertyWithMapType() throws Exception {
+ data("foo.mapping", "java.util.Map", null, "Nice little map");
+
+ //Try in-place completion
+ assertCompletion(
+ "map<*>"
+ ,
+ "foo:\n"+
+ " mapping:\n"+
+ " <*>"
+ );
+
+ //Try 'elswhere' completion
+ assertCompletion(
+ "foo:\n" +
+ " something:\n" +
+ "more: stuff\n" +
+ "map<*>"
+ ,
+ "foo:\n" +
+ " something:\n" +
+ " mapping:\n" +
+ " <*>\n" +
+ "more: stuff\n"
+ );
+ }
+
+ @Ignore @Test public void testContentAssistPropertyWithArrayType() throws Exception {
+ data("foo.list", "java.util.List", null, "Nice little list");
+
+ //Try in-place completion
+ assertCompletion(
+ "lis<*>"
+ ,
+ "foo:\n"+
+ " list:\n"+
+ " - <*>"
+ );
+
+ //Try 'elsewhere' completion
+ assertCompletion(
+ "foo:\n" +
+ " something:\n" +
+ "more: stuff\n" +
+ "lis<*>"
+ ,
+ "foo:\n" +
+ " something:\n" +
+ " list:\n" +
+ " - <*>\n" +
+ "more: stuff\n"
+ );
+ }
+
+ @Ignore @Test public void testContentAssistPropertyWithPojoType() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+
+ //Try in-place completion
+ assertCompletion(
+ "foo.d<*>"
+ ,
+ "foo:\n" +
+ " data:\n" +
+ " <*>"
+ );
+
+ //Try 'elsewhere' completion
+ assertCompletion(
+ "foo:\n" +
+ " something:\n" +
+ "more: stuff\n" +
+ "foo.d<*>"
+ ,
+ "foo:\n" +
+ " something:\n" +
+ " data:\n" +
+ " <*>\n" +
+ "more: stuff\n"
+ );
+ }
+
+ @Ignore @Test public void testContentAssistPropertyWithEnumType() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+
+ //Try in-place completion
+ assertCompletion(
+ "foo.co<*>"
+ ,
+ "foo:\n" +
+ " color: <*>"
+ );
+
+ //Try 'elsewhere' completion
+ assertCompletion(
+ "foo:\n" +
+ " something:\n" +
+ "more: stuff\n" +
+ "foo.co<*>"
+ ,
+ "foo:\n" +
+ " something:\n" +
+ " color: <*>\n" +
+ "more: stuff\n"
+ );
+ }
+
+ @Ignore @Test public void testCompletionForExistingGlobalPropertiesAreDemoted() throws Exception {
+ data("foo.bar", "java.lang.String", null, null);
+ data("foo.buttar", "java.lang.String", null, null);
+ data("foo.baracks", "java.lang.String", null, null);
+ data("foo.zamfir", "java.lang.String", null, null);
+ assertCompletions(
+ "foo:\n" +
+ " bar: nice\n" +
+ " baracks: full\n" +
+ "something:\n" +
+ " in: between\n"+
+ "bar<*>",
+ //=>
+ // buttar
+ "foo:\n" +
+ " bar: nice\n" +
+ " baracks: full\n" +
+ " buttar: <*>\n" +
+ "something:\n" +
+ " in: between",
+ // bar (already existed so becomes navigation)
+ "foo:\n" +
+ " bar: <*>nice\n" +
+ " baracks: full\n" +
+ "something:\n" +
+ " in: between",
+ // baracks (already existed so becomes navigation)
+ "foo:\n" +
+ " bar: nice\n" +
+ " baracks: <*>full\n" +
+ "something:\n" +
+ " in: between"
+ );
+ }
+
+ @Ignore @Test public void testCompletionForExistingBeanPropertiesAreDemoted() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+ assertCompletions(
+ "foo:\n" +
+ " data:\n" +
+ " children:\n" +
+ " -\n" +
+ " name: foo\n" +
+ " <*>",
+ ///// non-existing ///
+ //color-children
+ "foo:\n" +
+ " data:\n" +
+ " children:\n" +
+ " -\n" +
+ " name: foo\n" +
+ " color-children:\n"+
+ " <*>",
+ //funky
+ "foo:\n" +
+ " data:\n" +
+ " children:\n" +
+ " -\n" +
+ " name: foo\n" +
+ " funky: <*>",
+ //mapped-children
+ "foo:\n" +
+ " data:\n" +
+ " children:\n" +
+ " -\n" +
+ " name: foo\n" +
+ " mapped-children:\n"+
+ " <*>",
+ //nested
+ "foo:\n" +
+ " data:\n" +
+ " children:\n" +
+ " -\n" +
+ " name: foo\n" +
+ " nested:\n"+
+ " <*>",
+ //next
+ "foo:\n" +
+ " data:\n" +
+ " children:\n" +
+ " -\n" +
+ " name: foo\n" +
+ " next: <*>",
+ //tags
+ "foo:\n" +
+ " data:\n" +
+ " children:\n" +
+ " -\n" +
+ " name: foo\n" +
+ " tags:\n" +
+ " - <*>",
+ //wavelen
+ "foo:\n" +
+ " data:\n" +
+ " children:\n" +
+ " -\n" +
+ " name: foo\n" +
+ " wavelen: <*>",
+ ///// existing ////
+ //children
+ "foo:\n" +
+ " data:\n" +
+ " children:\n" +
+ " <*>-\n" +
+ " name: foo",
+ //name
+ "foo:\n" +
+ " data:\n" +
+ " children:\n" +
+ " -\n" +
+ " name: <*>foo"
+ );
+ }
+
+ @Ignore @Test public void testNoCompletionsInsideComments() throws Exception {
+ defaultTestData();
+
+ //Ensure this test is not trivially passing because of missing test data
+ assertCompletion(
+ "po<*>"
+ ,
+ "server:\n"+
+ " port: <*>"
+ );
+
+ assertNoCompletions(
+ "#po<*>"
+ );
+ }
+
+ @Ignore @Test public void testCompletionsFromDeeplyNestedNode() throws Exception {
+ String[] names = {"foo", "nested", "bar"};
+ int levels = 4;
+ generateNestedProperties(levels, names, "");
+
+ assertCompletionCount(81, // 3^4
+ "<*>"
+ );
+
+ assertCompletionCount(27, // 3^3
+ "#comment\n" +
+ "foo:\n" +
+ " <*>"
+ );
+
+ assertCompletionCount( 9, // 3^2
+ "#comment\n" +
+ "foo:\n" +
+ " bar: <*>"
+ );
+
+ assertCompletionCount( 3,
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ " <*>"
+ );
+
+ assertCompletionCount( 9,
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ " <*>"
+ );
+
+ assertCompletionCount(27,
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ " <*>"
+ );
+
+ assertCompletionCount(81,
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ "<*>"
+ );
+
+
+ assertCompletion(
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ " <*>"
+ ,
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ " bar: <*>"
+ );
+
+ assertCompletion(
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ " <*>"
+ ,
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ " bar:\n" +
+ " bar: <*>"
+ );
+
+ assertCompletion(
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ " <*>"
+ ,
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ " bar:\n" +
+ " bar: <*>\n" +
+ " "
+ );
+
+ assertCompletion(
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ "<*>"
+ ,
+ "#comment\n" +
+ "foo:\n" +
+ " bar:\n"+
+ " nested:\n" +
+ "bar:\n" +
+ " bar:\n" +
+ " bar:\n" +
+ " bar: <*>"
+ );
+ }
+
+ @Ignore @Test public void testInsertCompletionIntoDeeplyNestedNode() throws Exception {
+ String[] names = {"foo", "nested", "bar"};
+ int levels = 4;
+ generateNestedProperties(levels, names, "");
+
+ assertCompletion(
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ "bar.foo.nested.b<*>"
+ ,
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ "bar:\n" +
+ " foo:\n" +
+ " nested:\n" +
+ " bar: <*>"
+ );
+
+ assertCompletion(
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ "other:\n" +
+ "foo.foo.nested.b<*>"
+ ,
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ " foo:\n" +
+ " nested:\n" +
+ " bar: <*>\n" +
+ "other:\n"
+ );
+
+ assertCompletion(
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ "foo.foo.nested.b<*>"
+ ,
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ " foo:\n" +
+ " nested:\n" +
+ " bar: <*>"
+ );
+
+ assertCompletion(
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ "other:\n" +
+ "foo.nested.nested.b<*>"
+ ,
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ " nested:\n" +
+ " bar: <*>\n"+
+ "other:\n"
+ );
+
+ assertCompletion(
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ "foo.nested.nested.b<*>"
+ ,
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ " nested:\n" +
+ " bar: <*>\n"
+ );
+
+ assertCompletion(
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ "other:\n" +
+ "foo.nested.bar.b<*>"
+ ,
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ " bar: <*>\n" +
+ "other:\n"
+ );
+
+ assertCompletion(
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ "foo.nested.bar.b<*>"
+ ,
+ "foo:\n" +
+ " nested:\n" +
+ " bar:\n" +
+ " foo:\n" +
+ " bar: <*>\n"
+ );
+
+ }
+
+ @Ignore @Test public void testBooleanValueCompletion() throws Exception {
+ defaultTestData();
+ assertCompletions(
+ "liquibase:\n" +
+ " enabled: <*>",
+ "liquibase:\n" +
+ " enabled: false<*>",
+ "liquibase:\n" +
+ " enabled: true<*>"
+ );
+
+ assertCompletions(
+ "liquibase:\n" +
+ " enabled:\n" +
+ " <*>",
+ "liquibase:\n" +
+ " enabled:\n" +
+ " false<*>",
+ "liquibase:\n" +
+ " enabled:\n" +
+ " true<*>"
+ );
+
+ assertCompletions(
+ "liquibase:\n" +
+ " enabled: f<*>\n",
+ "liquibase:\n" +
+ " enabled: false<*>\n"
+ );
+
+ assertCompletions(
+ "liquibase:\n" +
+ " enabled: t<*>\n",
+ "liquibase:\n" +
+ " enabled: true<*>\n"
+ );
+
+ assertCompletions(
+ "liquibase:\n" +
+ " enabled:\n" +
+ " f<*>\n",
+ "liquibase:\n" +
+ " enabled:\n"+
+ " false<*>\n"
+ );
+
+ assertCompletions(
+ "liquibase:\n" +
+ " enabled:\n" +
+ " t<*>\n",
+ "liquibase:\n" +
+ " enabled:\n"+
+ " true<*>\n"
+ );
+
+ // booleans can also be completed in upper case?
+ assertCompletions(
+ "liquibase:\n" +
+ " enabled:\n" +
+ " T<*>\n",
+ "liquibase:\n" +
+ " enabled:\n" +
+ " TRUE<*>\n"
+ );
+
+ assertCompletions(
+ "liquibase:\n" +
+ " enabled:\n" +
+ " F<*>\n",
+ "liquibase:\n" +
+ " enabled:\n" +
+ " FALSE<*>\n"
+ );
+
+ //Dont suggest completion for something that's already complete. Causes odd
+ // and annoying behavior, like a completion popup after you stopped typing 'true'
+ assertNoCompletions(
+ "liquibase:\n" +
+ " enabled:\n" +
+ " true<*>"
+ );
+
+ //one more... for special char like '-' in the name
+
+ assertCompletions(
+ "liquibase:\n" +
+ " check-change-log-location: t<*>",
+ "liquibase:\n" +
+ " check-change-log-location: true<*>"
+ );
+
+ assertCompletions(
+ "liquibase:\n" +
+ " enabled:<*>",
+ "liquibase:\n" +
+ " enabled: false<*>",
+ "liquibase:\n" +
+ " enabled: true<*>"
+ );
+
+
+ }
+
+ @Ignore @Test public void testEnumValueCompletion() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+ data("foo.color", "demo.Color", null, "A foonky colour");
+
+ assertCompletion("foo.c<*>",
+ "foo:\n" +
+ " color: <*>" //Should complete on same line because enums are 'simple' values.
+ );
+
+ assertCompletion("foo:\n color: R<*>", "foo:\n color: RED<*>");
+ assertCompletion("foo:\n color: G<*>", "foo:\n color: GREEN<*>");
+ assertCompletion("foo:\n color: B<*>", "foo:\n color: BLUE<*>");
+
+ assertCompletion("foo:\n color: r<*>", "foo:\n color: red<*>");
+ assertCompletion("foo:\n color: g<*>", "foo:\n color: green<*>");
+ assertCompletion("foo:\n color: b<*>", "foo:\n color: blue<*>");
+
+ assertCompletionsDisplayString("foo:\n color: <*>",
+ "red", "green", "blue"
+ );
+ }
+
+ @Ignore @Test public void testEnumMapValueCompletion() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+
+ assertCompletions(
+ "foo:\n" +
+ " nam<*>",
+ //==>
+ "foo:\n" +
+ " name-colors:\n"+
+ " <*>",
+ // or
+ "foo:\n" +
+ " color-names:\n"+
+ " <*>"
+ );
+ assertCompletionsDisplayString(
+ "foo:\n"+
+ " name-colors:\n" +
+ " something: <*>",
+ //=>
+ "red", "green", "blue"
+ );
+ assertCompletions(
+ "foo:\n"+
+ " name-colors:\n" +
+ " something: G<*>",
+ // =>
+ "foo:\n"+
+ " name-colors:\n" +
+ " something: GREEN<*>"
+ );
+ }
+
+ @Ignore @Test public void testEnumMapValueReconciling() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+ data("foo.name-colors", "java.util.Map", null, "Map with colors in its values");
+
+ Editor editor;
+
+ editor = newEditor(
+ "foo:\n"+
+ " name-colors:\n" +
+ " jacket: BLUE\n" +
+ " hat: RED\n" +
+ " pants: GREEN\n" +
+ " wrong: NOT_A_COLOR\n"
+ );
+ editor.assertProblems(
+ "NOT_A_COLOR|Color"
+ );
+
+ //lowercase enums should work too
+ editor = newEditor(
+ "foo:\n"+
+ " name-colors:\n" +
+ " jacket: blue\n" +
+ " hat: red\n" +
+ " pants: green\n" +
+ " wrong: NOT_A_COLOR\n"
+ );
+ editor.assertProblems(
+ "NOT_A_COLOR|Color"
+ );
+ }
+
+ @Ignore @Test public void testEnumMapKeyCompletion() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+
+ data("foo.color-names", "java.util.Map", null, "Map with colors in its keys");
+ data("foo.color-data", "java.util.Map", null, "Map with colors in its keys, and pojo in values");
+
+ //Map Enum -> String:
+ assertCompletions("foo:\n colnam<*>",
+ "foo:\n" +
+ " color-names:\n" +
+ " <*>");
+ assertCompletions(
+ "foo:\n" +
+ " color-names:\n" +
+ " <*>",
+ //=>
+ "foo:\n" +
+ " color-names:\n" +
+ " blue: <*>",
+ "foo:\n" +
+ " color-names:\n" +
+ " green: <*>",
+ "foo:\n" +
+ " color-names:\n" +
+ " red: <*>"
+ );
+
+ assertCompletionsDisplayString(
+ "foo:\n" +
+ " color-names:\n" +
+ " <*>",
+ //=>
+ "blue : String", "green : String", "red : String"
+ );
+
+ assertCompletions(
+ "foo:\n" +
+ " color-names:\n" +
+ " B<*>",
+ "foo:\n" +
+ " color-names:\n" +
+ " BLUE: <*>"
+ );
+
+ //Map Enum -> Pojo:
+ assertCompletions("foo.coldat<*>",
+ "foo:\n" +
+ " color-data:\n" +
+ " <*>");
+ assertCompletions(
+ "foo:\n" +
+ " color-data:\n" +
+ " <*>",
+ // =>
+ "foo:\n" +
+ " color-data:\n" +
+ " blue:\n" +
+ " <*>",
+ "foo:\n" +
+ " color-data:\n" +
+ " green:\n" +
+ " <*>",
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " <*>"
+ );
+ assertCompletions(
+ "foo:\n" +
+ " color-data:\n" +
+ " B<*>",
+ //=>
+ "foo:\n" +
+ " color-data:\n" +
+ " BLUE:\n" +
+ " <*>"
+ );
+
+ assertCompletions(
+ "foo:\n" +
+ " color-data:\n" +
+ " b<*>",
+ //=>
+ "foo:\n" +
+ " color-data:\n" +
+ " blue:\n" +
+ " <*>"
+ );
+
+ assertCompletions(
+ "foo:\n" +
+ " color-data: b<*>",
+ //=>
+ "foo:\n" +
+ " color-data: \n" +
+ " blue:\n" +
+ " <*>"
+ );
+
+ assertCompletionsDisplayString(
+ "foo:\n" +
+ " color-data:\n" +
+ " <*>",
+ "red : demo.ColorData", "green : demo.ColorData", "blue : demo.ColorData"
+ );
+
+ assertCompletionsDisplayString(
+ "foo:\n" +
+ " color-data: <*>\n",
+ "red : demo.ColorData", "green : demo.ColorData", "blue : demo.ColorData"
+ );
+
+ }
+
+ @Ignore @Test public void testPojoReconciling() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+
+ Editor editor = newEditor(
+ "foo:\n" +
+ " data:\n" +
+ " bogus: Something\n" +
+ " wavelen: 3.0\n" +
+ " wavelen: not a double\n" +
+ " wavelen:\n"+
+ " more: 3.0\n"+
+ " wavelen:\n" +
+ " - 3.0\n"
+ );
+ editor.assertProblems(
+ "bogus|Unknown property",
+ "wavelen|Duplicate",
+ "wavelen|Duplicate",
+ "not a double|'double'",
+ "wavelen|Duplicate",
+ "more: 3.0|Expecting a 'double' but got a 'Mapping' node",
+ "wavelen|Duplicate",
+ "- 3.0|Expecting a 'double' but got a 'Sequence' node"
+ );
+ }
+
+
+ @Ignore @Test public void testListOfAtomicCompletions() throws Exception {
+ data("foo.slist", "java.util.List", null, "list of strings");
+ data("foo.ulist", "java.util.List", null, "list of strings");
+ data("foo.dlist", "java.util.List", null, "list of doubles");
+ assertCompletions("foo:\n u<*>",
+ "foo:\n" +
+ " ulist:\n" +
+ " - <*>");
+ assertCompletions("foo:\n d<*>",
+ "foo:\n" +
+ " dlist:\n" +
+ " - <*>");
+ assertCompletions("foo:\n sl<*>",
+ "foo:\n"+
+ " slist:\n" +
+ " - <*>");
+ }
+
+ @Ignore @Test public void testEnumsInLowerCaseReconciling() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+
+ data("simple.pants.size", "demo.ClothingSize", null, "The simple pant's size");
+
+ Editor editor = newEditor(
+ "simple:\n" +
+ " pants:\n"+
+ " size: NOT_A_SIZE\n"+
+ " size: EXTRA_SMALL\n"+
+ " size: extra-small\n"+
+ " size: small\n"+
+ " size: SMALL\n"
+ );
+ editor.assertProblems(
+ "size|Duplicate",
+ "NOT_A_SIZE|ClothingSize",
+ "size|Duplicate",
+ "size|Duplicate",
+ "size|Duplicate",
+ "size|Duplicate"
+ );
+
+ editor = newEditor(
+ "foo:\n" +
+ " color-names:\n"+
+ " red: Rood\n"+
+ " green: Groen\n"+
+ " blue: Blauw\n" +
+ " not-a-color: Wrong\n" +
+ " blue.bad: Blauw\n" +
+ " blue:\n" +
+ " bad: Blauw"
+ );
+ editor.assertProblems(
+ "blue|Duplicate",
+ "not-a-color|Color",
+ "blue.bad|Color",
+ "blue|Duplicate",
+ "bad: Blauw|Expecting a 'String' but got a 'Mapping'"
+ );
+
+ editor = newEditor(
+ "foo:\n" +
+ " color-data:\n"+
+ " red:\n" +
+ " next: green\n" +
+ " next: not a color\n" +
+ " bogus: green\n" +
+ " name: Rood\n"
+ );
+ editor.assertProblems(
+ "next|Duplicate",
+ "next|Duplicate",
+ "not a color|Color",
+ "bogus|Unknown property"
+ );
+ }
+
+ @Ignore @Test public void testEnumsInLowerCaseContentAssist() throws Exception {
+ TestProject p = createPredefinedMavenProject("demo-enum");
+ useProject(p);
+ assertNotNull(p.findType("demo.ClothingSize"));
+
+ data("simple.pants.size", "demo.ClothingSize", null, "The simple pant's size");
+
+ assertCompletions(
+ "simple:\n" +
+ " pants:\n"+
+ " size: S<*>",
+ "simple:\n" +
+ " pants:\n"+
+ " size: SMALL<*>",
+ "simple:\n" +
+ " pants:\n"+
+ " size: EXTRA_SMALL<*>"
+ );
+
+ assertCompletions(
+ "simple:\n" +
+ " pants:\n"+
+ " size: s<*>",
+ "simple:\n" +
+ " pants:\n"+
+ " size: small<*>",
+ "simple:\n" +
+ " pants:\n"+
+ " size: extra-small<*>"
+ );
+
+ assertCompletions(
+ "simple:\n" +
+ " pants:\n"+
+ " size: ex<*>",
+ // =>
+ "simple:\n" +
+ " pants:\n"+
+ " size: extra-large<*>",
+ // or
+ "simple:\n" +
+ " pants:\n"+
+ " size: extra-small<*>"
+ );
+
+ assertCompletions(
+ "simple:\n" +
+ " pants:\n"+
+ " size: EX<*>",
+ // =>
+ "simple:\n" +
+ " pants:\n"+
+ " size: EXTRA_LARGE<*>",
+ // or
+ "simple:\n" +
+ " pants:\n"+
+ " size: EXTRA_SMALL<*>"
+ );
+
+ assertCompletionsDisplayString("foo:\n color: <*>", "red", "green", "blue");
+
+ assertCompletions("foo:\n color-data: B<*>", "foo:\n color-data: \n BLUE:\n <*>");
+ assertCompletions("foo:\n color-data: b<*>", "foo:\n color-data: \n blue:\n <*>");
+ assertCompletions("foo:\n color-data: <*>",
+ "foo:\n color-data: \n blue:\n <*>",
+ "foo:\n color-data: \n green:\n <*>",
+ "foo:\n color-data: \n red:\n <*>"
+ );
+
+ assertCompletions(
+ "foo:\n"+
+ " color-data:\n"+
+ " red: na<*>",
+ "foo:\n"+
+ " color-data:\n"+
+ " red: \n"+
+ " name: <*>"
+ );
+ }
+
+ @Ignore @Test public void testPojoInListCompletion() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+
+ assertCompletion(
+ "foo:\n" +
+ " color-data:\n" +
+ " red: chi<*>"
+ ,// =>
+ "foo:\n" +
+ " color-data:\n" +
+ " red: \n" +
+ " children:\n" +
+ " - <*>"
+ );
+
+ assertCompletions(
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - nex<*>",
+ // =>
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - next: <*>"
+ );
+
+ assertCompletions(
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - nes<*>",
+ // =>
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - nested:\n"+
+ " <*>"
+ );
+
+ assertCompletions(
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - nex<*>",
+ // =>
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - next: <*>"
+ );
+
+ assertCompletions(
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - nes<*>",
+ // =>
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - nested:\n"+
+ " <*>"
+ );
+
+ assertCompletions(
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - next: RED\n" +
+ " wav<*>",
+ // =>
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - next: RED\n" +
+ " wavelen: <*>"
+ );
+
+ assertCompletions(
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - next: RED\n" +
+ " wav<*>",
+ // =>
+ "foo:\n" +
+ " color-data:\n" +
+ " red:\n" +
+ " children:\n" +
+ " - next: RED\n" +
+ " wavelen: <*>"
+ );
+ }
+
+ @Ignore @Test public void test_STS4111_NoEmptyLinesGapBeforeInsertedCompletion() throws Exception {
+ data("spring.application.name", "java.lang.String", null, "The name of the application");
+ data("spring.application.index", "java.lang.Integer", true, "App instance index");
+ data("spring.considerable.fun", "java.lang.Boolean", true, "Whether the spring fun is considerable");
+
+ assertCompletions(
+ "spring:\n" +
+ " application:\n" +
+ " index: 12\n" +
+ "\n" +
+ "server:\n" +
+ " port: 8888\n" +
+ "appname<*>"
+ , //=>
+ "spring:\n" +
+ " application:\n" +
+ " index: 12\n" +
+ " name: <*>\n" +
+ "\n" +
+ "server:\n" +
+ " port: 8888"
+
+ );
+
+ //Also test that:
+ // - Fully commented lines also count as gaps
+ // - Gaps of more than one line are also handled correctly
+ assertCompletions(
+ "# spring stuff\n" +
+ "spring:\n" +
+ " application:\n" +
+ " index: 12\n" +
+ "\n" +
+ "#server stuff\n" +
+ "server:\n" +
+ " port: 8888\n" +
+ "cfun<*>"
+ , //=>
+ "# spring stuff\n" +
+ "spring:\n" +
+ " application:\n" +
+ " index: 12\n" +
+ " considerable:\n" +
+ " fun: <*>\n" +
+ "\n" +
+ "#server stuff\n" +
+ "server:\n" +
+ " port: 8888"
+
+ );
+
+ }
+
+ @Ignore @Test public void testDocumentSeparator() throws Exception {
+ defaultTestData();
+
+ assertCompletion(
+ "flyway:\n" +
+ " encoding: utf8\n" +
+ "---\n" +
+ "flyena<*>",
+ // =>
+ "flyway:\n" +
+ " encoding: utf8\n" +
+ "---\n" +
+ "flyway:\n" +
+ " enabled: <*>"
+ );
+ }
+
+ @Ignore @Test public void testMultiProfileYamlReconcile() throws Exception {
+ Editor editor;
+ //See https://issuetracker.springsource.com/browse/STS-4144
+ defaultTestData();
+
+ //Narrowly focussed test-case for easier debugging
+ editor = newEditor(
+ "spring:\n" +
+ " profiles: seven\n"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ //More complete test
+ editor = newEditor(
+ "spring:\n" +
+ " profiles: seven\n" +
+ "server:\n" +
+ " port: 7777\n" +
+ "---\n" +
+ "spring:\n" +
+ " profiles: eight\n" +
+ "server:\n" +
+ " port: 8888\n"+
+ "bogus: bad"
+ );
+ editor.assertProblems(
+ "bogus|Unknown property"
+ );
+ }
+
+ @Ignore @Test public void testReconcileArrayOfPrimitiveType() throws Exception {
+ data("my.array", "int[]", null, "A primitive array");
+ data("my.boxarray", "int[]", null, "An array of boxed primitives");
+ data("my.list", "java.util.List", null, "A list of boxed types");
+
+ Editor editor = newEditor(
+ "my:\n" +
+ " array:\n" +
+ " - 777\n" +
+ " - bad\n" +
+ " - 888"
+ );
+ editor.assertProblems(
+ "bad|Expecting a 'int'"
+ );
+
+ editor = newEditor(
+ "my:\n" +
+ " boxarray:\n" +
+ " - 777\n" +
+ " - bad\n" +
+ " - 888"
+ );
+ editor.assertProblems(
+ "bad|Expecting a 'int'"
+ );
+
+ editor = newEditor(
+ "my:\n" +
+ " list:\n" +
+ " - 777\n" +
+ " - bad\n" +
+ " - 888"
+ );
+ editor.assertProblems(
+ "bad|Expecting a 'int'"
+ );
+ }
+
+ @Ignore @Test public void test_STS4231() throws Exception {
+ //Should the 'predefined' project need to be recreated... use the commented code below:
+// BootProjectTestHarness projectHarness = new BootProjectTestHarness(ResourcesPlugin.getWorkspace());
+// TestProject project = projectHarness.createBootProject("sts-4231",
+// bootVersionAtLeast("1.3.0"),
+// withStarters("web", "cloud-config-server")
+// );
+
+ //For more robust test use predefined project which is not so much a moving target:
+ TestProject project = createPredefinedMavenProject("sts-4231");
+ useProject(project);
+
+ assertCompletionsDisplayString(
+ "info:\n" +
+ " component: Config Server\n" +
+ "spring:\n" +
+ " application:\n" +
+ " name: configserver\n" +
+ " jmx:\n" +
+ " default-domain: cloud.config.server\n" +
+ " cloud:\n" +
+ " config:\n" +
+ " server:\n" +
+ " git:\n" +
+ " uri: https://github.com/spring-cloud-samples/config-repo\n" +
+ " repos:\n" +
+ " my-repo:\n" +
+ " <*>\n",
+ // ==>
+ "name : String",
+ "pattern : String[]"
+ );
+
+ assertCompletion(
+ "info:\n" +
+ " component: Config Server\n" +
+ "spring:\n" +
+ " application:\n" +
+ " name: configserver\n" +
+ " jmx:\n" +
+ " default-domain: cloud.config.server\n" +
+ " cloud:\n" +
+ " config:\n" +
+ " server:\n" +
+ " git:\n" +
+ " uri: https://github.com/spring-cloud-samples/config-repo\n" +
+ " repos:\n" +
+ " my-repo:\n" +
+ " p<*>\n",
+ // ==>
+ "info:\n" +
+ " component: Config Server\n" +
+ "spring:\n" +
+ " application:\n" +
+ " name: configserver\n" +
+ " jmx:\n" +
+ " default-domain: cloud.config.server\n" +
+ " cloud:\n" +
+ " config:\n" +
+ " server:\n" +
+ " git:\n" +
+ " uri: https://github.com/spring-cloud-samples/config-repo\n" +
+ " repos:\n" +
+ " my-repo:\n" +
+ " pattern:\n" +
+ " - <*>\n"
+ );
+
+ }
+
+ @Ignore @Test public void test_STS_4254_MapStringObjectReconciling() throws Exception {
+ Editor editor;
+ data("info", "java.util.Map", null, "Info for the actuator's info endpoint.");
+
+ editor = newEditor(
+ "info: not-a-map\n"
+ );
+ editor.assertProblems(
+ "not-a-map|Expecting a 'Map'"
+ );
+
+ editor= newEditor(
+ "info:\n" +
+ " build: \n" +
+ " artifact: foo-bar\n"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ editor= newEditor(
+ "info:\n" +
+ " more: \n" +
+ " deeply:\n" +
+ " nested: foo-bar\n"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ editor= newEditor(
+ "booger: Bad\n" +
+ "info:\n" +
+ " akey: avalue\n"
+ );
+ editor.assertProblems(
+ "booger|Unknown property"
+ );
+ }
+
+ @Ignore @Test public void test_STS_4254_MapStringStringReconciling() throws Exception {
+ Editor editor;
+ data("info", "java.util.Map", null, "Info for the actuator's info endpoint.");
+
+ editor= newEditor(
+ "info:\n" +
+ " build: \n" +
+ " artifact: foo-bar\n"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ editor= newEditor(
+ "info:\n" +
+ " more: \n" +
+ " deeply:\n" +
+ " nested: foo-bar\n"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ editor= newEditor(
+ "booger: Bad\n" +
+ "info:\n" +
+ " akey: avalue\n"
+ );
+ editor.assertProblems(
+ "booger|Unknown property"
+ );
+
+ }
+
+ @Ignore @Test public void test_STS_4254_MapStringIntegerReconciling() throws Exception {
+ Editor editor;
+ data("info", "java.util.Map", null, "Info for the actuator's info endpoint.");
+
+ editor= newEditor(
+ "info:\n" +
+ " build: \n" +
+ " foo-bar\n"
+ );
+ editor.assertProblems(
+ "foo-bar|Expecting a 'int'"
+ );
+
+ editor= newEditor(
+ "info:\n" +
+ " build: 123\n"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ editor= newEditor(
+ "info:\n" +
+ " build: \n" +
+ " number: 123\n"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ editor= newEditor(
+ "info:\n" +
+ " build: \n" +
+ " artifact: abc\n"
+ );
+ editor.assertProblems(
+ "abc|Expecting a 'int'"
+ );
+
+ //A more complex example for good measure
+ editor= newEditor(
+ "info:\n" +
+ " some: \n" +
+ " nested: foo\n" +
+ " and: bar\n" +
+ " or: 444\n" +
+ " also: bad\n"
+ );
+ editor.assertProblems(
+ "foo|Expecting a 'int'",
+ "bar|Expecting a 'int'",
+ "bad|Expecting a 'int'"
+ );
+ }
+
+ @Ignore @Test public void testDeprecatedReconcileProperty() throws Exception {
+ data("error.path", "java.lang.String", null, "Path of the error controller.");
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "error:\n"+
+ " path: foo\n"
+ );
+
+ deprecate("error.path", "server.error.path", null);
+ editor.assertProblems(
+ "path|'error.path' is Deprecated: Use 'server.error.path'"
+ //no other problems
+ );
+
+ deprecate("error.path", "server.error.path", "This is old.");
+ editor.assertProblems(
+ "path|'error.path' is Deprecated: Use 'server.error.path' instead. Reason: This is old."
+ //no other problems
+ );
+
+ deprecate("error.path", null, "This is old.");
+ editor.assertProblems(
+ "path|'error.path' is Deprecated: This is old."
+ //no other problems
+ );
+
+ deprecate("error.path", null, null);
+ editor.assertProblems(
+ "path|'error.path' is Deprecated!"
+ //no other problems
+ );
+ }
+
+ @Ignore @Test public void testDeprecatedPropertyCompletion() throws Exception {
+ data("error.path", "java.lang.String", null, "Path of the error controller.");
+ data("server.error.path", "java.lang.String", null, "Path of the error controller.");
+ deprecate("error.path", "server.error.path", "This is old.");
+ assertCompletionsDisplayString(
+ "errorpa<*>"
+ , // =>
+ "server.error.path : String", // should be first because it is not deprecated, even though it is not as good a pattern match
+ "error.path : String"
+ );
+ assertStyledCompletions("error.pa<*>",
+ StyledStringMatcher.plainFont("server.error.path : String"),
+ StyledStringMatcher.strikeout("error.path")
+ );
+ }
+
+ @Ignore @Test public void testDeprecatedPropertyHoverInfo() throws Exception {
+ data("error.path", "java.lang.String", null, "Path of the error controller.");
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "error:\n" +
+ " path: foo\n"
+ );
+
+ deprecate("error.path", "server.error.path", null);
+ editor.assertHoverContains("path", "error.path -> server.error.path");
+ editor.assertHoverContains("path", "Deprecated!");
+
+ deprecate("error.path", "server.error.path", "This is old.");
+ editor.assertHoverContains("path", "error.path -> server.error.path");
+ editor.assertHoverContains("path", "Deprecated: This is old");
+
+ deprecate("error.path", null, "This is old.");
+ editor.assertHoverContains("path", "Deprecated: This is old");
+
+ deprecate("error.path", null, null);
+ editor.assertHoverContains("path", "Deprecated!");
+ }
+
+ @Ignore @Test public void testDeprecatedBeanPropertyHoverInfo() throws Exception {
+ TestProject jp = createPredefinedMavenProject("demo");
+ useProject(jp);
+ data("foo", "demo.Deprecater", null, "A bean with deprecated property.");
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "foo:\n" +
+ " name: foo\n"
+ );
+
+ editor.assertHoverContains("name", "Deprecated!");
+ }
+
+ @Ignore @Test public void testDeprecatedBeanPropertyReconcile() throws Exception {
+ TestProject jp = createPredefinedMavenProject("demo");
+ useProject(jp);
+ data("foo", "demo.Deprecater", null, "A Bean with deprecated properties");
+
+ Editor editor = newEditor(
+ "# comment\n" +
+ "foo:\n" +
+ " name: Old faithfull\n" +
+ " new-name: New and fancy\n" +
+ " alt-name: alternate\n"
+ );
+ editor.assertProblems(
+ "name|Property 'name' of type 'demo.Deprecater' is Deprecated!",
+ "alt-name|Deprecated"
+ );
+
+ editor = newEditor(
+ "# comment\n" +
+ "foo:\n" +
+ " alt-name: alternate\n"
+ );
+ //check that message also contains reason and replacement infos.
+ editor.assertProblems(
+ "alt-name|Use 'something.else' instead"
+ );
+ editor.assertProblems(
+ "alt-name|No good anymore"
+ );
+
+
+ }
+
+ @Ignore @Test public void testDeprecatedBeanPropertyCompletions() throws Exception {
+ TestProject jp = createPredefinedMavenProject("demo");
+ useProject(jp);
+ data("foo", "demo.Deprecater", null, "A Bean with deprecated properties");
+
+ assertStyledCompletions(
+ "foo:\n" +
+ " nam<*>"
+ , // =>
+ StyledStringMatcher.plainFont("new-name : String"),
+ StyledStringMatcher.strikeout("name"),
+ StyledStringMatcher.strikeout("alt-name")
+ );
+ }
+
+ @Ignore @Test public void testDeprecatedPropertyQuickfixSimple() throws Exception {
+ //A simple case for starters. The path edits aren't too complicated since there's
+ //just the one property in the file and only the last part of the 'path' changes.
+ //So this is a simple 'in-place' edit.
+
+ data("my.old-name", "java.lang.String", null, "Old and deprecated name");
+ deprecate("my.old-name", "my.new-name", null);
+
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " old-name: foo\n"
+ );
+
+ Diagnostic problem = editor.assertProblem("old-name");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.new-name'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "my:\n"+
+ " new-name: foo\n"
+ );
+ }
+
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " old-name: foo\n" +
+ "your: stuff"
+ );
+
+ Diagnostic problem = editor.assertProblem("old-name");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.new-name'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "my:\n"+
+ " new-name: foo\n"+
+ "your: stuff"
+ );
+ }
+
+ { // Don't move prop if it doesn't need to be moved
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " old-name: foo\n" +
+ " other: bar\n"
+ );
+
+ Diagnostic problem = editor.assertProblem("old-name");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.new-name'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "my:\n"+
+ " new-name: foo\n" +
+ " other: bar\n"
+ );
+ }
+ }
+
+ @Ignore @Test public void testDeprecatedPropertyQuickfixMovingValue() throws Exception {
+ data("my.old-name", "java.lang.String", null, "Old and deprecated name");
+ deprecate("my.old-name", "your.new-name", null);
+
+ data("my.stuff", "java.lang.String", null, "Old and deprecated name");
+ deprecate("my.stuff", "my.for-sale.stuff", null);
+
+ data("my.long.path.with.many.pieces", "java.lang.String", null, "Old");
+ deprecate("my.long.path.with.many.pieces", "my.path.with.many.pieces", null);
+
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " long:\n"+
+ " path:\n"+
+ " with:\n"+
+ " many:\n"+
+ " pieces: foo\n"
+ );
+
+ Diagnostic problem = editor.assertProblem("pieces");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.path.with.many.pieces'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "my:\n" +
+ " path:\n"+
+ " with:\n"+
+ " many:\n"+
+ " pieces: foo"
+ );
+ }
+
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " long:\n"+
+ " path:\n"+
+ " with:\n"+
+ " many:\n"+
+ " cannot: remove this\n"+
+ " pieces: foo\n"
+ );
+
+ Diagnostic problem = editor.assertProblem("pieces");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.path.with.many.pieces'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "my:\n" +
+ " long:\n"+
+ " path:\n"+
+ " with:\n"+
+ " many:\n"+
+ " cannot: remove this\n"+
+ " path:\n"+
+ " with:\n"+
+ " many:\n"+
+ " pieces: foo"
+ );
+ }
+
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " stuff: foo\n"
+ );
+
+ Diagnostic problem = editor.assertProblem("stuff");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.for-sale.stuff'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "my:\n" +
+ " for-sale:\n"+
+ " stuff: foo"
+ );
+ }
+
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " old-name: foo\n"
+ );
+
+ Diagnostic problem = editor.assertProblem("old-name");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'your.new-name'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "your:\n"+
+ " new-name: foo"
+ );
+ }
+
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " old-name: foo\n" +
+ "your:\n" +
+ " goodies: nice"
+ );
+
+ Diagnostic problem = editor.assertProblem("old-name");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'your.new-name'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "your:\n"+
+ " goodies: nice\n"+
+ " new-name: foo"
+ );
+ }
+
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "your:\n" +
+ " goodies: nice\n" +
+ "my:\n" +
+ " other: stuff\n" +
+ " old-name: foo\n"
+ );
+
+ Diagnostic problem = editor.assertProblem("old-name");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'your.new-name'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "your:\n"+
+ " goodies: nice\n"+
+ " new-name: foo\n" +
+ "my:\n" +
+ " other: stuff"
+ );
+ }
+ }
+
+ @Ignore @Test public void testDeprecatedPropertyQuickfixMovingIndentedValue() throws Exception {
+ data("my.old-name", "java.lang.String", null, "Old and deprecated name");
+ deprecate("my.old-name", "your.new-name", null); //same indent level
+
+ data("my.stuff", "java.lang.String", null, "Old and deprecated name");
+ deprecate("my.stuff", "my.long.path.with.many.pieces", null); // deeper indent level
+
+ data("my.long.path.with.many.pieces", "java.lang.String", null, "Old");
+ deprecate("my.long.path.with.many.pieces", "short.path", null); //shallower level
+
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " long:\n"+
+ " path:\n"+
+ " with:\n"+
+ " many:\n"+
+ " pieces: >\n"+
+ " foo spread over\n"+
+ " several lines\n" +
+ " of text\n"+
+ "short:\n"+
+ " stuff: goes here\n"
+ );
+ Diagnostic problem = editor.assertProblem("pieces");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'short.path'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "short:\n"+
+ " stuff: goes here\n" +
+ " path: >\n" +
+ " foo spread over\n"+
+ " several lines\n" +
+ " of text\n"
+ );
+ }
+
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " long:\n"+
+ " bits: go here\n"+
+ " stuff: >\n" +
+ " foo spread over\n"+
+ " several lines\n" +
+ " of text\n"
+ );
+ Diagnostic problem = editor.assertProblem("stuff");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.long.path.with.many.pieces'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "my:\n" +
+ " long:\n"+
+ " bits: go here\n"+
+ " path:\n" +
+ " with:\n" +
+ " many:\n"+
+ " pieces: >\n" +
+ " foo spread over\n"+
+ " several lines\n" +
+ " of text"
+ );
+ }
+ {
+ Editor editor = newEditor(
+ "# a comment\n"+
+ "my:\n" +
+ " long:\n"+
+ " path:\n"+
+ " with:\n"+
+ " many:\n"+
+ " pieces:\n"+
+ "# some\n" +
+ " - foo spread over\n"+
+ " #confusing\n" +
+ " - several lines\n" +
+ " #comments\n" +
+ " - of text\n"+
+ "short:\n"+
+ " stuff: goes here\n"
+ );
+ Diagnostic problem = editor.assertProblem("pieces");
+ CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'short.path'");
+ editor.apply(fix);
+ editor.assertText(
+ "# a comment\n"+
+ "short:\n"+
+ " stuff: goes here\n" +
+ " path:\n" +
+ " # some\n" +
+ " - foo spread over\n"+
+ " #confusing\n" +
+ " - several lines\n" +
+ " #comments\n" +
+ " - of text\n"
+ );
+ }
+ }
+
+ @Ignore @Test public void testReconcileDuplicateProperties() throws Exception {
+ defaultTestData();
+ Editor editor = newEditor(
+ "spring:\n" +
+ " profiles: cloudfoundry\n" +
+ "spring: \n" +
+ " application:\n" +
+ " name: eureka"
+ );
+ editor.assertProblems(
+ "spring|Duplicate",
+ "spring|Duplicate"
+ );
+ }
+
+ @Ignore @Test public void testReconcileDuplicatePropertiesNested() throws Exception {
+ data("foo.person.name", "String", null, "Name of person");
+ data("foo.person.family", "String", null, "Family name of person");
+ Editor editor = newEditor(
+ "foo:\n" +
+ " person:\n" +
+ " name: Hohohoh\n" +
+ " person:\n" +
+ " family:\n"
+ );
+ editor.assertProblems(
+ "person|Duplicate",
+ "person|Duplicate"
+ );
+ }
+
+ @Ignore @Test public void testReconcileDuplicatePropertiesInBean() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+ data("some.color", "demo.ColorData", null, "Some info about a color.");
+ Editor editor = newEditor(
+ "some:\n" +
+ " color:\n" +
+ " name: RED\n" +
+ " name: GREEN\n"
+ );
+ editor.assertProblems(
+ "name|Duplicate",
+ "name|Duplicate"
+ );
+ }
+
+ @Ignore @Test public void testCharSetCompletions() throws Exception {
+ data("foobar.encoding", "java.nio.charset.Charset", null, "The charset-encoding to use for foobars");
+
+ assertCompletions(
+ "foobar:\n" +
+ " enco<*>"
+ , // ==>
+ "foobar:\n" +
+ " encoding: <*>"
+ );
+
+ assertCompletionWithLabel(
+ "foobar:\n" +
+ " encoding: UT<*>"
+ ,
+ "UTF-8"
+ ,
+ "foobar:\n" +
+ " encoding: UTF-8<*>"
+ );
+ }
+
+ @Ignore @Test public void testLocaleCompletions() throws Exception {
+ data("foobar.locale", "java.util.Locale", null, "The locale for foobars");
+
+ assertCompletions(
+ "foobar:\n" +
+ " loca<*>"
+ , // ==>
+ "foobar:\n" +
+ " locale: <*>"
+ );
+
+ assertCompletionWithLabel(
+ "foobar:\n" +
+ " locale: en<*>"
+ ,
+ "en_CA"
+ ,
+ "foobar:\n" +
+ " locale: en_CA<*>"
+ );
+ }
+
+ @Ignore @Test public void testMimeTypeCompletions() throws Exception {
+ data("foobar.mime", "org.springframework.util.MimeType", null, "The mimetype for foobars");
+
+ assertCompletions(
+ "foobar:\n" +
+ " mi<*>"
+ , // ==>
+ "foobar:\n" +
+ " mime: <*>"
+ );
+
+ assertCompletionWithLabel(
+ "foobar:\n" +
+ " mime: json<*>"
+ ,
+ "application/json; charset=utf-8"
+ ,
+ "foobar:\n" +
+ " mime: application/json; charset=utf-8<*>"
+ );
+ }
+
+ @Ignore @Test public void testPropertyValueHintCompletions() throws Exception {
+ //Test that 'value hints' work when property name is associated with 'value' hints.
+ // via boot metadata.
+ useProject(createPredefinedMavenProject("boot13"));
+
+ assertCompletionsDisplayString(
+ "spring:\n" +
+ " http:\n" +
+ " converters:\n" +
+ " preferred-json-mapper: <*>\n"
+ , //=>
+ "gson",
+ "jackson"
+ );
+ }
+
+ @Ignore @Test public void testPropertyListHintCompletions() throws Exception {
+ useProject(createPredefinedMavenProject("boot13"));
+
+ assertCompletion(
+ "management:\n" +
+ " health:\n" +
+ " status:\n" +
+ " ord<*>"
+ , //=>
+ "management:\n" +
+ " health:\n" +
+ " status:\n" +
+ " order:\n"+
+ " - <*>"
+ );
+
+ assertCompletionsDisplayString(
+ "management:\n" +
+ " health:\n" +
+ " status:\n" +
+ " order:\n" +
+ " - <*>"
+ , //=>
+ "DOWN",
+ "OUT_OF_SERVICE",
+ "UNKNOWN",
+ "UP"
+ );
+ }
+
+ @Ignore @Test public void testPropertyMapValueCompletions() throws Exception {
+ useProject(createPredefinedMavenProject("boot13"));
+
+ assertCompletionsDisplayString(
+ "logging:\n" +
+ " level:\n" +
+ " some.package: <*>"
+ , // =>
+ "trace",
+ "debug",
+ "info",
+ "warn",
+ "error",
+ "fatal",
+ "off"
+ );
+ }
+
+ @Ignore @Test public void testPropertyMapKeyCompletions() throws Exception {
+ useProject(createPredefinedMavenProject("boot13"));
+ assertCompletionWithLabel(
+ "logging:\n" +
+ " level:\n" +
+ " <*>"
+ , // =>
+ "root : String"
+ ,
+ "logging:\n" +
+ " level:\n" +
+ " root: <*>"
+ );
+ }
+
+ @Ignore @Test public void testEscapeStringValueStartingWithStar() throws Exception {
+ useProject(createPredefinedMavenProject("boot13"));
+ assertCompletions(
+ "endpoints:\n"+
+ " cors:\n"+
+ " allowed-headers: \n" +
+ " - <*>"
+ , // =>
+ "endpoints:\n"+
+ " cors:\n"+
+ " allowed-headers: \n" +
+ " - '*'<*>"
+ );
+ }
+
+ @Ignore @Test public void testEscapeStringValueWithAQuote() throws Exception {
+ data("foo.quote", "java.lang.String", null, "Character to used to surround quotes");
+ valueHints("foo.quote", "\"", "'", "`");
+
+ assertCompletions(
+ "foo:\n" +
+ " quote: <*>"
+ , // =>
+ "foo:\n" +
+ " quote: '\"'<*>"
+ ,
+ "foo:\n" +
+ " quote: ''''<*>"
+ ,
+ "foo:\n" +
+ " quote: '`'<*>"
+ );
+ }
+
+ @Ignore @Test public void testEscapeStringKeyWithAQuote() throws Exception {
+ data("foo.quote", "java.util.Map", null, "Name of quote characters");
+ keyHints("foo.quote", "\"", "'", "`");
+
+ assertCompletions(
+ "foo:\n" +
+ " quote: <*>"
+ , // =>
+ "foo:\n" +
+ " quote: \n"+
+ " '\"': <*>"
+ ,
+ "foo:\n" +
+ " quote: \n"+
+ " '''': <*>"
+ ,
+ "foo:\n" +
+ " quote: \n"+
+ " '`': <*>"
+ );
+ }
+
+ @Ignore @Test public void testLoggerNameCompletion() throws Exception {
+ CachingValueProvider.TIMEOUT = Duration.ofSeconds(20); // the provider can't be reliably tested if its not allowed to
+ // fetch all its values (even though in 'production' you
+ // wouldn't want it to block the UI thread for this long.
+ useProject(createPredefinedMavenProject("boot13"));
+ //Finds a package:
+ assertCompletionWithLabel(
+ "logging:\n" +
+ " level:\n" +
+ " boot.auto<*>"
+ , //-----------------
+ "org.springframework.boot.autoconfigure : String"
+ , // =>
+ "logging:\n" +
+ " level:\n" +
+ " org.springframework.boot.autoconfigure: <*>"
+ );
+
+ //Finds a type:
+ assertCompletionWithLabel(
+ "logging:\n" +
+ " level:\n" +
+ " MesgSource<*>"
+ , //-----------------
+ "org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration : String"
+ , // =>
+ "logging:\n" +
+ " level:\n" +
+ " org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration: <*>"
+ );
+ }
+
+ @Ignore @Test public void testSimpleResourceCompletion() throws Exception {
+ CachingValueProvider.TIMEOUT = Duration.ofSeconds(20);
+
+ useProject(createPredefinedMavenProject("boot13"));
+
+ data("my.nice.resource", "org.springframework.core.io.Resource", null, "A very nice resource.");
+
+ assertCompletion(
+ "my:\n" +
+ " nice:\n" +
+ " <*>\n"
+ ,// =>
+ "my:\n" +
+ " nice:\n" +
+ " resource: <*>\n"
+ );
+
+ assertCompletionsDisplayString(
+ "my:\n" +
+ " nice:\n" +
+ " resource: <*>\n"
+ , // =>
+ "classpath:",
+ "classpath*:",
+ "file:",
+ "http://",
+ "https://"
+ );
+
+ assertCompletionsDisplayString(
+ "my:\n" +
+ " nice:\n" +
+ " resource:\n" +
+ " <*>\n"
+ , // =>
+ "classpath:",
+ "classpath*:",
+ "file:",
+ "http://",
+ "https://"
+ );
+
+ }
+
+ @Ignore @Test public void testClasspathResourceCompletion() throws Exception {
+ CachingValueProvider.TIMEOUT = Duration.ofSeconds(20);
+
+ useProject(createPredefinedMavenProject("boot13"));
+
+ data("my.nice.resource", "org.springframework.core.io.Resource", null, "A very nice resource.");
+ data("my.nice.list", "java.util.List", null, "A nice list of resources.");
+
+ //Test 'simple key context'
+
+ assertCompletionsDisplayString(
+ "my:\n" +
+ " nice:\n" +
+ " resource: classpath:app<*>\n"
+ ,// =>
+ "classpath:application.properties",
+ "classpath:application.yml"
+ );
+
+ //Test 'list item' context:
+
+ assertCompletionsDisplayString(
+ "my:\n" +
+ " nice:\n" +
+ " list:\n"+
+ " - classpath:app<*>\n"
+ ,// =>
+ "classpath:application.properties",
+ "classpath:application.yml"
+ );
+
+ assertCompletionWithLabel(
+ "my:\n" +
+ " nice:\n" +
+ " list:\n"+
+ " - classpath:app<*>\n"
+ ,// ==========
+ "classpath:application.yml"
+ , // =>
+ "my:\n" +
+ " nice:\n" +
+ " list:\n"+
+ " - classpath:application.yml<*>\n"
+ );
+
+ assertCompletionWithLabel(
+ "my:\n" +
+ " nice:\n" +
+ " list:\n"+
+ " - classpath:<*>\n"
+ ,// ==========
+ "classpath:application.yml"
+ , // =>
+ "my:\n" +
+ " nice:\n" +
+ " list:\n"+
+ " - classpath:application.yml<*>\n"
+ );
+
+ //Test 'raw node' context
+
+ assertCompletionsDisplayString(
+ "my:\n" +
+ " nice:\n" +
+ " resource:\n"+
+ " classpath:app<*>\n"
+ ,// =>
+ "classpath:application.properties",
+ "classpath:application.yml"
+ );
+
+ assertCompletionWithLabel(
+ "my:\n" +
+ " nice:\n" +
+ " resource:\n"+
+ " classpath:app<*>\n"
+ ,//===============
+ "classpath:application.properties"
+ ,// =>
+ "my:\n" +
+ " nice:\n" +
+ " resource:\n"+
+ " classpath:application.properties<*>\n"
+ );
+
+ assertCompletionWithLabel(
+ "my:\n" +
+ " nice:\n" +
+ " resource:\n"+
+ " classpath:<*>\n"
+ ,//===============
+ "classpath:application.properties"
+ ,// =>
+ "my:\n" +
+ " nice:\n" +
+ " resource:\n"+
+ " classpath:application.properties<*>\n"
+ );
+
+ // do we find resources in sub-folders too?
+ assertCompletionWithLabel(
+ "my:\n" +
+ " nice:\n" +
+ " resource:\n"+
+ " classpath:word<*>\n"
+ ,//===============
+ "classpath:stuff/wordlist.txt"
+ ,// =>
+ "my:\n" +
+ " nice:\n" +
+ " resource:\n"+
+ " classpath:stuff/wordlist.txt<*>\n"
+ );
+ }
+
+ @Ignore @Test public void testClassReferenceCompletion() throws Exception {
+ CachingValueProvider.TIMEOUT = Duration.ofSeconds(20);
+
+ useProject(createPredefinedMavenProject("boot13_with_mongo"));
+
+ assertCompletion(
+ "spring:\n" +
+ " data:\n" +
+ " mongodb:\n" +
+ " field-na<*>"
+ , // =>
+ "spring:\n" +
+ " data:\n" +
+ " mongodb:\n" +
+ " field-naming-strategy: <*>"
+ );
+
+ assertCompletionsDisplayString(
+ "spring:\n" +
+ " data:\n" +
+ " mongodb:\n" +
+ " field-naming-strategy: <*>"
+ , // =>
+ "org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy",
+ "org.springframework.data.mapping.model.CamelCaseSplittingFieldNamingStrategy",
+ "org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy",
+ "org.springframework.data.mapping.model.SnakeCaseFieldNamingStrategy"
+ );
+
+ assertCompletionWithLabel(
+ "spring:\n" +
+ " data:\n" +
+ " mongodb:\n" +
+ " field-naming-strategy: <*>"
+ , //=====
+ "org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy"
+ , //=>
+ "spring:\n" +
+ " data:\n" +
+ " mongodb:\n" +
+ " field-naming-strategy: org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy<*>"
+ );
+
+ //Test what happens when 'target' type isn't on the classpath:
+ useProject(createPredefinedMavenProject("boot13"));
+ assertCompletionsDisplayString(
+ "spring:\n" +
+ " data:\n" +
+ " mongodb:\n" +
+ " field-naming-strategy: <*>"
+ // =>
+ /*NONE*/
+ );
+ }
+
+ @Ignore @Test public void testClassReferenceInValueLink() throws Exception {
+ Editor editor;
+ useProject(createPredefinedMavenProject("boot13_with_mongo"));
+
+ editor = newEditor(
+ "spring:\n" +
+ " data:\n" +
+ " mongodb:\n" +
+ " field-naming-strategy: org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy\n"
+ );
+ editor.assertLinkTargets("org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy", "org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy");
+
+ editor = newEditor(
+ "spring:\n" +
+ " data:\n" +
+ " mongodb:\n" +
+ " field-naming-strategy:\n" +
+ " org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy\n"
+ );
+ editor.assertLinkTargets("org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy", "org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy");
+
+ //Linking should also work for types that aren't valid based on the constraints
+ editor = newEditor(
+ "spring:\n" +
+ " data:\n" +
+ " mongodb:\n" +
+ " field-naming-strategy: java.lang.String\n" +
+ "#more stuff"
+ );
+ editor.assertLinkTargets("java.lang.String", "java.lang.String");
+ }
+
+ @Ignore @Test public void test_STS_3335_reconcile_list_nested_in_Map_of_String() throws Exception {
+ Editor editor;
+ useProject(createPredefinedMavenProject("demo-sts-4335"));
+
+ editor = newEditor(
+ "test-map:\n" +
+ " test-list-object:\n" +
+ " color-list:\n" +
+ " - not-a-color\n"+
+ " - RED\n" +
+ " - GREEN\n"
+ );
+ editor.assertProblems(
+ "not-a-color|Expecting a 'com.wellsfargo.lendingplatform.web.config.Color"
+ );
+
+ editor = newEditor(
+ "test-map:\n" +
+ " test-list-object:\n" +
+ " string-list:\n" +
+ " - abc\n" +
+ " - def\n"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ }
+
+
+ @Ignore @Test public void test_STS_3335_completions_list_nested_in_Map_of_String() throws Exception {
+ useProject(createPredefinedMavenProject("demo-sts-4335"));
+
+ assertCompletions(
+ "test-map:\n" +
+ " some-string-key:\n" +
+ " col<*>"
+ , // =>
+ "test-map:\n" +
+ " some-string-key:\n" +
+ " color-list:\n" +
+ " - <*>"
+ );
+
+ assertCompletionsDisplayString(
+ "test-map:\n" +
+ " some-string-key:\n" +
+ " color-list:\n" +
+ " - <*>"
+ , // =>
+ "red", "green", "blue"
+ );
+ }
+
+ @Ignore @Test public void testHandleAsResourceContentAssist() throws Exception {
+ //"name": "my.terms-and-conditions",
+ // "providers": [
+ // {
+ // "name": "handle-as",
+ // "parameters": {
+ // "target": "org.springframework.core.io.Resource"
+ // }
+ // }
+ // ]
+ data("my.terms-and-conditions", "java.lang.String", null, "Terms and Conditions text file")
+ .provider("handle-as", "target", "org.springframework.core.io.Resource");
+
+ assertCompletionsDisplayString(
+ "my:\n" +
+ " terms-and-conditions: <*>"
+ , // =>
+ "classpath:",
+ "classpath*:",
+ "file:",
+ "http://",
+ "https://"
+ );
+ }
+
+ @Ignore @Test public void testBootBug5905() throws Exception {
+ useProject(createPredefinedMavenProject("demo-with-resource-prop"));
+
+ //Check the metadata reflects the 'handle-as':
+ PropertyInfo metadata = getIndexProvider().getIndex(null).get("my.welcome.path");
+ assertEquals("org.springframework.core.io.Resource", metadata.getType());
+
+ //Check the content assist based on it works too:
+ assertCompletionsDisplayString(
+ "my:\n"+
+ " welcome:\n" +
+ " path: <*>"
+ , // =>
+ "classpath:",
+ "classpath*:",
+ "file:",
+ "http://",
+ "https://"
+ );
+ }
+
+ @Ignore @Test public void testEnumJavaDocShownInValueContentAssist() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+ data("my.background", "demo.Color", null, "Color to use as default background.");
+
+ assertCompletionWithInfoHover(
+ "my:\n" +
+ " background: <*>"
+ , // ==========
+ "red"
+ , // ==>
+ "Hot and delicious"
+ );
+ }
+
+ @Ignore @Test public void testEnumJavaDocShownInValueHover() throws Exception {
+ useProject(createPredefinedMavenProject("demo-enum"));
+ data("my.background", "demo.Color", null, "Color to use as default background.");
+
+ Editor editor;
+
+ editor = newEditor(
+ "my:\n" +
+ " background: red"
+ );
+ editor.assertHoverContains("red", "Hot and delicious");
+
+ editor = newEditor(
+ "my:\n" +
+ " background: RED"
+ );
+ editor.assertHoverContains("RED", "Hot and delicious");
+ }
+
+ @Ignore @Test public void testHyperLinkEnumValue() throws Exception {
+ Editor editor;
+ useProject(createPredefinedMavenProject("demo-enum"));
+ data("my.background", "demo.Color", null, "Color to use as default background.");
+
+ editor = newEditor(
+ "my:\n" +
+ " background: RED"
+ );
+ editor.assertLinkTargets("RED", "demo.Color.RED");
+
+ editor = newEditor(
+ "my:\n" +
+ " background: red"
+ );
+ editor.assertLinkTargets("red", "demo.Color.RED");
+ }
+
+ @Ignore @Test public void testHyperLinkEnumValueInMapKey() throws Exception {
+ Editor editor;
+ useProject(createPredefinedMavenProject("demo-enum"));
+ data("my.color.map", "java.util.Map", null, "Pretty names for the colors.");
+
+ editor = newEditor(
+ "my:\n" +
+ " color:\n" +
+ " map:\n" +
+ " RED: Rood\n" +
+ " green: Groen\n"
+ );
+ editor.assertLinkTargets("RED", "demo.Color.RED");
+ editor.assertLinkTargets("green", "demo.Color.GREEN");
+
+ editor = newEditor(
+ "spring:\n" +
+ " jackson:\n" +
+ " serialization:\n" +
+ " INDENT_OUTPUT: true"
+ );
+ editor.assertLinkTargets("INDENT_OUTPUT",
+ "com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT"
+ );
+
+ editor = newEditor(
+ "spring:\n" +
+ " jackson:\n" +
+ " serialization:\n" +
+ " indent-output: true"
+ );
+ editor.assertLinkTargets("indent-output",
+ "com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT"
+ );
+ }
+
+ ///////////////// cruft ////////////////////////////////////////////////////////
+
+ private void generateNestedProperties(int levels, String[] names, String prefix) {
+ if (levels==0) {
+ data(prefix, "java.lang.String", null, "Property "+prefix);
+ } else if (levels > 0) {
+ for (int i = 0; i < names.length; i++) {
+ generateNestedProperties(levels-1, names, join(prefix, names[i]));
+ }
+ }
+ }
+
+ private String join(String prefix, String string) {
+ if (StringUtil.hasText(prefix)) {
+ return prefix +"." + string;
+ }
+ return string;
+ }
+
}
diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/PropertyIndexHarness.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/PropertyIndexHarness.java
new file mode 100644
index 000000000..aee4bc943
--- /dev/null
+++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/PropertyIndexHarness.java
@@ -0,0 +1,547 @@
+package org.springframework.ide.vscode.yaml;
+
+import java.nio.file.Path;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
+import org.springframework.boot.configurationmetadata.Deprecation;
+import org.springframework.boot.configurationmetadata.ValueHint;
+import org.springframework.boot.configurationmetadata.ValueProvider;
+import org.springframework.ide.vscode.boot.properties.metadata.PropertyInfo;
+import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertyIndex;
+import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertyIndexProvider;
+import org.springframework.ide.vscode.boot.properties.metadata.ValueProviderRegistry;
+import org.springframework.ide.vscode.boot.properties.util.FuzzyMap;
+import org.springframework.ide.vscode.testharness.TestProject;
+import org.springframework.ide.vscode.util.IDocument;
+
+/**
+ * Provides some convenience apis for test code to create / use test data for a SpringPropertyIndex.
+ */
+public class PropertyIndexHarness {
+
+ private Map datas = new LinkedHashMap<>();
+ private ValueProviderRegistry valueProviders = ValueProviderRegistry.getDefault();
+ private SpringPropertyIndex index = null;
+ private TestProject testProject = null;
+
+ protected SpringPropertyIndexProvider indexProvider = new SpringPropertyIndexProvider() {
+ public FuzzyMap getIndex(IDocument doc) {
+ if (index==null) {
+ Path path = testProject == null ? null : testProject.getPath();
+ index = new SpringPropertyIndex(valueProviders, path);
+ for (ConfigurationMetadataProperty propertyInfo : datas.values()) {
+ index.add(propertyInfo);
+ }
+ }
+ return index;
+ }
+ };
+
+ public class ItemConfigurer {
+
+ private ConfigurationMetadataProperty item;
+
+ public ItemConfigurer(ConfigurationMetadataProperty item) {
+ this.item = item;
+ }
+
+ /**
+ * Add a provider with a single parameter.
+ * @return
+ */
+ public ItemConfigurer provider(String name, String paramName, Object paramValue) {
+ ValueProvider provider = new ValueProvider();
+ provider.setName(name);
+ provider.getParameters().put(paramName, paramValue);
+ item.getHints().getValueProviders().add(provider);
+ return this;
+ }
+
+ /**
+ * Add a value hint. If description contains a '.' the dot is used
+ * to break description into a short and long description.
+ * @return
+ */
+ public ItemConfigurer valueHint(Object value, String description) {
+ ValueHint hint = new ValueHint();
+ hint.setValue(value);
+ if (description!=null) {
+ int dotPos = description.indexOf('.');
+ if (dotPos>=0) {
+ hint.setShortDescription( description.substring(0, dotPos));
+ }
+ hint.setDescription(description);
+ }
+ item.getHints().getValueHints().add(hint);
+ return this;
+ }
+ }
+
+
+ public ItemConfigurer data(String id, String type, Object deflt, String description,
+ String... source
+ ) {
+ ConfigurationMetadataProperty item = new ConfigurationMetadataProperty();
+ item.setId(id);
+ item.setDescription(description);
+ item.setType(type);
+ item.setDefaultValue(deflt);
+ index = null;
+ datas.put(item.getId(), item);
+ return new ItemConfigurer(item);
+ }
+
+ public void keyHints(String id, String... hintValues) {
+ index = null;
+ List hints = datas.get(id).getHints().getKeyHints();
+ for (String value : hintValues) {
+ ValueHint hint = new ValueHint();
+ hint.setValue(value);
+ hints.add(hint);
+ }
+ }
+
+ public void valueHints(String id, String... hintValues) {
+ index = null;
+ List hints = datas.get(id).getHints().getValueHints();
+ for (String value : hintValues) {
+ ValueHint hint = new ValueHint();
+ hint.setValue(value);
+ hints.add(hint);
+ }
+ }
+
+ public void deprecate(String key, String replacedBy, String reason) {
+ index = null;
+ ConfigurationMetadataProperty info = datas.get(key);
+ Deprecation d = new Deprecation();
+ d.setReplacement(replacedBy);
+ d.setReason(reason);
+ info.setDeprecation(d);
+ }
+
+ /**
+ * Call this method to add some default test data to the Completion engine's index.
+ * Note that this data is not added automatically, some test may want to use smaller
+ * test data sets.
+ */
+ public void defaultTestData() {
+ data("banner.charset", "java.nio.charset.Charset", "UTF-8", "Banner file encoding.");
+ data("banner.location", "java.lang.String", "classpath:banner.txt", "Banner file location.");
+ data("debug", "java.lang.Boolean", "false", "Enable debug logs.");
+ data("flyway.check-location", "java.lang.Boolean", "false", "Check that migration scripts location exists.");
+ data("flyway.clean-on-validation-error", "java.lang.Boolean", null, null);
+ data("flyway.enabled", "java.lang.Boolean", "true", "Enable flyway.");
+ data("flyway.encoding", "java.lang.String", null, null);
+ data("flyway.ignore-failed-future-migration", "java.lang.Boolean", null, null);
+ data("flyway.init-description", "java.lang.String", null, null);
+ data("flyway.init-on-migrate", "java.lang.Boolean", null, null);
+ data("flyway.init-sqls", "java.util.List", null, "SQL statements to execute to initialize a connection immediately after obtaining\n it.");
+ data("flyway.init-version", "org.flywaydb.core.api.MigrationVersion", null, null);
+ data("flyway.locations", "java.util.List", null, "Locations of migrations scripts.");
+ data("flyway.out-of-order", "java.lang.Boolean", null, null);
+ data("flyway.password", "java.lang.String", null, "Login password of the database to migrate.");
+ data("flyway.placeholder-prefix", "java.lang.String", null, null);
+ data("flyway.placeholders", "java.util.Map", null, null);
+ data("flyway.placeholder-suffix", "java.lang.String", null, null);
+ data("flyway.schemas", "java.lang.String[]", null, null);
+ data("flyway.sql-migration-prefix", "java.lang.String", null, null);
+ data("flyway.sql-migration-separator", "java.lang.String", null, null);
+ data("flyway.sql-migration-suffix", "java.lang.String", null, null);
+ data("flyway.table", "java.lang.String", null, null);
+ data("flyway.target", "org.flywaydb.core.api.MigrationVersion", null, null);
+ data("flyway.url", "java.lang.String", null, "JDBC url of the database to migrate. If not set, the primary configured data source\n is used.");
+ data("flyway.user", "java.lang.String", null, "Login user of the database to migrate.");
+ data("flyway.validate-on-migrate", "java.lang.Boolean", null, null);
+ data("http.mappers.json-pretty-print", "java.lang.Boolean", null, "Enable json pretty print.");
+ data("http.mappers.json-sort-keys", "java.lang.Boolean", null, "Enable key sorting.");
+ data("liquibase.change-log", "java.lang.String", "classpath:/db/changelog/db.changelog-master.yaml", "Change log configuration path.");
+ data("liquibase.check-change-log-location", "java.lang.Boolean", "true", "Check the change log location exists.");
+ data("liquibase.contexts", "java.lang.String", null, "Comma-separated list of runtime contexts to use.");
+ data("liquibase.default-schema", "java.lang.String", null, "Default database schema.");
+ data("liquibase.drop-first", "java.lang.Boolean", "false", "Drop the database schema first.");
+ data("liquibase.enabled", "java.lang.Boolean", "true", "Enable liquibase support.");
+ data("liquibase.password", "java.lang.String", null, "Login password of the database to migrate.");
+ data("liquibase.url", "java.lang.String", null, "JDBC url of the database to migrate. If not set, the primary configured data source\n is used.");
+ data("liquibase.user", "java.lang.String", null, "Login user of the database to migrate.");
+ data("logging.config", "java.lang.String", null, "Location of the logging configuration file.");
+ data("logging.file", "java.lang.String", null, "Log file name.");
+ data("logging.level", "java.util.Map", null, "Log levels severity mapping. Use 'root' for the root logger.");
+ data("logging.path", "java.lang.String", null, "Location of the log file.");
+ data("multipart.file-size-threshold", "java.lang.String", "0", "Threshold after which files will be written to disk. Values can use the suffixed\n \"MB\" or \"KB\" to indicate a Megabyte or Kilobyte size.");
+ data("multipart.location", "java.lang.String", null, "Intermediate location of uploaded files.");
+ data("multipart.max-file-size", "java.lang.String", "1Mb", "Max file size. Values can use the suffixed \"MB\" or \"KB\" to indicate a Megabyte or\n Kilobyte size.");
+ data("multipart.max-request-size", "java.lang.String", "10Mb", "Max request size. Values can use the suffixed \"MB\" or \"KB\" to indicate a Megabyte\n or Kilobyte size.");
+ data("security.basic.enabled", "java.lang.Boolean", "true", "Enable basic authentication.");
+ data("security.basic.path", "java.lang.String[]", "[Ljava.lang.Object;@7abd0056", "Comma-separated list of paths to secure.");
+ data("security.basic.realm", "java.lang.String", "Spring", "HTTP basic realm name.");
+ data("security.enable-csrf", "java.lang.Boolean", "false", "Enable Cross Site Request Forgery support.");
+ data("security.filter-order", "java.lang.Integer", "0", "Security filter chain order.");
+ data("security.headers.cache", "java.lang.Boolean", "false", "Enable cache control HTTP headers.");
+ data("security.headers.content-type", "java.lang.Boolean", "false", "Enable \"X-Content-Type-Options\" header.");
+ data("security.headers.frame", "java.lang.Boolean", "false", "Enable \"X-Frame-Options\" header.");
+ data("security.headers.hsts", "org.springframework.boot.autoconfigure.security.SecurityProperties$Headers$HSTS", null, "HTTP Strict Transport Security (HSTS) mode (none, domain, all).");
+ data("security.headers.xss", "java.lang.Boolean", "false", "Enable cross site scripting (XSS) protection.");
+ data("security.ignored", "java.util.List", null, "Comma-separated list of paths to exclude from the default secured paths.");
+ data("security.require-ssl", "java.lang.Boolean", "false", "Enable secure channel for all requests.");
+ data("security.sessions", "org.springframework.security.config.http.SessionCreationPolicy", null, "Session creation policy (always, never, if_required, stateless).");
+ data("security.user.name", "java.lang.String", "user", "Default user name.");
+ data("security.user.password", "java.lang.String", null, "Password for the default user name.");
+ data("security.user.role", "java.util.List", null, "Granted roles for the default user name.");
+ data("server.address", "java.net.InetAddress", null, "Network address to which the server should bind to.");
+ data("server.context-parameters", "java.util.Map", null, "ServletContext parameters.");
+ data("server.context-path", "java.lang.String", null, "Context path of the application.");
+ data("server.port", "java.lang.Integer", null, "Server HTTP port.");
+ data("server.servlet-path", "java.lang.String", "/", "Path of the main dispatcher servlet.");
+ data("server.session-timeout", "java.lang.Integer", null, "Session timeout in seconds.");
+ data("server.ssl.ciphers", "java.lang.String[]", null, null);
+ data("server.ssl.client-auth", "org.springframework.boot.context.embedded.Ssl$ClientAuth", null, null);
+ data("server.ssl.key-alias", "java.lang.String", null, null);
+ data("server.ssl.key-password", "java.lang.String", null, null);
+ data("server.ssl.key-store", "java.lang.String", null, null);
+ data("server.ssl.key-store-password", "java.lang.String", null, null);
+ data("server.ssl.key-store-provider", "java.lang.String", null, null);
+ data("server.ssl.key-store-type", "java.lang.String", null, null);
+ data("server.ssl.protocol", "java.lang.String", null, null);
+ data("server.ssl.trust-store", "java.lang.String", null, null);
+ data("server.ssl.trust-store-password", "java.lang.String", null, null);
+ data("server.ssl.trust-store-provider", "java.lang.String", null, null);
+ data("server.ssl.trust-store-type", "java.lang.String", null, null);
+ data("server.tomcat.access-log-enabled", "java.lang.Boolean", "false", "Enable access log.");
+ data("server.tomcat.access-log-pattern", "java.lang.String", null, "Format pattern for access logs.");
+ data("server.tomcat.background-processor-delay", "java.lang.Integer", "30", "Delay in seconds between the invocation of backgroundProcess methods.");
+ data("server.tomcat.basedir", "java.io.File", null, "Tomcat base directory. If not specified a temporary directory will be used.");
+ data("server.tomcat.internal-proxies", "java.lang.String", "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|169\\.254\\.\\d{1,3}\\.\\d{1,3}|127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}", "Regular expression that matches proxies that are to be trusted.");
+ data("server.tomcat.max-http-header-size", "java.lang.Integer", "0", "Maximum size in bytes of the HTTP message header.");
+ data("server.tomcat.max-threads", "java.lang.Integer", "0", "Maximum amount of worker threads.");
+ data("server.tomcat.port-header", "java.lang.String", null, "Name of the HTTP header used to override the original port value.");
+ data("server.tomcat.protocol-header", "java.lang.String", null, "Header that holds the incoming protocol, usually named \"X-Forwarded-Proto\".\n Configured as a RemoteIpValve only if remoteIpHeader is also set.");
+ data("server.tomcat.remote-ip-header", "java.lang.String", null, "Name of the http header from which the remote ip is extracted. Configured as a\n RemoteIpValve only if remoteIpHeader is also set.");
+ data("server.tomcat.uri-encoding", "java.lang.String", null, "Character encoding to use to decode the URI.");
+ data("server.undertow.buffer-size", "java.lang.Integer", null, "Size of each buffer in bytes.");
+ data("server.undertow.buffers-per-region", "java.lang.Integer", null, "Number of buffer per region.");
+ data("server.undertow.direct-buffers", "java.lang.Boolean", null, null);
+ data("server.undertow.io-threads", "java.lang.Integer", null, "Number of I/O threads to create for the worker.");
+ data("server.undertow.worker-threads", "java.lang.Integer", null, "Number of worker threads.");
+ data("spring.activemq.broker-url", "java.lang.String", null, "URL of the ActiveMQ broker. Auto-generated by default.");
+ data("spring.activemq.in-memory", "java.lang.Boolean", "true", "Specify if the default broker URL should be in memory. Ignored if an explicit\n broker has been specified.");
+ data("spring.activemq.password", "java.lang.String", null, "Login password of the broker.");
+ data("spring.activemq.pooled", "java.lang.Boolean", "false", "Specify if a PooledConnectionFactory should be created instead of a regular\n ConnectionFactory.");
+ data("spring.activemq.user", "java.lang.String", null, "Login user of the broker.");
+ data("spring.aop.auto", "java.lang.Boolean", "true", "Add @EnableAspectJAutoProxy.");
+ data("spring.aop.proxy-target-class", "java.lang.Boolean", "false", "Whether subclass-based (CGLIB) proxies are to be created (true) as opposed to standard Java interface-based proxies (false).");
+ data("spring.application.index", "java.lang.Integer", null, "Application index.");
+ data("spring.application.name", "java.lang.String", null, "Application name.");
+ data("spring.batch.initializer.enabled", "java.lang.Boolean", "true", "Create the required batch tables on startup if necessary.");
+ data("spring.batch.job.enabled", "java.lang.Boolean", "true", "Execute all Spring Batch jobs in the context on startup.");
+ data("spring.batch.job.names", "java.lang.String", "", "Comma-separated list of job names to execute on startup. By default, all Jobs\n found in the context are executed.");
+ data("spring.batch.schema", "java.lang.String", "classpath:org/springframework/batch/core/schema-@@platform@@.sql", "Path to the SQL file to use to initialize the database schema.");
+ data("spring.config.location", "java.lang.String", null, "Config file locations.");
+ data("spring.config.name", "java.lang.String", "application", "Config file name.");
+ data("spring.dao.exceptiontranslation.enabled", "java.lang.Boolean", "true", "Enable the PersistenceExceptionTranslationPostProcessor.");
+ data("spring.data.elasticsearch.cluster-name", "java.lang.String", "elasticsearch", "Elasticsearch cluster name.");
+ data("spring.data.elasticsearch.cluster-nodes", "java.lang.String", null, "Comma-separated list of cluster node addresses. If not specified, starts a client\n node.");
+ data("spring.data.elasticsearch.repositories.enabled", "java.lang.Boolean", "true", "Enable Elasticsearch repositories.");
+ data("spring.data.jpa.repositories.enabled", "java.lang.Boolean", "true", "Enable JPA repositories.");
+ data("spring.data.mongodb.authentication-database", "java.lang.String", null, "Authentication database name.");
+ data("spring.data.mongodb.database", "java.lang.String", null, "Database name.");
+ data("spring.data.mongodb.grid-fs-database", "java.lang.String", null, "GridFS database name.");
+ data("spring.data.mongodb.host", "java.lang.String", null, "Mongo server host.");
+ data("spring.data.mongodb.password", "char[]", null, "Login password of the mongo server.");
+ data("spring.data.mongodb.port", "java.lang.Integer", null, "Mongo server port.");
+ data("spring.data.mongodb.repositories.enabled", "java.lang.Boolean", "true", "Enable Mongo repositories.");
+ data("spring.data.mongodb.uri", "java.lang.String", "mongodb://localhost/test", "Mmongo database URI. When set, host and port are ignored.");
+ data("spring.data.mongodb.username", "java.lang.String", null, "Login user of the mongo server.");
+ data("spring.data.rest.base-uri", "java.net.URI", null, null);
+ data("spring.data.rest.default-page-size", "java.lang.Integer", null, null);
+ data("spring.data.rest.limit-param-name", "java.lang.String", null, null);
+ data("spring.data.rest.max-page-size", "java.lang.Integer", null, null);
+ data("spring.data.rest.page-param-name", "java.lang.String", null, null);
+ data("spring.data.rest.return-body-on-create", "java.lang.Boolean", null, null);
+ data("spring.data.rest.return-body-on-update", "java.lang.Boolean", null, null);
+ data("spring.data.rest.sort-param-name", "java.lang.String", null, null);
+ data("spring.data.solr.host", "java.lang.String", "http://127.0.0.1:8983/solr", "Solr host. Ignored if \"zk-host\" is set.");
+ data("spring.data.solr.repositories.enabled", "java.lang.Boolean", "true", "Enable Solr repositories.");
+ data("spring.data.solr.zk-host", "java.lang.String", null, "ZooKeeper host address in the form HOST:PORT.");
+ data("spring.datasource.abandon-when-percentage-full", "java.lang.Integer", null, null);
+ data("spring.datasource.access-to-underlying-connection-allowed", "java.lang.Boolean", null, null);
+ data("spring.datasource.alternate-username-allowed", "java.lang.Boolean", null, null);
+ data("spring.datasource.auto-commit", "java.lang.Boolean", null, null);
+ data("spring.datasource.catalog", "java.lang.String", null, null);
+ data("spring.datasource.commit-on-return", "java.lang.Boolean", null, null);
+ data("spring.datasource.connection-customizer-class-name", "java.lang.String", null, null);
+ data("spring.datasource.connection-init-sql", "java.lang.String", null, null);
+ data("spring.datasource.connection-init-sqls", "java.util.Collection", null, null);
+ data("spring.datasource.connection-properties", "java.lang.String", null, null);
+ data("spring.datasource.connection-test-query", "java.lang.String", null, null);
+ data("spring.datasource.connection-timeout", "java.lang.Long", null, null);
+ data("spring.datasource.continue-on-error", "java.lang.Boolean", "false", "Do not stop if an error occurs while initializing the database.");
+ data("spring.datasource.data", "java.lang.String", null, "Data (DML) script resource reference.");
+ data("spring.datasource.data-source-class-name", "java.lang.String", null, null);
+ data("spring.datasource.data-source", "java.lang.Object", null, null);
+ data("spring.datasource.data-source-j-n-d-i", "java.lang.String", null, null);
+ data("spring.datasource.data-source-properties", "java.util.Properties", null, null);
+ data("spring.datasource.db-properties", "java.util.Properties", null, null);
+ data("spring.datasource.default-auto-commit", "java.lang.Boolean", null, null);
+ data("spring.datasource.default-catalog", "java.lang.String", null, null);
+ data("spring.datasource.default-read-only", "java.lang.Boolean", null, null);
+ data("spring.datasource.default-transaction-isolation", "java.lang.Integer", null, null);
+ data("spring.datasource.driver-class-name", "java.lang.String", null, "Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.");
+ data("spring.datasource.fair-queue", "java.lang.Boolean", null, null);
+ data("spring.datasource.idle-timeout", "java.lang.Long", null, null);
+ data("spring.datasource.ignore-exception-on-pre-load", "java.lang.Boolean", null, null);
+ data("spring.datasource.initialization-fail-fast", "java.lang.Boolean", null, null);
+ data("spring.datasource.initialize", "java.lang.Boolean", "true", "Populate the database using 'data.sql'.");
+ data("spring.datasource.initial-size", "java.lang.Integer", null, null);
+ data("spring.datasource.init-s-q-l", "java.lang.String", null, null);
+ data("spring.datasource.isolate-internal-queries", "java.lang.Boolean", null, null);
+ data("spring.datasource.jdbc4-connection-test", "java.lang.Boolean", null, null);
+ data("spring.datasource.jdbc-interceptors", "java.lang.String", null, null);
+ data("spring.datasource.jdbc-url", "java.lang.String", null, null);
+ data("spring.datasource.jmx-enabled", "java.lang.Boolean", "false", "Enable JMX support (if provided by the underlying pool).");
+ data("spring.datasource.jndi-name", "java.lang.String", null, "JNDI location of the datasource. Class, url, username & password are ignored when\n set.");
+ data("spring.datasource.leak-detection-threshold", "java.lang.Long", null, null);
+ data("spring.datasource.log-abandoned", "java.lang.Boolean", null, null);
+ data("spring.datasource.login-timeout", "java.lang.Integer", null, null);
+ data("spring.datasource.log-validation-errors", "java.lang.Boolean", null, null);
+ data("spring.datasource.max-active", "java.lang.Integer", null, null);
+ data("spring.datasource.max-age", "java.lang.Long", null, null);
+ data("spring.datasource.max-idle", "java.lang.Integer", null, null);
+ data("spring.datasource.maximum-pool-size", "java.lang.Integer", null, null);
+ data("spring.datasource.max-lifetime", "java.lang.Long", null, null);
+ data("spring.datasource.max-open-prepared-statements", "java.lang.Integer", null, null);
+ data("spring.datasource.max-wait", "java.lang.Integer", null, null);
+ data("spring.datasource.metric-registry", "java.lang.Object", null, null);
+ data("spring.datasource.min-evictable-idle-time-millis", "java.lang.Integer", null, null);
+ data("spring.datasource.min-idle", "java.lang.Integer", null, null);
+ data("spring.datasource.minimum-idle", "java.lang.Integer", null, null);
+ data("spring.datasource.name", "java.lang.String", null, null);
+ data("spring.datasource.num-tests-per-eviction-run", "java.lang.Integer", null, null);
+ data("spring.datasource.password", "java.lang.String", null, "Login password of the database.");
+ data("spring.datasource.platform", "java.lang.String", "all", "Platform to use in the schema resource (schema-${platform}.sql).");
+ data("spring.datasource.pool-name", "java.lang.String", null, null);
+ data("spring.datasource.pool-prepared-statements", "java.lang.Boolean", null, null);
+ data("spring.datasource.propagate-interrupt-state", "java.lang.Boolean", null, null);
+ data("spring.datasource.read-only", "java.lang.Boolean", null, null);
+ data("spring.datasource.register-mbeans", "java.lang.Boolean", null, null);
+ data("spring.datasource.remove-abandoned", "java.lang.Boolean", null, null);
+ data("spring.datasource.remove-abandoned-timeout", "java.lang.Integer", null, null);
+ data("spring.datasource.rollback-on-return", "java.lang.Boolean", null, null);
+ data("spring.datasource.schema", "java.lang.String", null, "Schema (DDL) script resource reference.");
+ data("spring.datasource.separator", "java.lang.String", ";", "Statement separator in SQL initialization scripts.");
+ data("spring.datasource.sql-script-encoding", "java.lang.String", null, "SQL scripts encoding.");
+ data("spring.datasource.suspect-timeout", "java.lang.Integer", null, null);
+ data("spring.datasource.test-on-borrow", "java.lang.Boolean", null, null);
+ data("spring.datasource.test-on-connect", "java.lang.Boolean", null, null);
+ data("spring.datasource.test-on-return", "java.lang.Boolean", null, null);
+ data("spring.datasource.test-while-idle", "java.lang.Boolean", null, null);
+ data("spring.datasource.time-between-eviction-runs-millis", "java.lang.Integer", null, null);
+ data("spring.datasource.transaction-isolation", "java.lang.String", null, null);
+ data("spring.datasource.url", "java.lang.String", null, "JDBC url of the database.");
+ data("spring.datasource.use-disposable-connection-facade", "java.lang.Boolean", null, null);
+ data("spring.datasource.use-equals", "java.lang.Boolean", null, null);
+ data("spring.datasource.use-lock", "java.lang.Boolean", null, null);
+ data("spring.datasource.username", "java.lang.String", null, "Login user of the database.");
+ data("spring.datasource.validation-interval", "java.lang.Long", null, null);
+ data("spring.datasource.validation-query", "java.lang.String", null, null);
+ data("spring.datasource.validation-query-timeout", "java.lang.Integer", null, null);
+ data("spring.datasource.validator-class-name", "java.lang.String", null, null);
+ data("spring.datasource.xa.data-source-class-name", "java.lang.String", null, "XA datasource fully qualified name.");
+ data("spring.datasource.xa.properties", "java.util.Map", null, "Properties to pass to the XA data source.");
+ data("spring.freemarker.allow-request-override", "java.lang.Boolean", null, "Set whether HttpServletRequest attributes are allowed to override (hide) controller\n generated model attributes of the same name.");
+ data("spring.freemarker.cache", "java.lang.Boolean", null, "Enable template caching.");
+ data("spring.freemarker.char-set", "java.lang.String", null, null);
+ data("spring.freemarker.charset", "java.lang.String", null, "Template encoding.");
+ data("spring.freemarker.check-template-location", "java.lang.Boolean", null, "Check that the templates location exists.");
+ data("spring.freemarker.content-type", "java.lang.String", null, "Content-Type value.");
+ data("spring.freemarker.enabled", "java.lang.Boolean", null, "Enable MVC view resolution for this technology.");
+ data("spring.freemarker.expose-request-attributes", "java.lang.Boolean", null, "Set whether all request attributes should be added to the model prior to merging\n with the template.");
+ data("spring.freemarker.expose-session-attributes", "java.lang.Boolean", null, "Set whether all HttpSession attributes should be added to the model prior to\n merging with the template.");
+ data("spring.freemarker.expose-spring-macro-helpers", "java.lang.Boolean", null, "Set whether to expose a RequestContext for use by Spring's macro library, under the\n name \"springMacroRequestContext\".");
+ data("spring.freemarker.prefix", "java.lang.String", null, "Prefix that gets prepended to view names when building a URL.");
+ data("spring.freemarker.request-context-attribute", "java.lang.String", null, "Name of the RequestContext attribute for all views.");
+ data("spring.freemarker.settings", "java.util.Map", null, "Well-known FreeMarker keys which will be passed to FreeMarker's Configuration.");
+ data("spring.freemarker.suffix", "java.lang.String", null, "Suffix that gets appended to view names when building a URL.");
+ data("spring.freemarker.template-loader-path", "java.lang.String[]", new String[] {"snuzzle" ,"buggles"}, "Comma-separated list of template paths.");
+ data("spring.freemarker.view-names", "java.lang.String[]", null, "White list of view names that can be resolved.");
+ data("spring.groovy.template.cache", "java.lang.Boolean", null, "Enable template caching.");
+ data("spring.groovy.template.char-set", "java.lang.String", null, null);
+ data("spring.groovy.template.charset", "java.lang.String", null, "Template encoding.");
+ data("spring.groovy.template.check-template-location", "java.lang.Boolean", null, "Check that the templates location exists.");
+ data("spring.groovy.template.configuration.auto-escape", "java.lang.Boolean", null, null);
+ data("spring.groovy.template.configuration.auto-indent", "java.lang.Boolean", null, null);
+ data("spring.groovy.template.configuration.auto-indent-string", "java.lang.String", null, null);
+ data("spring.groovy.template.configuration.auto-new-line", "java.lang.Boolean", null, null);
+ data("spring.groovy.template.configuration.base-template-class", "java.lang.Class extends groovy.text.markup.BaseTemplate>", null, null);
+ data("spring.groovy.template.configuration.cache-templates", "java.lang.Boolean", null, null);
+ data("spring.groovy.template.configuration.declaration-encoding", "java.lang.String", null, null);
+ data("spring.groovy.template.configuration.expand-empty-elements", "java.lang.Boolean", null, null);
+ data("spring.groovy.template.configuration", "java.util.Map", null, "Configuration to pass to TemplateConfiguration.");
+ data("spring.groovy.template.configuration.locale", "java.util.Locale", null, null);
+ data("spring.groovy.template.configuration.new-line-string", "java.lang.String", null, null);
+ data("spring.groovy.template.configuration.resource-loader-path", "java.lang.String", null, null);
+ data("spring.groovy.template.configuration.use-double-quotes", "java.lang.Boolean", null, null);
+ data("spring.groovy.template.content-type", "java.lang.String", null, "Content-Type value.");
+ data("spring.groovy.template.enabled", "java.lang.Boolean", null, "Enable MVC view resolution for this technology.");
+ data("spring.groovy.template.prefix", "java.lang.String", "classpath:/templates/", "Prefix that gets prepended to view names when building a URL.");
+ data("spring.groovy.template.suffix", "java.lang.String", ".tpl", "Suffix that gets appended to view names when building a URL.");
+ data("spring.groovy.template.view-names", "java.lang.String[]", null, "White list of view names that can be resolved.");
+ data("spring.hornetq.embedded.cluster-password", "java.lang.String", null, "Cluster password. Randomly generated on startup by default");
+ data("spring.hornetq.embedded.data-directory", "java.lang.String", null, "Journal file directory. Not necessary if persistence is turned off.");
+ data("spring.hornetq.embedded.enabled", "java.lang.Boolean", "true", "Enable embedded mode if the HornetQ server APIs are available.");
+ data("spring.hornetq.embedded.persistent", "java.lang.Boolean", "false", "Enable persistent store.");
+ data("spring.hornetq.embedded.queues", "java.lang.String[]", "[Ljava.lang.Object;@2f5ce114", "Comma-separate list of queues to create on startup.");
+ data("spring.hornetq.embedded.server-id", "java.lang.Integer", "0", "Server id. By default, an auto-incremented counter is used.");
+ data("spring.hornetq.embedded.topics", "java.lang.String[]", "[Ljava.lang.Object;@6272137a", "Comma-separate list of topics to create on startup.");
+ data("spring.hornetq.host", "java.lang.String", "localhost", "HornetQ broker host.");
+ data("spring.hornetq.mode", "org.springframework.boot.autoconfigure.jms.hornetq.HornetQMode", null, "HornetQ deployment mode, auto-detected by default. Can be explicitly set to\n \"native\" or \"embedded\".");
+ data("spring.hornetq.port", "java.lang.Integer", "5445", "HornetQ broker port.");
+ data("spring.http.encoding.charset", "java.nio.charset.Charset", null, "Charset of HTTP requests and responses. Added to the \"Content-Type\" header if not\n set explicitly.");
+ data("spring.http.encoding.enabled", "java.lang.Boolean", "true", "Enable http encoding support.");
+ data("spring.http.encoding.force", "java.lang.Boolean", "true", "Force the encoding to the configured charset on HTTP requests and responses.");
+ data("spring.jackson.date-format", "java.lang.String", null, "Date format string (yyyy-MM-dd HH:mm:ss), or a fully-qualified date format class\n name.");
+ data("spring.jackson.deserialization", "java.util.Map", null, "Jackson on/off features that affect the way Java objects are deserialized.");
+ data("spring.jackson.generator", "java.util.Map", null, "Jackson on/off features for generators.");
+ data("spring.jackson.mapper", "java.util.Map", null, "Jackson general purpose on/off features.");
+ data("spring.jackson.parser", "java.util.Map", null, "Jackson on/off features for parsers.");
+ data("spring.jackson.property-naming-strategy", "java.lang.String", null, "One of the constants on Jackson's PropertyNamingStrategy\n (CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES). Can also be a fully-qualified class\n name of a PropertyNamingStrategy subclass.");
+ data("spring.jackson.serialization", "java.util.Map", null, "Jackson on/off features that affect the way Java objects are serialized.");
+ data("spring.jersey.filter.order", "java.lang.Integer", "0", "Jersey filter chain order.");
+ data("spring.jersey.init", "java.util.Map", null, "Init parameters to pass to Jersey.");
+ data("spring.jersey.type", "org.springframework.boot.autoconfigure.jersey.JerseyProperties$Type", null, "Jersey integration type. Can be either \"servlet\" or \"filter\".");
+ data("spring.jms.jndi-name", "java.lang.String", null, "Connection factory JNDI name. When set, takes precedence to others connection\n factory auto-configurations.");
+ data("spring.jms.pub-sub-domain", "java.lang.Boolean", "false", "Specify if the default destination type is topic.");
+ data("spring.jmx.enabled", "java.lang.Boolean", "true", "Expose management beans to the JMX domain.");
+ data("spring.jpa.database", "org.springframework.orm.jpa.vendor.Database", null, "Target database to operate on, auto-detected by default. Can be alternatively set\n using the \"databasePlatform\" property.");
+ data("spring.jpa.database-platform", "java.lang.String", null, "Name of the target database to operate on, auto-detected by default. Can be\n alternatively set using the \"Database\" enum.");
+ data("spring.jpa.generate-ddl", "java.lang.Boolean", "false", "Initialize the schema on startup.");
+ data("spring.jpa.hibernate.ddl-auto", "java.lang.String", null, "DDL mode (\"none\", \"validate\", \"update\", \"create\", \"create-drop\"). This is\n actually a shortcut for the \"hibernate.hbm2ddl.auto\" property. Default to\n \"create-drop\" when using an embedded database, \"none\" otherwise.");
+ data("spring.jpa.hibernate.naming-strategy", "java.lang.Class>", null, "Naming strategy fully qualified name.");
+ data("spring.jpa.open-in-view", "java.lang.Boolean", "true", "Register OpenEntityManagerInViewInterceptor. Binds a JPA EntityManager to the thread for the entire processing of the request.");
+ data("spring.jpa.properties", "java.util.Map", null, "Additional native properties to set on the JPA provider.");
+ data("spring.jpa.show-sql", "java.lang.Boolean", "false", "Enable logging of SQL statements.");
+ data("spring.jta.allow-multiple-lrc", "java.lang.Boolean", null, null);
+ data("spring.jta.asynchronous2-pc", "java.lang.Boolean", null, null);
+ data("spring.jta.background-recovery-interval", "java.lang.Integer", null, null);
+ data("spring.jta.background-recovery-interval-seconds", "java.lang.Integer", null, null);
+ data("spring.jta.current-node-only-recovery", "java.lang.Boolean", null, null);
+ data("spring.jta.debug-zero-resource-transaction", "java.lang.Boolean", null, null);
+ data("spring.jta.default-transaction-timeout", "java.lang.Integer", null, null);
+ data("spring.jta.disable-jmx", "java.lang.Boolean", null, null);
+ data("spring.jta.enabled", "java.lang.Boolean", "true", "Enable JTA support.");
+ data("spring.jta.exception-analyzer", "java.lang.String", null, null);
+ data("spring.jta.filter-log-status", "java.lang.Boolean", null, null);
+ data("spring.jta.force-batching-enabled", "java.lang.Boolean", null, null);
+ data("spring.jta.forced-write-enabled", "java.lang.Boolean", null, null);
+ data("spring.jta.graceful-shutdown-interval", "java.lang.Integer", null, null);
+ data("spring.jta.jndi-transaction-synchronization-registry-name", "java.lang.String", null, null);
+ data("spring.jta.jndi-user-transaction-name", "java.lang.String", null, null);
+ data("spring.jta.journal", "java.lang.String", null, null);
+ data("spring.jta.log-dir", "java.lang.String", null, "Transaction logs directory.");
+ data("spring.jta.log-part1-filename", "java.lang.String", null, null);
+ data("spring.jta.log-part2-filename", "java.lang.String", null, null);
+ data("spring.jta.max-log-size-in-mb", "java.lang.Integer", null, null);
+ data("spring.jta.resource-configuration-filename", "java.lang.String", null, null);
+ data("spring.jta.server-id", "java.lang.String", null, null);
+ data("spring.jta.skip-corrupted-logs", "java.lang.Boolean", null, null);
+ data("spring.jta.transaction-manager-id", "java.lang.String", null, "Transaction manager unique identifier.");
+ data("spring.jta.warn-about-zero-resource-transaction", "java.lang.Boolean", null, null);
+ data("spring.mail.default-encoding", "java.lang.String", "UTF-8", "Default MimeMessage encoding.");
+ data("spring.mail.host", "java.lang.String", null, "SMTP server host.");
+ data("spring.mail.password", "java.lang.String", null, "Login password of the SMTP server.");
+ data("spring.mail.port", "java.lang.Integer", null, "SMTP server port.");
+ data("spring.mail.properties", "java.util.Map", null, "Additional JavaMail session properties.");
+ data("spring.mail.username", "java.lang.String", null, "Login user of the SMTP server.");
+ data("spring.main.show-banner", "java.lang.Boolean", "true", "Display the banner when the application runs.");
+ data("spring.main.sources", "java.util.Set", null, "Sources (class name, package name or XML resource location) used to create the ApplicationContext.");
+ data("spring.main.web-environment", "java.lang.Boolean", null, "Run the application in a web environment (auto-detected by default).");
+ data("spring.mandatory-file-encoding", "java.lang.String", null, "Expected character encoding the application must use.");
+ data("spring.messages.basename", "java.lang.String", "messages", "Comma-separated list of basenames, each following the ResourceBundle convention.\n Essentially a fully-qualified classpath location. If it doesn't contain a package\n qualifier (such as \"org.mypackage\"), it will be resolved from the classpath root.");
+ data("spring.messages.cache-seconds", "java.lang.Integer", "-1", "Loaded resource bundle files cache expiration, in seconds. When set to -1, bundles\n are cached forever.");
+ data("spring.messages.encoding", "java.lang.String", "utf-8", "Message bundles encoding.");
+ data("spring.mobile.devicedelegatingviewresolver.enabled", "java.lang.Boolean", "false", "Enable device view resolver.");
+ data("spring.mobile.devicedelegatingviewresolver.mobile-prefix", "java.lang.String", "mobile/", "Prefix that gets prepended to view names for mobile devices.");
+ data("spring.mobile.devicedelegatingviewresolver.mobile-suffix", "java.lang.String", "", "Suffix that gets appended to view names for mobile devices.");
+ data("spring.mobile.devicedelegatingviewresolver.normal-prefix", "java.lang.String", "", "Prefix that gets prepended to view names for normal devices.");
+ data("spring.mobile.devicedelegatingviewresolver.normal-suffix", "java.lang.String", "", "Suffix that gets appended to view names for normal devices.");
+ data("spring.mobile.devicedelegatingviewresolver.tablet-prefix", "java.lang.String", "tablet/", "Prefix that gets prepended to view names for tablet devices.");
+ data("spring.mobile.devicedelegatingviewresolver.tablet-suffix", "java.lang.String", "", "Suffix that gets appended to view names for tablet devices.");
+ data("spring.mobile.sitepreference.enabled", "java.lang.Boolean", "true", "Enable SitePreferenceHandler.");
+ data("spring.mvc.date-format", "java.lang.String", null, "Date format to use (e.g. dd/MM/yyyy)");
+ data("spring.mvc.ignore-default-model-on-redirect", "java.lang.Boolean", "true", "If the the content of the \"default\" model should be ignored during redirect\n scenarios.");
+ data("spring.mvc.locale", "java.lang.String", null, "Locale to use.");
+ data("spring.mvc.message-codes-resolver-format", "org.springframework.validation.DefaultMessageCodesResolver$Format", null, "Formatting strategy for message codes (PREFIX_ERROR_CODE, POSTFIX_ERROR_CODE).");
+ data("spring.profiles.active", "java.lang.String", null, "Comma-separated list of active profiles. Can be overridden by a command line switch.");
+ data("spring.profiles.include", "java.lang.String", null, "Unconditionally activate the specified comma separated profiles.");
+ data("spring.rabbitmq.addresses", "java.lang.String", null, "Comma-separated list of addresses to which the client should connect to.");
+ data("spring.rabbitmq.dynamic", "java.lang.Boolean", "true", "Create an AmqpAdmin bean.");
+ data("spring.rabbitmq.host", "java.lang.String", "localhost", "RabbitMQ host.");
+ data("spring.rabbitmq.password", "java.lang.String", null, "Login to authenticate against the broker.");
+ data("spring.rabbitmq.port", "java.lang.Integer", "5672", "RabbitMQ port.");
+ data("spring.rabbitmq.username", "java.lang.String", null, "Login user to authenticate to the broker.");
+ data("spring.rabbitmq.virtual-host", "java.lang.String", null, "Virtual host to use when connecting to the broker.");
+ data("spring.redis.database", "java.lang.Integer", "0", "Database index used by the connection factory.");
+ data("spring.redis.host", "java.lang.String", "localhost", "Redis server host.");
+ data("spring.redis.password", "java.lang.String", null, "Login password of the redis server.");
+ data("spring.redis.pool.max-active", "java.lang.Integer", "8", "Max number of connections that can be allocated by the pool at a given time.\n Use a negative value for no limit.");
+ data("spring.redis.pool.max-idle", "java.lang.Integer", "8", "Max number of \"idle\" connections in the pool. Use a negative value to indicate\n an unlimited number of idle connections.");
+ data("spring.redis.pool.max-wait", "java.lang.Integer", "-1", "Maximum amount of time (in milliseconds) a connection allocation should block\n before throwing an exception when the pool is exhausted. Use a negative value\n to block indefinitely.");
+ data("spring.redis.pool.min-idle", "java.lang.Integer", "0", "Target for the minimum number of idle connections to maintain in the pool. This\n setting only has an effect if it is positive.");
+ data("spring.redis.port", "java.lang.Integer", "6379", "Redis server port.");
+ data("spring.redis.sentinel.master", "java.lang.String", null, "Name of Redis server.");
+ data("spring.redis.sentinel.nodes", "java.lang.String", null, "Comma-separated list of host:port pairs.");
+ data("spring.resources.add-mappings", "java.lang.Boolean", "true", "Enable default resource handling.");
+ data("spring.resources.cache-period", "java.lang.Integer", null, "Cache period for the resources served by the resource handler, in seconds.");
+ data("spring.social.auto-connection-views", "java.lang.Boolean", "false", "Enable the connection status view for supported providers.");
+ data("spring.social.facebook.app-id", "java.lang.String", null, "Application id.");
+ data("spring.social.facebook.app-secret", "java.lang.String", null, "Application secret.");
+ data("spring.social.linkedin.app-id", "java.lang.String", null, "Application id.");
+ data("spring.social.linkedin.app-secret", "java.lang.String", null, "Application secret.");
+ data("spring.social.twitter.app-id", "java.lang.String", null, "Application id.");
+ data("spring.social.twitter.app-secret", "java.lang.String", null, "Application secret.");
+ data("spring.thymeleaf.cache", "java.lang.Boolean", "true", "Enable template caching.");
+ data("spring.thymeleaf.check-template-location", "java.lang.Boolean", "true", "Check that the templates location exists.");
+ data("spring.thymeleaf.content-type", "java.lang.String", "text/html", "Content-Type value.");
+ data("spring.thymeleaf.enabled", "java.lang.Boolean", "true", "Enable MVC Thymeleaf view resolution.");
+ data("spring.thymeleaf.encoding", "java.lang.String", "UTF-8", "Template encoding.");
+ data("spring.thymeleaf.excluded-view-names", "java.lang.String[]", null, "Comma-separated list of view names that should be excluded from resolution.");
+ data("spring.thymeleaf.mode", "java.lang.String", "HTML5", "Template mode to be applied to templates. See also StandardTemplateModeHandlers.");
+ data("spring.thymeleaf.prefix", "java.lang.String", "classpath:/templates/", "Prefix that gets prepended to view names when building a URL.");
+ data("spring.thymeleaf.suffix", "java.lang.String", ".html", "Suffix that gets appended to view names when building a URL.");
+ data("spring.thymeleaf.view-names", "java.lang.String[]", null, "Comma-separated list of view names that can be resolved.");
+ data("spring.velocity.allow-request-override", "java.lang.Boolean", null, "Set whether HttpServletRequest attributes are allowed to override (hide) controller\n generated model attributes of the same name.");
+ data("spring.velocity.cache", "java.lang.Boolean", null, "Enable template caching.");
+ data("spring.velocity.char-set", "java.lang.String", null, null);
+ data("spring.velocity.charset", "java.lang.String", null, "Template encoding.");
+ data("spring.velocity.check-template-location", "java.lang.Boolean", null, "Check that the templates location exists.");
+ data("spring.velocity.content-type", "java.lang.String", null, "Content-Type value.");
+ data("spring.velocity.date-tool-attribute", "java.lang.String", null, "Name of the DateTool helper object to expose in the Velocity context of the view.");
+ data("spring.velocity.enabled", "java.lang.Boolean", null, "Enable MVC view resolution for this technology.");
+ data("spring.velocity.expose-request-attributes", "java.lang.Boolean", null, "Set whether all request attributes should be added to the model prior to merging\n with the template.");
+ data("spring.velocity.expose-session-attributes", "java.lang.Boolean", null, "Set whether all HttpSession attributes should be added to the model prior to\n merging with the template.");
+ data("spring.velocity.expose-spring-macro-helpers", "java.lang.Boolean", null, "Set whether to expose a RequestContext for use by Spring's macro library, under the\n name \"springMacroRequestContext\".");
+ data("spring.velocity.number-tool-attribute", "java.lang.String", null, "Name of the NumberTool helper object to expose in the Velocity context of the view.");
+ data("spring.velocity.prefer-file-system-access", "java.lang.Boolean", "true", "Prefer file system access for template loading. File system access enables hot\n detection of template changes.");
+ data("spring.velocity.prefix", "java.lang.String", null, "Prefix that gets prepended to view names when building a URL.");
+ data("spring.velocity.properties", "java.util.Map", null, "Additional velocity properties.");
+ data("spring.velocity.request-context-attribute", "java.lang.String", null, "Name of the RequestContext attribute for all views.");
+ data("spring.velocity.resource-loader-path", "java.lang.String", "classpath:/templates/", "Template path.");
+ data("spring.velocity.suffix", "java.lang.String", null, "Suffix that gets appended to view names when building a URL.");
+ data("spring.velocity.toolbox-config-location", "java.lang.String", null, "Velocity Toolbox config location, for example \"/WEB-INF/toolbox.xml\". Automatically\n loads a Velocity Tools toolbox definition file and expose all defined tools in the\n specified scopes.");
+ data("spring.velocity.view-names", "java.lang.String[]", null, "White list of view names that can be resolved.");
+ data("spring.view.prefix", "java.lang.String", null, "Spring MVC view prefix.");
+ data("spring.view.suffix", "java.lang.String", null, "Spring MVC view suffix.");
+ }
+
+ public boolean isEmpty() {
+ return datas == null || datas.isEmpty();
+ }
+
+ public SpringPropertyIndexProvider getIndexProvider() {
+ return indexProvider;
+ }
+
+}
diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/StyledStringMatcher.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/StyledStringMatcher.java
new file mode 100644
index 000000000..c04fa5e50
--- /dev/null
+++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/StyledStringMatcher.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * 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.yaml;
+
+//import org.eclipse.jface.viewers.StyledString;
+//import org.eclipse.swt.custom.StyleRange;
+
+public abstract class StyledStringMatcher {
+
+// public abstract void match(StyledString styledString) throws Exception;
+
+ /**
+ * Creates a matcher that matches a given {@link StyledString} if a given String
+ * equals the concatenation of all the text in the {@link StyledString} formatted
+ * in 'plain' font (currently 'plain' just means that it is not using 'strikeout'
+ * as that is the only other style we currently care about).
+ */
+ public static StyledStringMatcher plainFont(final String string) {
+ throw new UnsupportedOperationException("Not yet implemented");
+// return new StyledStringMatcher() {
+// @Override
+// public String toString() {
+// return "plain("+string+")";
+// }
+//
+// @Override
+// public void match(StyledString styledString) throws Exception {
+// StringBuilder extractedText = new StringBuilder();
+// String string = styledString.getString();
+// for (StyleRange styleRange : styledString.getStyleRanges()) {
+// if (!styleRange.strikeout) {
+// extractedText.append(string.substring(styleRange.start, styleRange.start + styleRange.length));
+// }
+// }
+// assertEquals(string, extractedText.toString());
+// }
+// };
+ }
+
+ /**
+ * Creates a matcher that matches a given {@link StyledString} if a given String
+ * equals the concatenation of all the text in the {@link StyledString} formatted
+ * in 'strikeout' font.
+ */
+ public static StyledStringMatcher strikeout(final String expectedString) {
+ throw new UnsupportedOperationException("Not yet implemented");
+// return new StyledStringMatcher() {
+// @Override
+// public String toString() {
+// return "strikeout("+expectedString+")";
+// }
+// @Override
+// public void match(StyledString styledString) throws Exception {
+// StringBuilder extractedText = new StringBuilder();
+// String unstyledString = styledString.getString();
+// for (StyleRange styleRange : styledString.getStyleRanges()) {
+// if (styleRange.strikeout) {
+// extractedText.append(unstyledString.substring(styleRange.start, styleRange.start + styleRange.length));
+// }
+// }
+// assertEquals(expectedString, extractedText.toString());
+// }
+// };
+ }
+
+}
diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/YamlLanguageServerTest.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/YamlLanguageServerTests.java
similarity index 56%
rename from vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/YamlLanguageServerTest.java
rename to vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/YamlLanguageServerTests.java
index bf65645f9..af694eaab 100644
--- a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/YamlLanguageServerTest.java
+++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/YamlLanguageServerTests.java
@@ -18,10 +18,10 @@ import io.typefox.lsapi.InitializeResult;
import io.typefox.lsapi.ServerCapabilities;
import io.typefox.lsapi.TextDocumentSyncKind;
-public class YamlLanguageServerTest {
+public class YamlLanguageServerTests {
public static File getTestResource(String name) throws URISyntaxException {
- return Paths.get(YamlLanguageServerTest.class.getResource(name).toURI()).toFile();
+ return Paths.get(YamlLanguageServerTests.class.getResource(name).toURI()).toFile();
}
@Test
@@ -39,34 +39,6 @@ public class YamlLanguageServerTest {
}
- @Test public void completions() throws Exception {
- LanguageServerHarness harness = new LanguageServerHarness(YamlLanguageServer::new);
-
- File workspaceRoot = getTestResource("/workspace/");
- assertExpectedInitResult(harness.intialize(workspaceRoot));
-
- TextDocumentInfo doc = harness.openDocument(getTestResource("/workspace/testfile.yml"));
-
- CompletionList completions = harness.getCompletions(doc, doc.positionOf("foo"));
- assertThat(completions.isIncomplete()).isFalse();
- assertThat(completions.getItems())
- .extracting(CompletionItem::getLabel)
- .containsExactly("TypeScript", "JavaScript");
-
- List resolved = harness.resolveCompletions(completions);
- assertThat(resolved)
- .extracting(CompletionItem::getLabel)
- .containsExactly("TypeScript", "JavaScript");
-
- assertThat(resolved)
- .extracting(CompletionItem::getDetail)
- .containsExactly("TypeScript details", "JavaScript details");
-
- assertThat(resolved)
- .extracting(CompletionItem::getDocumentation)
- .containsExactly("TypeScript docs", "JavaScript docs");
- }
-
private void assertExpectedInitResult(InitializeResult initResult) {
assertThat(initResult.getCapabilities().getCompletionProvider().getResolveProvider()).isTrue();
assertThat(initResult.getCapabilities().getTextDocumentSync()).isEqualTo(TextDocumentSyncKind.Full);