1 //===- MsgPackDocumentTest.cpp --------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/BinaryFormat/MsgPackDocument.h"
10 #include "gtest/gtest.h"
13 using namespace msgpack
;
15 TEST(MsgPackDocument
, DocNodeTest
) {
18 DocNode Int1
= Doc
.getNode(1), Int2
= Doc
.getNode(2);
19 DocNode Str1
= Doc
.getNode("ab"), Str2
= Doc
.getNode("ab");
21 ASSERT_TRUE(Int1
!= Int2
);
22 ASSERT_TRUE(Str1
== Str2
);
25 TEST(MsgPackDocument
, TestReadInt
) {
27 bool Ok
= Doc
.readFromBlob(StringRef("\xd0\x00", 2), /*Multi=*/false);
29 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Int
);
30 ASSERT_EQ(Doc
.getRoot().getInt(), 0);
33 TEST(MsgPackDocument
, TestReadBinary
) {
35 uint8_t data
[] = {1, 2, 3, 4};
37 Doc
.readFromBlob(StringRef("\xC4\x4\x1\x2\x3\x4", 6), /*Multi=*/false);
39 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Binary
);
40 ASSERT_EQ(Doc
.getRoot().getBinary().getBuffer(),
41 StringRef(reinterpret_cast<const char *>(data
), 4));
44 TEST(MsgPackDocument
, TestReadMergeArray
) {
46 bool Ok
= Doc
.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
48 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Array
);
49 auto A
= Doc
.getRoot().getArray();
50 ASSERT_EQ(A
.size(), 2u);
52 ASSERT_EQ(SI
.getKind(), Type::Int
);
53 ASSERT_EQ(SI
.getInt(), 1);
55 ASSERT_EQ(SN
.getKind(), Type::Nil
);
57 Ok
= Doc
.readFromBlob(StringRef("\x91\xd0\x2a"), /*Multi=*/false,
58 [](DocNode
*DestNode
, DocNode SrcNode
, DocNode MapKey
) {
59 // Allow array, merging into existing elements, ORing
61 if (DestNode
->getKind() == Type::Int
&&
62 SrcNode
.getKind() == Type::Int
) {
63 *DestNode
= DestNode
->getDocument()->getNode(
64 DestNode
->getInt() | SrcNode
.getInt());
67 return DestNode
->isArray() && SrcNode
.isArray() ? 0
71 A
= Doc
.getRoot().getArray();
72 ASSERT_EQ(A
.size(), 2u);
74 ASSERT_EQ(SI
.getKind(), Type::Int
);
75 ASSERT_EQ(SI
.getInt(), 43);
77 ASSERT_EQ(SN
.getKind(), Type::Nil
);
80 TEST(MsgPackDocument
, TestReadAppendArray
) {
82 bool Ok
= Doc
.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
84 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Array
);
85 auto A
= Doc
.getRoot().getArray();
86 ASSERT_EQ(A
.size(), 2u);
88 ASSERT_EQ(SI
.getKind(), Type::Int
);
89 ASSERT_EQ(SI
.getInt(), 1);
91 ASSERT_EQ(SN
.getKind(), Type::Nil
);
93 Ok
= Doc
.readFromBlob(StringRef("\x91\xd0\x2a"), /*Multi=*/false,
94 [](DocNode
*DestNode
, DocNode SrcNode
, DocNode MapKey
) {
95 // Allow array, appending after existing elements
96 return DestNode
->isArray() && SrcNode
.isArray()
97 ? DestNode
->getArray().size()
101 A
= Doc
.getRoot().getArray();
102 ASSERT_EQ(A
.size(), 3u);
104 ASSERT_EQ(SI
.getKind(), Type::Int
);
105 ASSERT_EQ(SI
.getInt(), 1);
107 ASSERT_EQ(SN
.getKind(), Type::Nil
);
109 ASSERT_EQ(SI
.getKind(), Type::Int
);
110 ASSERT_EQ(SI
.getInt(), 42);
113 TEST(MsgPackDocument
, TestReadMergeMap
) {
115 bool Ok
= Doc
.readFromBlob(StringRef("\x82\xa3"
122 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Map
);
123 auto M
= Doc
.getRoot().getMap();
124 ASSERT_EQ(M
.size(), 2u);
125 auto FooS
= M
["foo"];
126 ASSERT_EQ(FooS
.getKind(), Type::Int
);
127 ASSERT_EQ(FooS
.getInt(), 1);
128 auto BarS
= M
["bar"];
129 ASSERT_EQ(BarS
.getKind(), Type::Int
);
130 ASSERT_EQ(BarS
.getInt(), 2);
132 Ok
= Doc
.readFromBlob(StringRef("\x82\xa3"
138 [](DocNode
*DestNode
, DocNode SrcNode
, DocNode MapKey
) {
139 return DestNode
->isMap() && SrcNode
.isMap() ? 0 : -1;
142 ASSERT_EQ(M
.size(), 4u);
144 ASSERT_EQ(FooS
.getKind(), Type::Int
);
145 ASSERT_EQ(FooS
.getInt(), 1);
147 ASSERT_EQ(BarS
.getKind(), Type::Int
);
148 ASSERT_EQ(BarS
.getInt(), 2);
149 auto FozS
= M
["foz"];
150 ASSERT_EQ(FozS
.getKind(), Type::Int
);
151 ASSERT_EQ(FozS
.getInt(), 3);
152 auto BazS
= M
["baz"];
153 ASSERT_EQ(BazS
.getKind(), Type::Int
);
154 ASSERT_EQ(BazS
.getInt(), 4);
156 Ok
= Doc
.readFromBlob(
162 /*Multi=*/false, [](DocNode
*Dest
, DocNode Src
, DocNode MapKey
) {
163 // Merger function that merges two ints by ORing their values, as long
164 // as the map key is "foz".
166 return Dest
->isMap();
168 return Dest
->isArray();
169 if (MapKey
.isString() && MapKey
.getString() == "foz" &&
170 Dest
->getKind() == Type::Int
&& Src
.getKind() == Type::Int
) {
171 *Dest
= Src
.getDocument()->getNode(Dest
->getInt() | Src
.getInt());
177 ASSERT_EQ(M
.size(), 5u);
179 ASSERT_EQ(FooS
.getKind(), Type::Int
);
180 ASSERT_EQ(FooS
.getInt(), 1);
182 ASSERT_EQ(BarS
.getKind(), Type::Int
);
183 ASSERT_EQ(BarS
.getInt(), 2);
185 ASSERT_EQ(FozS
.getKind(), Type::Int
);
186 ASSERT_EQ(FozS
.getInt(), 7);
188 ASSERT_EQ(BazS
.getKind(), Type::Int
);
189 ASSERT_EQ(BazS
.getInt(), 4);
190 auto BayS
= M
["bay"];
191 ASSERT_EQ(BayS
.getKind(), Type::Int
);
192 ASSERT_EQ(BayS
.getInt(), 8);
195 TEST(MsgPackDocument
, TestWriteInt
) {
199 Doc
.writeToBlob(Buffer
);
200 ASSERT_EQ(Buffer
, "\x01");
203 TEST(MsgPackDocument
, TestWriteBinary
) {
204 uint8_t data
[] = {1, 2, 3, 4};
206 Doc
.getRoot() = MemoryBufferRef(
207 StringRef(reinterpret_cast<const char *>(data
), sizeof(data
)), "");
209 Doc
.writeToBlob(Buffer
);
210 ASSERT_EQ(Buffer
, "\xC4\x4\x1\x2\x3\x4");
213 TEST(MsgPackDocument
, TestWriteArray
) {
215 auto A
= Doc
.getRoot().getArray(/*Convert=*/true);
216 A
.push_back(Doc
.getNode(int64_t(1)));
217 A
.push_back(Doc
.getNode());
219 Doc
.writeToBlob(Buffer
);
220 ASSERT_EQ(Buffer
, "\x92\x01\xc0");
223 TEST(MsgPackDocument
, TestWriteMap
) {
225 auto M
= Doc
.getRoot().getMap(/*Convert=*/true);
229 Doc
.writeToBlob(Buffer
);
230 ASSERT_EQ(Buffer
, "\x82\xa3"
237 TEST(MsgPackDocument
, TestOutputYAMLArray
) {
239 auto A
= Doc
.getRoot().getArray(/*Convert=*/true);
240 A
.push_back(Doc
.getNode(int64_t(1)));
241 A
.push_back(Doc
.getNode(int64_t(2)));
243 raw_string_ostream
OStream(Buffer
);
245 ASSERT_EQ(OStream
.str(), "---\n- 1\n- 2\n...\n");
248 TEST(MsgPackDocument
, TestInputYAMLArray
) {
250 bool Ok
= Doc
.fromYAML("---\n- !int 0x1\n- !str 2\n...\n");
252 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Array
);
253 auto A
= Doc
.getRoot().getArray();
254 ASSERT_EQ(A
.size(), 2u);
256 ASSERT_EQ(SI
.getKind(), Type::UInt
);
257 ASSERT_EQ(SI
.getUInt(), 1u);
259 ASSERT_EQ(SS
.getKind(), Type::String
);
260 ASSERT_EQ(SS
.getString(), "2");
263 TEST(MsgPackDocument
, TestOutputYAMLMap
) {
265 auto M
= Doc
.getRoot().getMap(/*Convert=*/true);
268 auto N
= Doc
.getMapNode();
272 raw_string_ostream
OStream(Buffer
);
274 ASSERT_EQ(OStream
.str(), "---\n"
282 TEST(MsgPackDocument
, TestOutputYAMLMapWithErase
) {
284 auto M
= Doc
.getRoot().getMap(/*Convert=*/true);
287 auto N
= Doc
.getMapNode();
290 M
.erase(Doc
.getNode("bar"));
292 raw_string_ostream
OStream(Buffer
);
294 ASSERT_EQ(OStream
.str(), "---\n"
301 TEST(MsgPackDocument
, TestOutputYAMLMapHex
) {
304 auto M
= Doc
.getRoot().getMap(/*Convert=*/true);
307 auto N
= Doc
.getMapNode();
311 raw_string_ostream
OStream(Buffer
);
313 ASSERT_EQ(OStream
.str(), "---\n"
321 TEST(MsgPackDocument
, TestInputYAMLMap
) {
323 bool Ok
= Doc
.fromYAML("---\nfoo: !int 0x1\nbaz: !str 2\n...\n");
325 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Map
);
326 auto M
= Doc
.getRoot().getMap();
327 ASSERT_EQ(M
.size(), 2u);
329 ASSERT_EQ(SI
.getKind(), Type::UInt
);
330 ASSERT_EQ(SI
.getUInt(), 1u);
332 ASSERT_EQ(SS
.getKind(), Type::String
);
333 ASSERT_EQ(SS
.getString(), "2");