Content assist for 'domains' inside of route-strings
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
package org.springframework.ide.vscode.commons.languageserver.completion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -295,7 +296,7 @@ public class DocumentEdits implements ProposalApplier {
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<Edit> edits = new ArrayList<Edit>();
|
||||
private List<Edit> edits = new ArrayList<Edit>();
|
||||
private IDocument doc;
|
||||
|
||||
public DocumentEdits(IDocument doc) {
|
||||
|
||||
@@ -58,18 +58,17 @@ public class FuzzyMatcher {
|
||||
//tend to favor matches at the end of the string over matches in the middle.
|
||||
skips+=dlen-dpos; //but do count the extra chars at end => more extra = worse score
|
||||
}
|
||||
return score(gaps, skips);
|
||||
return score(gaps, skips, pattern);
|
||||
}
|
||||
|
||||
private static double score(int gaps, int skips) {
|
||||
private static double score(int gaps, int skips, String pattern) {
|
||||
if (gaps==0) {
|
||||
//gaps == 0 means a prefix match, ignore 'skips' at end of String and just sort
|
||||
// alphabetic (see STS-4049)
|
||||
double badness = 0.1; // all scored equally, assumes using a 'stable' sorter.
|
||||
return -badness; //higher is better
|
||||
return 0.5+pattern.length(); //all scored equally, assumes using a 'stable' sorter.
|
||||
} else {
|
||||
double badness = 1+gaps + skips/10000.0; // higher is worse
|
||||
return -badness; //higher is better
|
||||
double badness = 1+gaps + skips/1000.0; // higher is worse
|
||||
return 1.0/badness + pattern.length(); //higher is better
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,20 @@ public abstract class AbstractYamlAssistContext implements YamlAssistContext {
|
||||
return doc;
|
||||
}
|
||||
|
||||
protected DocumentRegion getCustomAssistRegion(YamlDocument doc, SNode node, int offset) {
|
||||
if (node.getNodeType()==SNodeType.KEY) {
|
||||
SKeyNode keyNode = (SKeyNode) node;
|
||||
if (keyNode.isInValue(offset)) {
|
||||
int valueStart = keyNode.getColonOffset()+1;
|
||||
int valueEnd = keyNode.getNodeEnd(); // assumes we only look at the current line, good enough for now
|
||||
return new DocumentRegion(doc.getDocument(), valueStart, valueEnd);
|
||||
}
|
||||
}
|
||||
return null; // TODO Reaching here might mean support for calling the custom assistant isn't
|
||||
// implemented for this kind of context yet. It will have to be expanded upon
|
||||
// as the need for it arises in real use-cases.
|
||||
}
|
||||
|
||||
protected final String getPrefix(YamlDocument doc, SNode node, int offset) {
|
||||
//For value completions... in general we would like to determine the whole text
|
||||
// corresponding to the value, so a simplistic backwards scan isn't good enough.
|
||||
|
||||
@@ -84,7 +84,6 @@ public class DefaultCompletionFactory implements CompletionFactory {
|
||||
public class ValueProposal extends ScoreableProposal {
|
||||
|
||||
private String value;
|
||||
//private String query;
|
||||
private String label;
|
||||
private YType type;
|
||||
private double baseScore;
|
||||
@@ -94,7 +93,6 @@ public class DefaultCompletionFactory implements CompletionFactory {
|
||||
|
||||
public ValueProposal(String value, String query, String label, YType type, Renderable docs, double score, DocumentEdits edits, YTypeUtil typeUtil) {
|
||||
this.value = value;
|
||||
//this.query = query;
|
||||
this.label = label;
|
||||
this.type = type;
|
||||
this.docs = docs;
|
||||
|
||||
@@ -32,7 +32,9 @@ public abstract class TransformedCompletion extends ScoreableProposal {
|
||||
this.original = proposal;
|
||||
}
|
||||
|
||||
protected abstract String tranformLabel(String originalLabel);
|
||||
protected String tranformLabel(String originalLabel) {
|
||||
return originalLabel;
|
||||
}
|
||||
protected abstract DocumentEdits transformEdit(DocumentEdits textEdit);
|
||||
|
||||
@Override
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment.YamlPathSegmentType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.ISubCompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.SNodeDynamicSchemaContext;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil;
|
||||
@@ -84,6 +85,13 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
|
||||
|
||||
@Override
|
||||
public Collection<ICompletionProposal> getCompletions(YamlDocument doc, SNode node, int offset) throws Exception {
|
||||
ISubCompletionEngine customContentAssistant = typeUtil.getCustomContentAssistant(type);
|
||||
if (customContentAssistant!=null) {
|
||||
DocumentRegion region = getCustomAssistRegion(doc, node, offset);
|
||||
if (region!=null) {
|
||||
return customContentAssistant.getCompletions(completionFactory(), region, region.toRelative(offset));
|
||||
}
|
||||
}
|
||||
String query = getPrefix(doc, node, offset);
|
||||
List<ICompletionProposal> valueCompletions = getValueCompletions(doc, node, offset, query);
|
||||
if (!valueCompletions.isEmpty()) {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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.commons.yaml.schema;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.CompletionFactory;
|
||||
|
||||
/**
|
||||
* Interface that can be used by a {@link ICompletionEngine} to delegate to a
|
||||
* 'helper' completion engine that computes completions for some sub-region of
|
||||
* the document.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ISubCompletionEngine {
|
||||
|
||||
/**
|
||||
* @param region The relevant subregion of the document (typically, the sub-engine only cares about the text
|
||||
* within this particular region.)
|
||||
* @param offset The cursor position relative to the region.
|
||||
*/
|
||||
List<ICompletionProposal> getCompletions(CompletionFactory f, DocumentRegion region, int offset);
|
||||
|
||||
|
||||
}
|
||||
@@ -224,6 +224,11 @@ public class YTypeFactory {
|
||||
public List<Constraint> getConstraints(YType type) {
|
||||
return ((AbstractType)type).getConstraints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISubCompletionEngine getCustomContentAssistant(YType type) {
|
||||
return ((AbstractType)type).getCustomContentAssistant();
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -239,11 +244,21 @@ public class YTypeFactory {
|
||||
private Map<String, YTypedProperty> cachedPropertyMap;
|
||||
private SchemaContextAware<Callable<Collection<YValueHint>>> hintProvider;
|
||||
private List<Constraint> constraints = new ArrayList<>(2);
|
||||
private ISubCompletionEngine customContentAssistant = null;
|
||||
|
||||
public boolean isSequenceable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ISubCompletionEngine getCustomContentAssistant() {
|
||||
return customContentAssistant;
|
||||
}
|
||||
|
||||
public AbstractType setCustomContentAssistant(ISubCompletionEngine customContentAssistant) {
|
||||
this.customContentAssistant = customContentAssistant;
|
||||
return this;
|
||||
}
|
||||
|
||||
public YType inferMoreSpecificType(DynamicSchemaContext dc) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ package org.springframework.ide.vscode.commons.yaml.schema;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParser;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraint;
|
||||
|
||||
@@ -47,4 +48,6 @@ public interface YTypeUtil {
|
||||
*/
|
||||
YType inferMoreSpecificType(YType type, DynamicSchemaContext dc);
|
||||
List<Constraint> getConstraints(YType type);
|
||||
|
||||
ISubCompletionEngine getCustomContentAssistant(YType type);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
eclipse.preferences.version=1
|
||||
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
|
||||
sp_cleanup.add_default_serial_version_id=true
|
||||
sp_cleanup.add_generated_serial_version_id=false
|
||||
sp_cleanup.add_missing_annotations=true
|
||||
sp_cleanup.add_missing_deprecated_annotations=true
|
||||
sp_cleanup.add_missing_methods=false
|
||||
sp_cleanup.add_missing_nls_tags=false
|
||||
sp_cleanup.add_missing_override_annotations=true
|
||||
sp_cleanup.add_missing_override_annotations_interface_methods=true
|
||||
sp_cleanup.add_serial_version_id=false
|
||||
sp_cleanup.always_use_blocks=true
|
||||
sp_cleanup.always_use_parentheses_in_expressions=false
|
||||
sp_cleanup.always_use_this_for_non_static_field_access=false
|
||||
sp_cleanup.always_use_this_for_non_static_method_access=false
|
||||
sp_cleanup.convert_functional_interfaces=false
|
||||
sp_cleanup.convert_to_enhanced_for_loop=false
|
||||
sp_cleanup.correct_indentation=false
|
||||
sp_cleanup.format_source_code=false
|
||||
sp_cleanup.format_source_code_changes_only=false
|
||||
sp_cleanup.insert_inferred_type_arguments=false
|
||||
sp_cleanup.make_local_variable_final=true
|
||||
sp_cleanup.make_parameters_final=false
|
||||
sp_cleanup.make_private_fields_final=true
|
||||
sp_cleanup.make_type_abstract_if_missing_method=false
|
||||
sp_cleanup.make_variable_declarations_final=false
|
||||
sp_cleanup.never_use_blocks=false
|
||||
sp_cleanup.never_use_parentheses_in_expressions=true
|
||||
sp_cleanup.on_save_use_additional_actions=true
|
||||
sp_cleanup.organize_imports=false
|
||||
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
|
||||
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
|
||||
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
|
||||
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
|
||||
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
|
||||
sp_cleanup.remove_private_constructors=true
|
||||
sp_cleanup.remove_redundant_type_arguments=false
|
||||
sp_cleanup.remove_trailing_whitespaces=true
|
||||
sp_cleanup.remove_trailing_whitespaces_all=true
|
||||
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
|
||||
sp_cleanup.remove_unnecessary_casts=true
|
||||
sp_cleanup.remove_unnecessary_nls_tags=false
|
||||
sp_cleanup.remove_unused_imports=false
|
||||
sp_cleanup.remove_unused_local_variables=false
|
||||
sp_cleanup.remove_unused_private_fields=true
|
||||
sp_cleanup.remove_unused_private_members=false
|
||||
sp_cleanup.remove_unused_private_methods=true
|
||||
sp_cleanup.remove_unused_private_types=true
|
||||
sp_cleanup.sort_members=false
|
||||
sp_cleanup.sort_members_all=false
|
||||
sp_cleanup.use_anonymous_class_creation=false
|
||||
sp_cleanup.use_blocks=false
|
||||
sp_cleanup.use_blocks_only_for_return_and_throw=false
|
||||
sp_cleanup.use_lambda=true
|
||||
sp_cleanup.use_parentheses_in_expressions=false
|
||||
sp_cleanup.use_this_for_non_static_field_access=false
|
||||
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
|
||||
sp_cleanup.use_this_for_non_static_method_access=false
|
||||
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
|
||||
@@ -45,10 +45,12 @@ public class ManifestYmlSchema implements YamlSchema {
|
||||
|
||||
private static final String HEALTH_CHECK_HTTP_ENDPOINT_PROP = "health-check-http-endpoint";
|
||||
private static final String HEALTH_CHECK_TYPE_PROP = "health-check-type";
|
||||
|
||||
|
||||
private final AbstractType TOPLEVEL_TYPE;
|
||||
private final YTypeUtil TYPE_UTIL;
|
||||
|
||||
public final AbstractType t_route_string;
|
||||
|
||||
private static final Set<String> TOPLEVEL_EXCLUDED = ImmutableSet.of(
|
||||
"name", "host", "hosts"
|
||||
);
|
||||
@@ -65,7 +67,7 @@ public class ManifestYmlSchema implements YamlSchema {
|
||||
if (markerNode != null) {
|
||||
String healthCheckType = getEffectiveHealthCheckType(ast, dc.getPath(), node);
|
||||
if (!"http".equals(healthCheckType)) {
|
||||
problems.accept(YamlSchemaProblems.problem(ManifestYamlSchemaProblemsTypes.IGNORED_PROPERTY,
|
||||
problems.accept(YamlSchemaProblems.problem(ManifestYamlSchemaProblemsTypes.IGNORED_PROPERTY,
|
||||
"This has no effect unless `"+HEALTH_CHECK_TYPE_PROP+"` is `http` (but it is currently set to `"+healthCheckType+"`)", markerNode));
|
||||
}
|
||||
}
|
||||
@@ -142,14 +144,12 @@ public class ManifestYmlSchema implements YamlSchema {
|
||||
YType t_string = f.yatomic("String");
|
||||
YType t_strings = f.yseq(t_string);
|
||||
|
||||
// "routes" has nested required property "route":
|
||||
// routes:
|
||||
// - route: someroute.io
|
||||
t_route_string = f.yatomic("RouteUri")
|
||||
.parseWith(new RouteValueParser(YTypeFactory.valuesFromHintProvider(domainsProvider)))
|
||||
.setCustomContentAssistant(new RouteContentAssistant(domainsProvider, this));
|
||||
|
||||
YBeanType route = f.ybean("Route");
|
||||
YAtomicType t_route_string = f.yatomic("route");
|
||||
route.addProperty(f.yprop("route", t_route_string).isRequired(true));
|
||||
t_route_string.parseWith(new RouteValueParser(YTypeFactory.valuesFromHintProvider(domainsProvider)));
|
||||
|
||||
YAtomicType t_memory = f.yatomic("Memory");
|
||||
t_memory.addHints("256M", "512M", "1024M");
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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.manifest.yaml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMatcher;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.CompletionFactory;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.ISubCompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YValueHint;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Custom content assistant for making 'domains' suggestions inside of a RouteUri.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class RouteContentAssistant implements ISubCompletionEngine {
|
||||
|
||||
private static final Pattern STOP_AP = Pattern.compile("[#:/]");
|
||||
|
||||
private Callable<Collection<YValueHint>> domainsProvider;
|
||||
|
||||
private ManifestYmlSchema schema;
|
||||
|
||||
public RouteContentAssistant(Callable<Collection<YValueHint>> domainsProvider, ManifestYmlSchema manifestYmlSchema) {
|
||||
this.domainsProvider = domainsProvider;
|
||||
this.schema = manifestYmlSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ICompletionProposal> getCompletions(CompletionFactory f, DocumentRegion region, int offset) {
|
||||
// offset = 0 means: "<*>abc"
|
||||
// offset = 1 means: "a<*>bc"
|
||||
// offset = 2 means: "ab<*>c"
|
||||
try {
|
||||
region = chopEnd(region, offset);
|
||||
// region = "abc"
|
||||
// offset = 3 means: "abc<*>"
|
||||
// So offset > 3 means we are 'our of bounds for this content assistant
|
||||
if (offset<=region.length()) {
|
||||
String[] queries = getQueries(region.subSequence(0, offset));
|
||||
Collection<YValueHint> domains = domainsProvider.call();
|
||||
List<ICompletionProposal> proposals = new ArrayList<>();
|
||||
for (YValueHint domain : domains) {
|
||||
for (String query : queries) {
|
||||
double score = FuzzyMatcher.matchScore(query, domain.getValue());
|
||||
if (score!=0.0) {
|
||||
proposals.add(createProposal(f, region, offset, query, score, domain));
|
||||
break; //break here so we select the first (i.e. longest) query that matches
|
||||
}
|
||||
}
|
||||
}
|
||||
return proposals;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
//Ignore. This is somewhat expected. Stuff can go wrong resolving the domains
|
||||
// and CA engine just doesn't provide CA in that case.
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
private String[] getQueries(DocumentRegion region) {
|
||||
// Example of what this should do
|
||||
// region = "foo.bar.com"
|
||||
// We have to make a guess which part of this is the host-name and which part is domain-name
|
||||
// The split could be either at the very start, or at any one of the '.' chars.
|
||||
// So the possible queries are as follows:
|
||||
// - "foo.bar.com"
|
||||
// - "bar.com"
|
||||
// - "com"
|
||||
region = region.trimStart();
|
||||
DocumentRegion[] pieces = region.split('.');
|
||||
String[] queries = new String[pieces.length];
|
||||
for (int i = pieces.length-1; i >= 0; i--) {
|
||||
if (i==pieces.length-1) {
|
||||
queries[i] = pieces[i].toString();
|
||||
} else {
|
||||
queries[i] = pieces[i] + "." + queries[i+1];
|
||||
}
|
||||
}
|
||||
return queries;
|
||||
}
|
||||
|
||||
private ICompletionProposal createProposal(CompletionFactory f, DocumentRegion region, int offset, String query, double score, YValueHint domain) {
|
||||
DocumentEdits edits = new DocumentEdits(region.getDocument());
|
||||
region = region.subSequence(offset - query.length());
|
||||
boolean needSpace = region.textBefore(1).charAt(0)==':'; //Add extra space after ':' if needed!
|
||||
edits.replace(region.getStart(), region.getEnd(), needSpace ? " "+domain.getValue() : domain.getValue());
|
||||
return f.valueProposal(domain.getValue(), query, domain.getLabel(), schema.t_route_string,
|
||||
domain.getDocumentation(), score, edits, schema.getTypeUtil());
|
||||
}
|
||||
|
||||
/**
|
||||
* Chop-off the uninteresting parts of region (whitespace, comments, anything after the first ':' or '/'
|
||||
*/
|
||||
private DocumentRegion chopEnd(DocumentRegion region, int offset) {
|
||||
Matcher matcher = STOP_AP.matcher(region);
|
||||
if (matcher.find()) {
|
||||
region = region.subSequence(0, matcher.start());
|
||||
}
|
||||
if (offset<=region.getLength()) {
|
||||
//We want to trim whitespace of the end, but must be careful not to trim past the offset
|
||||
DocumentRegion trimmed = region.trimEnd();
|
||||
if (offset<=trimmed.length()) {
|
||||
return trimmed;
|
||||
} else {
|
||||
return region.subSequence(0, offset);
|
||||
}
|
||||
}
|
||||
return region;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -463,7 +463,7 @@ public class ManifestYamlEditorTest {
|
||||
);
|
||||
editor.assertProblems(/*NONE*/);
|
||||
}
|
||||
|
||||
|
||||
@Test public void reconcileHealthHttpEndPointIgnoredWarning() throws Exception {
|
||||
Editor editor;
|
||||
Diagnostic problem;
|
||||
@@ -483,7 +483,7 @@ public class ManifestYamlEditorTest {
|
||||
" health-check-http-endpoint: /health"
|
||||
);
|
||||
editor.assertProblems(/*NONE*/);
|
||||
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: my-app\n" +
|
||||
@@ -499,7 +499,7 @@ public class ManifestYamlEditorTest {
|
||||
" health-check-http-endpoint: /health"
|
||||
);
|
||||
editor.assertProblems(/*NONE*/);
|
||||
|
||||
|
||||
editor = harness.newEditor(
|
||||
"health-check-type: http\n" +
|
||||
"applications:\n" +
|
||||
@@ -508,12 +508,12 @@ public class ManifestYamlEditorTest {
|
||||
" health-check-http-endpoint: /health"
|
||||
);
|
||||
editor.assertProblems("health-check-http-endpoint|This has no effect unless `health-check-type` is `http` (but it is currently set to `process`)");
|
||||
|
||||
|
||||
editor = harness.newEditor(
|
||||
"health-check-http-endpoint: /health"
|
||||
);
|
||||
editor.assertProblems("health-check-http-endpoint|This has no effect unless `health-check-type` is `http` (but it is currently set to `port`)");
|
||||
|
||||
|
||||
editor = harness.newEditor(
|
||||
"health-check-type: process\n" +
|
||||
"health-check-http-endpoint: /health"
|
||||
@@ -662,19 +662,19 @@ public class ManifestYamlEditorTest {
|
||||
assertEquals("an-org : a-space [test.io]", c.getDocumentation());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test public void domainReconcile() throws Exception {
|
||||
List<CFDomain> domains = ImmutableList.of(mockDomain("one.com"), mockDomain("two.com"));
|
||||
when(cloudfoundry.client.getDomains()).thenReturn(domains);
|
||||
Editor editor;
|
||||
Diagnostic p;
|
||||
|
||||
|
||||
editor = harness.newEditor(
|
||||
"domain: bad.com"
|
||||
);
|
||||
p = editor.assertProblems("bad.com|unknown 'Domain'. Valid values are: [one.com, two.com]").get(0);
|
||||
assertEquals(DiagnosticSeverity.Warning, p.getSeverity());
|
||||
|
||||
|
||||
editor= harness.newEditor(
|
||||
"domains:\n" +
|
||||
"- one.com\n" +
|
||||
@@ -1282,7 +1282,7 @@ public class ManifestYamlEditorTest {
|
||||
" - route: host.springsource.org\n");
|
||||
editor.assertProblems();
|
||||
}
|
||||
|
||||
|
||||
@Test public void dashedContentAssistForServices() throws Exception {
|
||||
Editor editor;
|
||||
CFServiceInstance service = mock(CFServiceInstance.class);
|
||||
@@ -1401,6 +1401,183 @@ public class ManifestYamlEditorTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Test public void contentAssistInsideRouteDomain() throws Exception {
|
||||
Editor editor;
|
||||
|
||||
ImmutableList<CFDomain> domains = ImmutableList.of(
|
||||
mockDomain("cfapps.io"),
|
||||
mockDomain("dsyer.com")
|
||||
);
|
||||
when(cloudfoundry.client.getDomains()).thenReturn(domains);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route:<*>"
|
||||
);
|
||||
editor.assertCompletions(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: cfapps.io<*>"
|
||||
, // ==============
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: dsyer.com<*>"
|
||||
);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: <*>"
|
||||
);
|
||||
editor.assertCompletions(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: cfapps.io<*>"
|
||||
, // ==============
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: dsyer.com<*>"
|
||||
);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: dsyer.<*>"
|
||||
);
|
||||
editor.assertCompletions(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: dsyer.com<*>"
|
||||
, // ==============
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: dsyer.cfapps.io<*>"
|
||||
);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: test.<*>"
|
||||
);
|
||||
CompletionItem c = editor.assertCompletions(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: test.cfapps.io<*>"
|
||||
, // ==============
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: test.dsyer.com<*>"
|
||||
).get(0);
|
||||
assertEquals("cfapps.io", c.getLabel());
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: foo.bar.<*>"
|
||||
);
|
||||
editor.assertCompletions(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: foo.bar.cfapps.io<*>"
|
||||
, // ==============
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: foo.bar.dsyer.com<*>"
|
||||
);
|
||||
|
||||
/// no content assist inside of path or port section of route:
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: foo.bar.com/<*>"
|
||||
);
|
||||
editor.assertCompletions(/*NONE*/);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: foo.bar.com:<*>"
|
||||
);
|
||||
editor.assertCompletions(/*NONE*/);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: foo.bar.com:7777/blah<*>"
|
||||
);
|
||||
editor.assertCompletions(/*NONE*/);
|
||||
|
||||
// Martin's most fancy example:
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: test.cf<*>pps.io/superpath\n" +
|
||||
" memory: 1024M\n"
|
||||
);
|
||||
editor.assertCompletions(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: test.cfapps.io<*>/superpath\n" +
|
||||
" memory: 1024M\n"
|
||||
);
|
||||
|
||||
//Kris's variants of Martin's example:
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: test.ds<*>pps.io/superpath\n" +
|
||||
" memory: 1024M\n"
|
||||
);
|
||||
editor.assertCompletions(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: test.dsyer.com<*>/superpath\n" +
|
||||
" memory: 1024M\n"
|
||||
);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: test.ds<*>pps.io:8888/superpath\n" +
|
||||
" memory: 1024M\n"
|
||||
);
|
||||
editor.assertCompletions(
|
||||
"applications:\n" +
|
||||
"- name: test\n" +
|
||||
" routes:\n" +
|
||||
" - route: test.dsyer.com<*>:8888/superpath\n" +
|
||||
" memory: 1024M\n"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private List<CompletionItem> assertCompletions(String textBefore, String... textAfter) throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user