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