blob: 074e27f8318dc53736574d64fc5d6f4a6bee78a7 [file] [log] [blame]
Nick Kledzikf60a9272012-12-12 20:46:15 +00001//===- unittest/Support/YAMLIOTest.cpp ------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/ADT/SmallString.h"
11#include "llvm/ADT/Twine.h"
12#include "llvm/Support/Casting.h"
13#include "llvm/Support/Format.h"
14#include "llvm/Support/YAMLTraits.h"
15#include "gtest/gtest.h"
16
17
18using llvm::yaml::Input;
19using llvm::yaml::Output;
20using llvm::yaml::IO;
21using llvm::yaml::MappingTraits;
22using llvm::yaml::MappingNormalization;
23using llvm::yaml::ScalarTraits;
24using llvm::yaml::Hex8;
25using llvm::yaml::Hex16;
26using llvm::yaml::Hex32;
27using llvm::yaml::Hex64;
28
29
Nick Kledzik7cd45f22013-11-21 00:28:07 +000030
31
32static void suppressErrorMessages(const llvm::SMDiagnostic &, void *) {
33}
34
35
36
Nick Kledzikf60a9272012-12-12 20:46:15 +000037//===----------------------------------------------------------------------===//
38// Test MappingTraits
39//===----------------------------------------------------------------------===//
40
41struct FooBar {
42 int foo;
43 int bar;
44};
45typedef std::vector<FooBar> FooBarSequence;
46
47LLVM_YAML_IS_SEQUENCE_VECTOR(FooBar)
48
49
50namespace llvm {
51namespace yaml {
52 template <>
53 struct MappingTraits<FooBar> {
54 static void mapping(IO &io, FooBar& fb) {
55 io.mapRequired("foo", fb.foo);
56 io.mapRequired("bar", fb.bar);
57 }
58 };
59}
60}
61
62
63//
64// Test the reading of a yaml mapping
65//
66TEST(YAMLIO, TestMapRead) {
67 FooBar doc;
Alexander Kornienko681e37c2013-11-18 15:50:04 +000068 {
69 Input yin("---\nfoo: 3\nbar: 5\n...\n");
70 yin >> doc;
Nick Kledzikf60a9272012-12-12 20:46:15 +000071
Alexander Kornienko681e37c2013-11-18 15:50:04 +000072 EXPECT_FALSE(yin.error());
73 EXPECT_EQ(doc.foo, 3);
74 EXPECT_EQ(doc.bar, 5);
75 }
76
77 {
78 Input yin("{foo: 3, bar: 5}");
79 yin >> doc;
80
81 EXPECT_FALSE(yin.error());
82 EXPECT_EQ(doc.foo, 3);
83 EXPECT_EQ(doc.bar, 5);
84 }
Nick Kledzikf60a9272012-12-12 20:46:15 +000085}
86
Rafael Espindolaa97373f2014-08-08 13:58:00 +000087TEST(YAMLIO, TestMalformedMapRead) {
88 FooBar doc;
89 Input yin("{foo: 3; bar: 5}", nullptr, suppressErrorMessages);
90 yin >> doc;
91 EXPECT_TRUE(!!yin.error());
92}
93
Nick Kledzikf60a9272012-12-12 20:46:15 +000094//
95// Test the reading of a yaml sequence of mappings
96//
97TEST(YAMLIO, TestSequenceMapRead) {
98 FooBarSequence seq;
99 Input yin("---\n - foo: 3\n bar: 5\n - foo: 7\n bar: 9\n...\n");
100 yin >> seq;
101
102 EXPECT_FALSE(yin.error());
103 EXPECT_EQ(seq.size(), 2UL);
104 FooBar& map1 = seq[0];
105 FooBar& map2 = seq[1];
106 EXPECT_EQ(map1.foo, 3);
107 EXPECT_EQ(map1.bar, 5);
108 EXPECT_EQ(map2.foo, 7);
109 EXPECT_EQ(map2.bar, 9);
110}
111
112
113//
114// Test writing then reading back a sequence of mappings
115//
116TEST(YAMLIO, TestSequenceMapWriteAndRead) {
117 std::string intermediate;
118 {
119 FooBar entry1;
120 entry1.foo = 10;
121 entry1.bar = -3;
122 FooBar entry2;
123 entry2.foo = 257;
124 entry2.bar = 0;
125 FooBarSequence seq;
126 seq.push_back(entry1);
127 seq.push_back(entry2);
128
129 llvm::raw_string_ostream ostr(intermediate);
130 Output yout(ostr);
131 yout << seq;
132 }
133
134 {
135 Input yin(intermediate);
136 FooBarSequence seq2;
137 yin >> seq2;
138
139 EXPECT_FALSE(yin.error());
140 EXPECT_EQ(seq2.size(), 2UL);
141 FooBar& map1 = seq2[0];
142 FooBar& map2 = seq2[1];
143 EXPECT_EQ(map1.foo, 10);
144 EXPECT_EQ(map1.bar, -3);
145 EXPECT_EQ(map2.foo, 257);
146 EXPECT_EQ(map2.bar, 0);
147 }
148}
149
150
151//===----------------------------------------------------------------------===//
152// Test built-in types
153//===----------------------------------------------------------------------===//
154
155struct BuiltInTypes {
156 llvm::StringRef str;
John Thompson48e018a2013-11-19 17:28:21 +0000157 std::string stdstr;
Nick Kledzikf60a9272012-12-12 20:46:15 +0000158 uint64_t u64;
159 uint32_t u32;
160 uint16_t u16;
161 uint8_t u8;
162 bool b;
163 int64_t s64;
164 int32_t s32;
165 int16_t s16;
166 int8_t s8;
167 float f;
168 double d;
169 Hex8 h8;
170 Hex16 h16;
171 Hex32 h32;
172 Hex64 h64;
173};
174
175namespace llvm {
176namespace yaml {
177 template <>
178 struct MappingTraits<BuiltInTypes> {
179 static void mapping(IO &io, BuiltInTypes& bt) {
180 io.mapRequired("str", bt.str);
John Thompson48e018a2013-11-19 17:28:21 +0000181 io.mapRequired("stdstr", bt.stdstr);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000182 io.mapRequired("u64", bt.u64);
183 io.mapRequired("u32", bt.u32);
184 io.mapRequired("u16", bt.u16);
185 io.mapRequired("u8", bt.u8);
186 io.mapRequired("b", bt.b);
187 io.mapRequired("s64", bt.s64);
188 io.mapRequired("s32", bt.s32);
189 io.mapRequired("s16", bt.s16);
190 io.mapRequired("s8", bt.s8);
191 io.mapRequired("f", bt.f);
192 io.mapRequired("d", bt.d);
193 io.mapRequired("h8", bt.h8);
194 io.mapRequired("h16", bt.h16);
195 io.mapRequired("h32", bt.h32);
196 io.mapRequired("h64", bt.h64);
197 }
198 };
199}
200}
201
202
203//
204// Test the reading of all built-in scalar conversions
205//
206TEST(YAMLIO, TestReadBuiltInTypes) {
207 BuiltInTypes map;
208 Input yin("---\n"
209 "str: hello there\n"
John Thompson48e018a2013-11-19 17:28:21 +0000210 "stdstr: hello where?\n"
Nick Kledzikf60a9272012-12-12 20:46:15 +0000211 "u64: 5000000000\n"
212 "u32: 4000000000\n"
213 "u16: 65000\n"
214 "u8: 255\n"
215 "b: false\n"
216 "s64: -5000000000\n"
217 "s32: -2000000000\n"
218 "s16: -32000\n"
219 "s8: -127\n"
220 "f: 137.125\n"
221 "d: -2.8625\n"
222 "h8: 0xFF\n"
223 "h16: 0x8765\n"
224 "h32: 0xFEDCBA98\n"
225 "h64: 0xFEDCBA9876543210\n"
226 "...\n");
227 yin >> map;
228
229 EXPECT_FALSE(yin.error());
230 EXPECT_TRUE(map.str.equals("hello there"));
John Thompson48e018a2013-11-19 17:28:21 +0000231 EXPECT_TRUE(map.stdstr == "hello where?");
Nick Kledzikf60a9272012-12-12 20:46:15 +0000232 EXPECT_EQ(map.u64, 5000000000ULL);
Nick Kledzikbed953d2012-12-17 22:11:17 +0000233 EXPECT_EQ(map.u32, 4000000000U);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000234 EXPECT_EQ(map.u16, 65000);
235 EXPECT_EQ(map.u8, 255);
236 EXPECT_EQ(map.b, false);
237 EXPECT_EQ(map.s64, -5000000000LL);
238 EXPECT_EQ(map.s32, -2000000000L);
239 EXPECT_EQ(map.s16, -32000);
240 EXPECT_EQ(map.s8, -127);
241 EXPECT_EQ(map.f, 137.125);
242 EXPECT_EQ(map.d, -2.8625);
243 EXPECT_EQ(map.h8, Hex8(255));
244 EXPECT_EQ(map.h16, Hex16(0x8765));
245 EXPECT_EQ(map.h32, Hex32(0xFEDCBA98));
246 EXPECT_EQ(map.h64, Hex64(0xFEDCBA9876543210LL));
247}
248
249
250//
251// Test writing then reading back all built-in scalar types
252//
253TEST(YAMLIO, TestReadWriteBuiltInTypes) {
254 std::string intermediate;
255 {
256 BuiltInTypes map;
257 map.str = "one two";
John Thompson48e018a2013-11-19 17:28:21 +0000258 map.stdstr = "three four";
Nick Kledzikbed953d2012-12-17 22:11:17 +0000259 map.u64 = 6000000000ULL;
260 map.u32 = 3000000000U;
Nick Kledzikf60a9272012-12-12 20:46:15 +0000261 map.u16 = 50000;
262 map.u8 = 254;
263 map.b = true;
Nick Kledzikbed953d2012-12-17 22:11:17 +0000264 map.s64 = -6000000000LL;
Nick Kledzikf60a9272012-12-12 20:46:15 +0000265 map.s32 = -2000000000;
266 map.s16 = -32000;
267 map.s8 = -128;
268 map.f = 3.25;
269 map.d = -2.8625;
270 map.h8 = 254;
271 map.h16 = 50000;
Nick Kledzikbed953d2012-12-17 22:11:17 +0000272 map.h32 = 3000000000U;
Nick Kledzikf60a9272012-12-12 20:46:15 +0000273 map.h64 = 6000000000LL;
274
275 llvm::raw_string_ostream ostr(intermediate);
276 Output yout(ostr);
277 yout << map;
278 }
279
280 {
281 Input yin(intermediate);
282 BuiltInTypes map;
283 yin >> map;
284
285 EXPECT_FALSE(yin.error());
286 EXPECT_TRUE(map.str.equals("one two"));
John Thompson48e018a2013-11-19 17:28:21 +0000287 EXPECT_TRUE(map.stdstr == "three four");
Nick Kledzikf60a9272012-12-12 20:46:15 +0000288 EXPECT_EQ(map.u64, 6000000000ULL);
Nick Kledzikbed953d2012-12-17 22:11:17 +0000289 EXPECT_EQ(map.u32, 3000000000U);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000290 EXPECT_EQ(map.u16, 50000);
291 EXPECT_EQ(map.u8, 254);
292 EXPECT_EQ(map.b, true);
293 EXPECT_EQ(map.s64, -6000000000LL);
294 EXPECT_EQ(map.s32, -2000000000L);
295 EXPECT_EQ(map.s16, -32000);
296 EXPECT_EQ(map.s8, -128);
297 EXPECT_EQ(map.f, 3.25);
298 EXPECT_EQ(map.d, -2.8625);
299 EXPECT_EQ(map.h8, Hex8(254));
300 EXPECT_EQ(map.h16, Hex16(50000));
Nick Kledzikbed953d2012-12-17 22:11:17 +0000301 EXPECT_EQ(map.h32, Hex32(3000000000U));
Nick Kledzikf60a9272012-12-12 20:46:15 +0000302 EXPECT_EQ(map.h64, Hex64(6000000000LL));
303 }
304}
305
Rui Ueyama106eded2013-09-11 04:00:08 +0000306struct StringTypes {
307 llvm::StringRef str1;
308 llvm::StringRef str2;
309 llvm::StringRef str3;
310 llvm::StringRef str4;
311 llvm::StringRef str5;
David Majnemer97d8ee32014-04-09 17:04:27 +0000312 llvm::StringRef str6;
David Majnemer77880332014-04-10 07:37:33 +0000313 llvm::StringRef str7;
314 llvm::StringRef str8;
315 llvm::StringRef str9;
316 llvm::StringRef str10;
317 llvm::StringRef str11;
John Thompson48e018a2013-11-19 17:28:21 +0000318 std::string stdstr1;
319 std::string stdstr2;
320 std::string stdstr3;
321 std::string stdstr4;
322 std::string stdstr5;
David Majnemer97d8ee32014-04-09 17:04:27 +0000323 std::string stdstr6;
David Majnemer77880332014-04-10 07:37:33 +0000324 std::string stdstr7;
325 std::string stdstr8;
326 std::string stdstr9;
327 std::string stdstr10;
328 std::string stdstr11;
Rui Ueyama106eded2013-09-11 04:00:08 +0000329};
Nick Kledzikf60a9272012-12-12 20:46:15 +0000330
Rui Ueyama106eded2013-09-11 04:00:08 +0000331namespace llvm {
332namespace yaml {
333 template <>
334 struct MappingTraits<StringTypes> {
335 static void mapping(IO &io, StringTypes& st) {
336 io.mapRequired("str1", st.str1);
337 io.mapRequired("str2", st.str2);
338 io.mapRequired("str3", st.str3);
339 io.mapRequired("str4", st.str4);
340 io.mapRequired("str5", st.str5);
David Majnemer97d8ee32014-04-09 17:04:27 +0000341 io.mapRequired("str6", st.str6);
David Majnemer77880332014-04-10 07:37:33 +0000342 io.mapRequired("str7", st.str7);
343 io.mapRequired("str8", st.str8);
344 io.mapRequired("str9", st.str9);
345 io.mapRequired("str10", st.str10);
346 io.mapRequired("str11", st.str11);
John Thompson48e018a2013-11-19 17:28:21 +0000347 io.mapRequired("stdstr1", st.stdstr1);
348 io.mapRequired("stdstr2", st.stdstr2);
349 io.mapRequired("stdstr3", st.stdstr3);
350 io.mapRequired("stdstr4", st.stdstr4);
351 io.mapRequired("stdstr5", st.stdstr5);
David Majnemer97d8ee32014-04-09 17:04:27 +0000352 io.mapRequired("stdstr6", st.stdstr6);
David Majnemer77880332014-04-10 07:37:33 +0000353 io.mapRequired("stdstr7", st.stdstr7);
354 io.mapRequired("stdstr8", st.stdstr8);
355 io.mapRequired("stdstr9", st.stdstr9);
356 io.mapRequired("stdstr10", st.stdstr10);
357 io.mapRequired("stdstr11", st.stdstr11);
Rui Ueyama106eded2013-09-11 04:00:08 +0000358 }
359 };
360}
361}
362
363TEST(YAMLIO, TestReadWriteStringTypes) {
364 std::string intermediate;
365 {
366 StringTypes map;
367 map.str1 = "'aaa";
368 map.str2 = "\"bbb";
369 map.str3 = "`ccc";
370 map.str4 = "@ddd";
371 map.str5 = "";
David Majnemer97d8ee32014-04-09 17:04:27 +0000372 map.str6 = "0000000004000000";
David Majnemer77880332014-04-10 07:37:33 +0000373 map.str7 = "true";
374 map.str8 = "FALSE";
375 map.str9 = "~";
376 map.str10 = "0.2e20";
377 map.str11 = "0x30";
John Thompson48e018a2013-11-19 17:28:21 +0000378 map.stdstr1 = "'eee";
379 map.stdstr2 = "\"fff";
380 map.stdstr3 = "`ggg";
381 map.stdstr4 = "@hhh";
382 map.stdstr5 = "";
David Majnemer97d8ee32014-04-09 17:04:27 +0000383 map.stdstr6 = "0000000004000000";
David Majnemer77880332014-04-10 07:37:33 +0000384 map.stdstr7 = "true";
385 map.stdstr8 = "FALSE";
386 map.stdstr9 = "~";
387 map.stdstr10 = "0.2e20";
388 map.stdstr11 = "0x30";
Rui Ueyama106eded2013-09-11 04:00:08 +0000389
390 llvm::raw_string_ostream ostr(intermediate);
391 Output yout(ostr);
392 yout << map;
393 }
394
395 llvm::StringRef flowOut(intermediate);
396 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'''aaa"));
397 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'\"bbb'"));
398 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'`ccc'"));
399 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'@ddd'"));
400 EXPECT_NE(llvm::StringRef::npos, flowOut.find("''\n"));
David Majnemer97d8ee32014-04-09 17:04:27 +0000401 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0000000004000000'\n"));
David Majnemer77880332014-04-10 07:37:33 +0000402 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'true'\n"));
403 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'FALSE'\n"));
404 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'~'\n"));
405 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0.2e20'\n"));
406 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0x30'\n"));
John Thompson48e018a2013-11-19 17:28:21 +0000407 EXPECT_NE(std::string::npos, flowOut.find("'''eee"));
408 EXPECT_NE(std::string::npos, flowOut.find("'\"fff'"));
409 EXPECT_NE(std::string::npos, flowOut.find("'`ggg'"));
410 EXPECT_NE(std::string::npos, flowOut.find("'@hhh'"));
411 EXPECT_NE(std::string::npos, flowOut.find("''\n"));
David Majnemer97d8ee32014-04-09 17:04:27 +0000412 EXPECT_NE(std::string::npos, flowOut.find("'0000000004000000'\n"));
Rui Ueyama106eded2013-09-11 04:00:08 +0000413
414 {
415 Input yin(intermediate);
416 StringTypes map;
417 yin >> map;
418
419 EXPECT_FALSE(yin.error());
420 EXPECT_TRUE(map.str1.equals("'aaa"));
421 EXPECT_TRUE(map.str2.equals("\"bbb"));
422 EXPECT_TRUE(map.str3.equals("`ccc"));
423 EXPECT_TRUE(map.str4.equals("@ddd"));
424 EXPECT_TRUE(map.str5.equals(""));
David Majnemer97d8ee32014-04-09 17:04:27 +0000425 EXPECT_TRUE(map.str6.equals("0000000004000000"));
John Thompson48e018a2013-11-19 17:28:21 +0000426 EXPECT_TRUE(map.stdstr1 == "'eee");
427 EXPECT_TRUE(map.stdstr2 == "\"fff");
428 EXPECT_TRUE(map.stdstr3 == "`ggg");
429 EXPECT_TRUE(map.stdstr4 == "@hhh");
430 EXPECT_TRUE(map.stdstr5 == "");
David Majnemer97d8ee32014-04-09 17:04:27 +0000431 EXPECT_TRUE(map.stdstr6 == "0000000004000000");
Rui Ueyama106eded2013-09-11 04:00:08 +0000432 }
433}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000434
435//===----------------------------------------------------------------------===//
436// Test ScalarEnumerationTraits
437//===----------------------------------------------------------------------===//
438
439enum Colors {
440 cRed,
441 cBlue,
442 cGreen,
443 cYellow
444};
445
446struct ColorMap {
447 Colors c1;
448 Colors c2;
449 Colors c3;
450 Colors c4;
451 Colors c5;
452 Colors c6;
453};
454
455namespace llvm {
456namespace yaml {
457 template <>
458 struct ScalarEnumerationTraits<Colors> {
459 static void enumeration(IO &io, Colors &value) {
460 io.enumCase(value, "red", cRed);
461 io.enumCase(value, "blue", cBlue);
462 io.enumCase(value, "green", cGreen);
463 io.enumCase(value, "yellow",cYellow);
464 }
465 };
466 template <>
467 struct MappingTraits<ColorMap> {
468 static void mapping(IO &io, ColorMap& c) {
469 io.mapRequired("c1", c.c1);
470 io.mapRequired("c2", c.c2);
471 io.mapRequired("c3", c.c3);
472 io.mapOptional("c4", c.c4, cBlue); // supplies default
473 io.mapOptional("c5", c.c5, cYellow); // supplies default
474 io.mapOptional("c6", c.c6, cRed); // supplies default
475 }
476 };
477}
478}
479
480
481//
482// Test reading enumerated scalars
483//
484TEST(YAMLIO, TestEnumRead) {
485 ColorMap map;
486 Input yin("---\n"
487 "c1: blue\n"
488 "c2: red\n"
489 "c3: green\n"
490 "c5: yellow\n"
491 "...\n");
492 yin >> map;
493
494 EXPECT_FALSE(yin.error());
495 EXPECT_EQ(cBlue, map.c1);
496 EXPECT_EQ(cRed, map.c2);
497 EXPECT_EQ(cGreen, map.c3);
498 EXPECT_EQ(cBlue, map.c4); // tests default
499 EXPECT_EQ(cYellow,map.c5); // tests overridden
500 EXPECT_EQ(cRed, map.c6); // tests default
501}
502
503
504
505//===----------------------------------------------------------------------===//
506// Test ScalarBitSetTraits
507//===----------------------------------------------------------------------===//
508
509enum MyFlags {
510 flagNone = 0,
511 flagBig = 1 << 0,
512 flagFlat = 1 << 1,
513 flagRound = 1 << 2,
514 flagPointy = 1 << 3
515};
516inline MyFlags operator|(MyFlags a, MyFlags b) {
517 return static_cast<MyFlags>(
518 static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
519}
520
521struct FlagsMap {
522 MyFlags f1;
523 MyFlags f2;
524 MyFlags f3;
525 MyFlags f4;
526};
527
528
529namespace llvm {
530namespace yaml {
531 template <>
532 struct ScalarBitSetTraits<MyFlags> {
533 static void bitset(IO &io, MyFlags &value) {
534 io.bitSetCase(value, "big", flagBig);
535 io.bitSetCase(value, "flat", flagFlat);
536 io.bitSetCase(value, "round", flagRound);
537 io.bitSetCase(value, "pointy",flagPointy);
538 }
539 };
540 template <>
541 struct MappingTraits<FlagsMap> {
542 static void mapping(IO &io, FlagsMap& c) {
543 io.mapRequired("f1", c.f1);
544 io.mapRequired("f2", c.f2);
545 io.mapRequired("f3", c.f3);
546 io.mapOptional("f4", c.f4, MyFlags(flagRound));
547 }
548 };
549}
550}
551
552
553//
554// Test reading flow sequence representing bit-mask values
555//
556TEST(YAMLIO, TestFlagsRead) {
557 FlagsMap map;
558 Input yin("---\n"
559 "f1: [ big ]\n"
560 "f2: [ round, flat ]\n"
561 "f3: []\n"
562 "...\n");
563 yin >> map;
564
565 EXPECT_FALSE(yin.error());
566 EXPECT_EQ(flagBig, map.f1);
567 EXPECT_EQ(flagRound|flagFlat, map.f2);
568 EXPECT_EQ(flagNone, map.f3); // check empty set
569 EXPECT_EQ(flagRound, map.f4); // check optional key
570}
571
572
573//
574// Test writing then reading back bit-mask values
575//
576TEST(YAMLIO, TestReadWriteFlags) {
577 std::string intermediate;
578 {
579 FlagsMap map;
580 map.f1 = flagBig;
581 map.f2 = flagRound | flagFlat;
582 map.f3 = flagNone;
583 map.f4 = flagNone;
584
585 llvm::raw_string_ostream ostr(intermediate);
586 Output yout(ostr);
587 yout << map;
588 }
589
590 {
591 Input yin(intermediate);
592 FlagsMap map2;
593 yin >> map2;
594
595 EXPECT_FALSE(yin.error());
596 EXPECT_EQ(flagBig, map2.f1);
597 EXPECT_EQ(flagRound|flagFlat, map2.f2);
598 EXPECT_EQ(flagNone, map2.f3);
599 //EXPECT_EQ(flagRound, map2.f4); // check optional key
600 }
601}
602
603
604
605//===----------------------------------------------------------------------===//
606// Test ScalarTraits
607//===----------------------------------------------------------------------===//
608
609struct MyCustomType {
610 int length;
611 int width;
612};
613
614struct MyCustomTypeMap {
615 MyCustomType f1;
616 MyCustomType f2;
617 int f3;
618};
619
620
621namespace llvm {
622namespace yaml {
623 template <>
624 struct MappingTraits<MyCustomTypeMap> {
625 static void mapping(IO &io, MyCustomTypeMap& s) {
626 io.mapRequired("f1", s.f1);
627 io.mapRequired("f2", s.f2);
628 io.mapRequired("f3", s.f3);
629 }
630 };
631 // MyCustomType is formatted as a yaml scalar. A value of
632 // {length=3, width=4} would be represented in yaml as "3 by 4".
633 template<>
634 struct ScalarTraits<MyCustomType> {
635 static void output(const MyCustomType &value, void* ctxt, llvm::raw_ostream &out) {
636 out << llvm::format("%d by %d", value.length, value.width);
637 }
638 static StringRef input(StringRef scalar, void* ctxt, MyCustomType &value) {
639 size_t byStart = scalar.find("by");
640 if ( byStart != StringRef::npos ) {
641 StringRef lenStr = scalar.slice(0, byStart);
642 lenStr = lenStr.rtrim();
643 if ( lenStr.getAsInteger(0, value.length) ) {
644 return "malformed length";
645 }
646 StringRef widthStr = scalar.drop_front(byStart+2);
647 widthStr = widthStr.ltrim();
648 if ( widthStr.getAsInteger(0, value.width) ) {
649 return "malformed width";
650 }
651 return StringRef();
652 }
653 else {
654 return "malformed by";
655 }
656 }
David Majnemer77880332014-04-10 07:37:33 +0000657 static bool mustQuote(StringRef) { return true; }
Nick Kledzikf60a9272012-12-12 20:46:15 +0000658 };
659}
660}
661
662
663//
664// Test writing then reading back custom values
665//
666TEST(YAMLIO, TestReadWriteMyCustomType) {
667 std::string intermediate;
668 {
669 MyCustomTypeMap map;
670 map.f1.length = 1;
671 map.f1.width = 4;
672 map.f2.length = 100;
673 map.f2.width = 400;
674 map.f3 = 10;
675
676 llvm::raw_string_ostream ostr(intermediate);
677 Output yout(ostr);
678 yout << map;
679 }
680
681 {
682 Input yin(intermediate);
683 MyCustomTypeMap map2;
684 yin >> map2;
685
686 EXPECT_FALSE(yin.error());
687 EXPECT_EQ(1, map2.f1.length);
688 EXPECT_EQ(4, map2.f1.width);
689 EXPECT_EQ(100, map2.f2.length);
690 EXPECT_EQ(400, map2.f2.width);
691 EXPECT_EQ(10, map2.f3);
692 }
693}
694
695
696//===----------------------------------------------------------------------===//
697// Test flow sequences
698//===----------------------------------------------------------------------===//
699
700LLVM_YAML_STRONG_TYPEDEF(int, MyNumber)
701LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyNumber)
702LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::StringRef)
703
704namespace llvm {
705namespace yaml {
706 template<>
707 struct ScalarTraits<MyNumber> {
708 static void output(const MyNumber &value, void *, llvm::raw_ostream &out) {
709 out << value;
710 }
711
712 static StringRef input(StringRef scalar, void *, MyNumber &value) {
David Blaikieb088ff62012-12-12 22:14:32 +0000713 long long n;
Nick Kledzikf60a9272012-12-12 20:46:15 +0000714 if ( getAsSignedInteger(scalar, 0, n) )
715 return "invalid number";
716 value = n;
717 return StringRef();
718 }
David Majnemer77880332014-04-10 07:37:33 +0000719
720 static bool mustQuote(StringRef) { return false; }
Nick Kledzikf60a9272012-12-12 20:46:15 +0000721 };
722}
723}
724
725struct NameAndNumbers {
726 llvm::StringRef name;
727 std::vector<llvm::StringRef> strings;
728 std::vector<MyNumber> single;
729 std::vector<MyNumber> numbers;
730};
731
732namespace llvm {
733namespace yaml {
734 template <>
735 struct MappingTraits<NameAndNumbers> {
736 static void mapping(IO &io, NameAndNumbers& nn) {
737 io.mapRequired("name", nn.name);
738 io.mapRequired("strings", nn.strings);
739 io.mapRequired("single", nn.single);
740 io.mapRequired("numbers", nn.numbers);
741 }
742 };
743}
744}
745
746
747//
748// Test writing then reading back custom values
749//
750TEST(YAMLIO, TestReadWriteMyFlowSequence) {
751 std::string intermediate;
752 {
753 NameAndNumbers map;
754 map.name = "hello";
755 map.strings.push_back(llvm::StringRef("one"));
756 map.strings.push_back(llvm::StringRef("two"));
757 map.single.push_back(1);
758 map.numbers.push_back(10);
759 map.numbers.push_back(-30);
760 map.numbers.push_back(1024);
761
762 llvm::raw_string_ostream ostr(intermediate);
Rui Ueyama38dfffa2013-09-11 00:53:07 +0000763 Output yout(ostr);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000764 yout << map;
Rui Ueyama38dfffa2013-09-11 00:53:07 +0000765
Nick Kledzik11964f22013-01-04 19:32:00 +0000766 // Verify sequences were written in flow style
767 ostr.flush();
768 llvm::StringRef flowOut(intermediate);
769 EXPECT_NE(llvm::StringRef::npos, flowOut.find("one, two"));
770 EXPECT_NE(llvm::StringRef::npos, flowOut.find("10, -30, 1024"));
Nick Kledzikf60a9272012-12-12 20:46:15 +0000771 }
772
773 {
774 Input yin(intermediate);
775 NameAndNumbers map2;
776 yin >> map2;
777
778 EXPECT_FALSE(yin.error());
779 EXPECT_TRUE(map2.name.equals("hello"));
780 EXPECT_EQ(map2.strings.size(), 2UL);
781 EXPECT_TRUE(map2.strings[0].equals("one"));
782 EXPECT_TRUE(map2.strings[1].equals("two"));
783 EXPECT_EQ(map2.single.size(), 1UL);
784 EXPECT_EQ(1, map2.single[0]);
785 EXPECT_EQ(map2.numbers.size(), 3UL);
786 EXPECT_EQ(10, map2.numbers[0]);
787 EXPECT_EQ(-30, map2.numbers[1]);
788 EXPECT_EQ(1024, map2.numbers[2]);
789 }
790}
791
792
793//===----------------------------------------------------------------------===//
794// Test normalizing/denormalizing
795//===----------------------------------------------------------------------===//
796
797LLVM_YAML_STRONG_TYPEDEF(uint32_t, TotalSeconds)
798
799typedef std::vector<TotalSeconds> SecondsSequence;
800
Nick Kledzik11964f22013-01-04 19:32:00 +0000801LLVM_YAML_IS_SEQUENCE_VECTOR(TotalSeconds)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000802
803
804namespace llvm {
805namespace yaml {
806 template <>
807 struct MappingTraits<TotalSeconds> {
808
809 class NormalizedSeconds {
810 public:
811 NormalizedSeconds(IO &io)
812 : hours(0), minutes(0), seconds(0) {
813 }
814 NormalizedSeconds(IO &, TotalSeconds &secs)
815 : hours(secs/3600),
816 minutes((secs - (hours*3600))/60),
817 seconds(secs % 60) {
818 }
819 TotalSeconds denormalize(IO &) {
820 return TotalSeconds(hours*3600 + minutes*60 + seconds);
821 }
822
823 uint32_t hours;
824 uint8_t minutes;
825 uint8_t seconds;
826 };
827
828 static void mapping(IO &io, TotalSeconds &secs) {
829 MappingNormalization<NormalizedSeconds, TotalSeconds> keys(io, secs);
830
831 io.mapOptional("hours", keys->hours, (uint32_t)0);
832 io.mapOptional("minutes", keys->minutes, (uint8_t)0);
833 io.mapRequired("seconds", keys->seconds);
834 }
835 };
836}
837}
838
839
840//
841// Test the reading of a yaml sequence of mappings
842//
843TEST(YAMLIO, TestReadMySecondsSequence) {
844 SecondsSequence seq;
845 Input yin("---\n - hours: 1\n seconds: 5\n - seconds: 59\n...\n");
846 yin >> seq;
847
848 EXPECT_FALSE(yin.error());
849 EXPECT_EQ(seq.size(), 2UL);
850 EXPECT_EQ(seq[0], 3605U);
851 EXPECT_EQ(seq[1], 59U);
852}
853
854
855//
856// Test writing then reading back custom values
857//
858TEST(YAMLIO, TestReadWriteMySecondsSequence) {
859 std::string intermediate;
860 {
861 SecondsSequence seq;
862 seq.push_back(4000);
863 seq.push_back(500);
864 seq.push_back(59);
865
866 llvm::raw_string_ostream ostr(intermediate);
867 Output yout(ostr);
868 yout << seq;
869 }
870 {
871 Input yin(intermediate);
872 SecondsSequence seq2;
873 yin >> seq2;
874
875 EXPECT_FALSE(yin.error());
876 EXPECT_EQ(seq2.size(), 3UL);
877 EXPECT_EQ(seq2[0], 4000U);
878 EXPECT_EQ(seq2[1], 500U);
879 EXPECT_EQ(seq2[2], 59U);
880 }
881}
882
883
884//===----------------------------------------------------------------------===//
885// Test dynamic typing
886//===----------------------------------------------------------------------===//
887
888enum AFlags {
889 a1,
890 a2,
891 a3
892};
893
894enum BFlags {
895 b1,
896 b2,
897 b3
898};
899
900enum Kind {
901 kindA,
902 kindB
903};
904
905struct KindAndFlags {
906 KindAndFlags() : kind(kindA), flags(0) { }
907 KindAndFlags(Kind k, uint32_t f) : kind(k), flags(f) { }
908 Kind kind;
909 uint32_t flags;
910};
911
912typedef std::vector<KindAndFlags> KindAndFlagsSequence;
913
Nick Kledzik11964f22013-01-04 19:32:00 +0000914LLVM_YAML_IS_SEQUENCE_VECTOR(KindAndFlags)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000915
916namespace llvm {
917namespace yaml {
918 template <>
919 struct ScalarEnumerationTraits<AFlags> {
920 static void enumeration(IO &io, AFlags &value) {
921 io.enumCase(value, "a1", a1);
922 io.enumCase(value, "a2", a2);
923 io.enumCase(value, "a3", a3);
924 }
925 };
926 template <>
927 struct ScalarEnumerationTraits<BFlags> {
928 static void enumeration(IO &io, BFlags &value) {
929 io.enumCase(value, "b1", b1);
930 io.enumCase(value, "b2", b2);
931 io.enumCase(value, "b3", b3);
932 }
933 };
934 template <>
935 struct ScalarEnumerationTraits<Kind> {
936 static void enumeration(IO &io, Kind &value) {
937 io.enumCase(value, "A", kindA);
938 io.enumCase(value, "B", kindB);
939 }
940 };
941 template <>
942 struct MappingTraits<KindAndFlags> {
943 static void mapping(IO &io, KindAndFlags& kf) {
944 io.mapRequired("kind", kf.kind);
Dmitri Gribenkoba9d1b52013-01-10 21:10:44 +0000945 // Type of "flags" field varies depending on "kind" field.
David Greene4162c2d2013-01-10 18:17:54 +0000946 // Use memcpy here to avoid breaking strict aliasing rules.
Dmitri Gribenkoba9d1b52013-01-10 21:10:44 +0000947 if (kf.kind == kindA) {
Dmitri Gribenko7b4fb9a2013-01-10 21:21:32 +0000948 AFlags aflags = static_cast<AFlags>(kf.flags);
David Greene4162c2d2013-01-10 18:17:54 +0000949 io.mapRequired("flags", aflags);
Dmitri Gribenko7b4fb9a2013-01-10 21:21:32 +0000950 kf.flags = aflags;
Dmitri Gribenkoba9d1b52013-01-10 21:10:44 +0000951 } else {
Dmitri Gribenko7b4fb9a2013-01-10 21:21:32 +0000952 BFlags bflags = static_cast<BFlags>(kf.flags);
David Greene4162c2d2013-01-10 18:17:54 +0000953 io.mapRequired("flags", bflags);
Dmitri Gribenko7b4fb9a2013-01-10 21:21:32 +0000954 kf.flags = bflags;
David Greene4162c2d2013-01-10 18:17:54 +0000955 }
Nick Kledzikf60a9272012-12-12 20:46:15 +0000956 }
957 };
958}
959}
960
961
962//
963// Test the reading of a yaml sequence dynamic types
964//
965TEST(YAMLIO, TestReadKindAndFlagsSequence) {
966 KindAndFlagsSequence seq;
967 Input yin("---\n - kind: A\n flags: a2\n - kind: B\n flags: b1\n...\n");
968 yin >> seq;
969
970 EXPECT_FALSE(yin.error());
971 EXPECT_EQ(seq.size(), 2UL);
972 EXPECT_EQ(seq[0].kind, kindA);
Nick Kledzik52bfd382012-12-17 20:43:53 +0000973 EXPECT_EQ(seq[0].flags, (uint32_t)a2);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000974 EXPECT_EQ(seq[1].kind, kindB);
Nick Kledzik52bfd382012-12-17 20:43:53 +0000975 EXPECT_EQ(seq[1].flags, (uint32_t)b1);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000976}
977
978//
979// Test writing then reading back dynamic types
980//
981TEST(YAMLIO, TestReadWriteKindAndFlagsSequence) {
982 std::string intermediate;
983 {
984 KindAndFlagsSequence seq;
985 seq.push_back(KindAndFlags(kindA,a1));
986 seq.push_back(KindAndFlags(kindB,b1));
987 seq.push_back(KindAndFlags(kindA,a2));
988 seq.push_back(KindAndFlags(kindB,b2));
989 seq.push_back(KindAndFlags(kindA,a3));
990
991 llvm::raw_string_ostream ostr(intermediate);
992 Output yout(ostr);
993 yout << seq;
994 }
995 {
996 Input yin(intermediate);
997 KindAndFlagsSequence seq2;
998 yin >> seq2;
999
1000 EXPECT_FALSE(yin.error());
1001 EXPECT_EQ(seq2.size(), 5UL);
1002 EXPECT_EQ(seq2[0].kind, kindA);
Nick Kledzik52bfd382012-12-17 20:43:53 +00001003 EXPECT_EQ(seq2[0].flags, (uint32_t)a1);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001004 EXPECT_EQ(seq2[1].kind, kindB);
Nick Kledzik52bfd382012-12-17 20:43:53 +00001005 EXPECT_EQ(seq2[1].flags, (uint32_t)b1);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001006 EXPECT_EQ(seq2[2].kind, kindA);
Nick Kledzik52bfd382012-12-17 20:43:53 +00001007 EXPECT_EQ(seq2[2].flags, (uint32_t)a2);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001008 EXPECT_EQ(seq2[3].kind, kindB);
Nick Kledzik52bfd382012-12-17 20:43:53 +00001009 EXPECT_EQ(seq2[3].flags, (uint32_t)b2);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001010 EXPECT_EQ(seq2[4].kind, kindA);
Nick Kledzik52bfd382012-12-17 20:43:53 +00001011 EXPECT_EQ(seq2[4].flags, (uint32_t)a3);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001012 }
1013}
1014
1015
1016//===----------------------------------------------------------------------===//
1017// Test document list
1018//===----------------------------------------------------------------------===//
1019
1020struct FooBarMap {
1021 int foo;
1022 int bar;
1023};
1024typedef std::vector<FooBarMap> FooBarMapDocumentList;
1025
1026LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(FooBarMap)
1027
1028
1029namespace llvm {
1030namespace yaml {
1031 template <>
1032 struct MappingTraits<FooBarMap> {
1033 static void mapping(IO &io, FooBarMap& fb) {
1034 io.mapRequired("foo", fb.foo);
1035 io.mapRequired("bar", fb.bar);
1036 }
1037 };
1038}
1039}
1040
1041
1042//
1043// Test the reading of a yaml mapping
1044//
1045TEST(YAMLIO, TestDocRead) {
1046 FooBarMap doc;
1047 Input yin("---\nfoo: 3\nbar: 5\n...\n");
1048 yin >> doc;
1049
1050 EXPECT_FALSE(yin.error());
1051 EXPECT_EQ(doc.foo, 3);
1052 EXPECT_EQ(doc.bar,5);
1053}
1054
1055
1056
1057//
1058// Test writing then reading back a sequence of mappings
1059//
1060TEST(YAMLIO, TestSequenceDocListWriteAndRead) {
1061 std::string intermediate;
1062 {
1063 FooBarMap doc1;
1064 doc1.foo = 10;
1065 doc1.bar = -3;
1066 FooBarMap doc2;
1067 doc2.foo = 257;
1068 doc2.bar = 0;
1069 std::vector<FooBarMap> docList;
1070 docList.push_back(doc1);
1071 docList.push_back(doc2);
1072
1073 llvm::raw_string_ostream ostr(intermediate);
1074 Output yout(ostr);
1075 yout << docList;
1076 }
1077
1078
1079 {
1080 Input yin(intermediate);
1081 std::vector<FooBarMap> docList2;
1082 yin >> docList2;
1083
1084 EXPECT_FALSE(yin.error());
1085 EXPECT_EQ(docList2.size(), 2UL);
1086 FooBarMap& map1 = docList2[0];
1087 FooBarMap& map2 = docList2[1];
1088 EXPECT_EQ(map1.foo, 10);
1089 EXPECT_EQ(map1.bar, -3);
1090 EXPECT_EQ(map2.foo, 257);
1091 EXPECT_EQ(map2.bar, 0);
1092 }
1093}
1094
Nick Kledzik1e6033c2013-11-14 00:59:59 +00001095//===----------------------------------------------------------------------===//
1096// Test document tags
1097//===----------------------------------------------------------------------===//
1098
1099struct MyDouble {
1100 MyDouble() : value(0.0) { }
1101 MyDouble(double x) : value(x) { }
1102 double value;
1103};
1104
Nick Kledzik4a9f00d2013-11-14 03:03:05 +00001105LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDouble)
Nick Kledzik1e6033c2013-11-14 00:59:59 +00001106
1107
1108namespace llvm {
1109namespace yaml {
1110 template <>
1111 struct MappingTraits<MyDouble> {
1112 static void mapping(IO &io, MyDouble &d) {
1113 if (io.mapTag("!decimal", true)) {
1114 mappingDecimal(io, d);
1115 } else if (io.mapTag("!fraction")) {
1116 mappingFraction(io, d);
1117 }
1118 }
1119 static void mappingDecimal(IO &io, MyDouble &d) {
1120 io.mapRequired("value", d.value);
1121 }
1122 static void mappingFraction(IO &io, MyDouble &d) {
1123 double num, denom;
1124 io.mapRequired("numerator", num);
1125 io.mapRequired("denominator", denom);
1126 // convert fraction to double
1127 d.value = num/denom;
1128 }
1129 };
1130 }
1131}
1132
1133
1134//
1135// Test the reading of two different tagged yaml documents.
1136//
1137TEST(YAMLIO, TestTaggedDocuments) {
1138 std::vector<MyDouble> docList;
1139 Input yin("--- !decimal\nvalue: 3.0\n"
1140 "--- !fraction\nnumerator: 9.0\ndenominator: 2\n...\n");
1141 yin >> docList;
1142 EXPECT_FALSE(yin.error());
1143 EXPECT_EQ(docList.size(), 2UL);
1144 EXPECT_EQ(docList[0].value, 3.0);
1145 EXPECT_EQ(docList[1].value, 4.5);
1146}
1147
1148
1149
1150//
1151// Test writing then reading back tagged documents
1152//
1153TEST(YAMLIO, TestTaggedDocumentsWriteAndRead) {
1154 std::string intermediate;
1155 {
1156 MyDouble a(10.25);
1157 MyDouble b(-3.75);
1158 std::vector<MyDouble> docList;
1159 docList.push_back(a);
1160 docList.push_back(b);
1161
1162 llvm::raw_string_ostream ostr(intermediate);
1163 Output yout(ostr);
1164 yout << docList;
1165 }
1166
1167 {
1168 Input yin(intermediate);
1169 std::vector<MyDouble> docList2;
1170 yin >> docList2;
1171
1172 EXPECT_FALSE(yin.error());
1173 EXPECT_EQ(docList2.size(), 2UL);
1174 EXPECT_EQ(docList2[0].value, 10.25);
1175 EXPECT_EQ(docList2[1].value, -3.75);
1176 }
1177}
1178
1179
Nick Kledzik7cd45f22013-11-21 00:28:07 +00001180//===----------------------------------------------------------------------===//
1181// Test mapping validation
1182//===----------------------------------------------------------------------===//
1183
1184struct MyValidation {
1185 double value;
1186};
1187
1188LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyValidation)
1189
1190namespace llvm {
1191namespace yaml {
1192 template <>
1193 struct MappingTraits<MyValidation> {
1194 static void mapping(IO &io, MyValidation &d) {
1195 io.mapRequired("value", d.value);
1196 }
1197 static StringRef validate(IO &io, MyValidation &d) {
1198 if (d.value < 0)
1199 return "negative value";
1200 return StringRef();
1201 }
1202 };
1203 }
1204}
1205
1206
1207//
1208// Test that validate() is called and complains about the negative value.
1209//
1210TEST(YAMLIO, TestValidatingInput) {
1211 std::vector<MyValidation> docList;
1212 Input yin("--- \nvalue: 3.0\n"
1213 "--- \nvalue: -1.0\n...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001214 nullptr, suppressErrorMessages);
Nick Kledzik7cd45f22013-11-21 00:28:07 +00001215 yin >> docList;
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001216 EXPECT_TRUE(!!yin.error());
Nick Kledzik7cd45f22013-11-21 00:28:07 +00001217}
1218
Nick Kledzikf60a9272012-12-12 20:46:15 +00001219
1220//===----------------------------------------------------------------------===//
1221// Test error handling
1222//===----------------------------------------------------------------------===//
1223
Nick Kledzikf60a9272012-12-12 20:46:15 +00001224//
1225// Test error handling of unknown enumerated scalar
1226//
1227TEST(YAMLIO, TestColorsReadError) {
1228 ColorMap map;
1229 Input yin("---\n"
1230 "c1: blue\n"
1231 "c2: purple\n"
1232 "c3: green\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001233 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001234 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001235 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001236 yin >> map;
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001237 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001238}
1239
1240
1241//
1242// Test error handling of flow sequence with unknown value
1243//
1244TEST(YAMLIO, TestFlagsReadError) {
1245 FlagsMap map;
1246 Input yin("---\n"
1247 "f1: [ big ]\n"
1248 "f2: [ round, hollow ]\n"
1249 "f3: []\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001250 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001251 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001252 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001253 yin >> map;
1254
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001255 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001256}
1257
1258
1259//
1260// Test error handling reading built-in uint8_t type
1261//
1262LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
1263TEST(YAMLIO, TestReadBuiltInTypesUint8Error) {
1264 std::vector<uint8_t> seq;
1265 Input yin("---\n"
1266 "- 255\n"
1267 "- 0\n"
1268 "- 257\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001269 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001270 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001271 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001272 yin >> seq;
1273
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001274 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001275}
1276
1277
1278//
1279// Test error handling reading built-in uint16_t type
1280//
1281LLVM_YAML_IS_SEQUENCE_VECTOR(uint16_t)
1282TEST(YAMLIO, TestReadBuiltInTypesUint16Error) {
1283 std::vector<uint16_t> seq;
1284 Input yin("---\n"
1285 "- 65535\n"
1286 "- 0\n"
1287 "- 66000\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001288 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001289 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001290 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001291 yin >> seq;
1292
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001293 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001294}
1295
1296
1297//
1298// Test error handling reading built-in uint32_t type
1299//
1300LLVM_YAML_IS_SEQUENCE_VECTOR(uint32_t)
1301TEST(YAMLIO, TestReadBuiltInTypesUint32Error) {
1302 std::vector<uint32_t> seq;
1303 Input yin("---\n"
1304 "- 4000000000\n"
1305 "- 0\n"
1306 "- 5000000000\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001307 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001308 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001309 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001310 yin >> seq;
1311
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001312 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001313}
1314
1315
1316//
1317// Test error handling reading built-in uint64_t type
1318//
1319LLVM_YAML_IS_SEQUENCE_VECTOR(uint64_t)
1320TEST(YAMLIO, TestReadBuiltInTypesUint64Error) {
1321 std::vector<uint64_t> seq;
1322 Input yin("---\n"
1323 "- 18446744073709551615\n"
1324 "- 0\n"
1325 "- 19446744073709551615\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001326 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001327 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001328 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001329 yin >> seq;
1330
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001331 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001332}
1333
1334
1335//
1336// Test error handling reading built-in int8_t type
1337//
1338LLVM_YAML_IS_SEQUENCE_VECTOR(int8_t)
1339TEST(YAMLIO, TestReadBuiltInTypesint8OverError) {
1340 std::vector<int8_t> seq;
1341 Input yin("---\n"
1342 "- -128\n"
1343 "- 0\n"
1344 "- 127\n"
1345 "- 128\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001346 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001347 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001348 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001349 yin >> seq;
1350
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001351 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001352}
1353
1354//
1355// Test error handling reading built-in int8_t type
1356//
1357TEST(YAMLIO, TestReadBuiltInTypesint8UnderError) {
1358 std::vector<int8_t> seq;
1359 Input yin("---\n"
1360 "- -128\n"
1361 "- 0\n"
1362 "- 127\n"
1363 "- -129\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001364 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001365 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001366 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001367 yin >> seq;
1368
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001369 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001370}
1371
1372
1373//
1374// Test error handling reading built-in int16_t type
1375//
1376LLVM_YAML_IS_SEQUENCE_VECTOR(int16_t)
1377TEST(YAMLIO, TestReadBuiltInTypesint16UnderError) {
1378 std::vector<int16_t> seq;
1379 Input yin("---\n"
1380 "- 32767\n"
1381 "- 0\n"
1382 "- -32768\n"
1383 "- -32769\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001384 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001385 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001386 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001387 yin >> seq;
1388
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001389 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001390}
1391
1392
1393//
1394// Test error handling reading built-in int16_t type
1395//
1396TEST(YAMLIO, TestReadBuiltInTypesint16OverError) {
1397 std::vector<int16_t> seq;
1398 Input yin("---\n"
1399 "- 32767\n"
1400 "- 0\n"
1401 "- -32768\n"
1402 "- 32768\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001403 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001404 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001405 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001406 yin >> seq;
1407
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001408 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001409}
1410
1411
1412//
1413// Test error handling reading built-in int32_t type
1414//
1415LLVM_YAML_IS_SEQUENCE_VECTOR(int32_t)
1416TEST(YAMLIO, TestReadBuiltInTypesint32UnderError) {
1417 std::vector<int32_t> seq;
1418 Input yin("---\n"
1419 "- 2147483647\n"
1420 "- 0\n"
1421 "- -2147483648\n"
1422 "- -2147483649\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001423 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001424 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001425 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001426 yin >> seq;
1427
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001428 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001429}
1430
1431//
1432// Test error handling reading built-in int32_t type
1433//
1434TEST(YAMLIO, TestReadBuiltInTypesint32OverError) {
1435 std::vector<int32_t> seq;
1436 Input yin("---\n"
1437 "- 2147483647\n"
1438 "- 0\n"
1439 "- -2147483648\n"
1440 "- 2147483649\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001441 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001442 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001443 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001444 yin >> seq;
1445
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001446 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001447}
1448
1449
1450//
1451// Test error handling reading built-in int64_t type
1452//
1453LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
1454TEST(YAMLIO, TestReadBuiltInTypesint64UnderError) {
1455 std::vector<int64_t> seq;
1456 Input yin("---\n"
1457 "- -9223372036854775808\n"
1458 "- 0\n"
1459 "- 9223372036854775807\n"
1460 "- -9223372036854775809\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001461 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001462 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001463 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001464 yin >> seq;
1465
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001466 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001467}
1468
1469//
1470// Test error handling reading built-in int64_t type
1471//
1472TEST(YAMLIO, TestReadBuiltInTypesint64OverError) {
1473 std::vector<int64_t> seq;
1474 Input yin("---\n"
1475 "- -9223372036854775808\n"
1476 "- 0\n"
1477 "- 9223372036854775807\n"
1478 "- 9223372036854775809\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001479 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001480 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001481 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001482 yin >> seq;
1483
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001484 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001485}
1486
1487//
1488// Test error handling reading built-in float type
1489//
1490LLVM_YAML_IS_SEQUENCE_VECTOR(float)
1491TEST(YAMLIO, TestReadBuiltInTypesFloatError) {
1492 std::vector<float> seq;
1493 Input yin("---\n"
1494 "- 0.0\n"
1495 "- 1000.1\n"
1496 "- -123.456\n"
1497 "- 1.2.3\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001498 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001499 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001500 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001501 yin >> seq;
1502
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001503 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001504}
1505
1506//
1507// Test error handling reading built-in float type
1508//
1509LLVM_YAML_IS_SEQUENCE_VECTOR(double)
1510TEST(YAMLIO, TestReadBuiltInTypesDoubleError) {
1511 std::vector<double> seq;
1512 Input yin("---\n"
1513 "- 0.0\n"
1514 "- 1000.1\n"
1515 "- -123.456\n"
1516 "- 1.2.3\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001517 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001518 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001519 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001520 yin >> seq;
1521
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001522 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001523}
1524
1525//
1526// Test error handling reading built-in Hex8 type
1527//
1528LLVM_YAML_IS_SEQUENCE_VECTOR(Hex8)
1529TEST(YAMLIO, TestReadBuiltInTypesHex8Error) {
1530 std::vector<Hex8> seq;
1531 Input yin("---\n"
1532 "- 0x12\n"
1533 "- 0xFE\n"
1534 "- 0x123\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001535 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001536 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001537 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001538 yin >> seq;
1539
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001540 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001541}
1542
1543
1544//
1545// Test error handling reading built-in Hex16 type
1546//
1547LLVM_YAML_IS_SEQUENCE_VECTOR(Hex16)
1548TEST(YAMLIO, TestReadBuiltInTypesHex16Error) {
1549 std::vector<Hex16> seq;
1550 Input yin("---\n"
1551 "- 0x0012\n"
1552 "- 0xFEFF\n"
1553 "- 0x12345\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001554 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001555 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001556 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001557 yin >> seq;
1558
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001559 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001560}
1561
1562//
1563// Test error handling reading built-in Hex32 type
1564//
1565LLVM_YAML_IS_SEQUENCE_VECTOR(Hex32)
1566TEST(YAMLIO, TestReadBuiltInTypesHex32Error) {
1567 std::vector<Hex32> seq;
1568 Input yin("---\n"
1569 "- 0x0012\n"
1570 "- 0xFEFF0000\n"
1571 "- 0x1234556789\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001572 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001573 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001574 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001575 yin >> seq;
1576
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001577 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001578}
1579
1580//
1581// Test error handling reading built-in Hex64 type
1582//
1583LLVM_YAML_IS_SEQUENCE_VECTOR(Hex64)
1584TEST(YAMLIO, TestReadBuiltInTypesHex64Error) {
1585 std::vector<Hex64> seq;
1586 Input yin("---\n"
1587 "- 0x0012\n"
1588 "- 0xFFEEDDCCBBAA9988\n"
1589 "- 0x12345567890ABCDEF0\n"
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001590 "...\n",
Craig Topper66f09ad2014-06-08 22:29:17 +00001591 /*Ctxt=*/nullptr,
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001592 suppressErrorMessages);
Nick Kledzikf60a9272012-12-12 20:46:15 +00001593 yin >> seq;
1594
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001595 EXPECT_TRUE(!!yin.error());
Nick Kledzikf60a9272012-12-12 20:46:15 +00001596}
1597
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001598TEST(YAMLIO, TestMalformedMapFailsGracefully) {
1599 FooBar doc;
1600 {
1601 // We pass the suppressErrorMessages handler to handle the error
1602 // message generated in the constructor of Input.
Craig Topper66f09ad2014-06-08 22:29:17 +00001603 Input yin("{foo:3, bar: 5}", /*Ctxt=*/nullptr, suppressErrorMessages);
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001604 yin >> doc;
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001605 EXPECT_TRUE(!!yin.error());
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001606 }
1607
1608 {
Craig Topper66f09ad2014-06-08 22:29:17 +00001609 Input yin("---\nfoo:3\nbar: 5\n...\n", /*Ctxt=*/nullptr, suppressErrorMessages);
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001610 yin >> doc;
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001611 EXPECT_TRUE(!!yin.error());
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001612 }
1613}
1614
Aaron Ballman0e63e532013-08-15 23:17:53 +00001615struct OptionalTest {
1616 std::vector<int> Numbers;
1617};
1618
1619struct OptionalTestSeq {
1620 std::vector<OptionalTest> Tests;
1621};
1622
Aaron Ballman381f59f2013-08-16 01:53:58 +00001623LLVM_YAML_IS_SEQUENCE_VECTOR(OptionalTest)
Aaron Ballman0e63e532013-08-15 23:17:53 +00001624namespace llvm {
1625namespace yaml {
1626 template <>
1627 struct MappingTraits<OptionalTest> {
1628 static void mapping(IO& IO, OptionalTest &OT) {
1629 IO.mapOptional("Numbers", OT.Numbers);
1630 }
1631 };
1632
1633 template <>
1634 struct MappingTraits<OptionalTestSeq> {
1635 static void mapping(IO &IO, OptionalTestSeq &OTS) {
1636 IO.mapOptional("Tests", OTS.Tests);
1637 }
1638 };
1639}
1640}
1641
1642TEST(YAMLIO, SequenceElideTest) {
1643 // Test that writing out a purely optional structure with its fields set to
1644 // default followed by other data is properly read back in.
1645 OptionalTestSeq Seq;
1646 OptionalTest One, Two, Three, Four;
1647 int N[] = {1, 2, 3};
1648 Three.Numbers.assign(N, N + 3);
1649 Seq.Tests.push_back(One);
1650 Seq.Tests.push_back(Two);
1651 Seq.Tests.push_back(Three);
1652 Seq.Tests.push_back(Four);
1653
1654 std::string intermediate;
1655 {
1656 llvm::raw_string_ostream ostr(intermediate);
1657 Output yout(ostr);
1658 yout << Seq;
1659 }
1660
1661 Input yin(intermediate);
1662 OptionalTestSeq Seq2;
1663 yin >> Seq2;
Rui Ueyama38dfffa2013-09-11 00:53:07 +00001664
Aaron Ballman0e63e532013-08-15 23:17:53 +00001665 EXPECT_FALSE(yin.error());
1666
1667 EXPECT_EQ(4UL, Seq2.Tests.size());
1668
1669 EXPECT_TRUE(Seq2.Tests[0].Numbers.empty());
1670 EXPECT_TRUE(Seq2.Tests[1].Numbers.empty());
1671
1672 EXPECT_EQ(1, Seq2.Tests[2].Numbers[0]);
1673 EXPECT_EQ(2, Seq2.Tests[2].Numbers[1]);
1674 EXPECT_EQ(3, Seq2.Tests[2].Numbers[2]);
1675
1676 EXPECT_TRUE(Seq2.Tests[3].Numbers.empty());
1677}
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001678
1679TEST(YAMLIO, TestEmptyStringFailsForMapWithRequiredFields) {
1680 FooBar doc;
1681 Input yin("");
1682 yin >> doc;
Rafael Espindolad9a25d82014-06-03 04:42:24 +00001683 EXPECT_TRUE(!!yin.error());
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001684}
1685
1686TEST(YAMLIO, TestEmptyStringSucceedsForMapWithOptionalFields) {
1687 OptionalTest doc;
1688 Input yin("");
1689 yin >> doc;
1690 EXPECT_FALSE(yin.error());
1691}
1692
1693TEST(YAMLIO, TestEmptyStringSucceedsForSequence) {
1694 std::vector<uint8_t> seq;
Craig Topper66f09ad2014-06-08 22:29:17 +00001695 Input yin("", /*Ctxt=*/nullptr, suppressErrorMessages);
Alexander Kornienko681e37c2013-11-18 15:50:04 +00001696 yin >> seq;
1697
1698 EXPECT_FALSE(yin.error());
1699 EXPECT_TRUE(seq.empty());
1700}