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