Re-enable and fix failing concourse editor tests

Signed-off-by: Kris De Volder <kdevolder@pivotal.io>
This commit is contained in:
Kris De Volder
2020-12-02 15:10:41 -08:00
parent b366245748
commit 93b6a704d5
5 changed files with 157 additions and 95 deletions

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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));
}

View File

@@ -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()) {

View File

@@ -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(