View Javadoc

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