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.IOException;
21import java.io.InputStream;
22import java.io.StringWriter;
23import java.util.ArrayList;
24import java.util.Arrays;
25import java.util.Iterator;
26import java.util.List;
27
28import org.yaml.snakeyaml.DumperOptions;
29import org.yaml.snakeyaml.emitter.Emitter;
30import org.yaml.snakeyaml.emitter.EventConstructor;
31import org.yaml.snakeyaml.events.CollectionStartEvent;
32import org.yaml.snakeyaml.events.Event;
33import org.yaml.snakeyaml.events.MappingStartEvent;
34import org.yaml.snakeyaml.events.NodeEvent;
35import org.yaml.snakeyaml.events.ScalarEvent;
36import org.yaml.snakeyaml.events.SequenceStartEvent;
37import org.yaml.snakeyaml.parser.Parser;
38import org.yaml.snakeyaml.parser.ParserImpl;
39import org.yaml.snakeyaml.reader.StreamReader;
40import org.yaml.snakeyaml.reader.UnicodeReader;
41
42/**
43 * imported from PyYAML
44 */
45public class PyEmitterTest extends PyImportTest {
46    public void testEmitterOnData() {
47        _testEmitter(".data", false);
48    }
49
50    public void testEmitterOnCanonicalNormally() {
51        _testEmitter(".canonical", false);
52    }
53
54    public void testEmitterOnCanonicalCanonically() {
55        _testEmitter(".canonical", true);
56    }
57
58    private void _testEmitter(String mask, boolean canonical) {
59        File[] files = getStreamsByExtension(mask, true);
60        assertTrue("No test files found.", files.length > 0);
61        for (File file : files) {
62            // if (!file.getName().contains("spec-06-01.canonical")) {
63            // continue;
64            // }
65            try {
66                InputStream input = new FileInputStream(file);
67                List<Event> events = parse(input);
68                input.close();
69                //
70                StringWriter stream = new StringWriter();
71                DumperOptions options = new DumperOptions();
72                options.setCanonical(canonical);
73                Emitter emitter = new Emitter(stream, options);
74                for (Event event : events) {
75                    emitter.emit(event);
76                }
77                //
78                String data = stream.toString();
79                List<Event> newEvents = new ArrayList<Event>();
80                StreamReader reader = new StreamReader(data);
81                Parser parser = new ParserImpl(reader);
82                while (parser.peekEvent() != null) {
83                    Event event = parser.getEvent();
84                    newEvents.add(event);
85                }
86                // check
87                assertEquals(events.size(), newEvents.size());
88                Iterator<Event> iter1 = events.iterator();
89                Iterator<Event> iter2 = newEvents.iterator();
90                while (iter1.hasNext()) {
91                    Event event = iter1.next();
92                    Event newEvent = iter2.next();
93                    assertEquals(event.getClass().getName(), newEvent.getClass().getName());
94                    if (event instanceof NodeEvent) {
95                        NodeEvent e1 = (NodeEvent) event;
96                        NodeEvent e2 = (NodeEvent) newEvent;
97                        assertEquals(e1.getAnchor(), e2.getAnchor());
98                    }
99                    if (event instanceof CollectionStartEvent) {
100                        CollectionStartEvent e1 = (CollectionStartEvent) event;
101                        CollectionStartEvent e2 = (CollectionStartEvent) newEvent;
102                        assertEquals(e1.getTag(), e2.getTag());
103                    }
104                    if (event instanceof ScalarEvent) {
105                        ScalarEvent e1 = (ScalarEvent) event;
106                        ScalarEvent e2 = (ScalarEvent) newEvent;
107                        if (e1.getImplicit().bothFalse() && e2.getImplicit().bothFalse()) {
108                            assertEquals(e1.getTag(), e2.getTag());
109                        }
110                        assertEquals(e1.getValue(), e2.getValue());
111                    }
112                }
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    public void testEmitterStyles() {
122        File[] canonicalFiles = getStreamsByExtension(".canonical", false);
123        assertTrue("No test files found.", canonicalFiles.length > 0);
124        File[] dataFiles = getStreamsByExtension(".data", true);
125        assertTrue("No test files found.", dataFiles.length > 0);
126        List<File> allFiles = new ArrayList<File>(Arrays.asList(canonicalFiles));
127        allFiles.addAll(Arrays.asList(dataFiles));
128        for (File file : allFiles) {
129            try {
130                List<Event> events = new ArrayList<Event>();
131                InputStream input = new FileInputStream(file);
132                StreamReader reader = new StreamReader(new UnicodeReader(input));
133                Parser parser = new ParserImpl(reader);
134                while (parser.peekEvent() != null) {
135                    Event event = parser.getEvent();
136                    events.add(event);
137                }
138                input.close();
139                //
140                for (Boolean flowStyle : new Boolean[] { Boolean.FALSE, Boolean.TRUE }) {
141                    for (DumperOptions.ScalarStyle style : DumperOptions.ScalarStyle.values()) {
142                        List<Event> styledEvents = new ArrayList<Event>();
143                        for (Event event : events) {
144                            if (event instanceof ScalarEvent) {
145                                ScalarEvent scalar = (ScalarEvent) event;
146                                event = new ScalarEvent(scalar.getAnchor(), scalar.getTag(),
147                                        scalar.getImplicit(), scalar.getValue(),
148                                        scalar.getStartMark(), scalar.getEndMark(), style.getChar());
149                            } else if (event instanceof SequenceStartEvent) {
150                                SequenceStartEvent seqStart = (SequenceStartEvent) event;
151                                event = new SequenceStartEvent(seqStart.getAnchor(),
152                                        seqStart.getTag(), seqStart.getImplicit(),
153                                        seqStart.getStartMark(), seqStart.getEndMark(), flowStyle);
154                            } else if (event instanceof MappingStartEvent) {
155                                MappingStartEvent mapStart = (MappingStartEvent) event;
156                                event = new MappingStartEvent(mapStart.getAnchor(),
157                                        mapStart.getTag(), mapStart.getImplicit(),
158                                        mapStart.getStartMark(), mapStart.getEndMark(), flowStyle);
159                            }
160                            styledEvents.add(event);
161                        }
162                        // emit
163                        String data = emit(styledEvents);
164                        List<Event> newEvents = parse(data);
165                        assertEquals("Events must not change. File: " + file, events.size(),
166                                newEvents.size());
167                        Iterator<Event> oldIter = events.iterator();
168                        Iterator<Event> newIter = newEvents.iterator();
169                        while (oldIter.hasNext()) {
170                            Event event = oldIter.next();
171                            Event newEvent = newIter.next();
172                            assertEquals(event.getClass(), newEvent.getClass());
173                            if (event instanceof NodeEvent) {
174                                assertEquals(((NodeEvent) event).getAnchor(),
175                                        ((NodeEvent) newEvent).getAnchor());
176                            }
177                            if (event instanceof CollectionStartEvent) {
178                                assertEquals(((CollectionStartEvent) event).getTag(),
179                                        ((CollectionStartEvent) newEvent).getTag());
180                            }
181                            if (event instanceof ScalarEvent) {
182                                ScalarEvent scalarOld = (ScalarEvent) event;
183                                ScalarEvent scalarNew = (ScalarEvent) newEvent;
184                                if (scalarOld.getImplicit().bothFalse()
185                                        && scalarNew.getImplicit().bothFalse()) {
186                                    assertEquals(scalarOld.getTag(), scalarNew.getTag());
187                                }
188                                assertEquals(scalarOld.getValue(), scalarNew.getValue());
189                            }
190                        }
191                    }
192                }
193
194            } catch (Exception e) {
195                System.out.println("Failed File: " + file);
196                // fail("Failed File: " + file + "; " + e.getMessage());
197                throw new RuntimeException(e);
198            }
199        }
200    }
201
202    private String emit(List<Event> events) throws IOException {
203        StringWriter writer = new StringWriter();
204        Emitter emitter = new Emitter(writer, new DumperOptions());
205        for (Event event : events) {
206            emitter.emit(event);
207        }
208        return writer.toString();
209    }
210
211    private List<Event> parse(String data) {
212        ParserImpl parser = new ParserImpl(new StreamReader(data));
213        List<Event> newEvents = new ArrayList<Event>();
214        while (parser.peekEvent() != null) {
215            newEvents.add(parser.getEvent());
216        }
217        return newEvents;
218    }
219
220    @SuppressWarnings("unchecked")
221    public void testEmitterEvents() {
222        File[] files = getStreamsByExtension(".events", false);
223        assertTrue("No test files found.", files.length > 0);
224        for (File file : files) {
225            // if (!file.getName().contains("spec-06-01.canonical")) {
226            // continue;
227            // }
228            try {
229                List<Event> events = new ArrayList<Event>();
230                String content = getResource(file.getName());
231                events = (List<Event>) load(new EventConstructor(), content);
232                //
233                StringWriter stream = new StringWriter();
234                Emitter emitter = new Emitter(stream, new DumperOptions());
235                for (Event event : events) {
236                    emitter.emit(event);
237                }
238                //
239                String data = stream.toString();
240                List<Event> newEvents = new ArrayList<Event>();
241                StreamReader reader = new StreamReader(data);
242                Parser parser = new ParserImpl(reader);
243                while (parser.peekEvent() != null) {
244                    Event event = parser.getEvent();
245                    newEvents.add(event);
246                }
247                // check
248                assertEquals(events.size(), newEvents.size());
249                Iterator<Event> iter1 = events.iterator();
250                Iterator<Event> iter2 = newEvents.iterator();
251                while (iter1.hasNext()) {
252                    Event event = iter1.next();
253                    Event newEvent = iter2.next();
254                    assertEquals(event.getClass().getName(), newEvent.getClass().getName());
255                    if (event instanceof NodeEvent) {
256                        NodeEvent e1 = (NodeEvent) event;
257                        NodeEvent e2 = (NodeEvent) newEvent;
258                        assertEquals(e1.getAnchor(), e2.getAnchor());
259                    }
260                    if (event instanceof CollectionStartEvent) {
261                        CollectionStartEvent e1 = (CollectionStartEvent) event;
262                        CollectionStartEvent e2 = (CollectionStartEvent) newEvent;
263                        assertEquals(e1.getTag(), e2.getTag());
264                    }
265                    if (event instanceof ScalarEvent) {
266                        ScalarEvent e1 = (ScalarEvent) event;
267                        ScalarEvent e2 = (ScalarEvent) newEvent;
268                        if (e1.getImplicit().canOmitTagInPlainScalar() == e2.getImplicit()
269                                .canOmitTagInPlainScalar()
270                                && e1.getImplicit().canOmitTagInNonPlainScalar() == e2
271                                        .getImplicit().canOmitTagInNonPlainScalar()) {
272
273                        } else {
274                            if ((e1.getTag() == null || e2.getTag() == null)
275                                    || e1.getTag().equals(e2.getTag())) {
276                            } else {
277                                System.out.println("tag1: " + e1.getTag());
278                                System.out.println("tag2: " + e2.getTag());
279                                fail("in file: " + file);
280                            }
281                        }
282                        assertEquals(e1.getValue(), e2.getValue());
283                    }
284                }
285            } catch (Exception e) {
286                System.out.println("Failed File: " + file);
287                // fail("Failed File: " + file + "; " + e.getMessage());
288                throw new RuntimeException(e);
289            }
290        }
291    }
292}
293