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
, TestReadMergeArray
) {
35 bool Ok
= Doc
.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
37 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Array
);
38 auto A
= Doc
.getRoot().getArray();
39 ASSERT_EQ(A
.size(), 2u);
41 ASSERT_EQ(SI
.getKind(), Type::Int
);
42 ASSERT_EQ(SI
.getInt(), 1);
44 ASSERT_EQ(SN
.getKind(), Type::Nil
);
46 Ok
= Doc
.readFromBlob(StringRef("\x91\xd0\x2a"), /*Multi=*/false,
47 [](DocNode
*DestNode
, DocNode SrcNode
, DocNode MapKey
) {
48 // Allow array, merging into existing elements, ORing
50 if (DestNode
->getKind() == Type::Int
&&
51 SrcNode
.getKind() == Type::Int
) {
52 *DestNode
= DestNode
->getDocument()->getNode(
53 DestNode
->getInt() | SrcNode
.getInt());
56 return DestNode
->isArray() && SrcNode
.isArray() ? 0
60 A
= Doc
.getRoot().getArray();
61 ASSERT_EQ(A
.size(), 2u);
63 ASSERT_EQ(SI
.getKind(), Type::Int
);
64 ASSERT_EQ(SI
.getInt(), 43);
66 ASSERT_EQ(SN
.getKind(), Type::Nil
);
69 TEST(MsgPackDocument
, TestReadAppendArray
) {
71 bool Ok
= Doc
.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
73 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Array
);
74 auto A
= Doc
.getRoot().getArray();
75 ASSERT_EQ(A
.size(), 2u);
77 ASSERT_EQ(SI
.getKind(), Type::Int
);
78 ASSERT_EQ(SI
.getInt(), 1);
80 ASSERT_EQ(SN
.getKind(), Type::Nil
);
82 Ok
= Doc
.readFromBlob(StringRef("\x91\xd0\x2a"), /*Multi=*/false,
83 [](DocNode
*DestNode
, DocNode SrcNode
, DocNode MapKey
) {
84 // Allow array, appending after existing elements
85 return DestNode
->isArray() && SrcNode
.isArray()
86 ? DestNode
->getArray().size()
90 A
= Doc
.getRoot().getArray();
91 ASSERT_EQ(A
.size(), 3u);
93 ASSERT_EQ(SI
.getKind(), Type::Int
);
94 ASSERT_EQ(SI
.getInt(), 1);
96 ASSERT_EQ(SN
.getKind(), Type::Nil
);
98 ASSERT_EQ(SI
.getKind(), Type::Int
);
99 ASSERT_EQ(SI
.getInt(), 42);
102 TEST(MsgPackDocument
, TestReadMergeMap
) {
104 bool Ok
= Doc
.readFromBlob(StringRef("\x82\xa3"
111 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Map
);
112 auto M
= Doc
.getRoot().getMap();
113 ASSERT_EQ(M
.size(), 2u);
114 auto FooS
= M
["foo"];
115 ASSERT_EQ(FooS
.getKind(), Type::Int
);
116 ASSERT_EQ(FooS
.getInt(), 1);
117 auto BarS
= M
["bar"];
118 ASSERT_EQ(BarS
.getKind(), Type::Int
);
119 ASSERT_EQ(BarS
.getInt(), 2);
121 Ok
= Doc
.readFromBlob(StringRef("\x82\xa3"
127 [](DocNode
*DestNode
, DocNode SrcNode
, DocNode MapKey
) {
128 return DestNode
->isMap() && SrcNode
.isMap() ? 0 : -1;
131 ASSERT_EQ(M
.size(), 4u);
133 ASSERT_EQ(FooS
.getKind(), Type::Int
);
134 ASSERT_EQ(FooS
.getInt(), 1);
136 ASSERT_EQ(BarS
.getKind(), Type::Int
);
137 ASSERT_EQ(BarS
.getInt(), 2);
138 auto FozS
= M
["foz"];
139 ASSERT_EQ(FozS
.getKind(), Type::Int
);
140 ASSERT_EQ(FozS
.getInt(), 3);
141 auto BazS
= M
["baz"];
142 ASSERT_EQ(BazS
.getKind(), Type::Int
);
143 ASSERT_EQ(BazS
.getInt(), 4);
145 Ok
= Doc
.readFromBlob(
151 /*Multi=*/false, [](DocNode
*Dest
, DocNode Src
, DocNode MapKey
) {
152 // Merger function that merges two ints by ORing their values, as long
153 // as the map key is "foz".
155 return Dest
->isMap();
157 return Dest
->isArray();
158 if (MapKey
.isString() && MapKey
.getString() == "foz" &&
159 Dest
->getKind() == Type::Int
&& Src
.getKind() == Type::Int
) {
160 *Dest
= Src
.getDocument()->getNode(Dest
->getInt() | Src
.getInt());
166 ASSERT_EQ(M
.size(), 5u);
168 ASSERT_EQ(FooS
.getKind(), Type::Int
);
169 ASSERT_EQ(FooS
.getInt(), 1);
171 ASSERT_EQ(BarS
.getKind(), Type::Int
);
172 ASSERT_EQ(BarS
.getInt(), 2);
174 ASSERT_EQ(FozS
.getKind(), Type::Int
);
175 ASSERT_EQ(FozS
.getInt(), 7);
177 ASSERT_EQ(BazS
.getKind(), Type::Int
);
178 ASSERT_EQ(BazS
.getInt(), 4);
179 auto BayS
= M
["bay"];
180 ASSERT_EQ(BayS
.getKind(), Type::Int
);
181 ASSERT_EQ(BayS
.getInt(), 8);
184 TEST(MsgPackDocument
, TestWriteInt
) {
188 Doc
.writeToBlob(Buffer
);
189 ASSERT_EQ(Buffer
, "\x01");
192 TEST(MsgPackDocument
, TestWriteArray
) {
194 auto A
= Doc
.getRoot().getArray(/*Convert=*/true);
195 A
.push_back(Doc
.getNode(int64_t(1)));
196 A
.push_back(Doc
.getNode());
198 Doc
.writeToBlob(Buffer
);
199 ASSERT_EQ(Buffer
, "\x92\x01\xc0");
202 TEST(MsgPackDocument
, TestWriteMap
) {
204 auto M
= Doc
.getRoot().getMap(/*Convert=*/true);
208 Doc
.writeToBlob(Buffer
);
209 ASSERT_EQ(Buffer
, "\x82\xa3"
216 TEST(MsgPackDocument
, TestOutputYAMLArray
) {
218 auto A
= Doc
.getRoot().getArray(/*Convert=*/true);
219 A
.push_back(Doc
.getNode(int64_t(1)));
220 A
.push_back(Doc
.getNode(int64_t(2)));
222 raw_string_ostream
OStream(Buffer
);
224 ASSERT_EQ(OStream
.str(), "---\n- 1\n- 2\n...\n");
227 TEST(MsgPackDocument
, TestInputYAMLArray
) {
229 bool Ok
= Doc
.fromYAML("---\n- !int 0x1\n- !str 2\n...\n");
231 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Array
);
232 auto A
= Doc
.getRoot().getArray();
233 ASSERT_EQ(A
.size(), 2u);
235 ASSERT_EQ(SI
.getKind(), Type::UInt
);
236 ASSERT_EQ(SI
.getUInt(), 1u);
238 ASSERT_EQ(SS
.getKind(), Type::String
);
239 ASSERT_EQ(SS
.getString(), "2");
242 TEST(MsgPackDocument
, TestOutputYAMLMap
) {
244 auto M
= Doc
.getRoot().getMap(/*Convert=*/true);
247 auto N
= Doc
.getMapNode();
251 raw_string_ostream
OStream(Buffer
);
253 ASSERT_EQ(OStream
.str(), "---\n"
261 TEST(MsgPackDocument
, TestOutputYAMLMapWithErase
) {
263 auto M
= Doc
.getRoot().getMap(/*Convert=*/true);
266 auto N
= Doc
.getMapNode();
269 M
.erase(Doc
.getNode("bar"));
271 raw_string_ostream
OStream(Buffer
);
273 ASSERT_EQ(OStream
.str(), "---\n"
280 TEST(MsgPackDocument
, TestOutputYAMLMapHex
) {
283 auto M
= Doc
.getRoot().getMap(/*Convert=*/true);
286 auto N
= Doc
.getMapNode();
290 raw_string_ostream
OStream(Buffer
);
292 ASSERT_EQ(OStream
.str(), "---\n"
300 TEST(MsgPackDocument
, TestInputYAMLMap
) {
302 bool Ok
= Doc
.fromYAML("---\nfoo: !int 0x1\nbaz: !str 2\n...\n");
304 ASSERT_EQ(Doc
.getRoot().getKind(), Type::Map
);
305 auto M
= Doc
.getRoot().getMap();
306 ASSERT_EQ(M
.size(), 2u);
308 ASSERT_EQ(SI
.getKind(), Type::UInt
);
309 ASSERT_EQ(SI
.getUInt(), 1u);
311 ASSERT_EQ(SS
.getKind(), Type::String
);
312 ASSERT_EQ(SS
.getString(), "2");