• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- MsgPackDocumentTest.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/BinaryFormat/MsgPackDocument.h"
11 #include "gtest/gtest.h"
12 
13 using namespace llvm;
14 using namespace msgpack;
15 
TEST(MsgPackDocument,DocNodeTest)16 TEST(MsgPackDocument, DocNodeTest) {
17   Document Doc;
18 
19   DocNode Int1 = Doc.getNode(1), Int2 = Doc.getNode(2);
20   DocNode Str1 = Doc.getNode("ab"), Str2 = Doc.getNode("ab");
21 
22   ASSERT_TRUE(Int1 != Int2);
23   ASSERT_TRUE(Str1 == Str2);
24 }
25 
TEST(MsgPackDocument,TestReadInt)26 TEST(MsgPackDocument, TestReadInt) {
27   Document Doc;
28   bool Ok = Doc.readFromBlob(StringRef("\xd0\x00", 2), /*Multi=*/false);
29   ASSERT_TRUE(Ok);
30   ASSERT_EQ(Doc.getRoot().getKind(), Type::Int);
31   ASSERT_EQ(Doc.getRoot().getInt(), 0);
32 }
33 
TEST(MsgPackDocument,TestReadMergeArray)34 TEST(MsgPackDocument, TestReadMergeArray) {
35   Document Doc;
36   bool Ok = Doc.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
37   ASSERT_TRUE(Ok);
38   ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
39   auto A = Doc.getRoot().getArray();
40   ASSERT_EQ(A.size(), 2u);
41   auto SI = A[0];
42   ASSERT_EQ(SI.getKind(), Type::Int);
43   ASSERT_EQ(SI.getInt(), 1);
44   auto SN = A[1];
45   ASSERT_EQ(SN.getKind(), Type::Nil);
46 
47   Ok = Doc.readFromBlob(StringRef("\x91\xd0\x2a"), /*Multi=*/false,
48                         [](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
49                           // Allow array, merging into existing elements, ORing
50                           // ints.
51                           if (DestNode->getKind() == Type::Int &&
52                               SrcNode.getKind() == Type::Int) {
53                             *DestNode = DestNode->getDocument()->getNode(
54                                 DestNode->getInt() | SrcNode.getInt());
55                             return 0;
56                           }
57                           return DestNode->isArray() && SrcNode.isArray() ? 0
58                                                                           : -1;
59                         });
60   ASSERT_TRUE(Ok);
61   A = Doc.getRoot().getArray();
62   ASSERT_EQ(A.size(), 2u);
63   SI = A[0];
64   ASSERT_EQ(SI.getKind(), Type::Int);
65   ASSERT_EQ(SI.getInt(), 43);
66   SN = A[1];
67   ASSERT_EQ(SN.getKind(), Type::Nil);
68 }
69 
TEST(MsgPackDocument,TestReadAppendArray)70 TEST(MsgPackDocument, TestReadAppendArray) {
71   Document Doc;
72   bool Ok = Doc.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
73   ASSERT_TRUE(Ok);
74   ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
75   auto A = Doc.getRoot().getArray();
76   ASSERT_EQ(A.size(), 2u);
77   auto SI = A[0];
78   ASSERT_EQ(SI.getKind(), Type::Int);
79   ASSERT_EQ(SI.getInt(), 1);
80   auto SN = A[1];
81   ASSERT_EQ(SN.getKind(), Type::Nil);
82 
83   Ok = Doc.readFromBlob(StringRef("\x91\xd0\x2a"), /*Multi=*/false,
84                         [](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
85                           // Allow array, appending after existing elements
86                           return DestNode->isArray() && SrcNode.isArray()
87                                      ? DestNode->getArray().size()
88                                      : -1;
89                         });
90   ASSERT_TRUE(Ok);
91   A = Doc.getRoot().getArray();
92   ASSERT_EQ(A.size(), 3u);
93   SI = A[0];
94   ASSERT_EQ(SI.getKind(), Type::Int);
95   ASSERT_EQ(SI.getInt(), 1);
96   SN = A[1];
97   ASSERT_EQ(SN.getKind(), Type::Nil);
98   SI = A[2];
99   ASSERT_EQ(SI.getKind(), Type::Int);
100   ASSERT_EQ(SI.getInt(), 42);
101 }
102 
TEST(MsgPackDocument,TestReadMergeMap)103 TEST(MsgPackDocument, TestReadMergeMap) {
104   Document Doc;
105   bool Ok = Doc.readFromBlob(StringRef("\x82\xa3"
106                                        "foo"
107                                        "\xd0\x01\xa3"
108                                        "bar"
109                                        "\xd0\x02"),
110                              /*Multi=*/false);
111   ASSERT_TRUE(Ok);
112   ASSERT_EQ(Doc.getRoot().getKind(), Type::Map);
113   auto M = Doc.getRoot().getMap();
114   ASSERT_EQ(M.size(), 2u);
115   auto FooS = M["foo"];
116   ASSERT_EQ(FooS.getKind(), Type::Int);
117   ASSERT_EQ(FooS.getInt(), 1);
118   auto BarS = M["bar"];
119   ASSERT_EQ(BarS.getKind(), Type::Int);
120   ASSERT_EQ(BarS.getInt(), 2);
121 
122   Ok = Doc.readFromBlob(StringRef("\x82\xa3"
123                                   "foz"
124                                   "\xd0\x03\xa3"
125                                   "baz"
126                                   "\xd0\x04"),
127                         /*Multi=*/false,
128                         [](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
129                           return DestNode->isMap() && SrcNode.isMap() ? 0 : -1;
130                         });
131   ASSERT_TRUE(Ok);
132   ASSERT_EQ(M.size(), 4u);
133   FooS = M["foo"];
134   ASSERT_EQ(FooS.getKind(), Type::Int);
135   ASSERT_EQ(FooS.getInt(), 1);
136   BarS = M["bar"];
137   ASSERT_EQ(BarS.getKind(), Type::Int);
138   ASSERT_EQ(BarS.getInt(), 2);
139   auto FozS = M["foz"];
140   ASSERT_EQ(FozS.getKind(), Type::Int);
141   ASSERT_EQ(FozS.getInt(), 3);
142   auto BazS = M["baz"];
143   ASSERT_EQ(BazS.getKind(), Type::Int);
144   ASSERT_EQ(BazS.getInt(), 4);
145 
146   Ok = Doc.readFromBlob(
147       StringRef("\x82\xa3"
148                 "foz"
149                 "\xd0\x06\xa3"
150                 "bay"
151                 "\xd0\x08"),
152       /*Multi=*/false, [](DocNode *Dest, DocNode Src, DocNode MapKey) {
153         // Merger function that merges two ints by ORing their values, as long
154         // as the map key is "foz".
155         if (Src.isMap())
156           return Dest->isMap();
157         if (Src.isArray())
158           return Dest->isArray();
159         if (MapKey.isString() && MapKey.getString() == "foz" &&
160             Dest->getKind() == Type::Int && Src.getKind() == Type::Int) {
161           *Dest = Src.getDocument()->getNode(Dest->getInt() | Src.getInt());
162           return true;
163         }
164         return false;
165       });
166   ASSERT_TRUE(Ok);
167   ASSERT_EQ(M.size(), 5u);
168   FooS = M["foo"];
169   ASSERT_EQ(FooS.getKind(), Type::Int);
170   ASSERT_EQ(FooS.getInt(), 1);
171   BarS = M["bar"];
172   ASSERT_EQ(BarS.getKind(), Type::Int);
173   ASSERT_EQ(BarS.getInt(), 2);
174   FozS = M["foz"];
175   ASSERT_EQ(FozS.getKind(), Type::Int);
176   ASSERT_EQ(FozS.getInt(), 7);
177   BazS = M["baz"];
178   ASSERT_EQ(BazS.getKind(), Type::Int);
179   ASSERT_EQ(BazS.getInt(), 4);
180   auto BayS = M["bay"];
181   ASSERT_EQ(BayS.getKind(), Type::Int);
182   ASSERT_EQ(BayS.getInt(), 8);
183 }
184 
TEST(MsgPackDocument,TestWriteInt)185 TEST(MsgPackDocument, TestWriteInt) {
186   Document Doc;
187   Doc.getRoot() = 1;
188   std::string Buffer;
189   Doc.writeToBlob(Buffer);
190   ASSERT_EQ(Buffer, "\x01");
191 }
192 
TEST(MsgPackDocument,TestWriteArray)193 TEST(MsgPackDocument, TestWriteArray) {
194   Document Doc;
195   auto A = Doc.getRoot().getArray(/*Convert=*/true);
196   A.push_back(Doc.getNode(int64_t(1)));
197   A.push_back(Doc.getNode());
198   std::string Buffer;
199   Doc.writeToBlob(Buffer);
200   ASSERT_EQ(Buffer, "\x92\x01\xc0");
201 }
202 
TEST(MsgPackDocument,TestWriteMap)203 TEST(MsgPackDocument, TestWriteMap) {
204   Document Doc;
205   auto M = Doc.getRoot().getMap(/*Convert=*/true);
206   M["foo"] = 1;
207   M["bar"] = 2;
208   std::string Buffer;
209   Doc.writeToBlob(Buffer);
210   ASSERT_EQ(Buffer, "\x82\xa3"
211                     "bar"
212                     "\x02\xa3"
213                     "foo"
214                     "\x01");
215 }
216 
TEST(MsgPackDocument,TestOutputYAMLArray)217 TEST(MsgPackDocument, TestOutputYAMLArray) {
218   Document Doc;
219   auto A = Doc.getRoot().getArray(/*Convert=*/true);
220   A.push_back(Doc.getNode(int64_t(1)));
221   A.push_back(Doc.getNode(int64_t(2)));
222   std::string Buffer;
223   raw_string_ostream OStream(Buffer);
224   Doc.toYAML(OStream);
225   ASSERT_EQ(OStream.str(), "---\n- 1\n- 2\n...\n");
226 }
227 
TEST(MsgPackDocument,TestInputYAMLArray)228 TEST(MsgPackDocument, TestInputYAMLArray) {
229   Document Doc;
230   bool Ok = Doc.fromYAML("---\n- !int 0x1\n- !str 2\n...\n");
231   ASSERT_TRUE(Ok);
232   ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
233   auto A = Doc.getRoot().getArray();
234   ASSERT_EQ(A.size(), 2u);
235   auto SI = A[0];
236   ASSERT_EQ(SI.getKind(), Type::UInt);
237   ASSERT_EQ(SI.getUInt(), 1u);
238   auto SS = A[1];
239   ASSERT_EQ(SS.getKind(), Type::String);
240   ASSERT_EQ(SS.getString(), "2");
241 }
242 
TEST(MsgPackDocument,TestOutputYAMLMap)243 TEST(MsgPackDocument, TestOutputYAMLMap) {
244   Document Doc;
245   auto M = Doc.getRoot().getMap(/*Convert=*/true);
246   M["foo"] = 1;
247   M["bar"] = 2U;
248   auto N = Doc.getMapNode();
249   M["qux"] = N;
250   N["baz"] = true;
251   std::string Buffer;
252   raw_string_ostream OStream(Buffer);
253   Doc.toYAML(OStream);
254   ASSERT_EQ(OStream.str(), "---\n"
255                            "bar:             2\n"
256                            "foo:             1\n"
257                            "qux:\n"
258                            "  baz:             true\n"
259                            "...\n");
260 }
261 
TEST(MsgPackDocument,TestOutputYAMLMapWithErase)262 TEST(MsgPackDocument, TestOutputYAMLMapWithErase) {
263   Document Doc;
264   auto M = Doc.getRoot().getMap(/*Convert=*/true);
265   M["foo"] = 1;
266   M["bar"] = 2U;
267   auto N = Doc.getMapNode();
268   M["qux"] = N;
269   N["baz"] = true;
270   M.erase(Doc.getNode("bar"));
271   std::string Buffer;
272   raw_string_ostream OStream(Buffer);
273   Doc.toYAML(OStream);
274   ASSERT_EQ(OStream.str(), "---\n"
275                            "foo:             1\n"
276                            "qux:\n"
277                            "  baz:             true\n"
278                            "...\n");
279 }
280 
TEST(MsgPackDocument,TestOutputYAMLMapHex)281 TEST(MsgPackDocument, TestOutputYAMLMapHex) {
282   Document Doc;
283   Doc.setHexMode();
284   auto M = Doc.getRoot().getMap(/*Convert=*/true);
285   M["foo"] = 1;
286   M["bar"] = 2U;
287   auto N = Doc.getMapNode();
288   M["qux"] = N;
289   N["baz"] = true;
290   std::string Buffer;
291   raw_string_ostream OStream(Buffer);
292   Doc.toYAML(OStream);
293   ASSERT_EQ(OStream.str(), "---\n"
294                            "bar:             0x2\n"
295                            "foo:             1\n"
296                            "qux:\n"
297                            "  baz:             true\n"
298                            "...\n");
299 }
300 
TEST(MsgPackDocument,TestInputYAMLMap)301 TEST(MsgPackDocument, TestInputYAMLMap) {
302   Document Doc;
303   bool Ok = Doc.fromYAML("---\nfoo: !int 0x1\nbaz: !str 2\n...\n");
304   ASSERT_TRUE(Ok);
305   ASSERT_EQ(Doc.getRoot().getKind(), Type::Map);
306   auto M = Doc.getRoot().getMap();
307   ASSERT_EQ(M.size(), 2u);
308   auto SI = M["foo"];
309   ASSERT_EQ(SI.getKind(), Type::UInt);
310   ASSERT_EQ(SI.getUInt(), 1u);
311   auto SS = M["baz"];
312   ASSERT_EQ(SS.getKind(), Type::String);
313   ASSERT_EQ(SS.getString(), "2");
314 }
315