1 #![allow(dead_code)]
2 #![allow(non_upper_case_globals)]
3 extern crate yaml_rust;
4
5 use yaml_rust::parser::{Event, EventReceiver, Parser};
6 use yaml_rust::scanner::TScalarStyle;
7
8 // These names match the names used in the C++ test suite.
9 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
10 #[derive(Clone, PartialEq, PartialOrd, Debug)]
11 enum TestEvent {
12 OnDocumentStart,
13 OnDocumentEnd,
14 OnSequenceStart,
15 OnSequenceEnd,
16 OnMapStart,
17 OnMapEnd,
18 OnScalar,
19 OnAlias,
20 OnNull,
21 }
22
23 struct YamlChecker {
24 pub evs: Vec<TestEvent>,
25 }
26
27 impl EventReceiver for YamlChecker {
on_event(&mut self, ev: Event)28 fn on_event(&mut self, ev: Event) {
29 let tev = match ev {
30 Event::DocumentStart => TestEvent::OnDocumentStart,
31 Event::DocumentEnd => TestEvent::OnDocumentEnd,
32 Event::SequenceStart(..) => TestEvent::OnSequenceStart,
33 Event::SequenceEnd => TestEvent::OnSequenceEnd,
34 Event::MappingStart(..) => TestEvent::OnMapStart,
35 Event::MappingEnd => TestEvent::OnMapEnd,
36 Event::Scalar(ref v, style, _, _) => {
37 if v == "~" && style == TScalarStyle::Plain {
38 TestEvent::OnNull
39 } else {
40 TestEvent::OnScalar
41 }
42 }
43 Event::Alias(_) => TestEvent::OnAlias,
44 _ => return, // ignore other events
45 };
46 self.evs.push(tev);
47 }
48 }
49
str_to_test_events(docs: &str) -> Vec<TestEvent>50 fn str_to_test_events(docs: &str) -> Vec<TestEvent> {
51 let mut p = YamlChecker { evs: Vec::new() };
52 let mut parser = Parser::new(docs.chars());
53 parser.load(&mut p, true).unwrap();
54 p.evs
55 }
56
57 macro_rules! assert_next {
58 ($v:expr, $p:pat) => {
59 match $v.next().unwrap() {
60 $p => {}
61 e => {
62 panic!("unexpected event: {:?}", e);
63 }
64 }
65 };
66 }
67
68 // auto generated from handler_spec_test.cpp
69 include!("specexamples.rs.inc");
70 include!("spec_test.rs.inc");
71
72 // hand-crafted tests
73 //#[test]
74 //fn test_hc_alias() {
75 //}
76
77 #[test]
test_mapvec_legal()78 fn test_mapvec_legal() {
79 use yaml_rust::yaml::{Array, Hash, Yaml};
80 use yaml_rust::{YamlEmitter, YamlLoader};
81
82 // Emitting a `map<map<seq<_>>, _>` should result in legal yaml that
83 // we can parse.
84
85 let mut key = Array::new();
86 key.push(Yaml::Integer(1));
87 key.push(Yaml::Integer(2));
88 key.push(Yaml::Integer(3));
89
90 let mut keyhash = Hash::new();
91 keyhash.insert(Yaml::String("key".into()), Yaml::Array(key));
92
93 let mut val = Array::new();
94 val.push(Yaml::Integer(4));
95 val.push(Yaml::Integer(5));
96 val.push(Yaml::Integer(6));
97
98 let mut hash = Hash::new();
99 hash.insert(Yaml::Hash(keyhash), Yaml::Array(val));
100
101 let mut out_str = String::new();
102 {
103 let mut emitter = YamlEmitter::new(&mut out_str);
104 emitter.dump(&Yaml::Hash(hash)).unwrap();
105 }
106
107 // At this point, we are tempted to naively render like this:
108 //
109 // ```yaml
110 // ---
111 // {key:
112 // - 1
113 // - 2
114 // - 3}:
115 // - 4
116 // - 5
117 // - 6
118 // ```
119 //
120 // However, this doesn't work, because the key sequence [1, 2, 3] is
121 // rendered in block mode, which is not legal (as far as I can tell)
122 // inside the flow mode of the key. We need to either fully render
123 // everything that's in a key in flow mode (which may make for some
124 // long lines), or use the explicit map identifier '?':
125 //
126 // ```yaml
127 // ---
128 // ?
129 // key:
130 // - 1
131 // - 2
132 // - 3
133 // :
134 // - 4
135 // - 5
136 // - 6
137 // ```
138
139 YamlLoader::load_from_str(&out_str).unwrap();
140 }
141