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