314 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			314 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===- MsgPackDocumentTest.cpp --------------------------------------------===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "llvm/BinaryFormat/MsgPackDocument.h"
 | |
| #include "gtest/gtest.h"
 | |
| 
 | |
| using namespace llvm;
 | |
| using namespace msgpack;
 | |
| 
 | |
| TEST(MsgPackDocument, DocNodeTest) {
 | |
|   Document Doc;
 | |
| 
 | |
|   DocNode Int1 = Doc.getNode(1), Int2 = Doc.getNode(2);
 | |
|   DocNode Str1 = Doc.getNode("ab"), Str2 = Doc.getNode("ab");
 | |
| 
 | |
|   ASSERT_TRUE(Int1 != Int2);
 | |
|   ASSERT_TRUE(Str1 == Str2);
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestReadInt) {
 | |
|   Document Doc;
 | |
|   bool Ok = Doc.readFromBlob(StringRef("\xd0\x00", 2), /*Multi=*/false);
 | |
|   ASSERT_TRUE(Ok);
 | |
|   ASSERT_EQ(Doc.getRoot().getKind(), Type::Int);
 | |
|   ASSERT_EQ(Doc.getRoot().getInt(), 0);
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestReadMergeArray) {
 | |
|   Document Doc;
 | |
|   bool Ok = Doc.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
 | |
|   ASSERT_TRUE(Ok);
 | |
|   ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
 | |
|   auto A = Doc.getRoot().getArray();
 | |
|   ASSERT_EQ(A.size(), 2u);
 | |
|   auto SI = A[0];
 | |
|   ASSERT_EQ(SI.getKind(), Type::Int);
 | |
|   ASSERT_EQ(SI.getInt(), 1);
 | |
|   auto SN = A[1];
 | |
|   ASSERT_EQ(SN.getKind(), Type::Nil);
 | |
| 
 | |
|   Ok = Doc.readFromBlob(StringRef("\x91\xd0\x2a"), /*Multi=*/false,
 | |
|                         [](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
 | |
|                           // Allow array, merging into existing elements, ORing
 | |
|                           // ints.
 | |
|                           if (DestNode->getKind() == Type::Int &&
 | |
|                               SrcNode.getKind() == Type::Int) {
 | |
|                             *DestNode = DestNode->getDocument()->getNode(
 | |
|                                 DestNode->getInt() | SrcNode.getInt());
 | |
|                             return 0;
 | |
|                           }
 | |
|                           return DestNode->isArray() && SrcNode.isArray() ? 0
 | |
|                                                                           : -1;
 | |
|                         });
 | |
|   ASSERT_TRUE(Ok);
 | |
|   A = Doc.getRoot().getArray();
 | |
|   ASSERT_EQ(A.size(), 2u);
 | |
|   SI = A[0];
 | |
|   ASSERT_EQ(SI.getKind(), Type::Int);
 | |
|   ASSERT_EQ(SI.getInt(), 43);
 | |
|   SN = A[1];
 | |
|   ASSERT_EQ(SN.getKind(), Type::Nil);
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestReadAppendArray) {
 | |
|   Document Doc;
 | |
|   bool Ok = Doc.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
 | |
|   ASSERT_TRUE(Ok);
 | |
|   ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
 | |
|   auto A = Doc.getRoot().getArray();
 | |
|   ASSERT_EQ(A.size(), 2u);
 | |
|   auto SI = A[0];
 | |
|   ASSERT_EQ(SI.getKind(), Type::Int);
 | |
|   ASSERT_EQ(SI.getInt(), 1);
 | |
|   auto SN = A[1];
 | |
|   ASSERT_EQ(SN.getKind(), Type::Nil);
 | |
| 
 | |
|   Ok = Doc.readFromBlob(StringRef("\x91\xd0\x2a"), /*Multi=*/false,
 | |
|                         [](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
 | |
|                           // Allow array, appending after existing elements
 | |
|                           return DestNode->isArray() && SrcNode.isArray()
 | |
|                                      ? DestNode->getArray().size()
 | |
|                                      : -1;
 | |
|                         });
 | |
|   ASSERT_TRUE(Ok);
 | |
|   A = Doc.getRoot().getArray();
 | |
|   ASSERT_EQ(A.size(), 3u);
 | |
|   SI = A[0];
 | |
|   ASSERT_EQ(SI.getKind(), Type::Int);
 | |
|   ASSERT_EQ(SI.getInt(), 1);
 | |
|   SN = A[1];
 | |
|   ASSERT_EQ(SN.getKind(), Type::Nil);
 | |
|   SI = A[2];
 | |
|   ASSERT_EQ(SI.getKind(), Type::Int);
 | |
|   ASSERT_EQ(SI.getInt(), 42);
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestReadMergeMap) {
 | |
|   Document Doc;
 | |
|   bool Ok = Doc.readFromBlob(StringRef("\x82\xa3"
 | |
|                                        "foo"
 | |
|                                        "\xd0\x01\xa3"
 | |
|                                        "bar"
 | |
|                                        "\xd0\x02"),
 | |
|                              /*Multi=*/false);
 | |
|   ASSERT_TRUE(Ok);
 | |
|   ASSERT_EQ(Doc.getRoot().getKind(), Type::Map);
 | |
|   auto M = Doc.getRoot().getMap();
 | |
|   ASSERT_EQ(M.size(), 2u);
 | |
|   auto FooS = M["foo"];
 | |
|   ASSERT_EQ(FooS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(FooS.getInt(), 1);
 | |
|   auto BarS = M["bar"];
 | |
|   ASSERT_EQ(BarS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(BarS.getInt(), 2);
 | |
| 
 | |
|   Ok = Doc.readFromBlob(StringRef("\x82\xa3"
 | |
|                                   "foz"
 | |
|                                   "\xd0\x03\xa3"
 | |
|                                   "baz"
 | |
|                                   "\xd0\x04"),
 | |
|                         /*Multi=*/false,
 | |
|                         [](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
 | |
|                           return DestNode->isMap() && SrcNode.isMap() ? 0 : -1;
 | |
|                         });
 | |
|   ASSERT_TRUE(Ok);
 | |
|   ASSERT_EQ(M.size(), 4u);
 | |
|   FooS = M["foo"];
 | |
|   ASSERT_EQ(FooS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(FooS.getInt(), 1);
 | |
|   BarS = M["bar"];
 | |
|   ASSERT_EQ(BarS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(BarS.getInt(), 2);
 | |
|   auto FozS = M["foz"];
 | |
|   ASSERT_EQ(FozS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(FozS.getInt(), 3);
 | |
|   auto BazS = M["baz"];
 | |
|   ASSERT_EQ(BazS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(BazS.getInt(), 4);
 | |
| 
 | |
|   Ok = Doc.readFromBlob(
 | |
|       StringRef("\x82\xa3"
 | |
|                 "foz"
 | |
|                 "\xd0\x06\xa3"
 | |
|                 "bay"
 | |
|                 "\xd0\x08"),
 | |
|       /*Multi=*/false, [](DocNode *Dest, DocNode Src, DocNode MapKey) {
 | |
|         // Merger function that merges two ints by ORing their values, as long
 | |
|         // as the map key is "foz".
 | |
|         if (Src.isMap())
 | |
|           return Dest->isMap();
 | |
|         if (Src.isArray())
 | |
|           return Dest->isArray();
 | |
|         if (MapKey.isString() && MapKey.getString() == "foz" &&
 | |
|             Dest->getKind() == Type::Int && Src.getKind() == Type::Int) {
 | |
|           *Dest = Src.getDocument()->getNode(Dest->getInt() | Src.getInt());
 | |
|           return true;
 | |
|         }
 | |
|         return false;
 | |
|       });
 | |
|   ASSERT_TRUE(Ok);
 | |
|   ASSERT_EQ(M.size(), 5u);
 | |
|   FooS = M["foo"];
 | |
|   ASSERT_EQ(FooS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(FooS.getInt(), 1);
 | |
|   BarS = M["bar"];
 | |
|   ASSERT_EQ(BarS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(BarS.getInt(), 2);
 | |
|   FozS = M["foz"];
 | |
|   ASSERT_EQ(FozS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(FozS.getInt(), 7);
 | |
|   BazS = M["baz"];
 | |
|   ASSERT_EQ(BazS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(BazS.getInt(), 4);
 | |
|   auto BayS = M["bay"];
 | |
|   ASSERT_EQ(BayS.getKind(), Type::Int);
 | |
|   ASSERT_EQ(BayS.getInt(), 8);
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestWriteInt) {
 | |
|   Document Doc;
 | |
|   Doc.getRoot() = 1;
 | |
|   std::string Buffer;
 | |
|   Doc.writeToBlob(Buffer);
 | |
|   ASSERT_EQ(Buffer, "\x01");
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestWriteArray) {
 | |
|   Document Doc;
 | |
|   auto A = Doc.getRoot().getArray(/*Convert=*/true);
 | |
|   A.push_back(Doc.getNode(int64_t(1)));
 | |
|   A.push_back(Doc.getNode());
 | |
|   std::string Buffer;
 | |
|   Doc.writeToBlob(Buffer);
 | |
|   ASSERT_EQ(Buffer, "\x92\x01\xc0");
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestWriteMap) {
 | |
|   Document Doc;
 | |
|   auto M = Doc.getRoot().getMap(/*Convert=*/true);
 | |
|   M["foo"] = 1;
 | |
|   M["bar"] = 2;
 | |
|   std::string Buffer;
 | |
|   Doc.writeToBlob(Buffer);
 | |
|   ASSERT_EQ(Buffer, "\x82\xa3"
 | |
|                     "bar"
 | |
|                     "\x02\xa3"
 | |
|                     "foo"
 | |
|                     "\x01");
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestOutputYAMLArray) {
 | |
|   Document Doc;
 | |
|   auto A = Doc.getRoot().getArray(/*Convert=*/true);
 | |
|   A.push_back(Doc.getNode(int64_t(1)));
 | |
|   A.push_back(Doc.getNode(int64_t(2)));
 | |
|   std::string Buffer;
 | |
|   raw_string_ostream OStream(Buffer);
 | |
|   Doc.toYAML(OStream);
 | |
|   ASSERT_EQ(OStream.str(), "---\n- 1\n- 2\n...\n");
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestInputYAMLArray) {
 | |
|   Document Doc;
 | |
|   bool Ok = Doc.fromYAML("---\n- !int 0x1\n- !str 2\n...\n");
 | |
|   ASSERT_TRUE(Ok);
 | |
|   ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
 | |
|   auto A = Doc.getRoot().getArray();
 | |
|   ASSERT_EQ(A.size(), 2u);
 | |
|   auto SI = A[0];
 | |
|   ASSERT_EQ(SI.getKind(), Type::UInt);
 | |
|   ASSERT_EQ(SI.getUInt(), 1u);
 | |
|   auto SS = A[1];
 | |
|   ASSERT_EQ(SS.getKind(), Type::String);
 | |
|   ASSERT_EQ(SS.getString(), "2");
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestOutputYAMLMap) {
 | |
|   Document Doc;
 | |
|   auto M = Doc.getRoot().getMap(/*Convert=*/true);
 | |
|   M["foo"] = 1;
 | |
|   M["bar"] = 2U;
 | |
|   auto N = Doc.getMapNode();
 | |
|   M["qux"] = N;
 | |
|   N["baz"] = true;
 | |
|   std::string Buffer;
 | |
|   raw_string_ostream OStream(Buffer);
 | |
|   Doc.toYAML(OStream);
 | |
|   ASSERT_EQ(OStream.str(), "---\n"
 | |
|                            "bar:             2\n"
 | |
|                            "foo:             1\n"
 | |
|                            "qux:\n"
 | |
|                            "  baz:             true\n"
 | |
|                            "...\n");
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestOutputYAMLMapWithErase) {
 | |
|   Document Doc;
 | |
|   auto M = Doc.getRoot().getMap(/*Convert=*/true);
 | |
|   M["foo"] = 1;
 | |
|   M["bar"] = 2U;
 | |
|   auto N = Doc.getMapNode();
 | |
|   M["qux"] = N;
 | |
|   N["baz"] = true;
 | |
|   M.erase(Doc.getNode("bar"));
 | |
|   std::string Buffer;
 | |
|   raw_string_ostream OStream(Buffer);
 | |
|   Doc.toYAML(OStream);
 | |
|   ASSERT_EQ(OStream.str(), "---\n"
 | |
|                            "foo:             1\n"
 | |
|                            "qux:\n"
 | |
|                            "  baz:             true\n"
 | |
|                            "...\n");
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestOutputYAMLMapHex) {
 | |
|   Document Doc;
 | |
|   Doc.setHexMode();
 | |
|   auto M = Doc.getRoot().getMap(/*Convert=*/true);
 | |
|   M["foo"] = 1;
 | |
|   M["bar"] = 2U;
 | |
|   auto N = Doc.getMapNode();
 | |
|   M["qux"] = N;
 | |
|   N["baz"] = true;
 | |
|   std::string Buffer;
 | |
|   raw_string_ostream OStream(Buffer);
 | |
|   Doc.toYAML(OStream);
 | |
|   ASSERT_EQ(OStream.str(), "---\n"
 | |
|                            "bar:             0x2\n"
 | |
|                            "foo:             1\n"
 | |
|                            "qux:\n"
 | |
|                            "  baz:             true\n"
 | |
|                            "...\n");
 | |
| }
 | |
| 
 | |
| TEST(MsgPackDocument, TestInputYAMLMap) {
 | |
|   Document Doc;
 | |
|   bool Ok = Doc.fromYAML("---\nfoo: !int 0x1\nbaz: !str 2\n...\n");
 | |
|   ASSERT_TRUE(Ok);
 | |
|   ASSERT_EQ(Doc.getRoot().getKind(), Type::Map);
 | |
|   auto M = Doc.getRoot().getMap();
 | |
|   ASSERT_EQ(M.size(), 2u);
 | |
|   auto SI = M["foo"];
 | |
|   ASSERT_EQ(SI.getKind(), Type::UInt);
 | |
|   ASSERT_EQ(SI.getUInt(), 1u);
 | |
|   auto SS = M["baz"];
 | |
|   ASSERT_EQ(SS.getKind(), Type::String);
 | |
|   ASSERT_EQ(SS.getString(), "2");
 | |
| }
 |