1 /** 2 * Copyright (c) 2008, SnakeYAML 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 package org.pyyaml; 15 16 import java.io.File; 17 import java.io.FileInputStream; 18 import java.io.InputStream; 19 import java.io.Reader; 20 import java.util.ArrayList; 21 import java.util.Iterator; 22 import java.util.List; 23 import org.yaml.snakeyaml.Yaml; 24 import org.yaml.snakeyaml.composer.Composer; 25 import org.yaml.snakeyaml.constructor.AbstractConstruct; 26 import org.yaml.snakeyaml.constructor.Constructor; 27 import org.yaml.snakeyaml.events.AliasEvent; 28 import org.yaml.snakeyaml.events.CollectionStartEvent; 29 import org.yaml.snakeyaml.events.Event; 30 import org.yaml.snakeyaml.events.ScalarEvent; 31 import org.yaml.snakeyaml.nodes.MappingNode; 32 import org.yaml.snakeyaml.nodes.Node; 33 import org.yaml.snakeyaml.nodes.NodeTuple; 34 import org.yaml.snakeyaml.nodes.ScalarNode; 35 import org.yaml.snakeyaml.nodes.SequenceNode; 36 import org.yaml.snakeyaml.parser.ParserImpl; 37 import org.yaml.snakeyaml.reader.StreamReader; 38 import org.yaml.snakeyaml.reader.UnicodeReader; 39 import org.yaml.snakeyaml.resolver.Resolver; 40 41 /** 42 * imported from PyYAML 43 */ 44 public class PyStructureTest extends PyImportTest { 45 compareEvents(List<Event> events1, List<Event> events2, boolean full)46 private void compareEvents(List<Event> events1, List<Event> events2, boolean full) { 47 assertEquals(events1.size(), events2.size()); 48 Iterator<Event> iter1 = events1.iterator(); 49 Iterator<Event> iter2 = events2.iterator(); 50 while (iter1.hasNext()) { 51 Event event1 = iter1.next(); 52 Event event2 = iter2.next(); 53 assertEquals(event1.getClass(), event2.getClass()); 54 if (event1 instanceof AliasEvent && full) { 55 assertEquals(((AliasEvent) event1).getAnchor(), ((AliasEvent) event2).getAnchor()); 56 } 57 if (event1 instanceof CollectionStartEvent) { 58 String tag1 = ((CollectionStartEvent) event1).getTag(); 59 String tag2 = ((CollectionStartEvent) event1).getTag(); 60 if (tag1 != null && !"!".equals(tag1) && tag2 != null && !"!".equals(tag1)) { 61 assertEquals(tag1, tag2); 62 } 63 } 64 if (event1 instanceof ScalarEvent) { 65 ScalarEvent scalar1 = (ScalarEvent) event1; 66 ScalarEvent scalar2 = (ScalarEvent) event2; 67 if (scalar1.getImplicit().bothFalse() && scalar2.getImplicit().bothFalse()) { 68 assertEquals(scalar1.getTag(), scalar2.getTag()); 69 } 70 assertEquals(scalar1.getValue(), scalar2.getValue()); 71 } 72 } 73 } 74 testParser()75 public void testParser() { 76 File[] files = getStreamsByExtension(".data", true); 77 assertTrue("No test files found.", files.length > 0); 78 for (File file : files) { 79 if (!file.getName().contains("scan-line-b")) { 80 continue; 81 } 82 try { 83 InputStream input = new FileInputStream(file); 84 List<Event> events1 = parse(input); 85 input.close(); 86 assertFalse(events1.isEmpty()); 87 int index = file.getAbsolutePath().lastIndexOf('.'); 88 String canonicalName = file.getAbsolutePath().substring(0, index) + ".canonical"; 89 File canonical = new File(canonicalName); 90 List<Event> events2 = canonicalParse(new FileInputStream(canonical)); 91 assertFalse(events2.isEmpty()); 92 compareEvents(events1, events2, false); 93 } catch (Exception e) { 94 System.out.println("Failed File: " + file); 95 // fail("Failed File: " + file + "; " + e.getMessage()); 96 throw new RuntimeException(e); 97 } 98 } 99 } 100 testParserOnCanonical()101 public void testParserOnCanonical() { 102 File[] canonicalFiles = getStreamsByExtension(".canonical", false); 103 assertTrue("No test files found.", canonicalFiles.length > 0); 104 for (File file : canonicalFiles) { 105 try { 106 InputStream input = new FileInputStream(file); 107 List<Event> events1 = parse(input); 108 input.close(); 109 assertFalse(events1.isEmpty()); 110 List<Event> events2 = canonicalParse(new FileInputStream(file)); 111 assertFalse(events2.isEmpty()); 112 compareEvents(events1, events2, true); 113 } catch (Exception e) { 114 System.out.println("Failed File: " + file); 115 // fail("Failed File: " + file + "; " + e.getMessage()); 116 throw new RuntimeException(e); 117 } 118 } 119 } 120 compareNodes(Node node1, Node node2)121 private void compareNodes(Node node1, Node node2) { 122 assertEquals(node1.getClass(), node2.getClass()); 123 if (node1 instanceof ScalarNode) { 124 ScalarNode scalar1 = (ScalarNode) node1; 125 ScalarNode scalar2 = (ScalarNode) node2; 126 assertEquals(scalar1.getTag(), scalar2.getTag()); 127 assertEquals(scalar1.getValue(), scalar2.getValue()); 128 } else { 129 if (node1 instanceof SequenceNode) { 130 SequenceNode seq1 = (SequenceNode) node1; 131 SequenceNode seq2 = (SequenceNode) node2; 132 assertEquals(seq1.getTag(), seq2.getTag()); 133 assertEquals(seq1.getValue().size(), seq2.getValue().size()); 134 Iterator<Node> iter2 = seq2.getValue().iterator(); 135 for (Node child1 : seq1.getValue()) { 136 Node child2 = iter2.next(); 137 compareNodes(child1, child2); 138 } 139 } else { 140 MappingNode seq1 = (MappingNode) node1; 141 MappingNode seq2 = (MappingNode) node2; 142 assertEquals(seq1.getTag(), seq2.getTag()); 143 assertEquals(seq1.getValue().size(), seq2.getValue().size()); 144 Iterator<NodeTuple> iter2 = seq2.getValue().iterator(); 145 for (NodeTuple child1 : seq1.getValue()) { 146 NodeTuple child2 = iter2.next(); 147 compareNodes(child1.getKeyNode(), child2.getKeyNode()); 148 compareNodes(child1.getValueNode(), child2.getValueNode()); 149 } 150 } 151 } 152 } 153 testComposer()154 public void testComposer() { 155 File[] files = getStreamsByExtension(".data", true); 156 assertTrue("No test files found.", files.length > 0); 157 for (File file : files) { 158 try { 159 InputStream input = new FileInputStream(file); 160 List<Node> events1 = compose_all(input); 161 input.close(); 162 int index = file.getAbsolutePath().lastIndexOf('.'); 163 String canonicalName = file.getAbsolutePath().substring(0, index) + ".canonical"; 164 File canonical = new File(canonicalName); 165 InputStream input2 = new FileInputStream(canonical); 166 List<Node> events2 = canonical_compose_all(input2); 167 input2.close(); 168 assertEquals(events1.size(), events2.size()); 169 Iterator<Node> iter1 = events1.iterator(); 170 Iterator<Node> iter2 = events2.iterator(); 171 while (iter1.hasNext()) { 172 compareNodes(iter1.next(), iter2.next()); 173 } 174 } catch (Exception e) { 175 System.out.println("Failed File: " + file); 176 // fail("Failed File: " + file + "; " + e.getMessage()); 177 throw new RuntimeException(e); 178 } 179 } 180 } 181 compose_all(InputStream file)182 private List<Node> compose_all(InputStream file) { 183 Composer composer = 184 new Composer(new ParserImpl(new StreamReader(new UnicodeReader(file))), new Resolver()); 185 List<Node> documents = new ArrayList<Node>(); 186 while (composer.checkNode()) { 187 documents.add(composer.getNode()); 188 } 189 return documents; 190 } 191 canonical_compose_all(InputStream file)192 private List<Node> canonical_compose_all(InputStream file) { 193 StreamReader reader = new StreamReader(new UnicodeReader(file)); 194 StringBuilder buffer = new StringBuilder(); 195 while (reader.peek() != '\0') { 196 buffer.appendCodePoint(reader.peek()); 197 reader.forward(); 198 } 199 CanonicalParser parser = 200 new CanonicalParser(buffer.toString().replace(System.lineSeparator(), "\n")); 201 Composer composer = new Composer(parser, new Resolver()); 202 List<Node> documents = new ArrayList<Node>(); 203 while (composer.checkNode()) { 204 documents.add(composer.getNode()); 205 } 206 return documents; 207 } 208 209 class CanonicalLoader extends Yaml { 210 CanonicalLoader()211 public CanonicalLoader() { 212 super(new MyConstructor()); 213 } 214 215 @Override loadAll(Reader yaml)216 public Iterable<Object> loadAll(Reader yaml) { 217 StreamReader reader = new StreamReader(yaml); 218 StringBuilder buffer = new StringBuilder(); 219 while (reader.peek() != '\0') { 220 buffer.appendCodePoint(reader.peek()); 221 reader.forward(); 222 } 223 CanonicalParser parser = 224 new CanonicalParser(buffer.toString().replace(System.lineSeparator(), "\n")); 225 Composer composer = new Composer(parser, resolver); 226 this.constructor.setComposer(composer); 227 Iterator<Object> result = new Iterator<Object>() { 228 public boolean hasNext() { 229 return constructor.checkData(); 230 } 231 232 public Object next() { 233 return constructor.getData(); 234 } 235 236 public void remove() { 237 throw new UnsupportedOperationException(); 238 } 239 }; 240 return new YamlIterable(result); 241 } 242 243 private class YamlIterable implements Iterable<Object> { 244 245 private final Iterator<Object> iterator; 246 YamlIterable(Iterator<Object> iterator)247 public YamlIterable(Iterator<Object> iterator) { 248 this.iterator = iterator; 249 } 250 iterator()251 public Iterator<Object> iterator() { 252 return iterator; 253 } 254 255 } 256 257 } 258 259 private class MyConstructor extends Constructor { 260 MyConstructor()261 public MyConstructor() { 262 this.yamlConstructors.put(null, new ConstructUndefined()); 263 } 264 265 private class ConstructUndefined extends AbstractConstruct { 266 construct(Node node)267 public Object construct(Node node) { 268 return constructScalar((ScalarNode) node); 269 } 270 } 271 } 272 testConstructor()273 public void testConstructor() { 274 File[] files = getStreamsByExtension(".data", true); 275 assertTrue("No test files found.", files.length > 0); 276 Yaml myYaml = new Yaml(new MyConstructor()); 277 Yaml canonicalYaml = new CanonicalLoader(); 278 for (File file : files) { 279 try { 280 InputStream input = new FileInputStream(file); 281 Iterable<Object> documents1 = myYaml.loadAll(input); 282 int index = file.getAbsolutePath().lastIndexOf('.'); 283 String canonicalName = file.getAbsolutePath().substring(0, index) + ".canonical"; 284 File canonical = new File(canonicalName); 285 InputStream input2 = new FileInputStream(canonical); 286 Iterable<Object> documents2 = canonicalYaml.loadAll(input2); 287 input2.close(); 288 Iterator<Object> iter2 = documents2.iterator(); 289 for (Object object1 : documents1) { 290 Object object2 = iter2.next(); 291 if (object2 != null) { 292 assertFalse(System.identityHashCode(object1) == System.identityHashCode(object2)); 293 } 294 assertEquals("" + object1, object1, object2); 295 } 296 input.close(); 297 } catch (Exception e) { 298 System.out.println("Failed File: " + file); 299 // fail("Failed File: " + file + "; " + e.getMessage()); 300 throw new RuntimeException(e); 301 } 302 } 303 } 304 } 305