() {
- @Override
- public int compare(Diagnostic o1, Diagnostic o2) {
- int diff = compare(o1.getRange().getStart(), o2.getRange().getStart());
- if (diff!=0) return diff;
- return compare(o1.getRange().getEnd(), o2.getRange().getEnd());
- }
-
- private int compare(Position p1, Position p2) {
- int d = p1.getLine() - p2.getLine();
- if (d!=0) return d;
- return p1.getCharacter() - p2.getCharacter();
- }
- };
-
- private LanguageServerHarness harness;
- private TextDocumentInfo document;
-
- public Editor(LanguageServerHarness harness, String contents) throws Exception {
- this.harness = harness;
- this.document = harness.openDocument(harness.createWorkingCopy(contents));
- }
-
- /**
- * Check that a 'expectedProblems' are found by the reconciler. Expected problems are
- * specified by string of the form "${badSnippet}|${messageSnippet}". The badSnippet
- * is the text expected to be covered by the marker's region and the message snippet must
- * be found in the error marker's message.
- *
- * The expected problems are matched one-to-one in the order given (so markers in the
- * editor must appear in the expected order for the assert to pass).
- *
- * @param editor
- * @param expectedProblems
- * @throws BadLocationException
- */
- public void assertProblems(String... expectedProblems) throws Exception {
- Editor editor = this;
- List actualProblems = new ArrayList<>(editor.reconcile());
- Collections.sort(actualProblems, PROBLEM_COMPARATOR);
- String bad = null;
- if (actualProblems.size()!=expectedProblems.length) {
- bad = "Wrong number of problems (expecting "+expectedProblems.length+" but found "+actualProblems.size()+")";
- } else {
- for (int i = 0; i < expectedProblems.length; i++) {
- if (!matchProblem(editor, actualProblems.get(i), expectedProblems[i])) {
- bad = "First mismatch at index "+i+": "+expectedProblems[i]+"\n";
- break;
- }
- }
- }
- if (bad!=null) {
- fail(bad+problemSumary(editor, actualProblems));
- }
- }
-
- private String problemSumary(Editor editor, List actualProblems) throws Exception {
- StringBuilder buf = new StringBuilder();
- for (Diagnostic p : actualProblems) {
- buf.append("\n----------------------\n");
-
- String snippet = editor.getText(p.getRange());
- buf.append("("+p.getRange().getStart().getLine()+", "+p.getRange().getStart().getCharacter()+")["+snippet+"]:\n");
- buf.append(" "+p.getMessage());
- }
- return buf.toString();
- }
-
- public String getText(Range range) {
- return document.getText(range);
- }
-
- public void setText(String newContent) throws Exception {
- document = harness.changeDocument(document.getUri(), newContent);
- }
-
- private boolean matchProblem(Editor editor, Diagnostic problem, String expect) {
- String[] parts = expect.split("\\|");
- assertEquals(2, parts.length);
- String badSnippet = parts[0];
- String messageSnippet = parts[1];
- boolean spaceSensitive = badSnippet.trim().length() reconcile() {
- // We assume the language server works synchronously for now and it does an immediate reconcile
- // when the document changes. In the future this is probably not going to be the case though and then this
- // method will need to somehow ensure the linter is done working before retrieving the problems from the
- // test harness.
- PublishDiagnosticsParams diagnostics = harness.getDiagnostics(document);
- if (diagnostics!=null) {
- return (List) diagnostics.getDiagnostics();
- }
- return Collections.emptyList();
- }
-
-}
diff --git a/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java b/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java
deleted file mode 100644
index d7e81a611..000000000
--- a/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/testharness/LanguageServerHarness.java
+++ /dev/null
@@ -1,246 +0,0 @@
-package org.springframework.ide.vscode.testharness;
-
-import java.io.File;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.Callable;
-import java.util.stream.Collectors;
-
-import org.assertj.core.api.Condition;
-
-import io.typefox.lsapi.ClientCapabilitiesImpl;
-import io.typefox.lsapi.CompletionItem;
-import io.typefox.lsapi.CompletionList;
-import io.typefox.lsapi.Diagnostic;
-import io.typefox.lsapi.DidChangeTextDocumentParamsImpl;
-import io.typefox.lsapi.DidOpenTextDocumentParamsImpl;
-import io.typefox.lsapi.InitializeParamsImpl;
-import io.typefox.lsapi.InitializeResult;
-import io.typefox.lsapi.Position;
-import io.typefox.lsapi.PositionImpl;
-import io.typefox.lsapi.PublishDiagnosticsParams;
-import io.typefox.lsapi.Range;
-import io.typefox.lsapi.ServerCapabilities;
-import io.typefox.lsapi.TextDocumentContentChangeEventImpl;
-import io.typefox.lsapi.TextDocumentItemImpl;
-import io.typefox.lsapi.TextDocumentPositionParamsImpl;
-import io.typefox.lsapi.VersionedTextDocumentIdentifierImpl;
-import io.typefox.lsapi.services.LanguageServer;
-
-public class LanguageServerHarness {
-
- //Warning this 'harness' is not very good yet. It just implements bare minimum to
- // be able to test the MyLanguageServer example.
-
- private Random random = new Random();
-
- private Callable extends LanguageServer> factory;
-
- private LanguageServer server;
-
- private InitializeResult initResult;
-
- private Map documents = new HashMap<>();
- private Map diagnostics = new HashMap<>();
-
- public LanguageServerHarness(Callable extends LanguageServer> factory) throws Exception {
- this.factory = factory;
- }
-
- public synchronized TextDocumentInfo getOrReadFile(File file) throws Exception {
- String uri = file.toURI().toString();
- TextDocumentInfo d = documents.get(uri);
- if (d==null) {
- documents.put(uri, d = readFile(file));
- }
- return d;
- }
-
- public TextDocumentInfo readFile(File file) throws Exception {
- byte[] encoded = Files.readAllBytes(file.toPath());
- String content = new String(encoded, getEncoding());
- TextDocumentItemImpl document = new TextDocumentItemImpl();
- document.setText(content);
- document.setUri(file.toURI().toString());
- document.setVersion(getFirstVersion());
- document.setLanguageId(getLanguageId());
- return new TextDocumentInfo(document);
- }
-
- private synchronized TextDocumentItemImpl setDocumentContent(String uri, String newContent) {
- TextDocumentInfo o = documents.get(uri);
- TextDocumentItemImpl n = new TextDocumentItemImpl();
- n.setLanguageId(o.getLanguageId());
- n.setText(newContent);
- n.setVersion(o.getVersion()+1);
- n.setUri(o.getUri());
- documents.put(uri, new TextDocumentInfo(n));
- return n;
- }
-
- protected Charset getEncoding() {
- return Charset.forName("utf8");
- }
-
- protected String getLanguageId() {
- return "plaintext";
- }
-
- protected String getFileExtension() {
- return ".txt";
- }
-
- private synchronized void receiveDiagnostics(PublishDiagnosticsParams diags) {
- this.diagnostics.put(diags.getUri(), diags);
- }
-
- public InitializeResult intialize(File workspaceRoot) throws Exception {
- server = factory.call();
- int parentPid = random.nextInt(40000)+1000;
- InitializeParamsImpl initParams = new InitializeParamsImpl();
- initParams.setRootPath(workspaceRoot== null?null:workspaceRoot.toString());
- initParams.setProcessId(parentPid);
- ClientCapabilitiesImpl clientCap = new ClientCapabilitiesImpl();
- initParams.setCapabilities(clientCap);
- initResult = server.initialize(initParams).get();
-
- server.getTextDocumentService().onPublishDiagnostics(this::receiveDiagnostics);
- return initResult;
- }
-
- public TextDocumentInfo openDocument(TextDocumentInfo documentInfo) throws Exception {
- DidOpenTextDocumentParamsImpl didOpen = new DidOpenTextDocumentParamsImpl();
- didOpen.setTextDocument(documentInfo.getDocument());
- didOpen.setText(documentInfo.getText());
- didOpen.setUri(documentInfo.getUri());
- server.getTextDocumentService().didOpen(didOpen);
- return documentInfo;
- }
-
- public TextDocumentInfo openDocument(File file) throws Exception {
- return openDocument(getOrReadFile(file));
- }
-
- public TextDocumentInfo changeDocument(String uri, String newContent) throws Exception {
- TextDocumentItemImpl textDocument = setDocumentContent(uri, newContent);
- DidChangeTextDocumentParamsImpl didChange = new DidChangeTextDocumentParamsImpl();
- VersionedTextDocumentIdentifierImpl version = new VersionedTextDocumentIdentifierImpl();
- version.setUri(uri);
- version.setVersion(textDocument.getVersion());
- didChange.setTextDocument(version);
- switch (getDocumentSyncMode()) {
- case ServerCapabilities.SYNC_NONE:
- break; //nothing todo
- case ServerCapabilities.SYNC_INCREMENTAL:
- throw new IllegalStateException("Incremental sync not yet supported by this test harness");
- case ServerCapabilities.SYNC_FULL:
- TextDocumentContentChangeEventImpl change = new TextDocumentContentChangeEventImpl();
- change.setText(newContent);
- didChange.setContentChanges(Collections.singletonList(change));
- break;
- default:
- throw new IllegalStateException("Unkown SYNC mode: "+getDocumentSyncMode());
- }
- server.getTextDocumentService().didChange(didChange);
- return documents.get(uri);
- }
-
- private int getDocumentSyncMode() {
- Integer mode = initResult.getCapabilities().getTextDocumentSync();
- return mode==null ? ServerCapabilities.SYNC_NONE : mode;
- }
-
- public PublishDiagnosticsParams getDiagnostics(TextDocumentInfo doc) {
- return diagnostics.get(doc.getUri());
- }
-
- public static Condition isDiagnosticWithSeverity(int severity) {
- return new Condition<>(
- (d) -> d.getSeverity()==severity,
- "Diagnostic with severity '"+severity+"'"
- );
- }
-
- public static Condition isDiagnosticCovering(TextDocumentInfo doc, String string) {
- return new Condition<>(
- (d) -> isDiagnosticCovering(d, doc, string),
- "Diagnostic covering '"+string+"'"
- );
- }
-
- public static final Condition isWarning = isDiagnosticWithSeverity(Diagnostic.SEVERITY_WARNING);
-
- public static boolean isDiagnosticCovering(Diagnostic diag, TextDocumentInfo doc, String string) {
- Range rng = diag.getRange();
- String actualText = doc.getText(rng);
- return string.equals(actualText);
- }
-
- public static Condition isDiagnosticOnLine(int line) {
- return new Condition<>(
- (d) -> d.getRange().getStart().getLine()==line,
- "Diagnostic on line "+line
- );
- }
-
- public CompletionList getCompletions(TextDocumentInfo doc, Position cursor) throws Exception {
- TextDocumentPositionParamsImpl params = new TextDocumentPositionParamsImpl();
- params.setPosition(toImpl(cursor));
- params.setTextDocument(doc.getId());
- return server.getTextDocumentService().completion(params).get();
- }
-
- private PositionImpl toImpl(Position pos) {
- if (pos instanceof PositionImpl) {
- return (PositionImpl) pos;
- } else {
- PositionImpl imp = new PositionImpl();
- imp.setCharacter(pos.getCharacter());
- imp.setLine(pos.getLine());
- return imp;
- }
- }
-
- private CompletionItem resolveCompletionItem(CompletionItem unresolved) {
- try {
- return server.getTextDocumentService().resolveCompletionItem(unresolved).get();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public List resolveCompletions(CompletionList completions) {
- return completions.getItems().stream()
- .map(this::resolveCompletionItem)
- .collect(Collectors.toList());
- }
-
- public Editor newEditor(String contents) throws Exception {
- return new Editor(this, contents);
- }
-
- public synchronized TextDocumentInfo createWorkingCopy(String contents) throws Exception {
- TextDocumentItemImpl doc = new TextDocumentItemImpl();
- doc.setLanguageId(getLanguageId());
- doc.setText(contents);
- doc.setUri(createTempUri());
- doc.setVersion(getFirstVersion());
- TextDocumentInfo docinfo = new TextDocumentInfo(doc);
- documents.put(docinfo.getUri(), docinfo);
- return docinfo;
- }
-
- protected int getFirstVersion() {
- return 1;
- }
-
- protected String createTempUri() throws Exception {
- return File.createTempFile("workingcopy", getFileExtension()).toURI().toString();
- }
-
-}
diff --git a/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/testharness/TextDocumentInfo.java b/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/testharness/TextDocumentInfo.java
deleted file mode 100644
index 1062f6bfb..000000000
--- a/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/testharness/TextDocumentInfo.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package org.springframework.ide.vscode.testharness;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import io.typefox.lsapi.Position;
-import io.typefox.lsapi.PositionImpl;
-import io.typefox.lsapi.Range;
-import io.typefox.lsapi.TextDocumentIdentifierImpl;
-import io.typefox.lsapi.TextDocumentItemImpl;
-
-public class TextDocumentInfo {
-
- Pattern NEWLINE = Pattern.compile("\\r|\\n|\\r\\n|\\n\\r");
-
- private final TextDocumentItemImpl document;
-
- private int[] _lineStarts;
-
- public TextDocumentInfo(TextDocumentItemImpl document) {
- this.document = document;
- }
-
- public String getLanguageId() {
- return getDocument().getLanguageId();
- }
-
- public int getVersion() {
- return getDocument().getVersion();
- }
-
- public String getText() {
- return getDocument().getText();
- }
-
- public String getUri() {
- return getDocument().getUri();
- }
-
- public TextDocumentItemImpl getDocument() {
- return document;
- }
-
- public String getText(Range rng) {
- int start = toOffset(rng.getStart());
- int end = toOffset(rng.getEnd());
- return getText().substring(start, end);
- }
-
- public int toOffset(Position p) {
- int startOfLine = startOfLine(p.getLine());
- return startOfLine+p.getCharacter();
- }
-
- private int startOfLine(int line) {
- return lineStarts()[line];
- }
-
- private int[] lineStarts() {
- if (_lineStarts==null) {
- _lineStarts = parseLines();
- }
- return _lineStarts;
- }
-
- private int[] parseLines() {
- List lineStarts = new ArrayList<>();
- lineStarts.add(0);
- Matcher matcher = NEWLINE.matcher(getText());
- int pos = 0;
- while (matcher.find(pos)) {
- lineStarts.add(pos = matcher.end());
- }
- int[] array = new int[lineStarts.size()];
- for (int i = 0; i < array.length; i++) {
- array[i] = lineStarts.get(i);
- }
- return array;
- }
-
- /**
- * Find and return the (first) position of a given text snippet in the
- * document.
- *
- * @return The position, or null if the snippet can't be found.
- */
- public Position positionOf(String snippet) {
- int offset = getText().indexOf(snippet);
- if (offset>=0) {
- return toPosition(offset);
- }
- return null;
- }
-
- public Position toPosition(int offset) {
- int line = lineNumber(offset);
- int startOfLine = startOfLine(line);
- int column = offset - startOfLine;
- PositionImpl pos = new PositionImpl();
- pos.setCharacter(column);
- pos.setLine(line);
- return pos;
- }
-
- /**
- * Determine the line-number a given offset (i.e. what line is the offset inside of?)
- */
- private int lineNumber(int offset) {
- int[] lineStarts = lineStarts();
- // TODO Could use binary search which is faster
- int lineNumber = 0;
- for (int i = 0; i < lineStarts.length; i++) {
- if (lineStarts[i]<=offset) {
- lineNumber = i;
- } else {
- return lineNumber;
- }
- }
- return lineNumber;
- }
-
- public TextDocumentIdentifierImpl getId() {
- TextDocumentIdentifierImpl id = new TextDocumentIdentifierImpl();
- id.setUri(getUri());
- return id;
- }
-
-}
diff --git a/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java b/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java
deleted file mode 100644
index 11c33e3ca..000000000
--- a/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.springframework.ide.vscode.yaml;
-
-import org.junit.Test;
-import org.springframework.ide.vscode.testharness.Editor;
-import org.springframework.ide.vscode.testharness.LanguageServerHarness;
-import org.springframework.ide.vscode.yaml.YamlLanguageServer;
-
-/**
- * This class is a placeholder where we will attempt to copy and port
- * as many tests a possible from
- * org.springframework.ide.eclipse.boot.properties.editor.test.YamlEditorTests
- *
- * @author Kris De Volder
- */
-public class ApplicationYamlEditorTest {
-
- @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(
- "somemap: val\n"+
- "- sequence"
- );
-
- editor.assertProblems(
- "-|expected "
- );
-
- editor.setText(
- "- sequence\n" +
- "zomemap: val"
- );
-
- editor.assertProblems(
- "z|expected "
- );
- }
-}
diff --git a/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/yaml/ManifestYamlEditorTest.java b/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/yaml/ManifestYamlEditorTest.java
new file mode 100644
index 000000000..f25187a38
--- /dev/null
+++ b/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/yaml/ManifestYamlEditorTest.java
@@ -0,0 +1,381 @@
+/*******************************************************************************
+ * 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.junit.Before;
+import org.junit.Test;
+import org.springframework.ide.vscode.testharness.Editor;
+import org.springframework.ide.vscode.testharness.LanguageServerHarness;
+
+public class ManifestYamlEditorTest {
+
+ LanguageServerHarness harness;
+
+ @Before public void setup() throws Exception {
+ harness = new LanguageServerHarness(YamlLanguageServer::new);
+ harness.intialize(null);
+ }
+
+ @Test public void testReconcileCatchesParseError() throws Exception {
+
+ 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(
+ "somemap: val\n"+
+ "- sequence"
+ );
+
+ editor.assertProblems(
+ "-|expected "
+ );
+
+ editor.setText(
+ "- sequence\n" +
+ "zomemap: val"
+ );
+
+ editor.assertProblems(
+ "z|expected "
+ );
+ }
+
+ @Test
+ public void toplevelCompletions() throws Exception {
+ Editor editor;
+ editor = harness.newEditor("<*>");
+ editor.assertCompletions(
+ "applications:\n"+
+ " - <*>",
+ // ---------------
+ "buildpack: <*>",
+ // ---------------
+ "command: <*>",
+ // ---------------
+ "disk_quota: <*>",
+ // ---------------
+ "domain: <*>",
+ // ---------------
+ "domains:\n"+
+ " - <*>",
+ // ---------------
+ "env:\n"+
+ " <*>",
+ // ---------------
+// "host: <*>",
+ // ---------------
+// "hosts: \n"+
+// " - <*>",
+ // ---------------
+ "inherit: <*>",
+ // ---------------
+ "instances: <*>",
+ // ---------------
+ "memory: <*>",
+ // ---------------
+// "name: <*>",
+ // ---------------
+ "no-hostname: <*>",
+ // ---------------
+ "no-route: <*>",
+ // ---------------
+ "path: <*>",
+ // ---------------
+ "random-route: <*>",
+ // ---------------
+ "services:\n"+
+ " - <*>",
+ // ---------------
+ "stack: <*>",
+ // ---------------
+ "timeout: <*>"
+ );
+
+ editor = harness.newEditor("ranro<*>");
+ editor.assertCompletions(
+ "random-route: <*>"
+ );
+ }
+
+ @Test
+ public void nestedCompletions() throws Exception {
+ Editor editor;
+ editor = harness.newEditor(
+ "applications:\n" +
+ " - <*>"
+ );
+ editor.assertCompletions(
+ // ---------------
+ "applications:\n" +
+ " - buildpack: <*>",
+ // ---------------
+ "applications:\n" +
+ " - command: <*>",
+ // ---------------
+ "applications:\n" +
+ " - disk_quota: <*>",
+ // ---------------
+ "applications:\n" +
+ " - domain: <*>",
+ // ---------------
+ "applications:\n" +
+ " - domains:\n"+
+ " - <*>",
+ // ---------------
+ "applications:\n" +
+ " - env:\n"+
+ " <*>",
+ // ---------------
+ "applications:\n" +
+ " - host: <*>",
+ // ---------------
+ "applications:\n" +
+ " - hosts:\n"+
+ " - <*>",
+ // ---------------
+ "applications:\n" +
+ " - instances: <*>",
+ // ---------------
+ "applications:\n" +
+ " - memory: <*>",
+ // ---------------
+ "applications:\n" +
+ " - name: <*>",
+ // ---------------
+ "applications:\n" +
+ " - no-hostname: <*>",
+ // ---------------
+ "applications:\n" +
+ " - no-route: <*>",
+ // ---------------
+ "applications:\n" +
+ " - path: <*>",
+ // ---------------
+ "applications:\n" +
+ " - random-route: <*>",
+ // ---------------
+ "applications:\n" +
+ " - services:\n"+
+ " - <*>",
+ // ---------------
+ "applications:\n" +
+ " - stack: <*>",
+ // ---------------
+ "applications:\n" +
+ " - timeout: <*>"
+ );
+ }
+
+ @Test
+ public void valueCompletions() throws Exception {
+ assertCompletions("disk_quota: <*>",
+ "disk_quota: 1024M<*>",
+ "disk_quota: 256M<*>",
+ "disk_quota: 512M<*>"
+ );
+ assertCompletions("memory: <*>",
+ "memory: 1024M<*>",
+ "memory: 256M<*>",
+ "memory: 512M<*>"
+ );
+ assertCompletions("no-hostname: <*>",
+ "no-hostname: false<*>",
+ "no-hostname: true<*>"
+ );
+ assertCompletions("no-route: <*>",
+ "no-route: false<*>",
+ "no-route: true<*>"
+ );
+ assertCompletions("random-route: <*>",
+ "random-route: false<*>",
+ "random-route: true<*>"
+ );
+ }
+
+ @Test
+ public void hoverInfos() throws Exception {
+ Editor editor = harness.newEditor(
+ "memory: 1G\n" +
+ "applications:\n" +
+ " - buildpack: zbuildpack\n" +
+ " domain: zdomain\n" +
+ " name: foo"
+ );
+ editor.assertIsHoverRegion("memory");
+ editor.assertIsHoverRegion("applications");
+ editor.assertIsHoverRegion("buildpack");
+ editor.assertIsHoverRegion("domain");
+ editor.assertIsHoverRegion("name");
+
+ editor.assertHoverContains("memory", "Use the memory attribute to specify the memory limit");
+ editor.assertHoverContains("1G", "Use the memory attribute to specify the memory limit");
+ editor.assertHoverContains("buildpack", "use the buildpack attribute to specify its URL or name");
+ }
+
+ @Test
+ public void reconcileMisSpelledPropertyNames() throws Exception {
+ Editor editor;
+
+ editor = harness.newEditor(
+ "memory: 1G\n" +
+ "aplications:\n" +
+ " - buildpack: zbuildpack\n" +
+ " domain: zdomain\n" +
+ " name: foo"
+ );
+ editor.assertProblems("aplications|Unknown property");
+
+ //mispelled or not allowed at toplevel
+ editor = harness.newEditor(
+ "name: foo\n" +
+ "buildpeck: yahah\n" +
+ "memory: 1G\n" +
+ "memori: 1G\n"
+ );
+ editor.assertProblems(
+ "name|Unknown property",
+ "buildpeck|Unknown property",
+ "memori|Unknown property"
+ );
+
+ //mispelled or not allowed as nested
+ editor = harness.newEditor(
+ "applications:\n" +
+ "- name: fine\n" +
+ " buildpeck: yahah\n" +
+ " memory: 1G\n" +
+ " memori: 1G\n" +
+ " applications: bad\n"
+ );
+ editor.assertProblems(
+ "buildpeck|Unknown property",
+ "memori|Unknown property",
+ "applications|Unknown property"
+ );
+ }
+
+ @Test
+ public void reconcileStructuralProblems() throws Exception {
+ Editor editor;
+
+ //forgot the 'applications:' heading
+ editor = harness.newEditor(
+ "- name: foo"
+ );
+ editor.assertProblems(
+ "- name: foo|Expecting a 'Map' but found a 'Sequence'"
+ );
+
+ //forgot to make the '-' after applications
+ editor = harness.newEditor(
+ "applications:\n" +
+ " name: foo"
+ );
+ editor.assertProblems(
+ "name: foo|Expecting a 'Sequence' but found a 'Map'"
+ );
+
+ //Using a 'composite' element where a scalar type is expected
+ editor = harness.newEditor(
+ "memory:\n"+
+ "- bad sequence\n" +
+ "buildpack:\n" +
+ " bad: map\n"
+ );
+ editor.assertProblems(
+ "- bad sequence|Expecting a 'Memory' but found a 'Sequence'",
+ "bad: map|Expecting a 'Buildpack' but found a 'Map'"
+ );
+ }
+
+ @Test
+ public void reconcileSimpleTypes() throws Exception {
+ Editor editor;
+
+ //check for 'format' errors:
+ editor = harness.newEditor(
+ "applications:\n" +
+ "- name: foo\n" +
+ " instances: not a number\n" +
+ " no-route: notBool\n"+
+ " memory: 1024\n" +
+ " disk_quota: 2048\n"
+ );
+ editor.assertProblems(
+ "not a number|Positive Integer",
+ "notBool|boolean",
+ "1024|Memory",
+ "2048|Memory"
+ );
+
+ //check for 'range' errors:
+ editor = harness.newEditor(
+ "applications:\n" +
+ "- name: foo\n" +
+ " instances: -3\n" +
+ " memory: -1024M\n" +
+ " disk_quota: -2048M\n"
+ );
+ editor.assertProblems(
+ "-3|Positive Integer",
+ "-1024M|Memory",
+ "-2048M|Memory"
+ );
+
+ //check that correct values are indeed accepted
+ editor = harness.newEditor(
+ "applications:\n" +
+ "- name: foo\n" +
+ " instances: 2\n" +
+ " no-route: true\n"+
+ " memory: 1024M\n" +
+ " disk_quota: 2048MB\n"
+ );
+ editor.assertProblems(/*none*/);
+
+ //check that correct values are indeed accepted
+ editor = harness.newEditor(
+ "applications:\n" +
+ "- name: foo\n" +
+ " instances: 2\n" +
+ " no-route: false\n" +
+ " memory: 1024m\n" +
+ " disk_quota: 2048mb\n"
+ );
+ editor.assertProblems(/*none*/);
+
+ editor = harness.newEditor(
+ "applications:\n" +
+ "- name: foo\n" +
+ " instances: 2\n" +
+ " memory: 1G\n" +
+ " disk_quota: 2g\n"
+ );
+ editor.assertProblems(/*none*/);
+ }
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ private void assertCompletions(String textBefore, String... textAfter) throws Exception {
+ Editor editor = harness.newEditor(textBefore);
+ editor.assertCompletions(textAfter);
+ }
+}