Re-enable and fix failing concourse editor tests
Signed-off-by: Kris De Volder <kdevolder@pivotal.io>
This commit is contained in:
@@ -1,17 +1,25 @@
|
||||
resources:
|
||||
- name: docker-base
|
||||
type: registry-image
|
||||
source:
|
||||
repository: alpine
|
||||
sleep: &sleep
|
||||
config:
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: docker-image
|
||||
source:
|
||||
repository: alpine
|
||||
tag: latest
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -exc
|
||||
- sleep 60
|
||||
|
||||
##########
|
||||
|
||||
resource_types:
|
||||
- name: pool
|
||||
type: docker-image
|
||||
|
||||
jobs:
|
||||
- name: publish-jvm-launch-utils
|
||||
- name: acquire-1
|
||||
plan:
|
||||
- get: docker-base
|
||||
trigger: true
|
||||
params:
|
||||
skip_download: true
|
||||
- put: docker-base
|
||||
get_params:
|
||||
skip_download: true
|
||||
params:
|
||||
image: blah
|
||||
- task: sleep
|
||||
<<: *sleep
|
||||
|
||||
@@ -28,6 +28,9 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.YamlUtil;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.events.Event;
|
||||
import org.yaml.snakeyaml.nodes.MappingNode;
|
||||
import org.yaml.snakeyaml.nodes.Node;
|
||||
import org.yaml.snakeyaml.nodes.NodeTuple;
|
||||
@@ -48,83 +51,90 @@ public class NodeMergeSupport {
|
||||
this.problems = problems;
|
||||
}
|
||||
|
||||
public void flattenMapping(MappingNode node) {
|
||||
// perform merging only on nodes containing merge node(s)
|
||||
//processDuplicateKeys(node);
|
||||
if (node.isMerged()) {
|
||||
node.setValue(mergeNode(node, true, new HashMap<Object, Integer>(),
|
||||
new ArrayList<NodeTuple>()));
|
||||
node.setMerged(false);
|
||||
}
|
||||
}
|
||||
public void flattenMapping(Node node) {
|
||||
if (node instanceof MappingNode) {
|
||||
flattenMapping((MappingNode)node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does merge for supplied mapping node.
|
||||
*
|
||||
* @param node
|
||||
* where to merge
|
||||
* @param isPreffered
|
||||
* true if keys of node should take precedence over others...
|
||||
* @param key2index
|
||||
* maps already merged keys to index from values
|
||||
* @param values
|
||||
* collects merged NodeTuple
|
||||
* @return list of the merged NodeTuple (to be set as value for the
|
||||
* MappingNode)
|
||||
*/
|
||||
private List<NodeTuple> mergeNode(MappingNode node, boolean isPreffered,
|
||||
Map<Object, Integer> key2index, List<NodeTuple> values) {
|
||||
Iterator<NodeTuple> iter = node.getValue().iterator();
|
||||
while (iter.hasNext()) {
|
||||
final NodeTuple nodeTuple = iter.next();
|
||||
final Node keyNode = nodeTuple.getKeyNode();
|
||||
final Node valueNode = nodeTuple.getValueNode();
|
||||
if (keyNode.getTag().equals(Tag.MERGE)) {
|
||||
iter.remove();
|
||||
switch (valueNode.getNodeId()) {
|
||||
case mapping:
|
||||
MappingNode mn = (MappingNode) valueNode;
|
||||
mergeNode(mn, false, key2index, values);
|
||||
break;
|
||||
case sequence:
|
||||
SequenceNode sn = (SequenceNode) valueNode;
|
||||
List<Node> vals = sn.getValue();
|
||||
for (Node subnode : vals) {
|
||||
if (!(subnode instanceof MappingNode)) {
|
||||
problems.accept(YamlSchemaProblems.schemaProblem(
|
||||
"Expected a mapping for merging, but found "+subnode.getNodeId(), subnode
|
||||
));
|
||||
} else {
|
||||
MappingNode mnode = (MappingNode) subnode;
|
||||
mergeNode(mnode, false, key2index, values);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
problems.accept(YamlSchemaProblems.schemaProblem(
|
||||
"Expected a mapping or list of mappings for merging, but found "
|
||||
+ valueNode.getNodeId(),
|
||||
valueNode
|
||||
));
|
||||
}
|
||||
} else {
|
||||
// we need to construct keys to avoid duplications
|
||||
String key = NodeUtil.asScalar(keyNode);
|
||||
if (key!=null) {
|
||||
if (!key2index.containsKey(key)) { // 1st time merging key
|
||||
values.add(nodeTuple);
|
||||
// keep track where tuple for the key is
|
||||
key2index.put(key, values.size() - 1);
|
||||
} else if (isPreffered) { // there is value for the key, but we
|
||||
// need to override it
|
||||
// change value for the key using saved position
|
||||
values.set(key2index.get(key), nodeTuple);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
private void flattenMapping(MappingNode node) {
|
||||
// perform merging only on nodes containing merge node(s)
|
||||
//processDuplicateKeys(node);
|
||||
|
||||
if (node.isMerged()) {
|
||||
node.setValue(mergeNode(node, true, new HashMap<Object, Integer>(),
|
||||
new ArrayList<NodeTuple>()));
|
||||
node.setMerged(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does merge for supplied mapping node.
|
||||
*
|
||||
* @param node
|
||||
* where to merge
|
||||
* @param isPreffered
|
||||
* true if keys of node should take precedence over others...
|
||||
* @param key2index
|
||||
* maps already merged keys to index from values
|
||||
* @param values
|
||||
* collects merged NodeTuple
|
||||
* @return list of the merged NodeTuple (to be set as value for the
|
||||
* MappingNode)
|
||||
*/
|
||||
private List<NodeTuple> mergeNode(MappingNode node, boolean isPreffered,
|
||||
Map<Object, Integer> key2index, List<NodeTuple> values) {
|
||||
Iterator<NodeTuple> iter = node.getValue().iterator();
|
||||
while (iter.hasNext()) {
|
||||
final NodeTuple nodeTuple = iter.next();
|
||||
final Node keyNode = nodeTuple.getKeyNode();
|
||||
final Node valueNode = nodeTuple.getValueNode();
|
||||
if (keyNode.getTag().equals(Tag.MERGE)) {
|
||||
iter.remove();
|
||||
switch (valueNode.getNodeId()) {
|
||||
case mapping:
|
||||
MappingNode mn = (MappingNode) valueNode;
|
||||
mergeNode(mn, false, key2index, values);
|
||||
break;
|
||||
case sequence:
|
||||
SequenceNode sn = (SequenceNode) valueNode;
|
||||
List<Node> vals = sn.getValue();
|
||||
for (Node subnode : vals) {
|
||||
if (!(subnode instanceof MappingNode)) {
|
||||
problems.accept(YamlSchemaProblems.schemaProblem(
|
||||
"Expected a mapping for merging, but found "+subnode.getNodeId(), subnode
|
||||
));
|
||||
} else {
|
||||
MappingNode mnode = (MappingNode) subnode;
|
||||
mergeNode(mnode, false, key2index, values);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
problems.accept(YamlSchemaProblems.schemaProblem(
|
||||
"Expected a mapping or list of mappings for merging, but found "
|
||||
+ valueNode.getNodeId(),
|
||||
valueNode
|
||||
));
|
||||
}
|
||||
} else {
|
||||
// we need to construct keys to avoid duplications
|
||||
String key = NodeUtil.asScalar(keyNode);
|
||||
if (key!=null) {
|
||||
if (!key2index.containsKey(key)) { // 1st time merging key
|
||||
values.add(nodeTuple);
|
||||
// keep track where tuple for the key is
|
||||
key2index.put(key, values.size() - 1);
|
||||
} else if (isPreffered) { // there is value for the key, but we
|
||||
// need to override it
|
||||
// change value for the key using saved position
|
||||
values.set(key2index.get(key), nodeTuple);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.nodes.Node;
|
||||
|
||||
@@ -32,7 +34,9 @@ public class YamlParser implements YamlASTProvider {
|
||||
public YamlFileAST getAST(IDocument doc) throws Exception {
|
||||
CharSequenceReader reader = new CharSequenceReader();
|
||||
reader.setInput(atTokenTransformHack(doc.get()));
|
||||
Iterable<Node> nodes = new Yaml().composeAll(reader);
|
||||
LoaderOptions loaderOpts = new LoaderOptions();
|
||||
loaderOpts.setMaxAliasesForCollections(1000);
|
||||
Iterable<Node> nodes = new Yaml(loaderOpts).composeAll(reader);
|
||||
return new YamlFileAST(doc, ImmutableList.copyOf(nodes));
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.springframework.ide.vscode.commons.util.ValueParseException;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParser;
|
||||
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.AstDumper;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.NodeMergeSupport;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
@@ -142,6 +143,11 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
|
||||
}
|
||||
|
||||
private void reconcile(YamlFileAST ast, YamlPath path, Node parent, Node node, YType _type) {
|
||||
nodeMerger.flattenMapping(node);
|
||||
|
||||
// System.out.println("--------- Reconciling ---------");
|
||||
// AstDumper.dump(node, 0);
|
||||
|
||||
if (_type!=null && !skipReconciling(node)) {
|
||||
DynamicSchemaContext schemaContext = new ASTDynamicSchemaContext(ast, path, node);
|
||||
YType type = typeUtil.inferMoreSpecificType(_type, schemaContext);
|
||||
@@ -152,7 +158,6 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
|
||||
switch (getNodeId(node)) {
|
||||
case mapping:
|
||||
MappingNode map = (MappingNode) node;
|
||||
nodeMerger.flattenMapping(map);
|
||||
checkForDuplicateKeys(map);
|
||||
if (typeUtil.isMap(type)) {
|
||||
for (NodeTuple entry : map.getValue()) {
|
||||
|
||||
@@ -268,7 +268,6 @@ public class ConcourseEditorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void complexOutlineWithAnchors() throws Exception {
|
||||
harness.enableHierarchicalDocumentSymbols(true);
|
||||
//See: https://github.com/spring-projects/sts4/issues/483
|
||||
@@ -5807,8 +5806,8 @@ public class ConcourseEditorTest {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void anchorsAndReferenceSample_1() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"pool-template: &pool-template\n" +
|
||||
@@ -5888,6 +5887,42 @@ public class ConcourseEditorTest {
|
||||
editor.assertProblems(/*none*/);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anchorsAndReferenceSample_1_simple() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"sleep: &sleep\n" +
|
||||
" config:\n" +
|
||||
" platform: linux\n" +
|
||||
" image_resource:\n" +
|
||||
" type: docker-image\n" +
|
||||
" source:\n" +
|
||||
" repository: alpine\n" +
|
||||
" tag: latest\n" +
|
||||
" run:\n" +
|
||||
" path: sh\n" +
|
||||
" args:\n" +
|
||||
" - -exc\n" +
|
||||
" - sleep 60\n" +
|
||||
"\n" +
|
||||
"##########\n" +
|
||||
"\n" +
|
||||
"resource_types:\n" +
|
||||
"- name: pool\n" +
|
||||
" type: docker-image\n" +
|
||||
"\n" +
|
||||
"jobs:\n" +
|
||||
"- name: acquire-1\n" +
|
||||
" plan:\n" +
|
||||
" - task: sleep\n" +
|
||||
" <<: *sleep\n"
|
||||
);
|
||||
|
||||
System.out.println("============================");
|
||||
System.out.println(editor.getRawText());
|
||||
System.out.println("============================");
|
||||
editor.assertProblems(/*none*/);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anchorsAndReferenceSample_2() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
|
||||
Reference in New Issue
Block a user